--- loncom/interface/Attic/lonspreadsheet.pm	2002/10/24 14:34:07	1.125
+++ loncom/interface/Attic/lonspreadsheet.pm	2002/10/30 15:07:20	1.131
@@ -1,5 +1,5 @@
 #
-# $Id: lonspreadsheet.pm,v 1.125 2002/10/24 14:34:07 matthew Exp $
+# $Id: lonspreadsheet.pm,v 1.131 2002/10/30 15:07:20 matthew Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -828,9 +828,11 @@ sub expandnamed {
         foreach $parameter (keys(%c)) {
             push @matches,$parameter if ($parameter =~ /$expression/);
         }
-        if ($#matches == 0) {
+        if (scalar(@matches) == 0) {
+            $returnvalue = 'unmatched parameter: '.$parameter;
+        } elsif (scalar(@matches) == 1) {
             $returnvalue = '$c{\''.$matches[0].'\'}';
-        } elsif ($#matches > 0) {
+        } elsif (scalar(@matches) > 0) {
             # more than one match.  Look for a concise one
             $returnvalue =  "'non-unique parameter name : $expression'";
             foreach (@matches) {
@@ -839,7 +841,9 @@ sub expandnamed {
                 }
             }
         } else {
-            $returnvalue =  "'bad parameter name : $expression'";
+            # There was a negative number of matches, which indicates 
+            # something is wrong with reality.  Better warn the user.
+            $returnvalue = 'bizzare parameter: '.$parameter;
         }
         return $returnvalue;
     }
@@ -946,8 +950,7 @@ ENDDEFS
 }
 
 #
-# This is actually used for the student spreadsheet, not the assessment sheet
-# Do not be fooled by the name!
+#
 #
 sub templaterow {
     my $sheet = shift;
@@ -1042,11 +1045,6 @@ sub setconstants {
         $constants = \%tmp;
     }
     $sheet->{'constants'} = $constants;
-    &Apache::lonnet::logthis("----------------------------------");
-    foreach my $c (keys(%{$sheet->{'constants'}})) {
-        &Apache::lonnet::logthis('constant '.$c.' = '.
-                                 $sheet->{'constants'}->{$c});
-    }
     return %{$sheet->{'safe'}->varglob('c')}=%{$sheet->{'constants'}};
 }
 
@@ -1079,6 +1077,7 @@ sub calcsheet {
 }
 
 # ---------------------------------------------------------------- Get formulas
