--- loncom/homework/grades.pm 2019/02/05 16:13:05 1.596.2.12.2.41.2.4
+++ loncom/homework/grades.pm 2019/08/17 17:43:43 1.596.2.12.2.49
@@ -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.49 2019/08/17 17:43:43 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -44,6 +44,9 @@ use Apache::Constants qw(:common :http);
use Apache::lonlocal;
use Apache::lonenc;
use Apache::bridgetask();
+use Apache::lontexconvert();
+use HTML::Parser();
+use File::MMagic;
use String::Similarity;
use LONCAPA;
@@ -472,6 +475,7 @@ sub cleanRecord {
$env{'form.kwstyle'} = $keyhash{$loginuser.'_kwstyle'} ne '' ? $keyhash{$loginuser.'_kwstyle'} : '';
$env{'form.'.$symb} = 1; # so that we don't have to read it from disk for multiple sub of the same prob.
}
+ $answer = &Apache::lontexconvert::msgtexconverted($answer);
return '
'.&keywords_highlight($answer).'
';
} elsif ( $response eq 'organic') {
my $result=&mt('Smile representation: [_1]',
@@ -2051,6 +2055,7 @@ sub submission {
$env{'form.fullname'} = &Apache::loncommon::plainname($uname,$udom,'lastname') if $env{'form.fullname'} eq '';
my ($symb) = &get_symb($request);
if ($symb eq '') { $request->print("Unable to handle ambiguous references:."); return ''; }
+ my ($essayurl,%coursedesc_by_cid);
if (!&canview($usec)) {
$request->print(
@@ -2188,11 +2193,24 @@ sub submission {
#
# Load the other essays for similarity check
#
- my (undef,undef,$essayurl) = &Apache::lonnet::decode_symb($symb);
- my ($adom,$aname,$apath)=($essayurl=~/^($LONCAPA::domain_re)\/($LONCAPA::username_re)\/(.*)$/);
- $apath=&escape($apath);
- $apath=~s/\W/\_/gs;
- &init_old_essays($symb,$apath,$adom,$aname);
+ (undef,undef,$essayurl) = &Apache::lonnet::decode_symb($symb);
+ if ($essayurl eq 'lib/templates/simpleproblem.problem') {
+ my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+ my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+ if ($cdom ne '' && $cnum ne '') {
+ my ($map,$id,$res) = &Apache::lonnet::decode_symb($symb);
+ if ($map =~ m{^\Quploaded/$cdom/$cnum/\E(default(?:|_\d+)\.(?:sequence|page))$}) {
+ my $apath = $1.'_'.$id;
+ $apath=~s/\W/\_/gs;
+ &init_old_essays($symb,$apath,$cdom,$cnum);
+ }
+ }
+ } else {
+ my ($adom,$aname,$apath)=($essayurl=~/^($LONCAPA::domain_re)\/($LONCAPA::username_re)\/(.*)$/);
+ $apath=&escape($apath);
+ $apath=~s/\W/\_/gs;
+ &init_old_essays($symb,$apath,$adom,$aname);
+ }
}
}
@@ -2333,27 +2351,52 @@ sub submission {
&most_similar($uname,$udom,$symb,$subval);
if ($osim) {
$osim=int($osim*100.0);
- my %old_course_desc =
- &Apache::lonnet::coursedescription($ocrsid,
- {'one_time' => 1});
-
if ($hide eq 'anon') {
$similar='
'.&mt("Essay was found to be similar to another essay submitted for this assignment.").'
'.
&mt('As the current submission is for an anonymous survey, no other details are available.').'
';
} else {
- $similar="
".
- &mt('Essay is [_1]% similar to an essay by [_2] in course [_3] (course id [_4]:[_5])',
- $osim,
- &Apache::loncommon::plainname($oname,$odom).' ('.$oname.':'.$odom.')',
- $old_course_desc{'description'},
- $old_course_desc{'num'},
- $old_course_desc{'domain'}).
- '
'.
- &keywords_highlight($oessay).
- '
';
- }
- }
- }
+ $similar='
';
+ if ($essayurl eq 'lib/templates/simpleproblem.problem') {
+ $similar .= ''.
+ &mt('Essay is [_1]% similar to an essay by [_2]',
+ $osim,
+ &Apache::loncommon::plainname($oname,$odom).' ('.$oname.':'.$odom.')').
+ '
';
+ } elsif ($ocrsid ne '') {
+ my %old_course_desc;
+ if (ref($coursedesc_by_cid{$ocrsid}) eq 'HASH') {
+ %old_course_desc = %{$coursedesc_by_cid{$ocrsid}};
+ } else {
+ my $args;
+ if ($ocrsid ne $env{'request.course.id'}) {
+ $args = {'one_time' => 1};
+ }
+ %old_course_desc =
+ &Apache::lonnet::coursedescription($ocrsid,$args);
+ $coursedesc_by_cid{$ocrsid} = \%old_course_desc;
+ }
+ $similar .=
+ &mt('Essay is [_1]% similar to an essay by [_2] in course [_3] (course id [_4]:[_5])',
+ $osim,
+ &Apache::loncommon::plainname($oname,$odom).' ('.$oname.':'.$odom.')',
+ $old_course_desc{'description'},
+ $old_course_desc{'num'},
+ $old_course_desc{'domain'}).
+ '';
+ } else {
+ $similar .=
+ ''.
+ &mt('Essay is [_1]% similar to an essay by [_2] in an unknown course',
+ $osim,
+ &Apache::loncommon::plainname($oname,$odom).' ('.$oname.':'.$odom.')').
+ '
';
+ }
+ $similar .= ''.
+ &keywords_highlight($oessay).
+ '
';
+ }
+ }
+ }
my $order=&get_order($partid,$respid,$symb,$uname,$udom,
undef,$type,$trial,$rndseed);
if ($env{'form.lastSub'} eq 'lastonly' || $env{'form.lastSub'} eq 'datesub' || $env{'form.lastSub'} =~ /^(last|all)$/ || ($env{'form.lastSub'} eq 'hdgrade' &&
@@ -4214,7 +4257,7 @@ sub editgrades {
my ($uname,$udom)=split(/:/,$user);
my %newrecord;
my $updateflag = 0;
- my $usec=$classlist->{"$uname:$udom"}[5];
+ my $usec=$classlist->{"$uname:$udom"}[5];
my $canmodify = &canmodify($usec);
my $line = ''.
&nameUserString(undef,$$fullname{$user},$uname,$udom).' | ';
@@ -4607,8 +4650,8 @@ sub csvuploadmap {
$datatoken=&Apache::loncommon::upfile_store($request);
} else {
$datatoken=&Apache::loncommon::valid_datatoken($env{'form.datatoken'});
- if ($datatoken ne '') {
- &Apache::loncommon::load_tmp_file($request,$datatoken);
+ if ($datatoken ne '') {
+ &Apache::loncommon::load_tmp_file($request,$datatoken);
}
}
my @records=&Apache::loncommon::upfile_record_sep();
@@ -4869,6 +4912,7 @@ LISTJAVASCRIPT
my $cdom = $env{"course.$env{'request.course.id'}.domain"};
my $cnum = $env{"course.$env{'request.course.id'}.num"};
my $getsec = $env{'form.section'} eq '' ? 'all' : $env{'form.section'};
+ my $getgroup = $env{'form.group'} eq '' ? 'all' : $env{'form.group'};
my $result=' '.
&mt('Manual Grading by Page or Sequence').'
';
@@ -4939,7 +4983,7 @@ LISTJAVASCRIPT
''.&nameUserString('header').' | '.
&Apache::loncommon::end_data_table_header_row();
- my (undef,undef,$fullname) = &getclasslist($getsec,'1');
+ my (undef,undef,$fullname) = &getclasslist($getsec,'1',$getgroup);
my $ptr = 1;
foreach my $student (sort
{
@@ -5815,13 +5859,12 @@ 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.');
- &js_escape(\$alertmsg);
- my ($formatoptions,$formattitle,$formatjs) = &scantron_upload_dataformat($cdom);
- $r->print(&Apache::lonhtmlcommon::scripttag('
+ 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.');
+ &js_escape(\$alertmsg);
+ my ($formatoptions,$formattitle,$formatjs) = &scantron_upload_dataformat($cdom);
+ $r->print(&Apache::lonhtmlcommon::scripttag('
function checkUpload(formname) {
if (formname.upfile.value == "") {
alert("'.$alertmsg.'");
@@ -5829,7 +5872,7 @@ sub scantron_selectphase {
}
formname.submit();
}'."\n".$formatjs));
- $r->print('
+ $r->print('
'
- );
+ );
}
@@ -10263,7 +10306,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 +10316,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 +10359,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).'
'.
@@ -10408,6 +10469,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;
@@ -10701,7 +10805,7 @@ sub handler {
}
&Apache::loncommon::content_type($request,'text/html');
$request->send_http_header;
- if (($command eq 'scantron_selectphase' && $perm{'mgr'}) ||
+ if (($command eq 'scantron_selectphase' && $perm{'mgr'}) ||
(($command eq 'scantronupload') &&
(&Apache::lonnet::allowed('usc',$env{'request.role.domain'}) ||
&Apache::lonnet::allowed('usc',$env{'request.course.id'})))) {
@@ -10709,7 +10813,7 @@ sub handler {
undef,undef,undef,undef,'toggleScantab(document.rules);');
} else {
unless ((($command eq 'submission' || $command eq 'versionsub')) && ($perm{'vgr'})) {
- $request->print($start_page);
+ $request->print($start_page);
}
}
if ($command eq 'submission' && $perm{'vgr'}) {