--- loncom/homework/grades.pm	2003/12/05 19:40:56	1.168
+++ loncom/homework/grades.pm	2004/03/19 04:20:24	1.183
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # The LON-CAPA Grading handler
 #
-# $Id: grades.pm,v 1.168 2003/12/05 19:40:56 albertel Exp $
+# $Id: grades.pm,v 1.183 2004/03/19 04:20:24 albertel Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -49,7 +49,7 @@ use Apache::loncoursedata;
 use Apache::lonmsg qw(:user_normal_msg);
 use Apache::Constants qw(:common);
 use Apache::lonlocal;
-#use String::Similarity;
+use String::Similarity;
 
 my %oldessays=();
 my %perm=();
@@ -89,10 +89,15 @@ sub getpartlist {
 
 # --- Get the symbolic name of a problem and the url
 sub get_symb_and_url {
-    my ($request) = @_;
+    my ($request,$silent) = @_;
     (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)));
-    if ($symb eq '') { $request->print("Unable to handle ambiguous references:$url:."); return ''; }
+    if ($symb eq '') { 
+	if (!$silent) {
+	    $request->print("Unable to handle ambiguous references:$url:.");
+	    return ();
+	}
+    }
     return ($symb,$url);
 }
 
@@ -521,18 +526,27 @@ sub verifyreceipt {
 
     my ($string,$contents,$matches) = ('','',0);
     my (undef,undef,$fullname) = &getclasslist('all','0');
-
+    
+    my $receiptparts=0;
+    if ($ENV{"course.$courseid.receiptalg"} eq 'receipt2') { $receiptparts=1; }
+    my $parts=['0'];
+    if ($receiptparts) { ($parts)=&response_type($url,$symb); }
     foreach (sort {lc($$fullname{$a}) cmp lc($$fullname{$b}) } keys %$fullname) {
 	my ($uname,$udom)=split(/\:/);
-	if ($receipt eq 
-	    &Apache::lonnet::ireceipt($uname,$udom,$courseid,$symb)) {
-	    $contents.='<tr bgcolor="#ffffe6"><td>&nbsp;'."\n".
-		'<a href="javascript:viewOneStudent(\''.$uname.'\',\''.$udom.
-		'\')"; TARGET=_self>'.$$fullname{$_}.'</a>&nbsp;</td>'."\n".
-		'<td>&nbsp;'.$uname.'&nbsp;</td>'.
-		'<td>&nbsp;'.$udom.'&nbsp;</td></tr>'."\n";
-	    
-	    $matches++;
+	foreach my $part (@$parts) {
+	    if ($receipt eq &Apache::lonnet::ireceipt($uname,$udom,$courseid,$symb,$part)) {
+		$contents.='<tr bgcolor="#ffffe6"><td>&nbsp;'."\n".
+		    '<a href="javascript:viewOneStudent(\''.$uname.'\',\''.$udom.
+		    '\')"; TARGET=_self>'.$$fullname{$_}.'</a>&nbsp;</td>'."\n".
+		    '<td>&nbsp;'.$uname.'&nbsp;</td>'.
+		    '<td>&nbsp;'.$udom.'&nbsp;</td>';
+		if ($receiptparts) {
+		    $contents.='<td>&nbsp;'.$part.'&nbsp;</td>';
+		}
+		$contents.='</tr>'."\n";
+		
+		$matches++;
+	    }
 	}
     }
     if ($matches == 0) {
@@ -545,8 +559,11 @@ sub verifyreceipt {
 	    '<table border="0"><tr bgcolor="#e6ffff">'."\n".
 	    '<td><b>&nbsp;Fullname&nbsp;</b></td>'."\n".
 	    '<td><b>&nbsp;Username&nbsp;</b></td>'."\n".
-	    '<td><b>&nbsp;Domain&nbsp;</b></td></tr>'."\n".
-	    $contents.
+	    '<td><b>&nbsp;Domain&nbsp;</b></td>';
+	if ($receiptparts) {
+	    $string.='<td>&nbsp;Problem Part&nbsp;</td>';
+	}
+	$string.='</tr>'."\n".$contents.
 	    '</table></td></tr></table>'."\n";
     }
     return $string.&show_grading_menu_form($symb,$url);
@@ -738,9 +755,12 @@ LISTJAVASCRIPT
 	if ($num_students eq 0) {
 	    $gradeTable='<br />&nbsp;<font color="red">There are no students currently enrolled.</font>';
 	} else {
+	    my $submissions='submissions';
+	    if ($submitonly eq 'incorrect') { $submissions = 'incorrect submissions'; }
+	    if ($submitonly eq 'graded'   ) { $submissions = 'ungraded submissions'; }
 	    $gradeTable='<br />&nbsp;<font color="red">'.
-		'No submissions found for this resource for any students. ('.$num_students.
-		' checked for submissions)</font><br />';
+		'No '.$submissions.' found for this resource for any students. ('.$num_students.
+		' students checked for '.$submissions.')</font><br />';
 	}
     } elsif ($ctr == 1) {
 	$gradeTable =~ s/type=checkbox/type=checkbox checked/;
@@ -1275,10 +1295,10 @@ sub gradeBox {
     my $ctr = 0;
     $result.='<table border="0"><tr>'."\n";  # display radio buttons in a nice table 10 across
     while ($ctr<=$wgt) {
-	$result.= '<td><input type="radio" name="RADVAL'.$counter.'_'.$partid.'" '.
+	$result.= '<td><nobr><input type="radio" name="RADVAL'.$counter.'_'.$partid.'" '.
 	    'onclick="javascript:writeBox(this.form,\''.$counter.'_'.$partid.'\','.
 	    $ctr.')" value="'.$ctr.'" '.
-	    ($score eq $ctr ? 'checked':'').' /> '.$ctr."</td>\n";
+	    ($score eq $ctr ? 'checked':'').' /> '.$ctr."</nobr></td>\n";
 	$result.=(($ctr+1)%10 == 0 ? '</tr><tr>' : '');
 	$ctr++;
     }
@@ -1679,12 +1699,15 @@ KEYWORDS
 	my $toGrade.='<input type="button" value="Grade Student" '.
 	    'onClick="javascript:checksubmit(this.form,\'Grade Student\',\''
 	    .$counter.'\');" TARGET=_self> &nbsp;'."\n" if (&canmodify($usec));
-	$toGrade.='</td></tr></table></td></tr></table></form>'."\n";
-	$toGrade.=&show_grading_menu_form($symb,$url) 
-	    if (($ENV{'form.command'} eq 'submission') || 
-		($ENV{'form.command'} eq 'processGroup' && $counter == $total));
-	$request = print($toGrade);
+	$toGrade.='</td></tr></table></td></tr></table>'."\n";
+	if (($ENV{'form.command'} eq 'submission') || 
+	    ($ENV{'form.command'} eq 'processGroup' && $counter == $total)) {
+	    $toGrade.='</form>'.&show_grading_menu_form($symb,$url) 
+	}
+	$request->print($toGrade);
 	return;
+    } else {
+	$request->print('</td></tr></table></td></tr></table>'."\n");
     }
 
     # essay grading message center
@@ -3443,34 +3466,28 @@ sub scantron_selectphase {
         $default_form_data
         <table width="100%" border="0">
           <tr bgcolor="#e6ffff">
-            <td>
-              &nbsp;<b>Specify file location and which Folder/Sequence to grade</b>
+            <td colspan="2">
+              &nbsp;<b>Specify file and which Folder/Sequence to grade</b>
             </td>
           </tr>
           <tr bgcolor="#ffffe6">
-            <td>
-               Sequence to grade: $sequence_selector
-	    </td>
+            <td> Sequence to grade: </td><td> $sequence_selector </td>
           </tr>
           <tr bgcolor="#ffffe6">
-            <td>
-		Filename of scoring office file: $file_selector
-	    </td>
+            <td> Filename of scoring office file: </td><td> $file_selector </td>
           </tr>
           <tr bgcolor="#ffffe6">
-            <td>
-              Format of data file: $format_selector
-	    </td>
+            <td> Format of data file: </td><td> $format_selector </td>
           </tr>
           <tr bgcolor="#ffffe6">
             <td>
 <!-- FIXME this is lazy, a single parse of the set should let me know what this is -->
-              Last line to expect an answer on: 
+              Last line to expect an answer on: </td><td>
                 <input type="text" name="scantron_maxbubble" />
 	    </td>
           </tr>
           <tr bgcolor="#ffffe6">
-            <td>
+            <td colspan="2">
               <input type="submit" value="Validate Scantron Records" />
             </td>
           </tr>
@@ -3491,13 +3508,36 @@ SCANTRONFORM
         <table width="100%" border="0">
           <tr bgcolor="#e6ffff">
             <td>
-              Specify a Scantron data file to upload.
+              &nbsp;<b>Specify a Scantron data file to upload.</b>
             </td>
           </tr>
           <tr bgcolor="#ffffe6">
             <td>
 SCANTRONFORM
-        &scantron_upload_scantron_data($r);
+    my $default_form_data=&defaultFormData(&get_symb_and_url($r,1));
+    my $cdom= $ENV{'course.'.$ENV{'request.course.id'}.'.domain'};
+    my $cnum= $ENV{'course.'.$ENV{'request.course.id'}.'.num'};
+    $r->print(<<UPLOAD);
+              <script type="text/javascript" language="javascript">
+    function checkUpload(formname) {
+	if (formname.upfile.value == "") {
+	    alert("Please use the browse button to select a file from your local directory.");
+	    return false;
+	}
+	formname.submit();
+    }
+              </script>
+
+              <form enctype='multipart/form-data' action='/adm/grades' name='rules' method='post'>
+                $default_form_data
+                <input name='courseid' type='hidden' value='$cnum' />
+                <input name='domainid' type='hidden' value='$cdom' />
+                <input name='command' value='scantronupload_save' type='hidden' />
+                File to upload:<input type="file" name="upfile" size="50" />
+                <br />
+                <input type="button" onClick="javascript:checkUpload(this.form);" value="Upload Scantron Data" />
+              </form>
+UPLOAD
 
         $r->print(<<SCANTRONFORM);
             </td>
@@ -3817,7 +3857,7 @@ sub scantron_getfile {
     } else {
 	$scanlines{'skipped'}=[(split("\n",$lines,-1))];
     }
-    my @tmp=&Apache::lonnet::dump('scantrondata',$cdom,$cname);
+    my @tmp=&Apache::lonnet::dump('nohist_scantrondata',$cdom,$cname);
     if ($tmp[0] =~ /^(error:|no_such_host)/) { @tmp=(); }
     my %scan_data = @tmp;
     return (\%scanlines,\%scan_data);
@@ -3849,7 +3889,7 @@ sub scantron_putfile {
     &lonnet_putfile(join("\n",@{$scanlines->{'skipped'}}),
 		    $prefix.'skipped_'.
 		    $ENV{'form.scantron_selectfile'});
-    &Apache::lonnet::put('scantrondata',$scan_data,$cdom,$cname);
+    &Apache::lonnet::put('nohist_scantrondata',$scan_data,$cdom,$cname);
 }
 
 sub scantron_get_line {
@@ -3966,7 +4006,7 @@ sub scantron_get_correction {
 				       'scantron_username','scantron_domain'));
 	$r->print(": <input type='text' name='scantron_username' value='' />");
 	$r->print("\n@".
-		 &Apache::loncommon::select_dom_form(undef,'scantron_domain'));
+		 &Apache::loncommon::select_dom_form($ENV{'request.role..domain'},'scantron_domain'));
 
 	$r->print('</li>');
     } elsif ($error eq 'doublebubble') {
@@ -4151,11 +4191,11 @@ SCANTRONFORM
 						 'last student');
     }
     &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
-    my $lasttime = &Time::HiRes::time()-$start;
-    $r->print("<p>took $lasttime</p>");
+#    my $lasttime = &Time::HiRes::time()-$start;
+#    $r->print("<p>took $lasttime</p>");
 
     $navmap->untieHashes();
-    $r->print("<p>Done</p>");
+    $r->print("</form><p>Done</p>");
     $r->print(&show_grading_menu_form($symb,$url));
     return '';
 }
