';
+ my $display_part=&get_display_part($partID,$symb);
+ $result.='
Part: '.$display_part.' '.
+ $resID.'
'.
+ '
Type: '.$responsetype.'
';
# '
Handgrade: '.$handgrade.'
';
+ }
}
$result.=''."\n";
return $result,$responseType,$hdgrade,$partlist,$handgrade;
@@ -586,7 +588,7 @@ sub verifyreceipt {
my $receipt = &Apache::lonnet::recprefix($courseid).'-'.
$env{'form.receipt'};
$receipt =~ s/[^\-\d]//g;
- my $symb = &Apache::lonnet::symbread();
+ my ($symb) = &get_symb($request);
my $title.='
Verifying Submission Receipt '.
$receipt.'
'."\n".
@@ -1535,10 +1537,11 @@ sub handback_box {
my ($symb,$uname,$udom,$counter,$partid,$record) = @_;
my ($partlist,$handgrade,$responseType) = &response_type($symb);
my (@respids);
- foreach my $part_resp (sort(keys(%$handgrade))) {
- my ($part,$resp) = split(/_/,$part_resp);
+ my @part_response_id = &flatten_responseType($responseType);
+ foreach my $part_response_id (@part_response_id) {
+ my ($part,$resp) = @{ $part_response_id };
if ($part eq $partid) {
- push @respids,$resp;
+ push(@respids,$resp);
}
}
my $result;
@@ -1548,15 +1551,18 @@ sub handback_box {
next if (!@$files);
my $file_counter = 1;
foreach my $file (@$files) {
- my ($file_path, $file_disp) = ($file =~ m|(.+/)(.+)$|);
- my ($name,$version,$ext) = &file_name_version_ext($file_disp);
- $file_disp = "$name.$ext";
- $file = $file_path.$file_disp;
- $result.=&mt('Return commented version of [_1] to student.',
- ''.$file_disp.'');
- $result.=''."\n";
- $result.=' ';
- $file_counter++;
+ if ($file =~ /\/portfolio\//) {
+ my ($file_path, $file_disp) = ($file =~ m|(.+/)(.+)$|);
+ my ($name,$version,$ext) = &file_name_version_ext($file_disp);
+ $file_disp = "$name.$ext";
+ $file = $file_path.$file_disp;
+ $result.=&mt('Return commented version of [_1] to student.',
+ ''.$file_disp.'');
+ $result.=''."\n";
+ $result.=' ';
+ $result.='(File will be uploaded when you click on Save & Next below.) ';
+ $file_counter++;
+ }
}
}
return $result;
@@ -1573,7 +1579,7 @@ sub show_problem {
if ($removeform) {
$rendered=~s|||g;
- $rendered=~s|name="submit"|name="would_have_been_submit"|g;
+ $rendered=~s|(]*name\s*=\s*"?)(\w+)("?)|$1would_have_been_$2$3|g;
}
my $companswer;
if ($mode eq 'both' or $mode eq 'answer') {
@@ -1747,7 +1753,7 @@ KEYWORDS
#
my (undef,undef,$essayurl) = &Apache::lonnet::decode_symb($symb);
my ($adom,$aname,$apath)=($essayurl=~/^(\w+)\/(\w+)\/(.*)$/);
- $apath=&Apache::lonnet::escape($apath);
+ $apath=&escape($apath);
$apath=~s/\W/\_/gs;
%oldessays=&Apache::lonnet::dump('nohist_essay_'.$apath,$adom,$aname);
}
@@ -1852,8 +1858,9 @@ KEYWORDS
$lastsubonly.='
'.$$string[0];
} else {
my %seenparts;
- for my $part (sort keys(%$handgrade)) {
- my ($partid,$respid) = split(/_/,$part);
+ my @part_response_id = &flatten_responseType($responseType);
+ foreach my $part (@part_response_id) {
+ my ($partid,$respid) = @{ $part };
my $display_part=&get_display_part($partid,$symb);
if ($env{"form.$uname:$udom:$partid:submitted_by"}) {
if (exists($seenparts{$partid})) { next; }
@@ -1877,7 +1884,7 @@ KEYWORDS
}
foreach (@$string) {
my ($partid,$respid) = /^resource\.([^\.]*)\.([^\.]*)\.submission/;
- if ($part ne ($partid.'_'.$respid)) { next; }
+ if (join('_',@{$part}) ne ($partid.'_'.$respid)) { next; }
my ($ressub,$subval) = split(/:/,$_,2);
# Similarity check
my $similar='';
@@ -1897,7 +1904,7 @@ KEYWORDS
my $order=&get_order($partid,$respid,$symb,$uname,$udom);
if ($env{'form.lastSub'} eq 'lastonly' ||
($env{'form.lastSub'} eq 'hdgrade' &&
- $$handgrade{$part} eq 'yes')) {
+ $$handgrade{$$part[0].'_'.$$part[1]} eq 'yes')) {
my $display_part=&get_display_part($partid,$symb);
$lastsubonly.='
Part: '.
$display_part.' ( ID '.$respid.
@@ -1987,8 +1994,10 @@ KEYWORDS
my %seen = ();
my @partlist;
my @gradePartRespid;
- for my $part_resp (sort(keys(%$handgrade))) {
- my ($partid,$respid) = split(/_/, $part_resp);
+ my @part_response_id = &flatten_responseType($responseType);
+ foreach my $part_response_id (@part_response_id) {
+ my ($partid,$respid) = @{ $part_response_id };
+ my $part_resp = join('_',@{ $part_response_id });
next if ($seen{$partid} > 0);
$seen{$partid}++;
next if ($$handgrade{$part_resp} =~ /:no$/ && $env{'form.lastSub'} =~ /^(hdgrade)$/);
@@ -2104,6 +2113,7 @@ sub processHandGrade {
if ($includemsg =~ /savemsg|newmsg\Q$ctr\E/) {
$subject = $env{'form.msgsub'} if ($includemsg =~ /msgsub/);
unless ($subject=~/\w/) { $subject=&mt('Grading Feedback'); }
+ $subject.=' ['.&Apache::lonnet::declutter($url).']';
my (@msgnum) = split(/,/,$includemsg);
foreach (@msgnum) {
$message.=$env{'form.'.$_} if ($_ =~ /savemsg|newmsg/ && $_ ne '');
@@ -2116,8 +2126,8 @@ sub processHandGrade {
"?symb=$symb\">$env{'form.probTitle'}";
}
$msgstatus = &Apache::lonmsg::user_normal_msg($uname,$udom,
- $subject.' ['.
- &Apache::lonnet::declutter($url).']',$message);
+ $subject,
+ $message);
$request->print(' '.&mt('Sending message to [_1]@[_2]',$uname,$udom).': '.
$msgstatus);
}
@@ -2130,11 +2140,11 @@ sub processHandGrade {
&saveHandGrade($request,$symb,$collaborator,$udom,$ctr,
$env{'form.unamedom'.$ctr},$part);
if ($errorflag eq 'not_allowed') {
- $request->print("Not allowed to modify grades for $collaborator:$udom");
+ $request->print("".&mt('Not allowed to modify grades for [_1]',"$collaborator:$udom")."");
next;
} else {
if ($message ne '') {
- $msgstatus = &Apache::lonmsg::user_normal_msg($collaborator,$udom,$env{'form.msgsub'},$message);
+ $msgstatus = &Apache::lonmsg::user_normal_msg($collaborator,$udom,$subject,$message);
}
}
}
@@ -2326,7 +2336,7 @@ sub saveHandGrade {
if (exists($record{'resource.'.$new_part.'.awarded'})) {
$newrecord{'resource.'.$new_part.'.awarded'} = '';
}
- $newrecord{'resource.'.$new_part.'.regrader'}="$env{'user.name'}:$env{'user.domain'}";
+ $newrecord{'resource.'.$new_part.'.regrader'}="$env{'user.name'}:$env{'user.domain'}";
}
} elsif ($dropMenu eq 'reset status'
&& exists($record{'resource.'.$new_part.'.solved'})) { #don't bother if no old records -> no attempts
@@ -2386,7 +2396,6 @@ sub saveHandGrade {
}
$newrecord{'resource.'.$new_part.'.regrader'}=
"$env{'user.name'}:$env{'user.domain'}";
- &handback_files($request,$symb,$stuname,$domain,$newflg,$new_part,\%newrecord);
}
# unless problem has been graded, set flag to version the submitted files
unless ($record{'resource.'.$new_part.'.solved'} =~ /^correct_/ ||
@@ -2401,8 +2410,13 @@ sub saveHandGrade {
if (%newrecord) {
if (@version_parts) {
- my @changed_keys = &version_portfiles(\%record, \@parts_graded, $env{'request.course.id'}, $symb, $domain, $stuname, \@version_parts);
+ my @changed_keys = &version_portfiles(\%record, \@parts_graded,
+ $env{'request.course.id'}, $symb, $domain, $stuname, \@version_parts);
@newrecord{@changed_keys} = @record{@changed_keys};
+ foreach my $new_part (@version_parts) {
+ &handback_files($request,$symb,$stuname,$domain,$newflg,
+ $new_part,\%newrecord);
+ }
}
&Apache::lonnet::cstore(\%newrecord,$symb,
$env{'request.course.id'},$domain,$stuname);
@@ -2427,40 +2441,60 @@ sub saveHandGrade {
sub handback_files {
my ($request,$symb,$stuname,$domain,$newflg,$new_part,$newrecord) = @_;
- my $portfolio_root = &Apache::loncommon::propath($domain,
- $stuname).
- '/userfiles/portfolio';
- my ($partlist,$handgrade,$responseType) = &response_type($symb);
- foreach my $part_resp (sort(keys(%$handgrade))) {
- my ($part_id, $resp_id) = split(/_/,$part_resp);
+ my $portfolio_root = &propath($domain,$stuname).'/userfiles/portfolio';
+ my ($partlist,$handgrade,$responseType) = &response_type($symb);
+
+ my @part_response_id = &flatten_responseType($responseType);
+ foreach my $part_response_id (@part_response_id) {
+ my ($part_id,$resp_id) = @{ $part_response_id };
+ my $part_resp = join('_',@{ $part_response_id });
if (($env{'form.'.$newflg.'_'.$part_resp.'_returndoc1'}) && ($new_part == $part_id)) {
# if multiple files are uploaded names will be 'returndoc2','returndoc3'
my $file_counter = 1;
+ my $file_msg;
while ($env{'form.'.$newflg.'_'.$part_resp.'_returndoc'.$file_counter}) {
my $fname=$env{'form.'.$newflg.'_'.$part_resp.'_returndoc'.$file_counter.'.filename'};
my ($directory,$answer_file) =
($env{'form.'.$newflg.'_'.$part_resp.'_origdoc'.$file_counter} =~ /^(.*?)([^\/]*)$/);
my ($answer_name,$answer_ver,$answer_ext) =
&file_name_version_ext($answer_file);
- $directory =~ /^.+$stuname\/portfolio(.*)/;
- my $portfolio_path = $1;
+ my ($portfolio_path) = ($directory =~ /^.+$stuname\/portfolio(.*)/);
my @dir_list = &Apache::lonnet::dirlist($portfolio_path,$domain,$stuname,$portfolio_root);
my $version = &get_next_version($answer_name, $answer_ext, \@dir_list);
- my $new_answer = &version_selected_portfile($domain, $stuname, $portfolio_path, $answer_file, $version);
- $$newrecord{"resource.$new_part.$resp_id.handback"} = $new_answer;
- # set the filename to match the submitted file name
- $env{'form.'.$newflg.'_'.$part_resp.'_returndoc1.filename'} = $env{'form.'.$newflg.'_'.$part_resp.'_origdoc'.$file_counter};
- my $result=&Apache::lonnet::userfileupload($newflg.'_'.$part_resp.'_returndoc'.$file_counter,'',
- 'portfolio',undef,undef,undef,$stuname,$domain);
+ # fix file name
+ my ($save_file_name) = (($directory.$answer_name.".$version.".$answer_ext) =~ /^.+\/${stuname}\/(.*)/);
+ my $result=&Apache::lonnet::finishuserfileupload($stuname,$domain,
+ $newflg.'_'.$part_resp.'_returndoc'.$file_counter,
+ $save_file_name);
if ($result !~ m|^/uploaded/|) {
$request->print(' An errror occured ('.$result.
- ') while trying to upload '.&display_file().' ');
- # $request->print(&done('Back'));
+ ') while trying to upload '.$newflg.'_'.$part_resp.'_returndoc'.$file_counter.' ');
+ } else {
+ # mark the file as read only
+ my @files = ($save_file_name);
+ my @what = ($symb,$env{'request.course.id'},'handback');
+ &Apache::lonnet::mark_as_readonly($domain,$stuname,\@files,\@what);
+ if (exists($$newrecord{"resource.$new_part.$resp_id.handback"})) {
+ $$newrecord{"resource.$new_part.$resp_id.handback"}.=',';
+ }
+ $$newrecord{"resource.$new_part.$resp_id.handback"} .= $save_file_name;
+ $file_msg.= "\n".' '.$save_file_name." ";
+
}
$request->print(" ".$fname." will be the uploaded file name");
- $request->print("Will upload document ".$env{'form.'.$newflg.'_'.$part_resp.'_origdoc'.$file_counter});
+ $request->print(" ".$env{'form.'.$newflg.'_'.$part_resp.'_origdoc'.$file_counter});
$file_counter++;
}
+ my $subject = "File Handed Back by Instructor ";
+ my $message = "A file has been returned that was originally submitted in reponse to: ";
+ $message .= "".&Apache::lonnet::gettitle($symb)." ";
+ $message .= ' The returned file(s) are named: '. $file_msg;
+ $message .= " and can be found in your portfolio space.";
+ my $url = (&Apache::lonnet::decode_symb($symb))[2];
+ $url = &Apache::lonnet::declutter($url);
+ my $msgstatus = &Apache::lonmsg::user_normal_msg($stuname,$domain,
+ $subject.' (File Returned) ['.$url.']',$message);
+
}
}
return;
@@ -2546,14 +2580,13 @@ sub version_portfiles {
my $version_parts = join('|',@$v_flag);
my @returned_keys;
my $parts = join('|', @$parts_graded);
- my $portfolio_root = &Apache::loncommon::propath($domain,
- $stu_name).
- '/userfiles/portfolio';
+ my $portfolio_root = &propath($domain,$stu_name).
+ '/userfiles/portfolio';
foreach my $key (keys(%$record)) {
my $new_portfiles;
if ($key =~ /^resource\.($version_parts)\./ && $key =~ /\.portfiles$/ ) {
my @versioned_portfiles;
- my @portfiles = split(/,/,$$record{$key});
+ 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 =~ /^(.*?)([^\/]*)$/);
@@ -2565,7 +2598,7 @@ sub version_portfiles {
if ($new_answer ne 'problem getting file') {
push(@versioned_portfiles, $directory.$new_answer);
&Apache::lonnet::mark_as_readonly($domain,$stu_name,
- ['/portfolio'.$directory.$new_answer],
+ [$directory.$new_answer],
[$symb,$env{'request.course.id'},'graded']);
}
}
@@ -2847,16 +2880,18 @@ sub viewgrades {
'
';
#radio buttons/text box for assigning points for a section or class.
#handles different parts of a problem
- my ($partlist,$handgrade) = &response_type($symb);
+ my ($partlist,$handgrade,$responseType) = &response_type($symb);
my %weight = ();
my $ctsparts = 0;
$result.='
';
my %seen = ();
- for (sort keys(%$handgrade)) {
- my ($partid,$respid) = split (/_/,$_,2);
+ my @part_response_id = &flatten_responseType($responseType);
+ foreach my $part_response_id (@part_response_id) {
+ my ($partid,$respid) = @{ $part_response_id };
+ my $part_resp = join('_',@{ $part_response_id });
next if $seen{$partid};
$seen{$partid}++;
- my $handgrade=$$handgrade{$_};
+ my $handgrade=$$handgrade{$part_resp};
my $wgt = &Apache::lonnet::EXT('resource.'.$partid.'.weight',$symb);
$weight{$partid} = $wgt eq '' ? '1' : $wgt;
@@ -3415,9 +3450,10 @@ sub upcsvScores_form {
$result.=$table;
$result.='
'."\n";
$result.='
'."\n";
- $result.=' Specify a file containing the class scores for current resource'.
+ $result.=' '.&mt('Specify a file containing the class scores for current resource').
'.
'."\n";
$result.='
'."\n";
+ my $upload=&mt("Upload Scores");
my $upfile_select=&Apache::loncommon::upfile_select_html();
my $ignore=&mt('Ignore First Line');
$result.=<
$upfile_select
-
+
ENDUPFORM
- $result.='
'."\n";
+ $result.=&Apache::loncommon::help_open_topic("Course_Convert_To_CSV",
+ &mt("How do I create a CSV file from a spreadsheet"))
+ .'
'."\n";
$result.='
'."\n";
$result.=&show_grading_menu_form($symb);
return $result;
@@ -4219,7 +4257,7 @@ sub scantron_filenames {
my $cdom=$env{'course.'.$env{'request.course.id'}.'.domain'};
my $cname=$env{'course.'.$env{'request.course.id'}.'.num'};
my @files=&Apache::lonnet::dirlist('userfiles',$cdom,$cname,
- &Apache::loncommon::propath($cdom,$cname));
+ &propath($cdom,$cname));
my @possiblenames;
foreach my $filename (sort(@files)) {
($filename)=split(/&/,$filename);
@@ -4578,7 +4616,8 @@ sub scantron_parse_scanline {
substr($questions,0,$$scantron_config{'Qlength'})='';
if (length($currentquest) < $$scantron_config{'Qlength'}) { next; }
if ($$scantron_config{'Qon'} eq 'letter') {
- if ($currentquest eq '?') {
+ if ($currentquest eq '?'
+ || $currentquest eq '*') {
push(@{$record{'scantron.doubleerror'}},$questnum);
$record{"scantron.$questnum.answer"}='';
} elsif (!$currentquest
@@ -4592,7 +4631,8 @@ sub scantron_parse_scanline {
$record{"scantron.$questnum.answer"}=$currentquest;
}
} elsif ($$scantron_config{'Qon'} eq 'number') {
- if ($currentquest eq '?') {
+ if ($currentquest eq '?'
+ || $currentquest eq '*') {
push(@{$record{'scantron.doubleerror'}},$questnum);
$record{"scantron.$questnum.answer"}='';
} elsif (!$currentquest
@@ -4603,8 +4643,14 @@ sub scantron_parse_scanline {
push(@{$record{"scantron.missingerror"}},$questnum);
}
} else {
- $record{"scantron.$questnum.answer"}=
- $alphabet[$currentquest-1];
+ # wrap zero back to J
+ if ($currentquest eq '0') {
+ $record{"scantron.$questnum.answer"}=
+ $alphabet[9];
+ } else {
+ $record{"scantron.$questnum.answer"}=
+ $alphabet[$currentquest-1];
+ }
}
} else {
my @array=split($$scantron_config{'Qon'},$currentquest,-1);
@@ -4734,21 +4780,29 @@ sub reset_skipping_status {
&scantron_putfile(undef,$scan_data);
}
-sub allow_skipping {
+sub start_skipping {
my ($scan_data,$i)=@_;
my %remembered=split(':',&scan_data($scan_data,'remember_skipping'));
- delete($remembered{$i});
+ if ($env{'form.scantron_options_redo'} =~ /^redo_/) {
+ $remembered{$i}=2;
+ } else {
+ $remembered{$i}=1;
+ }
&scan_data($scan_data,'remember_skipping',join(':',%remembered));
}
sub should_be_skipped {
- my ($scan_data,$i)=@_;
+ my ($scanlines,$scan_data,$i)=@_;
if ($env{'form.scantron_options_redo'} !~ /^redo_/) {
# not redoing old skips
+ if ($scanlines->{'skipped'}[$i]) { return 1; }
return 0;
}
my %remembered=split(':',&scan_data($scan_data,'remember_skipping'));
- if (exists($remembered{$i})) { return 0; }
+
+ if (exists($remembered{$i}) && $remembered{$i} != 2 ) {
+ return 0;
+ }
return 1;
}
@@ -4760,6 +4814,7 @@ sub remember_current_skipped {
$to_remember{$i}=1;
}
}
+
&scan_data($scan_data,'remember_skipping',join(':',%to_remember));
&scantron_putfile(undef,$scan_data);
}
@@ -4775,15 +4830,15 @@ sub scantron_warning_screen {
my ($button_text)=@_;
my $title=&Apache::lonnet::gettitle($env{'form.selectpage'});
my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
- my $CODElist="a";
+ my $CODElist;
if ($scantron_config{'CODElocation'} &&
$scantron_config{'CODEstart'} &&
$scantron_config{'CODElength'}) {
$CODElist=$env{'form.scantron_CODElist'};
- if ($CODElist eq '') { $CODElist='None'; }
+ if ($env{'form.scantron_CODElist'} eq '') { $CODElist='None'; }
$CODElist=
'
List of CODES to validate against:
'.
- $CODElist.'
';
+ $env{'form.scantron_CODElist'}.'';
}
return (<
@@ -4865,7 +4920,6 @@ sub scantron_validate_file {
}
if ($env{'form.scantron_options_redo'} eq 'redo_skipped') {
&remember_current_skipped();
- &scantron_remove_file('skipped');
$env{'form.scantron_options_redo'}='redo_skipped_ready';
}
@@ -5035,8 +5089,8 @@ sub scantron_putfile {
sub scantron_get_line {
my ($scanlines,$scan_data,$i)=@_;
- if (&should_be_skipped($scan_data,$i)) { return undef; }
- if ($scanlines->{'skipped'}[$i]) { return undef; }
+ if (&should_be_skipped($scanlines,$scan_data,$i)) { return undef; }
+ #if ($scanlines->{'skipped'}[$i]) { return undef; }
if ($scanlines->{'corrected'}[$i]) {return $scanlines->{'corrected'}[$i];}
return $scanlines->{'orig'}[$i];
}
@@ -5056,12 +5110,21 @@ sub scantron_put_line {
my ($scanlines,$scan_data,$i,$newline,$skip)=@_;
if ($skip) {
$scanlines->{'skipped'}[$i]=$newline;
- &allow_skipping($scan_data,$i);
+ &start_skipping($scan_data,$i);
return;
}
$scanlines->{'corrected'}[$i]=$newline;
}
+sub scantron_clear_skip {
+ my ($scanlines,$scan_data,$i)=@_;
+ if (exists($scanlines->{'skipped'}[$i])) {
+ undef($scanlines->{'skipped'}[$i]);
+ return 1;
+ }
+ return 0;
+}
+
sub scantron_filter_not_exam {
my ($curres)=@_;
@@ -5093,7 +5156,7 @@ sub scantron_validate_sequence {
my @resources=
$navmap->retrieveResources($map,\&scantron_filter_not_exam,1,0);
if (@resources) {
- $r->print("
".&mt('Some resource in the sequece currently are not set to exam mode. Grading these resources currently may not work correctly.')."
");
+ $r->print("
".&mt('Some resources in the sequence currently are not set to exam mode. Grading these resources currently may not work correctly.')."