--- loncom/homework/grades.pm 2019/02/05 16:13:05 1.596.2.12.2.41.2.4 +++ loncom/homework/grades.pm 2019/02/23 17:34:59 1.596.2.12.2.41.2.6 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # The LON-CAPA Grading handler # -# $Id: grades.pm,v 1.596.2.12.2.41.2.4 2019/02/05 16:13:05 raeburn Exp $ +# $Id: grades.pm,v 1.596.2.12.2.41.2.6 2019/02/23 17:34:59 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -44,6 +44,8 @@ use Apache::Constants qw(:common :http); use Apache::lonlocal; use Apache::lonenc; use Apache::bridgetask(); +use HTML::Parser(); +use File::MMagic; use String::Similarity; use LONCAPA; @@ -5815,7 +5817,6 @@ sub scantron_selectphase { $r->print('
'); - my $default_form_data=&defaultFormData($symb); my $cdom= $env{'course.'.$env{'request.course.id'}.'.domain'}; my $cnum= $env{'course.'.$env{'request.course.id'}.'.num'}; my $alertmsg = &mt('Please use the browse button to select a file from your local directory.'); @@ -10263,7 +10264,7 @@ sub process_clicker_file { $result .= &Apache::lonhtmlcommon::confirm_success( &mt('No IDs found to determine correct answer'),1); - return $result,.&show_grading_menu_form($symb); + return $result.&show_grading_menu_form($symb); } } if (length($env{'form.upfile'}) < 2) { @@ -10273,6 +10274,22 @@ sub process_clicker_file { ''.&HTML::Entities::encode($env{'form.upfile.filename'},'<>&"').''),1); return $result.&show_grading_menu_form($symb); } + 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.&show_grading_menu_form($symb); + } + } 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.&show_grading_menu_form($symb); + } # Were able to get all the info needed, now analyze the file @@ -10300,12 +10317,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).'
'. @@ -10407,6 +10426,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)=@_;