--- loncom/homework/grades.pm 2014/02/27 02:52:22 1.596.2.12.2.29 +++ loncom/homework/grades.pm 2010/04/12 12:55:18 1.611 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # The LON-CAPA Grading handler # -# $Id: grades.pm,v 1.596.2.12.2.29 2014/02/27 02:52:22 raeburn Exp $ +# $Id: grades.pm,v 1.611 2010/04/12 12:55:18 www Exp $ # # Copyright Michigan State University Board of Trustees # @@ -40,10 +40,9 @@ use Apache::lonhomework; use Apache::lonpickcode; use Apache::loncoursedata; use Apache::lonmsg(); -use Apache::Constants qw(:common :http); +use Apache::Constants qw(:common); use Apache::lonlocal; use Apache::lonenc; -use Apache::bridgetask(); use String::Similarity; use LONCAPA; @@ -52,7 +51,6 @@ use POSIX qw(floor); my %perm=(); -my %old_essays=(); # These variables are used to recover from ssi errors @@ -98,6 +96,9 @@ sub ssi_print_error { # # --- Retrieve the parts from the metadata file.--- +# Returns an array of everything that the resources stores away +# + sub getpartlist { my ($symb,$errorref) = @_; @@ -122,24 +123,6 @@ sub getpartlist { return @stores; } -# --- Get the symbolic name of a problem and the url -sub get_symb { - my ($request,$silent) = @_; - my $symb=$env{'form.symb'}; - unless ($symb) { - (my $url=$env{'form.url'}) =~ s-^http://($ENV{'SERVER_NAME'}|$ENV{'HTTP_HOST'})--; - $symb = &Apache::lonnet::symbread($url); - if ($symb eq '') { - if (!$silent) { - $request->print(&mt("Unable to handle ambiguous references: [_1].",$url)); - return (); - } - } - } - &Apache::lonenc::check_decrypt(\$symb); - return ($symb); -} - #--- Format fullname, username:domain if different for display #--- Use anywhere where the student names are listed sub nameUserString { @@ -212,59 +195,9 @@ sub get_display_part { return $display; } -#--- Show resource title -#--- and parts and response type -sub showResourceInfo { - my ($symb,$probTitle,$checkboxes,$res_error) = @_; - my $result = '

'.&mt('Current Resource').': '.$probTitle.'