@@ -4164,10 +4204,11 @@ sub scantron_upload_scantron_data {
     my ($r)=@_;
     $r->print(&Apache::loncommon::coursebrowser_javascript($ENV{'request.role.domain'}));
     my $select_link=&Apache::loncommon::selectcourse_link('rules','courseid',
-							  'domainid');
+							  'domainid',
+							  'coursename');
     my $domsel=&Apache::loncommon::select_dom_form($ENV{'request.role.domain'},
 						   'domainid');
-    my $default_form_data=&defaultFormData(&get_symb_and_url($r));
+    my $default_form_data=&defaultFormData(&get_symb_and_url($r,1));
     $r->print(<<UPLOAD);
 <script type="text/javascript" language="javascript">
     function checkUpload(formname) {
@@ -4181,12 +4222,14 @@ sub scantron_upload_scantron_data {
 
 <form enctype='multipart/form-data' action='/adm/grades' name='rules' method='post'>
 $default_form_data
-Course: <input name='courseid' type='text' />
-Domain: $domsel $select_link
-<br />
+<table>
+<tr><td>$select_link </td></tr>
+<tr><td>Course ID:   </td><td><input name='courseid' type='text' />  </td></tr>
+<tr><td>Course Name: </td><td><input name='coursename' type='text' /></td></tr>
+<tr><td>Domain:      </td><td>$domsel                                </td></tr>
+<tr><td>File to upload:</td><td><input type="file" name="upfile" size="50" /></td></tr>
+</table>
 <input name='command' value='scantronupload_save' type='hidden' />
-File to upload:<input type="file" name="upfile" size="50" />
-<br />
 <input type="button" onClick="javascript:checkUpload(this.form);" value="Upload Scantron Data" />
 </form>
 UPLOAD
@@ -4195,11 +4238,21 @@ UPLOAD
 
 sub scantron_upload_scantron_data_save {
     my($r)=@_;
+    my ($symb,$url)=&get_symb_and_url($r,1);
+    my $doanotherupload=
+	'<br /><form action="/adm/grades" method="post">'."\n".
+	'<input type="hidden" name="command" value="scantronupload" />'."\n".
+	'<input type="submit" name="submit" value="Do Another Upload" />'."\n".
+	'</form>'."\n";
     if (!&Apache::lonnet::allowed('usc',$ENV{'form.domainid'}) &&
 	!&Apache::lonnet::allowed('usc',
 			    $ENV{'form.domainid'}.'_'.$ENV{'form.courseid'})) {
 	$r->print("You are not allowed to upload Scantron data to the requested course.<br />");
-	$r->print(&show_grading_menu_form(&get_symb_and_url($r)));
+	if ($symb) {
+	    $r->print(&show_grading_menu_form($symb,$url));
+	} else {
+	    $r->print($doanotherupload);
+	}
 	return '';
     }
     $r->print("Doing upload to ".$ENV{'form.courseid'}." <br />");
@@ -4220,10 +4273,21 @@ sub scantron_upload_scantron_data_save {
     # See if there is anything left
     unless ($fname) { return 'error: no uploaded file'; }
     $fname='scantron_orig_'.$fname;
-    $r->print(&Apache::lonnet::finishuserfileupload($ENV{'form.courseid'},
-						    $ENV{'form.domainid'},
-						    $home,'upfile',$fname));
-    $r->print(&show_grading_menu_form(&get_symb_and_url($r)));
+    if (length($ENV{'form.upfile'}) < 2) {
+	$r->print("<font color='red'>Error:</font> The file you attempted to upload, <tt>".&HTML::Entities::encode($ENV{'form.upfile.filename'})."</tt>, contained no information. Please check that you entered the correct filename.");
+    } else {
+	my $result=&Apache::lonnet::finishuserfileupload($ENV{'form.courseid'},$ENV{'form.domainid'},$home,'upfile',$fname);
+	if ($result =~ m|^/uploaded/|) {
+	    $r->print("<font color='green'>Success:</font> Successfully uploaded ".(length($ENV{'form.upfile'})-1)." bytes of data into location <tt>".$result."</tt>");
+	} else {
+	    $r->print("<font color='red'>Error:</font> An error (".$result.") occured when attempting to upload the file, <tt>".&HTML::Entities::encode($ENV{'form.upfile.filename'})."</tt>");
+	}
+    }
+    if ($symb) {
+	$r->print(&show_grading_menu_form($symb,$url));
+    } else {
+	$r->print($doanotherupload);
+    }
     return '';
 }