Diff for /loncom/interface/spreadsheet/studentcalc.pm between versions 1.3 and 1.45

version 1.3, 2003/05/19 15:48:18 version 1.45, 2010/06/14 01:30:54
Line 45  studentcalc Line 45  studentcalc
 ###################################################  ###################################################
 package Apache::studentcalc;  package Apache::studentcalc;
   
   use warnings FATAL=>'all';
   no warnings 'uninitialized';
   
 use strict;  use strict;
 use Apache::Constants qw(:common :http);  use Apache::Constants qw(:common :http);
 use Apache::lonnet;  use Apache::lonnet;
Line 54  use Apache::lonnavmaps; Line 57  use Apache::lonnavmaps;
 use Apache::Spreadsheet();  use Apache::Spreadsheet();
 use Apache::assesscalc();  use Apache::assesscalc();
 use HTML::Entities();  use HTML::Entities();
 use Spreadsheet::WriteExcel;  
 use Time::HiRes;  use Time::HiRes;
   use Apache::lonlocal;
   use LONCAPA;
    
   
 @Apache::studentcalc::ISA = ('Apache::Spreadsheet');  @Apache::studentcalc::ISA = ('Apache::Spreadsheet');
   
 my @Sequences = ();  my @Sequences = ();
   my $navmap;
 my %Exportrows = ();  my %Exportrows = ();
   
 my $current_course;  my $current_course;
   
   sub initialize {
       &initialize_sequence_cache();
       &Apache::assesscalc::initialize($navmap);
   }
   
 sub initialize_package {  sub initialize_package {
     $current_course = $ENV{'request.course.id'};      $current_course = $env{'request.course.id'};
     &initialize_sequence_cache();      &initialize_sequence_cache();
     &load_cached_export_rows();      &load_cached_export_rows();
 }  }
   
   sub ensure_correct_sequence_data {
       if ($current_course ne $env{'request.course.id'}) {
           &initialize_sequence_cache();
           $current_course = $env{'request.course.id'};
       }
       return;
   }
   
 sub initialize_sequence_cache {  sub initialize_sequence_cache {
     #      #
     # Set up the sequences and assessments      # Set up the sequences and assessments
     @Sequences = ();      undef(@Sequences);
     my ($top,$sequences,$assessments) =       undef($navmap);
         &Apache::loncoursedata::get_sequence_assessment_data();      $navmap = Apache::lonnavmaps::navmap->new();
     if (! defined($top) || ! ref($top)) {      if (!defined($navmap)) {
         # There has been an error, better report it          &Apache::lonnet::logthis('student spreadsheet:Can not open Coursemap');
         &Apache::lonnet::logthis('top is undefined (studentcalc.pm)');      }
         return;      my @all_sequences = $navmap->retrieveResources(undef,
                                                  sub { shift->is_map(); },1,0,1);
       my $toplevelseq = $navmap->getById('0.0');
       if (!grep(/^\Q$toplevelseq\E$/,@all_sequences)) {
            unshift(@all_sequences,$toplevelseq);
       }
       foreach my $sequence (@all_sequences) {
          if ($navmap->hasResource($sequence,sub { shift->is_problem(); }, 0,1)){
              push(@Sequences,$sequence);
              &get_resources($sequence);
          }
     }      }
     @Sequences = @{$sequences} if (ref($sequences) eq 'ARRAY');  }
   
   my %res_memoize;
   sub get_resources {
       my ($seq) = @_;
       if (exists($res_memoize{$seq->symb()})) {
    return @{$res_memoize{$seq->symb()}};
       }
       return () if (! defined($navmap) || ! ref($navmap));
       my @resources = $navmap->retrieveResources($seq,
                                                  sub { shift->is_problem(); },
                                                  0,0,1);
       $res_memoize{$seq->symb()}=\@resources;
       return @resources;
 }  }
   
 sub clear_package {  sub clear_package {
     @Sequences = undef;      undef(@Sequences);
     %Exportrows = undef;      undef(%Exportrows);
       undef(%res_memoize);
       undef($navmap);
       &Apache::assesscalc::clear_package();
 }  }
   
 sub get_title {  sub get_title {
     my $self = shift;      my $self = shift;
     my $title = '';      my @title = ();
     my %userenv = &Apache::loncoursedata::GetUserName($self->{'name'},      #
                                                       $self->{'domain'});      # Determine the students name
     &Apache::lonnet::logthis('userenv = '.join(' ',%userenv));      my $name = &Apache::loncommon::plainname($self->{'name'},
     my $name =        $self->{'domain'});
         join(' ',@userenv{'firstname','middlename','lastname','generation'});      push (@title,$name);
     $name =~ s/\s+$//;      push (@title,$self->{'coursedesc'});
     $title .= '<h1>'.$name;      push (@title,&Apache::lonlocal::locallocaltime(time));
     if ($ENV{'user.name'} ne $self->{'name'} &&       return @title;
         $ENV{'user.domain'} ne $self->{'domain'}) {  }
         $title .= &Apache::loncommon::aboutmewrapper  
   sub get_html_title {
       my $self = shift;
       my ($name,$desc,$time) = $self->get_title();
       my $title = '<h1>'.$name;
       if ($env{'user.name'} ne $self->{'name'} && 
           $env{'user.domain'} ne $self->{'domain'}) {
           $title .= ' '.&Apache::loncommon::aboutmewrapper
                                     ($self->{'name'}.'@'.$self->{'domain'},                                      ($self->{'name'}.'@'.$self->{'domain'},
                                      $self->{'name'},$self->{'domain'});                                       $self->{'name'},$self->{'domain'});
     }      }
     $title .= "</h1>\n";      $title .= "</h1>\n";
     $title .= '<h2>'.$self->{'coursedesc'}."</h2>\n";      $title .= '<h2>'.$desc."</h2>\n";
     $title .= '<h3>'.localtime(time).'</h3>';      $title .= '<h3>'.$time.'</h3>';
     return $title;      return $title;
 }  }
   
 sub parent_link {  sub parent_link {
     my $self = shift;      my $self = shift;
     my $link .= '<p><a href="/adm/classcalc?'.      return '<p><a href="/adm/classcalc">'.&mt('Course level sheet').'</a></p>'."\n";
         'sname='.$self->{'name'}.  }
             '&sdomain='.$self->{'domain'}.'">'.  
                 'Course level sheet</a></p>'."\n";  sub convenience_links {
     return $link;      my $self = shift;
       my ($resource) = @_;
       my $result=&Apache::loncommon::submlink('<img src="/adm/lonMisc/subm_button.gif" border="0" />',$self->{'name'},$self->{'domain'},$resource->symb,'LONcatInfo');
       $result .= &Apache::loncommon::pgrdlink('<img src="/adm/lonMisc/pgrd_button.gif" border="0" />',$self->{'name'},$self->{'domain'},$resource->symb,'LONcatInfo');
       $result .= &Apache::loncommon::pprmlink('<img src="/adm/lonMisc/pprm_button.gif" border="0" />',$self->{'name'},$self->{'domain'},$resource->symb,'LONcatInfo');
       return $result;
 }  }
   
 sub outsheet_html {  sub outsheet_html {
     my $self = shift;      my $self = shift;
     my ($r) = @_;      my ($r) = @_;
       my $importcolor = '#FFFFAA';
       my $exportcolor = '#88FF88';
     ####################################      ####################################
     # Get the list of assessment files #      # Get the list of assessment files #
     ####################################      ####################################
     my @AssessFileNames = $self->othersheets('assesscalc');      my @AssessFileNames = $self->othersheets('assesscalc');
     my $editing_is_allowed = &Apache::lonnet::allowed('mgr',      my $editing_is_allowed = &Apache::lonnet::allowed('mgr',
                                                 $ENV{'request.course.id'});                                                  $env{'request.course.id'});
       ####################################
       # Report any calculation errors    #
       ####################################
       $r->print($self->html_report_error());
     ####################################      ####################################
     # Determine table structure        #      # Determine table structure        #
     ####################################      ####################################
     my $num_uneditable = 26;      my $num_uneditable = 26;
     my $num_left = 52-$num_uneditable;      my $num_left = 52-$num_uneditable;
       my %lt=&Apache::lonlocal::texthash(
          'st' => 'Student',
          'im' => 'Import',
          'ca' => 'Calculations',
          'as' => 'Assessment',
          'ro' => 'Row',
          );
     my $tableheader =<<"END";      my $tableheader =<<"END";
 <p>  <p>
 <table border="2">  <table border="2">
 <tr>  <tr>
   <th colspan="2" rowspan="2"><font size="+2">Student</font></th>    <th colspan="2" rowspan="2"><font size="+2">$lt{'st'}</font></th>
   <td bgcolor="#FFDDDD" colspan="$num_uneditable">    <td bgcolor="$importcolor" colspan="$num_uneditable">
       <b><font size="+1">Import</font></b></td>        <b><font size="+1">$lt{'im'}</font></b></td>
   <td colspan="$num_left">    <td colspan="$num_left">
       <b><font size="+1">Calculations</font></b></td>        <b><font size="+1">$lt{'ca'}</font></b></td>
 </tr><tr>  </tr><tr>
 END  END
     my $label_num = 0;      my $label_num = 0;
     foreach (split(//,'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz')){      foreach (split(//,'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz')){
         if ($label_num<$num_uneditable) {           if ($label_num<$num_uneditable) { 
             $tableheader .='<td bgcolor="#FFDDDD">';              $tableheader .='<td bgcolor="'.$importcolor.'">';
         } else {          } else {
             $tableheader .='<td>';              $tableheader .='<td>';
         }          }
Line 156  END Line 226  END
         $label_num++;          $label_num++;
     }      }
     $tableheader .="</tr>\n";      $tableheader .="</tr>\n";
     #      if ($self->blackout()) {
     $r->print($tableheader);          $r->print('<p class="LC_warning">'.
     #                    &mt('Some computations are not available at this time.').'<br />'.
     # Print out template row                    &mt('There are problems whose status you are not allowed to view.').
     $r->print('<tr><td>Template</td><td>&nbsp;</td>'.                    '</p>'."\n");
       $self->html_template_row($num_uneditable)."</tr>\n");      } else {
     #          $r->print($tableheader);
     # Print out summary/export row          #
     $r->print('<tr><td>Export</td><td>0</td>'.          # Print out template row
       $self->html_export_row()."</tr>\n");          if (exists($env{'request.role.adv'}) && $env{'request.role.adv'}) {
               $r->print('<tr><td>'.&mt('Template').'</td><td>&nbsp;</td>'.
                         $self->html_template_row($num_uneditable,
                                                  $importcolor)."</tr>\n");
           }
           #
           # Print out summary/export row
           $r->print('<tr><td>'.&mt('Summary').'</td><td>0</td>'.
                     $self->html_export_row($exportcolor)."</tr>\n");
       }
     $r->print("</table>\n");      $r->print("</table>\n");
     #      #
     # Prepare to output rows      # Prepare to output rows
     $tableheader =<<"END";      if (exists($env{'request.role.adv'}) && $env{'request.role.adv'}) {
           $tableheader =<<"END";
   </p><p>
   <table border="2">
   <tr><th>$lt{'ro'}</th><th>&nbsp;</th><th>$lt{'as'}</th>
   END
       } else {
           $tableheader =<<"END";
 </p><p>  </p><p>
 <table border="2">  <table border="2">
 <tr><th>Row</th><th>Assessment</th>  <tr><th>&nbsp;</th><th>$lt{'as'}</th>
 END  END
       }
     foreach (split(//,'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz')){      foreach (split(//,'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz')){
  if ($label_num<$num_uneditable) {    if ($label_num<$num_uneditable) { 
             $tableheader.='<td bgcolor="#FFDDDD">';              $tableheader.='<td bgcolor="#FFDDDD">';
Line 189  END Line 276  END
         &initialize_sequence_cache();          &initialize_sequence_cache();
     }      }
     foreach my $Sequence (@Sequences) {      foreach my $Sequence (@Sequences) {
  next if ($Sequence->{'num_assess'} < 1);   $r->print("<h3>".$Sequence->compTitle."</h3>\n");
  $r->print("<h3>".$Sequence->{'title'}."</h3>\n");  
           my @resources = &get_resources($Sequence);
           my $first_rownum =
               $self->get_row_number_from_key($resources[0]->symb);
           my $last_rownum = 
               $self->get_row_number_from_key($resources[-1]->symb);
           $r->print(&assess_file_selector([$first_rownum, $last_rownum],
                                           undef, \@AssessFileNames));
   
   $r->print($tableheader);    $r->print($tableheader);
  foreach my $resource (@{$Sequence->{'contents'}}) {   foreach my $resource (@resources) {
     next if ($resource->{'type'} ne 'assessment');      my $rownum = $self->get_row_number_from_key($resource->symb);
     my $rownum = $self->get_row_number_from_key($resource->{'symb'});  
             my $assess_filename = $self->{'row_source'}->{$rownum};              my $assess_filename = $self->{'row_source'}->{$rownum};
             my $row_output = '<tr>';              my $row_output = '<tr>';
             if ($editing_is_allowed) {              if ($editing_is_allowed) {
                 $row_output .= '<td>'.$rownum.'</td>';                  $row_output .= '<td>'.$rownum.'</td>';
                   $row_output .= '<td>'.$self->convenience_links($resource).'</td>';
                 $row_output .= '<td>'.                  $row_output .= '<td>'.
                     '<a href="/adm/assesscalc?sname='.$self->{'name'}.                      '<a href="/adm/assesscalc?sname='.$self->{'name'}.
                     '&sdomain='.$self->{'domain'}.                      '&sdomain='.$self->{'domain'}.
                     '&filename='.$assess_filename.                      '&filename='.$assess_filename.
                     '&usymb='.&Apache::lonnet::escape($resource->{'symb'}).'">'.                      '&usymb='.&escape($resource->symb).
                     $resource->{'title'}.'</a><br />';                      '">'.$resource->compTitle.'</a><br />';
                 $row_output .= &assess_file_selector($rownum,                  $row_output .= &assess_file_selector($rownum,
                                                      $assess_filename,                                                       $assess_filename,
                                                      \@AssessFileNames).                                                       \@AssessFileNames).
                                                          '</td>';                                                           '</td>';
             } else {              } else {
                 $row_output .= '<td><a href="'.$resource->{'src'}.'?symb='.                  $row_output .= '<td><a href="'.$resource->src.'?symb='.
                     &Apache::lonnet::escape($resource->{'symb'}).'>Go To</a>';                      &escape($resource->symb).
                 $row_output .= '</td><td>'.$resource->{'title'}.'</td>';                      '">Go&nbsp;To</a>';
                   $row_output .= '</td><td>'.$resource->compTitle.'</td>';
               }
               if ($self->blackout() && $self->{'blackout_rows'}->{$rownum}>0) {
                   $row_output .= 
                       '<td colspan="52">'.&mt('Unavailable at this time').'</td></tr>'."\n";
               } else {
                   $row_output .= $self->html_row($num_uneditable,$rownum,
                                                  $exportcolor,$importcolor).
                       "</tr>\n";
             }              }
             $row_output .= $self->html_row($num_uneditable,$rownum).  
                 "</tr>\n";  
             $r->print($row_output);              $r->print($row_output);
  }   }
  $r->print("</table>\n");   $r->print("</table>\n");
Line 240  sub assess_file_selector { Line 342  sub assess_file_selector {
     if (!defined($AssessFiles) || ! @$AssessFiles) {      if (!defined($AssessFiles) || ! @$AssessFiles) {
         return '';          return '';
     }      }
     return '' if (! &Apache::lonnet::allowed('mgr',$ENV{'request.course.id'}));      return '' if (! &Apache::lonnet::allowed('mgr',$env{'request.course.id'}));
     my $element_name = 'FileSelect_'.$row;      my $element_name;
       my $source_row = $row;
       if (ref($row)) {
           my ($first_rownum, $last_rownum) = @$row;
           $element_name = "FileSelect_${first_rownum}_${last_rownum}";
           $source_row = "${first_rownum}:${last_rownum}";
       } else {
           $element_name = 'FileSelect_'.$row;
       }
     my $load_dialog = '<select size="1" name="'.$element_name.'" '.      my $load_dialog = '<select size="1" name="'.$element_name.'" '.
         'onchange="'.          'onchange="'.
         "document.sheet.cell.value='source_$row';".          "document.sheet.cell.value='source_${source_row}';".
         "document.sheet.newformula.value=document.sheet.$element_name\.value;".          "document.sheet.newformula.value=document.sheet.$element_name\.value;".
         'document.sheet.submit()" '.'>'."\n";          'document.sheet.submit()" '.'>'."\n";
       if (ref($row)) {
           $load_dialog .= '    <option name="" value="">' .
               &mt("Select spreadsheet for entire sequence")
               . "</option>\n";
       }
     foreach my $file (@{$AssessFiles}) {      foreach my $file (@{$AssessFiles}) {
         $load_dialog .= '    <option name="'.$file.'"';          $load_dialog .= '    <option name="'.$file.'"';
         $load_dialog .= ' selected' if ($default eq $file);          $load_dialog .= ' selected' if ($default eq $file);
Line 259  sub assess_file_selector { Line 374  sub assess_file_selector {
 sub modify_cell {  sub modify_cell {
     my $self = shift;      my $self = shift;
     my ($cell,$formula) = @_;      my ($cell,$formula) = @_;
     if ($cell =~ /^source_(\d+)$/) {  
         # Need to make sure $formula is a valid filename....      my $set_row = sub {
         my $row = $1;          my $row = shift;
         $cell = 'A'.$row;          my $formula = shift;
           my $cell = 'A' . $row;
         $self->{'row_source'}->{$row} = $formula;          $self->{'row_source'}->{$row} = $formula;
         my $original_source = $self->formula($cell);          my $original_source = $self->formula($cell);
         if ($original_source =~ /__&&&__/) {          if ($original_source =~ /__&&&__/) {
             ($original_source,undef) = split('__&&&__',$original_source);              ($original_source,undef) = split('__&&&__',$original_source);
         }          }
         $formula = $original_source.'__&&&__'.$formula;          $formula = $original_source.'__&&&__'.$formula;
           $self->set_formula($cell,$formula);
       };
   
       if ($cell =~ /^source_(\d+):(\d+)$/) {
           my $first_row = $1;
           my $last_row = $2;
           for my $row ($first_row..$last_row) {
               $set_row->($row, $formula);
           }
       } elsif ($cell =~ /^source_(\d+)$/) {
           # Need to make sure $formula is a valid filename....
           my $row = $1;
           $set_row->($row, $formula);
     } elsif ($cell =~ /([A-z])\-/) {      } elsif ($cell =~ /([A-z])\-/) {
         $cell = 'template_'.$1;          $cell = 'template_'.$1;
           $self->set_formula($cell,$formula);
     } elsif ($cell !~ /^([A-z](\d+)|template_[A-z])$/) {      } elsif ($cell !~ /^([A-z](\d+)|template_[A-z])$/) {
         return;          return;
       } else {
           $self->set_formula($cell,$formula);
     }      }
     $self->set_formula($cell,$formula);  
     $self->rebuild_stats();      $self->rebuild_stats();
     return;      return;
 }  }
   
 sub outsheet_csv {  sub csv_rows {
       # writes the meat of the spreadsheet to an excel worksheet.  Called
       # by Spreadsheet::outsheet_excel;
     my $self = shift;      my $self = shift;
     my ($r) = @_;      my ($connection,$filehandle) = @_;
       #
       # Write a header row
       $self->csv_output_row($filehandle,undef,
                             (&mt('Sequence or Folder'),&mt('Assessment title')));
       #
       # Write each assessments row
       if (scalar(@Sequences)< 1) {
           &initialize_sequence_cache();
       }
       foreach my $Sequence (@Sequences) {
    foreach my $resource (&get_resources($Sequence)) {
       my $rownum = $self->get_row_number_from_key($resource->symb);
               my @assessdata = ($Sequence->compTitle,
                                 $resource->compTitle);
               $self->csv_output_row($filehandle,$rownum,@assessdata);
           }
       }
       return;
 }  }
 sub outsheet_excel {  
   sub excel_rows {
       # writes the meat of the spreadsheet to an excel worksheet.  Called
       # by Spreadsheet::outsheet_excel;
     my $self = shift;      my $self = shift;
     my ($r) = @_;      my ($connection,$worksheet,$cols_output,$rows_output,$format) = @_;
       #
       # Write a header row
       $cols_output = 0;
       foreach my $value ('Container','Assessment title') {
           $worksheet->write($rows_output,$cols_output++,&mt($value),$format->{'h4'});
       }
       $rows_output++;    
       #
       # Write each assessments row
       if (scalar(@Sequences)< 1) {
           &initialize_sequence_cache();
       }
       foreach my $Sequence (@Sequences) {
    foreach my $resource (&get_resources($Sequence)) {
       my $rownum = $self->get_row_number_from_key($resource->symb);
               my @assessdata = ($Sequence->compTitle,
                                 $resource->compTitle);
               $self->excel_output_row($worksheet,$rownum,$rows_output++,
                                       @assessdata);
           }
       }
       return;
 }  }
   
 sub outsheet_recursive_excel {  sub outsheet_recursive_excel {
     my $self = shift;      my $self = shift;
     my ($r) = @_;      my ($r) = @_;
 }   } 
   
 sub display {  ##
     my $self = shift;  ## Routines to deal with sequences in the safe space
     my ($r) = @_;  ##
     $self->compute();  sub get_rows_in_sequence {
     $self->outsheet_html($r);      my $self = shift();
     return;      my ($sequence) = @_;
 }      my @Rows;
       my @resources = &get_resources($sequence);
 sub set_row_sources {      foreach my $resource (@resources) {
     my $self = shift;          my $rownum = $self->get_row_number_from_key($resource->symb);
     while (my ($cell,$value) = each(%{$self->{'formulas'}})) {          push (@Rows,$rownum);
         next if ($cell !~ /^A(\d+)/ && $1 > 0);      }
         my $row = $1;      return @Rows;
         (undef,$value) = split('__&&&__',$value);  }
         $value = 'Default' if (! defined($value));  
         $self->{'row_source'}->{$row} = $value;  sub remove_sequence_data_from_safe_space {
       my $self = shift();
       my $command = 'undef(%Sequence_Rows);';
       $self->{'safe'}->reval($command);
   }
   
   sub put_sequence_data_in_safe_space {
       my $self = shift();
       my $data = 'undef(%Sequence_Rows);';
       # Build up the %Sequence_Rows hash - each sequence title is associated with
       # an array pointer, which holds the rows in the sequence.
       foreach my $seq (@Sequences) {
           my @Rows = $self->get_rows_in_sequence($seq);
           # 
           # Potential problems with sequence titles:
           # 1. duplicate titles - they get the total for the titles
           # 2. control characters in titles - use q{} around the string to
           #    deal with it.  
           my $title = &HTML::Entities::decode($seq->title());
           $title =~ s/&\#058;/:/g;
           if (@Rows) {
               $data .= 'push(@{$Sequence_Rows{"'.quotemeta($title).'"}},'.
                   '('.join(',',@Rows).'));'."\n";;
           }
       }
       my $new_code = $data.<<'END';
   sub SUMSEQ {
       my ($col,@titles) = @_;
       return 'bad column: '.$col if ($col !~ /^[A-z]$/);
       my $sum = 0;
       foreach my $title (@titles) {
           while (my ($seq_title,$rows) = each(%Sequence_Rows)) {
               my $regexp;
               if ($title =~ /^regexp:(.*)$/) {
                   $regexp = $1;
               } elsif (lc($title) eq 'all') {
                   $regexp = '.';
               }
               if (defined($regexp)) {
                   next if ($seq_title !~ /$regexp/);
               } else {
                   next if ($seq_title ne $title);
               }
               foreach my $rownum (@{$rows}) {
                   my $cell = $col.$rownum;
                   if (exists($sheet_values{$cell})) {
                       $sum += $sheet_values{$cell};
                   }
               }
           }
     }      }
       return $sum;
   }
   END
       $self->{'safe'}->reval($new_code);
     return;      return;
 }  }
   
   ##
   ## Main computation method
   ##
 sub compute {  sub compute {
     my $self = shift;      my $self = shift;
     $self->logthis('computing');      my ($r) = @_;
     if (! defined($current_course) ||      if (! defined($current_course) ||
         $current_course ne $ENV{'request.course.id'}) {          $current_course ne $env{'request.course.id'} ||
         $current_course = $ENV{'request.course.id'};          ! @Sequences ) {
           $current_course = $env{'request.course.id'};
         &clear_package();          &clear_package();
         &initialize_sequence_cache();          &initialize_sequence_cache();
     }      }
     $self->initialize_safe_space();      $self->initialize_safe_space();
     my @sequences = @Sequences;      &Apache::assesscalc::initialize_package($self->{'name'},$self->{'domain'},
     if (@sequences < 1) {                                              $navmap,$self);
         my ($top,$sequences,$assessments) =   
             &Apache::loncoursedata::get_sequence_assessment_data();  
         if (! defined($top) || ! ref($top)) {  
             &Apache::lonnet::logthis('top is undefined');  
             return;  
         }  
         @sequences = @{$sequences} if (ref($sequences) eq 'ARRAY');  
     }  
     &Apache::assesscalc::initialize_package($self->{'name'},$self->{'domain'});  
     my %f = $self->formulas();      my %f = $self->formulas();
     #      #
     # Process the formulas list -       # Process the formulas list - 
     #   the formula for the A column of a row is symb__&&__filename      #   the formula for the A column of a row is symb__&&__filename
     my %c = $self->constants();      my %c = $self->constants();
     foreach my $seq (@sequences) {      foreach my $seq (@Sequences) {
         next if ($seq->{'num_assess'}<1);          foreach my $resource (&get_resources($seq)) {
         foreach my $resource (@{$seq->{'contents'}}) {              my $rownum = $self->get_row_number_from_key($resource->symb);
             next if ($resource->{'type'} ne 'assessment');  
             my $rownum = $self->get_row_number_from_key($resource->{'symb'});  
             my $cell = 'A'.$rownum;              my $cell = 'A'.$rownum;
             my $assess_filename = 'Default';              my $assess_filename = 'Default';
             if (exists($self->{'row_source'}->{$rownum})) {              if (exists($self->{'row_source'}->{$rownum})) {
Line 350  sub compute { Line 573  sub compute {
             } else {              } else {
                 $self->{'row_source'}->{$rownum} = $assess_filename;                  $self->{'row_source'}->{$rownum} = $assess_filename;
             }              }
             $f{$cell} = $resource->{'symb'}.'__&&&__'.$assess_filename;              $f{$cell} = $resource->symb.'__&&&__'.$assess_filename;
             my $assessSheet = Apache::assesscalc->new($self->{'name'},              my $assessSheet;
                                                       $self->{'domain'},                  $assessSheet = Apache::assesscalc->new($self->{'name'},
                                                       $assess_filename,                                                         $self->{'domain'},
                                                       $resource->{'symb'});                                                         $assess_filename,
             my @exportdata = $assessSheet->export_data();                                                         $resource->symb,
          $self->{'section'},
                                                          $self->{'groups'});
               my @exportdata = $assessSheet->export_data($r);
               #
               if ($assessSheet->badcalc()) {
                   $self->set_calcerror(
               &mt('Error computing row for assessment "[_1]" (row [_2]):[_3]',
                   $assessSheet->get_title(),$rownum,$assessSheet->calcerror()));
               }
               #
               if ($assessSheet->blackout()) {
                   $self->blackout(1);
                   $self->{'blackout_rows'}->{$rownum} = 1;
               }
             #              #
             # Be sure not to disturb the formulas in the 'A' column              # Be sure not to disturb the formulas in the 'A' column
             my $data = shift(@exportdata);              my $data = shift(@exportdata);
Line 376  sub compute { Line 613  sub compute {
     }      }
     $self->constants(\%c);      $self->constants(\%c);
     $self->formulas(\%f);      $self->formulas(\%f);
       $self->put_sequence_data_in_safe_space();
     $self->calcsheet();      $self->calcsheet();
       $self->remove_sequence_data_from_safe_space();
     #      #
     # Store export row in cache      # Store export row in cache
     my @exportarray=$self->exportrow();      my @exportarray=$self->exportrow();
Line 385  sub compute { Line 624  sub compute {
     $Exportrows{$student}->{'data'} = \@exportarray;      $Exportrows{$student}->{'data'} = \@exportarray;
     # save export row      # save export row
     $self->save_export_data();      $self->save_export_data();
       #
       $self->save() if ($self->need_to_save());
       return;
   }
   
   sub set_row_sources {
       my $self = shift;
       $self->check_formulas_loaded();
       while (my ($cell,$value) = each(%{$self->{'formulas'}})) {
           next if ($cell !~ /^A(\d+)$/ || $1 < 1);
           my $row = $1;
           (undef,$value) = split('__&&&__',$value);
           $value = 'Default' if (! defined($value));
           $self->{'row_source'}->{$row} = $value;
       }
     return;      return;
 }  }
   
 sub set_row_numbers {  sub set_row_numbers {
     my $self = shift;      my $self = shift;
       $self->check_formulas_loaded();
     while (my ($cell,$formula) = each(%{$self->{'formulas'}})) {      while (my ($cell,$formula) = each(%{$self->{'formulas'}})) {
         next if ($cell !~ /^A(\d+)/);          next if ($cell !~ /^A(\d+)/);
         my $row = $1;          my $row = $1;
         next if ($row == 0);          next if ($row == 0);
         my ($symb,undef) = split('__&&&__',$formula);          my ($symb,undef) = split('__&&&__',$formula);
         $self->{'row_numbers'}->{$symb} = $row;          $self->{'row_numbers'}->{$symb} = $row;
           $self->{'maxrow'} = $row if ($row > $self->{'maxrow'});
     }      }
 }  }
   
Line 425  These rows are saved in the courses dire Line 681  These rows are saved in the courses dire
 #############################################  #############################################
 #############################################  #############################################
 sub load_cached_export_rows {  sub load_cached_export_rows {
     %Exportrows = undef;      undef(%Exportrows);
     my @tmp = &Apache::lonnet::dump('nohist_calculatedsheets',      my @tmp = &Apache::lonnet::dump('nohist_calculatedsheets',
      $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},       $env{'course.'.$env{'request.course.id'}.'.domain'},
      $ENV{'course.'.$ENV{'request.course.id'}.'.num'},undef);       $env{'course.'.$env{'request.course.id'}.'.num'},undef);
     my %Selected_Assess_Sheet;      my %Selected_Assess_Sheet;
     if ($tmp[0] =~ /^error/) {      if ($tmp[0] =~ /^error/) {
         &Apache::lonnet::logthis('unable to read cached student export rows '.          &Apache::lonnet::logthis('unable to read cached student export rows '.
                                  'for course '.$ENV{'request.course.id'});                                   'for course '.$env{'request.course.id'});
         return;          return;
     }      }
     my %tmp = @tmp;      my %tmp = @tmp;
Line 465  Writes the export data for this student Line 721  Writes the export data for this student
 sub save_export_data {  sub save_export_data {
     my $self = shift;      my $self = shift;
     my $student = $self->{'name'}.':'.$self->{'domain'};      my $student = $self->{'name'}.':'.$self->{'domain'};
       return if ($self->temporary());
       if ($self->badcalc()){
           # do not save data away when calculations have not been done properly.
           delete($Exportrows{$student});
           return;
       }
     return if (! exists($Exportrows{$student}));      return if (! exists($Exportrows{$student}));
       &Apache::assesscalc::save_cached_export_rows($self->{'name'},
                                                    $self->{'domain'});
     return if (! $self->is_default());      return if (! $self->is_default());
     my $key = join(':',($self->{'name'},$self->{'domain'},'studentcalc')).':';      my $key = join(':',($self->{'name'},$self->{'domain'},'studentcalc')).':';
     my $timekey = $key.'.time';      my $timekey = $key.'.time';
     my $newstore = join('___;___',      my $newstore = join('___;___',
                         @{$Exportrows{$student}->{'data'}});                          @{$Exportrows{$student}->{'data'}});
     $newstore = '___=___'.$newstore;      $newstore = '___=___'.$newstore;
     &Apache::lonnet::put('nohist_calculatedsheets',      my $result= &Apache::lonnet::put('nohist_calculatedsheets',
                          { $key     => $newstore,                           { $key     => $newstore,
                            $timekey => $Exportrows{$student}->{'time'} },                             $timekey => $Exportrows{$student}->{'time'} },
                          $self->{'cdom'},                           $self->{'cdom'},
Line 496  spreadsheet only if necessary. Line 760  spreadsheet only if necessary.
 #############################################  #############################################
 sub export_data {  sub export_data {
     my $self = shift;      my $self = shift;
       my ($r) = @_;
       my $connection = $r->connection();
     my $student = $self->{'name'}.':'.$self->{'domain'};      my $student = $self->{'name'}.':'.$self->{'domain'};
     if (! exists($Exportrows{$student}) ||      if (! exists($Exportrows{$student}) ||
           ! defined($Exportrows{$student}) ||
           ! exists($Exportrows{$student}->{'data'}) ||
           ! defined($Exportrows{$student}->{'data'}) ||
           ! exists($Exportrows{$student}->{'time'}) ||
           ! defined($Exportrows{$student}->{'time'}) ||
         ! $self->check_expiration_time($Exportrows{$student}->{'time'})) {          ! $self->check_expiration_time($Exportrows{$student}->{'time'})) {
         $self->compute();          $self->compute($r);
     }      }
     my @Data = @{$Exportrows{$student}->{'data'}};      if ($connection->aborted()) { $self->cleanup(); return; }
     for (my $i=0; $i<=$#Data;$i++) {      my @Data;
         $Data[$i]="'".$Data[$i]."'" if ($Data[$i]=~/\D/ && defined($Data[$i]));      if ($self->badcalc()) {
           @Data = ();
       } else {
           @Data = @{$Exportrows{$student}->{'data'}};
           for (my $i=0; $i<=$#Data;$i++) {
               if ($Data[$i]=~/\D/ && defined($Data[$i])) {
                   $Data[$i]="'".$Data[$i]."'";
               }
           }
     }      }
     return @Data;      return @Data;
 }  }

Removed from v.1.3  
changed lines
  Added in v.1.45


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.