'."\n"; - my ($partlist,$handgrade,$responseType) = &response_type($symb,$res_error); - if (ref($res_error)) { - if ($$res_error) { - return; - } - } - $result.=&Apache::loncommon::start_data_table() - .&Apache::loncommon::start_data_table_header_row(); - if ($checkboxes) { - $result.=' '; - } - $result.=''.&mt('Problem Part').'' - .''.&mt('Res. ID').'' - .''.&mt('Type').'' - .&Apache::loncommon::end_data_table_header_row(); - my %resptype = (); - my $hdgrade='no'; - my %partsseen; - foreach my $partID (sort(keys(%$responseType))) { - foreach my $resID (sort(keys(%{ $responseType->{$partID} }))) { - my $handgrade=$$handgrade{$partID.'_'.$resID}; - my $responsetype = $responseType->{$partID}->{$resID}; - $hdgrade = $handgrade if ($handgrade eq 'yes'); - $result.=&Apache::loncommon::start_data_table_row(); - if ($checkboxes) { - if (exists($partsseen{$partID})) { - $result.=" "; - } else { - $result.=""; - } - $partsseen{$partID}=1; - } - my $display_part=&get_display_part($partID,$symb); - $result.=''.$display_part.'' - .''.''.$resID.'' - .''.&mt($responsetype).'' -# .''.&mt('Handgrade: [_1]',$handgrade).'' - .&Apache::loncommon::end_data_table_row(); - } - } - $result.=&Apache::loncommon::end_data_table(); - return $result,$responseType,$hdgrade,$partlist,$handgrade; -} - sub reset_caches { &reset_analyze_cache(); &reset_perm(); - &reset_old_essays(); } { @@ -277,13 +210,8 @@ sub reset_caches { } sub get_analyze { - my ($symb,$uname,$udom,$no_increment,$add_to_hash,$type,$trial,$rndseed,$bubbles_per_row)=@_; + my ($symb,$uname,$udom,$no_increment,$add_to_hash)=@_; my $key = "$symb\0$uname\0$udom"; - if ($type eq 'randomizetry') { - if ($trial ne '') { - $key .= "\0".$trial; - } - } if (exists($analyze_cache{$key})) { my $getupdate = 0; if (ref($add_to_hash) eq 'HASH') { @@ -311,18 +239,9 @@ sub reset_caches { 'grade_courseid' => $env{'request.course.id'}, 'grade_username' => $uname, 'grade_noincrement' => $no_increment); - if ($bubbles_per_row ne '') { - $form{'bubbles_per_row'} = $bubbles_per_row; - } - if ($type eq 'randomizetry') { - $form{'grade_questiontype'} = $type; - if ($rndseed ne '') { - $form{'grade_rndseed'} = $rndseed; - } - } if (ref($add_to_hash)) { %form = (%form,%{$add_to_hash}); - } + } my $subresult=&ssi_with_retries($url, $ssi_retries,%form); (undef,$subresult)=split(/_HASH_REF__/,$subresult,2); my %analyze=&Apache::lonnet::str2hash($subresult); @@ -335,15 +254,15 @@ sub reset_caches { } sub get_order { - my ($partid,$respid,$symb,$uname,$udom,$no_increment,$type,$trial,$rndseed)=@_; - my $analyze = &get_analyze($symb,$uname,$udom,$no_increment,undef,$type,$trial,$rndseed); + my ($partid,$respid,$symb,$uname,$udom,$no_increment)=@_; + my $analyze = &get_analyze($symb,$uname,$udom,$no_increment); return $analyze->{"$partid.$respid.shown"}; } sub get_radiobutton_correct_foil { - my ($partid,$respid,$symb,$uname,$udom,$type,$trial,$rndseed)=@_; - my $analyze = &get_analyze($symb,$uname,$udom,undef,undef,$type,$trial,$rndseed); - my $foils = &get_order($partid,$respid,$symb,$uname,$udom,undef,$type,$trial,$rndseed); + my ($partid,$respid,$symb,$uname,$udom)=@_; + my $analyze = &get_analyze($symb,$uname,$udom); + my $foils = &get_order($partid,$respid,$symb,$uname,$udom); if (ref($foils) eq 'ARRAY') { foreach my $foil (@{$foils}) { if ($analyze->{"$partid.$respid.foil.value.$foil"} eq 'true') { @@ -354,7 +273,7 @@ sub reset_caches { } sub scantron_partids_tograde { - my ($resource,$cid,$uname,$udom,$check_for_randomlist,$bubbles_per_row) = @_; + my ($resource,$cid,$uname,$udom,$check_for_randomlist) = @_; my (%analysis,@parts); if (ref($resource)) { my $symb = $resource->symb(); @@ -362,9 +281,7 @@ sub reset_caches { if ($check_for_randomlist) { $add_to_form = { 'check_parts_withrandomlist' => 1,}; } - my $analyze = - &get_analyze($symb,$uname,$udom,undef,$add_to_form, - undef,undef,undef,$bubbles_per_row); + my $analyze = &get_analyze($symb,$uname,$udom,undef,$add_to_form); if (ref($analyze) eq 'HASH') { %analysis = %{$analyze}; } @@ -387,12 +304,10 @@ sub reset_caches { # response types only. sub cleanRecord { my ($answer,$response,$symb,$partid,$respid,$record,$order,$version, - $uname,$udom,$type,$trial,$rndseed) = @_; + $uname,$udom) = @_; my $grayFont = ''; if ($response =~ /^(option|rank)$/) { my %answer=&Apache::lonnet::str2hash($answer); - my @answer = %answer; - %answer = map {&HTML::Entities::encode($_, '"<>&')} @answer; my %grading=&Apache::lonnet::str2hash($record->{$version."resource.$partid.$respid.submissiongrading"}); my ($toprow,$bottomrow); foreach my $foil (@$order) { @@ -406,11 +321,9 @@ sub cleanRecord { return '
'. ''.$toprow.''. ''. - $bottomrow.'
'.&mt('Answer').'
'.$grayFont.&mt('Option ID').'
'; + $grayFont.$bottomrow.''.''; } elsif ($response eq 'match') { my %answer=&Apache::lonnet::str2hash($answer); - my @answer = %answer; - %answer = map {&HTML::Entities::encode($_, '"<>&')} @answer; my %grading=&Apache::lonnet::str2hash($record->{$version."resource.$partid.$respid.submissiongrading"}); my @items=&Apache::lonnet::str2array($record->{$version."resource.$partid.$respid.submissionitems"}); my ($toprow,$middlerow,$bottomrow); @@ -430,12 +343,12 @@ sub cleanRecord { ''.$grayFont.&mt('Item ID').'
'. $middlerow.''. ''.$grayFont.&mt('Option ID').''. - $bottomrow.''; + $bottomrow.''.''; } elsif ($response eq 'radiobutton') { my %answer=&Apache::lonnet::str2hash($answer); my ($toprow,$bottomrow); my $correct = - &get_radiobutton_correct_foil($partid,$respid,$symb,$uname,$udom,$type,$trial,$rndseed); + &get_radiobutton_correct_foil($partid,$respid,$symb,$uname,$udom); foreach my $foil (@$order) { if (exists($answer{$foil})) { if ($foil eq $correct) { @@ -451,7 +364,7 @@ sub cleanRecord { return '
'. ''.$toprow.''. ''. - $bottomrow.'
'.&mt('Answer').'
'.$grayFont.&mt('Option ID').'
'; + $bottomrow.''.''; } elsif ($response eq 'essay') { if (! exists ($env{'form.'.$symb})) { my (%keyhash) = &Apache::lonnet::dump('nohist_handgrade', @@ -466,10 +379,9 @@ sub cleanRecord { $env{'form.'.$symb} = 1; # so that we don't have to read it from disk for multiple sub of the same prob. } $answer =~ s-\n-
-g; - return '

