@@ -3689,17 +3685,19 @@ sub scantron_fixup_scanline {
$args->{'username'}.':'.$args->{'domain'});
}
} elsif ($field eq 'CODE') {
- if (length($args->{'CODE'}) > $$scantron_config{'CODElength'}) {
- return ($line,1,'New CODE value too large');
+ if ($args->{'CODE_ignore_dup'}) {
+ &scan_data($scan_data,"$whichline.CODE_ignore_dup",'1');
}
- if (length($args->{'CODE'}) < $$scantron_config{'CODElength'}) {
- $args->{'CODE'}=sprintf('%-'.$$scantron_config{'CODElength'}.'s',
- $args->{'CODE'});
- }
- substr($line,$$scantron_config{'CODEstart'}-1,
- $$scantron_config{'CODElength'})=$args->{'CODE'};
- if ($args->{'CODE'}=~/^\s*$/) {
- &scan_data($scan_data,"$whichline.CODE",$args->{'CODE'});
+ &scan_data($scan_data,"$whichline.useCODE",'1');
+ if ($args->{'CODE'} ne 'use_unfound') {
+ if (length($args->{'CODE'}) > $$scantron_config{'CODElength'}) {
+ return ($line,1,'New CODE value too large');
+ }
+ if (length($args->{'CODE'}) < $$scantron_config{'CODElength'}) {
+ $args->{'CODE'}=sprintf('%-'.$$scantron_config{'CODElength'}.'s',$args->{'CODE'});
+ }
+ substr($line,$$scantron_config{'CODEstart'}-1,
+ $$scantron_config{'CODElength'})=$args->{'CODE'};
}
} elsif ($field eq 'answer') {
my $length=$scantron_config->{'Qlength'};
@@ -3737,8 +3735,15 @@ sub scantron_parse_scanline {
my $data=substr($line,0,$$scantron_config{'Qstart'}-1);
if ($$scantron_config{'CODElocation'} ne 0) {
if ($$scantron_config{'CODElocation'} < 0) {
- $record{'scantron.CODE'}=substr($data,$$scantron_config{'CODEstart'}-1,
+ $record{'scantron.CODE'}=substr($data,
+ $$scantron_config{'CODEstart'}-1,
$$scantron_config{'CODElength'});
+ if (&scan_data($scan_data,"$whichline.useCODE")) {
+ $record{'scantron.useCODE'}=1;
+ }
+ if (&scan_data($scan_data,"$whichline.CODE_ignore_dup")) {
+ $record{'scantron.CODE_ignore_dup'}=1;
+ }
} else {
#FIXME interpret first N questions
}
@@ -3836,10 +3841,23 @@ sub scantron_process_corrections {
'username'=>$ENV{'form.scantron_username'},
'domain'=>$ENV{'form.scantron_domain'}});
} elsif ($ENV{'form.scantron_corrections'} =~ /^(duplicate|incorrect)CODE$/) {
- my $newCODE=$ENV{'form.scantron_CODE'};
+ my $resolution=$ENV{'form.scantron_CODE_resolution'};
+ my $newCODE;
+ my %args;
+ if ($resolution eq 'use_unfound') {
+ $newCODE='use_unfound';
+ } elsif ($resolution eq 'use_found') {
+ $newCODE=$ENV{'form.scantron_CODE_selectedvalue'};
+ } elsif ($resolution eq 'use_typed') {
+ $newCODE=$ENV{'form.scantron_CODE_newvalue'};
+ }
+ if ($ENV{'form.scantron_corrections'} eq 'duplicateCODE') {
+ $args{'CODE_ignore_dup'}=1;
+ }
+ $args{'CODE'}=$newCODE;
($line,$err,$errmsg)=
&scantron_fixup_scanline(\%scantron_config,$scan_data,$line,$which,
- 'CODE',{'CODE'=>$newCODE});
+ 'CODE',\%args);
} elsif ($ENV{'form.scantron_corrections'} =~ /^(missing|double)bubble$/) {
foreach my $question (split(',',$ENV{'form.scantron_questions'})) {
($line,$err,$errmsg)=
@@ -3864,10 +3882,19 @@ sub scantron_validate_file {
my ($symb,$url)=&get_symb_and_url($r);
if (!$symb) {return '';}
my $default_form_data=&defaultFormData($symb,$url);
-
+ if ($ENV{'form.scantron_options_ignore'} eq 'ignore_corrections') {
+ my $result=&scantron_remove('corrected');
+ &Apache::lonnet::logthis("result was $result");
+ if ($result ne 'ok' && $result ne 'not_found' ) {
+ $r->print("An error occured ($result) when trying to Remove the existing corrections.");
+ }
+ $ENV{'form.scantron_options_ignore'}='done';
+ }
if ($ENV{'form.scantron_corrections'}) {
&scantron_process_corrections($r);
}
+ $r->print("Gathering neccessary info.
");$r->rflush();
+ my $max_bubble=&scantron_get_maxbubble($r);
#get the student pick code ready
$r->print(&Apache::loncommon::studentbrowser_javascript());
my $result= <
-
+
+
+
+
+
$default_form_data
SCANTRONFORM
$r->print($result);
@@ -3922,6 +3953,37 @@ SCANTRONFORM
return '';
}
+sub scantron_remove {
+ my ($which)=@_;
+ my $cname=$ENV{'course.'.$ENV{'request.course.id'}.'.num'};
+ my $cdom=$ENV{'course.'.$ENV{'request.course.id'}.'.domain'};
+ my $file='scantron_';
+ if ($which eq 'corrected') {
+ $file.='corrected_';
+ } else {
+ return 'refused';
+ }
+ $file.=$ENV{'form.scantron_selectfile'};
+ &Apache::lonnet::logthis("removeing $file");
+ my $result=&Apache::lonnet::removeuserfile($cname,$cdom,$file);
+ my @keys=&Apache::lonnet::getkeys('nohist_scantrondata',$cdom,$cname);
+ &Apache::lonnet::logthis('got keys '.join(':',@keys));
+ &Apache::lonnet::logthis("cdom $cdom cname $cname");
+ my @todelete;
+ my $filename=$ENV{'form.scantron_selectfile'};
+ &Apache::lonnet::logthis('filename '.$filename);
+ foreach my $key (@keys) {
+ if ($key=~/^\Q$filename\E_/) {
+ push(@todelete,$key);
+ }
+ }
+ &Apache::lonnet::logthis('todelete '.join(':',@todelete));
+ if (@todelete) {
+ &Apache::lonnet::del('nohist_scantrondata',\@todelete,$cdom,$cname);
+ }
+ return $result;
+}
+
sub scantron_getfile {
#FIXME really would prefer a scantron directory but tokenwrapper
# doesn't allow access to subdirs of userfiles
@@ -4116,12 +4178,12 @@ sub scantron_get_correction {
$$scan_record{'scantron.FirstName'}."");
$r->print("How should I handle this?
\n");
$r->print("\n
");
- $r->print(" Use the CODE ".$$scan_record{'scantron.CODE'}." that is was on the paper, ignoring the error.");
+ $r->print(" Use the CODE ".$$scan_record{'scantron.CODE'}." that is was on the paper, ignoring the error.");
$r->print("\n
");
$r->print(<
function change_radio(field) {
- var slct=document.scantronupload.scan_CODE_resolution;
+ var slct=document.scantronupload.scantron_CODE_resolution;
var i;
for (i=0;iprint(" Select a CODE from the list of all CODEs and use it. Selected CODE is ");
+ $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(" Use as the CODE.");
$r->print("\n
");
} elsif ($error eq 'doublebubble') {
#FIXME Need to print out who this is along with the paper info
@@ -4194,11 +4256,10 @@ sub scantron_validate_CODE {
if ($scantron_config{'CODElocation'} &&
$scantron_config{'CODEstart'} &&
$scantron_config{'CODElength'}) {
- if (!$ENV{'form.scantron_CODElist'}) {
+ if (!defined($ENV{'form.scantron_CODElist'})) {
&FIXME_blow_up()
}
} else {
- &Apache::lonnet::logthis(" CODE stuf $scantron_config{'CODElocation'}:$scantron_config{'CODEstart'}:$scantron_config{'CODElength'}");
return (0,$currentphase+1);
}
@@ -4208,7 +4269,7 @@ sub scantron_validate_CODE {
my $cdom =$ENV{'course.'.$ENV{'request.course.id'}.'.domain'};
my $cnum =$ENV{'course.'.$ENV{'request.course.id'}.'.num'};
my %result=&Apache::lonnet::get('CODEs',[$old_name],$cdom,$cnum);
- my %allcodes=map {($_,1)} split(',',$result{$old_name});
+ my %allcodes=map {(&Apache::lonprintout::num_to_letters($_),1)} split(',',$result{$old_name});
my ($scanlines,$scan_data)=&scantron_getfile();
for (my $i=0;$i<=$scanlines->{'count'};$i++) {
@@ -4218,13 +4279,14 @@ sub scantron_validate_CODE {
$scan_data);
my $CODE=$$scan_record{'scantron.CODE'};
my $error=0;
- if (!exists($allcodes{$CODE})) {
+ if (!exists($allcodes{$CODE}) && !$$scan_record{'scantron.useCODE'}) {
&scantron_get_correction($r,$i,$scan_record,
\%scantron_config,
$line,'incorrectCODE',$CODE);
return(1);
}
- if (exists($usedCODEs{$CODE}) && $ENV{'form.scantron_CODEunique'}) {
+ if (exists($usedCODEs{$CODE}) && $ENV{'form.scantron_CODEunique'}
+ && !$$scan_record{'scantron.CODE_ignore_dup'}) {
&scantron_get_correction($r,$i,$scan_record,
\%scantron_config,
$line,'duplicateCODE',$CODE);
@@ -4258,6 +4320,31 @@ sub scantron_validate_doublebubble {
return (0,$currentphase+1);
}
+sub scantron_get_maxbubble {
+ my ($r)=@_;
+ if (defined($ENV{'form.scantron_maxbubble'}) &&
+ $ENV{'form.scantron_maxbubble'}) {
+ return $ENV{'form.scantron_maxbubble'};
+ }
+ my $navmap=Apache::lonnavmaps::navmap->new();
+ my (undef,undef,$sequence)=
+ &Apache::lonnet::decode_symb($ENV{'form.selectpage'});
+ my $map=$navmap->getResourceByUrl($sequence);
+ my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0);
+ &Apache::lonnet::delenv('form.counter');
+ foreach my $resource (@resources) {
+ my $result=&Apache::lonnet::ssi($resource->src());
+ }
+ &Apache::lonnet::delenv('scantron\.');
+ my $envfile=$ENV{'user.environment'};
+ $envfile=~/\/([^\/]+)\.id$/;
+ $envfile=$1;
+ &Apache::lonnet::transfer_profile_to_env($r->dir_config('lonIDsDir'),
+ $envfile);
+ $ENV{'form.scantron_maxbubble'}=$ENV{'form.counter'}-1;
+ return $ENV{'form.scantron_maxbubble'};
+}
+
sub scantron_validate_missingbubbles {
my ($r,$currentphase) = @_;
#get student info
@@ -4267,7 +4354,7 @@ sub scantron_validate_missingbubbles {
#get scantron line setup
my %scantron_config=&get_scantron_config($ENV{'form.scantron_format'});
my ($scanlines,$scan_data)=&scantron_getfile();
- my $max_bubble=$ENV{'form.scantron_maxbubble'};
+ my $max_bubble=&scantron_get_maxbubble();
if (!$max_bubble) { $max_bubble=2**31; }
for (my $i=0;$i<=$scanlines->{'count'};$i++) {
my $line=&scantron_get_line($scanlines,$i);
@@ -4347,13 +4434,18 @@ SCANTRONFORM
my $i=0;
foreach my $resource (@resources) {
$i++;
- my $result=&Apache::lonnet::ssi($resource->src(),
- ('submitted' =>'scantron',
- 'grade_target' =>'grade',
- 'grade_username'=>$uname,
- 'grade_domain' =>$udom,
- 'grade_courseid'=>$ENV{'request.course.id'},
- 'grade_symb' =>$resource->symb()));
+ my %form=('submitted' =>'scantron',
+ 'grade_target' =>'grade',
+ 'grade_username'=>$uname,
+ 'grade_domain' =>$udom,
+ 'grade_courseid'=>$ENV{'request.course.id'},
+ 'grade_symb' =>$resource->symb());
+ if (exists($scan_record->{'scantron.CODE'}) &&
+ $scan_record->{'scantron.CODE'}) {
+ $form{'CODE'}=$scan_record->{'scantron.CODE'};
+ }
+ my $result=&Apache::lonnet::ssi($resource->src(),%form);
+
}
$completedstudents{$uname}={'line'=>$line};
} continue {