--- loncom/homework/grades.pm 2004/11/13 09:42:38 1.226 +++ loncom/homework/grades.pm 2005/04/04 23:56:44 1.256 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # The LON-CAPA Grading handler # -# $Id: grades.pm,v 1.226 2004/11/13 09:42:38 albertel Exp $ +# $Id: grades.pm,v 1.256 2005/04/04 23:56:44 banghart Exp $ # # Copyright Michigan State University Board of Trustees # @@ -96,7 +96,7 @@ sub get_symb_and_url { sub nameUserString { my ($type,$fullname,$uname,$udom) = @_; if ($type eq 'header') { - return ' Fullname (Username) '; + return ' Fullname (Username)'; } else { return ' '.$fullname.' ('.$uname. ($ENV{'user.domain'} eq $udom ? '' : ' ('.$udom.')').')'; @@ -664,17 +664,21 @@ LISTJAVASCRIPT $gradeTable.='To '.lc($viewgrade).' a submission or a group of submissions, click on the check box(es) '. 'next to the student\'s name(s). Then click on the Next button.
'."\n". ''."\n"; + +# checkall buttons + $gradeTable.=&check_script('gradesub', 'stuinfo'); $gradeTable.=''."\n"; + 'value="Next->" />
'."\n"; + $gradeTable.=&check_buttons(); $gradeTable.='Check For Plagiarism'; - my (undef, undef, $fullname) = &getclasslist($getsec,'1'); + my ($classlist, undef, $fullname) = &getclasslist($getsec,'1'); $gradeTable.='
'. ''; my $loop = 0; while ($loop < 2) { $gradeTable.=''. - ''; + ''; if ($ENV{'form.showgrading'} eq 'yes' && $submitonly ne 'all') { foreach (sort(@$partlist)) { my $display_part=&get_display_part((split(/_/))[0],$url,$symb); @@ -695,10 +699,12 @@ LISTJAVASCRIPT (%status) =&student_gradeStatus($url,$symb,$udom,$uname,$partlist); my $submitted = 0; my $graded = 0; + my $incorrect = 0; foreach (keys(%status)) { $submitted = 1 if ($status{$_} ne 'nothing'); - $graded = 1 if ($status{$_} !~ /^correct/); - + $graded = 1 if ($status{$_} =~ /^ungraded/); + $incorrect = 1 if ($status{$_} =~ /^incorrect/); + my ($foo,$partid,$foo1) = split(/\./,$_); if ($status{'resource.'.$partid.'.submitted_by'} ne '') { $submitted = 0; @@ -708,20 +714,25 @@ LISTJAVASCRIPT $status{'resource.'.$partid.'.submitted_by'}.'" />'; } } + next if (!$submitted && ($submitonly eq 'yes' || $submitonly eq 'incorrect' || $submitonly eq 'graded')); - next if (!$graded && ($submitonly eq 'graded' || - $submitonly eq 'incorrect')); + next if (!$graded && ($submitonly eq 'graded')); + next if (!$incorrect && $submitonly eq 'incorrect'); } $ctr++; + my $section = $classlist->{$student}->[&Apache::loncoursedata::CL_SECTION()]; + if ( $perm{'vgr'} eq 'F' ) { $gradeTable.='' if ($ctr%2 ==1); $gradeTable.=''. - ''."\n". - ''."\n"; + ''."\n".''."\n"; if ($ENV{'form.showgrading'} eq 'yes' && $submitonly ne 'all') { foreach (sort keys(%status)) { @@ -743,7 +754,7 @@ LISTJAVASCRIPT $gradeTable.=''; } - $gradeTable.='
 No.  Select '.&nameUserString('header').''.&nameUserString('header').' Section/Group
