';
+ next;
+ }
+ foreach my $submission (@$string) {
+ my ($partid,$respid) = ($submission =~ /^resource\.([^\.]*)\.([^\.]*)\.submission/);
+ if (join('_',@{$part}) ne ($partid.'_'.$respid)) { next; }
+ my ($ressub,$hide,$draft,$subval) = split(/:/,$submission,4);
+ # Similarity check
+ my $similar='';
+ my ($type,$trial,$rndseed);
+ if ($hide eq 'rand') {
+ $type = 'randomizetry';
+ $trial = $record{"resource.$partid.tries"};
+ $rndseed = $record{"resource.$partid.rndseed"};
+ }
+ if ($env{'form.checkPlag'}) {
+ my ($oname,$odom,$ocrsid,$oessay,$osim)=
+ &most_similar($uname,$udom,$symb,$subval);
+ if ($osim) {
+ $osim=int($osim*100.0);
+ 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='';
+ 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.')').
+ '
';
+ } else {
+ my %old_course_desc;
+ if ($ocrsid ne '') {
+ 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.')').
+ '
';
- next;
- }
- foreach my $submission (@$string) {
- my ($partid,$respid) = ($submission =~ /^resource\.([^\.]*)\.([^\.]*)\.submission/);
- if (join('_',@{$part}) ne ($partid.'_'.$respid)) { next; }
- my ($ressub,$hide,$draft,$subval) = split(/:/,$submission,4);
- # Similarity check
- my $similar='';
- my ($type,$trial,$rndseed);
- if ($hide eq 'rand') {
- $type = 'randomizetry';
- $trial = $record->{"resource.$partid.tries"};
- $rndseed = $record->{"resource.$partid.rndseed"};
- }
- if ($env{'form.checkPlag'}) {
- my ($oname,$odom,$ocrsid,$oessay,$osim)=
- &most_similar($uname,$udom,$symb,$subval);
- if ($osim) {
- $osim=int($osim*100.0);
- 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='';
- 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.')').
- '
';
- } else {
- my %old_course_desc;
- if ($ocrsid ne '') {
- 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.')').
- '
'.
- ''.&mt('Part: [_1]',$display_part).''.
- ' '.
- '('.&mt('Response ID: [_1]',$respid).')'.
- ' ';
- my $files=&get_submitted_files($udom,$uname,$partid,$respid,$record);
- if (@$files) {
- if ($hide eq 'anon') {
- $lastsubonly.=' '.&mt('[quant,_1,file] uploaded to this anonymous survey',scalar(@{$files}));
- } else {
- $lastsubonly.='
'.''.&mt('Submitted Files:').''
- .' ';
- if(@$files == 1) {
- $lastsubonly .= &mt('Like all files provided by users, this file may contain viruses!');
- } else {
- $lastsubonly .= &mt('Like all files provided by users, these files may contain viruses!');
- }
- $lastsubonly .= '';
- foreach my $file (@$files) {
- &Apache::lonnet::allowuploaded('/adm/grades',$file);
- $lastsubonly.=' '.$file.'';
- }
- }
- $lastsubonly.=' ';
- }
- if ($hide eq 'anon') {
- $lastsubonly.=' '.&mt('Anonymous Survey').'';
- } else {
- $lastsubonly.=' '.&mt('Submitted Answer:').' ';
- if ($draft) {
- $lastsubonly.= ' '.&mt('Draft Copy').'';
- }
- $subval =
- &cleanRecord($subval,$responsetype,$symb,$partid,
- $respid,$record,$order,undef,$uname,$udom,$type,$trial,$rndseed);
- if ($responsetype eq 'essay') {
- $subval =~ s{\n}{ }g;
- }
- $lastsubonly.=$subval."\n";
- }
- if ($similar) {$lastsubonly.="
$similar\n";}
- $lastsubonly.='
';
- }
- }
- }
- $lastsubonly.='
'."\n"; # End: LC_grade_submissions_body
- }
- return ($lastsubonly,$partinfo);
-}
-
sub check_collaborators {
my ($symb,$uname,$udom,$record,$handgrade,$counter) = @_;
my ($result,@col_fullnames);
@@ -2925,51 +2876,18 @@ sub check_collaborators {
#--- Retrieve the last submission for all the parts
sub get_last_submission {
my ($returnhash,$is_tool)=@_;
- my (@string,$timestamp,$lastgradetime,$lastsubmittime);
+ my (@string,$timestamp,%lasthidden);
if ($$returnhash{'version'}) {
my %lasthash=();
- my %prevsolved=();
- my %solved=();
- my $version;
+ my ($version);
for ($version=1;$version<=$$returnhash{'version'};$version++) {
- my %handgraded = ();
foreach my $key (sort(split(/\:/,
$$returnhash{$version.':keys'}))) {
$lasthash{$key}=$$returnhash{$version.':'.$key};
- if ($key =~ /\.([^.]+)\.regrader$/) {
- $handgraded{$1} = 1;
- } elsif ($key =~ /\.portfiles$/) {
- if (($$returnhash{$version.':'.$key} ne '') &&
- ($$returnhash{$version.':'.$key} !~ /\.\d+\.\w+$/)) {
- $lastsubmittime = $$returnhash{$version.':timestamp'};
- }
- } elsif ($key =~ /\.submission$/) {
- if ($$returnhash{$version.':'.$key} ne '') {
- $lastsubmittime = $$returnhash{$version.':timestamp'};
- }
- } elsif ($key =~ /\.([^.]+)\.solved$/) {
- $prevsolved{$1} = $solved{$1};
- $solved{$1} = $lasthash{$key};
- }
- }
- foreach my $partid (keys(%handgraded)) {
- if (($prevsolved{$partid} eq 'ungraded_attempted') &&
- (($solved{$partid} eq 'incorrect_by_override') ||
- ($solved{$partid} eq 'correct_by_override'))) {
- $lastgradetime = $$returnhash{$version.':timestamp'};
- }
- if ($solved{$partid} ne '') {
- $prevsolved{$partid} = $solved{$partid};
- }
- }
+ $timestamp =
+ &Apache::lonlocal::locallocaltime($$returnhash{$version.':timestamp'});
+ }
}
-#
-# Timestamp is for last transaction for this resource, which does not
-# necessarily correspond to the time of last submission for problem (or part).
-#
- if ($lasthash{'timestamp'} ne '') {
- $timestamp = &Apache::lonlocal::locallocaltime($lasthash{'timestamp'});
- }
my (%typeparts,%randombytry);
my $showsurv =
&Apache::lonnet::allowed('vas',$env{'request.course.id'});
@@ -3032,7 +2950,7 @@ sub get_last_submission {
$string[0] =
''.$msg.'';
}
- return (\@string,$timestamp,$lastgradetime,$lastsubmittime);
+ return (\@string,\$timestamp);
}
#--- High light keywords, with style choosen by user.
@@ -3062,11 +2980,12 @@ sub show_previous_task_version {
my ($uname,$udom) = ($env{'form.student'},$env{'form.userdom'});
my $usec = &Apache::lonnet::getsection($udom,$uname,$env{'request.course.id'});
if (!&canview($usec)) {
- $request->print(''.
- &mt('Unable to view previous version for requested student.').
- ' '.&mt('([_1] in section [_2] in course id [_3])',
- $uname.':'.$udom,$usec,$env{'request.course.id'}).
- '');
+ $request->print(
+ ''.
+ &mt('Unable to view previous version for requested student.').
+ ' '.&mt('([_1] in section [_2] in course id [_3])',
+ $uname.':'.$udom,$usec,$env{'request.course.id'}).
+ '');
return;
}
my $mode = 'both';
@@ -3238,37 +3157,19 @@ sub processHandGrade {
my $ntstu = $env{'form.NTSTU'};
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
- my ($res_error,%queueable);
- my ($partlist,$handgrade,$responseType,$numresp,$numessay) = &response_type($symb,\$res_error);
- if ($res_error) {
- $request->print(&navmap_errormsg());
- return;
- } else {
- foreach my $part (@{$partlist}) {
- if (ref($responseType->{$part}) eq 'HASH') {
- foreach my $id (keys(%{$responseType->{$part}})) {
- if (($responseType->{$part}->{$id} eq 'essay') ||
- (lc($handgrade->{$part.'_'.$id}) eq 'yes')) {
- $queueable{$part} = 1;
- last;
- }
- }
- }
- }
- }
if ($button eq 'Save & Next') {
my $ctr = 0;
while ($ctr < $ngrade) {
my ($uname,$udom) = split(/:/,$env{'form.unamedom'.$ctr});
my ($errorflag,$pts,$wgt,$numhidden) =
- &saveHandGrade($request,$symb,$uname,$udom,$ctr,undef,undef,\%queueable);
+ &saveHandGrade($request,$symb,$uname,$udom,$ctr);
if ($errorflag eq 'no_score') {
$ctr++;
next;
}
if ($errorflag eq 'not_allowed') {
- $request->print(
+ $request->print(
''
.&mt('Not allowed to modify grades for [_1]',"$uname:$udom")
.'');
@@ -3317,7 +3218,7 @@ sub processHandGrade {
foreach my $collaborator (@collaborators) {
my ($errorflag,$pts,$wgt) =
&saveHandGrade($request,$symb,$collaborator,$udom,$ctr,
- $env{'form.unamedom'.$ctr},$part,\%queueable);
+ $env{'form.unamedom'.$ctr},$part);
if ($errorflag eq 'not_allowed') {
$request->print("".&mt('Not allowed to modify grades for [_1]',"$collaborator:$udom")."");
next;
@@ -3339,6 +3240,13 @@ sub processHandGrade {
}
}
+ my $res_error;
+ my ($partlist,$handgrade,$responseType,$numresp,$numessay) = &response_type($symb,\$res_error);
+ if ($res_error) {
+ $request->print(&navmap_errormsg());
+ return;
+ }
+
my %keyhash = ();
if ($numessay) {
# Keywords sorted in alphabatical order
@@ -3369,9 +3277,9 @@ sub processHandGrade {
$ctr = 0;
while ($ctr < $ngrade) {
if ($env{'form.newmsg'.$ctr} ne '') {
- $keyhash{$symb.'_savemsg'.$idx} = $env{'form.newmsg'.$ctr};
- $env{'form.savemsg'.$idx} = $env{'form.newmsg'.$ctr};
- $idx++;
+ $keyhash{$symb.'_savemsg'.$idx} = $env{'form.newmsg'.$ctr};
+ $env{'form.savemsg'.$idx} = $env{'form.newmsg'.$ctr};
+ $idx++;
}
$ctr++;
}
@@ -3379,8 +3287,8 @@ sub processHandGrade {
$keyhash{$symb.'_savemsgN'} = $env{'form.savemsgN'};
}
if (($numessay) || ($env{'form.compmsg'})) {
- my $putresult = &Apache::lonnet::put
- ('nohist_handgrade',\%keyhash,$cdom,$cnum);
+ my $putresult = &Apache::lonnet::put
+ ('nohist_handgrade',\%keyhash,$cdom,$cnum);
}
# Called by Save & Refresh from Highlight Attribute Window
@@ -3482,7 +3390,7 @@ sub processHandGrade {
$ctr++;
}
if ($total < 0) {
- my $the_end.='
'.&mt('[_1]Message:[_2] No more students for this section or class.','','').'
'."\n";
+ my $the_end.='
'.&mt('[_1]Message:[_2] No more students for this section or class.','','').'
'."\n";
$request->print($the_end);
}
return '';
@@ -3490,7 +3398,7 @@ sub processHandGrade {
#---- Save the score and award for each student, if changed
sub saveHandGrade {
- my ($request,$symb,$stuname,$domain,$newflg,$submitter,$part,$queueable) = @_;
+ my ($request,$symb,$stuname,$domain,$newflg,$submitter,$part) = @_;
my @version_parts;
my $usec = &Apache::lonnet::getsection($domain,$stuname,
$env{'request.course.id'});
@@ -3602,7 +3510,7 @@ sub saveHandGrade {
&Apache::lonnet::cstore(\%newrecord,$symb,
$env{'request.course.id'},$domain,$stuname);
&check_and_remove_from_queue(\@parts,\%record,\%newrecord,$symb,
- $cdom,$cnum,$domain,$stuname,$queueable);
+ $cdom,$cnum,$domain,$stuname);
}
if ($aggregateflag) {
&Apache::lonnet::cinc('nohist_resourcetracker',\%aggregate,
@@ -3642,7 +3550,7 @@ sub makehidden {
}
sub check_and_remove_from_queue {
- my ($parts,$record,$newrecord,$symb,$cdom,$cnum,$domain,$stuname,$queueable) = @_;
+ my ($parts,$record,$newrecord,$symb,$cdom,$cnum,$domain,$stuname) = @_;
my @ungraded_parts;
foreach my $part (@{$parts}) {
if ( $record->{ 'resource.'.$part.'.awarded'} eq ''
@@ -3650,9 +3558,7 @@ sub check_and_remove_from_queue {
&& $newrecord->{'resource.'.$part.'.awarded'} eq ''
&& $newrecord->{'resource.'.$part.'.solved' } ne 'excused'
) {
- if ($queueable->{$part}) {
- push(@ungraded_parts, $part);
- }
+ push(@ungraded_parts, $part);
}
}
if ( !@ungraded_parts ) {
@@ -3678,19 +3584,19 @@ sub handback_files {
my $part_resp = join('_',@{ $part_response_id });
if (($env{'form.'.$newflg.'_'.$part_resp.'_countreturndoc'} =~ /^\d+$/) & ($new_part eq $part_id)) {
for (my $counter=1; $counter<=$env{'form.'.$newflg.'_'.$part_resp.'_countreturndoc'}; $counter++) {
- # if multiple files are uploaded names will be 'returndoc2','returndoc3'
- if ($env{'form.'.$newflg.'_'.$part_resp.'_returndoc'.$counter}) {
+ # if multiple files are uploaded names will be 'returndoc2','returndoc3'
+ if ($env{'form.'.$newflg.'_'.$part_resp.'_returndoc'.$counter}) {
my $fname=$env{'form.'.$newflg.'_'.$part_resp.'_returndoc'.$counter.'.filename'};
my ($directory,$answer_file) =
($env{'form.'.$newflg.'_'.$part_resp.'_origdoc'.$counter} =~ /^(.*?)([^\/]*)$/);
my ($answer_name,$answer_ver,$answer_ext) =
- &file_name_version_ext($answer_file);
+ &Apache::lonnet::file_name_version_ext($answer_file);
my ($portfolio_path) = ($directory =~ /^.+$stuname\/portfolio(.*)/);
my $getpropath = 1;
my ($dir_list,$listerror) =
&Apache::lonnet::dirlist($portfolio_root.$portfolio_path,
$domain,$stuname,$getpropath);
- my $version = &get_next_version($answer_name,$answer_ext,$dir_list);
+ my $version = &Apache::lonnet::get_next_version($answer_name,$answer_ext,$dir_list);
# fix filename
my ($save_file_name) = (($directory.$answer_name.".$version.".$answer_ext) =~ /^.+\/${stuname}\/(.*)/);
my $result=&Apache::lonnet::finishuserfileupload($stuname,$domain,
@@ -3708,8 +3614,7 @@ sub handback_files {
$$newrecord{"resource.$new_part.$resp_id.handback"}.=',';
}
$$newrecord{"resource.$new_part.$resp_id.handback"} .= $save_file_name;
- $file_msg.=''.$save_file_name." ";
-
+ $file_msg.= ''.$save_file_name." ";
}
$request->print(' '.&mt('[_1] will be the uploaded filename [_2]',''.$fname.'',''.$env{'form.'.$newflg.'_'.$part_resp.'_origdoc'.$counter}.''));
}
@@ -3720,7 +3625,7 @@ sub handback_files {
$request->print(' ');
my @what = ($symb,$env{'request.course.id'},'handback');
&Apache::lonnet::mark_as_readonly($domain,$stuname,\@handedback,\@what);
- my $user_lh = &Apache::loncommon::user_lang($stuname,$domain,$env{'request.course.id'});
+ my $user_lh = &Apache::loncommon::user_lang($stuname,$domain,$env{'request.course.id'});
my ($subject,$message);
if (scalar(@handedback) == 1) {
$subject = &mt_user($user_lh,'File Handed Back by Instructor');
@@ -3840,93 +3745,20 @@ sub version_portfiles {
my $version_parts = join('|',@$v_flag);
my @returned_keys;
my $parts = join('|', @$parts_graded);
- my $portfolio_root = '/userfiles/portfolio';
foreach my $key (keys(%$record)) {
my $new_portfiles;
if ($key =~ /^resource\.($version_parts)\./ && $key =~ /\.portfiles$/ ) {
my @versioned_portfiles;
my @portfiles = split(/\s*,\s*/,$$record{$key});
- foreach my $file (@portfiles) {
- &Apache::lonnet::unmark_as_readonly($domain,$stu_name,[$symb,$env{'request.course.id'}],$file);
- my ($directory,$answer_file) =($file =~ /^(.*?)([^\/]*)$/);
- my ($answer_name,$answer_ver,$answer_ext) =
- &file_name_version_ext($answer_file);
- my $getpropath = 1;
- my ($dir_list,$listerror) =
- &Apache::lonnet::dirlist($portfolio_root.$directory,$domain,
- $stu_name,$getpropath);
- my $version = &get_next_version($answer_name,$answer_ext,$dir_list);
- my $new_answer = &version_selected_portfile($domain, $stu_name, $directory, $answer_file, $version);
- if ($new_answer ne 'problem getting file') {
- push(@versioned_portfiles, $directory.$new_answer);
- &Apache::lonnet::mark_as_readonly($domain,$stu_name,
- [$directory.$new_answer],
- [$symb,$env{'request.course.id'},'graded']);
- }
+ if (@portfiles) {
+ &Apache::lonnet::portfiles_versioning($symb,$domain,$stu_name,\@portfiles,
+ \@versioned_portfiles);
}
$$record{$key} = join(',',@versioned_portfiles);
push(@returned_keys,$key);
}
- }
- return (@returned_keys);
-}
-
-sub get_next_version {
- my ($answer_name, $answer_ext, $dir_list) = @_;
- my $version;
- if (ref($dir_list) eq 'ARRAY') {
- foreach my $row (@{$dir_list}) {
- my ($file) = split(/\&/,$row,2);
- my ($file_name,$file_version,$file_ext) =
- &file_name_version_ext($file);
- if (($file_name eq $answer_name) &&
- ($file_ext eq $answer_ext)) {
- # gets here if filename and extension match,
- # regardless of version
- if ($file_version ne '') {
- # a versioned file is found so save it for later
- if ($file_version > $version) {
- $version = $file_version;
- }
- }
- }
- }
- }
- $version ++;
- return($version);
-}
-
-sub version_selected_portfile {
- my ($domain,$stu_name,$directory,$file_name,$version) = @_;
- my ($answer_name,$answer_ver,$answer_ext) =
- &file_name_version_ext($file_name);
- my $new_answer;
- $env{'form.copy'} = &Apache::lonnet::getfile("/uploaded/$domain/$stu_name/portfolio$directory$file_name");
- if($env{'form.copy'} eq '-1') {
- $new_answer = 'problem getting file';
- } else {
- $new_answer = $answer_name.'.'.$version.'.'.$answer_ext;
- my $copy_result = &Apache::lonnet::finishuserfileupload(
- $stu_name,$domain,'copy',
- '/portfolio'.$directory.$new_answer);
- }
- return ($new_answer);
-}
-
-sub file_name_version_ext {
- my ($file)=@_;
- my @file_parts = split(/\./, $file);
- my ($name,$version,$ext);
- if (@file_parts > 1) {
- $ext=pop(@file_parts);
- if (@file_parts > 1 && $file_parts[-1] =~ /^\d+$/) {
- $version=pop(@file_parts);
- }
- $name=join('.',@file_parts);
- } else {
- $name=join('.',@file_parts);
- }
- return($name,$version,$ext);
+ }
+ return (@returned_keys);
}
#--------------------------------------------------------------------------------------
@@ -4145,26 +3977,7 @@ sub viewgrades {
}
my ($common_header,$specific_header,@sections,$section_display);
- if ($env{'request.course.sec'} ne '') {
- @sections = ($env{'request.course.sec'});
- } else {
- @sections = &Apache::loncommon::get_env_multiple('form.section');
- }
-
-# Check if Save button should be usable
- my $disabled = ' disabled="disabled"';
- if ($perm{'mgr'}) {
- if (grep(/^all$/,@sections)) {
- undef($disabled);
- } else {
- foreach my $sec (@sections) {
- if (&canmodify($sec)) {
- undef($disabled);
- last;
- }
- }
- }
- }
+ @sections = &Apache::loncommon::get_env_multiple('form.section');
if (grep(/^all$/,@sections)) {
@sections = ('all');
if ($group_display) {
@@ -4174,7 +3987,7 @@ sub viewgrades {
$common_header = &mt('Assign Common Grade to Students not assigned to any groups');
$specific_header = &mt('Assign Grade to Specific Students not assigned to any groups');
} else {
- $common_header = &mt('Assign Common Grade to Class');
+ $common_header = &mt('Assign Common Grade to Class');
$specific_header = &mt('Assign Grade to Specific Students in Class');
}
} elsif (grep(/^none$/,@sections)) {
@@ -4187,7 +4000,7 @@ sub viewgrades {
$specific_header = &mt('Assign Grade to Specific Students in no Section and in no Group');
} else {
$common_header = &mt('Assign Common Grade to Students in no Section');
- $specific_header = &mt('Assign Grade to Specific Students in no Section');
+ $specific_header = &mt('Assign Grade to Specific Students in no Section');
}
} else {
$section_display = join (", ",@sections);
@@ -4201,7 +4014,7 @@ sub viewgrades {
$specific_header = &mt('Assign Grade to Specific Students in Section(s) [_1] and no Group',$section_display);
} else {
$common_header = &mt('Assign Common Grade to Students in Section(s) [_1]',$section_display);
- $specific_header = &mt('Assign Grade to Specific Students in Section(s) [_1]',$section_display);
+ $specific_header = &mt('Assign Grade to Specific Students in Section(s) [_1]',$section_display);
}
}
my %submit_types = &substatus_options();
@@ -4258,10 +4071,10 @@ sub viewgrades {
$partid.'" size="4" '.'onchange="javascript:writePoint(\''.
$partid.'\','.$weight{$partid}.',\'textval\')" /> /'.
$weight{$partid}.' '.&mt('(problem weight)').''."\n";
- $line.= '
'.&mt('Grade Status').':'.
- '
'.
&Apache::loncommon::end_data_table_row().
&Apache::loncommon::end_data_table();
return $result;
@@ -5023,13 +4816,12 @@ sub csvuploadmap {
if (!$env{'form.datatoken'}) {
$datatoken=&Apache::loncommon::upfile_store($request);
} else {
- $datatoken=&Apache::loncommon::valid_datatoken($env{'form.datatoken'});
- if ($datatoken ne '') {
+ $datatoken=&Apache::loncommon::valid_datatoken($env{'form.datatoken'});
+ if ($datatoken ne '') {
&Apache::loncommon::load_tmp_file($request,$datatoken);
}
}
my @records=&Apache::loncommon::upfile_record_sep();
- if ($env{'form.noFirstLine'}) { shift(@records); }
&csvuploadmap_header($request,$symb,$datatoken,$#records+1);
my ($i,$keyfields);
if (@records) {
@@ -5066,8 +4858,6 @@ sub csvuploadmap {
sub csvuploadoptions {
my ($request,$symb)= @_;
my $overwrite=&mt('Overwrite any existing score');
- my $checked=(($env{'form.noFirstLine'})?'1':'0');
- my $ignore=&mt('Ignore First Line');
$request->print(<
@@ -5081,7 +4871,7 @@ ENDPICK
my %fields=&get_fields();
if (!defined($fields{'domain'})) {
my $domform = &Apache::loncommon::select_dom_form($env{'request.role.domain'},'default_domain');
- $request->print("\n
".&mt('Users are in domain: [_1]',$domform)."
\n");
+ $request->print("\n
".&mt('Users are in domain: [_1]',$domform)."
\n");
}
foreach my $key (sort(keys(%env))) {
if ($key !~ /^form\.(.*)$/) { next; }
@@ -5119,11 +4909,10 @@ sub csvuploadassign {
if (!$symb) {return '';}
my $error_msg = '';
my $datatoken = &Apache::loncommon::valid_datatoken($env{'form.datatoken'});
- if ($datatoken ne '') {
+ if ($datatoken ne '') {
&Apache::loncommon::load_tmp_file($request,$datatoken);
}
my @gradedata = &Apache::loncommon::upfile_record_sep();
- if ($env{'form.noFirstLine'}) { shift(@gradedata); }
my %fields=&get_fields();
my $courseid=$env{'request.course.id'};
my ($classlist) = &getclasslist('all',0);
@@ -5145,13 +4934,45 @@ sub csvuploadassign {
if (!$username) {
my $id=$entries{$fields{'ID'}};
$id=~s/\s//g;
- my %ids=&Apache::lonnet::idget($domain,$id);
- $username=$ids{$id};
+ if ($id ne '') {
+ my %ids=&Apache::lonnet::idget($domain,[$id]);
+ $username=$ids{$id};
+ } else {
+ if ($entries{$fields{'clicker'}}) {
+ my $clicker = $entries{$fields{'clicker'}};
+ $clicker=~s/\s//g;
+ if ($clicker ne '') {
+ my %clickers = &Apache::lonnet::idget($domain,[$clicker],'clickers');
+ if ($clickers{$clicker} ne '') {
+ my $match = 0;
+ my @inclass;
+ foreach my $poss (split(/,/,$clickers{$clicker})) {
+ if (exists($$classlist{"$poss:$domain"})) {
+ $username = $poss;
+ push(@inclass,$poss);
+ $match ++;
+
+ }
+ }
+ if ($match > 1) {
+ undef($username);
+ $request->print('
'.
+ &mt('Score not saved for clicker: [_1] (matched multiple usernames: [_2])',
+ $clicker,join(', ',@inclass)).'
');
+ }
+ }
+ }
+ }
+ }
}
if (!exists($$classlist{"$username:$domain"})) {
my $id=$entries{$fields{'ID'}};
$id=~s/\s//g;
- if ($id) {
+ my $clicker = $entries{$fields{'clicker'}};
+ $clicker=~s/\s//g;
+ if ($clicker) {
+ push(@skipped,"$clicker:$domain");
+ } elsif ($id) {
push(@skipped,"$id:$domain");
} else {
push(@skipped,"$username:$domain");
@@ -5179,7 +5000,7 @@ sub csvuploadassign {
my $award=($pcr == 0) ? 'incorrect_by_override'
: 'correct_by_override';
if ($pcr>1) {
- push(@warnings,&mt("[_1]: point value larger than weight","$username:$domain"));
+ push(@warnings,&mt("[_1]: point value larger than weight","$username:$domain"));
}
$grades{"resource.$part.awarded"}=$pcr;
$grades{"resource.$part.solved"}=$award;
@@ -5215,13 +5036,13 @@ sub csvuploadassign {
$env{'course.'.$env{'request.course.id'}.'.domain'},
$env{'course.'.$env{'request.course.id'}.'.num'},
$domain,$username);
- } else {
+ $countdone++;
+ } else {
$request->print("
".
&mt("Failed to save data for student [_1]. Message when trying to save was: [_2]",
"$username:$domain",$result)."
");
}
$request->rflush();
- $countdone++;
}
}
$request->print(' '.&Apache::lonhtmlcommon::confirm_success(&mt("Saved scores for [quant,_1,student]",$countdone),$countdone==0));
@@ -5290,30 +5111,30 @@ LISTJAVASCRIPT
# Collection of hidden fields
my $ctr=0;
foreach (@$titles) {
- my ($minder,$showtitle) = ($_ =~ /(\d+)\.(.*)/);
- $result.=''."\n";
- $result.=''."\n";
- $ctr++;
+ my ($minder,$showtitle) = ($_ =~ /(\d+)\.(.*)/);
+ $result.=''."\n";
+ $result.=''."\n";
+ $ctr++;
}
$result.=''."\n".
- ''."\n";
+ ''."\n";
$result.=&build_section_inputs();
my $stu_status = join(':',&Apache::loncommon::get_env_multiple('form.Status'));
$result.=''."\n".
- ''."\n".
- ''."\n";
+ ''."\n".
+ ''."\n";
# Show grading options
$result.=&Apache::lonhtmlcommon::start_pick_box();
my $select = ''."\n";
$ctr=0;
foreach (@$titles) {
- my ($minder,$showtitle) = ($_ =~ /(\d+)\.(.*)/);
- $select.=''."\n";
- $ctr++;
+ my ($minder,$showtitle) = ($_ =~ /(\d+)\.(.*)/);
+ $select.=''."\n";
+ $ctr++;
}
$select.= '';
@@ -5339,7 +5160,7 @@ LISTJAVASCRIPT
.''
.&Apache::lonhtmlcommon::row_closure();
-
+
$result.=
&Apache::lonhtmlcommon::row_title(&mt('Use CODE'))
.''
@@ -5442,10 +5263,10 @@ sub displayPage {
&Apache::lonnet::clear_EXT_cache_status();
if (!&canview($usec)) {
- $request->print(
+ $request->print(
''.
&mt('Unable to view requested student. ([_1])',
- $env{'form.student'}).
+ $env{'form.student'}).
'');
return;
}
@@ -5528,7 +5349,7 @@ sub displayPage {
} else {
if ($env{'form.vProb'} eq 'yes' ) {
$studentTable.=&show_problem($request,$symbx,$uname,$udom,1,
- undef,'both',\%form);
+ undef,'both',\%form);
} else {
my $companswer = &Apache::loncommon::get_student_answers($symbx,$uname,$udom,$env{'request.course.id'},%form);
$companswer =~ s|");
@@ -9314,7 +9273,7 @@ sub graders_resources_pass {
=item users_order
Returns array of resources in current map, ordered based on either CODE,
- if this is a CODEd exam, or based on student's identity if this is a
+ if this is a CODEd exam, or based on student's identity if this is a
"NAMEd" exam.
Should be used when randomorder and/or randompick applied when the
@@ -9341,7 +9300,7 @@ sub users_order {
if (ref($actual_seq) eq 'ARRAY') {
@mapresources = map { $symb_to_resource->{$_}; } @{$actual_seq};
if (ref($orderedforcode) eq 'HASH') {
- if (@mapresources > 0) {
+ if (@mapresources > 0) {
$orderedforcode->{$scancode} = \@mapresources;
}
}
@@ -9354,7 +9313,7 @@ sub users_order {
$master_seq,
$user,undef,1);
if (ref($actual_seq) eq 'ARRAY') {
- @mapresources =
+ @mapresources =
map { $symb_to_resource->{$_}; } @{$actual_seq};
}
}
@@ -9419,7 +9378,7 @@ sub scantron_upload_scantron_data {
'domainid',
'coursename',$dom);
my $syllabuslink = ''.&mt('Syllabus').''.
- (' 'x2).&mt('(shows course personnel)');
+ (' 'x2).&mt('(shows course personnel)');
my $default_form_data=&defaultFormData($symb);
my $nofile_alert = &mt('Please use the browse button to select a file from your local directory.');
&js_escape(\$nofile_alert);
@@ -9500,13 +9459,13 @@ END
if (keys(%{$domconfig{'scantron'}{'config'}}) > 1) {
if (($domconfig{'scantron'}{'config'}{'dat'}) &&
(ref($domconfig{'scantron'}{'config'}{'csv'}) eq 'HASH')) {
- if (ref($domconfig{'scantron'}{'config'}{'csv'}{'fields'}) eq 'HASH') {
+ 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 =~ /^\#/) || ($line eq ''));
+ next if ($line =~ /^#/);
$singleline = $line;
$count ++;
}
@@ -9574,16 +9533,18 @@ sub scantron_upload_scantron_data_save {
''."\n";
if (!&Apache::lonnet::allowed('usc',$env{'form.domainid'}) &&
!&Apache::lonnet::allowed('usc',
- $env{'form.domainid'}.'_'.$env{'form.courseid'})) {
+ $env{'form.domainid'}.'_'.$env{'form.courseid'}) &&
+ !&Apache::lonnet::allowed('usc',
+ $env{'form.domainid'}.'_'.$env{'form.courseid'}.'/'.$env{'form.coursesec'})) {
$r->print(&mt("You are not allowed to upload bubblesheet data to the requested course.")." ");
- unless ($symb) {
+ unless ($symb) {
$r->print($doanotherupload);
}
return '';
}
my %coursedata=&Apache::lonnet::coursedescription($env{'form.domainid'}.'_'.$env{'form.courseid'});
my $uploadedfile;
- $r->print('
'.&mt("Uploading file to [_1]",$coursedata{'description'}).'
');
+ $r->print('
'.&mt('Uploading file to [_1]','"'.$coursedata{'description'}.'"').'
');
if (length($env{'form.upfile'}) < 2) {
$r->print(
&Apache::lonhtmlcommon::confirm_success(
@@ -9623,16 +9584,25 @@ sub scantron_upload_scantron_data_save {
my $result =
&Apache::lonnet::userfileupload('upfile','scantron','scantron',$parser,'','',
$env{'form.courseid'},$env{'form.domainid'});
- if ($result =~ m{^/uploaded/}) {
+ if ($result =~ m{^/uploaded/}) {
$r->print(
&Apache::lonhtmlcommon::confirm_success(&mt('Upload successful')).' '.
&mt('Uploaded [_1] bytes of data into location: [_2]',
(length($env{'form.upfile'})-1),
''.$result.''));
($uploadedfile) = ($result =~ m{/([^/]+)$});
+ if ($uploadedfile =~ /^scantron_orig_/) {
+ my $logname = $uploadedfile;
+ $logname =~ s/^scantron_orig_//;
+ if ($logname ne '') {
+ my $now = time;
+ my %info = ($logname => { $now => $env{'user.name'}.':'.$env{'user.domain'} });
+ &Apache::lonnet::put('scantronupload',\%info,$env{'form.domainid'},$env{'form.courseid'});
+ }
+ }
$r->print(&validate_uploaded_scantron_file($env{'form.domainid'},
- $env{'form.courseid'},$uploadedfile));
- } else {
+ $env{'form.courseid'},$symb,$uploadedfile));
+ } else {
$r->print(
&Apache::lonhtmlcommon::confirm_success(&mt('Upload failed'),1).' '.
&mt('An error ([_1]) occurred when attempting to upload the file: [_2]',
@@ -9649,13 +9619,34 @@ sub scantron_upload_scantron_data_save {
}
sub validate_uploaded_scantron_file {
- my ($cdom,$cname,$fname) = @_;
+ my ($cdom,$cname,$symb,$fname,$context,$countsref) = @_;
+
my $scanlines=&Apache::lonnet::getfile('/uploaded/'.$cdom.'/'.$cname.'/'.$fname);
my @lines;
if ($scanlines ne '-1') {
@lines=split("\n",$scanlines,-1);
}
- my $output;
+ my ($output,$secidx,$checksec,$priv,%crsroleshash,@possibles);
+ $secidx = &Apache::loncoursedata::CL_SECTION();
+ if ($context eq 'download') {
+ $priv = 'mgr';
+ } else {
+ $priv = 'usc';
+ }
+ unless ((&Apache::lonnet::allowed($priv,$env{'request.role.domain'})) ||
+ (($env{'request.course.id'}) &&
+ (&Apache::lonnet::allowed($priv,$env{'request.course.id'})))) {
+ if ($env{'request.course.sec'} ne '') {
+ unless (&Apache::lonnet::allowed($priv,
+ "$env{'request.course.id'}/$env{'request.course.sec'}")) {
+ unless ($context eq 'download') {
+ $output = '
'.&mt('You do not have permission to upload bubblesheet data').'
';
+ }
+ return $output;
+ }
+ ($checksec,@possibles)=&gradable_sections();
+ }
+ }
if (@lines) {
my (%counts,$max_match_format);
my ($found_match_count,$max_match_count,$max_match_pct) = (0,0,0);
@@ -9668,7 +9659,7 @@ sub validate_uploaded_scantron_file {
my %unique_formats;
my @formatlines = &Apache::lonnet::get_scantronformat_file();
foreach my $line (@formatlines) {
- next if (($line =~ /^\#/) || ($line eq ''));
+ chomp($line);
my @config = split(/:/,$line);
my $idstart = $config[5];
my $idlength = $config[6];
@@ -9685,6 +9676,8 @@ sub validate_uploaded_scantron_file {
%{$counts{$key}} = (
'found' => 0,
'total' => 0,
+ 'totalanysec' => 0,
+ 'othersec' => 0,
);
foreach my $line (@lines) {
next if ($line =~ /^#/);
@@ -9692,6 +9685,23 @@ sub validate_uploaded_scantron_file {
my $id = substr($line,$idstart-1,$idlength);
$id = lc($id);
if (exists($idmap{$id})) {
+ if ($checksec ne '') {
+ $counts{$key}{'totalanysec'} ++;
+ if (ref($classlist->{$idmap{$id}}) eq 'ARRAY') {
+ my $stusec = $classlist->{$idmap{$id}}->[$secidx];
+ if ($stusec ne $checksec) {
+ if (@possibles) {
+ unless (grep(/^\Q$stusec\E$/,@possibles)) {
+ $counts{$key}{'othersec'} ++;
+ next;
+ }
+ } else {
+ $counts{$key}{'othersec'} ++;
+ next;
+ }
+ }
+ }
+ }
$counts{$key}{'found'} ++;
}
$counts{$key}{'total'} ++;
@@ -9706,7 +9716,7 @@ sub validate_uploaded_scantron_file {
}
}
}
- if (ref($unique_formats{$max_match_format}) eq 'ARRAY') {
+ if ((ref($unique_formats{$max_match_format}) eq 'ARRAY') && ($context ne 'download')) {
my $format_descs;
my $numwithformat = @{$unique_formats{$max_match_format}};
for (my $i=0; $i<$numwithformat; $i++) {
@@ -9751,13 +9761,179 @@ sub validate_uploaded_scantron_file {
'
'.&mt('The course roster is not up to date.').'
'.
'';
}
+ if (($checksec ne '') && (ref($counts{$max_match_format}) eq 'HASH')) {
+ if ($counts{$max_match_format}{'othersec'}) {
+ my $percent_nongrade = (100*$counts{$max_match_format}{'othersec'})/($counts{$max_match_format}{'totalanysec'});
+ my $showpct = sprintf("%.0f",$percent_nongrade).'%';
+ my $confirmdel = &mt('Are you sure you want to permanently delete this file?');
+ &js_escape(\$confirmdel);
+ $output .= '
'.
+ &mt('Comparison of student IDs in the uploaded file with the course roster found [_1][quant,_2,match,matches][_3] for students in section(s) for which none of your role(s) have privileges to modify grades',
+ '',$counts{$max_match_format}{'othersec'},'').
+ ' '.
+ &mt('Unless you are assigned role(s) which allow modification of grades in additional sections, [_1] of the records in this file will be automatically excluded when you perform bubblesheet grading.',''.$showpct.'').
+ '
'.
+ &mt('If you prefer to delete the file now, use: [_1]').
+ '
';
}
return $output;
}
+sub gradable_sections {
+ my $checksec = $env{'request.course.sec'};
+ my @oksecs;
+ if ($checksec) {
+ my %availablesecs = §ions_grade_privs();
+ if (ref($availablesecs{'mgr'}) eq 'ARRAY') {
+ foreach my $sec (@{$availablesecs{'mgr'}}) {
+ unless (grep(/^\Q$sec\E$/,@oksecs)) {
+ push(@oksecs,$sec);
+ }
+ }
+ if (grep(/^all$/,@oksecs)) {
+ undef($checksec);
+ }
+ }
+ }
+ return($checksec,@oksecs);
+}
+
+sub sections_grade_privs {
+ my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+ my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+ my %availablesecs = (
+ mgr => [],
+ vgr => [],
+ usc => [],
+ );
+ my $ccrole = 'cc';
+ if ($env{'course.'.$env{'request.course.id'}.'.type'} eq 'Community') {
+ $ccrole = 'co';
+ }
+ my %crsroleshash = &Apache::lonnet::get_my_roles($env{'user.name'},$env{'user.domain'},
+ 'userroles',['active'],
+ [$ccrole,'in','cr'],$cdom,1);
+ my $crsid = $cnum.':'.$cdom;
+ foreach my $item (keys(%crsroleshash)) {
+ next unless ($item =~ /^$crsid\:/);
+ my ($crsnum,$crsdom,$role,$sec) = split(/\:/,$item);
+ my $suffix = "/$cdom/$cnum./$cdom/$cnum";
+ if ($sec ne '') {
+ $suffix = "/$cdom/$cnum/$sec./$cdom/$cnum/$sec";
+ }
+ if (($role eq $ccrole) || ($role eq 'in')) {
+ foreach my $priv ('mgr','vgr','usc') {
+ unless (grep(/^all$/,@{$availablesecs{$priv}})) {
+ if ($sec eq '') {
+ $availablesecs{$priv} = ['all'];
+ } elsif ($sec ne $env{'request.course.sec'}) {
+ unless (grep(/^\Q$sec\E$/,@{$availablesecs{$priv}})) {
+ push(@{$availablesecs{$priv}},$sec);
+ }
+ }
+ }
+ }
+ } elsif ($role =~ m{^cr/}) {
+ foreach my $priv ('mgr','vgr','usc') {
+ unless (grep(/^all$/,@{$availablesecs{$priv}})) {
+ if ($env{"user.priv.$role.$suffix"} =~ /:$priv&/) {
+ if ($sec eq '') {
+ $availablesecs{$priv} = ['all'];
+ } elsif ($sec ne $env{'request.course.sec'}) {
+ unless (grep(/^\Q$sec\E$/,@{$availablesecs{$priv}})) {
+ push(@{$availablesecs{$priv}},$sec);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return %availablesecs;
+}
+
+sub scantron_upload_delete {
+ my ($r,$symb) = @_;
+ my $filename = $env{'form.uploadedfile'};
+ if ($filename =~ /^scantron_orig_/) {
+ if (&Apache::lonnet::allowed('usc',$env{'form.domainid'}) ||
+ &Apache::lonnet::allowed('usc',
+ $env{'form.domainid'}.'_'.$env{'form.courseid'}) ||
+ &Apache::lonnet::allowed('usc',
+ $env{'form.domainid'}.'_'.$env{'form.courseid'}.'/'.$env{'form.coursesec'})) {
+ my $uploadurl = '/uploaded/'.$env{'form.domainid'}.'/'.$env{'form.courseid'}.'/'.$env{'form.uploadedfile'};
+ my $retrieval = &Apache::lonnet::getfile($uploadurl);
+ if ($retrieval eq '-1') {
+ $r->print(&Apache::lonhtmlcommon::confirm_success(&mt('File deletion failed'),1).' '.
+ &mt('File requested for deletion not found.'));
+ } else {
+ $filename =~ s/^scantron_orig_//;
+ if ($filename ne '') {
+ my ($is_valid,$numleft);
+ my %info = &Apache::lonnet::get('scantronupload',[$filename],$env{'form.domainid'},$env{'form.courseid'});
+ if (keys(%info)) {
+ if (ref($info{$filename}) eq 'HASH') {
+ foreach my $timestamp (sort(keys(%{$info{$filename}}))) {
+ if ($info{$filename}{$timestamp} eq $env{'user.name'}.':'.$env{'user.domain'}) {
+ $is_valid = 1;
+ delete($info{$filename}{$timestamp});
+ }
+ }
+ $numleft = scalar(keys(%{$info{$filename}}));
+ }
+ }
+ if ($is_valid) {
+ my $result = &Apache::lonnet::removeuploadedurl($uploadurl);
+ if ($result eq 'ok') {
+ $r->print(&Apache::lonhtmlcommon::confirm_success(&mt('File deletion successful')).' ');
+ if ($numleft) {
+ &Apache::lonnet::put('scantronupload',\%info,$env{'form.domainid'},$env{'form.courseid'});
+ } else {
+ &Apache::lonnet::del('scantronupload',[$filename],$env{'form.domainid'},$env{'form.courseid'});
+ }
+ } else {
+ $r->print(&Apache::lonhtmlcommon::confirm_success(&mt('File deletion failed'),1).' '.
+ &mt('Result was [_1]',$result));
+ }
+ } else {
+ $r->print(&Apache::lonhtmlcommon::confirm_success(&mt('File deletion failed'),1).' '.
+ &mt('File requested for deletion was uploaded by a different user.'));
+ }
+ } else {
+ $r->print(&Apache::lonhtmlcommon::confirm_success(&mt('File deletion failed'),1).' '.
+ &mt('Filename of bubblesheet data file requested for deletion is invalid.'));
+ }
+ }
+ } else {
+ $r->print(&Apache::lonhtmlcommon::confirm_success(&mt('File deletion failed'),1).' '.
+ &mt('You are not permitted to delete bubblesheet data files from the requested course.'));
+ }
+ } else {
+ $r->print(&Apache::lonhtmlcommon::confirm_success(&mt('File deletion failed'),1).' '.
+ &mt('Filename of bubblesheet data file requested for deletion is invalid.'));
+ }
+ return;
+}
+
sub valid_file {
my ($requested_file)=@_;
foreach my $filename (sort(&scantron_filenames())) {
@@ -9780,6 +9956,29 @@ sub scantron_download_scantron_data {
');
return;
}
+ my (%uploader,$is_owner,%counts,$percent);
+ my %uploader = &Apache::lonnet::get('scantronupload',[$file],$cdom,$cname);
+ if (ref($uploader{$file}) eq 'HASH') {
+ foreach my $timestamp (sort { $a <=> $b } keys(%{$uploader{$file}})) {
+ if ($uploader{$file}{$timestamp} eq $env{'user.name'}.':'.$env{'user.domain'}) {
+ $is_owner = 1;
+ last;
+ }
+ }
+ }
+ unless ($is_owner) {
+ &validate_uploaded_scantron_file($cdom,$cname,$symb,'scantron_orig_'.$file,'download',\%counts);
+ if ($counts{'totalanysec'}) {
+ my $percent_othersec = (100*$counts{'othersec'})/($counts{'totalanysec'});
+ if ($percent_othersec >= 10) {
+ my $showpct = sprintf("%.0f",$percent_othersec).'%';
+ $r->print('
'.
+ &mt('The original uploaded file includes [_1] or more of records for students for which none of your roles have rights to modify grades, so files are unavailable for download.',$showpct).
+ '
');
+ return;
+ }
+ }
+ }
my $orig='/uploaded/'.$cdom.'/'.$cname.'/scantron_orig_'.$file;
my $corrected='/uploaded/'.$cdom.'/'.$cname.'/scantron_corrected_'.$file;
my $skipped='/uploaded/'.$cdom.'/'.$cname.'/scantron_skipped_'.$file;
@@ -9816,7 +10015,7 @@ sub checkscantron_results {
my %scantron_config =
&Apache::lonnet::get_scantron_config($env{'form.scantron_format'});
my $bubbles_per_row = &bubblesheet_bubbles_per_row(\%scantron_config);
- my ($scanlines,$scan_data)=&Apache::grades::scantron_getfile();
+ my ($scanlines,$scan_data)=&scantron_getfile();
my $classlist=&Apache::loncoursedata::get_classlist();
my %idmap=&Apache::grades::username_to_idmap($classlist);
my $navmap=Apache::lonnavmaps::navmap->new();
@@ -9827,20 +10026,9 @@ sub checkscantron_results {
my $map=$navmap->getResourceByUrl($sequence);
my ($randomorder,$randompick,@master_seq,%symb_to_resource,%grader_partids_by_symb,
%grader_randomlists_by_symb,%orderedforcode);
- if (ref($map)) {
+ if (ref($map)) {
$randomorder=$map->randomorder();
$randompick=$map->randompick();
- unless ($randomorder || $randompick) {
- foreach my $res ($navmap->retrieveResources($map,sub { $_[0]->is_map() },1,0,1)) {
- if ($res->randomorder()) {
- $randomorder = 1;
- }
- if ($res->randompick()) {
- $randompick = 1;
- }
- last if ($randomorder || $randompick);
- }
- }
}
my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0);
my $nav_error = &get_master_seq(\@resources,\@master_seq,\%symb_to_resource);
@@ -9867,8 +10055,7 @@ sub checkscantron_results {
return '';
}
- &Apache::lonhtmlcommon::Update_PrgWin($r,\%prog_state,
- 'Processing first student');
+ &Apache::lonhtmlcommon::Update_PrgWin($r,\%prog_state,'Processing first student');
my $start=&Time::HiRes::time();
my $i=-1;
@@ -9878,8 +10065,7 @@ sub checkscantron_results {
my $line=&Apache::grades::scantron_get_line($scanlines,$scan_data,$i);
if ($line=~/^[\s\cz]*$/) { next; }
if ($started) {
- &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,
- 'last student');
+ &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,'last student');
}
$started=1;
my $scan_record=
@@ -9991,19 +10177,21 @@ sub checkscantron_results {
}
}
}
- $r->print('
'.
- &mt('Comparison of bubblesheet data (including corrections) with corresponding submission records (most recent submission) for [_1][quant,_2,student][_3] ([quant,_4,bubblesheet line] per student).',
- '',
- $numstudents,
- '',
- $env{'form.scantron_maxbubble'}).
- '
'
+ $r->print(
+ '
'
+ .&mt('Comparison of bubblesheet data (including corrections) with corresponding submission records (most recent submission) for [_1][quant,_2,student][_3] ([quant,_4,bubblesheet line] per student).',
+ '',
+ $numstudents,
+ '',
+ $env{'form.scantron_maxbubble'})
+ .'
'
);
$r->print('
'
.&mt('Exact matches for [_1][quant,_2,student][_3].','',$passed,'')
.' '
.&mt('Discrepancies detected for [_1][quant,_2,student][_3].','',$failed,'')
- .'
');
+ .''
+ );
if ($passed) {
$r->print(&mt('Students with exact correspondence between bubblesheet data and submissions are as follows:').'
');
$r->print(&Apache::loncommon::start_data_table()."\n".
@@ -10168,7 +10356,7 @@ sub grading_menu {
my %fields = ('symb'=>&Apache::lonenc::check_encrypt($symb),
'command'=>'individual');
-
+
my $url1a = &Apache::lonhtmlcommon::build_url('grades/',\%fields);
$fields{'command'}='ungraded';
@@ -10182,7 +10370,7 @@ sub grading_menu {
$fields{'command'}='downloadfilesselect';
my $url1e=&Apache::lonhtmlcommon::build_url('grades/',\%fields);
-
+
$fields{'command'} = 'csvform';
my $url2 = &Apache::lonhtmlcommon::build_url('grades/',\%fields);
@@ -10194,74 +10382,64 @@ sub grading_menu {
$fields{'command'} = 'initialverifyreceipt';
my $url5 = &Apache::lonhtmlcommon::build_url('grades/',\%fields);
-
- my %permissions;
- if ($perm{'mgr'}) {
- $permissions{'either'} = 'F';
- $permissions{'mgr'} = 'F';
- }
- if ($perm{'vgr'}) {
- $permissions{'either'} = 'F';
- $permissions{'vgr'} = 'F';
- }
-
+
my @menu = ({ categorytitle=>'Hand Grading',
items =>[
- { linktext => 'Select individual students to grade',
- url => $url1a,
- permission => $permissions{'either'},
- icon => 'grade_students.png',
- linktitle => 'Grade current resource for a selection of students.'
- },
+ { linktext => 'Select individual students to grade',
+ url => $url1a,
+ permission => 'F',
+ icon => 'grade_students.png',
+ linktitle => 'Grade current resource for a selection of students.'
+ },
{ linktext => 'Grade ungraded submissions',
url => $url1b,
- permission => $permissions{'either'},
+ permission => 'F',
icon => 'ungrade_sub.png',
linktitle => 'Grade all submissions that have not been graded yet.'
},
{ linktext => 'Grading table',
url => $url1c,
- permission => $permissions{'either'},
+ permission => 'F',
icon => 'grading_table.png',
linktitle => 'Grade current resource for all students.'
},
{ linktext => 'Grade page/folder for one student',
url => $url1d,
- permission => $permissions{'either'},
+ permission => 'F',
icon => 'grade_PageFolder.png',
linktitle => 'Grade all resources in current page/sequence/folder for one student.'
},
- { linktext => 'Download submitted files',
+ { linktext => 'Download submissions',
url => $url1e,
- permission => $permissions{'either'},
+ permission => 'F',
icon => 'download_sub.png',
- linktitle => 'Download all files submitted by students.'
+ linktitle => 'Download all students submissions.'
}]},
{ categorytitle=>'Automated Grading',
items =>[
{ linktext => 'Upload Scores',
url => $url2,
- permission => $permissions{'mgr'},
+ permission => 'F',
icon => 'uploadscores.png',
linktitle => 'Specify a file containing the class scores for current resource.'
},
{ linktext => 'Process Clicker',
url => $url3,
- permission => $permissions{'mgr'},
+ permission => 'F',
icon => 'addClickerInfoFile.png',
linktitle => 'Specify a file containing the clicker information for this resource.'
},
{ linktext => 'Grade/Manage/Review Bubblesheets',
url => $url4,
- permission => $permissions{'mgr'},
+ permission => 'F',
icon => 'bubblesheet.png',
linktitle => 'Grade bubblesheet exams, upload/download bubblesheet data files, and review previously graded bubblesheet exams.'
},
{ linktext => 'Verify Receipt Number',
url => $url5,
- permission => $permissions{'either'},
+ permission => 'F',
icon => 'receipt_number.png',
linktitle => 'Verify a system-generated receipt number for correct problem solution.'
}
@@ -10348,13 +10526,13 @@ sub submit_options_download {
&commonJSfunctions($request);
my $result='
';
@@ -10392,34 +10570,26 @@ sub selectfield {
(&transtatus_options,
'select_form_order' => ['yes','incorrect','all']);
} else {
- %options =
+ %options =
(&substatus_options,
'select_form_order' => ['yes','queued','graded','incorrect','all']);
}
-
- #
- # PrepareClasslist() needs to be called to avoid getting a sections list
- # for a different course from the @Sections global in lonstatistics.pm,
- # populated by an earlier request.
- #
- &Apache::lonstatistics::PrepareClasslist();
-
my $result='