--- loncom/homework/grades.pm 2007/06/22 23:45:19 1.418
+++ loncom/homework/grades.pm 2008/12/31 21:08:09 1.528.2.6
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# The LON-CAPA Grading handler
#
-# $Id: grades.pm,v 1.418 2007/06/22 23:45:19 albertel Exp $
+# $Id: grades.pm,v 1.528.2.6 2008/12/31 21:08:09 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -35,6 +35,7 @@ use Apache::loncommon;
use Apache::lonhtmlcommon;
use Apache::lonnavmaps;
use Apache::lonhomework;
+use Apache::lonpickcode;
use Apache::loncoursedata;
use Apache::lonmsg();
use Apache::Constants qw(:common);
@@ -45,36 +46,105 @@ use LONCAPA;
use POSIX qw(floor);
-my %oldessays=();
+
+
my %perm=();
-# ----- These first few routines are general use routines.----
+# These variables are used to recover from ssi errors
+
+my $ssi_retries = 5;
+my $ssi_error;
+my $ssi_error_resource;
+my $ssi_error_message;
+
+
+# Do an ssi with retries:
+# While I'd love to factor out this with the vesrion in lonprintout,
+# that would either require a data coupling between modules, which I refuse to perpetuate
+# (there's quite enough of that already), or would require the invention of another infrastructure
+# I'm not quite ready to invent (e.g. an ssi_with_retry object).
+#
+# At least the logic that drives this has been pulled out into loncommon.
+
+
+#
+# ssi_with_retries - Does the server side include of a resource.
+# if the ssi call returns an error we'll retry it up to
+# the number of times requested by the caller.
+# If we still have a proble, no text is appended to the
+# output and we set some global variables.
+# to indicate to the caller an SSI error occurred.
+# All of this is supposed to deal with the issues described
+# in LonCAPA BZ 5631 see:
+# http://bugs.lon-capa.org/show_bug.cgi?id=5631
+# by informing the user that this happened.
+#
+# Parameters:
+# resource - The resource to include. This is passed directly, without
+# interpretation to lonnet::ssi.
+# form - The form hash parameters that guide the interpretation of the resource
+#
+# retries - Number of retries allowed before giving up completely.
+# Returns:
+# On success, returns the rendered resource identified by the resource parameter.
+# Side Effects:
+# The following global variables can be set:
+# ssi_error - If an unrecoverable error occurred this becomes true.
+# It is up to the caller to initialize this to false
+# if desired.
+# ssi_error_resource - If an unrecoverable error occurred, this is the value
+# of the resource that could not be rendered by the ssi
+# call.
+# ssi_error_message - The error string fetched from the ssi response
+# in the event of an error.
+#
+sub ssi_with_retries {
+ my ($resource, $retries, %form) = @_;
+ my ($content, $response) = &Apache::loncommon::ssi_with_retries($resource, $retries, %form);
+ if ($response->is_error) {
+ $ssi_error = 1;
+ $ssi_error_resource = $resource;
+ $ssi_error_message = $response->code . " " . $response->message;
+ }
+
+ return $content;
+
+}
+#
+# Prodcuces an ssi retry failure error message to the user:
+#
+
+sub ssi_print_error {
+ my ($r) = @_;
+ my $helpurl = &Apache::loncommon::top_nav_help('Helpdesk');
+ $r->print('
+
+
+'.&mt('Unable to retrieve a resource from a server:').'
+'.&mt('Resource:').' '.$ssi_error_resource.'
+'.&mt('Error:').' '.$ssi_error_message.'
+
'.
+&mt('It is recommended that you try again later, as this error may mean the server was just temporarily unavailable, or is down for maintenance.').'
'.
+&mt('If the error persists, please contact the [_1] for assistance.',$helpurl).
+'
'; } elsif ($response eq 'match') { my %answer=&Apache::lonnet::str2hash($answer); @@ -251,31 +354,31 @@ sub cleanRecord { $bottomrow.=''. - '
'. - ' Answer '.$toprow.''.$grayFont.'Option ID '. + ''. + ' '.&mt('Answer').' '.$toprow.''.' '.$grayFont.&mt('Option ID').' '. $grayFont.$bottomrow.'
'; } elsif ($response eq 'radiobutton') { my %answer=&Apache::lonnet::str2hash($answer); my ($toprow,$bottomrow); - my $correct=($order->[0])+1; - for (my $i=1;$i<=$#$order;$i++) { - my $foil=$order->[$i]; + my $correct = + &get_radiobutton_correct_foil($partid,$respid,$symb,$uname,$udom); + foreach my $foil (@$order) { if (exists($answer{$foil})) { - if ($i == $correct) { - $toprow.=''. - '
'. - ' Answer '.$toprow.''.$grayFont.'Item ID '. + ''. + ' '.&mt('Answer').' '.$toprow.''. - ' '.$grayFont.&mt('Item ID').' '. $middlerow.''.$grayFont.'Option ID '. + ''.' '.$grayFont.&mt('Option ID').' '. $bottomrow.'
'; } elsif ($response eq 'essay') { if (! exists ($env{'form.'.$symb})) { @@ -327,7 +430,10 @@ sub cleanRecord { $result.=''; return $result; } - + } elsif ( $response =~ m/(?:numerical|formula)/) { + $answer = + &Apache::loncommon::format_previous_attempt_value('submission', + $answer); } return $answer; } @@ -371,8 +477,10 @@ COMMONJSFUNCTIONS #--- Dumps the class list with usernames,list of sections, #--- section, ids and fullnames for each user. sub getclasslist { - my ($getsec,$filterlist) = @_; + my ($getsec,$filterlist,$getgroup) = @_; my @getsec; + my @getgroup; + my $stu_status = join(':',&Apache::loncommon::get_env_multiple('form.Status')); if (!ref($getsec)) { if ($getsec ne '' && $getsec ne 'all') { @getsec=($getsec); @@ -381,10 +489,19 @@ sub getclasslist { @getsec=@{$getsec}; } if (grep(/^all$/,@getsec)) { undef(@getsec); } + if (!ref($getgroup)) { + if ($getgroup ne '' && $getgroup ne 'all') { + @getgroup=($getgroup); + } + } else { + @getgroup=@{$getgroup}; + } + if (grep(/^all$/,@getgroup)) { undef(@getgroup); } - my $classlist=&Apache::loncoursedata::get_classlist(); + my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist(); # Bail out if we were unable to get the classlist return if (! defined($classlist)); + &Apache::loncoursedata::get_group_memberships($classlist,$keylist); # my %sections; my %fullnames; @@ -401,18 +518,40 @@ sub getclasslist { $classlist->{$student}->[&Apache::loncoursedata::CL_FULLNAME()]; my $status = $classlist->{$student}->[&Apache::loncoursedata::CL_STATUS()]; + my $group = + $classlist->{$student}->[&Apache::loncoursedata::CL_GROUP()]; # filter students according to status selected - if ($filterlist && $env{'form.Status'} ne 'Any') { - if ($env{'form.Status'} ne $status) { - delete ($classlist->{$student}); + if ($filterlist && (!($stu_status =~ /Any/))) { + if (!($stu_status =~ $status)) { + delete($classlist->{$student}); next; } } + # filter students according to groups selected + my @stu_groups = split(/,/,$group); + if (@getgroup) { + my $exclude = 1; + foreach my $grp (@getgroup) { + foreach my $stu_group (@stu_groups) { + if ($stu_group eq $grp) { + $exclude = 0; + } + } + if (($grp eq 'none') && !$group) { + $exclude = 0; + } + } + if ($exclude) { + delete($classlist->{$student}); + } + } $section = ($section ne '' ? $section : 'none'); if (&canview($section)) { if (!@getsec || grep(/^\Q$section\E$/,@getsec)) { $sections{$section}++; - $fullnames{$student}=$fullname; + if ($classlist->{$student}) { + $fullnames{$student}=$fullname; + } } else { delete($classlist->{$student}); } @@ -485,6 +624,7 @@ sub student_gradeStatus { # Shows a student's view of problem and submission sub jscriptNform { my ($symb) = @_; + my $stu_status = join(':',&Apache::loncommon::get_env_multiple('form.Status')); my $jscript=' - -UPLOAD +'); - $r->print(<'. - '
'. - ' Answer '.$toprow.''.$grayFont.'Option ID '. + ''. + ' '.&mt('Answer').' '.$toprow.''.' '.$grayFont.&mt('Option ID').' '. $grayFont.$bottomrow.'