'.$ctr.' '.&nameUserString(undef,$$fullname{$student},$uname,$udom).''. + &nameUserString(undef,$$fullname{$student},$uname,$udom). + ' '.$section.'
'. + $gradeTable.=''."\n". ''."\n"; @@ -768,6 +779,52 @@ LISTJAVASCRIPT } #---- Called from the listStudents routine + +sub check_script { + my ($form, $type)=@_; + my $chkallscript=''."\n"; + return $chkallscript; +} + +sub check_buttons { + my $buttons.=''; + $buttons.=' '; + $buttons.=''; + $buttons.=' '; + return $buttons; +} + # Displays the submissions for one student or a group of students sub processGroup { my ($request) = shift; @@ -973,6 +1030,7 @@ sub sub_page_kw_js { my $iconpath = $request->dir_config('lonIconsURL'); &commonJSfunctions($request); my $docopen=&Apache::lonhtmlcommon::javascript_docopen(); + $docopen=~s/^document\.//; $request->print(< @@ -1670,10 +1728,26 @@ KEYWORDS $lastsubonly.='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"}) { - &Apache::lonnet::allowuploaded('/adm/grades', - $record{"resource.$partid.$respid.uploadedurl"}); - $lastsubonly.=' File uploaded by student Like all files provided by users, this file may contain virusses
'; + push(@files,$record{"resource.$partid.$respid.uploadedurl"}); + } + if (@files) { + $lastsubonly.='
Like all files provided by users, this file may contain virusses
'; + foreach my $file (@files) { + &Apache::lonnet::allowuploaded('/adm/grades',$file); + $lastsubonly.='
'.$file.''; + } + $lastsubonly.='
'; } $lastsubonly.='Submitted Answer: '. &cleanRecord($subval,$responsetype,$symb,$partid, @@ -1989,10 +2063,12 @@ sub processHandGrade { # my %record = &Apache::lonnet::restore($symb,$ENV{'request.course.id'},$udom,$uname); my %status=&student_gradeStatus($url,$symb,$udom,$uname,$partlist); my $submitted = 0; - my $graded = 1; + my $ungraded = 0; + my $incorrect = 0; foreach (keys(%status)) { $submitted = 1 if ($status{$_} ne 'nothing'); - $graded = 0 if ($status{$_} =~ /^correct/); + $ungraded = 1 if ($status{$_} =~ /^ungraded/); + $incorrect = 1 if ($status{$_} =~ /^incorrect/); my ($foo,$partid,$foo1) = split(/\./,$_); if ($status{'resource.'.$partid.'.submitted_by'} ne '') { $submitted = 0; @@ -2001,8 +2077,8 @@ sub processHandGrade { next if (!$submitted && ($submitonly eq 'yes' || $submitonly eq 'incorrect' || $submitonly eq 'graded')); - next if (!$graded && ($submitonly eq 'graded' || - $submitonly eq 'incorrect')); + next if (!$ungraded && ($submitonly eq 'graded')); + next if (!$incorrect && $submitonly eq 'incorrect'); } push @nextlist,$student if ($ctr < $ntstu); last if ($ctr == $ntstu); @@ -2037,6 +2113,7 @@ sub saveHandGrade { $ENV{'request.course.id'}); if (!&canmodify($usec)) { return('not_allowed'); } my %record = &Apache::lonnet::restore($symb,$ENV{'request.course.id'},$domain,$stuname); + my @parts_graded; my %newrecord = (); my ($pts,$wgt) = ('',''); foreach (split(/:/,$ENV{'form.partlist'.$newflg})) { @@ -2071,6 +2148,8 @@ sub saveHandGrade { if ($partial eq $record{'resource.'.$_.'.awarded'}) { #do not update score for part if not changed. next; + } else { + push @parts_graded, $_; } if ($record{'resource.'.$_.'.awarded'} ne $partial) { $newrecord{'resource.'.$_.'.awarded'} = $partial; @@ -2094,12 +2173,62 @@ sub saveHandGrade { } } if (scalar(keys(%newrecord)) > 0) { + &version_portfiles(\%record, \@parts_graded, $ENV{'request.course.id'}, $symb, $domain, $stuname); &Apache::lonnet::cstore(\%newrecord,$symb, $ENV{'request.course.id'},$domain,$stuname); } return '',$pts,$wgt; } +# ----------- Handles creating versions for portfolio files as answers +sub version_portfiles { + my ($record, $parts_graded, $courseid, $symb, $domain, $stuname) = @_; + my $parts = join('|', @$parts_graded); + my $portfolio_root = &Apache::loncommon::propath($domain, + $stuname). + '/userfiles/portfolio'; + foreach my $key(keys %$record) { + if ($key =~ /^resource\.($parts)\./ && $key =~ /\.portfiles$/) { + my @portfiles = split(/,/,$$record{$key}); + foreach my $file (@portfiles) { + 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++; + my $home_server = &Apache::lonnet::homeserver($stuname,$domain,undef); + $ENV{'form.copy'} = &Apache::lonnet::getfile("/uploaded/$domain/$stuname/$directory$answer_file"); + # $ENV{'form.copy.filename'}=''; + my $copy_result = &Apache::lonnet::finishuserfileupload($stuname,$domain,$home_server,'copy', + '/portfolio'.$directory.$answer_file_parts[0].'.'.$version.'.'.$answer_file_parts[-1]); + &Apache::lonnet::logthis('copy result is '.$copy_result); + &Apache::lonnet::logthis('answer file is '.$answer_file. + ' becomes '.$answer_file_parts[0].'.'.$version.'.'.$answer_file_parts[-1]); + &Apache::lonnet::logthis('from dir list is '.$file_names[0].' has '.@file_name_parts.' parts'); + } + &Apache::lonnet::logthis('found key portfiles '.$key); + &Apache::lonnet::logthis('found value portfiles '.$$record{$key}); + } + } + + +} + #-------------------------------------------------------------------------------------- # #-------------------------- Next few routines handles grading by section or whole class @@ -2387,9 +2516,6 @@ sub viewgrades { my (undef,undef,$fullname) = &getclasslist($ENV{'form.section'},'1'); my $ctr = 0; foreach (sort {lc($$fullname{$a}) cmp lc($$fullname{$b}) } keys %$fullname) { - my $uname = $_; - $uname=~s/:/_/; - $result.=''."\n"; $ctr++; $result.=&viewstudentgrade($url,$symb,$ENV{'request.course.id'}, $_,$$fullname{$_},\@parts,\%weight,$ctr); @@ -2413,18 +2539,21 @@ sub viewstudentgrade { my ($uname,$udom) = split(/:/,$student); $student=~s/:/_/; my %record=&Apache::lonnet::restore($symb,$courseid,$udom,$uname); - my $result=''.$ctr.'  '. + my $result=''. + ''. + "\n".$ctr.'  '. ''.$fullname.' '. '('.$uname.($ENV{'user.domain'} eq $udom ? '' : ':'.$udom).')'."\n"; foreach my $apart (@$parts) { my ($part,$type) = &split_part_type($apart); my $score=$record{"resource.$part.$type"}; + $result.=''; if ($type eq 'awarded') { my $pts = $score eq '' ? '' : $score*$$weight{$part}; $result.=''."\n"; - $result.=''."\n"; @@ -2433,7 +2562,7 @@ sub viewstudentgrade { $status = 'nothing' if ($status eq ''); $result.=''."\n"; - $result.=' '. "\n"; - $result.=''."\n"; } @@ -2634,24 +2763,26 @@ sub split_part_type { # #--- Javascript to handle csv upload sub csvupload_javascript_reverse_associate { + my $error1=&mt('You need to specify the username or ID'); + my $error2=&mt('You need to specify at least one grading field'); return(<2) { foundsomething=1; } - } - if (founduname==0 || founddomain==0) { - alert('You need to specify at both the username and domain'); - return; + if (tw==1) { foundID=1; } + if (tw==2) { founduname=1; } + if (tw>3) { foundsomething=1; } + } + if (founduname==0 && foundID==0) { + alert('$error1'); + return; } if (foundsomething==0) { - alert('You need to specify at least one grading field'); - return; + alert('$error2'); + return; } vf.submit(); } @@ -2716,7 +2849,8 @@ sub csvuploadmap_header { } my ($result) = &showResourceInfo($url,$ENV{'form.probTitle'}); - + my $checked=(($ENV{'form.noFirstLine'})?' checked="checked"':''); + my $ignore=&mt('Ignore First Line'); $request->print(<

Uploading Class Grades

@@ -2727,6 +2861,7 @@ Total number of records found in file: $ Enter as many fields as you can. The system will inform you and bring you back to this page if the data selected is insufficient to run your class.
+ @@ -2738,7 +2873,7 @@ to this page if the data selected is ins - +