1) {
if (($domconfig{'scantron'}{'config'}{'dat'}) &&
(ref($domconfig{'scantron'}{'config'}{'csv'}) eq 'HASH')) {
- if (keys(%{$domconfig{'scantron'}{'config'}{'csv'}})) {
- my ($onclick,$formatextra,$singleline);
- my @lines = &Apache::lonnet::get_scantronformat_file();
- my $count = 0;
- foreach my $line (@lines) {
- next if ($line =~ /^#/);
- $singleline = $line;
- $count ++;
- }
- if ($count > 1) {
- $formatextra = ''.
- &scantron_scantab().'
';
- $onclick = ' onclick="toggleScantab(this.form);"';
- $formatjs = <<"END";
+ if (ref($domconfig{'scantron'}{'config'}{'csv'}{'fields'}) eq 'HASH') {
+ if (keys(%{$domconfig{'scantron'}{'config'}{'csv'}{'fields'}})) {
+ my ($onclick,$formatextra,$singleline);
+ my @lines = &Apache::lonnet::get_scantronformat_file();
+ my $count = 0;
+ foreach my $line (@lines) {
+ next if ($line =~ /^#/);
+ $singleline = $line;
+ $count ++;
+ }
+ if ($count > 1) {
+ $formatextra = ''.
+ ''.
+ &mt('Bubblesheet type:').' '.
+ &scantron_scantab().'
';
+ $onclick = ' onclick="toggleScantab(this.form);"';
+ $formatjs = <<"END";
function toggleScantab(form) {
var divid = 'bubbletype';
if (document.getElementById(divid)) {
@@ -9125,7 +9127,7 @@ function toggleScantab(form) {
if (chosen == 'dat') {
document.getElementById(divid).style.display = 'none';
} else if (chosen == 'csv') {
- document.getElementById(divid).style.display = 'inline-block';
+ document.getElementById(divid).style.display = 'block';
}
}
}
@@ -9135,22 +9137,25 @@ function toggleScantab(form) {
}
END
- } elsif ($count == 1) {
- my $formatname = (split(/:/,$singleline,2))[0];
- $formatextra = '';
+ } elsif ($count == 1) {
+ my $formatname = (split(/:/,$singleline,2))[0];
+ $formatextra = '';
+ }
+ $formattitle = &mt('File format');
+ $formatoptions = ''.(' 'x2).
+ ''.$formatextra;
}
- $formattitle = &mt('File format');
- $formatoptions = ''.(' 'x2).
- ''.$formatextra;
}
}
} elsif (keys(%{$domconfig{'scantron'}{'config'}}) == 1) {
- if (keys(%{$domconfig{'scantron'}{'config'}{'csv'}})) {
- $formattitle = &mt('Format of bubblesheet data file:');
- $formatoptions = &scantron_scantab();
+ if (ref($domconfig{'scantron'}{'config'}{'csv'}{'fields'}) eq 'HASH') {
+ if (keys(%{$domconfig{'scantron'}{'config'}{'csv'}{'fields'}})) {
+ $formattitle = &mt('Bubblesheet type');
+ $formatoptions = &scantron_scantab();
+ }
}
}
}
@@ -9159,7 +9164,7 @@ END
}
sub scantron_upload_scantron_data_save {
- my($r,$symb)=@_;
+ my ($r,$symb) = @_;
my $doanotherupload=
'
';
return $result;
}
@@ -10200,12 +10205,12 @@ ENDUPFORM
ENDGRADINGFORM
- $result.=''.&Apache::loncommon::end_data_table_row().
+ $result.=''.&Apache::loncommon::end_data_table_row().
&Apache::loncommon::start_data_table_row().''.(<$pcorrect:
-'
+
ENDPERCFORM
$result.=' | '.
&Apache::loncommon::end_data_table_row().
@@ -10214,7 +10219,7 @@ ENDPERCFORM
}
sub process_clicker_file {
- my ($r,$symb)=@_;
+ my ($r,$symb) = @_;
if (!$symb) {return '';}
my %Saveable_Parameters=&clicker_grading_parameters();
@@ -10286,6 +10291,22 @@ sub process_clicker_file {
''.&HTML::Entities::encode($env{'form.upfile.filename'},'<>&"').''),1);
return $result;
}
+ my $mimetype;
+ if ($env{'form.upfiletype'} eq 'iclicker') {
+ my $mm = new File::MMagic;
+ $mimetype = $mm->checktype_contents($env{'form.upfile'});
+ unless (($mimetype eq 'text/plain') || ($mimetype eq 'text/html')) {
+ $result.= ''.
+ &Apache::lonhtmlcommon::confirm_success(
+ &mt('File format is neither csv (iclicker 6) nor xml (iclicker 7)'),1).'
';
+ return $result;
+ }
+ } elsif (($env{'form.upfiletype'} ne 'interwrite') && ($env{'form.upfiletype'} ne 'turning')) {
+ $result .= ''.
+ &Apache::lonhtmlcommon::confirm_success(
+ &mt('Invalid clicker type: choose one of: i>clicker, Interwrite PRS, or Turning Technologies.'),1).'
';
+ return $result;
+ }
# Were able to get all the info needed, now analyze the file
@@ -10312,12 +10333,14 @@ ENDHEADER
my $errormsg='';
my $number=0;
if ($env{'form.upfiletype'} eq 'iclicker') {
- ($errormsg,$number)=&iclicker_eval(\@questiontitles,\%responses);
- }
- if ($env{'form.upfiletype'} eq 'interwrite') {
+ if ($mimetype eq 'text/plain') {
+ ($errormsg,$number)=&iclicker_eval(\@questiontitles,\%responses);
+ } elsif ($mimetype eq 'text/html') {
+ ($errormsg,$number)=&iclickerxml_eval(\@questiontitles,\%responses);
+ }
+ } elsif ($env{'form.upfiletype'} eq 'interwrite') {
($errormsg,$number)=&interwrite_eval(\@questiontitles,\%responses);
- }
- if ($env{'form.upfiletype'} eq 'turning') {
+ } elsif ($env{'form.upfiletype'} eq 'turning') {
($errormsg,$number)=&turning_eval(\@questiontitles,\%responses);
}
$result.='
'.&mt('Found [_1] question(s)',$number).'
'.
@@ -10370,7 +10393,7 @@ ENDHEADER
"\n".&mt("Username").": ".
"\n".&mt("Domain").": ".
&Apache::loncommon::select_dom_form($env{'course.'.$env{'request.course.id'}.'.domain'},'udom'.$id).' '.
- &Apache::loncommon::selectstudent_link('clickeranalysis','uname'.$id,'udom'.$id,0,$id);
+ &Apache::loncommon::selectstudent_link('clickeranalysis','uname'.$id,'udom'.$id,'',$id);
$unknown_count++;
}
}
@@ -10425,6 +10448,49 @@ sub iclicker_eval {
return ($errormsg,$number);
}
+sub iclickerxml_eval {
+ my ($questiontitles,$responses)=@_;
+ my $number=0;
+ my $errormsg='';
+ my @state;
+ my %respbyid;
+ my $p = HTML::Parser->new
+ (
+ xml_mode => 1,
+ start_h =>
+ [sub {
+ my ($tagname,$attr) = @_;
+ push(@state,$tagname);
+ if ("@state" eq "ssn p") {
+ my $title = $attr->{qn};
+ $title =~ s/(^\s+|\s+$)//g;
+ $questiontitles->[$number]=$title;
+ } elsif ("@state" eq "ssn p v") {
+ my $id = $attr->{id};
+ my $entry = $attr->{ans};
+ $id=~s/^[\#0]+//;
+ $entry =~s/[^a-zA-Z0-9\.\*\-\+]+//g;
+ $respbyid{$id}[$number] = $entry;
+ }
+ }, "tagname, attr"],
+ end_h =>
+ [sub {
+ my ($tagname) = @_;
+ if ("@state" eq "ssn p") {
+ $number++;
+ }
+ pop(@state);
+ }, "tagname"],
+ );
+
+ $p->parse($env{'form.upfile'});
+ $p->eof;
+ foreach my $id (keys(%respbyid)) {
+ $responses->{$id}=join(',',@{$respbyid{$id}});
+ }
+ return ($errormsg,$number);
+}
+
sub interwrite_eval {
my ($questiontitles,$responses)=@_;
my $number=0;
@@ -10483,7 +10549,7 @@ sub turning_eval {
sub assign_clicker_grades {
- my ($r,$symb)=@_;
+ my ($r,$symb) = @_;
if (!$symb) {return '';}
# See which part we are saving to
my $res_error;
@@ -10494,11 +10560,11 @@ sub assign_clicker_grades {
# FIXME: This should probably look for the first handgradeable part
my $part=$$partlist[0];
# Start screen output
- my $result=&Apache::loncommon::start_data_table().
- &Apache::loncommon::start_data_table_header_row().
- ''.&mt('Assigning grades based on clicker file').' | '.
- &Apache::loncommon::end_data_table_header_row().
- &Apache::loncommon::start_data_table_row().'';
+ my $result = &Apache::loncommon::start_data_table().
+ &Apache::loncommon::start_data_table_header_row().
+ ' | '.&mt('Assigning grades based on clicker file').' | '.
+ &Apache::loncommon::end_data_table_header_row().
+ &Apache::loncommon::start_data_table_row().'';
# Get correct result
# FIXME: Possibly need delimiter other than ":"
my @correct=();
@@ -10560,7 +10626,7 @@ sub assign_clicker_grades {
for (my $i=0;$i<$number;$i++) {
if ($correct[$i] eq '-') {
$realnumber--;
- } elsif (($answer[$i]) || ($answer[$i]=~/^[0\.]+$/)) {
+ } elsif (($answer[$i]) || ($answer[$i]=~/^[0\.]+$/)) {
if ($gradingmechanism eq 'attendance') {
$sum+=$pcorrect;
} elsif ($correct[$i] eq '*') {
@@ -10629,15 +10695,17 @@ sub startpage {
}
if ($nomenu) {
$args{'only_body'} = 1;
- $r->print(&Apache::loncommon::start_page("Student's Version",$js,\%args);
+ $r->print(&Apache::loncommon::start_page("Student's Version",$js,\%args));
} else {
unshift(@$crumbs,{href=>&href_symb_cmd($symb,'gradingmenu'),text=>"Grading"});
$args{'bread_crumbs'} = $crumbs;
$r->print(&Apache::loncommon::start_page('Grading',$js,\%args));
- &Apache::lonquickgrades::startGradeScreen($r,($env{'form.symb'}?'probgrading':'grading'));
+ if ($env{'request.course.id'}) {
+ &Apache::lonquickgrades::startGradeScreen($r,($env{'form.symb'}?'probgrading':'grading'));
+ }
}
unless ($nodisplayflag) {
- $r->print(&Apache::lonhtmlcommon::resource_info_box($symb,$onlyfolderflag,$stuvcurrent,$stuvdisp));
+ $r->print(&Apache::lonhtmlcommon::resource_info_box($symb,$onlyfolderflag,$stuvcurrent,$stuvdisp));
}
}
@@ -10865,7 +10933,7 @@ sub handler {
}
if ($env{'form.inhibitmenu'}) {
$request->print(&Apache::loncommon::end_page());
- } else {
+ } elsif ($env{'request.course.id'}) {
&Apache::lonquickgrades::endGradeScreen($request);
}
&reset_caches();
@@ -11016,7 +11084,7 @@ Side Effects: None.
$r - Apache request object
$i - number of the current scanline
$scan_record - hash ref as returned from &scantron_parse_scanline()
- $scan_config - hash ref as returned from &get_scantron_config()
+ $scan_config - hash ref as returned from &Apache::lonnet::get_scantron_config()
$line - full contents of the current scanline
$error - error condition, valid values are
'incorrectCODE', 'duplicateCODE',
|