--- loncom/homework/grades.pm 2003/11/25 21:44:45 1.162 +++ loncom/homework/grades.pm 2004/03/04 14:09:47 1.179 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # The LON-CAPA Grading handler # -# $Id: grades.pm,v 1.162 2003/11/25 21:44:45 albertel Exp $ +# $Id: grades.pm,v 1.179 2004/03/04 14:09:47 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -48,6 +48,7 @@ use Apache::lonhomework; use Apache::loncoursedata; use Apache::lonmsg qw(:user_normal_msg); use Apache::Constants qw(:common); +use Apache::lonlocal; use String::Similarity; my %oldessays=(); @@ -88,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); } @@ -168,7 +174,7 @@ sub showResourceInfo { my $col=3; if ($checkboxes) { $col=4; } my $result ='<table border="0">'. - '<tr><td colspan="'.$col.'"><font size="+1"><b>Current Resource: </b>'. + '<tr><td colspan="'.$col.'"><font size="+1"><b>'.&mt('Current Resource').': </b>'. $probTitle.'</font></td></tr>'."\n"; my ($partlist,$handgrade,$responseType) = &response_type($url); my %resptype = (); @@ -290,7 +296,8 @@ sub cleanRecord { $ENV{'form.kwstyle'} = $keyhash{$loginuser.'_kwstyle'} ne '' ? $keyhash{$loginuser.'_kwstyle'} : ''; $ENV{'form.'.$symb} = 1; # so that we don't have to read it from disk for multiple sub of the same prob. } - return '<br /><br /><blockquote><pre>'.&keywords_highlight($answer).'</pre></blockquote>'; + $answer =~ s-\n-<br />-g; + return '<br /><br /><blockquote><tt>'.&keywords_highlight($answer).'</tt></blockquote>'; } return $answer; } @@ -519,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> '."\n". - '<a href="javascript:viewOneStudent(\''.$uname.'\',\''.$udom. - '\')"; TARGET=_self>'.$$fullname{$_}.'</a> </td>'."\n". - '<td> '.$uname.' </td>'. - '<td> '.$udom.' </td></tr>'."\n"; - - $matches++; + foreach my $part (@$parts) { + if ($receipt eq &Apache::lonnet::ireceipt($uname,$udom,$courseid,$symb,$part)) { + $contents.='<tr bgcolor="#ffffe6"><td> '."\n". + '<a href="javascript:viewOneStudent(\''.$uname.'\',\''.$udom. + '\')"; TARGET=_self>'.$$fullname{$_}.'</a> </td>'."\n". + '<td> '.$uname.' </td>'. + '<td> '.$udom.' </td>'; + if ($receiptparts) { + $contents.='<td> '.$part.' </td>'; + } + $contents.='</tr>'."\n"; + + $matches++; + } } } if ($matches == 0) { @@ -543,8 +559,11 @@ sub verifyreceipt { '<table border="0"><tr bgcolor="#e6ffff">'."\n". '<td><b> Fullname </b></td>'."\n". '<td><b> Username </b></td>'."\n". - '<td><b> Domain </b></td></tr>'."\n". - $contents. + '<td><b> Domain </b></td>'; + if ($receiptparts) { + $string.='<td> Problem Part </td>'; + } + $string.='</tr>'."\n".$contents. '</table></td></tr></table>'."\n"; } return $string.&show_grading_menu_form($symb,$url); @@ -678,10 +697,11 @@ LISTJAVASCRIPT if ($ENV{'form.showgrading'} eq 'yes' && $submitonly ne 'all') { (%status) =&student_gradeStatus($url,$symb,$udom,$uname,$partlist); my $submitted = 0; - my $graded = 1; + my $graded = 0; foreach (keys(%status)) { $submitted = 1 if ($status{$_} ne 'nothing'); - $graded = 0 if ($status{$_} =~ /^correct/); + $graded = 1 if ($status{$_} !~ /^correct/); + my ($foo,$partid,$foo1) = split(/\./,$_); if ($status{'resource.'.$partid.'.submitted_by'} ne '') { $submitted = 0; @@ -735,9 +755,12 @@ LISTJAVASCRIPT if ($num_students eq 0) { $gradeTable='<br /> <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 /> <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/; @@ -1272,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++; } @@ -1375,7 +1398,9 @@ sub submission { return; } - $ENV{'form.lastSub'} = ($ENV{'form.lastSub'} eq '' ? 'datesub' : $ENV{'form.lastSub'}); + if (!$ENV{'form.lastSub'}) { $ENV{'form.lastSub'} = 'datesub'; } + if (!$ENV{'form.vProb'}) { $ENV{'form.vProb'} = 'yes'; } + if (!$ENV{'form.vAns'}) { $ENV{'form.vAns'} = 'yes'; } my $last = ($ENV{'form.lastSub'} eq 'last' ? 'last' : ''); my $checkIcon = '<img src="'.$request->dir_config('lonIconsURL'). '/check.gif" height="16" border="0" />'; @@ -1644,7 +1669,7 @@ KEYWORDS $partid.'</b> <font color="#999999">( ID '.$respid. ' )</font> '; if ($record{"resource.$partid.$respid.uploadedurl"}) { - $lastsubonly.='<a href="'.&Apache::lonnet::tokenwrapper($record{"resource.$partid.$respid.uploadedurl"}).'"><img src="/adm/lonIcons/unknown.gif" border=0"> File uploaded by student</a> <font color="red" size="1">Like all files provided by users, this file may contain virusses</font><br />'; + $lastsubonly.='<a href="'.&Apache::lonnet::tokenwrapper($record{"resource.$partid.$respid.uploadedurl"}).'" target="lonGRDs"><img src="/adm/lonIcons/unknown.gif" border=0"> File uploaded by student</a> <font color="red" size="1">Like all files provided by users, this file may contain virusses</font><br />'; } $lastsubonly.='<b>Submitted Answer: </b>'. &cleanRecord($subval,$responsetype,$symb,$partid, @@ -1674,10 +1699,11 @@ KEYWORDS my $toGrade.='<input type="button" value="Grade Student" '. 'onClick="javascript:checksubmit(this.form,\'Grade Student\',\'' .$counter.'\');" TARGET=_self> '."\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)); + $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; } @@ -2243,8 +2269,14 @@ sub viewgrades { &viewgrades_js($request); my ($symb,$url) = ($ENV{'form.symb'},$ENV{'form.url'}); - my $result='<h3><font color="#339933">Manual Grading</font></h3>'; + #need to make sure we have the correct data for later EXT calls, + #thus invalidate the cache + &Apache::lonnet::devalidatecourseresdata( + $ENV{'course.'.$ENV{'request.course.id'}.'.num'}, + $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}); + &Apache::lonnet::clear_EXT_cache_status(); + my $result='<h3><font color="#339933">'.&mt('Manual Grading').'</font></h3>'; $result.='<font size=+1><b>Current Resource: </b>'.$ENV{'form.probTitle'}.'</font>'."\n"; #view individual student submission form - called using Javascript viewOneStudent @@ -3027,6 +3059,14 @@ sub displayPage { my ($classlist,undef,$fullname) = &getclasslist($getsec,'1'); my ($uname,$udom) = split(/:/,$ENV{'form.student'}); my $usec=$classlist->{$ENV{'form.student'}}[5]; + + #need to make sure we have the correct data for later EXT calls, + #thus invalidate the cache + &Apache::lonnet::devalidatecourseresdata( + $ENV{'course.'.$ENV{'request.course.id'}.'.num'}, + $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}); + &Apache::lonnet::clear_EXT_cache_status(); + if (!&canview($usec)) { $request->print('<font color="red">Unable to view requested student.('.$ENV{'form.student'}.')</font>'); $request->print(&show_grading_menu_form($symb,$url)); @@ -3198,7 +3238,7 @@ sub displaySubByDates { } if (exists $$record{"$version:resource.$partid.regrader"}) { $displaySub[2].=$$record{"$version:resource.$partid.regrader"}. - ' (<b>Part:</b> '.$partid.')'; + ' (<b>'.&mt('Part').':</b> '.$partid.')'; } } # needed because old essay regrader has not parts info @@ -3424,34 +3464,28 @@ sub scantron_selectphase { $default_form_data <table width="100%" border="0"> <tr bgcolor="#e6ffff"> - <td> - <b>Specify file location and which Folder/Sequence to grade</b> + <td colspan="2"> + <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> @@ -3472,13 +3506,36 @@ SCANTRONFORM <table width="100%" border="0"> <tr bgcolor="#e6ffff"> <td> - Specify a Scantron data file to upload. + <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> @@ -3798,7 +3855,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); @@ -3830,7 +3887,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 { @@ -3947,7 +4004,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') { @@ -4132,11 +4189,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 ''; } @@ -4148,7 +4205,7 @@ sub scantron_upload_scantron_data { 'domainid'); 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) { @@ -4204,7 +4261,15 @@ sub scantron_upload_scantron_data_save { $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))); + my ($symb,$url)=&get_symb_and_url($r); + if ($symb) { + $r->print(&show_grading_menu_form(&get_symb_and_url($r))); + } else { + $r->print('<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"); + } return ''; } @@ -4311,7 +4376,7 @@ GRADINGMENUJS $result.='<table width="100%" border=0>'; $result.='<tr bgcolor="#ffffe6" valign="top"><td>'."\n". - ' Select Section: <select name="section">'."\n"; + ' '.&mt('Select Section').': <select name="section">'."\n"; if (ref($sections)) { foreach (sort (@$sections)) { $result.='<option value="'.$_.'" '. @@ -4320,7 +4385,7 @@ GRADINGMENUJS } $result.= '<option value="all" '.($saveSec eq 'all' ? 'selected="on"' : ''). '>all</select> '; - $result.='Student Status:</b>'.&Apache::lonhtmlcommon::StatusOptions($saveStatus,undef,1,undef); + $result.=&mt('Student Status').':</b>'.&Apache::lonhtmlcommon::StatusOptions($saveStatus,undef,1,undef); if (ref($sections) && (grep /no/,@$sections)) { $result.=' (Section "no" implies the students were not assigned a section.)<br />'; @@ -4329,8 +4394,8 @@ GRADINGMENUJS $result.='<tr bgcolor="#ffffe6"valign="top"><td>'. '<input type="radio" name="radioChoice" value="submission" '. - ($saveCmd eq 'submission' ? 'checked' : '').'> '.'<b>Current Resource:</b> For one or more students '. - '<select name="submitonly">'. + ($saveCmd eq 'submission' ? 'checked' : '').'> '.'<b>'.&mt('Current Resource').':</b> '.&mt('For one or more students'). + ' <select name="submitonly">'. '<option value="yes" '. ($saveSub eq 'yes' ? 'selected="on"' : '').'>with submissions</option>'. '<option value="graded" '.