--- loncom/homework/grades.pm 2001/02/13 19:43:44 1.4 +++ loncom/homework/grades.pm 2002/09/20 23:46:41 1.51 @@ -1,5 +1,37 @@ +# The LearningOnline Network with CAPA # The LON-CAPA Grading handler +# +# $Id: grades.pm,v 1.51 2002/09/20 23:46:41 albertel Exp $ +# +# Copyright Michigan State University Board of Trustees +# +# This file is part of the LearningOnline Network with CAPA (LON-CAPA). +# +# LON-CAPA is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# LON-CAPA is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with LON-CAPA; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# /home/httpd/html/adm/gpl.txt +# +# http://www.lon-capa.org/ +# # 2/9,2/13 Guy Albertelli +# 6/8 Gerd Kortemeyer +# 7/26 H.K. Ng +# 8/20 Gerd Kortemeyer +# Year 2002 +# June-August H.K. Ng +# package Apache::grades; use strict; @@ -8,88 +40,2323 @@ use Apache::lonxml; use Apache::lonnet; use Apache::loncommon; use Apache::lonhomework; +use Apache::lonmsg qw(:user_normal_msg); use Apache::Constants qw(:common); -sub moreinfo { - my ($request,$reason) = @_; - $request->print("Unable to process request: $reason"); - $request->print('
'); +# ----- These first few routines are general use routines.----- +# +# --- Retrieve the parts that matches stores_\d+ from the metadata file.--- +sub getpartlist { + my ($url) = @_; + my @parts =(); + my (@metakeys) = split(/,/,&Apache::lonnet::metadata($url,'keys')); + foreach my $key (@metakeys) { + if ( $key =~ m/stores_([0-9]+)_.*/) { + push(@parts,$key); + } + } + return @parts; +} + +# --- Get the symbolic name of a problem and the url +sub get_symb_and_url { + my ($request) = @_; + (my $url=$ENV{'form.url'}) =~ s-^http://($ENV{'SERVER_NAME'}|$ENV{'HTTP_HOST'})--; + my $symb=($ENV{'form.symb'} ne '' ? $ENV{'form.symb'} : (&Apache::lonnet::symbread($url))); + if ($symb eq '') { $request->print("Unable to handle ambiguous references:$url:."); return ''; } + return ($symb,$url); } +# --- Retrieve the fullname for a user. Return lastname, first middle --- +# --- Generation is attached next to the lastname if it exists. --- +sub get_fullname { + my ($uname,$udom) = @_; + my %name=&Apache::lonnet::get('environment', ['lastname','generation', + 'firstname','middlename'],$udom,$uname); + my $fullname; + my ($tmp) = keys(%name); + if ($tmp !~ /^(con_lost|error|no_such_host)/i) { + $fullname=$name{'lastname'}.$name{'generation'}; + if ($fullname =~ /[^\s]+/) { $fullname.=', '; } + $fullname.=$name{'firstname'}.' '.$name{'middlename'}; + } + return $fullname; +} -#FIXME - needs to be much smarter +#--- Get the partlist and the response type for a given problem. --- +#--- Indicate if a response type is coded handgraded or not. --- +sub response_type { + my ($url) = shift; + my $allkeys = &Apache::lonnet::metadata($url,'keys'); + my %seen = (); + my (@partlist,%handgrade); + foreach (split(/,/,&Apache::lonnet::metadata($url,'packages'))) { + if (/^\w+response_\d+.*/) { + my ($responsetype,$part) = split(/_/,$_,2); + my ($partid,$respid) = split(/_/,$part); + $handgrade{$part} = $responsetype.':'.($allkeys =~ /parameter_$part\_handgrade/ ? 'yes' : 'no'); + next if ($seen{$partid} > 0); + $seen{$partid}++; + push @partlist,$partid; + } + } + return \@partlist,\%handgrade; +} + +#--- Dumps the class list with usernames,list of sections, +#--- section, ids and fullnames for each user. +sub getclasslist { + my ($getsec,$hideexpired) = @_; + my $now = time; + my %classlist=&Apache::lonnet::dump('classlist', + $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, + $ENV{'course.'.$ENV{'request.course.id'}.'.num'}); + my ($tmp) = keys(%classlist); + # Bail out if we were unable to get the classlist + return if ($tmp =~ /^(con_lost|error|no_such_host)/i); + + # codes to check for fields in the classlist + # should contain end:start:id:section:fullname + for (keys %classlist) { + my (@fields) = split(/:/,$classlist{$_}); + %classlist = &reformat_classlist(\%classlist) if (scalar(@fields) <= 2); + last; + } + + my (@holdsec,@sections,%allids,%stusec,%fullname); + foreach (keys(%classlist)) { + my ($end,$start,$id,$section,$fullname)=split(/:/,$classlist{$_}); + # still a student? + if (($hideexpired) && ($end) && ($end < $now)) { + next; + } + $section = ($section ne '' ? $section : 'no'); + push @holdsec,$section; + if ($getsec eq 'all' || $getsec eq $section) { + push (@{ $classlist{$getsec} }, $_); + $allids{$_} =$id; + $stusec{$_} =$section; + $fullname{$_}=$fullname; + } + } + my %seen = (); + foreach my $item (@holdsec) { + push (@sections, $item) unless $seen{$item}++; + } + return (\%classlist,\@sections,\%allids,\%stusec,\%fullname); +} + +# add id, section and fullname to the classlist.db +# done to maintain backward compatibility with older versions +sub reformat_classlist { + my ($classlist) = shift; + foreach (sort keys(%$classlist)) { + my ($unam,$udom) = split(/:/); + my $section = &Apache::lonnet::usection($udom,$unam,$ENV{'request.course.id'}); + my $fullname = &get_fullname ($unam,$udom); + my %userid = &Apache::lonnet::idrget($udom,($unam)); + $$classlist{$_} = $$classlist{$_}.':'.$userid{$unam}.':'.$section.':'.$fullname; + } + my $putresult = &Apache::lonnet::put + ('classlist',\%$classlist, + $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, + $ENV{'course.'.$ENV{'request.course.id'}.'.num'}); + + return %$classlist; +} + +#find user domain sub finduser { - my ($name) = @_; - return ($name,$ENV{'user.domain'}); + my ($name) = @_; + my $domain = ''; + if ( $Apache::grades::viewgrades eq 'F' ) { + my %classlist=&Apache::lonnet::dump('classlist', + $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, + $ENV{'course.'.$ENV{'request.course.id'}.'.num'}); + my (@fields) = grep /^$name:/, keys %classlist; + ($name, $domain) = split(/:/,$fields[0]); + return ($name,$domain); + } else { + return ($ENV{'user.name'},$ENV{'user.domain'}); + } } -sub submission { - my ($request) = @_; - my $url=$ENV{'form.url'}; - $url=~s-^http://($ENV{'SERVER_NAME'}|$ENV{'HTTP_HOST'})--; - if ($ENV{'form.student'} eq '') { &moreinfo($request,"Need student login id"); return ''; } - my ($uname,$udom) = &finduser($ENV{'form.student'}); - if ($uname eq '') { &moreinfo($request,"Unable to find student"); return ''; } - my $symb=&Apache::lonnet::symbread($url); - if ($symb eq '') { $request->print("Unable to handle ambiguous references:$url:."); return ''; } - my $home=&Apache::lonnet::homeserver($uname,$udom); - my $answer=&Apache::loncommon::get_previous_attempt($symb,$uname,$udom,$home, - $ENV{'request.course.id'}); - my $result="'."\n".
+ '
|
'. + 'Resource: '.$url.' |
';
+ $result.='
|
Part '.$partid.' Points: | ';
+
+ my $ctr = 0;
+ $result.='
| or | '; + $result.=''."\n"; + $result.=' | /'.$wgt.' '.$wgtmsg.' | '; + + $result.=''."\n". + ''. + ''."  \n"; + $result.=''; + $result.=' |
'. + ''."\n"; + if ($ENV{'form.handgrade'} eq 'yes') { + $endform.=' '."\n"; + my $ntstu =''."\n"; + my $nsel = ($ENV{'form.NTSTU'} ne '' ? $ENV{'form.NTSTU'} : '1'); + $ntstu =~ s/ |
'."\n";
+ $result.= '
|
Resource: '.$url.' | ||
Part '.(split(/_/))[0].' | '. + 'Type: '.$responsetype.' | '. + 'Handgrade: '.$handgrade.' |
Resource: '.$url.' | ||
Part '.(split(/_/))[0].' | '. + 'Type: '.$responsetype.' | '. + 'Handgrade: '.$handgrade.' |
'."\n";
+ $result.='
|
'."\n";
+ $result.='
|
'."\n";
+ $result.='
|
'."\n";
+ $result.='
|