'.&keywords_highlight(&HTML::Entities::encode($answer, '"<>&')).'
'; + return '

'.&keywords_highlight($answer).'
'; } elsif ( $response eq 'organic') { - my $result=&mt('Smile representation: [_1]', - '"'.&HTML::Entities::encode($answer, '"<>&').'"'); + my $result='Smile representation: "'.$answer.'"'; my $jme=$record->{$version."resource.$partid.$respid.molecule"}; $result.=&Apache::chemresponse::jme_img($jme,$answer,400); return $result; @@ -503,21 +415,18 @@ sub cleanRecord { $result.=''; return $result; } - } elsif ( $response =~ m/(?:numerical|formula|custom)/) { - # Respect multiple input fields, see Bug #5409 + } elsif ( $response =~ m/(?:numerical|formula)/) { $answer = &Apache::loncommon::format_previous_attempt_value('submission', $answer); - return $answer; } - return &HTML::Entities::encode($answer, '"<>&'); + return $answer; } #-- A couple of common js functions sub commonJSfunctions { my $request = shift; - $request->print(< + $request->print(&Apache::lonhtmlcommon::scripttag(< 1) { @@ -545,7 +454,6 @@ sub commonJSfunctions { return selectOne.value; } } - COMMONJSFUNCTIONS } @@ -700,17 +608,16 @@ sub student_gradeStatus { sub jscriptNform { my ($symb) = @_; my $stu_status = join(':',&Apache::loncommon::get_env_multiple('form.Status')); - my $jscript=''."\n"; + "\n"); $jscript.= '
'."\n". ''."\n". ''."\n". - ''."\n". ''."\n". ''."\n". ''."\n". @@ -755,11 +662,7 @@ sub compute_points { # sub most_similar { - my ($uname,$udom,$symb,$uessay)=@_; - - unless ($symb) { return ''; } - - unless (ref($old_essays{$symb}) eq 'HASH') { return ''; } + my ($uname,$udom,$uessay,$old_essays)=@_; # ignore spaces and punctuation @@ -776,11 +679,11 @@ sub most_similar { my $scrsid=''; my $sessay=''; # go through all essays ... - foreach my $tkey (keys(%{$old_essays{$symb}})) { + foreach my $tkey (keys(%$old_essays)) { my ($tname,$tdom,$tcrsid)=map {&unescape($_)} (split(/\./,$tkey)); # ... except the same student next if (($tname eq $uname) && ($tdom eq $udom)); - my $tessay=$old_essays{$symb}{$tkey}; + my $tessay=$old_essays->{$tkey}; $tessay=~s/\W+/ /gs; # String similarity gives up if not even limit my $tsimilar=&String::Similarity::similarity($uessay,$tessay,$limit); @@ -790,7 +693,7 @@ sub most_similar { $sname=$tname; $sdom=$tdom; $scrsid=$tcrsid; - $sessay=$old_essays{$symb}{$tkey}; + $sessay=$old_essays->{$tkey}; } } if ($limit>0.6) { @@ -804,22 +707,31 @@ sub most_similar { #------------------------------------ Receipt Verification Routines # + +sub initialverifyreceipt { + my ($request,$symb) = @_; + &commonJSfunctions($request); + return ''. + &Apache::lonnet::recprefix($env{'request.course.id'}). + '-'. + ''."\n". + ''. + "
\n"; +} + #--- Check whether a receipt number is valid.--- sub verifyreceipt { - my $request = shift; + my ($request,$symb) = @_; my $courseid = $env{'request.course.id'}; my $receipt = &Apache::lonnet::recprefix($courseid).'-'. $env{'form.receipt'}; $receipt =~ s/[^\-\d]//g; - my ($symb) = &get_symb($request); my $title.= '

