Part: '.
$display_part.' ( ID '.$respid.
' ) ';
- my @files;
- if ($record{"resource.$partid.$respid.portfiles"}) {
- my $file_url = '/uploaded/'.$udom.'/'.$uname.'/portfolio';
- foreach my $file (split(',',$record{"resource.$partid.$respid.portfiles"})) {
- push(@files,$file_url.$file);
-
- &Apache::lonnet::logthis("found a portfolio file".$record{"resource.$partid.$respid.portfiles"});
- &Apache::lonnet::logthis("uploaded URL file".$record{"resource.$partid.$respid.uploadedurl"});
- }
- }
- if ($record{"resource.$partid.$respid.uploadedurl"}) {
- push(@files,$record{"resource.$partid.$respid.uploadedurl"});
- }
- if (@files) {
+ my $files=&get_submitted_files($udom,$uname,$partid,$respid,\%record);
+ if (@$files) {
$lastsubonly.='Like all files provided by users, this file may contain virusses ';
- foreach my $file (@files) {
+ my $file_counter = 0;
+ foreach my $file (@$files) {
+ $file_counter ++;
&Apache::lonnet::allowuploaded('/adm/grades',$file);
- $lastsubonly.=' '.$file.' ';
+ $lastsubonly.=' '.$file.' ';
}
$lastsubonly.=' ';
}
@@ -1822,26 +1892,40 @@ KEYWORDS
' '."\n";
$result.=' '.
- 'Compose Message to student'.(scalar(@col_fullnames) >= 1 ? 's' : '').' '.
+ &mt('Compose message to student').(scalar(@col_fullnames) >= 1 ? 's' : '').' ('.
+ &mt('incl. grades').' )'.
' '."\n".
- ' (Message will be sent when you click on Save & Next below.)'."\n"
- if ($env{'form.handgrade'} eq 'yes');
+ ' ('.
+ &mt('Message will be sent when you click on Save & Next below.').")\n";
$request->print($result);
}
+ if ($perm{'vgr'}) {
+ $request->print(' '.
+ &Apache::loncommon::track_student_link(&mt('View recent activity'),
+ $uname,$udom,'check'));
+ }
+ if ($perm{'opa'}) {
+ $request->print(' '.
+ &Apache::loncommon::pprmlink(&mt('Set/Change parameters'),
+ $uname,$udom,$symb,'check'));
+ }
my %seen = ();
my @partlist;
my @gradePartRespid;
- for (sort keys(%$handgrade)) {
- my ($partid,$respid) = split(/_/);
- next if ($seen{$partid} > 0);
+ for my $part_resp(sort keys(%$handgrade)) {
+ my ($partid,$respid) = split(/_/, $part_resp);
+ #next if ($seen{$partid} > 0);
+ if ($seen{$partid} > 0) {
+ $request->print(&handbackBox($uname,$udom,$counter,$partid,\%record,$respid));
+ next;
+ }
$seen{$partid}++;
- next if ($$handgrade{$_} =~ /:no$/ && $env{'form.lastSub'} =~ /^(hdgrade)$/);
+ next if ($$handgrade{$part_resp} =~ /:no$/ && $env{'form.lastSub'} =~ /^(hdgrade)$/);
push @partlist,$partid;
push @gradePartRespid,$partid.'.'.$respid;
-
- $request->print(&gradeBox($request,$symb,$uname,$udom,$counter,$partid,\%record));
+ $request->print(&gradeBox($request,$symb,$uname,$udom,$counter,$partid,\%record,$respid));
}
$result=' '."\n";
@@ -1927,6 +2011,9 @@ sub processHandGrade {
my $button = $env{'form.gradeOpt'};
my $ngrade = $env{'form.NCT'};
my $ntstu = $env{'form.NTSTU'};
+ my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+ my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+
if ($button eq 'Save & Next') {
my $ctr = 0;
while ($ctr < $ngrade) {
@@ -1944,35 +2031,40 @@ sub processHandGrade {
my $includemsg = $env{'form.includemsg'.$ctr};
my ($subject,$message,$msgstatus) = ('','','');
if ($includemsg =~ /savemsg|newmsg\Q$ctr\E/) {
- $subject = $env{'form.msgsub'} if ($includemsg =~ /^msgsub/);
+ $subject = $env{'form.msgsub'} if ($includemsg =~ /msgsub/);
+ unless ($subject=~/\w/) { $subject=&mt('Grading Feedback'); }
my (@msgnum) = split(/,/,$includemsg);
foreach (@msgnum) {
$message.=$env{'form.'.$_} if ($_ =~ /savemsg|newmsg/ && $_ ne '');
}
$message =&Apache::lonfeedback::clear_out_html($message);
- $message.="\n\nPoint".($pts > 1 ? 's':'').' awarded = '.$pts.' out of '.$wgt;
- $message.=" for 1 ? 's':'').' awarded = '.$pts.' out of '.$wgt;
+ $message.=" for $env{'form.probTitle'} ";
+ }
$msgstatus = &Apache::lonmsg::user_normal_msg ($uname,$udom,
- $env{'form.msgsub'},$message);
+ $subject.' ['.
+ &Apache::lonnet::declutter($url).']',$message);
+ $request->print(' '.&mt('Sending message to [_1]@[_2]',$uname,$udom).': '.
+ $msgstatus);
}
if ($env{'form.collaborator'.$ctr}) {
my @collabstrs=&Apache::loncommon::get_env_multiple("form.collaborator$ctr");
foreach my $collabstr (@collabstrs) {
my ($part,@collaborators) = split(/:/,$collabstr);
- foreach (@collaborators) {
+ foreach my $collaborator (@collaborators) {
my ($errorflag,$pts,$wgt) =
- &saveHandGrade($request,$url,$symb,$_,$udom,$ctr,
+ &saveHandGrade($request,$url,$symb,$collaborator,$udom,$ctr,
$env{'form.unamedom'.$ctr},$part);
if ($errorflag eq 'not_allowed') {
- $request->print("Not allowed to modify grades for $_:$udom ");
+ $request->print("Not allowed to modify grades for $collaborator:$udom ");
next;
} else {
if ($message ne '') {
- $msgstatus = &Apache::lonmsg::user_normal_msg($_,$udom,$env{'form.msgsub'},$message);
+ $msgstatus = &Apache::lonmsg::user_normal_msg($collaborator,$udom,$env{'form.msgsub'},$message);
}
-
}
}
}
@@ -2018,9 +2110,7 @@ sub processHandGrade {
$env{'form.savemsgN'} = --$idx;
$keyhash{$symb.'_savemsgN'} = $env{'form.savemsgN'};
my $putresult = &Apache::lonnet::put
- ('nohist_handgrade',\%keyhash,
- $env{'course.'.$env{'request.course.id'}.'.domain'},
- $env{'course.'.$env{'request.course.id'}.'.num'});
+ ('nohist_handgrade',\%keyhash,$cdom,$cnum);
}
# Called by Save & Refresh from Highlight Attribute Window
my (undef,undef,$fullname) = &getclasslist($env{'form.section'},'1');
@@ -2064,7 +2154,13 @@ sub processHandGrade {
my (@parsedlist,@nextlist);
my ($nextflg) = 0;
- foreach (sort {lc($$fullname{$a}) cmp lc($$fullname{$b}) } keys %$fullname) {
+ foreach (sort
+ {
+ if (lc($$fullname{$a}) ne lc($$fullname{$b})) {
+ return (lc($$fullname{$a}) cmp lc($$fullname{$b}));
+ }
+ return $a cmp $b;
+ } (keys(%$fullname))) {
if ($nextflg == 1 && $button =~ /Next$/) {
push @parsedlist,$_;
}
@@ -2080,6 +2176,14 @@ sub processHandGrade {
foreach my $student (@parsedlist) {
my $submitonly=$env{'form.submitonly'};
my ($uname,$udom) = split(/:/,$student);
+
+ if ($submitonly eq 'queued') {
+ my %queue_status =
+ &Apache::bridgetask::get_student_status($symb,$cdom,$cnum,
+ $udom,$uname);
+ next if (!defined($queue_status{'gradingqueue'}));
+ }
+
if ($submitonly =~ /^(yes|graded|incorrect)$/) {
# my %record = &Apache::lonnet::restore($symb,$env{'request.course.id'},$udom,$uname);
my %status=&student_gradeStatus($url,$symb,$udom,$uname,$partlist);
@@ -2121,7 +2225,7 @@ sub processHandGrade {
my $the_end = 'LON-CAPA User Message '."\n";
$the_end.='Message: No more students for this section or class. '."\n";
$the_end.='Click on the button below to return to the grading menu. '."\n";
- $the_end.=&show_grading_menu_form ($symb,$url);
+ $the_end.=&show_grading_menu_form($symb,$url);
$request->print($the_end);
}
return '';
@@ -2140,7 +2244,9 @@ sub saveHandGrade {
my ($pts,$wgt) = ('','');
my %aggregate = ();
my $aggregateflag = 0;
- foreach my $new_part (split(/:/,$env{'form.partlist'.$newflg})) {
+
+ my @parts = split(/:/,$env{'form.partlist'.$newflg});
+ foreach my $new_part (@parts) {
#collaborator may vary for different parts
if ($submitter && $new_part ne $part) { next; }
my $dropMenu = $env{'form.GD_SEL'.$newflg.'_'.$new_part};
@@ -2210,26 +2316,78 @@ sub saveHandGrade {
$newrecord{'resource.'.$new_part.'.regrader'}=
"$env{'user.name'}:$env{'user.domain'}";
}
+ if ($env{'form.part'.$new_part.'_returndoc1'}) {
+ # if multiple files are uploaded names will be 'returndoc2','returndoc3'
+
+ my $portfolio_root = &Apache::loncommon::propath($domain,
+ $stuname).
+ '/userfiles/portfolio';
+ $request->print(' '.$portfolio_root.' ');
+
+ # my $result=&Apache::lonnet::userfileupload('uploaddoc','',
+ # 'portfolio'.$env{'form.currentpath'});
+
+ my $file_counter = 1;
+ my $respid = $env{'form.respid'};
+ while ($env{'form.part'.$new_part.'_returndoc'.$file_counter}) {
+ my $fname=$env{'form.returndoc'.$file_counter.'.filename'};
+ $newrecord{"resource.$new_part.$respid.handback"} = $env{'form.returndocorig'.$file_counter};
+ $request->print(" ".$fname." will be the uploaded file name");
+ $request->print("Will upload document ".$env{'form.returndocorig'.$file_counter});
+ $file_counter++;
+ }
+ }
+
# unless problem has been graded, set flag to version the submitted files
- unless ($record{'resource.'.$new_part.'.solved'} =~ /^correct_/ || $record{'resource.'.$new_part.'.solved'} eq 'incorrect_by_override') {
+ unless ($record{'resource.'.$new_part.'.solved'} =~ /^correct_/ ||
+ $record{'resource.'.$new_part.'.solved'} eq 'incorrect_by_override' ||
+ $dropMenu eq 'reset status')
+ {
push (@v_flag,$new_part);
}
}
+ my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+ my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+
if (scalar(keys(%newrecord)) > 0) {
if (scalar(@v_flag)) {
&version_portfiles(\%record, \@parts_graded, $env{'request.course.id'}, $symb, $domain, $stuname, \@v_flag);
}
&Apache::lonnet::cstore(\%newrecord,$symb,
$env{'request.course.id'},$domain,$stuname);
+
+ my @ungraded_parts;
+ foreach my $part (@parts) {
+ if ( !defined($record{'resource.'.$part.'.awarded'})
+ && !defined($newrecord{'resource.'.$part.'.awarded'}) ) {
+ push(@ungraded_parts, $part);
+ }
+ }
+ if ( !@ungraded_parts ) {
+ &Apache::bridgetask::remove_from_queue('gradingqueue',$symb,$cdom,
+ $cnum,$domain,$stuname);
+ }
}
if ($aggregateflag) {
&Apache::lonnet::cinc('nohist_resourcetracker',\%aggregate,
- $env{'course.'.$env{'request.course.id'}.'.domain'},
- $env{'course.'.$env{'request.course.id'}.'.num'});
+ $cdom,$cnum);
}
- return '',$pts,$wgt;
+ return ('',$pts,$wgt);
+}
+sub get_submitted_files {
+ my ($udom,$uname,$partid,$respid,$record) = @_;
+ my @files;
+ if ($$record{"resource.$partid.$respid.portfiles"}) {
+ my $file_url = '/uploaded/'.$udom.'/'.$uname.'/portfolio';
+ foreach my $file (split(',',$$record{"resource.$partid.$respid.portfiles"})) {
+ push(@files,$file_url.$file);
+ }
+ }
+ if ($$record{"resource.$partid.$respid.uploadedurl"}) {
+ push(@files,$$record{"resource.$partid.$respid.uploadedurl"});
+ }
+ return (\@files);
}
-
# ----------- Provides number of tries since last reset.
sub get_num_tries {
my ($record,$last_reset,$part) = @_;
@@ -2291,58 +2449,94 @@ sub get_last_resets {
# ----------- Handles creating versions for portfolio files as answers
sub version_portfiles {
- my ($record, $parts_graded, $courseid, $symb, $domain, $stuname, $v_flag) = @_;
+ my ($record, $parts_graded, $courseid, $symb, $domain, $stu_name, $v_flag) = @_;
my $version_parts = join('|',@$v_flag);
my $parts = join('|', @$parts_graded);
my $portfolio_root = &Apache::loncommon::propath($domain,
- $stuname).
+ $stu_name).
'/userfiles/portfolio';
foreach my $key (keys(%$record)) {
my $new_portfiles;
-
if ($key =~ /^resource\.($version_parts)\./ && $key =~ /\.portfiles$/ ) {
my @v_portfiles;
my @portfiles = split(/,/,$$record{$key});
- &Apache::lonnet::logthis("should be unmarking and remarking $key",@portfiles);
foreach my $file (@portfiles) {
- &Apache::lonnet::unmark_as_readonly($domain,$stuname,[$symb,$env{'request.course.id'}],$file);
- my ($directory,$answer_file) =($file =~ /^(.*?)([^\/]*$)/);
+ &Apache::lonnet::unmark_as_readonly($domain,$stu_name,[$symb,$env{'request.course.id'}],$file);
+ my ($directory,$answer_file) =($file =~ /^(.*?)([^\/]*)$/);
my $version = 0;
- my @answer_file_parts = split(/\./, $answer_file);
- my @dir_list = &Apache::lonnet::dirlist($directory,$domain,$stuname,$portfolio_root);
- my @file_names;
- my @file_name_parts;
- foreach my $row (@dir_list) {
- @file_names = split(/\&/,$row,2);
- @file_name_parts = split(/\./, $file_names[0]);
- # ($file_name_parts[scalar @file_name_parts] eq $answer_file_parts[scalar @answer_file_parts])
- if (($file_name_parts[0] eq $answer_file_parts[0]) &&
- ($file_name_parts[-1] eq $answer_file_parts[-1])) {
- # gets here if filename and extension match, regardless of version
- if (scalar @file_name_parts == 3) { # a versioned file is found
- # so save it for later
- if ($file_name_parts[1] > $version) {$version = $file_name_parts[1]};
- }
- }
- }
- $version++;
- $env{'form.copy'} = &Apache::lonnet::getfile("/uploaded/$domain/$stuname/portfolio$directory$answer_file");
- if($env{'form.copy'} eq '-1') {
- &Apache::lonnet::logthis('problem getting file '.$directory.$answer_file);
- } else {
- my $copy_result = &Apache::lonnet::finishuserfileupload($stuname,$domain,'copy',
- '/portfolio'.$directory.$answer_file_parts[0].'.'.$version.'.'.$answer_file_parts[-1]);
- push(@v_portfiles, $directory.$answer_file_parts[0].'.'.$version.'.'.$answer_file_parts[-1]);
- &Apache::lonnet::mark_as_readonly($domain,$stuname,
- ['/portfolio'.$directory.$answer_file_parts[0].'.'.$version.'.'.$answer_file_parts[-1]],
- [$symb,$env{'request.course.id'},'graded']);
+ my ($answer_name,$answer_ver,$answer_ext) =
+ &file_name_version_ext($answer_file);
+ my @dir_list = &Apache::lonnet::dirlist($directory,$domain,$stu_name,$portfolio_root);
+ $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(@v_portfiles, $directory.$new_answer);
+ &Apache::lonnet::mark_as_readonly($domain,$stu_name,
+ ['/portfolio'.$directory.$new_answer],
+ [$symb,$env{'request.course.id'},'graded']);
}
+
}
$$record{$key} = join(',',@v_portfiles);
}
}
return 'ok';
-
+}
+
+sub get_next_version {
+ my ($answer_name, $answer_ext, $dir_list);
+ my $version;
+ 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') {
+ &Apache::lonnet::logthis('problem getting file '.$file_name);
+ $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);
}
#--------------------------------------------------------------------------------------
@@ -2642,7 +2836,13 @@ sub viewgrades {
#list all the students - with points and grade status
my (undef,undef,$fullname) = &getclasslist($env{'form.section'},'1');
my $ctr = 0;
- foreach (sort {lc($$fullname{$a}) cmp lc($$fullname{$b}) } keys %$fullname) {
+ foreach (sort
+ {
+ if (lc($$fullname{$a}) ne lc($$fullname{$b})) {
+ return (lc($$fullname{$a}) cmp lc($$fullname{$b}));
+ }
+ return $a cmp $b;
+ } (keys(%$fullname))) {
$ctr++;
$result.=&viewstudentgrade($url,$symb,$env{'request.course.id'},
$_,$$fullname{$_},\@parts,\%weight,$ctr,\%last_resets);
@@ -2693,7 +2893,7 @@ sub viewstudentgrade {
$aggregates{$part} = 1;
}
if ($type eq 'awarded') {
- my $pts = $score eq '' ? '' : $score*$$weight{$part};
+ my $pts = $score eq '' ? '' : &compute_points($score,$$weight{$part});
$result.=' '."\n";
$result.=' nothing to reset
- $newrecord{'resource.'.$_.'.tries'} = 0;
+ $newrecord{'resource.'.$_.'.tries'} = '';
$newrecord{'resource.'.$_.'.solved'} = '';
$newrecord{'resource.'.$_.'.award'} = '';
- $newrecord{'resource.'.$_.'.awarded'} = 0;
- $newrecord{'resource.'.$_.'.regrader'}="$env{'user.name'}:$env{'user.domain'}";
+ $newrecord{'resource.'.$_.'.awarded'} = '';
$updateflag = 1;
if ($env{'form.GD_'.$user.'_'.$_.'_aggtries'} > 0) {
my $aggtries = $env{'form.GD_'.$user.'_'.$_.'_aggtries'};
@@ -2870,10 +3071,38 @@ sub editgrades {
}
}
$line.=' '."\n";
+
+ my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+ my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+
if ($updateflag) {
$count++;
&Apache::lonnet::cstore(\%newrecord,$symb,$env{'request.course.id'},
$udom,$uname);
+
+ if (&Apache::bridgetask::in_queue('gradingqueue',$symb,$cdom,
+ $cnum,$udom,$uname)) {
+ # need to figure out if should be in queue.
+ my %record =
+ &Apache::lonnet::restore($symb,$env{'request.course.id'},
+ $udom,$uname);
+ my $all_graded = 1;
+ my $none_graded = 1;
+ foreach my $part (@parts) {
+ if ( $record{'resource.'.$part.'.awarded'} eq '' ) {
+ $all_graded = 0;
+ } else {
+ $none_graded = 0;
+ }
+ }
+
+ if ($all_graded || $none_graded) {
+ &Apache::bridgetask::remove_from_queue('gradingqueue',
+ $symb,$cdom,$cnum,
+ $udom,$uname);
+ }
+ }
+
$result.='