+# Return a copy of the formulas
 sub getformulas {
     my $sheet = shift;
     return %{$sheet->{'safe'}->varglob('f')};
@@ -1097,7 +1096,11 @@ sub exportdata {
     my @exportarray=();
     foreach ('A','B','C','D','E','F','G','H','I','J','K','L','M',
 	     'N','O','P','Q','R','S','T','U','V','W','X','Y','Z') {
-	push(@exportarray,$sheet->{'values'}->{$_.'0'});
+        if (exists($sheet->{'values'}->{$_.'0'})) {
+            push(@exportarray,$sheet->{'values'}->{$_.'0'});
+        } else {
+            push(@exportarray,'');
+        }
     } 
     return @exportarray;
 }
@@ -1237,6 +1240,8 @@ sub outsheet {
     # Prepare to output rows
     my $row;
     #
+    # Sort the rows in some manner
+    #
     my @sortby=();
     my @sortidx=();
     for ($row=1;$row<=$sheet->{'maxrow'};$row++) {
@@ -1450,31 +1455,19 @@ sub writesheet {
         # Cache new sheet
         $spreadsheets{$cnum.'_'.$cdom.'_'.$stype.'_'.$fn}=join('___;___',%f);
         # Write sheet
-        my $sheetdata='';
         foreach (keys(%f)) {
-            unless ($f{$_} eq 'import') {
-                $sheetdata.=&Apache::lonnet::escape($_).'='.
-                    &Apache::lonnet::escape($f{$_}).'&';
-            }
+            delete($f{$_}) if ($f{$_} eq 'import');
         }
-        $sheetdata=~s/\&$//;
-        my $reply=&Apache::lonnet::reply('put:'.$cdom.':'.$cnum.':'.$fn.':'.
-                                         $sheetdata,$chome);
+        my $reply = &Apache::lonnet::put($fn,\%f,$cdom,$cnum);
         if ($reply eq 'ok') {
-            $reply=&Apache::lonnet::reply('put:'.$cdom.':'.$cnum.':'.
-                                          $stype.'_spreadsheets:'.
-                                          &Apache::lonnet::escape($fn).
-                                          '='.$ENV{'user.name'}.'@'.
-                                          $ENV{'user.domain'},
-                                          $chome);
+            $reply = &Apache::lonnet::put($stype.'_spreadsheets',
+                            {$fn => $ENV{'user.name'}.'@'.$ENV{'user.domain'}},
+                                          $cdom,$cnum);
             if ($reply eq 'ok') {
                 if ($makedef) { 
-                    return &Apache::lonnet::reply('put:'.$cdom.':'.$cnum.
-                                                  ':environment:'.
-                                                  'spreadsheet_default_'.
-                                                  $stype.'='.
-                                                  &Apache::lonnet::escape($fn),
-                                                  $chome);
+                    return &Apache::lonnet::put('environment',
+                                  {'spreadsheet_default_'.$stype => $fn },
+                                                $cdom,$cnum);
                 } 
                 return $reply;
             } 
@@ -1527,7 +1520,7 @@ sub tmpread {
         }
     }
     if ($nform eq 'changesheet') {
-        $fo{'A'.$nfield}=(split(/\_\_\&\&\&\_\_/,$fo{'A'.$nfield}))[0];
+        $fo{'A'.$nfield}=(split(/__&&&\__/,$fo{'A'.$nfield}))[0];
         unless ($ENV{'form.sel_'.$nfield} eq 'Default') {
 	    $fo{'A'.$nfield}.='__&&&__'.$ENV{'form.sel_'.$nfield};
         }
@@ -1631,7 +1624,7 @@ sub format_rowlabel {
         if ($ENV{'form.showcsv'}) {
             $result = $title;
         } else {
-            $result = '<a href="/adm/assesscalc?usmb='.$symb.
+            $result = '<a href="/adm/assesscalc?usymb='.$symb.
                 '&uname='.$uname.'&udom='.$udom.'">'.$title.'</a>';
         }
     } elsif ($type eq 'student') {
@@ -1646,10 +1639,9 @@ sub format_rowlabel {
         }
     } elsif ($type eq 'parameter') {
         if ($ENV{'form.showcsv'}) {
-            $result = $labeldata =~ s/<br>//g;
-        } else {
-            $result = $labeldata;
+            $labeldata =~ s/<br>/ /g;
         }
+        $result = $labeldata;
     } else {
         &Apache::lonnet::logthis("lonspreadsheet:bogus rowlabel type: $type");
     }
@@ -1708,11 +1700,11 @@ sub updateclasssheet {
     }
     #
     # New and unknown keys
-    foreach (sort keys(%currentlist)) {
-        unless ($existing{$_}) {
+    foreach my $student (sort keys(%currentlist)) {
+        unless ($existing{$student}) {
             $changed=1;
             $sheet->{'maxrow'}++;
-            $f{'A'.$sheet->{'maxrow'}}=$_;
+            $f{'A'.$sheet->{'maxrow'}}=$student;
         }
     }
     if ($changed) { 
@@ -1726,45 +1718,42 @@ sub updateclasssheet {
 # ----------------------------------- Update rows for student and assess sheets
 sub updatestudentassesssheet {
     my ($sheet) = @_;
+    #
     my %bighash;
-    my $stype=$sheet->{'sheettype'};
-    my $uname=$sheet->{'uname'};
-    my $udom =$sheet->{'udom'};
+    #
+    my $stype = $sheet->{'sheettype'};
+    my $uname = $sheet->{'uname'};
+    my $udom  = $sheet->{'udom'};
     $sheet->{'rowlabel'} = {};
-    if  ($updatedata
-         {$ENV{'request.course.fn'}.'_'.$stype.'_'.$uname.'_'.$udom}) {
-        %{$sheet->{'rowlabel'}}=split(/___;___/,
-                       $updatedata{$ENV{'request.course.fn'}.
-                                       '_'.$stype.'_'.$uname.'_'.$udom});
+    my $identifier =$sheet->{'coursefilename'}.'_'.$stype.'_'.$uname.'_'.$udom;
+    if  ($updatedata{$identifier}) {
+        %{$sheet->{'rowlabel'}}=split(/___;___/,$updatedata{$identifier});
     } else {
         # Tie hash
-        tie(%bighash,'GDBM_File',$ENV{'request.course.fn'}.'.db',
+        tie(%bighash,'GDBM_File',$sheet->{'coursefilename'}.'.db',
             &GDBM_READER(),0640);
         if (! tied(%bighash)) {
             return 'Could not access course data';
         }
         # Get all assessments
         #
-        # allkeys is used in the assessment sheets to provide labels
+        # parameter_labels is used in the assessment sheets to provide labels
         # for the parameters.
-        my %allkeys=('timestamp' => 
-                     'parameter:Timestamp of Last Transaction<br>timestamp',
-                     'subnumber' =>
-                     'parameter:Number of Submissions<br>subnumber',
-                     'tutornumber' =>
-                     'parameter:Number of Tutor Responses<br>tutornumber',
-                     'totalpoints' =>
-                     'parameter:Total Points Granted<br>totalpoints');
-        my $adduserstr='';
-        if (($uname ne $ENV{'user.name'}) || ($udom ne $ENV{'user.domain'})){
-            $adduserstr='&uname='.$uname.'&udom='.$udom;
-        }
+        my %parameter_labels=
+            ('timestamp' => 
+                 'parameter:Timestamp of Last Transaction<br>timestamp',
+             'subnumber' =>
+                 'parameter:Number of Submissions<br>subnumber',
+             'tutornumber' =>
+                 'parameter:Number of Tutor Responses<br>tutornumber',
+             'totalpoints' =>
+                 'parameter:Total Points Granted<br>totalpoints');
         #
-        # allassess holds the descriptions of all assessments
-        my %allassess;
+        # assesslist holds the descriptions of all assessments
+        my %assesslist;
         foreach ('Feedback','Evaluation','Tutoring','Discussion') {
             my $symb = '_'.lc($_);
-            $allassess{$symb} = join(':',('symb',$symb,$uname,$udom,$_));
+            $assesslist{$symb} = join(':',('symb',$symb,$uname,$udom,$_));
         }
         while (($_,undef) = each(%bighash)) {
             next if ($_!~/^src\_(\d+)\.(\d+)$/);
@@ -1776,7 +1765,7 @@ sub updatestudentassesssheet {
                 my $symb=
                     &Apache::lonnet::declutter($bighash{'map_id_'.$mapid}).
                         '___'.$resid.'___'.&Apache::lonnet::declutter($srcf);
-                $allassess{$symb}='symb:'.&Apache::lonnet::escape($symb).':'
+                $assesslist{$symb}='symb:'.&Apache::lonnet::escape($symb).':'
                     .$uname.':'.$udom.':'.$bighash{'title_'.$id};
                 next if ($stype ne 'assesscalc');
                 foreach my $key (split(/\,/,
@@ -1790,22 +1779,24 @@ sub updatestudentassesssheet {
                             &Apache::lonnet::metadata($srcf,$key.'.name');
                     }
                     $display.='<br>'.$key;
-                    $allkeys{$key}='parameter:'.$display;
+                    $parameter_labels{$key}='parameter:'.$display;
                 } # end of foreach
             }
         } # end of foreach (keys(%bighash))
         untie(%bighash);
         #
-        # %allkeys has a list of storage and parameter displays by unikey
-        # %allassess has a list of all resource displays by symb
+        # %parameter_labels has a list of storage and parameter displays by 
+        # unikey
+        # %assesslist has a list of all resource, by symb
         #
         if ($stype eq 'assesscalc') {
-            $sheet->{'rowlabel'} = \%allkeys;
+            $sheet->{'rowlabel'} = \%parameter_labels;
         } elsif ($stype eq 'studentcalc') {
-            $sheet->{'rowlabel'} = \%allassess;
+            $sheet->{'rowlabel'} = \%assesslist;
         }
-        $updatedata{$ENV{'request.course.fn'}.'_'.$stype.'_'.$uname.'_'.$udom}=
-            join('___;___',%{$sheet->{'rowlabel'}});
+        $updatedata{$sheet->{'coursefilename'}.'_'.$stype.'_'
+                        .$uname.'_'.$udom}=
+                            join('___;___',%{$sheet->{'rowlabel'}});
         # Get current from cache
     }
     # Find discrepancies between the course row table and this
@@ -1872,7 +1863,7 @@ sub loadstudent {
         my $row=$1;
         next if (($f{$_}=~/^[\!\~\-]/) || ($row==0));
         my ($usy,$ufn)=split(/__&&&\__/,$f{$_});
-        @assessdata=&exportsheet($sheet->{'uname'},
+        @assessdata=&exportsheet($sheet,$sheet->{'uname'},
                                  $sheet->{'udom'},
                                  'assesscalc',$usy,$ufn);
         my $index=0;
@@ -1929,8 +1920,8 @@ ENDPOP
 	next if ($_!~/^A(\d+)/);
         my $row=$1;
         next if (($f{$_}=~/^[\!\~\-]/)  || ($row==0));
-        my @studentdata=&exportsheet(split(/\:/,$f{$_}),
-                                     'studentcalc');
+        my ($sname,$sdom) = split(':',$f{$_});
+        my @studentdata=&exportsheet($sheet,$sname,$sdom,'studentcalc');
         undef %userrdatas;
         $now++;
         $r->print('<script>popwin.document.popremain.remaining.value="'.
@@ -1941,7 +1932,7 @@ ENDPOP
         my $index=0;
         foreach ('A','B','C','D','E','F','G','H','I','J','K','L','M',
                  'N','O','P','Q','R','S','T','U','V','W','X','Y','Z') {
-            if ($studentdata[$index]) {
+            if (defined($studentdata[$index++])) {
                 my $col=$_;
                 if ($studentdata[$index]=~/\D/) {
                     $c{$col.$row}="'".$studentdata[$index]."'";
@@ -1951,7 +1942,6 @@ ENDPOP
                 unless ($col eq 'A') { 
                     $f{$col.$row}='import';
                 }
-                $index++;
             }
         }
     }
@@ -2173,8 +2163,14 @@ sub forcedrecalc {
 }
 
 # ============================================================== Export handler
+# exportsheet
+# returns the export row for a spreadsheet.
+#
 sub exportsheet {
-    my ($uname,$udom,$stype,$usymb,$fn)=@_;
+    my ($sheet,$uname,$udom,$stype,$usymb,$fn)=@_;
+    $uname = $uname || $sheet->{'uname'};
+    $udom  = $udom  || $sheet->{'udom'};
+    $stype = $stype || $sheet->{'sheettype'};
     my @exportarr=();
     if (defined($usymb) && ($usymb=~/^\_(\w+)/) && (!$fn)) {
         $fn='default_'.$1;
@@ -2193,7 +2189,7 @@ sub exportsheet {
         }
     }
     unless ($found) {
-        &cachedssheets($uname,$udom,&Apache::lonnet::homeserver($uname,$udom));
+        &cachedssheets($sheet,$uname,$udom);
         if ($oldsheets{$key}) {
             foreach (split(/___&\___/,$oldsheets{$key})) {
                 my ($name,$value)=split(/___=___/,$_);
@@ -2221,53 +2217,55 @@ sub exportsheet {
     #
     # Not cached
     #        
-    my ($sheet)=&makenewsheet($uname,$udom,$stype,$usymb);
-    &readsheet($sheet,$fn);
-    &updatesheet($sheet);
-    &loadrows($sheet);
-    &calcsheet($sheet); 
-    @exportarr=&exportdata($sheet);
+    my ($newsheet)=&makenewsheet($uname,$udom,$stype,$usymb);
+    &readsheet($newsheet,$fn);
+    &updatesheet($newsheet);
+    &loadrows($newsheet);
+    &calcsheet($newsheet); 
+    @exportarr=&exportdata($newsheet);
+    ##
+    ## Store now
+    ##
     #
-    # Store now
+    # load in the old value
     #
-    my $cid=$ENV{'request.course.id'}; 
-    my $current='';
-    if ($stype eq 'studentcalc') {
-        $current=&Apache::lonnet::reply('get:'.
-                                        $ENV{'course.'.$cid.'.domain'}.':'.
-                                        $ENV{'course.'.$cid.'.num'}.
-                                        ':nohist_calculatedsheets:'.
-                                        &Apache::lonnet::escape($key),
-                                        $ENV{'course.'.$cid.'.home'});
-    } else {
-        $current=&Apache::lonnet::reply('get:'.$sheet->{'udom'}.':'.
-                                        $sheet->{'uname'}.
-                                        ':nohist_calculatedsheets_'.
-                                        $ENV{'request.course.id'}.':'.
-                                        &Apache::lonnet::escape($key),
-                                        $sheet->{'uhome'});
-    }
     my %currentlystored=();
-    unless ($current=~/^error\:/) {
-        foreach (split(/___&\___/,&Apache::lonnet::unescape($current))) {
-            my ($name,$value)=split(/___=___/,$_);
-            $currentlystored{$name}=$value;
+    if ($stype eq 'studentcalc') {
+        my @tmp = &Apache::lonnet::get('nohist_calculatedsheets',
+                                       [$key],
+                                       $sheet->{'cdom'},$sheet->{'cnum'});
+        if ($tmp[0]!~/^error/) {
+            %currentlystored = @tmp;
+        }
+    } else {
+        my @tmp = &Apache::lonnet::get('nohist_calculatedsheets_'.
+                                       $sheet->{'cid'},[$key],
+                                       $sheet->{'udom'},$sheet->{'uname'});
+        if ($tmp[0]!~/^error/) {
+            %currentlystored = @tmp;
         }
     }
+    #
+    # Add the new line
+    #
     $currentlystored{$fn}=join('___;___',@exportarr);
     #
+    # Stick everything back together
+    #
     my $newstore='';
     foreach (keys(%currentlystored)) {
         if ($newstore) { $newstore.='___&___'; }
         $newstore.=$_.'___=___'.$currentlystored{$_};
     }
     my $now=time;
+    #
+    # Store away the new value
+    #
     if ($stype eq 'studentcalc') {
         &Apache::lonnet::put('nohist_calculatedsheets',
                              { $key => $newstore,
                                $key.time => $now },
-                             $ENV{'course.'.$cid.'.domain'},
-                             $ENV{'course.'.$cid.'.num'})
+                             $sheet->{'cdom'},$sheet->{'cnum'});
     } else {
         &Apache::lonnet::put('nohist_calculatedsheets_'.$sheet->{'cid'},
                              { $key => $newstore,
@@ -2285,17 +2283,11 @@ sub exportsheet {
 sub expirationdates {
     undef %expiredates;
     my $cid=$ENV{'request.course.id'};
-    my $reply=&Apache::lonnet::reply('dump:'.
-				     $ENV{'course.'.$cid.'.domain'}.':'.
-                                     $ENV{'course.'.$cid.'.num'}.
-				     ':nohist_expirationdates',
-                                     $ENV{'course.'.$cid.'.home'});
-    unless ($reply=~/^error\:/) {
-	foreach (split(/\&/,$reply)) {
-            my ($name,$value)=split(/\=/,$_);
-            $expiredates{&Apache::lonnet::unescape($name)}
-                        =&Apache::lonnet::unescape($value);
-        }
+    my @tmp = &Apache::lonnet::dump('nohist_expirationdates',
+                                    $ENV{'course.'.$cid.'.domain'},
+                                    $ENV{'course.'.$cid.'.num'});
+    if (lc($tmp[0])!~/^error/){
+        %expiredates = @tmp;
     }
 }
 
@@ -2306,16 +2298,13 @@ sub expirationdates {
 
 sub cachedcsheets {
     my $cid=$ENV{'request.course.id'};
-    my $reply=&Apache::lonnet::reply('dump:'.
-				     $ENV{'course.'.$cid.'.domain'}.':'.
-                                     $ENV{'course.'.$cid.'.num'}.
-				     ':nohist_calculatedsheets',
-                                     $ENV{'course.'.$cid.'.home'});
-    unless ($reply=~/^error\:/) {
-	foreach ( split(/\&/,$reply)) {
-            my ($name,$value)=split(/\=/,$_);
-            $oldsheets{&Apache::lonnet::unescape($name)}
-                      =&Apache::lonnet::unescape($value);
+    my @tmp = &Apache::lonnet::dump('nohist_calculatedsheets',
+                                    $ENV{'course.'.$cid.'.domain'},
+                                    $ENV{'course.'.$cid.'.num'});
+    if ($tmp[0] !~ /^error/) {
+        my %StupidTempHash = @tmp;
+        while (my ($key,$value) = each %StupidTempHash) {
+            $oldsheets{$key} = $value;
         }
     }
 }
@@ -2326,22 +2315,21 @@ sub cachedcsheets {
 #
 
 sub cachedssheets {
-  my ($sname,$sdom,$shome)=@_;
-  unless (($loadedcaches{$sname.'_'.$sdom}) || ($shome eq 'no_host')) {
-    my $cid=$ENV{'request.course.id'};
-    my $reply=&Apache::lonnet::reply('dump:'.$sdom.':'.$sname.
-			             ':nohist_calculatedsheets_'.
-                                      $ENV{'request.course.id'},
-                                     $shome);
-    unless ($reply=~/^error\:/) {
-	foreach ( split(/\&/,$reply)) {
-            my ($name,$value)=split(/\=/,$_);
-            $oldsheets{&Apache::lonnet::unescape($name)}
-                      =&Apache::lonnet::unescape($value);
+    my ($sheet,$uname,$udom) = @_;
+    $uname = $uname || $sheet->{'uname'};
+    $udom  = $udom  || $sheet->{'udom'};
+    if (! $loadedcaches{$sheet->{'uname'}.'_'.$sheet->{'udom'}}) {
+        my @tmp = &Apache::lonnet::dump('nohist_calculatedsheets',
+                                        $sheet->{'udom'},
+                                        $sheet->{'uname'});
+        if ($tmp[0] !~ /^error/) {
+            my %StupidTempHash = @tmp;
+            while (my ($key,$value) = each %StupidTempHash) {
+                $oldsheets{$key} = $value;
+            }
+            $loadedcaches{$sheet->{'uname'}.'_'.$sheet->{'udom'}}=1;
         }
     }
-    $loadedcaches{$sname.'_'.$sdom}=1;
-  }
 }
 
 # ===================================================== Calculated sheets cache
@@ -2556,7 +2544,7 @@ ENDSCRIPT
     } elsif ($sheet->{'sheettype'} eq 'studentcalc') {
         $r->print("Loading previously calculated assessment sheets ...\n");
         $r->rflush();
-        &cachedssheets($sheet->{'uname'},$sheet->{'udom'},$sheet->{'uhome'});
+        &cachedssheets($sheet);
     }
     # Update sheet, load rows
     $r->print("Loaded sheet(s), updating rows ...<br>\n");
@@ -2604,7 +2592,7 @@ ENDSCRIPT
     } else {
         unless ($ENV{'form.userselhidden'}) {
             unless 
-                ($ENV{'course.'.$ENV{'request.course.id'}.'.hideemptyrows'} eq 'yes') {
+                ($ENV{'course.'.$sheet->{'cid'}.'.hideemptyrows'} eq 'yes') {
                     $r->print(' checked');
                     $ENV{'form.showall'}=1;
                 }