'. - &mt('Verifying Receipt No. [_1]',$receipt). - '

'."\n". - '

'.&mt('[_1]Resource: [_2]','',''.$env{'form.probTitle'}). - '

'."\n"; + &mt('Verifying Receipt Number [_1]',$receipt). + ''."\n"; my ($string,$contents,$matches) = ('','',0); my (undef,undef,$fullname) = &getclasslist('all','0'); @@ -897,30 +809,28 @@ sub verifyreceipt { #--- Also called directly when one clicks on the subm button # on the problem page. sub listStudents { - my ($request) = shift; + my ($request,$symb) = @_; - my ($symb) = &get_symb($request); my $cdom = $env{"course.$env{'request.course.id'}.domain"}; my $cnum = $env{"course.$env{'request.course.id'}.num"}; my $getsec = $env{'form.section'} eq '' ? 'all' : $env{'form.section'}; my $getgroup = $env{'form.group'} eq '' ? 'all' : $env{'form.group'}; my $submitonly= $env{'form.submitonly'} eq '' ? 'all' : $env{'form.submitonly'}; my $viewgrade = $env{'form.showgrading'} eq 'yes' ? 'View/Grade/Regrade' : 'View'; - $env{'form.probTitle'} = $env{'form.probTitle'} eq '' ? - &Apache::lonnet::gettitle($symb) : $env{'form.probTitle'}; my $result='

 ' .&mt("$viewgrade Submissions for a Student or a Group of Students") .'

'; - my ($table,undef,$hdgrade,$partlist,$handgrade) = &showResourceInfo($symb,$env{'form.probTitle'},($env{'form.showgrading'} eq 'yes')); + my ($partlist,$handgrade,$responseType) = &response_type($symb +#,$res_error + ); my %lt = &Apache::lonlocal::texthash ( 'multiple' => 'Please select a student or group of students before clicking on the Next button.', 'single' => 'Please select the student before clicking on the Next button.', ); - $request->print(< + $request->print(&Apache::lonhtmlcommon::scripttag(< LISTJAVASCRIPT &commonJSfunctions($request); @@ -958,7 +867,7 @@ LISTJAVASCRIPT my $checkhdgrade = ($env{'form.handgrade'} eq 'yes' && scalar(@$partlist) > 1 ) ? 'checked="checked"' : ''; my $checklastsub = $checkhdgrade eq '' ? 'checked="checked"' : ''; my $gradeTable='
'. - "\n".$table; + "\n"; $gradeTable .= &Apache::lonhtmlcommon::start_pick_box(); $gradeTable .= &Apache::lonhtmlcommon::row_title(&mt('View Problem Text')) @@ -1012,7 +921,6 @@ LISTJAVASCRIPT '
'."\n". '
'."\n". ''."\n". - ''."\n". ''."\n". ''."\n"; @@ -1169,7 +1077,7 @@ LISTJAVASCRIPT if ($submitonly eq 'graded' ) { $submissions = 'ungraded submissions'; } if ($submitonly eq 'queued' ) { $submissions = 'queued submissions'; } $gradeTable='
 '. - &mt('No '.$submissions.' found for this resource for any students. ([quant,_1,student] checked for '.$submissions.')', + &mt('No '.$submissions.' found for this resource for any students. ([_1] students checked for '.$submissions.')', $num_students). '
