--- loncom/homework/grades.pm 2019/02/23 17:34:59 1.596.2.12.2.41.2.6
+++ loncom/homework/grades.pm 2018/09/11 14:35:56 1.596.2.12.2.43
@@ -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.6 2019/02/23 17:34:59 raeburn Exp $
+# $Id: grades.pm,v 1.596.2.12.2.43 2018/09/11 14:35:56 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -44,8 +44,6 @@ 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;
@@ -4216,7 +4214,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).' ';
@@ -4609,8 +4607,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();
@@ -5718,7 +5716,7 @@ sub scantron_uploads {
sub scantron_scantab {
my $result=''."\n";
$result.=' '."\n";
- my @lines = &Apache::lonnet::get_scantronformat_file();
+ my @lines = &get_scantronformat_file();
if (@lines > 0) {
foreach my $line (@lines) {
next if (($line =~ /^\#/) || ($line eq ''));
@@ -5730,6 +5728,62 @@ sub scantron_scantab {
return $result;
}
+=pod
+
+=item get_scantronformat_file
+
+ Returns an array containing lines from the scantron format file for
+ the domain of the course.
+
+ If a url for a custom.tab file is listed in domain's configuration.db,
+ lines are from this file.
+
+ Otherwise, if a default.tab has been published in RES space by the
+ domainconfig user, lines are from this file.
+
+ Otherwise, fall back to getting lines from the legacy file on the
+ local server: /home/httpd/lonTabs/default_scantronformat.tab
+
+=cut
+
+sub get_scantronformat_file {
+ my $cdom= $env{'course.'.$env{'request.course.id'}.'.domain'};
+ my %domconfig = &Apache::lonnet::get_dom('configuration',['scantron'],$cdom);
+ my $gottab = 0;
+ my @lines;
+ if (ref($domconfig{'scantron'}) eq 'HASH') {
+ if ($domconfig{'scantron'}{'scantronformat'} ne '') {
+ my $formatfile = &Apache::lonnet::getfile($Apache::lonnet::perlvar{'lonDocRoot'}.$domconfig{'scantron'}{'scantronformat'});
+ if ($formatfile ne '-1') {
+ @lines = split("\n",$formatfile,-1);
+ $gottab = 1;
+ }
+ }
+ }
+ if (!$gottab) {
+ my $confname = $cdom.'-domainconfig';
+ my $default = $Apache::lonnet::perlvar{'lonDocRoot'}.'/res/'.$cdom.'/'.$confname.'/default.tab';
+ my $formatfile = &Apache::lonnet::getfile($default);
+ if ($formatfile ne '-1') {
+ @lines = split("\n",$formatfile,-1);
+ $gottab = 1;
+ }
+ }
+ if (!$gottab) {
+ my @domains = &Apache::lonnet::current_machine_domains();
+ if (grep(/^\Q$cdom\E$/,@domains)) {
+ my $fh=Apache::File->new($Apache::lonnet::perlvar{'lonTabDir'}.'/scantronformat.tab');
+ @lines = <$fh>;
+ close($fh);
+ } else {
+ my $fh=Apache::File->new($Apache::lonnet::perlvar{'lonTabDir'}.'/default_scantronformat.tab');
+ @lines = <$fh>;
+ close($fh);
+ }
+ }
+ return @lines;
+}
+
=pod
=item scantron_CODElist
@@ -5816,55 +5870,48 @@ sub scantron_selectphase {
# Chunk of form to prompt for a scantron file upload.
$r->print('
- ');
+
+ '.&Apache::loncommon::start_data_table('LC_scantron_action').'
+ '.&Apache::loncommon::start_data_table_header_row().'
+
+ '.&mt('Specify a bubblesheet data file to upload.').'
+
+ '.&Apache::loncommon::end_data_table_header_row().'
+ '.&Apache::loncommon::start_data_table_row().'
+
+');
+ my $default_form_data=&defaultFormData(&get_symb($r,1));
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('
+ $r->print('
+
+
'
- );
+ '.&mt('File to upload: [_1]',' ').'
+
+
+
+');
+ $r->print('
+
+ '.&Apache::loncommon::end_data_table_row().'
+ '.&Apache::loncommon::end_data_table().'
+');
}
# Chunk of form to prompt for a file to grade and how:
@@ -5976,6 +6023,98 @@ sub scantron_selectphase {
return;
}
+=pod
+
+=item get_scantron_config
+
+ Parse and return the scantron configuration line selected as a
+ hash of configuration file fields.
+
+ Arguments:
+ which - the name of the configuration to parse from the file.
+
+
+ Returns:
+ If the named configuration is not in the file, an empty
+ hash is returned.
+ a hash with the fields
+ name - internal name for the this configuration setup
+ description - text to display to operator that describes this config
+ CODElocation - if 0 or the string 'none'
+ - no CODE exists for this config
+ if -1 || the string 'letter'
+ - a CODE exists for this config and is
+ a string of letters
+ Unsupported value (but planned for future support)
+ if a positive integer
+ - The CODE exists as the first n items from
+ the question section of the form
+ if the string 'number'
+ - The CODE exists for this config and is
+ a string of numbers
+ CODEstart - (only matter if a CODE exists) column in the line where
+ the CODE starts
+ CODElength - length of the CODE
+ IDstart - column where the student/employee ID starts
+ IDlength - length of the student/employee ID info
+ Qstart - column where the information from the bubbled
+ 'questions' start
+ Qlength - number of columns comprising a single bubble line from
+ the sheet. (usually either 1 or 10)
+ Qon - either a single character representing the character used
+ to signal a bubble was chosen in the positional setup, or
+ the string 'letter' if the letter of the chosen bubble is
+ in the final, or 'number' if a number representing the
+ chosen bubble is in the file (1->A 0->J)
+ Qoff - the character used to represent that a bubble was
+ left blank
+ PaperID - if the scanning process generates a unique number for each
+ sheet scanned the column that this ID number starts in
+ PaperIDlength - number of columns that comprise the unique ID number
+ for the sheet of paper
+ FirstName - column that the first name starts in
+ FirstNameLength - number of columns that the first name spans
+
+ LastName - column that the last name starts in
+ LastNameLength - number of columns that the last name spans
+ BubblesPerRow - number of bubbles available in each row used to
+ bubble an answer. (If not specified, 10 assumed).
+
+=cut
+
+sub get_scantron_config {
+ my ($which) = @_;
+ my @lines = &get_scantronformat_file();
+ my %config;
+ #FIXME probably should move to XML it has already gotten a bit much now
+ foreach my $line (@lines) {
+ my ($name,$descrip)=split(/:/,$line);
+ if ($name ne $which ) { next; }
+ chomp($line);
+ my @config=split(/:/,$line);
+ $config{'name'}=$config[0];
+ $config{'description'}=$config[1];
+ $config{'CODElocation'}=$config[2];
+ $config{'CODEstart'}=$config[3];
+ $config{'CODElength'}=$config[4];
+ $config{'IDstart'}=$config[5];
+ $config{'IDlength'}=$config[6];
+ $config{'Qstart'}=$config[7];
+ $config{'Qlength'}=$config[8];
+ $config{'Qoff'}=$config[9];
+ $config{'Qon'}=$config[10];
+ $config{'PaperID'}=$config[11];
+ $config{'PaperIDlength'}=$config[12];
+ $config{'FirstName'}=$config[13];
+ $config{'FirstNamelength'}=$config[14];
+ $config{'LastName'}=$config[15];
+ $config{'LastNamelength'}=$config[16];
+ $config{'BubblesPerRow'}=$config[17];
+ last;
+ }
+ return %config;
+}
+
=pod
=item username_to_idmap
@@ -6021,7 +6160,7 @@ sub username_to_idmap {
Process a requested correction to a scanline.
Arguments:
- $scantron_config - hash from &Apache::lonnet::get_scantron_config()
+ $scantron_config - hash from &get_scantron_config()
$scan_data - hash of correction information
(see &scantron_getfile())
$line - existing scanline
@@ -6704,7 +6843,7 @@ sub scantron_filter {
sub scantron_process_corrections {
my ($r) = @_;
- my %scantron_config=&Apache::lonnet::get_scantron_config($env{'form.scantron_format'});
+ my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
my ($scanlines,$scan_data)=&scantron_getfile();
my $classlist=&Apache::loncoursedata::get_classlist();
my $which=$env{'form.scantron_line'};
@@ -6873,7 +7012,7 @@ sub check_for_error {
sub scantron_warning_screen {
my ($button_text)=@_;
my $title=&Apache::lonnet::gettitle($env{'form.selectpage'});
- my %scantron_config=&Apache::lonnet::get_scantron_config($env{'form.scantron_format'});
+ my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
my $CODElist;
if ($scantron_config{'CODElocation'} &&
$scantron_config{'CODEstart'} &&
@@ -7032,7 +7171,7 @@ sub scantron_validate_file {
#get the student pick code ready
$r->print(&Apache::loncommon::studentbrowser_javascript());
my $nav_error;
- my %scantron_config=&Apache::lonnet::get_scantron_config($env{'form.scantron_format'});
+ my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
my $max_bubble=&scantron_get_maxbubble(\$nav_error,\%scantron_config);
if ($nav_error) {
$r->print(&navmap_errormsg());
@@ -7491,7 +7630,7 @@ sub scantron_validate_ID {
my %idmap=&username_to_idmap($classlist);
#get scantron line setup
- my %scantron_config=&Apache::lonnet::get_scantron_config($env{'form.scantron_format'});
+ my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
my ($scanlines,$scan_data)=&scantron_getfile();
my $nav_error;
@@ -7955,7 +8094,7 @@ sub prompt_for_corrections {
Arguments:
$r - Apache request object
- $scan_config - hash from &Apache::lonnet::get_scantron_config()
+ $scan_config - hash from &get_scantron_config()
$line - Number of the line being displayed.
$questionnum - Question number (may include subquestion)
$error - Type of error.
@@ -8119,7 +8258,7 @@ sub get_codes {
sub scantron_validate_CODE {
my ($r,$currentphase) = @_;
- my %scantron_config=&Apache::lonnet::get_scantron_config($env{'form.scantron_format'});
+ my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
if ($scantron_config{'CODElocation'} &&
$scantron_config{'CODEstart'} &&
$scantron_config{'CODElength'}) {
@@ -8193,7 +8332,7 @@ sub scantron_validate_doublebubble {
&Apache::lonnet::decode_symb($env{'form.selectpage'});
#get scantron line setup
- my %scantron_config=&Apache::lonnet::get_scantron_config($env{'form.scantron_format'});
+ my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
my ($scanlines,$scan_data)=&scantron_getfile();
my $navmap = Apache::lonnavmaps::navmap->new();
@@ -8375,7 +8514,7 @@ sub scantron_validate_missingbubbles {
&Apache::lonnet::decode_symb($env{'form.selectpage'});
#get scantron line setup
- my %scantron_config=&Apache::lonnet::get_scantron_config($env{'form.scantron_format'});
+ my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
my ($scanlines,$scan_data)=&scantron_getfile();
my $navmap = Apache::lonnavmaps::navmap->new();
@@ -8504,7 +8643,7 @@ sub hand_bubble_option {
}
}
if ($needs_hand_bubbles) {
- my %scantron_config=&Apache::lonnet::get_scantron_config($env{'form.scantron_format'});
+ my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
my $bubbles_per_row = &bubblesheet_bubbles_per_row(\%scantron_config);
return &mt('The sequence to be graded contains response types which are handgraded.').''.
&mt('If you have already graded these by bubbling sheets to indicate points awarded, [_1]what point value is assigned to a filled last bubble in each row?',' ').
@@ -8524,7 +8663,7 @@ sub scantron_process_students {
}
my $default_form_data=&defaultFormData($symb);
- my %scantron_config=&Apache::lonnet::get_scantron_config($env{'form.scantron_format'});
+ my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
my $bubbles_per_row = &bubblesheet_bubbles_per_row(\%scantron_config);
my ($scanlines,$scan_data)=&scantron_getfile();
my $classlist=&Apache::loncoursedata::get_classlist();
@@ -8594,7 +8733,7 @@ SCANTRONFORM
return ''; # Dunno why the other returns return '' rather than just returning.
}
- my %lettdig = &Apache::lonnet::letter_to_digits();
+ my %lettdig = &letter_to_digits();
my $numletts = scalar(keys(%lettdig));
my %orderedforcode;
@@ -8925,7 +9064,6 @@ sub grade_student_bubbles {
sub scantron_upload_scantron_data {
my ($r)=@_;
my $dom = $env{'request.role.domain'};
- my ($formatoptions,$formattitle,$formatjs) = &scantron_upload_dataformat($dom);
my $domdesc = &Apache::lonnet::domain($dom,'description');
$r->print(&Apache::loncommon::coursebrowser_javascript($dom));
my $select_link=&Apache::loncommon::selectcourse_link('rules','courseid',
@@ -8939,7 +9077,8 @@ sub scantron_upload_scantron_data {
&js_escape(\$nofile_alert);
my $nocourseid_alert = &mt("Please use the 'Select Course' link to open a separate window where you can search for a course to which a file can be uploaded.");
&js_escape(\$nocourseid_alert);
- $r->print(&Apache::lonhtmlcommon::scripttag('
+ $r->print('
+
+
'.&mt('Send bubblesheet data to a course').'