--- loncom/homework/grades.pm 2014/02/27 01:39:48 1.722
+++ loncom/homework/grades.pm 2015/03/18 12:53:24 1.735
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# The LON-CAPA Grading handler
#
-# $Id: grades.pm,v 1.722 2014/02/27 01:39:48 raeburn Exp $
+# $Id: grades.pm,v 1.735 2015/03/18 12:53:24 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -406,8 +406,7 @@ 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.
}
- $answer =~ s-\n- -g;
- return '
';
} elsif ( $response eq 'organic') {
my $result=&mt('Smile representation: [_1]',
@@ -1296,10 +1295,8 @@ sub sub_page_js {
}
}
}
-
}
}
-
}
formname.submit();
}
@@ -1814,7 +1811,7 @@ sub handback_box {
if ($file =~ /\/portfolio\//) {
$file_counter++;
my ($file_path, $file_disp) = ($file =~ m|(.+/)(.+)$|);
- my ($name,$version,$ext) = &file_name_version_ext($file_disp);
+ my ($name,$version,$ext) = &Apache::lonnet::file_name_version_ext($file_disp);
$file_disp = "$name.$ext";
$file = $file_path.$file_disp;
$result.=&mt('Return commented version of [_1] to student.',
@@ -2227,7 +2224,7 @@ sub submission {
foreach my $submission (@$string) {
my ($partid,$respid) = ($submission =~ /^resource\.([^\.]*)\.([^\.]*)\.submission/);
if (join('_',@{$part}) ne ($partid.'_'.$respid)) { next; }
- my ($ressub,$hide,$subval) = split(/:/,$submission,3);
+ my ($ressub,$hide,$draft,$subval) = split(/:/,$submission,4);
# Similarity check
my $similar='';
my ($type,$trial,$rndseed);
@@ -2296,9 +2293,17 @@ sub submission {
if ($hide eq 'anon') {
$lastsubonly.=' '.&mt('Anonymous Survey').'';
} else {
- $lastsubonly.=' '.&mt('Submitted Answer:').' '.
+ $lastsubonly.=' '.&mt('Submitted Answer:').' ';
+ if ($draft) {
+ $lastsubonly.= ' '.&mt('Draft Copy').'';
+ }
+ $subval =
&cleanRecord($subval,$responsetype,$symb,$partid,
$respid,\%record,$order,undef,$uname,$udom,$type,$trial,$rndseed);
+ if ($responsetype eq 'essay') {
+ $subval =~ s{\n}{ }g;
+ }
+ $lastsubonly.=$subval."\n";
}
if ($similar) {$lastsubonly.="
$similar\n";}
$lastsubonly.='';
@@ -2314,10 +2319,12 @@ sub submission {
}
if ($env{'form.lastSub'} =~ /^(last|all)$/) {
+ my $identifier = (&canmodify($usec)? $counter : '');
$request->print(&Apache::loncommon::get_previous_attempt($symb,$uname,$udom,
$env{'request.course.id'},
$last,'.submission',
- 'Apache::grades::keywords_highlight'));
+ 'Apache::grades::keywords_highlight',
+ $usec,$identifier));
}
$request->print(''."\n");
@@ -2536,7 +2543,7 @@ sub get_last_submission {
}
unless ($hide) {
if (@randomize) {
- foreach my $id (@hidden) {
+ foreach my $id (@randomize) {
if ($key =~ /^\Q$id\E/) {
$hide = 'rand';
last;
@@ -2545,10 +2552,8 @@ sub get_last_submission {
}
}
my ($partid,$foo) = split(/submission$/,$key);
- my $draft = $lasthash{$partid.'awarddetail'} eq 'DRAFT' ?
- ''.&mt('Draft Copy').' ' : '';
- #push(@string, join(':', $key, $hide, $draft.$lasthash{$key}));
- push(@string, join(':', $key, $hide, $draft.(
+ my $draft = $lasthash{$partid.'awarddetail'} eq 'DRAFT' ? 1 : 0;
+ push(@string, join(':', $key, $hide, $draft, (
ref($lasthash{$key}) eq 'ARRAY' ?
join(',', @{$lasthash{$key}}) : $lasthash{$key}) ));
}
@@ -2769,7 +2774,8 @@ sub processHandGrade {
my $ctr = 0;
while ($ctr < $ngrade) {
my ($uname,$udom) = split(/:/,$env{'form.unamedom'.$ctr});
- my ($errorflag,$pts,$wgt) = &saveHandGrade($request,$symb,$uname,$udom,$ctr);
+ my ($errorflag,$pts,$wgt,$numhidden) =
+ &saveHandGrade($request,$symb,$uname,$udom,$ctr);
if ($errorflag eq 'no_score') {
$ctr++;
next;
@@ -2782,6 +2788,12 @@ sub processHandGrade {
$ctr++;
next;
}
+ if ($numhidden) {
+ $request->print(
+ ''
+ .&mt('For [_1]: [quant,_2,transaction] hidden',"$uname:$udom",$numhidden)
+ .' ');
+ }
my $includemsg = $env{'form.includemsg'.$ctr};
my ($subject,$message,$msgstatus) = ('','','');
my $restitle = &Apache::lonnet::gettitle($symb);
@@ -3003,9 +3015,14 @@ sub saveHandGrade {
my %record = &Apache::lonnet::restore($symb,$env{'request.course.id'},$domain,$stuname);
my @parts_graded;
my %newrecord = ();
- my ($pts,$wgt) = ('','');
+ my ($pts,$wgt,$totchg) = ('','',0);
my %aggregate = ();
my $aggregateflag = 0;
+ if ($env{'form.HIDE'.$newflg}) {
+ my ($version,$parts) = split(/:/,$env{'form.HIDE'.$newflg},2);
+ my $numchgs = &makehidden($version,$parts,\%record,$symb,$domain,$stuname,1);
+ $totchg += $numchgs;
+ }
my @parts = split(/:/,$env{'form.partlist'.$newflg});
foreach my $new_part (@parts) {
#collaborator ($submi may vary for different parts
@@ -3108,7 +3125,37 @@ sub saveHandGrade {
&Apache::lonnet::cinc('nohist_resourcetracker',\%aggregate,
$cdom,$cnum);
}
- return ('',$pts,$wgt);
+ return ('',$pts,$wgt,$totchg);
+}
+
+sub makehidden {
+ my ($version,$parts,$record,$symb,$domain,$stuname,$tolog) = @_;
+ return unless (ref($record) eq 'HASH');
+ my %modified;
+ my $numchanged = 0;
+ if (exists($record->{$version.':keys'})) {
+ my $partsregexp = $parts;
+ $partsregexp =~ s/,/|/g;
+ foreach my $key (split(/\:/,$record->{$version.':keys'})) {
+ if ($key =~ /^resource\.(?:$partsregexp)\.([^\.]+)$/) {
+ my $item = $1;
+ unless (($item eq 'solved') || ($item =~ /^award(|msg|ed)$/)) {
+ $modified{$key} = $record->{$version.':'.$key};
+ }
+ } elsif ($key =~ m{^(resource\.(?:$partsregexp)\.[^\.]+\.)(.+)$}) {
+ $modified{$1.'hidden'.$2} = $record->{$version.':'.$key};
+ } elsif ($key =~ /^(ip|timestamp|host)$/) {
+ $modified{$key} = $record->{$version.':'.$key};
+ }
+ }
+ if (keys(%modified)) {
+ if (&Apache::lonnet::putstore($env{'request.course.id'},$symb,$version,\%modified,
+ $domain,$stuname,$tolog) eq 'ok') {
+ $numchanged ++;
+ }
+ }
+ }
+ return $numchanged;
}
sub check_and_remove_from_queue {
@@ -3152,13 +3199,13 @@ sub handback_files {
my ($directory,$answer_file) =
($env{'form.'.$newflg.'_'.$part_resp.'_origdoc'.$counter} =~ /^(.*?)([^\/]*)$/);
my ($answer_name,$answer_ver,$answer_ext) =
- &file_name_version_ext($answer_file);
+ &Apache::lonnet::file_name_version_ext($answer_file);
my ($portfolio_path) = ($directory =~ /^.+$stuname\/portfolio(.*)/);
my $getpropath = 1;
my ($dir_list,$listerror) =
&Apache::lonnet::dirlist($portfolio_root.$portfolio_path,
$domain,$stuname,$getpropath);
- my $version = &get_next_version($answer_name,$answer_ext,$dir_list);
+ my $version = &Apache::lonnet::get_next_version($answer_name,$answer_ext,$dir_list);
# fix filename
my ($save_file_name) = (($directory.$answer_name.".$version.".$answer_ext) =~ /^.+\/${stuname}\/(.*)/);
my $result=&Apache::lonnet::finishuserfileupload($stuname,$domain,
@@ -3307,29 +3354,14 @@ sub version_portfiles {
my $version_parts = join('|',@$v_flag);
my @returned_keys;
my $parts = join('|', @$parts_graded);
- my $portfolio_root = '/userfiles/portfolio';
foreach my $key (keys(%$record)) {
my $new_portfiles;
if ($key =~ /^resource\.($version_parts)\./ && $key =~ /\.portfiles$/ ) {
my @versioned_portfiles;
my @portfiles = split(/\s*,\s*/,$$record{$key});
- foreach my $file (@portfiles) {
- &Apache::lonnet::unmark_as_readonly($domain,$stu_name,[$symb,$env{'request.course.id'}],$file);
- my ($directory,$answer_file) =($file =~ /^(.*?)([^\/]*)$/);
- my ($answer_name,$answer_ver,$answer_ext) =
- &file_name_version_ext($answer_file);
- my $getpropath = 1;
- my ($dir_list,$listerror) =
- &Apache::lonnet::dirlist($portfolio_root.$directory,$domain,
- $stu_name,$getpropath);
- my $version = &get_next_version($answer_name,$answer_ext,$dir_list);
- my $new_answer = &version_selected_portfile($domain, $stu_name, $directory, $answer_file, $version);
- if ($new_answer ne 'problem getting file') {
- push(@versioned_portfiles, $directory.$new_answer);
- &Apache::lonnet::mark_as_readonly($domain,$stu_name,
- [$directory.$new_answer],
- [$symb,$env{'request.course.id'},'graded']);
- }
+ if (@portfiles) {
+ &Apache::lonnet::portfiles_versioning($symb,$domain,$stu_name,\@portfiles,
+ \@versioned_portfiles);
}
$$record{$key} = join(',',@versioned_portfiles);
push(@returned_keys,$key);
@@ -3338,64 +3370,6 @@ sub version_portfiles {
return (@returned_keys);
}
-sub get_next_version {
- my ($answer_name, $answer_ext, $dir_list) = @_;
- my $version;
- if (ref($dir_list) eq 'ARRAY') {
- foreach my $row (@{$dir_list}) {
- my ($file) = split(/\&/,$row,2);
- my ($file_name,$file_version,$file_ext) =
- &file_name_version_ext($file);
- if (($file_name eq $answer_name) &&
- ($file_ext eq $answer_ext)) {
- # gets here if filename and extension match,
- # regardless of version
- if ($file_version ne '') {
- # a versioned file is found so save it for later
- if ($file_version > $version) {
- $version = $file_version;
- }
- }
- }
- }
- }
- $version ++;
- return($version);
-}
-
-sub version_selected_portfile {
- my ($domain,$stu_name,$directory,$file_name,$version) = @_;
- my ($answer_name,$answer_ver,$answer_ext) =
- &file_name_version_ext($file_name);
- my $new_answer;
- $env{'form.copy'} = &Apache::lonnet::getfile("/uploaded/$domain/$stu_name/portfolio$directory$file_name");
- if($env{'form.copy'} eq '-1') {
- $new_answer = 'problem getting file';
- } else {
- $new_answer = $answer_name.'.'.$version.'.'.$answer_ext;
- my $copy_result = &Apache::lonnet::finishuserfileupload(
- $stu_name,$domain,'copy',
- '/portfolio'.$directory.$new_answer);
- }
- return ($new_answer);
-}
-
-sub file_name_version_ext {
- my ($file)=@_;
- my @file_parts = split(/\./, $file);
- my ($name,$version,$ext);
- if (@file_parts > 1) {
- $ext=pop(@file_parts);
- if (@file_parts > 1 && $file_parts[-1] =~ /^\d+$/) {
- $version=pop(@file_parts);
- }
- $name=join('.',@file_parts);
- } else {
- $name=join('.',@file_parts);
- }
- return($name,$version,$ext);
-}
-
#--------------------------------------------------------------------------------------
#
#-------------------------- Next few routines handles grading by section or whole class
@@ -4776,9 +4750,11 @@ sub displayPage {
}
} elsif ($env{'form.lastSub'} eq 'all') {
my $last = ($env{'form.lastSub'} eq 'last' ? 'last' : '');
+ my $identifier = (&canmodify($usec)? $prob : '');
$studentTable.=&Apache::loncommon::get_previous_attempt($symbx,$uname,$udom,
$env{'request.course.id'},
- '','.submission');
+ '','.submission',undef,
+ $usec,$identifier);
}
if (&canmodify($usec)) {
@@ -4830,7 +4806,7 @@ sub displaySubByDates {
my $interaction;
my $no_increment = 1;
- my %lastrndseed;
+ my (%lastrndseed,%lasttype);
for ($version=1;$version<=$$record{'version'};$version++) {
my $timestamp =
&Apache::lonlocal::locallocaltime($$record{$version.':timestamp'});
@@ -4888,12 +4864,14 @@ sub displaySubByDates {
} else {
$displaySub[0].=&mt('Trial: [_1]',
$$record{"$where.$partid.tries"});
- if ($rndseed || $lastrndseed{$partid}) {
- if ($rndseed ne $lastrndseed{$partid}) {
+ if (($rndseed ne '') && ($lastrndseed{$partid} ne '')) {
+ if (($rndseed ne $lastrndseed{$partid}) &&
+ (($type eq 'randomizetry') || ($lasttype{$partid} eq 'randomizetry'))) {
$newvariation = ' ('.&mt('New variation this try').')';
}
}
$lastrndseed{$partid} = $rndseed;
+ $lasttype{$partid} = $type;
}
my $responseType=($isTask ? 'Task'
: $responseType->{$partid}->{$responseId});
@@ -4991,7 +4969,7 @@ sub updateGradeByPage {
$iterator->next(); # skip the first BEGIN_MAP
my $curRes = $iterator->next(); # for "current resource"
- my ($depth,$question,$prob,$changeflag)= (1,1,1,0);
+ my ($depth,$question,$prob,$changeflag,$hideflag)= (1,1,1,0,0);
while ($depth > 0) {
if($curRes == $iterator->BEGIN_MAP) { $depth++; }
if($curRes == $iterator->END_MAP) { $depth--; }
@@ -5012,6 +4990,12 @@ sub updateGradeByPage {
my @displayPts=();
my %aggregate = ();
my $aggregateflag = 0;
+ if ($env{'form.HIDE'.$prob}) {
+ my %record = &Apache::lonnet::restore($symbx,$env{'request.course.id'},$udom,$uname);
+ my ($version,$parts) = split(/:/,$env{'form.HIDE'.$prob},2);
+ my $numchgs = &makehidden($version,$parts,\%record,$symbx,$udom,$uname,1);
+ $hideflag += $numchgs;
+ }
foreach my $partid (@{$parts}) {
my $newpts = $env{'form.GD_BOX'.$question.'_'.$partid};
my $oldpts = $env{'form.oldpts'.$question.'_'.$partid};
@@ -5102,8 +5086,11 @@ sub updateGradeByPage {
$studentTable.=&Apache::loncommon::end_data_table();
my $grademsg=($changeflag == 0 ? &mt('No score was changed or updated.') :
&mt('The scores were changed for [quant,_1,problem].',
- $changeflag));
- $request->print($grademsg.$studentTable);
+ $changeflag).' ');
+ my $hidemsg=($hideflag == 0 ? '' :
+ &mt('Submissions were marked "hidden" for [quant,_1,transaction].',
+ $hideflag).' ');
+ $request->print($hidemsg.$grademsg.$studentTable);
return '';
}
@@ -5729,7 +5716,9 @@ sub get_scantron_config {
=item username_to_idmap
creates a hash keyed by student/employee ID with values of the corresponding
- student username:domain.
+ student username:domain. If a single ID occurs for more than one student,
+ the status of the student is checked, and if Active, the value in the hash
+ will be set to the Active student.
Arguments:
@@ -5747,8 +5736,17 @@ sub username_to_idmap {
my ($classlist)= @_;
my %idmap;
foreach my $student (keys(%$classlist)) {
- $idmap{$classlist->{$student}->[&Apache::loncoursedata::CL_ID]}=
- $student;
+ my $id = $classlist->{$student}->[&Apache::loncoursedata::CL_ID];
+ unless ($id eq '') {
+ if (!exists($idmap{$id})) {
+ $idmap{$id} = $student;
+ } else {
+ my $status = $classlist->{$student}->[&Apache::loncoursedata::CL_STATUS];
+ if ($status eq 'Active') {
+ $idmap{$id} = $student;
+ }
+ }
+ }
}
return %idmap;
}
@@ -8914,7 +8912,7 @@ sub scantron_download_scantron_data {
&Apache::lonnet::allowuploaded('/adm/grades',$skipped);
$r->print('
- '.&mt('[_1]Original[_2] file as uploaded by the bubblesheet office.',
+ '.&mt('[_1]Original[_2] file as uploaded by the bubblesheet scanning office.',
'','').'