'; } @@ -1185,7 +1093,7 @@ LISTJAVASCRIPT sub check_script { my ($form, $type)=@_; - my $chkallscript=''."\n"; +'."\n"); return $chkallscript; } @@ -1255,8 +1163,7 @@ sub processGroup { sub sub_page_js { my $request = shift; my $alertmsg = &mt('A number equal or greater than 0 is expected. Entered value = '); - $request->print(< + $request->print(&Apache::lonhtmlcommon::scripttag(< SUBJAVASCRIPT } @@ -1434,8 +1340,7 @@ sub sub_page_kw_js { my $iconpath = $request->dir_config('lonIconsURL'); &commonJSfunctions($request); - my $inner_js_msg_central=< + my $inner_js_msg_central= &Apache::lonhtmlcommon::scripttag(< INNERJS - my $inner_js_highlight_central=< + my $inner_js_highlight_central= &Apache::lonhtmlcommon::scripttag(< INNERJS my $start_page_msg_central = @@ -1510,38 +1412,12 @@ INNERJS my $docopen=&Apache::lonhtmlcommon::javascript_docopen(); $docopen=~s/^document\.//; - my %lt = &Apache::lonlocal::texthash( - keyw => 'Keywords list, separated by a space. Add/delete to list if desired.', - plse => 'Please select a word or group of words from document and then click this link.', - adds => 'Add selection to keyword list? Edit if desired.', - comp => 'Compose Message for: ', - incl => 'Include', - type => 'Type', - subj => 'Subject', - mesa => 'Message', - new => 'New', - save => 'Save', - canc => 'Cancel', - kehi => 'Keyword Highlight Options', - txtc => 'Text Color', - font => 'Font Size', - fnst => 'Font Style', - col1 => 'red', - col2 => 'green', - col3 => 'blue', - siz1 => 'normal', - siz2 => '+1', - siz3 => '+2', - sty1 => 'normal', - sty2 => 'italic', - sty3 => 'bold', - ); - $request->print(< + my $alertmsg = &mt('Please select a word or group of words from document and then click this link.'); + $request->print(&Apache::lonhtmlcommon::scripttag(< 600) { height = 600; + scrollbar = "yes"; } var xpos = (screen.width-600)/2; xpos = (xpos < 0) ? '0' : xpos; var ypos = (screen.height-height)/2-30; ypos = (ypos < 0) ? '0' : ypos; - pWin = window.open('', 'MessageCenter', 'resizable=yes,toolbar=no,location=no,scrollbars=yes,screenx='+xpos+',screeny='+ypos+',width=700,height='+height); + pWin = window.open('', 'MessageCenter', 'resizable=yes,toolbar=no,location=no,scrollbars='+scrollbar+',screenx='+xpos+',screeny='+ypos+',width=600,height='+height); pWin.focus(); pDoc = pWin.document; pDoc.$docopen; @@ -1651,16 +1529,16 @@ INNERJS pDoc.write(""); pDoc.write(""); - pDoc.write("

 $lt{'comp'}\"+fullname+\"<\\/span><\\/h3>

"); + pDoc.write("

 Compose Message for \"+fullname+\"<\\/span><\\/h3>

"); pDoc.write('
'); pDoc.write(''); - pDoc.write(""); - pDoc.write(""); - pDoc.write("
$lt{'type'}<\\/b><\\/td>$lt{'incl'}<\\/b><\\/td>$lt{'mesa'}<\\/td><\\/tr>"); + pDoc.write("Type<\\/b><\\/td>Include<\\/b><\\/td>Message<\\/td><\\/tr>"); } function displaySubject(msg,shwsel) { pDoc = pWin.document; pDoc.write("
$lt{'subj'}<\\/td>"); + pDoc.write("Subject<\\/td>"); pDoc.write("<\\/td>"); pDoc.write("<\\/td><\\/tr>"); } @@ -1676,7 +1554,7 @@ INNERJS function newMsg(newmsg,shwsel) { pDoc = pWin.document; pDoc.write("
$lt{'new'}<\\/td>"); + pDoc.write("New<\\/td>"); pDoc.write("<\\/td>"); pDoc.write("