--- loncom/homework/grades.pm 2025/01/18 05:20:01 1.596.2.12.2.60.2.8
+++ loncom/homework/grades.pm 2024/12/13 05:04:49 1.805
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# The LON-CAPA Grading handler
#
-# $Id: grades.pm,v 1.596.2.12.2.60.2.8 2025/01/18 05:20:01 raeburn Exp $
+# $Id: grades.pm,v 1.805 2024/12/13 05:04:49 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -44,6 +44,7 @@ use Apache::Constants qw(:common :http);
use Apache::lonlocal;
use Apache::lonenc;
use Apache::lonstathelpers;
+use Apache::lonquickgrades;
use Apache::bridgetask();
use Apache::lontexconvert();
use Apache::loncourserespicker;
@@ -148,7 +149,6 @@ sub nameUserString {
}
#--- Get the partlist and the response type for a given problem. ---
-#--- Indicate if a response type is coded handgraded or not. ---
#--- Count responseIDs, essayresponse items, and dropbox items ---
#--- Sets response_error pointer to "1" if navmaps object broken ---
sub response_type {
@@ -1263,18 +1263,18 @@ sub do_passback {
my $cdom = $env{"course.$env{'request.course.id'}.domain"};
my $cnum = $env{"course.$env{'request.course.id'}.num"};
my $crstype = &Apache::loncommon::course_type();
- my ($launchsymb,$appname,$setter,$linkuri,$linkprotector,$scope,$chosen);
+ my ($launcher,$appname,$setter,$linkuri,$linkprotector,$scope,$chosen);
if ($env{'form.passback'} ne '') {
$chosen = &unescape($env{'form.passback'});
($linkuri,$linkprotector,$scope) = split("\0",$chosen);
- ($launchsymb,$appname,$setter) = &get_passback_launcher($cdom,$cnum,$chosen);
+ ($launcher,$appname,$setter) = &get_passback_launcher($cdom,$cnum,$chosen);
}
- if ($launchsymb ne '') {
- $request->print(&launcher_info_box($launchsymb,$appname,$setter,$linkuri,$scope));
+ if ($launcher ne '') {
+ $request->print(&launcher_info_box($launcher,$appname,$setter,$linkuri,$scope));
}
my $error;
if ($perm{'mgr'}) {
- if ($launchsymb ne '') {
+ if ($launcher ne '') {
my @poss_students = &Apache::loncommon::get_env_multiple('form.stuinfo');
if (@poss_students) {
my %possibles;
@@ -1312,11 +1312,12 @@ sub do_passback {
if ($lti_in_use->{'scoreformat'} =~ /^(decimal|ratio|percentage)$/) {
$scoretype = $1;
}
+ my $pbsymb = &Apache::loncommon::symb_from_tinyurl($linkuri,$cnum,$cdom);
my $pbmap;
- if ($launchsymb =~ /\.(page|sequence)$/) {
- $pbmap = &Apache::lonnet::deversion((&Apache::lonnet::decode_symb($launchsymb))[2]);
+ if ($pbsymb =~ /\.(page|sequence)$/) {
+ $pbmap = &Apache::lonnet::deversion((&Apache::lonnet::decode_symb($pbsymb))[2]);
} else {
- $pbmap = &Apache::lonnet::deversion((&Apache::lonnet::decode_symb($launchsymb))[0]);
+ $pbmap = &Apache::lonnet::deversion((&Apache::lonnet::decode_symb($pbsymb))[0]);
}
$pbmap = &Apache::lonnet::clutter($pbmap);
my $pbscope;
@@ -1331,13 +1332,13 @@ sub do_passback {
my $numstudents = scalar(keys(%tosend));
my %prog_state = &Apache::lonhtmlcommon::Create_PrgWin($request,$numstudents);
my $outcome = &Apache::loncommon::start_data_table().
- &Apache::loncommon::start_data_table_header_row();
+ &Apache::loncommon::start_data_table_header_row();
my $loop = 0;
while ($loop < 2) {
$outcome .= '
';
+ $loop++;
}
$outcome .= &Apache::loncommon::end_data_table_header_row()."\n";
my $ctr=0;
@@ -1364,14 +1365,14 @@ sub do_passback {
$possible = 0;
my $navmap = Apache::lonnavmaps::navmap->new($uname,$udom);
if (ref($navmap)) {
- my $res = $navmap->getBySymb($launchsymb);
+ my $res = $navmap->getBySymb($pbsymb);
if (ref($res)) {
my $partlist = $res->parts();
if (ref($partlist) eq 'ARRAY') {
- my %record = &Apache::lonnet::restore($launchsymb,$env{'request.course.id'},$udom,$uname);
+ my %record = &Apache::lonnet::restore($pbsymb,$env{'request.course.id'},$udom,$uname);
foreach my $part (@{$partlist}) {
next if ($record{"resource.$part.solved"} =~/^excused/);
- my $weight = &Apache::lonnet::EXT("resource.$part.weight",$launchsymb,$udom,$uname,$usec);
+ my $weight = &Apache::lonnet::EXT("resource.$part.weight",$pbsymb,$udom,$uname,$usec);
$possible += $weight;
if (($record{'version'}) && (exists($record{"resource.$part.awarded"}))) {
my $awarded = $record{"resource.$part.awarded"};
@@ -1385,7 +1386,7 @@ sub do_passback {
}
} elsif (($pbscope eq 'map') || ($pbscope eq 'nonrec')) {
($total,$possible) =
- &Apache::lonhomework::get_lti_score($uname,$udom,$usec,$pbmap,$pbscope);
+ &Apache::lonhomework::get_lti_score($uname,$udom,$pbmap,$pbscope);
}
if (($id ne '') && ($url ne '') && ($possible)) {
my ($sent,$score,$code,$result) =
@@ -1407,23 +1408,24 @@ sub do_passback {
'id' => $id,
'clientip' => $pb{'clientip'},
'whodoneit' => $env{'user.name'}.':'.$env{'user.domain'},
- };
+ };
my $value='';
foreach my $key (keys(%{$store})) {
$value.=&escape($key).'='.&Apache::lonnet::freeze_escape($store->{$key}).'&';
}
$value=~s/\&$//;
&Apache::lonnet::courselog(&escape($linkuri).':'.$uname.':'.$udom.':EXPORT:'.$value);
- &Apache::lonnet::store_userdata({'score' => $score},$chosen,$namespace,$udom,$uname,$pb{'ip'});
+ &Apache::lonnet::cstore({'score' => $score},$chosen,$namespace,$udom,$uname,'',$pb{'ip'},1);
$ctr++;
if ($ctr%2 ==1) {
$outcome .= &Apache::loncommon::start_data_table_row();
}
+ my $section = $classlist->{$student}->[&Apache::loncoursedata::CL_SECTION()];
my $group = $classlist->{$student}->[&Apache::loncoursedata::CL_GROUP()];
$outcome .= '
'.$ctr.'
'.
- '
'.&nameUserString(undef,$$fullname{$student},$uname,$udom).
- ' '.$usec.($group ne '' ?'/'.$group:'').'
'.
- '
'.$score.'
'."\n";
+ '
'.&nameUserString(undef,$$fullname{$student},$uname,$udom).
+ ' '.$section.($group ne '' ?'/'.$group:'').'
'.
+ '
'.$score.'
'."\n";
if ($ctr%2 ==0) {
$outcome .= &Apache::loncommon::end_data_table_row()."\n";
}
@@ -1440,7 +1442,7 @@ sub do_passback {
if ($no_passback) {
&Apache::lonnet::log($udom,$uname,$uhome,$no_passback." score: $score; total: $total; possible: $possible");
my $key = &Time::HiRes::time().':'.$uname.':'.$udom.':'.
- "$linkuri\0$linkprotector\0$scope";
+ "$linkuri\0$linkprotector\0$scope";
my $ltigrade = {
$key => {
'ltinum' => $ltinum,
@@ -1455,7 +1457,7 @@ sub do_passback {
'pbtype' => $pb{'type'},
'pbscope' => $pbscope,
'pbmap' => $pbmap,
- 'pbsymb' => $launchsymb,
+ 'pbsymb' => $pbsymb,
'format' => $scoretype,
'scope' => $scope,
'clientip' => $pb{'clientip'},
@@ -1577,27 +1579,31 @@ sub get_passback_launcher {
}
}
}
- my $launchsymb = &Apache::loncommon::symb_from_tinyurl($linkuri,$cnum,$cdom);
- if ($launchsymb eq '') {
- my %passback = &Apache::lonnet::dump('nohist_linkprot_passback',$cdom,$cnum);
- foreach my $poss_symb (keys(%passback)) {
- if (ref($passback{$poss_symb}) eq 'HASH') {
- if (exists($passback{$poss_symb}{$chosen})) {
- $launchsymb = $poss_symb;
- last;
+ if ($linkuri =~ m{^\Q/tiny/$cdom/\E(\w+)$}) {
+ my $key = $1;
+ my $tinyurl;
+ my ($result,$cached)=&Apache::lonnet::is_cached_new('tiny',$cdom."\0".$key);
+ if (defined($cached)) {
+ $tinyurl = $result;
+ } else {
+ my $configuname = &Apache::lonnet::get_domainconfiguser($cdom);
+ my %currtiny = &Apache::lonnet::get('tiny',[$key],$cdom,$configuname);
+ if ($currtiny{$key} ne '') {
+ $tinyurl = $currtiny{$key};
+ &Apache::lonnet::do_cache_new('tiny',$cdom."\0".$key,$currtiny{$key},600);
+ }
+ }
+ if ($tinyurl) {
+ my ($crsnum,$launchsymb) = split(/\&/,$tinyurl);
+ if ($crsnum eq $cnum) {
+ my %passback = &Apache::lonnet::get('nohist_linkprot_passback',[$launchsymb],$cdom,$cnum);
+ if (ref($passback{$launchsymb}) eq 'HASH') {
+ if (exists($passback{$launchsymb}{$chosen})) {
+ return ($launchsymb,$appname,$setter);
+ }
}
}
}
- if ($launchsymb ne '') {
- return ($launchsymb,$appname,$setter);
- }
- } else {
- my %passback = &Apache::lonnet::get('nohist_linkprot_passback',[$launchsymb],$cdom,$cnum);
- if (ref($passback{$launchsymb}) eq 'HASH') {
- if (exists($passback{$launchsymb}{$chosen})) {
- return ($launchsymb,$appname,$setter);
- }
- }
}
return ();
}
@@ -1660,7 +1666,7 @@ sub launcher_info_box {
$appname.' '.$setter.
&Apache::lonhtmlcommon::row_closure().
&Apache::lonhtmlcommon::row_title(&mt('Score Type')).
- $shownscope.
+ $shownscope.
&Apache::lonhtmlcommon::row_closure(1).
&Apache::lonhtmlcommon::end_pick_box().''."\n";
}
@@ -1677,7 +1683,7 @@ sub passbacks_for_symb {
}
if (ref($passback{$symb}) eq 'HASH') {
foreach my $launcher (keys(%{$passback{$symb}})) {
- $needpb{$launcher} = $symb;
+ $needpb{$launcher} = 1;
}
}
}
@@ -1694,7 +1700,7 @@ sub passbacks_for_symb {
}
if (ref($passback{$mapsymb}) eq 'HASH') {
foreach my $launcher (keys(%{$passback{$mapsymb}})) {
- $needpb{$launcher} = $mapsymb;
+ $needpb{$launcher} = 1;
}
}
}
@@ -1711,7 +1717,7 @@ sub passbacks_for_symb {
foreach my $launcher (keys(%{$passback{$key}})) {
my ($linkuri,$linkprotector,$scope) = split("\0",$launcher);
next unless ($scope eq 'rec');
- $needpb{$launcher} = $key;
+ $needpb{$launcher} = 1;
}
}
}
@@ -1776,7 +1782,7 @@ sub process_passbacks {
if ($pb{'lti_in_use'}->{'scoreformat'} =~ /^(decimal|ratio|percentage)$/) {
$pb{'scoretype'} = $1;
}
- $pb{'symb'} = $needpb->{$launcher};
+ $pb{'symb'} = &Apache::loncommon::symb_from_tinyurl($pb{'linkuri'},$cnum,$cdom);
if ($pb{'symb'} =~ /\.(page|sequence)$/) {
$pb{'map'} = &Apache::lonnet::deversion((&Apache::lonnet::decode_symb($pb{'symb'}))[2]);
} else {
@@ -1848,7 +1854,7 @@ sub process_passbacks {
$possible = $possible_by_symb{$pb{'symb'}};
} elsif (($pb{'pbscope'} eq 'map') || ($pb{'pbscope'} eq 'nonrec')) {
($total,$possible) =
- &Apache::lonhomework::get_lti_score($uname,$udom,$usec,$pb{'map'},$pb{'pbscope'},
+ &Apache::lonhomework::get_lti_score($uname,$udom,$pb{'map'},$pb{'pbscope'},
\%total_by_symb,\%possible_by_symb);
}
if (!$possible) {
@@ -1881,7 +1887,7 @@ sub process_passbacks {
}
$value=~s/\&$//;
&Apache::lonnet::courselog(&escape($pb{'linkuri'}).':'.$uname.':'.$udom.':EXPORT:'.$value);
- &Apache::lonnet::store_userdata({'score' => $score},$launcher,$namespace,$udom,$uname,$pb{'ip'});
+ &Apache::lonnet::cstore({'score' => $score},$launcher,$namespace,$udom,$uname,'',$pb{'ip'},1);
} else {
$no_passback = 1;
}
@@ -2719,6 +2725,7 @@ INNERJS
function msgTail() {
pDoc = pWin.document;
+ //pDoc.write("<\\/table>");
pDoc.write("<\\/td><\\/tr><\\/table> ");
pDoc.write(" ");
pDoc.write("
");
@@ -3038,7 +3045,7 @@ sub handback_box {
if ($file =~ /\/portfolio\//) {
$file_counter++;
my ($file_path, $file_disp) = ($file =~ m|(.+/)(.+)$|);
- my ($name,$version,$ext) = &file_name_version_ext($file_disp);
+ my ($name,$version,$ext) = &Apache::lonnet::file_name_version_ext($file_disp);
$file_disp = "$name.$ext";
$file = $file_path.$file_disp;
$result.=&mt('Return commented version of [_1] to student.',
@@ -3250,7 +3257,7 @@ sub submission {
}
if (!$env{'form.lastSub'}) { $env{'form.lastSub'} = 'datesub'; }
- unless ($is_tool) {
+ unless ($is_tool) {
if (!$env{'form.vProb'}) { $env{'form.vProb'} = 'yes'; }
if (!$env{'form.vAns'}) { $env{'form.vAns'} = 'yes'; }
}
@@ -3489,7 +3496,7 @@ sub submission {
}
if ($env{'form.lastSub'} =~ /^(last|all)$/) {
my $identifier = (&canmodify($usec)? $counter : '');
- $request->print(&Apache::loncommon::get_previous_attempt($symb,$uname,$udom,
+ $request->print(&Apache::loncommon::get_previous_attempt($symb,$uname,$udom,
$env{'request.course.id'},
$last,'.submission',
'Apache::grades::keywords_highlight',
@@ -3499,8 +3506,8 @@ sub submission {
.$udom.'" />'."\n");
# return if view submission with no grading option
if (!&canmodify($usec)) {
- $request->print('
'.&mt('No grading privileges').'
');
- return;
+ $request->print('
'.&mt('No grading privileges').'
');
+ return;
} else {
$request->print(''."\n");
}
@@ -3520,7 +3527,7 @@ sub submission {
$msgfor =~ s/\'/\\'/g; #' stupid emacs - no! javascript
$result.=''."\n".
''."\n".
- ' '.
&mt('Compose message to student'.(scalar(@$col_fullnames) >= 1 ? 's' : '')).')'.
@@ -3528,7 +3535,7 @@ sub submission {
'/mailbkgrd.gif" width="14" height="10" alt="" name="mailicon'.$counter.'" />'."\n".
' ('.
&mt('Message will be sent when you click on Save & Next below.').")\n".
- '';
+ '';
$request->print($result);
}
@@ -3881,7 +3888,7 @@ sub get_last_submission {
if ($solved{$partid} ne '') {
$prevsolved{$partid} = $solved{$partid};
}
- }
+ }
}
#
# Timestamp is for last transaction for this resource, which does not
@@ -3982,11 +3989,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';
@@ -4190,7 +4198,7 @@ sub processHandGrade {
next;
}
if ($errorflag eq 'not_allowed') {
- $request->print(
+ $request->print(
''
.&mt('Not allowed to modify grades for [_1]',"$uname:$udom")
.'');
@@ -4243,22 +4251,22 @@ sub processHandGrade {
if ($errorflag eq 'not_allowed') {
$request->print("".&mt('Not allowed to modify grades for [_1]',"$collaborator:$udom")."");
next;
- } else {
- if ($numchg || $numupdate) {
+ } else {
+ if ($numchg || $numupdate) {
$pbcollab{$collaborator}{$part} = [$pts,$wgt];
}
if ($message ne '') {
- my ($baseurl,$showsymb) =
- &get_feedurl_and_symb($symb,$collaborator,
- $udom);
- if ($env{'form.withgrades'.$ctr}) {
- $messagetail = " for $restitle";
- }
- $msgstatus =
- &Apache::lonmsg::user_normal_msg($collaborator,$udom,$subject,$message.$messagetail,undef,$baseurl,undef,undef,undef,$showsymb,$restitle);
- }
- }
+ }
+ $msgstatus =
+ &Apache::lonmsg::user_normal_msg($collaborator,$udom,$subject,$message.$messagetail,undef,$baseurl,undef,undef,undef,$showsymb,$restitle);
+ }
+ }
}
}
}
@@ -4267,7 +4275,7 @@ sub processHandGrade {
if ((keys(%pbcollab)) && (keys(%needpb))) {
foreach my $user (keys(%pbcollab)) {
my ($clbuname,$clbudom) = split(/:/,$user);
- my $clbusec = &Apache::lonnet::getsection($clbudom,$clbuname,$cdom.'_'.$cnum);
+ my $clbusec = &Apache::lonnet::getsection($clbudom,$clbuname,$cdom.'_'.$cnum);
if (ref($pbcollab{$user}) eq 'HASH') {
my @clparts = keys(%{$pbcollab{$user}});
if (@clparts) {
@@ -4281,7 +4289,7 @@ sub processHandGrade {
foreach my $part (@{$partlist}) {
if ($res->status($part) eq $res->EXCUSED) {
$excuseds{$symb}{$part} = 1;
- } else {
+ } else {
$excuseds{$symb}{$part} = '';
}
if ((exists($pbcollab{$user}{$part})) && (ref($pbcollab{$user}{$part}) eq 'ARRAY')) {
@@ -4340,9 +4348,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++;
}
@@ -4350,8 +4358,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
@@ -4453,7 +4461,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 '';
@@ -4671,19 +4679,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,
@@ -4701,8 +4709,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}.''));
}
@@ -4713,7 +4720,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');
@@ -4833,29 +4840,14 @@ 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);
@@ -4864,64 +4856,6 @@ sub version_portfiles {
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);
-}
-
#--------------------------------------------------------------------------------------
#
#-------------------------- Next few routines handles grading by section or whole class
@@ -5167,7 +5101,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)) {
@@ -5180,7 +5114,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);
@@ -5194,7 +5128,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();
@@ -5251,10 +5185,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;
@@ -6029,13 +5963,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) {
@@ -6072,8 +6005,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(<
@@ -6087,7 +6018,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; }
@@ -6125,11 +6056,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 $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
@@ -6173,13 +6103,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");
@@ -6212,7 +6174,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;
@@ -6261,7 +6223,7 @@ sub csvuploadassign {
$request->print('.');
# Remove from grading queue
&Apache::bridgetask::remove_from_queue('gradingqueue',$symb,$cdom,$cnum,
- $domain,$username);
+ $domain,$username);
$countdone++;
if ($passback) {
my @parts_in_upload;
@@ -6286,7 +6248,7 @@ sub csvuploadassign {
&process_passbacks('csvupload',[$symb],$cdom,$cnum,$domain,$username,$usec,\%weights,
\%awardeds,\%excuseds,\%needpb,\%skip_passback,\%pbsave);
}
- } else {
+ } else {
$request->print("
".
&mt("Failed to save data for student [_1]. Message when trying to save was: [_2]",
"$username:$domain",$result)."