--- loncom/homework/grades.pm 2002/07/01 21:20:29 1.34 +++ loncom/homework/grades.pm 2002/07/07 20:08:45 1.36 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # The LON-CAPA Grading handler # -# $Id: grades.pm,v 1.34 2002/07/01 21:20:29 ng Exp $ +# $Id: grades.pm,v 1.36 2002/07/07 20:08:45 ng Exp $ # # Copyright Michigan State University Board of Trustees # @@ -30,7 +30,7 @@ # 7/26 H.K. Ng # 8/20 Gerd Kortemeyer # Year 2002 -# June 2002 H.K. Ng +# June, July 2002 H.K. Ng # package Apache::grades; @@ -53,6 +53,7 @@ sub moreinfo { if ($ENV{'form.symb'}) { $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="'.$ENV{'form.command'}.'" />'."\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"); @@ -140,6 +141,8 @@ sub listStudents { <input type="radio" name="lastSub" value="all"> all <input type="hidden" name="section" value="$getsec"> <input type="hidden" name="submitonly" value="$submitonly"> +<input type="hidden" name="response" value="$ENV{'form.response'}"> +<input type="hidden" name="handgrade" value="$ENV{'form.handgrade'}"> <table border="0"><tr><td bgcolor="#777777"> <table border="0"><tr bgcolor="#e6ffff"> <td><b> Select </b></td><td><b> Username </b></td> @@ -181,31 +184,39 @@ sub processGroup { my ($request) = shift; my $ctr = 0; my @stuchecked = (ref($ENV{'form.stuinfo'}) ? @{$ENV{'form.stuinfo'}} - : ($ENV{'form.stuinfo'}) ); + : ($ENV{'form.stuinfo'})); my $total = scalar(@stuchecked)-1; - foreach my $student (@stuchecked) { - my ($sname,$sdom,$fullname) = split(/:/,$student); + if ($stuchecked[0] eq '') { + &userError($request,'No student was selected for viewing/grading.'); + return; + } + foreach (@stuchecked) { + my ($sname,$sdom,$fullname) = split(/:/); $ENV{'form.student'} = $sname; $ENV{'form.fullname'} = $fullname; &submission($request,$ctr,$total); $ctr++; } - return 'The End'; } +sub userError { + my ($request, $reason, $step) = @_; + $request->print('<h3><font color="red">LON-CAPA User Error</font></h3><br />'."\n"); + $request->print('<b>Reason: </b>'.$reason.'<br /><br />'."\n"); + $request->print('<b>Step: </b>'.($step ne '' ? $step : 'Use your browser back button to correct') + .'<br /><br />'."\n"); + return ''; +} + #FIXME - needs to handle multiple matches sub finduser { my ($name) = @_; my $domain = ''; - if ( $Apache::grades::viewgrades eq 'F' ) { - #get classlist -# my ($cdom,$cnum) = split(/_/,$ENV{'request.course.id'}); - #print "Found $cdom:$cnum<br />"; my ($classlist) = &getclasslist('all','0'); - foreach my $student ( sort(@{ $$classlist{'all'} }) ) { - my ($posname,$posdomain) = split(/:/,$student); + foreach ( sort(@{ $$classlist{'all'} }) ) { + my ($posname,$posdomain) = split(/:/); if ($posname =~ $name) { $name=$posname; $domain=$posdomain; last; } } return ($name,$domain); @@ -228,8 +239,9 @@ sub getclasslist { } my ($unam,$udom) = split(/:/,$student,2); my $section = &Apache::lonnet::usection($udom,$unam,$ENV{'request.course.id'}); + $section = ($section ne '-1' ? $section : 'no'); push @holdsec,$section; - push (@{ $classlist{$getsec} }, $student) if ($getsec eq 'all' or $getsec == $section); + push (@{ $classlist{$getsec} }, $student) if ($getsec eq 'all' || $getsec eq $section); } my %seen = (); foreach my $item (@holdsec) { @@ -326,10 +338,6 @@ sub setstudentgrade { } if ( scalar(keys(%newrecord)) > 0 ) { $newrecord{'resource.regrader'}="$ENV{'user.name'}:$ENV{'user.domain'}"; - print "grader=$newrecord{'resource.regrader'}:<br>records<br>"; - while (my ($k,$v) = each %newrecord) { - print "k=$k:v=$v:<br>\n"; - } # &Apache::lonnet::cstore(\%newrecord,$symb,$courseid,$domain,$stuname); $result.="Stored away ".scalar(keys(%newrecord))." elements.<br />\n"; @@ -343,7 +351,7 @@ sub submission { my ($request,$counter,$total) = @_; if ($counter == 0) { - $request->print(<<JAVASCRIPT); + $request->print(<<SUBJAVASCRIPT); <script type="text/javascript" language="javascript"> function updateRadio(radioButton,formtextbox,formsel,wgt) { var pts = formtextbox.value; @@ -390,13 +398,227 @@ sub submission { return; } + function keywords(keyform) { + var keywds = keyform.value; + var nret = prompt("Keywords list, separated by a space. Add/delete to list if desired.",keywds); + if (nret==null) return; + keyform.value = nret; + return; + } + +//===================== Script to add keyword(s) ================== + function getSel() { + if (document.getSelection) txt = document.getSelection(); + else if (document.selection) txt = document.selection.createRange().text; + else return; + var cleantxt = txt.replace(new RegExp('([\\f\\n\\r\\t\\v ])+', 'g')," "); + if (cleantxt=="") { + alert("Select a word or group of words from document and then click this link."); + return; + } + var nret = prompt("Add selection to keyword list?",cleantxt); + if (nret==null) return; + var curlist = document.SCORE.keywords.value; + document.SCORE.keywords.value = curlist+" "+nret; + return; + } + +//====================== Script for composing message ============== + function msgCenter(msgform,usrctr,fullname) { + var Nmsg = msgform.savemsgN.value; + savedMsgHeader(Nmsg,usrctr,fullname); + var subject = msgform.msgsub.value; + displaySubject(subject); + for (var i=1; i<=Nmsg; i++) { + var message = eval("document.SCORE.savemsg"+i+".value"); + displaySavedMsg(i,message); + } + newmsg = eval("document.SCORE.newmsg"+usrctr+".value"); + newMsg(newmsg); + msgTail(); + return; + } + +function savedMsgHeader(Nmsg,usrctr,fullname) { + var height = 30*Nmsg+250; + var scrollbar = "no"; + if (height > 600) { + height = 600; + scrollbar = "yes"; + } + pWin = window.open('', 'MessageCenter', 'toolbar=no,location=no,scrollbars='+scrollbar+',width=600,height='+height); + pWin.document.write("<html><head>"); + pWin.document.write("<title>Message Central</title>"); + + pWin.document.write("<script language=javascript>"); + pWin.document.write("function checkInput() {"); + pWin.document.write(" opener.document.SCORE.msgsub.value = document.msgcenter.msgsub.value;"); + pWin.document.write(" var nmsg = opener.document.SCORE.savemsgN.value;"); + pWin.document.write(" var usrctr = document.msgcenter.usrctr.value;"); + pWin.document.write(" var newval = eval(\\"opener.document.SCORE.newmsg\\"+usrctr);"); + pWin.document.write(" newval.value = document.msgcenter.newmsg.value;"); + + pWin.document.write(" var msgchk = \\"\\";"); + pWin.document.write(" if (document.msgcenter.subchk.checked) {"); + pWin.document.write(" msgchk = \\"subject,\\";"); + pWin.document.write(" }"); + pWin.document.write( "for (var i=1; i<=nmsg; i++) {"); + pWin.document.write(" var opnmsg = eval(\\"opener.document.SCORE.savemsg\\"+i);"); + pWin.document.write(" var frmmsg = eval(\\"document.msgcenter.msg\\"+i);"); + pWin.document.write(" opnmsg.value = frmmsg.value;"); + pWin.document.write(" var chkbox = eval(\\"document.msgcenter.msgn\\"+i);"); + pWin.document.write(" if (chkbox.checked) {"); + pWin.document.write(" msgchk += i+\\",\\";"); + pWin.document.write(" }"); + pWin.document.write(" }"); + pWin.document.write(" if (document.msgcenter.newmsgchk.checked) {"); + pWin.document.write(" msgchk += \\"new\\";"); + pWin.document.write(" }"); + pWin.document.write(" var includemsg = eval(\\"opener.document.SCORE.includemsg\\"+usrctr);"); + pWin.document.write(" includemsg.value = msgchk;"); + + pWin.document.write(" self.close()"); + + pWin.document.write("}"); + + pWin.document.write("<"); + pWin.document.write("/script>"); + + pWin.document.write("</head><body bgcolor=white>"); + + pWin.document.write("<form action=\\"inactive\\" name=\\"msgcenter\\">"); + pWin.document.write("<input value=\\""+usrctr+"\\" name=\\"usrctr\\" type=\\"hidden\\">"); + pWin.document.write("<font color=\\"green\\" size=+1> Compose Message for \"+fullname+\"</font><br><br>"); + + pWin.document.write("<table border=0 width=100%><tr><td bgcolor=\\"#777777\\">"); + pWin.document.write("<table border=0 width=100%><tr bgcolor=\\"#ddffff\\">"); + pWin.document.write("<td><b>Type</b></td><td><b>Include</b></td><td><b>Message</td></tr>"); +} + function displaySubject(msg) { + pWin.document.write("<tr bgcolor=\\"#ffffdd\\">"); + pWin.document.write("<td>Subject</td>"); + pWin.document.write("<td align=\\"center\\"><input name=\\"subchk\\" type=\\"checkbox\\" checked></td>"); + pWin.document.write("<td><input name=\\"msgsub\\" type=\\"text\\" value=\\""+msg+" \\"size=\\"60\\" maxlength=\\"80\\"></td></tr>"); +} + +function displaySavedMsg(ctr,msg) { + pWin.document.write("<tr bgcolor=\\"#ffffdd\\">"); + pWin.document.write("<td align=\\"center\\">"+ctr+"</td>"); + pWin.document.write("<td align=\\"center\\"><input name=\\"msgn"+ctr+"\\" type=\\"checkbox\\"></td>"); + pWin.document.write("<td><input name=\\"msg"+ctr+"\\" type=\\"text\\" value=\\""+msg+" \\" size=\\"60\\" maxlength=\\"80\\"></td></tr>"); +} + +function newMsg(newmsg) { + pWin.document.write("<tr bgcolor=\\"#ffffdd\\">"); + pWin.document.write("<td align=\\"center\\">New</td>"); + pWin.document.write("<td align=\\"center\\"><input name=\\"newmsgchk\\" type=\\"checkbox\\"></td>"); + pWin.document.write("<td><input name=\\"newmsg\\" type=\\"text\\" value=\\""+newmsg+" \\" size=\\"60\\" maxlength=\\"80\\"></td></tr>"); +} + +function msgTail() { + pWin.document.write("</table>"); + pWin.document.write("</td></tr></table> "); + pWin.document.write("<input type=\\"button\\" value=\\"Save\\" onClick=\\"javascript:checkInput()\\"> "); + pWin.document.write("<input type=\\"button\\" value=\\"Cancel\\" onClick=\\"self.close()\\"><br><br>"); + pWin.document.write("</form>"); + pWin.document.write("</body></html>"); +} + +//====================== Script for keyword highlight options ============== + function kwhighlight() { + var kwclr = document.SCORE.kwclr.value; + var kwsize = document.SCORE.kwsize.value; + var kwstyle = document.SCORE.kwstyle.value; + var redsel = ""; + var grnsel = ""; + var blusel = ""; + if (kwclr=="red") {var redsel="checked"}; + if (kwclr=="green") {var grnsel="checked"}; + if (kwclr=="blue") {var blusel="checked"}; + var sznsel = ""; + var sz1sel = ""; + var sz2sel = ""; + if (kwsize=="0") {var sznsel="checked"}; + if (kwsize=="+1") {var sz1sel="checked"}; + if (kwsize=="+2") {var sz2sel="checked"}; + var synsel = ""; + var syisel = ""; + var sybsel = ""; + if (kwstyle=="") {var synsel="checked"}; + if (kwstyle=="<i>") {var syisel="checked"}; + if (kwstyle=="<b>") {var sybsel="checked"}; + highlightCentral(); + highlightbody('red','red',redsel,'0','normal',sznsel,'','normal',synsel); + highlightbody('green','green',grnsel,'+1','+1',sz1sel,'<i>','italic',syisel); + highlightbody('blue','blue',blusel,'+2','+2',sz2sel,'<b>','bold',sybsel); + highlightend(); + return; + } + + +function highlightCentral() { + hwdWin = window.open('', 'KeywordHighlightCentral', 'toolbar=no,location=no,scrollbars=no,width=400,height=300'); + hwdWin.document.write("<html><head>"); + hwdWin.document.write("<title>Highlight Central</title>"); + + hwdWin.document.write("<script language=javascript>"); + hwdWin.document.write("function updateChoice() {"); + 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.kwstyle.value = radioSelection(document.hlCenter.kwdstyle);"); + hwdWin.document.write(" self.close()"); + hwdWin.document.write("}"); + + hwdWin.document.write("function radioSelection(radioButton) {"); + hwdWin.document.write(" var selection=null;"); + hwdWin.document.write(" for (var i=0; i<radioButton.length; i++) {"); + hwdWin.document.write(" if (radioButton[i].checked) {"); + hwdWin.document.write(" selection=radioButton[i].value;"); + hwdWin.document.write(" return selection;"); + hwdWin.document.write(" }"); + hwdWin.document.write(" }"); + hwdWin.document.write("}"); + + hwdWin.document.write("<"); + hwdWin.document.write("/script>"); + + hwdWin.document.write("</head><body bgcolor=white>"); + + hwdWin.document.write("<form action=\\"inactive\\" name=\\"hlCenter\\">"); + hwdWin.document.write("<font color=\\"green\\" size=+1> Keyword Highlight Options</font><br><br>"); + + hwdWin.document.write("<table border=0 width=100%><tr><td bgcolor=\\"#777777\\">"); + hwdWin.document.write("<table border=0 width=100%><tr bgcolor=\\"#ddffff\\">"); + hwdWin.document.write("<td><b>Text Color</b></td><td><b>Font Size</b></td><td><b>Font Style</td></tr>"); +} + +function highlightbody(clrval,clrtxt,clrsel,szval,sztxt,szsel,syval,sytxt,sysel) { + hwdWin.document.write("<tr bgcolor=\\"#ffffdd\\">"); + hwdWin.document.write("<td align=\\"left\\">"); + hwdWin.document.write("<input name=\\"kwdclr\\" type=\\"radio\\" value=\\""+clrval+"\\" "+clrsel+"> "+clrtxt+"</td>"); + hwdWin.document.write("<td align=\\"left\\">"); + hwdWin.document.write("<input name=\\"kwdsize\\" type=\\"radio\\" value=\\""+szval+"\\" "+szsel+"> "+sztxt+"</td>"); + hwdWin.document.write("<td align=\\"left\\">"); + hwdWin.document.write("<input name=\\"kwdstyle\\" type=\\"radio\\" value=\\""+syval+"\\" "+sysel+"> "+sytxt+"</td>"); + hwdWin.document.write("</tr>"); + } + +function highlightend() { + hwdWin.document.write("</table>"); + hwdWin.document.write("</td></tr></table> "); + hwdWin.document.write("<input type=\\"button\\" value=\\"Set Options\\" onClick=\\"javascript:updateChoice()\\"> "); + hwdWin.document.write("<input type=\\"button\\" value=\\"Cancel\\" onClick=\\"self.close()\\"><br><br>"); + hwdWin.document.write("</form>"); + hwdWin.document.write("</body></html>"); +} + </script> -JAVASCRIPT +SUBJAVASCRIPT } (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 ''; } + 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 ''; } + 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 ''; } @@ -404,7 +626,8 @@ JAVASCRIPT # # header info if ($counter == 0) { - $request->print('<h2><font color="#339933">Submission Record</font></h2>'); + $request->print('<h2> <font color="#339933">Submission Record</font></h2>'. + '<font size=+1> <b>Resource: </b>'.$url.'</font>'); } # @@ -425,33 +648,80 @@ JAVASCRIPT # # beginning of form if ($counter == 0) { + my %keyhash = &Apache::lonnet::get + ('nohist_handgrade',[$symb.'_keywords'], + $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, + $ENV{'course.'.$ENV{'request.course.id'}.'.num'}); + $request->print('<form action="/adm/grades" method="post" name="SCORE">'."\n". - '<input type="hidden" name="symb" value="'.$symb.'" />'."\n". - '<input type="hidden" name="url" value="'.$url.'" />'."\n". - '<input type="hidden" name="vProb" value="'.$ENV{'form.vProb'}.'" />'."\n". - '<input type="hidden" name="lastSub" value="'.$last.'" />'."\n". - '<input type="hidden" name="section" value="'.$ENV{'form.section'}.'">'."\n". + '<input type="hidden" name="symb" value="'.$symb.'" />'."\n". + '<input type="hidden" name="url" value="'.$url.'" />'."\n". + '<input type="hidden" name="vProb" value="'.$ENV{'form.vProb'}.'" />'."\n". + '<input type="hidden" name="lastSub" value="'.$last.'" />'."\n". + '<input type="hidden" name="section" value="'.$ENV{'form.section'}.'">'."\n". '<input type="hidden" name="submitonly" value="'.$ENV{'form.submitonly'}.'">'."\n". - '<input type="hidden" name="command" value="handgrade" />'."\n". + '<input type="hidden" name="response" value="'.$ENV{'form.response'}.'">'."\n". + '<input type="hidden" name="handgrade" value="'.$ENV{'form.handgrade'}.'">'."\n". + '<input type="hidden" name="command" value="handgrade" />'."\n". + '<input type="hidden" name="keywords" value="'.$keyhash{$symb.'_keywords'}.'" />'."\n". + '<input type="hidden" name="kwclr" value="blue" />'."\n". + '<input type="hidden" name="kwsize" value="0" />'."\n". + '<input type="hidden" name="kwstyle" value="" />'."\n". + '<input type="hidden" name="msgsub" value="Problem title" />'."\n". + '<input type="hidden" name="savemsgN" value="4" />'."\n". + '<input type="hidden" name="savemsg1" value="Good Job!" />'."\n". + '<input type="hidden" name="savemsg2" value="Needs a better explanation." />'."\n". + '<input type="hidden" name="savemsg3" value="Read the book before submitting such garbagge!" />'."\n". + '<input type="hidden" name="savemsg4" value="You are nowhere close." />'."\n". '<input type="hidden" name="NCT"'. ' value="'.($ENV{'form.NTSTU'} ne '' ? $ENV{'form.NTSTU'} : '1').'" />'."\n"); + + if ($ENV{'form.handgrade'} eq 'yes') { + $request->print(<<KEYWORDS); + <b>Keyword Options</b> +<a href="javascript:keywords(document.SCORE.keywords)"; TARGET=_self>Keyword List</a> +<a href="#" onMouseDown="javascript:getSel(); return false" + CLASS="page">Paste Selection to Keyword list</a> (requires N4+ and IE5+) +<a href="javascript:kwhighlight()"; TARGET=_self>Keyword Highlight Attribute</a><br /><br /> +KEYWORDS + } } + # # Student info $request->print(($counter == 0 ? '' : '<br /><hr><br />')); + my $fullname = ($ENV{'form.fullname'} ne '' ? $ENV{'form.fullname'} : &get_fullname($uname,$udom)); my $result.='<table border="0"><tr><td><b>Username: </b>'.$uname. - '</td><td><b>Fullname: </b>'. - ($ENV{'form.fullname'} ne '' ? $ENV{'form.fullname'} : &get_fullname($uname,$udom)). + '</td><td><b>Fullname: </b>'.$fullname. +# ($ENV{'form.fullname'} ne '' ? $ENV{'form.fullname'} : &get_fullname($uname,$udom)). '</td><td><b>Domain: </b>'.$udom.'</td></tr>'; - $result.='<tr><td colspan=3><b>Resource: </b>'.$url.'</td></tr></table>'; + if ($ENV{'form.handgrade'} eq 'yes') { + my $subonly = &get_last_submission($symb,$uname,$udom,$ENV{'request.course.id'}); + my ($classlist) = &getclasslist('all','0'); + my @collaborators; + foreach ( sort(@{ $$classlist{'all'} }) ) { + my ($sname,$sdom) = split(/:/); + push @collaborators,$sname if (grep /\b$sname(\b|\.)/i,$subonly); + } + push @collaborators,'leede','carlandmm','freyniks'; # as a test to display collaborators. + if (scalar(@collaborators) != 0) { + $result.='<tr><td colspan=3><b>Collaborators: </b>'; + foreach (@collaborators) { + $result.=$_.' ('.&get_fullname($_,$udom).') '; + } + $result.='</td></tr>'."\n"; + $result.='<input type="hidden" name="collaborator'.$counter. + '" value="'.(join ':',@collaborators).'" />'."\n"; + } + } + $result.='</table>'."\n"; $request->print($result); # # print student answer - my $answer=&Apache::loncommon::get_previous_attempt($symb,$uname,$udom, - $ENV{'request.course.id'},$last); - $request->print($answer); - $answer =~ m/.*<\/tr><tr.*?<td>.*?<td>(.*?)<td>(.*?)<\/td>/; - print "Submitted=$1:<br>$2;"; + $request->print(&Apache::loncommon::get_previous_attempt($symb,$uname,$udom, + $ENV{'request.course.id'},$last, + '.submission','Apache::grades::keywords_highlight')); +# # my $wgt = &Apache::lonnet::EXT('resource.partid.weight',$symb,$udom,$uname); my $wgtmsg = ($wgt > 0 ? '(problem weight)' : '<font color="red">problem weight assigned by computer</font>'); @@ -463,6 +733,8 @@ JAVASCRIPT # display grading options $result='<input type="hidden" name="WGT'.$counter.'" value="'.$wgt.'" />'. '<input type="hidden" name="unamedom'.$counter.'" value="'.$uname.':'.$udom.'" />'."\n"; + $result.='<input type="hidden" name="newmsg'.$counter.'" value="" />'."\n". + $result.='<input type="hidden" name="includemsg'.$counter.'" value="" />'."\n". $result.='<table border="0"><tr><td><b>Points</b></td><td>'; my $ctr = 0; @@ -497,7 +769,9 @@ JAVASCRIPT '<option>partial</option><option>nothing</option>'."\n"; $optsel =~ s/<option>$status/<option selected="on">$status/; $result.=$optsel; - $result.="</select></td></tr>\n"; + $result.="</select>  \n"; + $result.='<a href="javascript:msgCenter(document.SCORE,'.$counter. + ',\''.$fullname.'\')"; TARGET=_self>Compose Message</a></td></tr>'."\n"; } } $result.='</table>'; @@ -522,6 +796,42 @@ JAVASCRIPT return ''; } +sub get_last_submission { + my ($symb,$username,$domain,$course)=@_; + if ($symb) { + my (%returnhash)=&Apache::lonnet::restore($symb,$course,$domain,$username); + if ($returnhash{'version'}) { + my %lasthash=(); + my $version; + for ($version=1;$version<=$returnhash{'version'};$version++) { + foreach (sort(split(/\:/,$returnhash{$version.':keys'}))) { + $lasthash{$_}=$returnhash{$version.':'.$_}; + } + } + foreach ((keys %lasthash)) { + if ($_ =~ /\.submission$/) {return $lasthash{$_}} + } + return ''; + } + } +} + +sub keywords_highlight { + my $string = shift; + (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 %keyhash = &Apache::lonnet::get + ('nohist_handgrade',[$symb.'_keywords'], + $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, + $ENV{'course.'.$ENV{'request.course.id'}.'.num'}); + my @keylist = split(/[,\s+]/,$keyhash{$symb.'_keywords'}); + foreach my $word (@keylist) { + next if ($word eq ''); + $string =~ s/\b$word(\b|\.)/\<font color\=red\>$word\<\/font\>/gi; + } + return $string; +} + sub processHandGrade { my ($request) = shift; my $url = $ENV{'form.url'}; @@ -529,34 +839,52 @@ sub processHandGrade { my $button = $ENV{'form.gradeOpt'}; my $ngrade = $ENV{'form.NCT'}; my $ntstu = $ENV{'form.NTSTU'}; -# my $vProb = $ENV{'form.vProb'}; -# my $lastSub= $ENV{'form.lastSub'}; - + my $keywords= $ENV{'form.keywords'}; + my $newmsg0 = $ENV{'form.newmsg0'}; + print "newmsg0=$newmsg0<br>"; + my $newmsg1 = $ENV{'form.newmsg1'}; + print "newmsg1=$newmsg1<br>"; + my $oldmsg1 = $ENV{'form.savemsg1'}; + print "oldmsg1=$oldmsg1<br>"; + my $oldmsg2 = $ENV{'form.savemsg2'}; + print "oldmsg1=$oldmsg2<br>"; + my $oldmsg3 = $ENV{'form.savemsg3'}; + print "oldmsg1=$oldmsg3<br>"; + my $oldmsg4 = $ENV{'form.savemsg4'}; + print "oldmsg1=$oldmsg4<br>"; + my $messages = $ENV{'form.includemsg0'}; + print "messages=$messages<br>"; + if ($keywords ne '') { + my $crsname = $ENV{'course.'.$ENV{'request.course.id'}.'.num'}; + my $crsdom = $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}; +# my $putresult = &Apache::lonnet::put +# ('nohist_handgrade',{$symb.'_keywords' => $keywords}, +# $crsdom,$crsname); + } my (@parts) = sort(&getpartlist($url)); if ($button eq 'Save & Next') { my $ctr = 0; while ($ctr < $ENV{'form.NCT'}) { -# my $pts = ($ENV{'form.GRADE_BOX'.$ctr} ne '' ? $ENV{'form.GRADE_BOX'.$ctr} : $ENV{'form.RADVAL'.$ctr}); -# my $wgt = $ENV{'form.WGT'.$ctr}; -# my $sel = $ENV{'form.GRADE_SEL'.$ctr}; -# my $score = $pts/$wgt if ($wgt != 0); my ($uname,$udom) = split(/:/,$ENV{'form.unamedom'.$ctr}); &saveHandGrade($url,$symb,$uname,$udom,$ctr,@parts); -# &saveHandGrade($url,$symb,$uname,$udom,$score,@parts); + if ($ENV{'form.collaborator'.$ctr}) { + my (@collaborators) = split(/:/,$ENV{'form.collaborator'.$ctr}); + foreach (@collaborators) { + &saveHandGrade($url,$symb,$_,$udom,$ctr,@parts); + } + } $ctr++; } } my $firststu = $ENV{'form.unamedom0'}; my $laststu = $ENV{'form.unamedom'.($ngrade-1)}; - #get classlist -# my ($cdom,$cnum) = split(/_/,$ENV{'request.course.id'}); - my ($classlist) = &getclasslist('all','0'); + my ($classlist) = &getclasslist($ENV{'form.section'},'0'); my (@nextlist,@prevlist); my ($nextflg,$prevflg,$ctr,$ctprev) = (0,0,0,0); - foreach my $student ( sort(@{ $$classlist{'all'} }) ) { + foreach my $student ( sort(@{ $$classlist{$ENV{'form.section'}} }) ) { my ($uname,$udom) = split(/:/,$student); if ($nextflg == 1 && $button =~ /Next$/) { push @nextlist,$uname if ($ctr < $ntstu); @@ -594,7 +922,6 @@ sub processHandGrade { sub saveHandGrade { my ($url,$symb,$stuname,$domain,$newflg,@parts) = @_; -# my ($stuname,$domain) = split(/:/,$student); my %record=&Apache::lonnet::restore($symb,$ENV{'request.course.id'},$domain,$stuname); my %newrecord; @@ -603,7 +930,8 @@ sub saveHandGrade { my $oldscore=$record{"resource.$part.$type"}; my $newscore; if ($type eq 'awarded' && $newflg >= 0) { - my $pts = ($ENV{'form.GRADE_BOX'.$newflg} ne '' ? $ENV{'form.GRADE_BOX'.$newflg} : $ENV{'form.RADVAL'.$newflg}); + my $pts = ($ENV{'form.GRADE_BOX'.$newflg} ne '' ? + $ENV{'form.GRADE_BOX'.$newflg} : $ENV{'form.RADVAL'.$newflg}); my $wgt = $ENV{'form.WGT'.$newflg}; # my $sel = $ENV{'form.GRADE_SEL'.$newflg}; $newscore = $pts/$wgt if ($wgt != 0); @@ -633,10 +961,10 @@ sub saveHandGrade { } if ( scalar(keys(%newrecord)) > 0 ) { $newrecord{'resource.regrader'}="$ENV{'user.name'}:$ENV{'user.domain'}"; - while (my ($k,$v) = each %newrecord) { - print "k=$k:v=$v:<br>\n"; - } - print "symb=$symb,courseid=$ENV{'request.course.id'},dom=$domain,name=$stuname<br>"; +# while (my ($k,$v) = each %newrecord) { +# print "k=$k:v=$v:<br>\n"; +# } +# print "symb=$symb,courseid=$ENV{'request.course.id'},dom=$domain,name=$stuname<br>"; # &Apache::lonnet::cstore(\%newrecord,$symb,$ENV{'request.course.id'},$domain,$stuname); } return ''; @@ -665,13 +993,21 @@ sub gradingmenu { my ($request) = @_; my ($symb,$url)=&get_symb_and_url($request); if (!$symb) {return '';} + my $allkeys = &Apache::lonnet::metadata($url,'keys'); + my $handgrade = ($allkeys =~ /parameter_.*?_handgrade/ ? 'yes' : 'no'); + my ($responsetype,$foo) = split(/_/,&Apache::lonnet::metadata($url,'packages')); my $result='<h2> <font color="#339933">Select a Grading Method</font></h2>'; - $result.=' <font size=+1><b>Resource: </b>'.$url.'</font><br /><br />'; + $result.='<table border="0">'; + $result.='<tr><td><font size=+1><b>Resource: </b></font></td>'. + '<td><font size=+1>'.$url.'</font></td></tr>'; + $result.='<tr><td><font size=+1><b>Type: </b></font></td>'. + '<td><font size=+1>'.$responsetype.' <b>Handgrade: </b>'.$handgrade.'</font></td></tr>'; + $result.='</table>'; $result.=&view_edit_entire_class_form($symb,$url).'<br />'; $result.=&upcsvScores_form($symb,$url).'<br />'; - $result.=&viewGradeaStu_form($symb,$url).'<br />'; + $result.=&viewGradeaStu_form($symb,$url,$responsetype,$handgrade).'<br />'; $result.=&verifyReceipt_form($symb,$url); return $result; } @@ -718,7 +1054,7 @@ ENDUPFORM } sub viewGradeaStu_form { - my ($symb,$url) = @_; + 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"; @@ -727,7 +1063,9 @@ sub viewGradeaStu_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="submission" />'."\n"; + '<input type="hidden" name="response" value="'.$response.'" />'."\n". + '<input type="hidden" name="handgrade" value="'.$handgrade.'" />'."\n". + '<input type="hidden" name="command" value="submission" />'."\n"; $result.=' <b>Select section:</b> <select name="section">'."\n"; foreach my $section (sort (@$sections)) { @@ -737,7 +1075,8 @@ sub viewGradeaStu_form { $result.=' <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.=' (Section -1 implies the students were not assigned a section.)<br />' if (grep /-1/,@$sections); + $result.=' (Section "no" implies the students were not assigned a section.)<br />' + if (grep /no/,@$sections); $result.='<br /> <input type="submit" name="submit" value="View/Grade" />'."\n". '</form>'."\n"; @@ -839,7 +1178,7 @@ sub editgrades { '<input type="hidden" name="command" value="viewgrades" />'."\n". '<input type="submit" name="submit" value="See Grades" /> <br />'."\n"; - foreach my $student ( sort(@{ $$classlist{'all '} }) ) { + foreach my $student ( sort(@{ $$classlist{'all'} }) ) { $result.=&setstudentgrade($url,$symb,$ENV{'request.course.id'},$student,@parts); }