Diff for /loncom/homework/grades.pm between versions 1.38 and 1.41

version 1.38, 2002/07/10 21:08:38 version 1.41, 2002/07/25 21:25:38
Line 42  use Apache::loncommon; Line 42  use Apache::loncommon;
 use Apache::lonhomework;  use Apache::lonhomework;
 use Apache::lonmsg qw(:user_normal_msg);  use Apache::lonmsg qw(:user_normal_msg);
 use Apache::Constants qw(:common);  use Apache::Constants qw(:common);
 use Time::HiRes qw( gettimeofday tv_interval );  #use Time::HiRes qw( gettimeofday tv_interval );
   
 sub moreinfo {  sub moreinfo {
   my ($request,$reason) = @_;      my ($request,$reason) = @_;
   $request->print("Unable to process request: $reason");      $request->print("Unable to process request: $reason");
   if ( $Apache::grades::viewgrades eq 'F' ) {      if ( $Apache::grades::viewgrades eq 'F' ) {
     $request->print('<form action="/adm/grades" method="post">'."\n");   $request->print('<form action="/adm/grades" method="post">'."\n");
     if ($ENV{'form.url'}) {   if ($ENV{'form.url'}) {
       $request->print('<input type="hidden" name="url" value="'.$ENV{'form.url'}.'" />'."\n");      $request->print('<input type="hidden" name="url" value="'.$ENV{'form.url'}.'" />'."\n");
     }   }
     if ($ENV{'form.symb'}) {   if ($ENV{'form.symb'}) {
       $request->print('<input type="hidden" name="symb" value="'.$ENV{'form.symb'}.'" />'."\n");      $request->print('<input type="hidden" name="symb" value="'.$ENV{'form.symb'}.'" />'."\n");
     }   }
 #    $request->print('<input type="hidden" name="command" value="submission" />'."\n");  #    $request->print('<input type="hidden" name="command" value="submission" />'."\n");
     $request->print('<input type="hidden" name="command" value="'.$ENV{'form.command'}.'" />'."\n");   $request->print('<input type="hidden" name="command" value="'.$ENV{'form.command'}.'" />'."\n");
     $request->print("Student:".'<input type="text" name="student" value="'.$ENV{'form.student'}.'" />'."<br />\n");   $request->print("Student:".'<input type="text" name="student" value="'.$ENV{'form.student'}.'" />'."<br />\n");
     $request->print("Domain:".'<input type="text" name="domain" value="'.$ENV{'user.domain'}.'" />'."<br />\n");   $request->print("Domain:".'<input type="text" name="domain" value="'.$ENV{'user.domain'}.'" />'."<br />\n");
     $request->print('<input type="submit" name="submit" value="ReSubmit" />'."<br />\n");   $request->print('<input type="submit" name="submit" value="ReSubmit" />'."<br />\n");
     $request->print('</form>');   $request->print('</form>');
   }      }
   return '';      return '';
 }  }
   
 sub verifyreceipt {  sub verifyreceipt {
Line 71  sub verifyreceipt { Line 71  sub verifyreceipt {
 #    my $cdom=$ENV{"course.$courseid.domain"};  #    my $cdom=$ENV{"course.$courseid.domain"};
 #    my $cnum=$ENV{"course.$courseid.num"};  #    my $cnum=$ENV{"course.$courseid.num"};
     my $receipt=unpack("%32C*",$Apache::lonnet::perlvar{'lonHostID'}).'-'.      my $receipt=unpack("%32C*",$Apache::lonnet::perlvar{'lonHostID'}).'-'.
                 $ENV{'form.receipt'};   $ENV{'form.receipt'};
     $receipt=~s/[^\-\d]//g;      $receipt=~s/[^\-\d]//g;
     my $symb=$ENV{'form.symb'};      my $symb=$ENV{'form.symb'};
     unless ($symb) {      unless ($symb) {
Line 84  sub verifyreceipt { Line 84  sub verifyreceipt {
         foreach my $student ( sort(@{ $$classlist{'all'} }) ) {          foreach my $student ( sort(@{ $$classlist{'all'} }) ) {
             my ($uname,$udom)=split(/\:/,$student);              my ($uname,$udom)=split(/\:/,$student);
             if ($receipt eq               if ($receipt eq 
              &Apache::lonnet::ireceipt($uname,$udom,$courseid,$symb)) {   &Apache::lonnet::ireceipt($uname,$udom,$courseid,$symb)) {
                $request->print('Matching '.$student.'<br>');   $request->print('Matching '.$student.'<br>');
                $matches++;   $matches++;
    }     }
         }          }
         $request->printf('<p>'.$matches." match%s</p>",$matches <= 1 ? '' : 'es');          $request->printf('<p>'.$matches." match%s</p>",$matches <= 1 ? '' : 'es');
Line 96  sub verifyreceipt { Line 96  sub verifyreceipt {
 }  }
   
 sub student_gradeStatus {  sub student_gradeStatus {
   my ($url,$udom,$uname) = @_;      my ($url,$udom,$uname,$partlist) = @_;
   my $symb=($ENV{'form.symb'} ne '' ? $ENV{'form.symb'} : (&Apache::lonnet::symbread($url)));      my $symb=($ENV{'form.symb'} ne '' ? $ENV{'form.symb'} : (&Apache::lonnet::symbread($url)));
   my %record= &Apache::lonnet::restore($symb,$ENV{'request.course.id'},$udom,$uname);      my %record= &Apache::lonnet::restore($symb,$ENV{'request.course.id'},$udom,$uname);
   foreach my $part (&getpartlist($url)) {      my %partstatus = ();
     my ($temp,$part,$type)=split(/_/,$part);      foreach (@$partlist) {
     if ($type eq 'solved') {   my ($status,$foo)=split(/_/,$record{"resource.$_.solved"},2);
       my ($status,$foo)=split(/_/,$record{"resource.$part.$type"},2);   $status = 'nothing' if ($status eq '');
       $status = 'partial' if ($foo =~ /^partially/);   $partstatus{$_} = $status;
       $status = 'nothing' if ($status eq '');   $partstatus{"resource.$_.submitted_by"} = $record{"resource.$_.submitted_by"} 
       return $type,$status;   if ($record{"resource.$_.submitted_by"} ne '');
     }      }
   }      return %partstatus;
   return '';  
 }  }
   
 sub get_fullname {  sub get_fullname {
     my ($sname,$sdom) = @_;      my ($uname,$udom) = @_;
     my %name=&Apache::lonnet::get('environment', ['lastname','generation',      my %name=&Apache::lonnet::get('environment', ['lastname','generation',
   'firstname','middlename'],    'firstname','middlename'],$udom,$uname);
   $sdom,$sname);  
     my $fullname;      my $fullname;
     my ($tmp) = keys(%name);      my ($tmp) = keys(%name);
     if ($tmp !~ /^(con_lost|error|no_such_host)/i) {      if ($tmp !~ /^(con_lost|error|no_such_host)/i) {
Line 126  sub get_fullname { Line 124  sub get_fullname {
     return $fullname;      return $fullname;
 }  }
   
   sub response_type {
       my ($url) = shift;
       my $allkeys = &Apache::lonnet::metadata($url,'keys');
   #    print "allkeys=>$allkeys<br>";
       my %seen = ();
       my (@partlist,%handgrade);
       foreach (split(/,/,&Apache::lonnet::metadata($url,'packages'))) {
    if (/^\w+response_\d{1,2}.*/) {
       my ($responsetype,$part) = split(/_/,$_,2);
       my ($partid,$respid) = split(/_/,$part);
       $handgrade{$part} = $responsetype.':'.($allkeys =~ /parameter_$part\_handgrade/ ? 'yes' : 'no');
       next if ($seen{$partid} > 0);
       $seen{$partid}++;
       push @partlist,$partid;
    }
       }
       return \@partlist,\%handgrade;
   }
   
   
 sub listStudents {  sub listStudents {
   my ($request) = shift;      my ($request) = shift;
   my $cdom      =$ENV{"course.$ENV{'request.course.id'}.domain"};      my $cdom      =$ENV{"course.$ENV{'request.course.id'}.domain"};
   my $cnum      =$ENV{"course.$ENV{'request.course.id'}.num"};      my $cnum      =$ENV{"course.$ENV{'request.course.id'}.num"};
   my $getsec    =$ENV{'form.section'};      my $getsec    =$ENV{'form.section'} eq '' ? 'all' : $ENV{'form.section'};
   my $submitonly=$ENV{'form.submitonly'};      my $submitonly=$ENV{'form.submitonly'} eq '' ? 'all' : $ENV{'form.submitonly'};
   
   $request->print(<<ENDTABLEST);      my $result='<h2><font color="#339933">&nbsp;View Submissions for a Student or a Group of Students</font></h2>';
 <h2><font color="#339933">&nbsp;View Submissions for a Student or a Group of Students</font></h2>      $result.='<table border="0">';
 &nbsp;<font size=+1><b>Resource:</b> $ENV{'form.url'}<br /><br />      $result.='<tr><td colspan=3><font size=+1><b>Resource: </b>'.$ENV{'form.url'}.'</font></td></tr>';
 <form action="/adm/grades" method="post">&nbsp;<b>View Options</b></font><br />      my ($partlist,$handgrade) = &response_type($ENV{'form.url'});
       for (sort keys(%$handgrade)) {
    my ($responsetype,$handgrade)=split(/:/,$$handgrade{$_});
    $ENV{'form.handgrade'} = 'yes' if ($handgrade eq 'yes');
    $result.='<tr><td><b>Part id: </b>'.$_.'</td>'.
       '<td><b>Type: </b>'.$responsetype.'</td>'.
       '<td><b>Handgrade: </b>'.$handgrade.'</font></td></tr>';
       }
       $result.='</table>';
       $request->print($result);
   
       $request->print(<<ENDTABLEST);
   <form action="/adm/grades" method="post">
 &nbsp;<b>View Problem: </b><input type="radio" name="vProb" value="no" checked> no   &nbsp;<b>View Problem: </b><input type="radio" name="vProb" value="no" checked> no 
 <input type="radio" name="vProb" value="yes"> yes <br />  <input type="radio" name="vProb" value="yes"> yes <br />
 &nbsp;<b>Submissions: </b>  &nbsp;<b>Submissions: </b>
 <input type="radio" name="lastSub" value="lastonly" checked> last sub only  <input type="radio" name="lastSub" value="hdgrade" checked /> handgrade only
 <input type="radio" name="lastSub" value="last"> last sub & parts info  <input type="radio" name="lastSub" value="lastonly" /> last sub only
 <input type="radio" name="lastSub" value="all"> all details  <input type="radio" name="lastSub" value="last" /> last sub & parts info
 <input type="hidden" name="section" value="$getsec">  <input type="radio" name="lastSub" value="all" /> all details
 <input type="hidden" name="submitonly" value="$submitonly">  <input type="hidden" name="section" value="$getsec" />
 <input type="hidden" name="response" value="$ENV{'form.response'}">  <input type="hidden" name="submitonly" value="$submitonly" />
 <input type="hidden" name="handgrade" value="$ENV{'form.handgrade'}">  <input type="hidden" name="response" value="$ENV{'form.response'}" />
 <table border="0"><tr><td bgcolor="#777777">  <input type="hidden" name="handgrade" value="$ENV{'form.handgrade'}" /><br />
 <table border="0"><tr bgcolor="#e6ffff">  <input type="hidden" name="showgrading" value="$ENV{'form.showgrading'}" /><br />
 <td><b>&nbsp;Select&nbsp;</b></td><td><b>&nbsp;Username&nbsp;</b></td>  <input type="submit" name="submit" value="View/Grade" />
 <td><b>&nbsp;Fullname&nbsp;</b></td><td><b>&nbsp;Domain&nbsp;</b></td>  
 <td><b>&nbsp;Grade Status&nbsp;</b></td></tr>  
 ENDTABLEST  ENDTABLEST
   if ($ENV{'form.url'}) {      if ($ENV{'form.url'}) {
       $request->print('<input type="hidden" name="url" value="'.$ENV{'form.url'}.'" />'."\n");   $request->print('<input type="hidden" name="url" value="'.$ENV{'form.url'}.'" />'."\n");
   }      }
   if ($ENV{'form.symb'}) {      if ($ENV{'form.symb'}) {
       $request->print('<input type="hidden" name="symb" value="'.$ENV{'form.symb'}.'" />'."\n");   $request->print('<input type="hidden" name="symb" value="'.$ENV{'form.symb'}.'" />'."\n");
   }      }
   $request->print('<input type="hidden" name="command" value="processGroup" />'."\n");      $request->print('<input type="hidden" name="command" value="processGroup" />'."\n");
       
   my $t0=&Time::HiRes::time();      my ($classlist,$seclist,$ids,$stusec,$fullname) = &getclasslist($getsec,'0');
       
   my ($classlist) = &getclasslist($getsec,'0');      $result='<table border="0"><tr><td bgcolor="#777777">'.
   my $t1=&Time::HiRes::time();   '<table border="0"><tr bgcolor="#e6ffff">'.
   print "getclasslist=",$t1-$t0,"<br />";   '<td><b>&nbsp;Select&nbsp;</b></td><td><b>&nbsp;Username&nbsp;</b></td>'.
    '<td><b>&nbsp;Fullname&nbsp;</b></td><td><b>&nbsp;Domain&nbsp;</b></td>';
   foreach my $student ( sort(@{ $$classlist{$getsec} }) ) {      foreach (sort(@$partlist)) {
       my ($sname,$sdom) = split(/:/,$student);   $result.='<td><b>&nbsp;Part ID '.$_.' Status&nbsp;</b></td>';
       my ($type,$status) = &student_gradeStatus($ENV{'form.url'},$cdom,$sname);      }
       next if ($status eq 'nothing' && $submitonly eq 'yes');      $request->print($result.'</tr>'."\n");
   
       my $fullname = &get_fullname($sname,$sdom);      foreach my $student (sort(@{ $$classlist{$getsec} }) ) {
       if ( $Apache::grades::viewgrades eq 'F' ) {   my ($uname,$udom) = split(/:/,$student);
   $request->print("\n".'<tr bgcolor="#ffffe6">'.   my (%status) = &student_gradeStatus($ENV{'form.url'},$udom,$uname,$partlist);
   '<td align="center"><input type=checkbox name="stuinfo" value="'.   my $statusflg = '';
   $student.':'.$fullname.'"></td>'."\n".   foreach (keys(%status)) {
   '<td>&nbsp;'.$sname.'&nbsp;</td>'."\n".      $statusflg = 1 if ($status{$_} ne 'nothing');
   '<td>&nbsp;'.$fullname.'&nbsp;</td>'."\n".      my ($foo,$partid,$foo) = split(/\./,$_);
   '<td align="middle">&nbsp;'.$sdom.'&nbsp;</td>'."\n");      if ($status{'resource.'.$partid.'.submitted_by'} ne '') {
   $request->print('<td align="middle">&nbsp;'.$status.'&nbsp;</td>'."\n");   $statusflg = '';
    $request->print('<input type="hidden" name="'.
    $student.':submitted_by" value="'.
    $status{'resource.'.$partid.'.submitted_by'}.'" />');
       }
    }
    next if ($statusflg eq '' && $submitonly eq 'yes');
   
   $request->print('</tr>');   if ( $Apache::grades::viewgrades eq 'F' ) {
       }      $result='<tr bgcolor="#ffffe6">'.
   }   '<td align="center"><input type=checkbox name="stuinfo" value="'.
   my $t2=&Time::HiRes::time();   $student.':'.$$fullname{$student}.'"></td>'."\n".
   print "processclasslist=",$t2-$t1,"<br />";   '<td>&nbsp;'.$uname.'&nbsp;</td>'."\n".
   $request->print('</table></td></tr></table>');   '<td>&nbsp;'.$$fullname{$student}.'&nbsp;</td>'."\n".
   $request->print('<input type="submit" name="submit" value="View/Grade" /><form />');   '<td align="middle">&nbsp;'.$udom.'&nbsp;</td>'."\n";
       
       foreach (sort keys(%status)) {
    next if (/^resource.*?submitted_by$/);
    $result.='<td align="middle">&nbsp;'.$status{$_}.'&nbsp;</td>'."\n";
       }
       $request->print($result.'</tr>'."\n");
    }
       }
       $request->print('</table></td></tr></table>');
       $request->print('<input type="submit" name="submit" value="View/Grade" /><form />');
 }  }
   
 sub processGroup {  sub processGroup {
   my ($request)  = shift;      my ($request)  = shift;
   my $ctr        = 0;      my $ctr        = 0;
   my @stuchecked = (ref($ENV{'form.stuinfo'}) ? @{$ENV{'form.stuinfo'}}      my @stuchecked = (ref($ENV{'form.stuinfo'}) ? @{$ENV{'form.stuinfo'}}
                            : ($ENV{'form.stuinfo'}));        : ($ENV{'form.stuinfo'}));
   my $total      = scalar(@stuchecked)-1;      my $total      = scalar(@stuchecked)-1;
   if ($stuchecked[0] eq '') {      if ($stuchecked[0] eq '') {
       &userError($request,'No student was selected for viewing/grading.');   &userError($request,'No student was selected for viewing/grading.');
       return;   return;
   }      }
   foreach (@stuchecked) {      foreach (@stuchecked) {
       my ($sname,$sdom,$fullname) = split(/:/);   my ($uname,$udom,$fullname) = split(/:/);
       $ENV{'form.student'} = $sname;   $ENV{'form.student'} = $uname;
       $ENV{'form.fullname'} = $fullname;   $ENV{'form.fullname'} = $fullname;
       &submission($request,$ctr,$total);   &submission($request,$ctr,$total);
       $ctr++;   $ctr++;
   }      }
   return 'The End';      return '';
 }  }
   
 sub userError {  sub userError {
Line 222  sub userError { Line 266  sub userError {
   
 #FIXME - needs to handle multiple matches  #FIXME - needs to handle multiple matches
 sub finduser {  sub finduser {
   my ($name) = @_;      my ($name) = @_;
   my $domain = '';      my $domain = '';
   if ( $Apache::grades::viewgrades eq 'F' ) {      if ( $Apache::grades::viewgrades eq 'F' ) {
     my ($classlist) = &getclasslist('all','0');   my ($classlist) = &getclasslist('all','0');
     foreach ( sort(@{ $$classlist{'all'} }) ) {   foreach ( sort(@{ $$classlist{'all'} }) ) {
       my ($posname,$posdomain) = split(/:/);      my ($posname,$posdomain) = split(/:/);
       if ($posname =~ $name) { $name=$posname; $domain=$posdomain; last; }      if ($posname =~ $name) { $name=$posname; $domain=$posdomain; last; }
     }   }
     return ($name,$domain);   return ($name,$domain);
   } else {      } else {
     return ($ENV{'user.name'},$ENV{'user.domain'});   return ($ENV{'user.name'},$ENV{'user.domain'});
   }      }
 }  }
   
 sub getclasslist {  sub getclasslist {
   my ($getsec,$hideexpired) = @_;      my ($getsec,$hideexpired) = @_;
   my ($coursedomain,$coursenum) = split(/_/,$ENV{'request.course.id'});      my $now = time;
   my %classlist=&Apache::lonnet::dump('classlist',$coursedomain,$coursenum);      my %classlist=&Apache::lonnet::dump('classlist',
   my $now = time;   $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
   my (@holdsec,@sections);   $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
   foreach my $student (keys(%classlist)) {      my (@holdsec,@sections,%allids,%stusec,%fullname);
     my ($end,$start)=split(/:/,$classlist{$student});      foreach (keys(%classlist)) {
     # still a student?   my ($end,$start,$id,$section,$fullname)=split(/:/,$classlist{$_});
     if (($hideexpired) && ($end) && ($end < $now)) {         # still a student?
       next;   if (($hideexpired) && ($end) && ($end < $now)) {
     }      next;
     my ($unam,$udom) = split(/:/,$student,2);   }
     my $section = &Apache::lonnet::usection($udom,$unam,$ENV{'request.course.id'});   $section = ($section ne '' ? $section : 'no');
     $section = ($section ne '-1' ? $section : 'no');   push @holdsec,$section;
     push @holdsec,$section;   if ($getsec eq 'all' || $getsec eq $section) {
     push (@{ $classlist{$getsec} }, $student) if ($getsec eq 'all' || $getsec eq $section);      push (@{ $classlist{$getsec} }, $_);
   }      $allids{$_}=$id;
   my %seen = ();      $stusec{$_}=$section;
   foreach my $item (@holdsec) {      $fullname{$_}=$fullname;
       push (@sections, $item) unless $seen{$item}++;   }
   }  
   return (\%classlist,\@sections);  
 }  
   
 sub getpartlist {  
   my ($url) = @_;  
   my @parts =();  
   my (@metakeys) = split(/,/,&Apache::lonnet::metadata($url,'keys'));  
   foreach my $key (@metakeys) {  
     if ( $key =~ m/stores_([0-9]+)_.*/) {  
       push(@parts,$key);  
     }      }
   }      my %seen = ();
   return @parts;      foreach my $item (@holdsec) {
    push (@sections, $item) unless $seen{$item}++;
       }
       return (\%classlist,\@sections,\%allids,\%stusec,\%fullname);
 }  }
   
 sub viewstudentgrade {  sub getpartlist {
   my ($url,$symb,$courseid,$student,@parts) = @_;      my ($url) = @_;
   my $result ='';      my @parts =();
   my $cellclr = '"#ffffdd"';      my (@metakeys) = split(/,/,&Apache::lonnet::metadata($url,'keys'));
   my ($username,$domain) = split(/:/,$student);      foreach my $key (@metakeys) {
    if ( $key =~ m/stores_([0-9]+)_.*/) {
   my $fullname = &get_fullname($username,$domain);      push(@parts,$key);
   my %record=&Apache::lonnet::restore($symb,$courseid,$domain,$username);   }
   
   $result.="<tr bgcolor=$cellclr><td>$username</td><td>$fullname</td><td align=\"middle\">$domain</td>\n";  
   foreach my $part (@parts) {  
     my ($temp,$part,$type)=split(/_/,$part);  
     my $score=$record{"resource.$part.$type"};  
     if ($type eq 'awarded' || $type eq 'tries') {  
       $result.='<td align="middle"><input type="text" name="GRADE.'.$student.'.'.$part.'.'.$type.  
   '" value="'.$score.'" size="4" /></td>'."\n";  
     } elsif ($type eq 'solved') {  
       my ($status,$foo)=split(/_/,$score,2);  
       $result.="<td align=\"middle\"><select name=\"GRADE.$student.$part.$type\">\n";  
       my $optsel = '<option>correct</option><option>incorrect</option><option>excused</option>'.  
   '<option>ungraded</option><option>partial</option><option>nothing</option>'."\n";  
       $status = 'nothing' if ($status eq '');  
       $optsel =~ s/<option>$status/<option selected="on">$status/;  
       $result.=$optsel;  
       $result.="</select></td>\n";  
     }      }
   }      return @parts;
   $result.='</td></tr>';  
   return $result;  
 }  }
   
 #FIXME need to look at the metadata <stores> spec on what type of data to accept and provide an  #FIXME need to look at the metadata <stores> spec on what type of data to accept and provide an
 #interface based on that, also do that to above function.  #interface based on that, also do that to above function.
 sub setstudentgrade {  sub setstudentgrade {
   my ($url,$symb,$courseid,$student,@parts) = @_;      my ($url,$symb,$courseid,$student,@parts) = @_;
   print "set student grade parts=@parts<br>";      my $result ='';
   my $result ='';      my ($stuname,$domain) = split(/:/,$student);
   my ($stuname,$domain) = split(/:/,$student);      my %record=&Apache::lonnet::restore($symb,$courseid,$domain,$stuname);
   my %record=&Apache::lonnet::restore($symb,$courseid,$domain,$stuname);      my %newrecord;
   my %newrecord;  
       foreach my $part (@parts) {
   foreach my $part (@parts) {   my ($temp,$part,$type)=split(/_/,$part);
     my ($temp,$part,$type)=split(/_/,$part);   my $oldscore=$record{"resource.$part.$type"};
     my $oldscore=$record{"resource.$part.$type"};   my $newscore=$ENV{"form.GRADE.$student.$part.$type"};
     my $newscore=$ENV{"form.GRADE.$student.$part.$type"};   if ($type eq 'solved') {
     print "old=$oldscore:new=$newscore:<br>";      my $update=0;
     if ($type eq 'solved') {      if ($newscore eq 'nothing' ) {
       my $update=0;   if ($oldscore ne '') {
       if ($newscore eq 'nothing' ) {      $update=1;
  if ($oldscore ne '') {      $newscore = '';
   $update=1;   }
   $newscore = '';      } elsif ($oldscore !~ m/^$newscore/) {
  }   $update=1;
       } elsif ($oldscore !~ m/^$newscore/) {   $result.="Updating $stuname to $newscore<br />\n";
  $update=1;   if ($newscore eq 'correct')   { $newscore = 'correct_by_override'; }
  $result.="Updating $stuname to $newscore<br />\n";   if ($newscore eq 'incorrect') { $newscore = 'incorrect_by_override'; }
  if ($newscore eq 'correct')   { $newscore = 'correct_by_override'; }   if ($newscore eq 'excused')   { $newscore = 'excused'; }
  if ($newscore eq 'incorrect') { $newscore = 'incorrect_by_override'; }   if ($newscore eq 'ungraded')  { $newscore = 'ungraded_attempted'; }
  if ($newscore eq 'excused')   { $newscore = 'excused'; }      } else {
  if ($newscore eq 'ungraded')  { $newscore = 'ungraded_attempted'; }   #$result.="$stuname:$part:$type:unchanged  $oldscore to $newscore:<br />\n";
  if ($newscore eq 'partial')   { $newscore = 'correct_partially_by_override'; }      }
       } else {      if ($update) { $newrecord{"resource.$part.$type"}=$newscore; }
  #$result.="$stuname:$part:$type:unchanged  $oldscore to $newscore:<br />\n";   } else {
       }      if ($oldscore ne $newscore) {
       if ($update) { $newrecord{"resource.$part.$type"}=$newscore; }   $newrecord{"resource.$part.$type"}=$newscore;
     } else {   $result.="Updating $student"."'s status for $part.$type to $newscore<br />\n";
       if ($oldscore ne $newscore) {      } else {
  $newrecord{"resource.$part.$type"}=$newscore;   #$result.="$stuname:$part:$type:unchanged  $oldscore to $newscore:<br />\n";
  $result.="Updating $student"."'s status for $part.$type to $newscore<br />\n";      }
       } else {   }
  #$result.="$stuname:$part:$type:unchanged  $oldscore to $newscore:<br />\n";  
       }  
     }      }
   }      if ( scalar(keys(%newrecord)) > 0 ) {
   if ( scalar(keys(%newrecord)) > 0 ) {   $newrecord{'resource.regrader'}="$ENV{'user.name'}:$ENV{'user.domain'}";
     $newrecord{'resource.regrader'}="$ENV{'user.name'}:$ENV{'user.domain'}";  #       &Apache::lonnet::cstore(\%newrecord,$symb,$courseid,$domain,$stuname);
 #    &Apache::lonnet::cstore(\%newrecord,$symb,$courseid,$domain,$stuname);  
   
     $result.="Stored away ".scalar(keys(%newrecord))." elements.<br />\n";   $result.="Stored away ".scalar(keys(%newrecord))." elements.<br />\n";
   }      }
   return $result;      return $result;
 }  }
   
   sub print_hash {
       my ($request, $hash) = @_;
       $request->print('<table border=1><tr><td>Key</td><td>Value</td></tr>');
       for (sort keys (%$hash)) {
    $request->print('<tr><td>'.$_.'</td><td>'.$$hash{$_}.'&nbsp;</td></tr>');
       }
       $request->print('</table>');
       return '';
   }
 #  #
 # --------------------------- show submissions of a student, option to grade --------  # --------------------------- show submissions of a student, option to grade --------
 sub submission {  sub submission {
   my ($request,$counter,$total) = @_;      my ($request,$counter,$total) = @_;
   
   (my $url=$ENV{'form.url'})=~s-^http://($ENV{'SERVER_NAME'}|$ENV{'HTTP_HOST'})--;  
   if ($ENV{'form.student'} eq '') { &moreinfo($request,'Need student login id'); return ''; }  
   my ($uname,$udom) = &finduser($ENV{'form.student'});  
   if ($uname eq '') { &moreinfo($request,'Unable to find student'); return ''; }  
   
   my $symb=($ENV{'form.symb'} ne '' ? $ENV{'form.symb'} : (&Apache::lonnet::symbread($url)));  
   if ($symb eq '') { $request->print("Unable to handle ambiguous references:$url:."); return ''; }  
   my $last = ($ENV{'form.lastSub'} eq 'last' ? 'last' : '');  
   
   # header info  
   if ($counter == 0) {  
       &sub_page_js($request);  
       $request->print('<h2>&nbsp;<font color="#339933">Submission Record</font></h2>'.  
       '<font size=+1>&nbsp;<b>Resource: </b>'.$url.'</font>');  
   
       # option to display problem, only once else it cause problems with the form later   
       # since the problem has a form.  
       if ($ENV{'form.vProb'} eq 'yes') {  
   my $rendered=&Apache::loncommon::get_student_view($symb,$uname,$udom,  
     $ENV{'request.course.id'});  
   my $companswer=&Apache::loncommon::get_student_answers($symb,$uname,$udom,  
  $ENV{'request.course.id'});  
   my $result.='<table border="0" width="100%"><tr><td bgcolor="#777777">';  
   $result.='<table border="0" width="100%"><tr><td bgcolor="#e6ffff">';  
   $result.='<b>Student\'s view of the problem</b></td></tr><tr><td bgcolor="#ffffff">'.$rendered.'<br />';  
   $result.='<b>Correct answer:</b><br />'.$companswer;  
   $result.='</td></tr></table>';  
   $result.='</td></tr></table><br />';  
   $request->print($result);  
       }  
   
       # kwclr is the only variable that is non blank if this has been used once.      (my $url=$ENV{'form.url'})=~s-^http://($ENV{'SERVER_NAME'}|$ENV{'HTTP_HOST'})--;
       my %keyhash = ();      if ($ENV{'form.student'} eq '') { &moreinfo($request,'Need student login id'); return ''; }
       if ($ENV{'form.kwclr'} eq '') {      my ($uname,$udom) = &finduser($ENV{'form.student'});
   %keyhash = &Apache::lonnet::dump('nohist_handgrade',      if ($uname eq '') { &moreinfo($request,'Unable to find student'); return ''; }
       $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},  
       $ENV{'course.'.$ENV{'request.course.id'}.'.num'});      my $symb=($ENV{'form.symb'} ne '' ? $ENV{'form.symb'} : (&Apache::lonnet::symbread($url)));
       if ($symb eq '') { $request->print("Unable to handle ambiguous references:$url:."); return ''; }
   my $loginuser = $ENV{'user.name'}.':'.$ENV{'user.domain'};      my $last = ($ENV{'form.lastSub'} eq 'last' ? 'last' : '');
   $ENV{'form.keywords'} = $keyhash{$symb.'_keywords'} ne '' ? $keyhash{$symb.'_keywords'} : '';      $ENV{'form.vProb'} = $ENV{'form.vProb'} ne '' ? $ENV{'form.vProb'} : 'yes';
   $ENV{'form.kwclr'}    = $keyhash{$loginuser.'_kwclr'} ne '' ? $keyhash{$loginuser.'_kwclr'} : 'red';      my ($classlist,$seclist,$ids,$stusec,$fullname);
   $ENV{'form.kwsize'}   = $keyhash{$loginuser.'_kwsize'} ne '' ? $keyhash{$loginuser.'_kwsize'} : '0';  
   $ENV{'form.kwstyle'}  = $keyhash{$loginuser.'_kwstyle'} ne '' ? $keyhash{$loginuser.'_kwstyle'} : '';      # header info
   $ENV{'form.msgsub'}   = $keyhash{$symb.'_subject'} ne '' ?       if ($counter == 0) {
       $keyhash{$symb.'_subject'} : &Apache::lonnet::metadata($url,'title');   &sub_page_js($request);
   $ENV{'form.savemsgN'} = $keyhash{$symb.'_savemsgN'} ne '' ? $keyhash{$symb.'_savemsgN'} : '0';   $request->print('<h2>&nbsp;<font color="#339933">Submission Record</font></h2>'.
    '<font size=+1>&nbsp;<b>Resource: </b>'.$url.'</font>');
   
    # option to display problem, only once else it cause problems with the form later 
    # since the problem has a form.
    if ($ENV{'form.vProb'} eq 'yes') {
       my $rendered=&Apache::loncommon::get_student_view($symb,$uname,$udom,
         $ENV{'request.course.id'});
       my $companswer=&Apache::loncommon::get_student_answers($symb,$uname,$udom,
      $ENV{'request.course.id'});
       my $result.='<table border="0" width="100%"><tr><td bgcolor="#777777">';
       $result.='<table border="0" width="100%"><tr><td bgcolor="#e6ffff">';
       $result.='<b>Student\'s view of the problem</b></td></tr><tr><td bgcolor="#ffffff">'.$rendered.'<br />';
       $result.='<b>Correct answer:</b><br />'.$companswer;
       $result.='</td></tr></table>';
       $result.='</td></tr></table><br />';
       $request->print($result);
    }
   
    # kwclr is the only variable that is guaranteed to be non blank if this subroutine has been called once.
    my %keyhash = ();
    if ($ENV{'form.kwclr'} eq '') {
       %keyhash = &Apache::lonnet::dump('nohist_handgrade',
        $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
        $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
   
       my $loginuser = $ENV{'user.name'}.':'.$ENV{'user.domain'};
       $ENV{'form.keywords'} = $keyhash{$symb.'_keywords'} ne '' ? $keyhash{$symb.'_keywords'} : '';
       $ENV{'form.kwclr'}    = $keyhash{$loginuser.'_kwclr'} ne '' ? $keyhash{$loginuser.'_kwclr'} : 'red';
       $ENV{'form.kwsize'}   = $keyhash{$loginuser.'_kwsize'} ne '' ? $keyhash{$loginuser.'_kwsize'} : '0';
       $ENV{'form.kwstyle'}  = $keyhash{$loginuser.'_kwstyle'} ne '' ? $keyhash{$loginuser.'_kwstyle'} : '';
       $ENV{'form.msgsub'}   = $keyhash{$symb.'_subject'} ne '' ? 
    $keyhash{$symb.'_subject'} : &Apache::lonnet::metadata($url,'title');
       $ENV{'form.savemsgN'} = $keyhash{$symb.'_savemsgN'} ne '' ? $keyhash{$symb.'_savemsgN'} : '0';
   
       }   }
       $request->print('<form action="/adm/grades" method="post" name="SCORE">'."\n".   $request->print('<form action="/adm/grades" method="post" name="SCORE">'."\n".
       '<input type="hidden" name="command"    value="handgrade" />'."\n".   '<input type="hidden" name="command"    value="handgrade" />'."\n".
       '<input type="hidden" name="symb"       value="'.$symb.'" />'."\n".   '<input type="hidden" name="refresh"    value="off" />'."\n".
       '<input type="hidden" name="url"        value="'.$url.'" />'."\n".   '<input type="hidden" name="symb"       value="'.$symb.'" />'."\n".
       '<input type="hidden" name="vProb"      value="'.$ENV{'form.vProb'}.'" />'."\n".   '<input type="hidden" name="url"        value="'.$url.'" />'."\n".
       '<input type="hidden" name="lastSub"    value="'.$ENV{'form.lastSub'}.'" />'."\n".   '<input type="hidden" name="showgrading" value="'.$ENV{'form.showgrading'}.'" />'."\n".
       '<input type="hidden" name="section"    value="'.$ENV{'form.section'}.'">'."\n".   '<input type="hidden" name="vProb"      value="'.$ENV{'form.vProb'}.'" />'."\n".
       '<input type="hidden" name="submitonly" value="'.$ENV{'form.submitonly'}.'">'."\n".   '<input type="hidden" name="lastSub"    value="'.$ENV{'form.lastSub'}.'" />'."\n".
       '<input type="hidden" name="response"   value="'.$ENV{'form.response'}.'">'."\n".   '<input type="hidden" name="section"    value="'.$ENV{'form.section'}.'">'."\n".
       '<input type="hidden" name="handgrade"  value="'.$ENV{'form.handgrade'}.'">'."\n".   '<input type="hidden" name="submitonly" value="'.$ENV{'form.submitonly'}.'">'."\n".
       '<input type="hidden" name="keywords"   value="'.$ENV{'form.keywords'}.'" />'."\n".   '<input type="hidden" name="response"   value="'.$ENV{'form.response'}.'">'."\n".
       '<input type="hidden" name="kwclr"      value="'.$ENV{'form.kwclr'}.'" />'."\n".   '<input type="hidden" name="handgrade"  value="'.$ENV{'form.handgrade'}.'">'."\n".
       '<input type="hidden" name="kwsize"     value="'.$ENV{'form.kwsize'}.'" />'."\n".   '<input type="hidden" name="keywords"   value="'.$ENV{'form.keywords'}.'" />'."\n".
       '<input type="hidden" name="kwstyle"    value="'.$ENV{'form.kwstyle'}.'" />'."\n".   '<input type="hidden" name="kwclr"      value="'.$ENV{'form.kwclr'}.'" />'."\n".
       '<input type="hidden" name="msgsub"     value="'.$ENV{'form.msgsub'}.'" />'."\n".   '<input type="hidden" name="kwsize"     value="'.$ENV{'form.kwsize'}.'" />'."\n".
       '<input type="hidden" name="savemsgN"   value="'.$ENV{'form.savemsgN'}.'" />'."\n".   '<input type="hidden" name="kwstyle"    value="'.$ENV{'form.kwstyle'}.'" />'."\n".
       '<input type="hidden" name="NCT"'.   '<input type="hidden" name="msgsub"     value="'.$ENV{'form.msgsub'}.'" />'."\n".
       ' value="'.($ENV{'form.NTSTU'} ne '' ? $ENV{'form.NTSTU'} : $total+1).'" />'."\n");   '<input type="hidden" name="savemsgN"   value="'.$ENV{'form.savemsgN'}.'" />'."\n".
    '<input type="hidden" name="NCT"'.
       my ($cts,$prnmsg) = (1,'');   ' value="'.($ENV{'form.NTSTU'} ne '' ? $ENV{'form.NTSTU'} : $total+1).'" />'."\n");
       while ($cts <= $ENV{'form.savemsgN'}) {  
   $prnmsg.='<input type="hidden" name="savemsg'.$cts.'" value="'.   my ($cts,$prnmsg) = (1,'');
       ($keyhash{$symb.'_savemsg'.$cts} eq '' ? $ENV{'form.savemsg'.$cts} : $keyhash{$symb.'_savemsg'.$cts}).   while ($cts <= $ENV{'form.savemsgN'}) {
       '" />'."\n";      $prnmsg.='<input type="hidden" name="savemsg'.$cts.'" value="'.
   $cts++;   ($keyhash{$symb.'_savemsg'.$cts} eq '' ? $ENV{'form.savemsg'.$cts} : $keyhash{$symb.'_savemsg'.$cts}).
       }   '" />'."\n";
       $request->print($prnmsg);      $cts++;
    }
    $request->print($prnmsg);
   
       if ($ENV{'form.handgrade'} eq 'yes') {   if ($ENV{'form.handgrade'} eq 'yes' && $ENV{'form.showgrading'} eq 'yes') {
   $request->print(<<KEYWORDS);      $request->print(<<KEYWORDS);
 &nbsp;<b>Keyword Options:</b>&nbsp;  &nbsp;<b>Keyword Options:</b>&nbsp;
 <a href="javascript:keywords(document.SCORE.keywords)"; TARGET=_self>List</a>&nbsp; &nbsp;  <a href="javascript:keywords(document.SCORE.keywords)"; TARGET=_self>List</a>&nbsp; &nbsp;
 <a href="#" onMouseDown="javascript:getSel(); return false"  <a href="#" onMouseDown="javascript:getSel(); return false"
  CLASS="page">Paste Selection to List</a>&nbsp; &nbsp;   CLASS="page">Paste Selection to List</a>&nbsp; &nbsp;
 <a href="javascript:kwhighlight()"; TARGET=_self>Highlight Attribute</a><br /><br />  <a href="javascript:kwhighlight()"; TARGET=_self>Highlight Attribute</a><br /><br />
 KEYWORDS  KEYWORDS
       }          }
   }      }
       my %record = &Apache::lonnet::restore($symb,$ENV{'request.course.id'},$udom,$uname);
   # Student info      my ($partlist,$handgrade) = &response_type($url);
   $request->print(($counter == 0 ? '' : '<br />'));  #    &print_hash($request,\%record);
   my $fullname = ($ENV{'form.fullname'} ne '' ? $ENV{'form.fullname'} : &get_fullname($uname,$udom));  
   my $result.='<table border="0" width=100%><tr><td bgcolor="#777777">'.      # Student info
       '<table border="0" width=100%><tr bgcolor="#ffffff"><td>';      $request->print(($counter == 0 ? '' : '<br />'));
   $result.='<table border="0"><tr bgcolor="#ffffff"><td><b>Username: </b>'.$uname.      my $fullname = ($ENV{'form.fullname'} ne '' ? $ENV{'form.fullname'} : &get_fullname($uname,$udom));
       '</td><td><b>Fullname: </b>'.$fullname.      my $result='<table border="0" width=100%><tr><td bgcolor="#777777">'.
       '</td><td><b>Domain: </b>'.$udom.'</td></tr>';   '<table border="0" width=100%><tr bgcolor="#ffffff"><td>';
   if ($ENV{'form.handgrade'} eq 'yes') {  
 #      my $subonly = &get_last_submission($symb,$uname,$udom,$ENV{'request.course.id'});      $result.='<table border="0"><tr bgcolor="#ffffff"><td><b>Fullname: </b>'.$fullname.
       my ($classlist) = &getclasslist('all','0');   '</td><td>&nbsp; &nbsp;<b>Username: </b>'.$uname.
       my @collaborators;   '</td><td>&nbsp; &nbsp;<b>Domain: </b>'.$udom.'</td></tr>';
 #      foreach ( sort(@{ $$classlist{'all'} }) ) {      if ($ENV{'form.handgrade'} eq 'yes') {
 #  my ($sname,$sdom) = split(/:/);   my @col_list;
 #  push @collaborators,$sname if (grep /\b$sname(\b|\.)/i,$subonly);   ($classlist,$seclist,$ids,$stusec,$fullname) = &getclasslist('all','0');
 #      }   for (keys (%$handgrade)) {
 #      push @collaborators,'leede','carlandmm','freyniks'; # as a test to display collaborators.      my $ncol = &Apache::lonnet::EXT('resource.'.$_.'.maxcollaborators',$symb,$udom,$uname);
       if (scalar(@collaborators) != 0) {      if ($ncol > 0) {
   $result.='<tr bgcolor="#ffffff"><td colspan=3><b>Collaborators: </b>';   s/\_/\./g;
   foreach (@collaborators) {   if ($record{'resource.'.$_.'.collaborators'} ne '') {
       $result.=$_.' ('.&get_fullname($_,$udom).') &nbsp; &nbsp;';      my (@collaborators) = split(/,?\s+/,$record{'resource.'.$_.'.collaborators'});
   }      my (@badcollaborators);
   $result.='</td></tr>'."\n";      if (scalar(@collaborators) != 0) {
   $result.='<input type="hidden" name="collaborator'.$counter.   $result.='<tr bgcolor="#ffffff"><td colspan=3><b>Collaborators: </b>';
       '" value="'.(join ':',@collaborators).'" />'."\n";   foreach my $collaborator (@collaborators) {
       }      $collaborator = $collaborator =~ /\@|:/ ? 
   }   (split(/@|:/,$collaborator))[0] : $collaborator;
   $result.='</table>'."\n";      next if ($collaborator eq $uname);
   $request->print($result);      if (!grep /^$collaborator:/i,keys %$classlist) {
    push @badcollaborators,$collaborator;
    next;
       }
       push @col_list, $collaborator;
       $result.=$$fullname{$collaborator.':'.$udom}.' ('.$collaborator.') &nbsp; &nbsp;';
    }
    $result.='</td></tr>'."\n";
    $result.='<tr bgcolor="#ffbbbb"><td colspan=2>'.
       'This student has submitted '.(scalar (@badcollaborators) > 1 ? '' : 'an').
       ' invalid collaborator'.(scalar (@badcollaborators) > 1 ? 's. ' : '. ').
       (join ', ',@badcollaborators).'</td></tr>' 
       if (scalar(@badcollaborators) > 0);
   
    $result.='<tr bgcolor="#ffbbbb"><td colspan=2>'.
       'This student has submitted too many collaborators. Maximum is '.
       $ncol.'.</td></tr>' if (scalar(@collaborators) > $ncol);
    $result.='<input type="hidden" name="collaborator'.$counter.
       '" value="'.(join ':',@col_list).'" />'."\n";
       }
    }
       }
    }
       }
       $request->print($result.'</table>'."\n");
   
  # print student answer      # print student answer
   if ($ENV{'form.lastSub'} eq 'lastonly') {      if ($ENV{'form.lastSub'} =~ /^(lastonly|hdgrade)$/) {
       my ($string,$timestamp)=&get_last_submission ($symb,$uname,$udom,$ENV{'request.course.id'});   if ($ENV{'form.'.$uname.':'.$udom.':submitted_by'}) {
       $string=&keywords_highlight(join('::::',@$string));      my $submitby='</td></tr><tr><td bgcolor="#e6ffff">'.
       my $lastsubonly='<table border="0" width=100%><tr><td bgcolor="#777777">';   '<b>Collaborative submission by: </b>'.
       $lastsubonly.='<table border="0" width=100%><tr bgcolor="#ddffff">';   '<a href="javascript:viewSubmitter(\''.$ENV{'form.'.$uname.':'.$udom.':submitted_by'}.
       $lastsubonly.='<td><b>Last Submission Only</b>'.   '\')"; TARGET=_self>'.
   ($timestamp eq '' ? '' : '&nbsp; &nbsp; <b>Date Submitted:</b> '.@$timestamp).'</td></tr>';   $$fullname{$ENV{'form.'.$uname.':'.$udom.':submitted_by'}}.'</a>';
       $lastsubonly.='<tr><td bgcolor="#ffffe6">';      $submitby.='</td></tr><tr><td bgcolor="#ffffff">'."\n";
       $lastsubonly.=$string;      $request->print($submitby);
       $lastsubonly.='</td></tr></table></td></tr></table>'."\n";   } else {
       $request->print($lastsubonly);      my ($string,$timestamp)=&get_last_submission ($symb,$uname,$udom,$ENV{'request.course.id'});
   } else {      my $lastsubonly.='</td></tr><tr><td bgcolor="#e6ffff"><b>Last Submission Only</b>'.
       $request->print(&Apache::loncommon::get_previous_attempt($symb,$uname,$udom,   ($$timestamp eq '' ? '' : '&nbsp; &nbsp; <b>Date Submitted:</b> '.$$timestamp).'</td></tr>';
        $ENV{'request.course.id'},$last,      if ($$timestamp eq '') {
        '.submission','Apache::grades::keywords_highlight'));   $lastsubonly.='<tr><td bgcolor="#ffffe6">'.$$string[0].'</td></tr>';
   }      } else {
    for my $part (sort keys(%$handgrade)) {
       foreach (@$string) {
    my ($partid,$respid) = /^resource\.(\d+)\.(\d+)\.submission/;
    if ($part eq ($partid.'_'.$respid)) {
       my ($ressub,$subval) = split(/:/,$_,2);
       $lastsubonly.='<tr><td bgcolor="#ffffe6"><b>Part ID</b> '.
    $partid.' <b>Response ID</b> '.$respid.
    ' <b>Submission</b> '.&keywords_highlight($subval).'</td></tr>'
    if ($ENV{'form.lastSub'} eq 'lastonly' || 
       ($ENV{'form.lastSub'} eq 'hdgrade' && $$handgrade{$part} =~ /:yes$/));
    }
       }
    }
       }
       $lastsubonly.='</td></tr><tr><td bgcolor="#ffffff">'."\n";
       $request->print($lastsubonly);
    }
       } else {
    $request->print(&Apache::loncommon::get_previous_attempt($symb,$uname,$udom,
    $ENV{'request.course.id'},$last,
    '.submission','Apache::grades::keywords_highlight'));
       }
       
       # view submission with no grading option
       if ($ENV{'form.showgrading'} eq '') {
    $request->print('</td></tr></table></td></tr></table></form>');
    return;
       }
   
   my $wgt    = &Apache::lonnet::EXT('resource.partid.weight',$symb,$udom,$uname);      $result='<input type="hidden" name="newmsg'.$counter.'" value="" />'."\n".
   my $wgtmsg = ($wgt > 0 ? '(problem weight)' : '<font color="red">problem weight assigned by computer</font>');   '<input type="hidden" name="includemsg'.$counter.'" value="" />'."\n".
   $wgt       = ($wgt > 0 ? $wgt : '1');   '<input type="hidden" name="unamedom'.$counter.'" value="'.$uname.':'.$udom.'" />'."\n";
   my %record = &Apache::lonnet::restore($symb,$ENV{'request.course.id'},$udom,$uname);      $result.='&nbsp;<a href="javascript:msgCenter(document.SCORE,'.$counter.
   my $score  = ($record{'resource.0.awarded'} eq '' ? '' : $record{'resource.0.awarded'}*$wgt);   ',\''.$fullname.'\')"; TARGET=_self>Compose Message</a><br />'."\n" if ($ENV{'form.handgrade'} eq 'yes');
       $request->print($result);
   # display grading options  
   $result='<input type="hidden" name="WGT'.$counter.'" value="'.$wgt.'" />'.      my %seen = ();
       '<input type="hidden" name="unamedom'.$counter.'" value="'.$uname.':'.$udom.'" />'."\n";      my @partlist;
   $result.='<input type="hidden" name="newmsg'.$counter.'" value="" />'."\n";      for (sort keys(%$handgrade)) {
   $result.='<input type="hidden" name="includemsg'.$counter.'" value="" />'."\n";   my ($partid,$respid) = split(/_/);
   $result.='<table border="0"><tr><td><b>Points</b></td><td>';   next if ($seen{$partid} > 0);
    $seen{$partid}++;
   my $ctr = 0;   next if ($$handgrade{$_} =~ /:no$/);
   $result.='<table border="0"><tr>';  # display radio buttons in a nice table with 10 across   push @partlist,$partid;
   while ($ctr<=$wgt) {   my $wgt    = &Apache::lonnet::EXT('resource.'.$partid.'.weight',$symb,$udom,$uname);
       $result.= '<td><input type="radio" name="RADVAL'.$counter.'" '.   my $wgtmsg = ($wgt > 0 ? '(problem weight)' : '<font color="red">problem weight assigned by computer</font>');
   'onclick="javascript:writeBox(this.form.GRADE_BOX'.$counter.   $wgt       = ($wgt > 0 ? $wgt : '1');
     ',this.form.GRADE_SEL'.$counter.','.$ctr.','.$wgt.')" '.   my $score  = ($record{'resource.'.$partid.'.awarded'} eq '' ?
         '' : $record{'resource.'.$partid.'.awarded'}*$wgt);
   
    # display grading options
    $result='<input type="hidden" name="WGT'.$counter.'_'.$partid.'" value="'.$wgt.'" />';
    $result.='<table border="0"><tr><td><b>Part </b>'.$partid.' <b>Points</b></td><td>';
   
    my $ctr = 0;
    $result.='<table border="0"><tr>';  # display radio buttons in a nice table 10 across
    while ($ctr<=$wgt) {
       $result.= '<td><input type="radio" name="RADVAL'.$counter.'_'.$partid.'" '.
    'onclick="javascript:writeBox(this.form.GRADE_BOX'.$counter.'_'.$partid.
    ',this.form.GRADE_SEL'.$counter.'_'.$partid.','.$ctr.
    ',this.form.stores'.$counter.'_'.$partid.')" '.
  ($score eq $ctr ? 'checked':'').' /> '.$ctr."</td>\n";   ($score eq $ctr ? 'checked':'').' /> '.$ctr."</td>\n";
       $result.=(($ctr+1)%10 == 0 ? '</tr><tr>' : '');      $result.=(($ctr+1)%10 == 0 ? '</tr><tr>' : '');
       $ctr++;      $ctr++;
   }   }
   $result.='</tr></table>';   $result.='</tr></table>';
   
   $result.='</td><td>&nbsp;<b>or</b>&nbsp;</td>';   $result.='</td><td>&nbsp;<b>or</b>&nbsp;</td>';
   $result.='<td><input type="text" name="GRADE_BOX'.$counter.'"'.   $result.='<td><input type="text" name="GRADE_BOX'.$counter.'_'.$partid.'"'.
       ($score ne ''? ' value = "'.$score.'"':'').' size="4" '.      ($score ne ''? ' value = "'.$score.'"':'').' size="4" '.
        'onChange="javascript:updateRadio(this.form.RADVAL'.$counter.      'onChange="javascript:updateRadio(this.form.RADVAL'.$counter.'_'.$partid.
         ',this.form.GRADE_BOX'.$counter.      ',this.form.GRADE_BOX'.$counter.'_'.$partid.
    ',this.form.GRADE_SEL'.$counter.',\''.$wgt.'\')" /></td>'."\n";      ',this.form.GRADE_SEL'.$counter.'_'.$partid.
   $result.='<td>/'.$wgt.' '.$wgtmsg.' </td><td>';      ',this.form.stores'.$counter.'_'.$partid.')" /></td>'."\n";
    $result.='<td>/'.$wgt.' '.$wgtmsg.' </td><td>';
   foreach my $part (&getpartlist($url)) {  
       print "parts=$part<br>";   $result.='<select name="GRADE_SEL'.$counter.'_'.$partid.'" '.
     my ($temp,$part,$type)=split(/_/,$part);      'onChange="javascript:clearRadBox(this.form.RADVAL'.$counter.'_'.$partid.
     if ($type eq 'solved') {      ',this.form.GRADE_BOX'.$counter.'_'.$partid.
       my ($status,$foo)=split(/_/,$record{"resource.$part.$type"},2);      ',this.form.GRADE_SEL'.$counter.'_'.$partid.
       $status = 'partial' if ($foo =~ /partially/);      ',this.form.stores'.$counter.'_'.$partid.')" />'."\n".
       $status = 'nothing' if ($status eq '');      '<option selected="on"> </option>'.
       $result.='<select name="GRADE_SEL'.$counter.'">'."\n";      '<option>excused</option></select>'."&nbsp&nbsp\n";
       my $optsel = '<option>correct</option><option>incorrect</option>'.   $result.='<input type="hidden" name="stores'.$counter.'_'.$partid.'" value="0" />';
   '<option>excused</option><option>ungraded</option>'.   $result.='</td></tr></table>';
       '<option>partial</option><option>nothing</option>'."\n";   $request->print($result);
       $optsel =~ s/<option>$status/<option selected="on">$status/;      }
       $result.=$optsel;      $request->print('<input type="hidden" name="partlist'.$counter.'" value="'.(join ":",@partlist).'" />'."\n");
       $result.="</select>&nbsp&nbsp\n";      $request->print('</td></tr></table></td></tr></table>'."\n");
   
       # print end of form
       if ($counter == $total) {
    my $endform.='<table border="0"><tr><td><input type="submit" name="gradeOpt" value="Save & Next" />';
    my $ntstu ='<select name="NTSTU">'.
       '<option>1</option><option>2</option>'.
       '<option>3</option><option>5</option>'.
       '<option>7</option><option>10</option></select>'."\n";
    my $nsel = ($ENV{'form.NTSTU'} ne '' ? $ENV{'form.NTSTU'} : '1');
    $ntstu =~ s/<option>$nsel</<option selected="on">$nsel</;
    $endform.=$ntstu.'student(s) &nbsp;&nbsp;'.
       '<input type="submit" name="gradeOpt" value="Next" />&nbsp'.
       '<input type="submit" name="gradeOpt" value="Previous" />&nbsp'.
       '(Next and Previous do not save the scores.)'.
       '</td><tr></table></form>';
    $request->print($endform);
     }      }
   }      return '';
   $result.='<a href="javascript:msgCenter(document.SCORE,'.$counter.  
       ',\''.$fullname.'\')"; TARGET=_self>Compose Message</a></td></tr></table>'."\n";  
 #  $result.='</table>';  
   $result.='</td></tr></table></td></tr></table>';  
   $request->print($result);  
   
   # print end of form  
   if ($counter == $total) {  
       my $endform.='<table border="0"><tr><td><input type="submit" name="gradeOpt" value="Save & Next" />';  
       my $ntstu ='<select name="NTSTU">'.  
   '<option>1</option><option>2</option>'.  
       '<option>3</option><option>5</option>'.  
   '<option>7</option><option>10</option></select>'."\n";  
       my $nsel = ($ENV{'form.NTSTU'} ne '' ? $ENV{'form.NTSTU'} : '1');  
       $ntstu =~ s/<option>$nsel/<option selected="on">$nsel/;  
       $endform.=$ntstu.'student(s) &nbsp;&nbsp;';  
       $endform.='<input type="submit" name="gradeOpt" value="Next" />&nbsp';  
       $endform.='<input type="submit" name="gradeOpt" value="Previous" />&nbsp';  
       $endform.='(Next and Previous do not save the scores.)';  
       $endform.='</td><tr></table></form>';  
       $request->print($endform);  
   }  
   
   return '';  
 }  }
   
 sub get_last_submission {  sub get_last_submission {
   my ($symb,$username,$domain,$course)=@_;      my ($symb,$username,$domain,$course)=@_;
   if ($symb) {      if ($symb) {
       my (@string,@timestamp);   my (@string,$timestamp);
      my (%returnhash)=&Apache::lonnet::restore($symb,$course,$domain,$username);   my (%returnhash)=&Apache::lonnet::restore($symb,$course,$domain,$username);
      if ($returnhash{'version'}) {   if ($returnhash{'version'}) {
  my %lasthash=();      my %lasthash=();
  my ($version);      my ($version);
  for ($version=1;$version<=$returnhash{'version'};$version++) {      for ($version=1;$version<=$returnhash{'version'};$version++) {
   foreach (sort(split(/\:/,$returnhash{$version.':keys'}))) {   foreach (sort(split(/\:/,$returnhash{$version.':keys'}))) {
       $lasthash{$_}=$returnhash{$version.':'.$_};      $lasthash{$_}=$returnhash{$version.':'.$_};
   }   }
         }      }
  foreach ((keys %lasthash)) {      foreach ((keys %lasthash)) {
     print "lasthash key=$_<br>";   if ($_ =~ /\.submission$/) {push @string, (join(':',$_,$lasthash{$_}))}
     if ($_ =~ /\.submission$/) {push @string, $_,$lasthash{$_}}   if ($_ =~ /timestamp/) {$timestamp = scalar(localtime($lasthash{$_}))};
     if ($_ =~ /timestamp/) {push @timestamp, scalar(localtime($lasthash{$_}))};      }
 #    if ($_ =~ /\.submission$/) {$string = $lasthash{$_}}  
 #    if ($_ =~ /timestamp/) {$timestamp=scalar(localtime($lasthash{$_}))};  
  }   }
    @string = $string[0] eq '' ? 'Nothing submitted - no attempts.' : @string;
    return \@string,\$timestamp;
     }      }
      @string = $string[0] eq '' ? 'Nothing submitted - no attempts.' : @string;  
      return \@string,\@timestamp;  
   }  
 }  }
   
 sub keywords_highlight {  sub keywords_highlight {
   my $string  = shift;      my $string  = shift;
   my $size    = $ENV{'form.kwsize'} eq '0' ? '' : 'size='.$ENV{'form.kwsize'};      my $size    = $ENV{'form.kwsize'} eq '0' ? '' : 'size='.$ENV{'form.kwsize'};
   my $styleon = $ENV{'form.kwstyle'} eq ''  ? '' : $ENV{'form.kwstyle'};      my $styleon = $ENV{'form.kwstyle'} eq ''  ? '' : $ENV{'form.kwstyle'};
   (my $styleoff = $styleon) =~ s/\</\<\//;      (my $styleoff = $styleon) =~ s/\</\<\//;
   my @keylist = split(/[,\s+]/,$ENV{'form.keywords'});      my @keylist = split(/[,\s+]/,$ENV{'form.keywords'});
   foreach (@keylist) {      foreach (@keylist) {
  #     next if ($_ eq '');   $string =~ s/\b$_(\b|\.)/\<font color\=$ENV{'form.kwclr'} $size\>$styleon$_$styleoff\<\/font\>/gi;
       $string =~ s/\b$_(\b|\.)/\<font color\=$ENV{'form.kwclr'} $size\>$styleon$_$styleoff\<\/font\>/gi;      }
   }      return $string;
   return $string;  
 }  }
   
 sub processHandGrade {  sub processHandGrade {
   my ($request) = shift;      my ($request) = shift;
   my $url    = $ENV{'form.url'};      my $url    = $ENV{'form.url'};
   my $symb   = $ENV{'form.symb'};      my $symb   = $ENV{'form.symb'};
   my $button = $ENV{'form.gradeOpt'};      my $button = $ENV{'form.gradeOpt'};
   my $ngrade = $ENV{'form.NCT'};      my $ngrade = $ENV{'form.NCT'};
   my $ntstu  = $ENV{'form.NTSTU'};      my $ntstu  = $ENV{'form.NTSTU'};
   
   my $loginuser = $ENV{'user.name'}.':'.$ENV{'user.domain'};      my $loginuser = $ENV{'user.name'}.':'.$ENV{'user.domain'};
   my %keyhash = ();      my %keyhash = ();
   $ENV{'form.keywords'} =~ s/,\s{0,}|\s+/ /g;      $ENV{'form.keywords'}           =~ s/,\s{0,}|\s+/ /g;
   $keyhash{$symb.'_handgrade'} = 'activated';      $ENV{'form.keywords'}           =~ s/^\s+|\s+$//;
   $keyhash{$symb.'_keywords'} = $ENV{'form.keywords'};      $keyhash{$symb.'_keywords'}     = $ENV{'form.keywords'};
   $keyhash{$symb.'_subject'} = $ENV{'form.msgsub'};      $keyhash{$symb.'_subject'}      = $ENV{'form.msgsub'};
   $keyhash{$loginuser.'_kwclr'} = $ENV{'form.kwclr'};      $keyhash{$loginuser.'_kwclr'}   = $ENV{'form.kwclr'};
   $keyhash{$loginuser.'_kwsize'} = $ENV{'form.kwsize'};      $keyhash{$loginuser.'_kwsize'}  = $ENV{'form.kwsize'};
   $keyhash{$loginuser.'_kwstyle'} = $ENV{'form.kwstyle'};      $keyhash{$loginuser.'_kwstyle'} = $ENV{'form.kwstyle'};
   
   my ($ctr,$idx) = (1,1);      my ($ctr,$idx) = (1,1);
   while ($ctr <= $ENV{'form.savemsgN'}) {      while ($ctr <= $ENV{'form.savemsgN'}) {
       if ($ENV{'form.savemsg'.$ctr} ne '') {   if ($ENV{'form.savemsg'.$ctr} ne '') {
   $keyhash{$symb.'_savemsg'.$idx} = $ENV{'form.savemsg'.$ctr};      $keyhash{$symb.'_savemsg'.$idx} = $ENV{'form.savemsg'.$ctr};
   $idx++;      $idx++;
       }   }
       $ctr++;   $ctr++;
   }      }
   $ctr = 0;      $ctr = 0;
   while ($ctr < $ngrade) {      while ($ctr < $ngrade) {
       if ($ENV{'form.newmsg'.$ctr} ne '') {   if ($ENV{'form.newmsg'.$ctr} ne '') {
   $keyhash{$symb.'_savemsg'.$idx} = $ENV{'form.newmsg'.$ctr};      $keyhash{$symb.'_savemsg'.$idx} = $ENV{'form.newmsg'.$ctr};
   $ENV{'form.savemsg'.$idx} = $ENV{'form.newmsg'.$ctr};      $ENV{'form.savemsg'.$idx} = $ENV{'form.newmsg'.$ctr};
   $idx++;      $idx++;
       }   }
       $ctr++;   $ctr++;
   }      }
   $ENV{'form.savemsgN'} = --$idx;      $ENV{'form.savemsgN'} = --$idx;
   $keyhash{$symb.'_savemsgN'} = $ENV{'form.savemsgN'};      $keyhash{$symb.'_savemsgN'} = $ENV{'form.savemsgN'};
   my $putresult = &Apache::lonnet::put      my $putresult = &Apache::lonnet::put
       ('nohist_handgrade',\%keyhash,   ('nohist_handgrade',\%keyhash,
        $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},   $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
        $ENV{'course.'.$ENV{'request.course.id'}.'.num'});   $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
   
   my (@parts) = sort(&getpartlist($url));      if ($ENV{'form.refresh'} eq 'on') {
    my $ctr = 0;
   if ($button eq 'Save & Next') {   $ENV{'form.NTSTU'}=$ngrade;
       my $ctr = 0;   while ($ctr < $ngrade) {
       while ($ctr < $ngrade) {      ($ENV{'form.student'},my $udom) = split(/:/,$ENV{'form.unamedom'.$ctr});
   my ($uname,$udom) = split(/:/,$ENV{'form.unamedom'.$ctr});      &submission($request,$ctr,$ngrade-1);
   &saveHandGrade($url,$symb,$uname,$udom,$ctr,@parts);      $ctr++;
    }
   my $includemsg = $ENV{'form.includemsg'.$ctr};   return '';
   my ($subject,$message,$msgstatus) = ('','','');      }
   if ($includemsg =~ /savemsg|new$ctr/) {  
       $subject = $ENV{'form.msgsub'} if ($includemsg =~ /^msgsub/);  
       my (@msgnum) = split(/,/,$includemsg);  
       foreach (@msgnum) {  
   $message.=$ENV{'form.'.$_} if ($_ =~ /savemsg|newmsg/ && $_ ne '');  
       }  
       $message =~ s/\s+/ /g;  
       $msgstatus = &Apache::lonmsg::user_normal_msg ($uname,$udom,$ENV{'form.msgsub'},$message);  
   }  
   if ($ENV{'form.collaborator'.$ctr}) {  
       my (@collaborators) = split(/:/,$ENV{'form.collaborator'.$ctr});  
       foreach (@collaborators) {  
   &saveHandGrade($url,$symb,$_,$udom,$ctr,@parts);  
   if ($message ne '') {  
       $msgstatus = &Apache::lonmsg::user_normal_msg ($uname,$udom,$ENV{'form.msgsub'},$message);  
   }  
       }  
   }  
   $ctr++;  
       }  
   }  
   my $firststu = $ENV{'form.unamedom0'};  
   my $laststu  = $ENV{'form.unamedom'.($ngrade-1)};  
   
   my ($classlist) = &getclasslist($ENV{'form.section'},'0');      if ($button eq 'Save & Next') {
   my (@nextlist,@prevlist);   my $ctr = 0;
   my ($nextflg,$prevflg,$ctr,$ctprev) = (0,0,0,0);   while ($ctr < $ngrade) {
   foreach my $student ( sort(@{ $$classlist{$ENV{'form.section'}} }) ) {      my ($uname,$udom) = split(/:/,$ENV{'form.unamedom'.$ctr});
       my ($uname,$udom) = split(/:/,$student);      my ($errorflg) = &saveHandGrade($request,$url,$symb,$uname,$udom,$ctr);
       my ($type,$status) = &student_gradeStatus($ENV{'form.url'},$udom,$uname);      return '' if ($errorflg eq 'error');
       next if ($status eq 'nothing' && $ENV{'form.submitonly'} eq 'yes');  
       my $includemsg = $ENV{'form.includemsg'.$ctr};
       if ($nextflg == 1 && $button =~ /Next$/) {      my ($subject,$message,$msgstatus) = ('','','');
   push @nextlist,$uname if ($ctr < $ntstu);      if ($includemsg =~ /savemsg|new$ctr/) {
   $ctr++;   $subject = $ENV{'form.msgsub'} if ($includemsg =~ /^msgsub/);
       }   my (@msgnum) = split(/,/,$includemsg);
       $nextflg = 1 if ($student eq $laststu);   foreach (@msgnum) {
       $prevflg = 1 if ($student eq $firststu);      $message.=$ENV{'form.'.$_} if ($_ =~ /savemsg|newmsg/ && $_ ne '');
       if ($prevflg == 0 && $button eq 'Previous') {   }
   push @prevlist,$uname;   $message =~ s/\s+/ /g;
   $ctprev++;   $msgstatus = &Apache::lonmsg::user_normal_msg ($uname,$udom,
       }         $ENV{'form.msgsub'},$message);
   }      }
   if ($button eq 'Previous') {      if ($ENV{'form.collaborator'.$ctr}) {
       if ($ctprev <= $ntstu) {   my (@collaborators) = split(/:/,$ENV{'form.collaborator'.$ctr});
   @nextlist = @prevlist;   foreach (@collaborators) {
       } else {      &saveHandGrade($request,$url,$symb,$_,$udom,$ctr,
   my $idx = 0;     $ENV{'form.unamedom'.$ctr});
   my $start = $ctprev - $ntstu;      if ($message ne '') {
   while ($idx < $ntstu) {   $msgstatus = &Apache::lonmsg::user_normal_msg ($_,$udom,
       $nextlist[$idx] = $prevlist[$start+$idx];         $ENV{'form.msgsub'},
       $idx++;         $message);
   }      }
       }   }
   }      }
   $ctr = 0;      $ctr++;
   my $total = scalar(@nextlist)-1;   }
   foreach my $student (@nextlist) {      }
       $ENV{'form.student'} = $student;      my $firststu = $ENV{'form.unamedom0'};
       &submission($request,$ctr,$total);      my $laststu = $ENV{'form.unamedom'.($ngrade-1)};
       $ctr++;      $ctr = 2;
   }      while ($laststu eq '') {
   if ($total < 0) {   $laststu  = $ENV{'form.unamedom'.($ngrade-$ctr)};
       my $the_end = '<h3><font color="red">LON-CAPA User Message</font></h3><br />'."\n";   $ctr++;
       $the_end.='<b>Message: </b> No more students for this section or class.<br /><br />'."\n";   $laststu = $firststu if ($ctr > $ngrade);
       $the_end.='Click on the button below to return to the grading menu.<br /><br />'."\n";      }
       $the_end.=&show_grading_menu_form ($symb,$url);      my ($classlist,$seclist,$ids,$stusec,$fullname) = &getclasslist($ENV{'form.section'},'0');
       $request->print($the_end);  
   }      my (@parsedlist,@nextlist);
   return '';      my ($nextflg) = 0;
       foreach ( sort(@{ $$classlist{$ENV{'form.section'}} }) ) {
    if ($nextflg == 1 && $button =~ /Next$/) {
       push @parsedlist,$_;
    }
    $nextflg = 1 if ($_ eq $laststu);
    if ($button eq 'Previous') {
       last if ($_ eq $firststu);
       push @parsedlist,$_;
    }
       }
       $ctr = 0;
       my ($partlist,$handgrade) = &response_type($ENV{'form.url'});
       @parsedlist = reverse @parsedlist if ($button eq 'Previous');
       foreach my $student (@parsedlist) {
    my ($uname,$udom) = split(/:/,$student);
    if ($ENV{'form.submitonly'} eq 'yes') {
       my (%status) = &student_gradeStatus($ENV{'form.url'},$udom,$uname,$partlist) ;
       my $statusflg = '';
       foreach (keys(%status)) {
    $statusflg = 1 if ($status{$_} ne 'nothing');
    my ($foo,$partid,$foo) = split(/\./,$_);
    $statusflg = '' if ($status{'resource.'.$partid.'.submitted_by'} ne '');
       }
       next if ($statusflg eq '');
    }
    push @nextlist,$student if ($ctr < $ntstu);
    $ctr++;
       }
   
       $ctr = 0;
       my $total = scalar(@nextlist)-1;
   
       foreach (sort @nextlist) {
    my ($uname,$udom,$submitter) = split(/:/);
    $ENV{'form.student'} = $uname;
    $ENV{'form.fullname'} = $$fullname{$_};
   # $ENV{'form.'.$_.':submitted_by'} = $submitter;
   # print "submitter=$ENV{'form.'.$_.':submitted_by'}= $submitter:<br>";
    &submission($request,$ctr,$total);
    $ctr++;
       }
       if ($total < 0) {
    my $the_end = '<h3><font color="red">LON-CAPA User Message</font></h3><br />'."\n";
    $the_end.='<b>Message: </b> No more students for this section or class.<br /><br />'."\n";
    $the_end.='Click on the button below to return to the grading menu.<br /><br />'."\n";
    $the_end.=&show_grading_menu_form ($symb,$url);
    $request->print($the_end);
       }
       return '';
 }  }
   
 sub saveHandGrade {  sub saveHandGrade {
   my ($url,$symb,$stuname,$domain,$newflg,@parts) = @_;      my ($request,$url,$symb,$stuname,$domain,$newflg,$submitter) = @_;
   my %record=&Apache::lonnet::restore($symb,$ENV{'request.course.id'},$domain,$stuname);  #   my %record=&Apache::lonnet::restore($symb,$ENV{'request.course.id'},$domain,$stuname);
   my %newrecord;      my %newrecord;
       foreach (split(/:/,$ENV{'form.partlist'.$newflg})) {
   foreach my $part (@parts) {   if ($ENV{'form.GRADE_SEL'.$newflg.'_'.$_} eq 'excused') {
     my ($temp,$part,$type)=split(/_/,$part);      $newrecord{'resource.'.$_.'.solved'} = 'excused';
     my $oldscore=$record{"resource.$part.$type"};   } else {
     my $newscore;      my $pts    = ($ENV{'form.GRADE_BOX'.$newflg.'_'.$_} ne '' ? 
     if ($type eq 'awarded' && $newflg >= 0) {    $ENV{'form.GRADE_BOX'.$newflg.'_'.$_} : $ENV{'form.RADVAL'.$newflg.'_'.$_});
  my $pts    = ($ENV{'form.GRADE_BOX'.$newflg} ne '' ?       if ($pts eq '') {
       $ENV{'form.GRADE_BOX'.$newflg} : $ENV{'form.RADVAL'.$newflg});   &userError($request,'No point was assigned for part id '.$_.' and for username '.$stuname.'.');
  my $wgt    = $ENV{'form.WGT'.$newflg};   return 'error';
 # my $sel    = $ENV{'form.GRADE_SEL'.$newflg};      }
  $newscore  = $pts/$wgt if ($wgt != 0);      my $wgt    = $ENV{'form.WGT'.$newflg.'_'.$_} eq '' ? 1 : $ENV{'form.WGT'.$newflg.'_'.$_};
     }      my $partial= $pts/$wgt;
     if ($type eq 'solved') {      $newrecord{'resource.'.$_.'.awarded'}  = $partial;
       $newscore = $ENV{'form.GRADE_SEL'.$newflg} if ($newflg >= 0);      if ($partial == 0) {
       my $update=0;   $newrecord{'resource.'.$_.'.solved'} = 'incorrect_by_override';
       if ($newscore eq 'nothing' ) {      } else {
  if ($oldscore ne '') {   $newrecord{'resource.'.$_.'.solved'} = 'correct_by_override';
   $update=1;      }
   $newscore = '';      $newrecord{'resource.'.$_.'.submitted_by'} = $submitter if ($submitter);
  }   }
       } elsif ($oldscore !~ m/^$newscore/) {  
  $update=1;  
  if ($newscore eq 'correct')   { $newscore = 'correct_by_override'; }  
  if ($newscore eq 'incorrect') { $newscore = 'incorrect_by_override'; }  
  if ($newscore eq 'excused')   { $newscore = 'excused'; }  
  if ($newscore eq 'ungraded')  { $newscore = 'ungraded_attempted'; }  
  if ($newscore eq 'partial')   { $newscore = 'correct_partially_by_override'; }  
       }  
       if ($update) { $newrecord{"resource.$part.$type"}=$newscore; }  
     } else {  
       if ($oldscore ne $newscore) {  
  $newrecord{"resource.$part.$type"}=$newscore;  
       }  
     }      }
   }      
   if ( scalar(keys(%newrecord)) > 0 ) {      if ( scalar(keys(%newrecord)) > 0 ) {
       $newrecord{'resource.regrader'}="$ENV{'user.name'}:$ENV{'user.domain'}";   $newrecord{'resource.regrader'}="$ENV{'user.name'}:$ENV{'user.domain'}";
 #      while (my ($k,$v) = each %newrecord) {  # &print_hash($request,\%newrecord);
 # print "k=$k:v=$v:<br>\n";   &Apache::lonnet::cstore(\%newrecord,$symb,$ENV{'request.course.id'},$domain,$stuname);
 #      }      }
 #      print "symb=$symb,courseid=$ENV{'request.course.id'},dom=$domain,name=$stuname<br>";      return '';
 #     &Apache::lonnet::cstore(\%newrecord,$symb,$ENV{'request.course.id'},$domain,$stuname);  
   }  
   return '';  
 }  }
   
 sub get_symb_and_url {  sub get_symb_and_url {
   my ($request) = @_;      my ($request) = @_;
   (my $url=$ENV{'form.url'}) =~ s-^http://($ENV{'SERVER_NAME'}|$ENV{'HTTP_HOST'})--;      (my $url=$ENV{'form.url'}) =~ s-^http://($ENV{'SERVER_NAME'}|$ENV{'HTTP_HOST'})--;
   my $symb=($ENV{'form.symb'} ne '' ? $ENV{'form.symb'} : (&Apache::lonnet::symbread($url)));      my $symb=($ENV{'form.symb'} ne '' ? $ENV{'form.symb'} : (&Apache::lonnet::symbread($url)));
   if ($symb eq '') { $request->print("Unable to handle ambiguous references:$url:."); return ''; }      if ($symb eq '') { $request->print("Unable to handle ambiguous references:$url:."); return ''; }
   return ($symb,$url);      return ($symb,$url);
 }  }
   
 sub show_grading_menu_form {  sub show_grading_menu_form {
   my ($symb,$url)=@_;      my ($symb,$url)=@_;
   my $result.='<form action="/adm/grades" method="post">'."\n".      my $result.='<form action="/adm/grades" method="post">'."\n".
     '<input type="hidden" name="symb" value="'.$symb.'" />'."\n".   '<input type="hidden" name="symb" value="'.$symb.'" />'."\n".
       '<input type="hidden" name="url" value="'.$url.'" />'."\n".   '<input type="hidden" name="url" value="'.$url.'" />'."\n".
  '<input type="hidden" name="command" value="gradingmenu" />'."\n".   '<input type="hidden" name="command" value="gradingmenu" />'."\n".
   '<input type="submit" name="submit" value="Grading Menu" />'."\n".   '<input type="submit" name="submit" value="Grading Menu" />'."\n".
     '</form>'."\n";   '</form>'."\n";
   return $result;      return $result;
 }  }
   
 sub gradingmenu {  sub gradingmenu {
   my ($request) = @_;      my ($request) = @_;
   my ($symb,$url)=&get_symb_and_url($request);      my ($symb,$url)=&get_symb_and_url($request);
   if (!$symb) {return '';}      if (!$symb) {return '';}
   my $allkeys = &Apache::lonnet::metadata($url,'keys');      my $result='<h2>&nbsp;<font color="#339933">Select a Grading Method</font></h2>';
   my $handgrade = ($allkeys =~ /parameter_.*?_handgrade/ ? 'yes' : 'no');      $result.='<table border="0">';
   my ($responsetype,$foo) = split(/_/,&Apache::lonnet::metadata($url,'packages'));      $result.='<tr><td colspan=3><font size=+1><b>Resource: </b>'.$url.'</font></td></tr>';
   $allkeys=~s/,/\<br\>/g;      my ($partlist,$handgrade) = &response_type($url);
 #  print "allkeys=$allkeys<br><br>";      my ($resptype,$hdgrade)=('','no');
   $Apache::lonxml::debug=1;      for (sort keys(%$handgrade)) {
   &Apache::lonxml::debug(join(':',&Apache::lonnet::metadata($url,'packages')));   my ($responsetype,$handgrade)=split(/:/,$$handgrade{$_});
   $Apache::lonxml::debug=0;   $resptype = $responsetype;
    $hdgrade = $handgrade if ($handgrade eq 'yes');
   my $result='<h2>&nbsp;<font color="#339933">Select a Grading Method</font></h2>';   $result.='<tr><td><b>Part id: </b>'.$_.'</td>'.
   $result.='<table border="0">';      '<td><b>Type: </b>'.$responsetype.'</td>'.
   $result.='<tr><td><font size=+1><b>Resource: </b></font></td>'.      '<td><b>Handgrade: </b>'.$handgrade.'</font></td></tr>';
       '<td><font size=+1>'.$url.'</font></td></tr>';      }
   $result.='<tr><td><font size=+1><b>Type: </b></font></td>'.      $result.='</table>';
       '<td><font size=+1>'.$responsetype.'&nbsp;&nbsp;<b>Handgrade: </b>'.$handgrade.'</font></td></tr>';      $result.=&view_edit_entire_class_form($symb,$url).'<br />';
   $result.='</table>';      $result.=&upcsvScores_form($symb,$url).'<br />';
   my $t0=&Time::HiRes::time();      $result.=&viewGradeaStu_form($symb,$url,$resptype,$hdgrade).'<br />';
   $result.=&view_edit_entire_class_form($symb,$url).'<br />';      $result.=&verifyReceipt_form($symb,$url).'<br />';
   my $t1=&Time::HiRes::time();      $result.=&view_classlist_form($symb,$url);
   print "elapsed10=",$t1-$t0,"<br />";  
   $result.=&upcsvScores_form($symb,$url).'<br />';      return $result;
   my $t2=&Time::HiRes::time();  }
   print "elapsed21=",$t2-$t1,"<br />";  
   $result.=&viewGradeaStu_form($symb,$url,$responsetype,$handgrade).'<br />';  sub view_classlist_form {
   my $t3=&Time::HiRes::time();      my ($symb,$url)=@_;
   print "elapsed32=",$t3-$t2,"<br />";      my $result.='<table width=100% border=0><tr><td bgcolor=#777777>'."\n";
   $result.=&verifyReceipt_form($symb,$url);      $result.='<table width=100% border=0><tr bgcolor="#e6ffff"><td>'."\n";
   my $t4=&Time::HiRes::time();      $result.='&nbsp;<b>View Class List</b></td></tr>'."\n";
   print "elapsed43=",$t4-$t3,"<br />";      $result.='<tr bgcolor=#ffffe6><td>'."\n";
   print "Total elapsed time=",$t4-$t0,"<br />";      $result.='<form action="/adm/grades" method="post">'."\n".
   return $result;   '<input type="hidden" name="symb" value="'.$symb.'" />'."\n".
    '<input type="hidden" name="url" value="'.$url.'" />'."\n".
    '<input type="hidden" name="command" value="viewclasslist" />'."\n";
       $result.='&nbsp;<input type="submit" name="submit" value="View Class" /></form>'."\n";
       $result.='</td></tr></table>'."\n";
       $result.='</td></tr></table>'."\n";
       return $result;
   }
   
   sub viewclasslist {
       my ($request) = shift;
       my ($coursedomain,$coursenum) = split(/_/,$ENV{'request.course.id'});
       my %classlist=&Apache::lonnet::dump('classlist',$coursedomain,$coursenum);
       $request->print('<table border=1>');
       foreach (sort keys(%classlist)) {
   #    my ($unam,$udom) = split(/:/,$_,2);
   #    my $section = &Apache::lonnet::usection($udom,$unam,$ENV{'request.course.id'});
   #    my $fullname = &get_fullname ($unam,$udom);
   #    my @uname;
   #    $uname[0]=$unam;
   #    my %userid=&Apache::lonnet::idrget($udom,@uname);
   #    my $value=$classlist{$_}.':'.$userid{$unam}.':'.$section.':'.$fullname;
   #    $classlist{$_}=$value;
    $request->print('<tr><td>'.$_.' </td><td><pre> '.$classlist{$_}.'</pre></td></tr>');
       }
       $request->print('</table>');
   #  my $putresult = &Apache::lonnet::put
   #      ('classlist',\%classlist,
   #       $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
   #       $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
   
       return '';
 }  }
   
 sub view_edit_entire_class_form {  sub view_edit_entire_class_form {
   my ($symb,$url)=@_;      my ($symb,$url)=@_;
   my $result.='<table width=100% border=0><tr><td bgcolor=#777777>'."\n";      my ($classlist,$sections) = &getclasslist('all','0');
   $result.='<table width=100% border=0><tr bgcolor="#e6ffff"><td>'."\n";      my $result.='<table width=100% border=0><tr><td bgcolor=#777777>'."\n";
   $result.='&nbsp;<b>View/Grade Entire Class</b></td></tr>'."\n";      $result.='<table width=100% border=0><tr bgcolor="#e6ffff"><td>'."\n";
   $result.='<tr bgcolor=#ffffe6><td>'."\n";      $result.='&nbsp;<b>View/Grade Entire Section/Class</b></td></tr>'."\n";
   $result.='<form action="/adm/grades" method="post">'."\n".      $result.='<tr bgcolor=#ffffe6><td>'."\n";
     '<input type="hidden" name="symb" value="'.$symb.'" />'."\n".      $result.='<form action="/adm/grades" method="post">'."\n".
       '<input type="hidden" name="url" value="'.$url.'" />'."\n".   '<input type="hidden" name="symb" value="'.$symb.'" />'."\n".
   '<input type="hidden" name="command" value="viewgrades" />'."\n";   '<input type="hidden" name="url" value="'.$url.'" />'."\n".
   $result.='&nbsp;<b>Display students who has: </b>'.   '<input type="hidden" name="command" value="viewgrades" />'."\n";
       '<input type="radio" name="submitonly" value="yes" checked> submitted'.      $result.='&nbsp;<b>Select section:</b> <select name="section">'."\n";
   '<input type="radio" name="submitonly" value="all"> everybody <br /><br />';      foreach (sort (@$sections)) {
   $result.='&nbsp;<input type="submit" name="submit" value="View/Grade" /></form>'."\n";   $result.= '<option>'.$_.'</option>'."\n";
   $result.='</td></tr></table>'."\n";      }
   $result.='</td></tr></table>'."\n";      $result.= '<option selected="on">all</select>'."<br />\n";
   return $result;  #    $result.='&nbsp;<b>Display students who has: </b>'.
   # '<input type="radio" name="submitonly" value="yes" checked> submitted'.
   # '<input type="radio" name="submitonly" value="all"> everybody <br /><br />';
       $result.='&nbsp;<input type="submit" name="submit" value="View/Grade" /></form>'."\n";
       $result.='</td></tr></table>'."\n";
       $result.='</td></tr></table>'."\n";
       return $result;
 }  }
   
 sub upcsvScores_form {  sub upcsvScores_form {
   my ($symb,$url) = @_;      my ($symb,$url) = @_;
   if (!$symb) {return '';}      if (!$symb) {return '';}
   my $result.='<table width=100% border=0><tr><td bgcolor=#777777>'."\n";      my $result.='<table width=100% border=0><tr><td bgcolor=#777777>'."\n";
   $result.='<table width=100% border=0><tr bgcolor="#e6ffff"><td>'."\n";      $result.='<table width=100% border=0><tr bgcolor="#e6ffff"><td>'."\n";
   $result.='&nbsp;<b>Specify a file containing the class scores for above resource</b></td></tr>'."\n";      $result.='&nbsp;<b>Specify a file containing the class scores for above resource</b></td></tr>'."\n";
   $result.='<tr bgcolor=#ffffe6><td>'."\n";      $result.='<tr bgcolor=#ffffe6><td>'."\n";
   my $upfile_select=&Apache::loncommon::upfile_select_html();      my $upfile_select=&Apache::loncommon::upfile_select_html();
   $result.=<<ENDUPFORM;    $result.=<<ENDUPFORM;
 <form method="post" enctype="multipart/form-data" action="/adm/grades" name="gradesupload">  <form method="post" enctype="multipart/form-data" action="/adm/grades" name="gradesupload">
 <input type="hidden" name="symb" value="$symb" />  <input type="hidden" name="symb" value="$symb" />
Line 876  $upfile_select Line 1003  $upfile_select
 <br />&nbsp;<input type="submit" name="submit" value="Upload Grades" />  <br />&nbsp;<input type="submit" name="submit" value="Upload Grades" />
 </form>  </form>
 ENDUPFORM  ENDUPFORM
   $result.='</td></tr></table>'."\n";      $result.='</td></tr></table>'."\n";
   $result.='</td></tr></table>'."\n";      $result.='</td></tr></table>'."\n";
   return $result;      return $result;
 }  }
   
 sub viewGradeaStu_form {  sub viewGradeaStu_form {
   my ($symb,$url,$response,$handgrade) = @_;      my ($symb,$url,$response,$handgrade) = @_;
       my ($classlist,$sections) = &getclasslist('all','0');
       my $result.='<table width=100% border=0><tr><td bgcolor=#777777>'."\n";
       $result.='<table width=100% border=0><tr bgcolor="#e6ffff"><td>'."\n";
       $result.='&nbsp;<b>View/Grade an Individual Student\'s Submission</b></td></tr>'."\n";
       $result.='<tr bgcolor=#ffffe6><td>'."\n";
       $result.='<form action="/adm/grades" method="post">'."\n".
    '<input type="hidden" name="symb" value="'.$symb.'" />'."\n".
    '<input type="hidden" name="url" value="'.$url.'" />'."\n".
    '<input type="hidden" name="response" value="'.$response.'" />'."\n".
    '<input type="hidden" name="handgrade" value="'.$handgrade.'" />'."\n".
    '<input type="hidden" name="showgrading" value="yes" />'."\n".
    '<input type="hidden" name="command" value="submission" />'."\n";
   
       $result.='&nbsp;<b>Select section:</b> <select name="section">'."\n";
       foreach (sort (@$sections)) {
    $result.= '<option>'.$_.'</option>'."\n";
       }
       $result.= '<option selected="on">all</select>'."\n";
       $result.='&nbsp;&nbsp;<b>Display students who has: </b>'.
    '<input type="radio" name="submitonly" value="yes" checked> submitted'.
    '<input type="radio" name="submitonly" value="all"> everybody <br />';
       $result.='&nbsp;(Section "no" implies the students were not assigned a section.)<br />' 
    if (grep /no/,@$sections);
       
       $result.='<br />&nbsp;<input type="submit" name="submit" value="View/Grade" />'."\n".
    '</form>'."\n";
       $result.='</td></tr></table>'."\n";
       $result.='</td></tr></table>'."\n";
       return $result;
   }
   
   sub verifyReceipt_form {
       my ($symb,$url) = @_;
       my $cdom=$ENV{"course.$ENV{'request.course.id'}.domain"};
       my $cnum=$ENV{"course.$ENV{'request.course.id'}.num"};
       my $hostver=unpack("%32C*",$Apache::lonnet::perlvar{'lonHostID'});
   
       my $result.='<table width=100% border=0><tr><td bgcolor=#777777>'."\n";
       $result.='<table width=100% border=0><tr><td bgcolor=#e6ffff>'."\n";
       $result.='&nbsp;<b>Verify a Submission Receipt Issued by this Server</td></tr>'."\n";
       $result.='<tr bgcolor=#ffffe6><td>'."\n";
       $result.='<form action="/adm/grades" method="post">'."\n";
       $result.='&nbsp;<tt>'.$hostver.'-<input type="text" name="receipt" size="4"></tt><br />'."\n";
       $result.='&nbsp;<input type="submit" name="submit" value="Verify Receipt">'."\n";
       $result.='<input type="hidden" name="command" value="verify">'."\n";
       if ($ENV{'form.url'}) {
    $result.='<input type="hidden" name="url" value="'.$ENV{'form.url'}.'" />';
       }
       if ($ENV{'form.symb'}) {
    $result.='<input type="hidden" name="symb" value="'.$ENV{'form.symb'}.'" />';
       }
       $result.='</form>';
       $result.='</td></tr></table>'."\n";
       $result.='</td></tr></table>'."\n";
       return $result;
   }
   
   my $t3=&Time::HiRes::time();  sub viewgrades {
       my ($request) = @_;
       $request->print(<<VIEWJAVASCRIPT);
   <script type="text/javascript" language="javascript">
       function viewOneStudent(user) {
    document.onestudent.student.value = user;
    document.onestudent.submit();
       }
   
   my ($classlist,$sections) = &getclasslist('all','0');  
   
   my $t4=&Time::HiRes::time();      function writePoint(partid,weight,point) {
   print "elapsed_getclasslist=",$t4-$t3,"<br />";   for (i=0;i<document.classgrade.total.value;i++) {
       var user = eval("document.classgrade.counter"+i+".value");
       var scorename = eval("document.classgrade.GRADE_"+user+"_"+partid+"_awarded");
       scorename.value = point;
    }
   }
   </script>
   VIEWJAVASCRIPT
   
       my ($symb,$url) = ($ENV{'form.symb'},$ENV{'form.url'}); 
       $request->print ('<h2><font color="#339933">Manual Grading</font></h2>');
   
   my $result.='<table width=100% border=0><tr><td bgcolor=#777777>'."\n";      my $result='<table border="0">';
   $result.='<table width=100% border=0><tr bgcolor="#e6ffff"><td>'."\n";      $result.='<tr><td colspan=3><font size=+1><b>Resource: </b>'.$ENV{'form.url'}.
   $result.='&nbsp;<b>View/Grade an Individual Student\'s Submission</b></td></tr>'."\n";   '</font></td></tr>'."\n";
   $result.='<tr bgcolor=#ffffe6><td>'."\n";      my ($partlist,$handgrade) = &response_type($ENV{'form.url'});
   $result.='<form action="/adm/grades" method="post">'."\n".      my %weight = ();
      '<input type="hidden" name="symb" value="'.$symb.'" />'."\n".      for (sort keys(%$handgrade)) {
       '<input type="hidden" name="url" value="'.$url.'" />'."\n".   my ($responsetype,$handgrade)=split(/:/,$$handgrade{$_});
        '<input type="hidden" name="response" value="'.$response.'" />'."\n".   my ($partid,$respid) = split (/_/);
         '<input type="hidden" name="handgrade" value="'.$handgrade.'" />'."\n".   my $wgt = &Apache::lonnet::EXT('resource.'.$partid.'.weight',$symb);
  '<input type="hidden" name="command" value="submission" />'."\n";   $weight{$partid} = $wgt eq '' ? '1' : $wgt;
    $result.='<tr><td><b>Part id: </b>'.$partid.'</td>'.
       '<td><b>Type: </b>'.$responsetype.'</td>'.
       '<td><b>Handgrade: </b>'.$handgrade.'</font></td></tr>'."\n";
       }
       $request->print($result.'</table>'."\n");
   
       #view individual student submission form - called using Javascript viewOneStudent
       $result = '<form action="/adm/grades" method="post" name="onestudent">'."\n".
    '<input type="hidden" name="symb"    value="'.$symb.'" />'."\n".
    '<input type="hidden" name="url"     value="'.$url.'" />'."\n".
    '<input type="hidden" name="command" value="submission" />'."\n".
    '<input type="hidden" name="student" value="" />'."\n".
    '</form>'."\n";
   
       #start the form
       $result.= '<form action="/adm/grades" method="post" name="classgrade">'."\n".
    '<input type="hidden" name="symb"    value="'.$symb.'" />'."\n".
    '<input type="hidden" name="url"     value="'.$url.'" />'."\n".
    '<input type="hidden" name="command" value="editgrades" />'."\n".
    '<input type="hidden" name="section" value="'.$ENV{'form.section'}.'" />'."\n";
       $result.='To assign the same score for all the students use the radio buttons or box below. '.
    'To assign individual score fill in the score for each student in the table below.<br />';
       $result.='<table border="0">';
       for (sort keys (%weight)) {
    my $ctr = 0;
    $result.='<tr><td><b>Part</b> '.$_.'</td><td>';
    $result.='<table border="0"><tr>';  # display radio buttons in a nice table 10 across
    while ($ctr<=$weight{$_}) {
       $result.= '<td><input type="radio" name="RADVAL_'.$_.'" '.
    'onclick="javascript:writePoint('.$_.','.$weight{$_}.
    ','.$ctr.')" />'.$ctr."</td>\n";
       $result.=(($ctr+1)%10 == 0 ? '</tr><tr>' : '');
       $ctr++;
    }
    $result.='</tr></table>';
       }
       $result.='</tr></table>';
   
   $result.='&nbsp;<b>Select section:</b> <select name="section">'."\n";      $result.= '<input type="submit" name="submit"  value="Submit Changes" />'."\n".
   foreach my $section (sort (@$sections)) {   '<table border=0><tr><td bgcolor="#777777">'."\n".
       $result.= '<option>'.$section.'</option>'."\n";   '<table border=0><tr bgcolor="#deffff">'.
   }   '<td><b>Username</b></td><td><b>Fullname</b></td><td><b>Domain</b></td>'."\n";
   $result.= '<option selected="on">all</select>'."\n";      #get list of parts for this problem
   $result.='&nbsp;&nbsp;<b>Display students who has: </b>'.      my (@parts) = sort(&getpartlist($url));
       '<input type="radio" name="submitonly" value="yes" checked> submitted'.      foreach my $part (@parts) {
   '<input type="radio" name="submitonly" value="all"> everybody <br />';   my $display=&Apache::lonnet::metadata($url,$part.'.display');
   $result.='&nbsp;(Section "no" implies the students were not assigned a section.)<br />'    next if ($display =~ /^Number of Attempts/);
       if (grep /no/,@$sections);   if  (!$display) { $display = &Apache::lonnet::metadata($url,$part.'.name'); }
    if ($display =~ /^Partial Credit Factor/) {
   $result.='<br />&nbsp;<input type="submit" name="submit" value="View/Grade" />'."\n".      $_ = $display;
       '</form>'."\n";      my ($partid) = /.*?(\d+).*/;
   $result.='</td></tr></table>'."\n";      $result.='<td><b>Score Part '.$partid.'<br>(weight = '.$weight{$partid}.')</b></td>'."\n";
   $result.='</td></tr></table>'."\n";      next;
   return $result;   }
    $display =~ s/Problem Status/Grade Status/;
    $result.='<td><b>'.$display.'</b></td>'."\n";
       }
       $result.='</tr>';
       #get info for each student
       my ($classlist,$seclist,$ids,$stusec,$fullname) = &getclasslist($ENV{'form.section'},'0');
       my $ctr = 0;
       foreach ( sort(@{ $$classlist{$ENV{'form.section'}} }) ) {
    (my $username = $_) = split(/:/);
    $result.='<input type="hidden" name="counter'.$ctr.'" value="'.$username.'" />'."\n";
    $result.=&viewstudentgrade($url,$symb,$ENV{'request.course.id'},
      $_,$$fullname{$_},\@parts,\%weight);
    $ctr++;
       }
       $result.='</table></td></tr></table>';
       $result.='<input type="hidden" name="total" value="'.$ctr.'" />'."\n";
       $result.='<input type="submit" name="submit" value="Submit Changes" /></form>';
       $result.=&show_grading_menu_form($symb,$url);
       return $result;
 }  }
   
 sub verifyReceipt_form {  sub viewstudentgrade {
   my ($symb,$url) = @_;      my ($url,$symb,$courseid,$student,$fullname,$parts,$weight) = @_;
   my $cdom=$ENV{"course.$ENV{'request.course.id'}.domain"};      my ($username,$domain) = split(/:/,$student);
   my $cnum=$ENV{"course.$ENV{'request.course.id'}.num"};      my %record=&Apache::lonnet::restore($symb,$courseid,$domain,$username);
   my $hostver=unpack("%32C*",$Apache::lonnet::perlvar{'lonHostID'});      my $result='<tr bgcolor="#ffffdd"><td>'.
    '<a href="javascript:viewOneStudent(\''.$username.'\')"; TARGET=_self>'.$username.'</a>'.
   my $result.='<table width=100% border=0><tr><td bgcolor=#777777>'."\n";   '</td><td>'.$fullname.'</td><td align="middle">'.$domain.'</td>'."\n";
   $result.='<table width=100% border=0><tr><td bgcolor=#e6ffff>'."\n";      foreach my $part (@$parts) {
   $result.='&nbsp;<b>Verify a Submission Receipt Issued by this Server</td></tr>'."\n";   my ($temp,$part,$type)=split(/_/,$part);
   $result.='<tr bgcolor=#ffffe6><td>'."\n";   my $score=$record{"resource.$part.$type"};
   $result.='<form action="/adm/grades" method="post">'."\n";   next if $type eq 'tries';
   $result.='&nbsp;<tt>'.$hostver.'-<input type="text" name="receipt" size="4"></tt><br />'."\n";   if ($type eq 'awarded') {
   $result.='&nbsp;<input type="submit" name="submit" value="Verify Receipt">'."\n";      my $pts = $score*$$weight{$part};
   $result.='<input type="hidden" name="command" value="verify">'."\n";      $result.='<td align="middle"><input type="text" name="GRADE_'.$username.'_'.$part.'_'.$type.
   if ($ENV{'form.url'}) {   '" value="'.$pts.'" size="4" /></td>'."\n";
       $result.='<input type="hidden" name="url" value="'.$ENV{'form.url'}.'" />';  #    $result.='<td align="middle"><input type="text" name="GRADE.'.$student.'.'.$part.'.'.$type.
   }  # '" value="'.$pts.'" size="4" /></td>'."\n";
   if ($ENV{'form.symb'}) {  # } elsif ($type eq 'tries') {
       $result.='<input type="hidden" name="symb" value="'.$ENV{'form.symb'}.'" />';  #    $result.='<td align="middle">'.$score.'&nbsp;</td>'."\n";
   }   } elsif ($type eq 'solved') {
   $result.='</form>';      my ($status,$foo)=split(/_/,$score,2);
   $result.='</td></tr></table>'."\n";      $result.="<td align=\"middle\"><select name=\"GRADE.$student.$part.$type\">\n";
   $result.='</td></tr></table>'."\n";      my $optsel = '<option>correct</option><option>incorrect</option><option>excused</option>'.
   return $result;   '<option>ungraded</option><option>nothing</option>'."\n";
       $status = 'nothing' if ($status eq '');
       $optsel =~ s/<option>$status/<option selected="on">$status/;
       $result.=$optsel;
       $result.="</select></td>\n";
    }
       }
       $result.='</tr>';
       return $result;
 }  }
   
 sub viewgrades {  
   my ($request) = @_;  
   my $result='';  
   
   #get resource reference  
   my ($symb,$url)=&get_symb_and_url($request);  
   if (!$symb) {return '';}  
   #get classlist  
   my ($cdom,$cnum) = split(/_/,$ENV{'request.course.id'});  
   #print "Found $cdom:$cnum<br />";  
   my ($classlist) = &getclasslist('all','0');  
   my $headerclr = '"#ddffff"';  
   my $cellclr = '"#ffffdd"';  
   
   #get list of parts for this problem  
   my (@parts) = sort(&getpartlist($url));  
   
   $request->print ("<h2><font color=\"#339933\">Manual Grading</font></h2>");  
   
   #start the form  
   $result = '<form action="/adm/grades" method="post">'."\n".  
     '<input type="hidden" name="symb" value="'.$symb.'" />'."\n".  
       '<input type="hidden" name="url" value="'.$url.'" />'."\n".  
  '<input type="hidden" name="command" value="editgrades" />'."\n".  
   '<input type="submit" name="submit" value="Submit Changes" />'."\n".  
     '<table border=0><tr><td bgcolor="#777777">'."\n".  
      '<table border=0>'."\n".  
       '<tr bgcolor='.$headerclr.'><td><b>Username</b></td><td><b>Fullname</b></td><td><b>Domain</b></td>'."\n";  
   foreach my $part (@parts) {  
      my $display=&Apache::lonnet::metadata($url,$part.'.display');  
      if  (!$display) { $display = &Apache::lonnet::metadata($url,$part.'.name'); }  
      $result.='<td><b>'.$display.'</b></td>'."\n";  
   }  
   $result.='</tr>';  
   #get info for each student  
   foreach my $student ( sort(@{ $$classlist{'all'} }) ) {  
 #    my $display=&viewstudentgrade($url,$symb,$ENV{'request.course.id'},$student,@parts);  
 #      print "ID=$ENV{'request.course.id'}:STU=$student:DIS=$display:<br>\n";  
     $result.=&viewstudentgrade($url,$symb,$ENV{'request.course.id'},$student,@parts);  
   }  
   $result.='</table></td></tr></table>';  
   $result.='<input type="submit" name="submit" value="Submit Changes" /></form>';  
   $result.=&show_grading_menu_form($symb,$url);  
   return $result;  
 }  
   
 sub editgrades {  sub editgrades {
   my ($request) = @_;      my ($request) = @_;
   my $result='';  
   
   my $symb=$ENV{'form.symb'};      my $symb=$ENV{'form.symb'};
   if ($symb eq '') { $request->print("Unable to handle ambiguous references:$symb:$ENV{'form.url'}"); return ''; }      if ($symb eq '') { $request->print("Unable to handle ambiguous references:$symb:$ENV{'form.url'}"); return ''; }
   my $url=$ENV{'form.url'};      my $url=$ENV{'form.url'};
   #get classlist  
 #  my ($cdom,$cnum) = split(/_/,$ENV{'request.course.id'});  
   #print "Found $cdom:$cnum<br />";  
   my ($classlist) = &getclasslist('all','0');  
   
   #get list of parts for this problem  
   my (@parts) = &getpartlist($url);  
   
   $result.='<form action="/adm/grades" method="post">'."\n".  
     '<input type="hidden" name="symb" value="'.$symb.'" />'."\n".  
       '<input type="hidden" name="url" value="'.$url.'" />'."\n".  
  '<input type="hidden" name="command" value="viewgrades" />'."\n".  
   '<input type="submit" name="submit" value="See Grades" /> <br />'."\n";  
   
   foreach my $student ( sort(@{ $$classlist{'all'} }) ) {      my $result.='<form action="/adm/grades" method="post">'."\n".
     $result.=&setstudentgrade($url,$symb,$ENV{'request.course.id'},$student,@parts);   '<input type="hidden" name="symb" value="'.$symb.'" />'."\n".
   }   '<input type="hidden" name="url" value="'.$url.'" />'."\n".
    '<input type="hidden" name="command" value="viewgrades" />'."\n".
    '<input type="submit" name="submit" value="See Grades" /> <br />'."\n";
       
       my (@parts) = &getpartlist($url);
       my ($classlist) = &getclasslist($ENV{'form.section'},'0');
       foreach my $student ( sort(@{ $$classlist{$ENV{'form.section'}} }) ) {
    $result.=&setstudentgrade($url,$symb,$ENV{'request.course.id'},$student,@parts);
       }
   
   $result.='<input type="submit" name="submit" value="See Grades" /></table></form>';      $result.='<input type="submit" name="submit" value="See Grades" /></table></form>';
   return $result;      return $result;
 }  }
   
 sub sub_page_js {  sub sub_page_js {
   my $request = shift;      my $request = shift;
   $request->print(<<SUBJAVASCRIPT);      $request->print(<<SUBJAVASCRIPT);
 <script type="text/javascript" language="javascript">  <script type="text/javascript" language="javascript">
   function updateRadio(radioButton,formtextbox,formsel,wgt) {    function updateRadio(radioButton,formtextbox,formsel,scores) {
      var pts = formtextbox.value;       var pts = formtextbox.value;
      var resetbox =false;       var resetbox =false;
      if (isNaN(pts) || pts < 0) {       if (isNaN(pts) || pts < 0) {
Line 1050  sub sub_page_js { Line 1260  sub sub_page_js {
    radioButton[i].checked=true;     radioButton[i].checked=true;
  }   }
     }      }
     updateSelect(formsel,pts,wgt);      updateSelect(formsel);
       scores.value = "0";
   }    }
   
   function writeBox(formrad,formsel,pts,wgt) {    function writeBox(formrad,formsel,pts,scores) {
     formrad.value = pts;      formrad.value = pts;
     updateSelect(formsel,pts,wgt);      scores.value = "0";
       updateSelect(formsel,pts);
     return;      return;
   }    }
   
   function updateSelect(formsel,pts,wgt) {    function clearRadBox(radioButton,formbox,formsel,scores) {
     if (pts == 0) {      for (var i=0; i<formsel.length; i++) {
       formsel[1].selected = true;   if (formsel[i].selected) {
     }      var selectx=i;
     if (pts > 0 && pts < wgt) {   }
       formsel[4].selected = true;  
     }      }
     if (pts == wgt) {      if (selectx == scores.value) { return };
       formsel[0].selected = true;      formbox.value = "";
       for (var i=0; i<radioButton.length; i++) {
    radioButton[i].checked=false;
     }      }
       scores.value = selectx;
     }
   
     function updateSelect(formsel) {
       formsel[0].selected = true;
     return;      return;
   }    }
   
   //===================== Show list of keywords ====================
   function keywords(keyform) {    function keywords(keyform) {
     var keywds = keyform.value;      var keywds = keyform.value;
     var nret = prompt("Keywords list, separated by a space. Add/delete to list if desired.",keywds);      var nret = prompt("Keywords list, separated by a space. Add/delete to list if desired.",keywds);
Line 1080  sub sub_page_js { Line 1299  sub sub_page_js {
     return;      return;
   }    }
   
   //===================== Script to view submitted by ==================
     function viewSubmitter(submitter) {
       document.SCORE.refresh.value = "on";
       document.SCORE.NCT.value = "1";
       document.SCORE.unamedom0.value = submitter;
       document.SCORE.submit();
       return;
     }
   
 //===================== Script to add keyword(s) ==================  //===================== Script to add keyword(s) ==================
   function getSel() {    function getSel() {
     if (document.getSelection) txt = document.getSelection();      if (document.getSelection) txt = document.getSelection();
Line 1202  function displaySavedMsg(ctr,msg,shwsel) Line 1430  function displaySavedMsg(ctr,msg,shwsel)
     pWin.document.write("<tr bgcolor=\\"#ffffdd\\">");      pWin.document.write("<tr bgcolor=\\"#ffffdd\\">");
     pWin.document.write("<td align=\\"center\\">New</td>");      pWin.document.write("<td align=\\"center\\">New</td>");
     pWin.document.write("<td align=\\"center\\"><input name=\\"newmsgchk\\" type=\\"checkbox\\"" +shwsel+"></td>");      pWin.document.write("<td align=\\"center\\"><input name=\\"newmsgchk\\" type=\\"checkbox\\"" +shwsel+"></td>");
     pWin.document.write("<td><input name=\\"newmsg\\" type=\\"text\\" value=\\""+newmsg+" \\" size=\\"60\\" maxlength=\\"80\\"></td></tr>");      pWin.document.write("<td><input name=\\"newmsg\\" type=\\"text\\" onchange=\\"javascript:this.form.newmsgchk.checked=true\\" value=\\""+newmsg+" \\" size=\\"60\\" maxlength=\\"80\\"></td></tr>");
 }  }
   
   function msgTail() {    function msgTail() {
Line 1252  function displaySavedMsg(ctr,msg,shwsel) Line 1480  function displaySavedMsg(ctr,msg,shwsel)
     hwdWin.document.write("<title>Highlight Central</title>");      hwdWin.document.write("<title>Highlight Central</title>");
   
     hwdWin.document.write("<script language=javascript>");      hwdWin.document.write("<script language=javascript>");
     hwdWin.document.write("function updateChoice() {");      hwdWin.document.write("function updateChoice(flag) {");
     hwdWin.document.write("  opener.document.SCORE.kwclr.value = radioSelection(document.hlCenter.kwdclr);");      hwdWin.document.write("  opener.document.SCORE.kwclr.value = radioSelection(document.hlCenter.kwdclr);");
     hwdWin.document.write("  opener.document.SCORE.kwsize.value = radioSelection(document.hlCenter.kwdsize);");      hwdWin.document.write("  opener.document.SCORE.kwsize.value = radioSelection(document.hlCenter.kwdsize);");
     hwdWin.document.write("  opener.document.SCORE.kwstyle.value = radioSelection(document.hlCenter.kwdstyle);");      hwdWin.document.write("  opener.document.SCORE.kwstyle.value = radioSelection(document.hlCenter.kwdstyle);");
   //    hwdWin.document.write("     var kwords=opener.document.SCORE.keywords.value;");
   //    hwdWin.document.write("     alert(\\"keywords=\\"+opener.document.SCORE.keywords.value);");
   //    hwdWin.document.write("     return;");
   
       hwdWin.document.write("  if (flag==1){");
       hwdWin.document.write("     opener.document.SCORE.refresh.value = \\"on\\";");
       hwdWin.document.write("     if (opener.document.SCORE.keywords.value!=\\"\\"){");
       hwdWin.document.write("        opener.document.SCORE.submit();");
       hwdWin.document.write("     }");
       hwdWin.document.write("   }");
     hwdWin.document.write("  self.close()");      hwdWin.document.write("  self.close()");
     hwdWin.document.write("}");      hwdWin.document.write("}");
   
Line 1296  function displaySavedMsg(ctr,msg,shwsel) Line 1534  function displaySavedMsg(ctr,msg,shwsel)
   function highlightend() {     function highlightend() { 
     hwdWin.document.write("</table>");      hwdWin.document.write("</table>");
     hwdWin.document.write("</td></tr></table>&nbsp;");      hwdWin.document.write("</td></tr></table>&nbsp;");
     hwdWin.document.write("<input type=\\"button\\" value=\\"Set Options\\" onClick=\\"javascript:updateChoice()\\">&nbsp;&nbsp;");      hwdWin.document.write("<input type=\\"button\\" value=\\"Save\\" onClick=\\"javascript:updateChoice(0)\\">&nbsp;&nbsp;");
       hwdWin.document.write("<input type=\\"button\\" value=\\"Save & Refresh\\" onClick=\\"javascript:updateChoice(1)\\">&nbsp;&nbsp;");
     hwdWin.document.write("<input type=\\"button\\" value=\\"Cancel\\" onClick=\\"self.close()\\"><br><br>");      hwdWin.document.write("<input type=\\"button\\" value=\\"Cancel\\" onClick=\\"self.close()\\"><br><br>");
     hwdWin.document.write("</form>");      hwdWin.document.write("</form>");
     hwdWin.document.write("</body></html>");      hwdWin.document.write("</body></html>");
Line 1380  ENDPICK Line 1619  ENDPICK
 }  }
   
 sub csvuploadmap_header {  sub csvuploadmap_header {
   my ($request,$symb,$url,$datatoken,$distotal)= @_;      my ($request,$symb,$url,$datatoken,$distotal)= @_;
   my $result;      my $result;
   my $javascript;      my $javascript;
   if ($ENV{'form.upfile_associate'} eq 'reverse') {      if ($ENV{'form.upfile_associate'} eq 'reverse') {
     $javascript=&csvupload_javascript_reverse_associate();   $javascript=&csvupload_javascript_reverse_associate();
   } else {      } else {
     $javascript=&csvupload_javascript_forward_associate();   $javascript=&csvupload_javascript_forward_associate();
   }      }
   $request->print(<<ENDPICK);      $request->print(<<ENDPICK);
 <form method="post" enctype="multipart/form-data" action="/adm/grades" name="gradesupload">  <form method="post" enctype="multipart/form-data" action="/adm/grades" name="gradesupload">
 <h3>Uploading Class Grades for resource $url</h3>  <h3>Uploading Class Grades for resource $url</h3>
 <hr>  <hr>
Line 1412  to this page if the data selected is ins Line 1651  to this page if the data selected is ins
 $javascript  $javascript
 </script>  </script>
 ENDPICK  ENDPICK
   return '';  return '';
   
 }  }
   
 sub csvupload_fields {  sub csvupload_fields {
   my ($url) = @_;      my ($url) = @_;
   my (@parts) = &getpartlist($url);      my (@parts) = &getpartlist($url);
   my @fields=(['username','Student Username'],['domain','Student Domain']);      my @fields=(['username','Student Username'],['domain','Student Domain']);
   foreach my $part (sort(@parts)) {      foreach my $part (sort(@parts)) {
     my @datum;   my @datum;
     my $display=&Apache::lonnet::metadata($url,$part.'.display');   my $display=&Apache::lonnet::metadata($url,$part.'.display');
     my $name=$part;   my $name=$part;
     if  (!$display) { $display = $name; }   if  (!$display) { $display = $name; }
     @datum=($name,$display);   @datum=($name,$display);
     push(@fields,\@datum);   push(@fields,\@datum);
   }      }
   return (@fields);      return (@fields);
 }  }
   
 sub csvuploadmap_footer {  sub csvuploadmap_footer {
   my ($request,$i,$keyfields) =@_;      my ($request,$i,$keyfields) =@_;
   $request->print(<<ENDPICK);      $request->print(<<ENDPICK);
 </table>  </table>
 <input type="hidden" name="nfields" value="$i" />  <input type="hidden" name="nfields" value="$i" />
 <input type="hidden" name="keyfields" value="$keyfields" />  <input type="hidden" name="keyfields" value="$keyfields" />
Line 1443  ENDPICK Line 1682  ENDPICK
 }  }
   
 sub csvuploadmap {  sub csvuploadmap {
   my ($request)= @_;      my ($request)= @_;
   my ($symb,$url)=&get_symb_and_url($request);      my ($symb,$url)=&get_symb_and_url($request);
   if (!$symb) {return '';}      if (!$symb) {return '';}
   my $datatoken;      my $datatoken;
   if (!$ENV{'form.datatoken'}) {      if (!$ENV{'form.datatoken'}) {
     $datatoken=&Apache::loncommon::upfile_store($request);   $datatoken=&Apache::loncommon::upfile_store($request);
   } else {  
     $datatoken=$ENV{'form.datatoken'};  
     &Apache::loncommon::load_tmp_file($request);  
   }  
   my @records=&Apache::loncommon::upfile_record_sep();  
   &csvuploadmap_header($request,$symb,$url,$datatoken,$#records+1);  
   my $i;  
   my $keyfields;  
   if (@records) {  
     my @fields=&csvupload_fields($url);  
     if ($ENV{'form.upfile_associate'} eq 'reverse') {  
       &Apache::loncommon::csv_print_samples($request,\@records);  
       $i=&Apache::loncommon::csv_print_select_table($request,\@records,  
     \@fields);  
       foreach (@fields) { $keyfields.=$_->[0].','; }  
       chop($keyfields);  
     } else {      } else {
       unshift(@fields,['none','']);   $datatoken=$ENV{'form.datatoken'};
       $i=&Apache::loncommon::csv_samples_select_table($request,\@records,   &Apache::loncommon::load_tmp_file($request);
       \@fields);  
       my %sone=&Apache::loncommon::record_sep($records[0]);  
       $keyfields=join(',',sort(keys(%sone)));  
     }      }
   }      my @records=&Apache::loncommon::upfile_record_sep();
   &csvuploadmap_footer($request,$i,$keyfields);      &csvuploadmap_header($request,$symb,$url,$datatoken,$#records+1);
   return '';      my ($i,$keyfields);
       if (@records) {
    my @fields=&csvupload_fields($url);
    if ($ENV{'form.upfile_associate'} eq 'reverse') {
       &Apache::loncommon::csv_print_samples($request,\@records);
       $i=&Apache::loncommon::csv_print_select_table($request,\@records,
     \@fields);
       foreach (@fields) { $keyfields.=$_->[0].','; }
       chop($keyfields);
    } else {
       unshift(@fields,['none','']);
       $i=&Apache::loncommon::csv_samples_select_table($request,\@records,
       \@fields);
       my %sone=&Apache::loncommon::record_sep($records[0]);
       $keyfields=join(',',sort(keys(%sone)));
    }
       }
       &csvuploadmap_footer($request,$i,$keyfields);
       return '';
 }  }
   
 sub csvuploadassign {  sub csvuploadassign {
   my ($request)= @_;      my ($request)= @_;
   my ($symb,$url)=&get_symb_and_url($request);      my ($symb,$url)=&get_symb_and_url($request);
   if (!$symb) {return '';}      if (!$symb) {return '';}
   &Apache::loncommon::load_tmp_file($request);      &Apache::loncommon::load_tmp_file($request);
   my @gradedata=&Apache::loncommon::upfile_record_sep();      my @gradedata=&Apache::loncommon::upfile_record_sep();
   my @keyfields = split(/\,/,$ENV{'form.keyfields'});      my @keyfields = split(/\,/,$ENV{'form.keyfields'});
   my %fields=();      my %fields=();
   for (my $i=0; $i<=$ENV{'form.nfields'}; $i++) {      for (my $i=0; $i<=$ENV{'form.nfields'}; $i++) {
     if ($ENV{'form.upfile_associate'} eq 'reverse') {   if ($ENV{'form.upfile_associate'} eq 'reverse') {
       if ($ENV{'form.f'.$i} ne 'none') {      if ($ENV{'form.f'.$i} ne 'none') {
  $fields{$keyfields[$i]}=$ENV{'form.f'.$i};   $fields{$keyfields[$i]}=$ENV{'form.f'.$i};
       }      }
     } else {   } else {
       if ($ENV{'form.f'.$i} ne 'none') {      if ($ENV{'form.f'.$i} ne 'none') {
  $fields{$ENV{'form.f'.$i}}=$keyfields[$i];   $fields{$ENV{'form.f'.$i}}=$keyfields[$i];
       }      }
    }
     }      }
   }      $request->print('<h3>Assigning Grades</h3>');
   $request->print('<h3>Assigning Grades</h3>');      my $courseid=$ENV{'request.course.id'};
   my $courseid=$ENV{'request.course.id'};  
 #  my $cdom=$ENV{"course.$courseid.domain"};  #  my $cdom=$ENV{"course.$courseid.domain"};
 #  my $cnum=$ENV{"course.$courseid.num"};  #  my $cnum=$ENV{"course.$courseid.num"};
   my ($classlist) = &getclasslist('all','1');      my ($classlist) = &getclasslist('all','1');
   my @skipped;      my @skipped;
   my $countdone=0;      my $countdone=0;
   foreach my $grade (@gradedata) {      foreach my $grade (@gradedata) {
     my %entries=&Apache::loncommon::record_sep($grade);   my %entries=&Apache::loncommon::record_sep($grade);
     my $username=$entries{$fields{'username'}};   my $username=$entries{$fields{'username'}};
     my $domain=$entries{$fields{'domain'}};   my $domain=$entries{$fields{'domain'}};
     if (!exists($$classlist{"$username:$domain"})) {   if (!exists($$classlist{"$username:$domain"})) {
       push(@skipped,"$username:$domain");      push(@skipped,"$username:$domain");
       next;      next;
     }   }
     my %grades;   my %grades;
     foreach my $dest (keys(%fields)) {   foreach my $dest (keys(%fields)) {
       if ($dest eq 'username' || $dest eq 'domain') { next; }      if ($dest eq 'username' || $dest eq 'domain') { next; }
       if ($entries{$fields{$dest}} eq '') { next; }      if ($entries{$fields{$dest}} eq '') { next; }
       my $store_key=$dest;      my $store_key=$dest;
       $store_key=~s/^stores/resource/;      $store_key=~s/^stores/resource/;
       $store_key=~s/_/\./g;      $store_key=~s/_/\./g;
       $grades{$store_key}=$entries{$fields{$dest}};      $grades{$store_key}=$entries{$fields{$dest}};
     }   }
     $grades{"resource.regrader"}="$ENV{'user.name'}:$ENV{'user.domain'}";   $grades{"resource.regrader"}="$ENV{'user.name'}:$ENV{'user.domain'}";
     &Apache::lonnet::cstore(\%grades,$symb,$ENV{'request.course.id'},   &Apache::lonnet::cstore(\%grades,$symb,$ENV{'request.course.id'},
     $domain,$username);   $domain,$username);
     $request->print('.');   $request->print('.');
     $request->rflush();   $request->rflush();
     $countdone++;   $countdone++;
   }      }
   $request->print("<br />Stored $countdone students\n");      $request->print("<br />Stored $countdone students\n");
   if (@skipped) {      if (@skipped) {
     $request->print('<br /><font size="+1"><b>Skipped Students</b></font><br />');   $request->print('<br /><font size="+1"><b>Skipped Students</b></font><br />');
     foreach my $student (@skipped) { $request->print("<br />$student"); }   foreach my $student (@skipped) { $request->print("<br />$student"); }
   }      }
   $request->print(&view_edit_entire_class_form($symb,$url));      $request->print(&view_edit_entire_class_form($symb,$url));
   $request->print(&show_grading_menu_form($symb,$url));      $request->print(&show_grading_menu_form($symb,$url));
   return '';      return '';
 }  }
   
 sub send_header {  sub send_header {
   my ($request)= @_;      my ($request)= @_;
   $request->print(&Apache::lontexconvert::header());      $request->print(&Apache::lontexconvert::header());
 #  $request->print("  #  $request->print("
 #<script>  #<script>
 #remotewindow=open('','homeworkremote');  #remotewindow=open('','homeworkremote');
 #remotewindow.close();  #remotewindow.close();
 #</script>");   #</script>"); 
   $request->print('<body bgcolor="#FFFFFF">');      $request->print('<body bgcolor="#FFFFFF">');
 }  }
   
 sub send_footer {  sub send_footer {
   my ($request)= @_;      my ($request)= @_;
   $request->print('</body>');      $request->print('</body>');
   $request->print(&Apache::lontexconvert::footer());      $request->print(&Apache::lontexconvert::footer());
 }  }
   
 sub handler {  sub handler {
   my $request=$_[0];      my $request=$_[0];
       
   if ($ENV{'browser.mathml'}) {      if ($ENV{'browser.mathml'}) {
     $request->content_type('text/xml');   $request->content_type('text/xml');
   } else {      } else {
     $request->content_type('text/html');   $request->content_type('text/html');
   }      }
   $request->send_http_header;      $request->send_http_header;
   return OK if $request->header_only;      return OK if $request->header_only;
   &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'});      &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'});
   my $url=$ENV{'form.url'};      my $url=$ENV{'form.url'};
   my $symb=$ENV{'form.symb'};      my $symb=$ENV{'form.symb'};
   my $command=$ENV{'form.command'};      my $command=$ENV{'form.command'};
   if (!$url) {      if (!$url) {
     my ($temp1,$temp2);   my ($temp1,$temp2);
     ($temp1,$temp2,$ENV{'form.url'})=split(/___/,$symb);   ($temp1,$temp2,$ENV{'form.url'})=split(/___/,$symb);
     $url = $ENV{'form.url'};   $url = $ENV{'form.url'};
   }      }
   &send_header($request);      &send_header($request);
   if ($url eq '' && $symb eq '') {      if ($url eq '' && $symb eq '') {
      if ($ENV{'user.adv'}) {   if ($ENV{'user.adv'}) {
          if (($ENV{'form.codeone'}) && ($ENV{'form.codetwo'}) &&      if (($ENV{'form.codeone'}) && ($ENV{'form.codetwo'}) &&
              ($ENV{'form.codethree'})) {   ($ENV{'form.codethree'})) {
              my $token=$ENV{'form.codeone'}.'*'.$ENV{'form.codetwo'}.'*'.   my $token=$ENV{'form.codeone'}.'*'.$ENV{'form.codetwo'}.'*'.
         $ENV{'form.codethree'};      $ENV{'form.codethree'};
              my ($tsymb,$tuname,$tudom,$tcrsid)=   my ($tsymb,$tuname,$tudom,$tcrsid)=
  &Apache::lonnet::checkin($token);      &Apache::lonnet::checkin($token);
              if ($tsymb) {   if ($tsymb) {
                 my ($map,$id,$url)=split(/\_\_\_/,$tsymb);      my ($map,$id,$url)=split(/\_\_\_/,$tsymb);
                 if (&Apache::lonnet::allowed('mgr',$tcrsid)) {      if (&Apache::lonnet::allowed('mgr',$tcrsid)) {
                    $request->print(   $request->print(
                      &Apache::lonnet::ssi('/res/'.$url,   &Apache::lonnet::ssi('/res/'.$url,
                         ('grade_username' => $tuname,       ('grade_username' => $tuname,
                          'grade_domain' => $tudom,        'grade_domain' => $tudom,
                          'grade_courseid' => $tcrsid,        'grade_courseid' => $tcrsid,
                          'grade_symb' => $tsymb)));        'grade_symb' => $tsymb)));
                 } else {      } else {
                    $request->print('<h1>Not authorized: '.$token.'</h1>');   $request->print('<h1>Not authorized: '.$token.'</h1>');
                 }                 }           
    } else {
       $request->print('<h1>Not a valid DocID: '.$token.'</h1>');
    }
     } else {      } else {
                 $request->print('<h1>Not a valid DocID: '.$token.'</h1>');   $request->print(&Apache::lonxml::tokeninputfield());
             }      }
  } else {   }
              $request->print(&Apache::lonxml::tokeninputfield());      } else {
          }   #&Apache::lonhomework::showhashsubset(\%ENV,'^form');
      }   $Apache::grades::viewgrades=&Apache::lonnet::allowed('vgr',$ENV{'request.course.id'});
   } else {   if ($command eq 'submission') {
     #&Apache::lonhomework::showhashsubset(\%ENV,'^form');      &listStudents($request) if ($ENV{'form.student'} eq '');
     $Apache::grades::viewgrades=&Apache::lonnet::allowed('vgr',$ENV{'request.course.id'});      &submission($request,0,0) if ($ENV{'form.student'} ne '');
     if ($command eq 'submission') {   } elsif ($command eq 'processGroup') {
       &listStudents($request) if ($ENV{'form.student'} eq '');      &processGroup($request);
       &submission($request,0,0) if ($ENV{'form.student'} ne '');   } elsif ($command eq 'gradingmenu') {
     } elsif ($command eq 'processGroup') {      $request->print(&gradingmenu($request));
       &processGroup($request);   } elsif ($command eq 'viewgrades') {
     } elsif ($command eq 'gradingmenu') {      $request->print(&viewgrades($request));
       $request->print(&gradingmenu($request));   } elsif ($command eq 'handgrade') {
     } elsif ($command eq 'viewgrades') {      $request->print(&processHandGrade($request));
       $request->print(&viewgrades($request));   } elsif ($command eq 'editgrades') {
     } elsif ($command eq 'handgrade') {      $request->print(&editgrades($request));
       $request->print(&processHandGrade($request));   } elsif ($command eq 'verify') {
     } elsif ($command eq 'editgrades') {      $request->print(&verifyreceipt($request));
       $request->print(&editgrades($request));   } elsif ($command eq 'csvupload') {
     } elsif ($command eq 'verify') {      $request->print(&csvupload($request));
       $request->print(&verifyreceipt($request));   } elsif ($command eq 'viewclasslist') {
     } elsif ($command eq 'csvupload') {      $request->print(&viewclasslist($request));
       $request->print(&csvupload($request));   } elsif ($command eq 'csvuploadmap') {
     } elsif ($command eq 'csvuploadmap') {      $request->print(&csvuploadmap($request));
       $request->print(&csvuploadmap($request));  
 #    } elsif ($command eq 'receiptInput') {  #    } elsif ($command eq 'receiptInput') {
 #      &receiptInput($request);  #      &receiptInput($request);
     } elsif ($command eq 'csvuploadassign') {   } elsif ($command eq 'csvuploadassign') {
       if ($ENV{'form.associate'} ne 'Reverse Association') {      if ($ENV{'form.associate'} ne 'Reverse Association') {
  $request->print(&csvuploadassign($request));   $request->print(&csvuploadassign($request));
       } else {      } else {
  if ( $ENV{'form.upfile_associate'} ne 'reverse' ) {   if ( $ENV{'form.upfile_associate'} ne 'reverse' ) {
   $ENV{'form.upfile_associate'} = 'reverse';      $ENV{'form.upfile_associate'} = 'reverse';
    } else {
       $ENV{'form.upfile_associate'} = 'forward';
    }
    $request->print(&csvuploadmap($request));
       }
  } else {   } else {
   $ENV{'form.upfile_associate'} = 'forward';      $request->print("Unknown action: $command:");
  }   }
  $request->print(&csvuploadmap($request));  
       }  
     } else {  
       $request->print("Unknown action: $command:");  
     }      }
   }      &send_footer($request);
   &send_footer($request);      return OK;
   return OK;  
 }  }
   
 1;  1;

Removed from v.1.38  
changed lines
  Added in v.1.41


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>