Part: '.
+ $display_part.' ( ID '.$respid.
' ) ';
+ my @files;
+ if ($record{"resource.$partid.$respid.portfiles"}) {
+ my $file_url = '/uploaded/'.$udom.'/'.$uname.'/portfolio';
+ foreach my $file (split(',',$record{"resource.$partid.$respid.portfiles"})) {
+ push(@files,$file_url.$file);
+
+ &Apache::lonnet::logthis("found a portfolio file".$record{"resource.$partid.$respid.portfiles"});
+ &Apache::lonnet::logthis("uploaded URL file".$record{"resource.$partid.$respid.uploadedurl"});
+ }
+ }
if ($record{"resource.$partid.$respid.uploadedurl"}) {
- $lastsubonly.=' File uploaded by student Like all files provided by users, this file may contain virusses ';
+ push(@files,$record{"resource.$partid.$respid.uploadedurl"});
+ }
+ if (@files) {
+ $lastsubonly.=' Like all files provided by users, this file may contain virusses ';
+ foreach my $file (@files) {
+ &Apache::lonnet::allowuploaded('/adm/grades',$file);
+ $lastsubonly.=' '.$file.'';
+ }
+ $lastsubonly.=' ';
}
$lastsubonly.='Submitted Answer: '.
&cleanRecord($subval,$responsetype,$symb,$partid,
@@ -1985,10 +2063,12 @@ sub processHandGrade {
# my %record = &Apache::lonnet::restore($symb,$ENV{'request.course.id'},$udom,$uname);
my %status=&student_gradeStatus($url,$symb,$udom,$uname,$partlist);
my $submitted = 0;
- my $graded = 1;
+ my $ungraded = 0;
+ my $incorrect = 0;
foreach (keys(%status)) {
$submitted = 1 if ($status{$_} ne 'nothing');
- $graded = 0 if ($status{$_} =~ /^correct/);
+ $ungraded = 1 if ($status{$_} =~ /^ungraded/);
+ $incorrect = 1 if ($status{$_} =~ /^incorrect/);
my ($foo,$partid,$foo1) = split(/\./,$_);
if ($status{'resource.'.$partid.'.submitted_by'} ne '') {
$submitted = 0;
@@ -1997,8 +2077,8 @@ sub processHandGrade {
next if (!$submitted && ($submitonly eq 'yes' ||
$submitonly eq 'incorrect' ||
$submitonly eq 'graded'));
- next if (!$graded && ($submitonly eq 'graded' ||
- $submitonly eq 'incorrect'));
+ next if (!$ungraded && ($submitonly eq 'graded'));
+ next if (!$incorrect && $submitonly eq 'incorrect');
}
push @nextlist,$student if ($ctr < $ntstu);
last if ($ctr == $ntstu);
@@ -2033,6 +2113,7 @@ sub saveHandGrade {
$ENV{'request.course.id'});
if (!&canmodify($usec)) { return('not_allowed'); }
my %record = &Apache::lonnet::restore($symb,$ENV{'request.course.id'},$domain,$stuname);
+ my @parts_graded;
my %newrecord = ();
my ($pts,$wgt) = ('','');
foreach (split(/:/,$ENV{'form.partlist'.$newflg})) {
@@ -2049,11 +2130,11 @@ sub saveHandGrade {
}
} elsif ($dropMenu eq 'reset status'
&& exists($record{'resource.'.$_.'.solved'})) { #don't bother if no old records -> no attempts
- $newrecord{'resource.'.$_.'.tries'} = 0;
- $newrecord{'resource.'.$_.'.solved'} = '';
- $newrecord{'resource.'.$_.'.award'} = '';
- $newrecord{'resource.'.$_.'.awarded'} = 0;
- $newrecord{'resource.'.$_.'.regrader'}="$ENV{'user.name'}:$ENV{'user.domain'}";
+ foreach my $key (keys (%record)) {
+ if ($key=~/^resource\.\Q$_\E\./) { $newrecord{$key} = ''; }
+ }
+ $newrecord{'resource.'.$_.'.regrader'}=
+ "$ENV{'user.name'}:$ENV{'user.domain'}";
} elsif ($dropMenu eq '') {
$pts = ($ENV{'form.GD_BOX'.$newflg.'_'.$_} ne '' ?
$ENV{'form.GD_BOX'.$newflg.'_'.$_} :
@@ -2067,6 +2148,8 @@ sub saveHandGrade {
if ($partial eq $record{'resource.'.$_.'.awarded'}) {
#do not update score for part if not changed.
next;
+ } else {
+ push @parts_graded, $_;
}
if ($record{'resource.'.$_.'.awarded'} ne $partial) {
$newrecord{'resource.'.$_.'.awarded'} = $partial;
@@ -2090,12 +2173,62 @@ sub saveHandGrade {
}
}
if (scalar(keys(%newrecord)) > 0) {
+ &version_portfiles(\%record, \@parts_graded, $ENV{'request.course.id'}, $symb, $domain, $stuname);
&Apache::lonnet::cstore(\%newrecord,$symb,
$ENV{'request.course.id'},$domain,$stuname);
}
return '',$pts,$wgt;
}
+# ----------- Handles creating versions for portfolio files as answers
+sub version_portfiles {
+ my ($record, $parts_graded, $courseid, $symb, $domain, $stuname) = @_;
+ my $parts = join('|', @$parts_graded);
+ my $portfolio_root = &Apache::loncommon::propath($domain,
+ $stuname).
+ '/userfiles/portfolio';
+ foreach my $key(keys %$record) {
+ if ($key =~ /^resource\.($parts)\./ && $key =~ /\.portfiles$/) {
+ my @portfiles = split(/,/,$$record{$key});
+ foreach my $file (@portfiles) {
+ my ($directory,$answer_file) =($file =~ /^(.*?)([^\/]*$)/);
+ my $version = 0;
+ my @answer_file_parts = split(/\./, $answer_file);
+ my @dir_list = &Apache::lonnet::dirlist($directory,$domain,$stuname,$portfolio_root);
+ my @file_names;
+ my @file_name_parts;
+ foreach my $row (@dir_list) {
+ @file_names = split(/\&/,$row,2);
+ @file_name_parts = split(/\./, $file_names[0]);
+ # ($file_name_parts[scalar @file_name_parts] eq $answer_file_parts[scalar @answer_file_parts])
+ if (($file_name_parts[0] eq $answer_file_parts[0]) &&
+ ($file_name_parts[-1] eq $answer_file_parts[-1])) {
+ # gets here if filename and extension match, regardless of version
+ if (scalar @file_name_parts == 3) { # a versioned file is found
+ # so save it for later
+ if ($file_name_parts[1] > $version) {$version = $file_name_parts[1]};
+ }
+ }
+ }
+ $version++;
+ my $home_server = &Apache::lonnet::homeserver($stuname,$domain,undef);
+ $ENV{'form.copy'} = &Apache::lonnet::getfile("/uploaded/$domain/$stuname/$directory$answer_file");
+ # $ENV{'form.copy.filename'}='';
+ my $copy_result = &Apache::lonnet::finishuserfileupload($stuname,$domain,$home_server,'copy',
+ '/portfolio'.$directory.$answer_file_parts[0].'.'.$version.'.'.$answer_file_parts[-1]);
+ &Apache::lonnet::logthis('copy result is '.$copy_result);
+ &Apache::lonnet::logthis('answer file is '.$answer_file.
+ ' becomes '.$answer_file_parts[0].'.'.$version.'.'.$answer_file_parts[-1]);
+ &Apache::lonnet::logthis('from dir list is '.$file_names[0].' has '.@file_name_parts.' parts');
+ }
+ &Apache::lonnet::logthis('found key portfiles '.$key);
+ &Apache::lonnet::logthis('found value portfiles '.$$record{$key});
+ }
+ }
+
+
+}
+
#--------------------------------------------------------------------------------------
#
#-------------------------- Next few routines handles grading by section or whole class
@@ -2297,7 +2430,7 @@ sub viewgrades {
my $sectionClass;
if ($ENV{'form.section'} eq 'all') {
$sectionClass='Class ';
- } elsif ($ENV{'form.section'} eq 'no') {
+ } elsif ($ENV{'form.section'} eq 'none') {
$sectionClass='Students in no Section ';
} else {
$sectionClass='Students in Section '.$ENV{'form.section'}.'';
@@ -2324,7 +2457,8 @@ sub viewgrades {
$ctsparts.'" value="'.$partid.'" />'."\n";
$result.=''."\n";
- $result.='
Part '.$partid.' Point:
';
+ my $display_part=&get_display_part($partid,$url,$symb);
+ $result.='
Part: '.$display_part.' Point:
';
$result.='
';
my $ctr = 0;
while ($ctr<=$weight{$partid}) { # display radio buttons in a nice table 10 across
@@ -2363,14 +2497,17 @@ sub viewgrades {
my $display=&Apache::lonnet::metadata($url,$part.'.display');
$display =~ s|^Number of Attempts|Tries |; # makes the column narrower
if (!$display) { $display = &Apache::lonnet::metadata($url,$part.'.name'); }
+ my ($partid) = &split_part_type($part);
+ my $display_part=&get_display_part($partid,$url,$symb);
if ($display =~ /^Partial Credit Factor/) {
- my ($partid) = &split_part_type($part);
- $result.='
Score Part '.$partid.' (weight = '.
- $weight{$partid}.')
'."\n";
foreach my $apart (@$parts) {
my ($part,$type) = &split_part_type($apart);
my $score=$record{"resource.$part.$type"};
+ $result.='
';
if ($type eq 'awarded') {
my $pts = $score eq '' ? '' : $score*$$weight{$part};
$result.=''."\n";
- $result.='
'."\n";
@@ -2425,7 +2562,7 @@ sub viewstudentgrade {
$status = 'nothing' if ($status eq '');
$result.=''."\n";
- $result.='
';
}
$result .= '
';
@@ -2596,7 +2734,7 @@ sub editgrades {
if ($noupdate) {
# my $numcols=(scalar(@partid)*(scalar(@parts)-1)*2)+3;
my $numcols=scalar(@partid)*4+2;
- $result .= '
No Changes Occurred For the Students Below
'.$noupdate;
+ $result .= '
No Changes Occurred For the Students Below
'.$noupdate;
}
$result .= '
'."\n".
&show_grading_menu_form ($symb,$url);
@@ -2625,24 +2763,26 @@ sub split_part_type {
#
#--- Javascript to handle csv upload
sub csvupload_javascript_reverse_associate {
+ my $error1=&mt('You need to specify the username or ID');
+ my $error2=&mt('You need to specify at least one grading field');
return(<2) { foundsomething=1; }
- }
- if (founduname==0 || founddomain==0) {
- alert('You need to specify at both the username and domain');
- return;
+ if (tw==1) { foundID=1; }
+ if (tw==2) { founduname=1; }
+ if (tw>3) { foundsomething=1; }
+ }
+ if (founduname==0 && foundID==0) {
+ alert('$error1');
+ return;
}
if (foundsomething==0) {
- alert('You need to specify at least one grading field');
- return;
+ alert('$error2');
+ return;
}
vf.submit();
}
@@ -2707,7 +2849,8 @@ sub csvuploadmap_header {
}
my ($result) = &showResourceInfo($url,$ENV{'form.probTitle'});
-
+ my $checked=(($ENV{'form.noFirstLine'})?' checked="checked"':'');
+ my $ignore=&mt('Ignore First Line');
$request->print(<
Uploading Class Grades
@@ -2718,6 +2861,7 @@ Total number of records found in file: $
Enter as many fields as you can. The system will inform you and bring you back
to this page if the data selected is insufficient to run your class.
+
@@ -2729,7 +2873,7 @@ to this page if the data selected is ins
-
+
+ENDSCRIPT
+ my $href="/adm/pickcode?".
+ "form=".&Apache::lonnet::escape("scantronupload").
+ "&scantron_format=".&Apache::lonnet::escape($ENV{'form.scantron_format'}).
+ "&scantron_CODElist=".&Apache::lonnet::escape($ENV{'form.scantron_CODElist'}).
+ "&curCODE=".&Apache::lonnet::escape($$scan_record{'scantron.CODE'}).
+ "&scantron_selectfile=".&Apache::lonnet::escape($ENV{'form.scantron_selectfile'});
+ $r->print(" Select a CODE from the list of all CODEs and use it. Selected CODE is ");
+ $r->print("\n ");
+ $r->print(" Use as the CODE.");
+ $r->print("\n
");
} elsif ($error eq 'doublebubble') {
-#FIXME Need to print out who this is along with the paper info
$r->print("
There have been multiple bubbles scanned for a some question(s)
Please indicate which bubble should be used for grading
");
foreach my $question (@{$arg}) {
my $selected=$$scan_record{"scantron.$question.answer"};
@@ -4021,6 +4619,7 @@ sub scantron_get_correction {
}
} elsif ($error eq 'missingbubble') {
$r->print("
There have been no bubbles scanned for some question(s)
\n");
+ $r->print($message);
$r->print("
Please indicate which bubble should be used for grading
");
$r->print("Some questions have no scanned bubbles\n");
$r->print(' $result");
+ &Apache::lonnet::logthis("scantron grading error info name $uname domain $udom course $ENV{'request.course.id'} url ".$resource->src());
+ }
+ if (&Apache::loncommon::connection_aborted($r)) { last; }
}
$completedstudents{$uname}={'line'=>$line};
+ if (&Apache::loncommon::connection_aborted($r)) { last; }
} continue {
&Apache::lonnet::delenv('form.counter');
&Apache::lonnet::delenv('scantron\.');
- &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,
- 'last student');
}
&Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
# my $lasttime = &Time::HiRes::time()-$start;
# $r->print("
took $lasttime
");
- $navmap->untieHashes();
- $r->print("
Done
");
+ $r->print("");
$r->print(&show_grading_menu_form($symb,$url));
return '';
}
@@ -4255,7 +4970,8 @@ sub scantron_upload_scantron_data_save {
}
return '';
}
- $r->print("Doing upload to ".$ENV{'form.courseid'}." ");
+ my %coursedata=&Apache::lonnet::coursedescription($ENV{'form.domainid'}.'_'.$ENV{'form.courseid'});
+ $r->print("Doing upload to ".$coursedata{'description'}." ");
my $home=&Apache::lonnet::homeserver($ENV{'form.courseid'},
$ENV{'form.domainid'});
my $fname=$ENV{'form.upfile.filename'};
@@ -4272,31 +4988,75 @@ sub scantron_upload_scantron_data_save {
$fname=~s/[^\w\.\-]//g;
# See if there is anything left
unless ($fname) { return 'error: no uploaded file'; }
+ my $uploadedfile=$fname;
$fname='scantron_orig_'.$fname;
if (length($ENV{'form.upfile'}) < 2) {
- $r->print("Error: The file you attempted to upload, ".&HTML::Entities::encode($ENV{'form.upfile.filename'}).", contained no information. Please check that you entered the correct filename.");
+ $r->print("Error: The file you attempted to upload, ".&HTML::Entities::encode($ENV{'form.upfile.filename'},'<>&"').", contained no information. Please check that you entered the correct filename.");
} else {
my $result=&Apache::lonnet::finishuserfileupload($ENV{'form.courseid'},$ENV{'form.domainid'},$home,'upfile',$fname);
if ($result =~ m|^/uploaded/|) {
$r->print("Success: Successfully uploaded ".(length($ENV{'form.upfile'})-1)." bytes of data into location ".$result."");
} else {
- $r->print("Error: An error (".$result.") occured when attempting to upload the file, ".&HTML::Entities::encode($ENV{'form.upfile.filename'})."");
+ $r->print("Error: An error (".$result.") occurred when attempting to upload the file, ".&HTML::Entities::encode($ENV{'form.upfile.filename'},'<>&"')."");
}
}
if ($symb) {
- $r->print(&show_grading_menu_form($symb,$url));
+ $r->print(&scantron_selectphase($r,$uploadedfile));
} else {
$r->print($doanotherupload);
}
return '';
}
+sub valid_file {
+ my ($requested_file)=@_;
+ foreach my $filename (sort(&scantron_filenames())) {
+ &Apache::lonnet::logthis("$requested_file $filename");
+ if ($requested_file eq $filename) { return 1; }
+ }
+ return 0;
+}
+
+sub scantron_download_scantron_data {
+ my ($r)=@_;
+ my $default_form_data=&defaultFormData(&get_symb_and_url($r,1));
+ my $cname=$ENV{'course.'.$ENV{'request.course.id'}.'.num'};
+ my $cdom=$ENV{'course.'.$ENV{'request.course.id'}.'.domain'};
+ my $file=$ENV{'form.scantron_selectfile'};
+ if (! &valid_file($file)) {
+ $r->print(<
+ The requested file name was invalid.
+
+ERROR
+ $r->print(&show_grading_menu_form(&get_symb_and_url($r,1)));
+ return;
+ }
+ my $orig='/uploaded/'.$cdom.'/'.$cname.'/scantron_orig_'.$file;
+ my $corrected='/uploaded/'.$cdom.'/'.$cname.'/scantron_corrected_'.$file;
+ my $skipped='/uploaded/'.$cdom.'/'.$cname.'/scantron_skipped_'.$file;
+ &Apache::lonnet::allowuploaded('/adm/grades',$orig);
+ &Apache::lonnet::allowuploaded('/adm/grades',$corrected);
+ &Apache::lonnet::allowuploaded('/adm/grades',$skipped);
+ $r->print(<
+ Original file as uploaded by the scantron office.
+
+
+ Corrections, a file of corrected records that were used in grading.
+