Annotation of loncom/homework/bridgetask.pm, revision 1.254

1.1       albertel    1: # The LearningOnline Network with CAPA 
                      2: # definition of tags that give a structure to a document
                      3: #
1.254   ! raeburn     4: # $Id: bridgetask.pm,v 1.253 2010/09/27 18:45:14 raeburn Exp $
1.1       albertel    5: #
                      6: # Copyright Michigan State University Board of Trustees
                      7: #
                      8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                      9: #
                     10: # LON-CAPA is free software; you can redistribute it and/or modify
                     11: # it under the terms of the GNU General Public License as published by
                     12: # the Free Software Foundation; either version 2 of the License, or
                     13: # (at your option) any later version.
                     14: #
                     15: # LON-CAPA is distributed in the hope that it will be useful,
                     16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     18: # GNU General Public License for more details.
                     19: #
                     20: # You should have received a copy of the GNU General Public License
                     21: # along with LON-CAPA; if not, write to the Free Software
                     22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     23: #
                     24: # /home/httpd/html/adm/gpl.txt
                     25: #
                     26: # http://www.lon-capa.org/
                     27: #
                     28: ###
                     29: 
                     30: 
                     31: package Apache::bridgetask; 
                     32: 
                     33: use strict;
                     34: use Apache::lonnet;
                     35: use Apache::File();
                     36: use Apache::lonmenu;
                     37: use Apache::lonlocal;
                     38: use Apache::lonxml;
1.37      albertel   39: use Apache::slotrequest();
1.1       albertel   40: use Time::HiRes qw( gettimeofday tv_interval );
1.158     www        41: use LONCAPA;
                     42:  
1.9       albertel   43: 
1.1       albertel   44: BEGIN {
1.225     albertel   45:     &Apache::lonxml::register('Apache::bridgetask',('Task','IntroParagraph','Dimension','Question','QuestionText','Setup','Instance','InstanceText','Criteria','CriteriaText','GraderNote','ClosingParagraph'));
1.1       albertel   46: }
                     47: 
1.169     albertel   48: my %dimension;
1.194     albertel   49: my $top = 'top';
                     50: 
1.9       albertel   51: sub initialize_bridgetask {
                     52:     # id of current Dimension, 0 means that no dimension is current 
                     53:     # (inside <Task> only)
1.178     albertel   54:     @Apache::bridgetask::dimension=();
1.9       albertel   55:     # list of all current Instance ids
1.168     albertel   56:     %Apache::bridgetask::instance=();
1.9       albertel   57:     # list of all Instance ids seen in this problem
                     58:     @Apache::bridgetask::instancelist=();
1.15      albertel   59:     # key of queud user data that we are currently grading
                     60:     $Apache::bridgetask::queue_key='';
1.169     albertel   61:     undef(%dimension);
1.9       albertel   62: }
                     63: 
1.4       albertel   64: sub proctor_check_auth {
1.81      albertel   65:     my ($slot_name,$slot,$type)=@_;
1.11      albertel   66:     my $user=$env{'form.proctorname'};
                     67:     my $domain=$env{'form.proctordomain'};
1.4       albertel   68:     
                     69:     my @allowed=split(",",$slot->{'proctor'});
                     70:     foreach my $possible (@allowed) {
1.138     albertel   71: 	my ($puser,$pdom)=(split(':',$possible));
1.4       albertel   72: 	if ($puser eq $user && $pdom eq $domain) {
1.72      albertel   73: 	    my $authenticated=0;
                     74: 	    if ( $slot->{'secret'} =~ /\S/ &&
                     75: 		 $env{'form.proctorpassword'} eq $slot->{'secret'} ) {
                     76: 		$authenticated=1;
                     77: 	    } else {
                     78: 		
                     79: 		my $authhost=&Apache::lonnet::authenticate($puser,$env{'form.proctorpassword'},$pdom);
                     80: 		if ($authhost ne 'no_host') {
                     81: 		    $authenticated=1;
                     82: 		}
                     83: 	    }
1.150     albertel   84: 	    if ($authenticated) {
1.246     raeburn    85: 		my $check = &check_in($type,$user,$domain,$slot_name);
                     86:                 if ($check =~ /^error:/) {
                     87:                     return 0;
                     88:                 }
1.4       albertel   89: 		return 1;
                     90: 	    }
                     91: 	}
                     92:     }
                     93:     return 0;
                     94: }
                     95: 
1.174     albertel   96: sub check_in {
                     97:     my ($type,$user,$domain,$slot_name) = @_;
                     98:     my $useslots = &Apache::lonnet::EXT("resource.0.useslots");
                     99:     if ( $useslots eq 'map_map') {
1.246     raeburn   100: 	my $result = &check_in_sequence($user,$domain,$slot_name);
                    101:         if ($result =~ /^error: /) {
                    102:             return $result;
                    103:         }
1.174     albertel  104:     } else {
                    105: 	&create_new_version($type,$user,$domain,$slot_name);
1.217     albertel  106: 	&Apache::structuretags::finalize_storage();
1.174     albertel  107:     }
                    108:     return 1;
                    109: }
                    110: 
                    111: sub check_in_sequence {
                    112:     my ($user,$domain,$slot_name) = @_;
                    113:     my $navmap = Apache::lonnavmaps::navmap->new();
1.246     raeburn   114:     if (!defined($navmap)) {
                    115:         return 'error: ';
                    116:     }
1.185     albertel  117:     my ($symb) = &Apache::lonnet::whichuser();
1.174     albertel  118:     my ($map)  = &Apache::lonnet::decode_symb($symb);
1.175     albertel  119:     my @resources = 
                    120: 	$navmap->retrieveResources($map, sub { $_[0]->is_problem() },0,0);
1.174     albertel  121:     my %old_history = %Apache::lonhomework::history;
                    122:     my %old_results = %Apache::lonhomework::results;
                    123: 
                    124:     foreach my $res (@resources) {
                    125: 	&Apache::lonxml::debug("doing ".$res->src);
                    126: 	&Apache::structuretags::initialize_storage($res->symb);
                    127: 	my $type = ($res->is_task()) ? 'Task' : 'problem';
                    128: 	&create_new_version($type,$user,$domain,$slot_name);
                    129: 	&Apache::structuretags::finalize_storage($res->symb);
                    130:     }
                    131:     
                    132:     %Apache::lonhomework::history = %old_history;
                    133:     %Apache::lonhomework::results = %old_results;
                    134: }
                    135: 
1.150     albertel  136: sub create_new_version {
                    137:     my ($type,$user,$domain,$slot_name) = @_;
1.174     albertel  138:     
                    139:     my $id = '0';
1.150     albertel  140:     if ($type eq 'Task') {
                    141: 	# increment version
                    142: 	my $version=
                    143: 	    $Apache::lonhomework::history{'resource.0.version'};
                    144: 	$version++;
1.152     albertel  145: 	&Apache::lonxml::debug("Making version $version");
1.150     albertel  146: 	#clean out all current results
                    147: 	foreach my $key (keys(%Apache::lonhomework::history)) {
                    148: 	    if ($key=~/^resource\.0\./) {
                    149: 		$Apache::lonhomework::results{$key}='';
                    150: 	    }
                    151: 	}
                    152: 	
                    153: 	#setup new version and who did it
1.174     albertel  154:        	$Apache::lonhomework::results{'resource.0.version'}=$version;
                    155: 	$id = "$version.0";
1.178     albertel  156: 	if (!defined($user) || !defined($domain)) {
1.174     albertel  157: 	    $user = $env{'user.name'};
                    158: 	    $domain = $env{'user.domain'};
1.150     albertel  159: 	}
1.174     albertel  160: 	
1.150     albertel  161:     } elsif ($type eq 'problem') {
                    162: 	&Apache::lonxml::debug("authed $slot_name");
1.174     albertel  163:     }
1.181     albertel  164:     if (!defined($user) || !defined($domain)) {
                    165: 	$user = $env{'user.name'};
                    166: 	$domain = $env{'user.domain'};
                    167:     }
                    168: 
                    169:     $Apache::lonhomework::results{"resource.$id.checkedin"}=
                    170: 	$user.':'.$domain;
1.174     albertel  171: 
                    172:     if (defined($slot_name)) {
                    173: 	$Apache::lonhomework::results{"resource.$id.checkedin.slot"}=
                    174: 	    $slot_name;
1.150     albertel  175:     }
                    176: }
                    177: 
1.25      albertel  178: sub get_version {
1.29      albertel  179:     my ($version,$previous);
1.25      albertel  180:     if ($env{'form.previousversion'} && 
1.36      albertel  181: 	$env{'form.previousversion'} ne 'current' &&
1.89      albertel  182: 	defined($Apache::lonhomework::history{'resource.'.$env{'form.previousversion'}.'.0.status'})) {
1.29      albertel  183: 	$version=$env{'form.previousversion'};
                    184: 	$previous=1;
                    185:     } else {
1.150     albertel  186: 	if (defined($Apache::lonhomework::results{'resource.0.version'})) {
                    187: 	    $version=$Apache::lonhomework::results{'resource.0.version'};
                    188: 	} elsif (defined($Apache::lonhomework::history{'resource.0.version'})) {
                    189: 	    $version=$Apache::lonhomework::history{'resource.0.version'};
                    190: 	}
1.29      albertel  191: 	$previous=0;
                    192:     }
                    193:     if (wantarray) {
                    194: 	return ($version,$previous);
1.25      albertel  195:     }
1.29      albertel  196:     return $version;
1.25      albertel  197: }
                    198: 
1.8       albertel  199: sub add_previous_version_button {
1.25      albertel  200:     my ($status)=@_;
1.8       albertel  201:     my $result;
1.89      albertel  202:     if ($Apache::lonhomework::history{'resource.0.version'} eq '') {
1.25      albertel  203: 	return '';
                    204:     }
1.89      albertel  205:     if ($Apache::lonhomework::history{'resource.0.version'} < 2 &&
1.29      albertel  206: 	$status ne 'NEEDS_CHECKIN') {
1.25      albertel  207: 	return '';
                    208:     }
1.29      albertel  209:     my $version=&get_version();
                    210:     if ($env{'form.previousversion'} ne '' &&
                    211: 	$env{'form.previousversion'} eq $version) {
                    212: 	$result.="<h3>".&mt("Showing previous version [_1]",$version).
                    213: 	    "</h3>\n";
                    214:     }
                    215:     my @to_show;
1.89      albertel  216:     foreach my $test_version (1..$Apache::lonhomework::history{'resource.0.version'}) {
                    217: 	if (defined($Apache::lonhomework::history{'resource.'.$test_version.'.0.status'})) {
1.29      albertel  218: 	    push(@to_show,$test_version);
                    219: 	}
                    220:     }
                    221:     my $list='<option>'.
                    222: 	join("</option>\n<option>",@to_show).
                    223: 	     "</option>\n";
1.36      albertel  224:     $list.='<option value="current">'.&mt('Current').'</option>';
1.115     albertel  225:     $result.='<form name="getprevious" method="post" action="';
1.29      albertel  226:     my $uri=$env{'request.uri'};
                    227:     if ($env{'request.enc'}) { $uri=&Apache::lonenc::encrypted($uri); }
                    228:     $result.=$uri.'">'.
                    229: 	&mt(' Show a previously done version: [_1]','<select onchange="this.form.submit()" name="previousversion">
                    230: <option>'.&mt('Pick one').'</option>
                    231: '.$list.'
                    232: </select>')."</form>";
1.8       albertel  233:     return $result;
                    234: }
                    235: 
1.13      albertel  236: sub add_grading_button {
1.185     albertel  237:     my (undef,$cid)=&Apache::lonnet::whichuser();
1.59      albertel  238:     my $cnum=$env{'course.'.$cid.'.num'};
                    239:     my $cdom=$env{'course.'.$cid.'.domain'};
1.144     albertel  240:     my %sections = &Apache::loncommon::get_sections($cdom,$cnum);
                    241: 
1.59      albertel  242:     my $size=5;
                    243:     if (scalar(keys(%sections)) < 3) {
                    244: 	$size=scalar(keys(%sections))+2;
                    245:     }
1.200     albertel  246:     my $sec_select = "\n".'<select multiple="multiple" name="chosensections" size="'.$size.'">'."\n";
                    247:     $sec_select .= "\t<option value='all' selected='selected'>all</option>\n";
1.59      albertel  248:     foreach my $sec (sort {lc($a) cmp lc($b)} (keys(%sections))) {
1.200     albertel  249: 	$sec_select .= "\t<option value=\"$sec\">$sec</option>\n";
1.59      albertel  250:     }
1.200     albertel  251:     $sec_select .= "\t<option value='none'>none</option>\n</select>\n";
1.59      albertel  252:     
1.200     albertel  253:     my $result="\n\t".'<input type="submit" name="gradeasubmission" value="'.
1.13      albertel  254: 	&mt("Get a submission to grade").'" />';
1.200     albertel  255:     $result.="\n\t".'<input type="hidden" name="grade_target" value="webgrade" />';
1.237     albertel  256:     my $see_all = &Apache::lonnet::allowed('mgq',$env{'request.course.id'});
                    257:     my $see_sec = &Apache::lonnet::allowed('mgq',$env{'request.course.id'}.
                    258: 					   '/'.$env{'request.course.sec'});
                    259: 
                    260:     if ($see_all || $see_sec) {
1.34      albertel  261: 	my ($entries,$ready,$locks)=&get_queue_counts('gradingqueue');
1.200     albertel  262: 	$result.="\n\t".'<table>'."\n\t\t".'<tr>';
1.237     albertel  263: 	if ($see_all || (!&section_restricted())) {
1.239     bisitz    264: 	    $result.="\n\t\t\t".'<td rowspan="4">'.&mt('Specify a section:').' </td>'.
1.237     albertel  265: 		"\n\t\t\t".'<td rowspan="4">'.$sec_select."\n\t\t\t".'</td>';
                    266: 	} else {
1.239     bisitz    267: 	    $result.="\n\t\t\t".'<td rowspan="4">'.&mt('Grading section:').' </td>'.
1.237     albertel  268: 		"\n\t\t\t".'<td rowspan="4">'.$env{'request.course.sec'}."\n\t\t\t".'</td>';
                    269: 	}
1.200     albertel  270: 	$result.="\n\t\t\t".'<td>'.'<input type="submit" name="reviewagrading" value="'.
1.106     albertel  271: 	    &mt("Select an entry from the grading queue:").'" /> ';
1.34      albertel  272: 
1.200     albertel  273: 	$result.= "\n\t\t\t\t".&mt("[_1] entries, [_2] ready, [_3] being graded",$entries,$ready,$locks).'</td>'."\n\t\t".'</tr>'."\n";
1.34      albertel  274: 
                    275: 	($entries,$ready,$locks)=&get_queue_counts('reviewqueue');
1.200     albertel  276: 	$result.="\n\t\t".'<tr>'.
                    277: 	    "\n\t\t\t".'<td>'.
                    278: 	    "\n\t\t\t\t".'<input type="submit" name="reviewasubmission" value="'.
1.106     albertel  279: 	    &mt("Select an entry from the review queue:").'" /> ';
                    280: 	$result.=&mt("[_1] entries, [_2] ready, [_3] being graded",
1.200     albertel  281: 		     $entries,$ready,$locks).'</td>'."\n\t\t".'</tr>'."\n";
                    282: 	$result.="\n\t\t".'<tr>'.
                    283: 	    "\n\t\t\t".'<td>'.
                    284: 	    "\n\t\t\t\t".'<input type="submit" name="regradeasubmission" value="'.
                    285: 	    &mt("List of user's grade status").'" /> </td>'
                    286: 	    ."\n\t\t".'</tr>'
                    287: 	    ."\n\t".'</table>'."\n";
                    288: 	$result.="\n\t".'<p>'.
                    289: 	    "\n\t\t".'<input type="submit" name="regradeaspecificsubmission" value="'.
                    290: 	    &mt("Regrade specific user:").'" />';
                    291: 	$result.= "\n\t\t".'<input type="text" size="12" name="gradinguser" />';
1.105     albertel  292: 	$result.=&Apache::loncommon::select_dom_form($env{'user.domain'},
                    293: 						     'gradingdomain');
                    294: 	$result.=' '.
                    295: 	    &Apache::loncommon::selectstudent_link('gradesubmission',
                    296: 						   'gradinguser',
                    297: 						   'gradingdomain');
                    298: 	$result.=&Apache::loncommon::studentbrowser_javascript();
1.200     albertel  299: 	$result.= '</p>'."\n";
1.144     albertel  300:     }
1.13      albertel  301:     return $result;
                    302: }
                    303: 
1.22      albertel  304: sub add_request_another_attempt_button {
1.38      albertel  305:     my ($text)=@_;
1.239     bisitz    306:     if (!$text) { $text=&mt('Request another attempt'); }
1.25      albertel  307:     my $result;
1.36      albertel  308:     my $symb=&Apache::lonnet::symbread();
1.149     albertel  309:     # not a slot access based resource
                    310:     my $useslots = &Apache::lonnet::EXT("resource.0.useslots",$symb);
                    311:     if ($useslots =~ /^\s*no\s*$/i) {
                    312: 	return '';
                    313:     }
                    314: 
1.37      albertel  315:     my ($slot_name,$slot)=&Apache::slotrequest::check_for_reservation($symb);
1.38      albertel  316:     my $action='get_reservation';
1.37      albertel  317:     if ($slot_name) {
1.247     raeburn   318: 	$text=&mt('Change reservation');
1.38      albertel  319: 	$action='change_reservation';
1.37      albertel  320: 	my $description=&Apache::slotrequest::get_description($slot_name,
                    321: 							      $slot);
1.239     bisitz    322: 	$result.='<p>'
                    323:                 .&mt('Will be next available:')
                    324:                 .' '.$description
                    325:                 .'</p>';
1.37      albertel  326:     }
1.38      albertel  327:     
                    328:     if ($env{'request.enc'}) { $symb=&Apache::lonenc::encrypted($symb); }
1.158     www       329:     $symb=&escape($symb);
1.200     albertel  330:     $result.=
                    331:         "\n\t".'<form method="post" action="/adm/slotrequest">'."\n\t\t".
                    332: 	'<input type="hidden" name="symb" value="'.$symb.'" />'."\n\t\t".
                    333: 	'<input type="hidden" name="command" value="'.$action.'" />'."\n\t\t".
1.38      albertel  334: 	'<input type="submit" name="requestattempt" value="'.
1.239     bisitz    335: 	$text.'" />'."\n\t".
1.200     albertel  336: 	'</form>'."\n";
1.25      albertel  337:     return $result;
1.22      albertel  338: }
                    339: 
1.30      albertel  340: sub preserve_grade_info {
                    341:     my $result;
                    342:     # if we are viewing someone else preserve that info
                    343:     if (defined $env{'form.grade_symb'}) {
                    344: 	foreach my $field ('symb','courseid','domain','username') {
                    345: 	    $result .= '<input type="hidden" name="grade_'.$field.
                    346: 		'" value="'.$env{"form.grade_$field"}.'" />'."\n";
                    347: 	}
                    348:     }
                    349:     return $result;
                    350: }
                    351: 
1.53      albertel  352: sub style {
1.125     albertel  353:     my ($target) = @_;
                    354:     if ($target eq 'web'
                    355: 	|| $target eq 'webgrade') {
1.192     albertel  356: 	my $style = (<<STYLE);
1.126     albertel  357: <link rel="stylesheet" type="text/css" href="/res/adm/includes/task.css" />
1.53      albertel  358: STYLE
1.192     albertel  359:         if ($env{'browser.type'} eq 'explorer'
                    360: 	    && $env{'browser.os'} eq 'win' ) {
                    361: 	    if ($env{'browser.version'} < 7) {
                    362: 		$style .= (<<STYLE);
                    363: <link rel="stylesheet" type="text/css" href="/res/adm/includes/task_ie.css" />
                    364: STYLE
                    365:             } else {
                    366: 		$style .= (<<STYLE);
                    367: <link rel="stylesheet" type="text/css" href="/res/adm/includes/task_ie7.css" />
                    368: STYLE
                    369: 	    }
                    370: 	}
1.193     albertel  371: 	return $style;
1.125     albertel  372:     }
                    373:     return;
1.53      albertel  374: }
                    375: 
1.54      albertel  376: sub show_task {
                    377:     my ($status,$previous)=@_;
                    378:     if (!$previous && (
                    379: 		       ( $status eq 'CLOSED' ) ||
                    380: 		       ( $status eq 'BANNED') ||
                    381: 		       ( $status eq 'UNAVAILABLE') ||
                    382: 		       ( $status eq 'NOT_IN_A_SLOT') ||
                    383: 		       ( $status eq 'NEEDS_CHECKIN') ||
                    384: 		       ( $status eq 'WAITING_FOR_GRADE') ||
1.150     albertel  385: 		       ( $status eq 'INVALID_ACCESS') ||
                    386: 		       ( &get_version() eq ''))) {
1.54      albertel  387: 	return 0;
                    388:     }
1.64      albertel  389:     if ($env{'form.donescreen'}) { return 0; }
1.54      albertel  390:     return 1;
                    391: }
                    392: 
1.173     albertel  393: my @delay;
                    394: sub nest { 
                    395:     if (@delay) {
                    396: 	return $delay[-1];
                    397:     } else {
                    398: 	return;
                    399:     }
                    400: }
                    401: 
1.208     albertel  402: sub start_delay {
                    403:     push(@delay,1);
                    404: }
                    405: sub end_delay {
                    406:     pop(@delay);
                    407: }
                    408: 
1.173     albertel  409: sub nested_parse {
                    410:     my ($str,$env,$args) = @_;
                    411:     my @old_env = @Apache::scripttag::parser_env;
                    412:     @Apache::scripttag::parser_env = @$env;
                    413:     if (exists($args->{'set_dim_id'})) {
                    414: 	&enable_dimension_parsing($args->{'set_dim_id'});
                    415:     }
                    416:     push(@delay,(($args->{'delayed_dim_results'})? 1 : 0));
                    417:     my $result = &Apache::scripttag::xmlparse($$str);
                    418:     pop(@delay);
                    419:     if (exists($args->{'set_dim_id'})) {
                    420: 	&disable_dimension_parsing();
                    421:     }
                    422:     @Apache::scripttag::parser_env = @old_env;
                    423:     if ($args->{'delayed_dim_results'}) {
                    424: 	my $dim = &get_dim_id();
1.180     albertel  425: 	&Apache::lonxml::debug(" tossing out $result ");
                    426: 	&Apache::lonxml::debug(" usining out $dim 's  ". $dimension{$dim}{'result'});
1.173     albertel  427: 	return $dimension{$dim}{'result'};
                    428:     }
                    429:     return $result;
                    430: }
                    431: 
1.54      albertel  432: sub internal_location {
                    433:     my ($id)=@_;
                    434:     return '<!-- LONCAPA_INTERNAL_ADD_TASK_STATUS'.$id.' -->';
                    435: }
                    436: 
1.60      albertel  437: sub submission_time_stamp {
1.185     albertel  438:     my ($symb,$courseid,$udom,$uname)=&Apache::lonnet::whichuser();
1.60      albertel  439:     my $submissiontime;
1.89      albertel  440:     my $version=$Apache::lonhomework::history{'resource.0.version'};
1.60      albertel  441:     for (my $v=$Apache::lonhomework::history{'version'};$v>0;$v--) {
1.183     albertel  442: 	if (defined($Apache::lonhomework::history{$v.':resource.'.$version.'.0.bridgetask.portfiles'})
                    443: 	    && defined($Apache::lonhomework::history{$v.':resource.'.$version.'.0.tries'})) {
1.60      albertel  444: 	    $submissiontime=$Apache::lonhomework::history{$v.':timestamp'};
1.182     albertel  445: 	    last;
1.60      albertel  446: 	}
                    447:     }
                    448:     my $result;
                    449:     if ($submissiontime) {
1.89      albertel  450: 	my $slot_name=$Apache::lonhomework::history{'resource.'.$version.'.0.checkedin.slot'};
1.60      albertel  451: 	my %slot=&Apache::lonnet::get_slot($slot_name);
                    452: 	my $diff = $slot{'endtime'} - $submissiontime;
1.71      albertel  453: 	my ($color,$when)=('#FF6666','after');
                    454: 	if ($diff > 0) { ($color,$when)=('#336600','before'); }
1.60      albertel  455: 	my $info;
1.182     albertel  456: 	$diff = abs($diff);
1.60      albertel  457: 	if ($diff%60) { $info=($diff%60).' seconds'; }
                    458: 	$diff=int($diff/60);
                    459: 	if ($diff%60) { $info=($diff%60).' minutes '.$info; }
                    460: 	$diff=int($diff/60);
                    461: 	if ($diff) {    $info=$diff.' hours '.$info; }
                    462: 	$result='<p><font color="'.$color.'">'.
1.182     albertel  463: 	    &mt('Student submitted [_1] [_2] the deadline. '.
                    464: 		'(Submission was at [_3], end of period was [_4].)',
                    465: 		$info,$when,
                    466: 		&Apache::lonlocal::locallocaltime($submissiontime),
                    467: 		&Apache::lonlocal::locallocaltime($slot{'endtime'})).
1.60      albertel  468: 		'</font></p>';
                    469:     }
                    470:     return $result;
                    471: }
                    472: 
1.119     albertel  473: sub file_list {
                    474:     my ($files,$uname,$udom) = @_;
                    475:     if (!defined($uname) || !defined($udom)) {
1.185     albertel  476: 	(undef,undef,$udom,$uname) = &Apache::lonnet::whichuser();
1.119     albertel  477:     }
1.70      albertel  478:     my $file_url = '/uploaded/'.$udom.'/'.$uname.'/portfolio/';
1.119     albertel  479: 
1.120     albertel  480:     my $file_list="<ul class=\"LC_GRADING_handininfo\">\n";
1.119     albertel  481:     foreach my $partial_file (split(',',$files)) {
1.70      albertel  482: 	my $file=$file_url.$partial_file;
                    483: 	$file=~s|/+|/|g;
                    484: 	&Apache::lonnet::allowuploaded('/adm/bridgetask',$file);
1.243     bisitz    485: 	$file_list.='<li><span class="LC_nobreak"><a href="'.$file.'?rawmode=1" target="lonGRDs"><img src="'.
1.161     albertel  486: 	    &Apache::loncommon::icon($file).'" alt="file icon" border="0" /> '.$file.
                    487: 	    '</a></span></li>'."\n";
1.70      albertel  488:     }
                    489:     $file_list.="</ul>\n";
1.119     albertel  490:     return $file_list;
                    491: }
                    492: 
1.163     albertel  493: sub grade_mode {
                    494:     if ($env{'form.regrade'} || $env{'form.regradeaspecificsubmission'}) {
                    495: 	return 'regrade';
                    496:     }
                    497:     return 'queue_grade';
                    498: }
                    499: 
1.119     albertel  500: sub webgrade_standard_info {
                    501:     my ($version)=&get_version();
                    502: 
                    503:     my $file_list = &file_list($Apache::lonhomework::history{"resource.$version.0.bridgetask.portfiles"});
1.70      albertel  504: 
1.245     bisitz    505:     my %lt = &Apache::lonlocal::texthash(
                    506:         'done'   => 'Next Item',
                    507:         'stop'   => 'Quit Grading',
                    508:         'fail'   => 'Fail Rest',
                    509:         'cancel' => 'Cancel',
                    510:         'submit' => 'Submit Grades',
                    511:     );
1.163     albertel  512: 
1.70      albertel  513:     my $result=<<INFO;
1.120     albertel  514:   <div class="LC_GRADING_maincontrols">
1.163     albertel  515: INFO
                    516: 
1.231     albertel  517:     if ($env{'request.state'} eq 'construct') {
1.163     albertel  518: 	$result.=<<INFO;
1.231     albertel  519:     <input type="submit" name="next" value="$lt{'submit'}" />
                    520: INFO
                    521:     } else {
                    522: 	if (&grade_mode() eq 'regrade' && $env{'request.state'} ne 'construct') {
                    523: 	    $result.=<<INFO;
1.163     albertel  524:     <input type="submit" name="cancel" value="$lt{'cancel'}" />
                    525: INFO
1.231     albertel  526:         }
1.163     albertel  527: 
1.231     albertel  528: 	$result.=<<INFO;
1.111     albertel  529:     <input type="submit" name="next" value="$lt{'done'}" />
                    530:     <input type="submit" name="stop" value="$lt{'stop'}" />
1.231     albertel  531: INFO
                    532:     }
                    533:     $result.=<<INFO;
1.143     albertel  534:     <input type="button" name="fail" value="$lt{'fail'}" 
                    535:            onclick="javascript:onFailRest()" />
1.111     albertel  536:   </div>
1.70      albertel  537:   $file_list
                    538: INFO
                    539:     return $result;
1.231     albertel  540: 
1.70      albertel  541: }
                    542: 
1.166     albertel  543: sub done_screen {
                    544:     my ($version) = @_;
1.231     albertel  545:     my $title=&Apache::lonnet::gettitle($env{'request.uri'});
1.166     albertel  546:     my @files=split(',',$Apache::lonhomework::history{'resource.'.$version.'.0.bridgetask.portfiles'});
1.185     albertel  547:     my (undef,undef,$domain,$user)= &Apache::lonnet::whichuser();
1.166     albertel  548:     my $files = '<ul>';
1.167     albertel  549:     my $msg;
1.166     albertel  550:     foreach my $file (@files) {
                    551: 	my $url="/uploaded/$domain/$user/portfolio$file";
                    552: 	if (! &Apache::lonnet::stat_file($url)) {
1.239     bisitz    553: 	    $file = '<span class="LC_error">'
                    554:                    .&mt('[_1]Nonexistent file:[_2]'
                    555:                        ,'<span class="LC_error"> '
                    556:                        ,'</span> <span class="LC_filename">'.$file.'</span>');
1.241     raeburn   557: 	    $msg .= "<p>".&mt('Submitted non-existent file [_1]',$file)."</p>\n";
1.166     albertel  558: 	} else {
                    559: 	    $file = '<span class="LC_filename">'.$file.'</span>';
1.239     bisitz    560: 	    $msg .= "<p>".&mt('Submitted file [_1]',$file)."</p>\n";
1.166     albertel  561: 	}
                    562: 	$files .= '<li>'.$file.'</li>';
                    563:     }
                    564:     $files.='</ul>';
1.239     bisitz    565:     my $subject = &mt('Submission message for [_1]',$title);
1.167     albertel  566:     my ($message_status,$comment_status);
                    567:     my $setting = $env{'course.'.$env{'request.course.id'}.'.task_messages'};
                    568:     $setting =~ s/^\s*(\S*)\s*$/$1/;
                    569:     $setting = lc($setting);
                    570:     if ($setting eq 'only_student'
                    571: 	|| $setting eq 'student_and_user_notes_screen') {
                    572: 	$message_status =
                    573: 	    &Apache::lonmsg::user_normal_msg($user,$domain,$subject,$msg);
                    574: 	$message_status = '<p>'.&mt('Message sent to user: [_1]',
                    575: 				    $message_status).' </p>';
                    576:     }
                    577:     if ($setting eq 'student_and_user_notes_screen') {
                    578: 	$comment_status = 
                    579: 	    &Apache::lonmsg::store_instructor_comment($subject.'<br />'.
                    580: 						      $msg,$user,$domain);
                    581: 	$comment_status = '<p>'.&mt('Message sent to instructor: [_1]',
                    582: 				    $comment_status).' </p>';
                    583:     }
1.239     bisitz    584:     return "<h2>$title</h2>"
                    585:           .'<p>'.&mt('Files submitted: [_1]',$files).'</p>'
                    586:           .'<p>'.&mt('You are now done with this Bridge Task').'</p>'
                    587:           .'<hr />'
                    588:           .'<p><a href="/adm/logout">'.&mt('Logout').'</a></p>'
                    589: .'<p><a href="/adm/roles">'.&mt('Change to a different course').'</a></p>'
                    590: .$message_status
1.241     raeburn   591: .$comment_status;
1.166     albertel  592: 
                    593: }
                    594: 
1.1       albertel  595: sub start_Task {
1.87      albertel  596:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.1       albertel  597: 
1.4       albertel  598:     my ($status,$accessmsg,$slot);
1.179     albertel  599:     &Apache::structuretags::init_problem_globals('Task');
1.16      albertel  600:     if ($target ne 'webgrade') {
                    601: 	&Apache::structuretags::initialize_storage();
                    602: 	&Apache::lonhomework::showhash(%Apache::lonhomework::history);
1.74      albertel  603: 	if ($env{'request.state'} eq 'construct') {
                    604: 	    &Apache::structuretags::setup_rndseed($safeeval);
                    605: 	}
1.16      albertel  606:     } 
                    607: 
1.4       albertel  608:     $Apache::lonhomework::parsing_a_task=1;
1.141     albertel  609: 
                    610:     my $name;
                    611:     if ($target eq 'web' || $target eq 'webgrade') {
                    612: 	$name = &Apache::structuretags::get_resource_name($parstack,$safeeval);
                    613:     }
                    614: 
1.145     albertel  615:     my ($result,$form_tag_start);
                    616:     if ($target eq 'web' || $target eq 'webgrade' || $target eq 'tex'
                    617: 	|| $target eq 'edit') {
                    618: 	($result,$form_tag_start) =
                    619: 	    &Apache::structuretags::page_start($target,$token,$tagstack,
                    620: 					       $parstack,$parser,$safeeval,
1.146     albertel  621: 					       $name,&style($target));
1.145     albertel  622:     }
1.123     albertel  623: 
1.74      albertel  624:     if ($target eq 'web' && $env{'request.state'} ne 'construct') {
1.147     albertel  625: 	if ($Apache::lonhomework::queuegrade
                    626: 	    || $Apache::lonhomework::modifygrades) {
1.141     albertel  627: 	    $result.='<form name="gradesubmission" method="post" action="';
1.13      albertel  628: 	    my $uri=$env{'request.uri'};
                    629: 	    if ($env{'request.enc'}) { $uri=&Apache::lonenc::encrypted($uri); }
1.200     albertel  630: 	    $result.=$uri.'">'.&add_grading_button()."</form>\n";
1.38      albertel  631: 	    my $symb=&Apache::lonnet::symbread();
1.235     albertel  632: 	    if (&Apache::lonnet::allowed('mgq',$env{'request.course.id'})
                    633: 		|| &Apache::lonnet::allowed('mgq',$env{'request.course.id'}.'/'.$env{'request.course.sec'})) {
1.141     albertel  634: 		$result.='<form method="post" name="slotrequest" action="/adm/slotrequest">'.
1.40      albertel  635: 		    '<input type="hidden" name="symb" value="'.$symb.'" />'.
                    636: 		    '<input type="hidden" name="command" value="showslots" />'.
                    637: 		    '<input type="submit" name="requestattempt" value="'.
                    638: 		    &mt('Show Slot list').'" />'.
                    639: 		    '</form>';
1.108     albertel  640: 		my $target_id = 
                    641: 		    &Apache::lonstathelpers::make_target_id({symb => $symb,
                    642: 							     part => '0'});
1.238     albertel  643: 		if (!&section_restricted()) {
1.237     albertel  644: 		    $result.='<form method="post" name="gradingstatus" action="/adm/statistics">'.
                    645: 			'<input type="hidden" name="problemchoice" value="'.$target_id.'" />'.
                    646: 			'<input type="hidden" name="reportSelected" value="grading_analysis" />'.
                    647: 			'<input type="submit" name="grading" value="'.
                    648: 			&mt('Show Grading Status').'" />'.
                    649: 			'</form>';
                    650: 		}
1.40      albertel  651: 	    }
1.13      albertel  652: 	}
1.8       albertel  653:     }
1.231     albertel  654:     if ($target =~/(web|webgrade)/ && $env{'request.state'} eq 'construct') {
1.74      albertel  655: 	$form_tag_start.=&Apache::structuretags::problem_web_to_edit_header($env{'form.rndseed'});
                    656:     }
1.163     albertel  657:     if ($target eq 'web' 
                    658: 	|| ($target eq 'grade' && !$env{'form.webgrade'}) 
                    659: 	|| $target eq 'answer' 
                    660: 	|| $target eq 'tex') {
1.29      albertel  661: 	my ($version,$previous)=&get_version();
1.14      albertel  662: 	($status,$accessmsg,my $slot_name,$slot) = 
1.81      albertel  663: 	    &Apache::lonhomework::check_slot_access('0','Task');
1.152     albertel  664: 	if ($status eq 'CAN_ANSWER' && $version eq '') {
1.177     albertel  665: 	    # CAN_ANSWER mode, and no current version, unproctored access
1.174     albertel  666: 	    # thus self-checkedin
1.246     raeburn   667: 	    my $check = &check_in('Task',undef,undef,$slot_name);
                    668:             if ($check =~ /^error: /) {
                    669:                 my $symb=&Apache::lonnet::symbread();
                    670:                 &Apache::lonnet::logthis("Error during self-checkin of version $version of Task (symb: $symb) using slot: $slot_name");   
                    671:             }
1.152     albertel  672: 	    &add_to_queue('gradingqueue',{'type' => 'Task',
                    673: 					  'time' => time,
                    674: 					  'slot' => $slot_name});
1.150     albertel  675: 	    ($version,$previous)=&get_version();
                    676: 	}
1.218     albertel  677: 	
                    678: 	my $status_id = 
                    679: 	    ($previous || $status eq 'SHOW_ANSWER') ? 'LC_task_feedback'
                    680: 	                                            : 'LC_task_take';
                    681: 	$result .= '<div class="LC_task" id="'.$status_id.'">'."\n";
1.150     albertel  682: 
1.9       albertel  683: 	push(@Apache::inputtags::status,$status);
1.14      albertel  684: 	$Apache::inputtags::slot_name=$slot_name;
1.1       albertel  685: 	my $expression='$external::datestatus="'.$status.'";';
1.89      albertel  686: 	$expression.='$external::gradestatus="'.$Apache::lonhomework::history{"resource.$version.0.solved"}.'";';
1.1       albertel  687: 	&Apache::run::run($expression,$safeeval);
                    688: 	&Apache::lonxml::debug("Got $status");
1.141     albertel  689: 	$result.=&add_previous_version_button($status);
1.54      albertel  690: 	if (!&show_task($status,$previous)) {
1.87      albertel  691: 	    my $bodytext=&Apache::lonxml::get_all_text("/task",$parser,$style);
1.1       albertel  692: 	    if ( $target eq "web" ) {
1.74      albertel  693: 		if ($env{'request.state'} eq 'construct') {
                    694: 		    $result.=$form_tag_start;
                    695: 		}
1.4       albertel  696: 		my $msg;
1.1       albertel  697: 		if ($status eq 'UNAVAILABLE') {
                    698: 		    $msg.='<h1>'.&mt('Unable to determine if this resource is open due to network problems. Please try again later.').'</h1>';
1.3       albertel  699: 		} elsif ($status eq 'NOT_IN_A_SLOT') {
                    700: 		    $msg.='<h1>'.&mt('You are not currently signed up to work at this time and/or place.').'</h1>';
1.247     raeburn   701: 		    $msg.=&add_request_another_attempt_button("Sign up for time to work");
1.4       albertel  702: 		} elsif ($status eq 'NEEDS_CHECKIN') {
                    703: 		    $msg.='<h1>'.&mt('You need the Proctor to validate you.').
                    704: 			'</h1>'.&proctor_validation_screen($slot);
1.22      albertel  705: 		} elsif ($status eq 'WAITING_FOR_GRADE') {
                    706: 		    $msg.='<h1>'.&mt('Your submission is in the grading queue.').'</h1>';
1.64      albertel  707: 		} elsif ($env{'form.donescreen'}) {
1.167     albertel  708: 		    $result .= &done_screen($version);
1.1       albertel  709: 		} elsif ($status ne 'NOT_YET_VIEWED') {
                    710: 		    $msg.='<h1>'.&mt('Not open to be viewed').'</h1>';
                    711: 		}
                    712: 		if ($status eq 'CLOSED' || $status eq 'INVALID_ACCESS') {
                    713: 		    $msg.='The problem '.$accessmsg;
                    714: 		}
                    715: 		$result.=$msg.'<br />';
                    716: 	    } elsif ($target eq 'tex') {
1.248     foxr      717: 		$result.='\noindent \vskip 1 mm  \begin{minipage}{\textwidth}\vskip 0 mm';
1.1       albertel  718: 		if ($status eq 'UNAVAILABLE') {
                    719: 		    $result.=&mt('Unable to determine if this resource is open due to network problems. Please try again later.').'\vskip 0 mm ';
                    720: 		} else {
                    721: 		    $result.=&mt('Problem is not open to be viewed. It')." $accessmsg \\vskip 0 mm ";
                    722: 		}
1.22      albertel  723: 	    } elsif ($target eq 'grade' && !$env{'form.webgrade'}) {
1.4       albertel  724: 		if ($status eq 'NEEDS_CHECKIN') {
1.83      albertel  725: 		    if(&proctor_check_auth($slot_name,$slot,'Task')
                    726: 		       && defined($Apache::inputtags::slot_name)) {
1.148     albertel  727: 			my $result=
                    728: 			    &add_to_queue('gradingqueue',
1.152     albertel  729: 					  {'type' => 'Task',
1.148     albertel  730: 					   'time' => time,
                    731: 					   'slot' => 
                    732: 					       $Apache::inputtags::slot_name});
1.77      albertel  733: 			&Apache::lonxml::debug("add_to_queue said $result");
                    734: 		    }
1.4       albertel  735: 		}
1.1       albertel  736: 	    }
                    737: 	} elsif ($target eq 'web') {
1.141     albertel  738: 
1.57      albertel  739: 	    $result.=&preserve_grade_info();
1.194     albertel  740: 	    $result.=&internal_location(); 
1.200     albertel  741: 	    $result.=$form_tag_start."\t".
1.36      albertel  742: 		'<input type="hidden" name="submitted" value="yes" />';
1.54      albertel  743: 	    &Apache::lonxml::startredirection();
1.1       albertel  744: 	}
1.21      albertel  745:     } elsif ( ($target eq 'grade' && $env{'form.webgrade'}) ||
                    746: 	      $target eq 'webgrade') {
1.32      albertel  747: 	my $webgrade='yes';
1.21      albertel  748: 	if ($target eq 'webgrade') {
1.218     albertel  749: 	    $result .= '<div class="LC_task">'."\n";
1.141     albertel  750: 	    $result.= "\n".'<div class="LC_GRADING_task">'."\n".
1.124     albertel  751: 		'<script type="text/javascript" 
1.126     albertel  752:                          src="/res/adm/includes/task_grading.js"></script>';
1.49      albertel  753: 	    #$result.='<br />Review'.&show_queue('reviewqueue');
                    754: 	    #$result.='<br />Grade'.&show_queue('gradingqueue');
1.30      albertel  755: 	}
1.194     albertel  756: 
1.105     albertel  757: 	my ($todo,$status_code,$msg)=&get_key_todo($target);
1.33      albertel  758: 
                    759: 	if ($todo) {
                    760: 	    &setup_env_for_other_user($todo,$safeeval);
                    761: 	    my ($symb,$uname,$udom)=&decode_queue_key($todo);
1.231     albertel  762: 	    if ($env{'request.state'} eq 'construct') {
                    763: 		$symb = $env{'request.uri'};
                    764: 	    }
                    765: 	    $result.="\n".'<p>'.
                    766: 		&mt('Grading [_1] for [_2] at [_3]',
                    767: 		    &Apache::lonnet::gettitle($symb),$uname,$udom).'</p>';
1.33      albertel  768: 	    $form_tag_start.=
                    769: 		'<input type="hidden" name="gradingkey" value="'.
1.158     www       770: 		&escape($todo).'" />';
1.33      albertel  771: 	    $Apache::bridgetask::queue_key=$todo;
                    772: 	    &Apache::structuretags::initialize_storage();
                    773: 	    &Apache::lonhomework::showhash(%Apache::lonhomework::history);
1.110     albertel  774: 	    if ($target eq 'webgrade' && $status_code eq 'selected') {
                    775: 		$form_tag_start.=
                    776: 		    '<input type="hidden" name="queuemode" value="selected" />';
1.33      albertel  777: 	    }
1.15      albertel  778: 	} else {
1.33      albertel  779: 	    if ($target eq 'webgrade') {
                    780: 		$result.="\n";
1.81      albertel  781: 		my $back='<p><a href="/adm/flip?postdata=return:">'.
                    782: 		    &mt('Return to resource').'</a></p>';
1.33      albertel  783: 		if      ($status_code eq 'stop') {
1.81      albertel  784: 		    $result.='<b>'.&mt("Stopped grading.").'</b>'.$back;
1.163     albertel  785: 		} elsif ($status_code eq 'cancel') {
                    786: 		    $result.='<b>'.&mt("Cancelled grading.").'</b>'.$back;
1.254   ! raeburn   787:                 } elsif ($status_code eq 'terminated') {
        !           788:                     $result.= '<b>'.&mt('Terminated grading').'</b><br />'.
        !           789:                               '<span class="LC_error">'.
        !           790:                               &mt('Grading for [_1] has not been saved because of a grading key mismatch.',
        !           791:                               '<tt>'.$env{'form.terminated'}.'</tt>').'</span><br />'.$back;
1.164     albertel  792: 		} elsif ($status_code eq 'never_versioned') {
                    793: 		    $result.='<b>'.
                    794: 			&mt("Requested user has never accessed the task.").
                    795: 			'</b>'.$back;
1.165     albertel  796: 		} elsif ($status_code =~ /still_open:(.*)/) {
                    797: 		    my $date = &Apache::lonlocal::locallocaltime($1);
                    798: 		    $result.='<b>'.
                    799: 			&mt("Task is still open, will close at [_1].",$date).
                    800: 			'</b>'.$back;
1.33      albertel  801: 		} elsif ($status_code eq 'lock_failed') {
1.105     albertel  802: 		    $result.='<b>'.&mt("Failed to lock the requested record.")
1.81      albertel  803: 			.'</b>'.$back;
1.33      albertel  804: 		} elsif ($status_code eq 'unlock') {
1.81      albertel  805: 		    $result.='<b>'.&mt("Unlocked the requested record.")
                    806: 			.'</b>'.$back;
1.33      albertel  807: 		    $result.=&show_queue($env{'form.queue'},1);
                    808: 		} elsif ($status_code eq 'show_list') {
                    809: 		    $result.=&show_queue($env{'form.queue'},1);
1.49      albertel  810: 		} elsif ($status_code eq 'select_user') {
                    811: 		    $result.=&select_user();
1.95      albertel  812: 		} elsif ($status_code eq 'unable') {
                    813: 		    $result.='<b>'.&mt("Unable to aqcuire a user to grade.").'</b>'.$back;
1.105     albertel  814: 		} elsif ($status_code eq 'not_allowed') {
                    815: 		    $result.='<b>'.&mt('Not allowed to grade the requested user.').' '.$msg.'</b>'.$back;
1.33      albertel  816: 		} else {
1.81      albertel  817: 		    $result.='<b>'.&mt("No user to be graded.").'</b>'.$back;
1.32      albertel  818: 		}
1.21      albertel  819: 	    }
1.33      albertel  820: 	    $webgrade='no';
1.163     albertel  821: 	}
                    822: 	if (!$todo || $env{'form.cancel'}) {
1.87      albertel  823: 	    my $bodytext=&Apache::lonxml::get_all_text("/task",$parser,$style);
1.32      albertel  824: 	}
                    825: 	if ($target eq 'webgrade' && defined($env{'form.queue'})) {
1.61      albertel  826: 	    if ($webgrade eq 'yes') {
                    827: 		$result.=&submission_time_stamp();
                    828: 	    }
1.32      albertel  829: 	    $result.=$form_tag_start;
                    830: 	    $result.='<input type="hidden" name="webgrade" value="'.
                    831: 		$webgrade.'" />';
                    832: 	    $result.='<input type="hidden" name="queue" value="'.
                    833: 		$env{'form.queue'}.'" />';
1.52      albertel  834: 	    if ($env{'form.regrade'}) {
                    835: 		$result.='<input type="hidden" name="regrade" value="'.
                    836: 		    $env{'form.regrade'}.'" />';
                    837: 	    }
1.237     albertel  838: 	    if ($env{'form.chosensections'} || &section_restricted()) {
                    839: 		my @chosen_sections = &get_allowed_sections();
1.62      albertel  840: 		foreach my $sec (@chosen_sections) {
                    841: 		    $result.='<input type="hidden" name="chosensections" 
                    842:                                value="'.$sec.'" />';
                    843: 		}
                    844: 	    }
1.70      albertel  845: 	    if ($webgrade eq 'yes') { $result.=&webgrade_standard_info(); }
1.231     albertel  846: 	} elsif ($target eq 'webgrade' 
                    847: 		 && $env{'request.state'} eq 'construct') {
                    848: 	    $result.=$form_tag_start;
                    849: 	    $result.='<input type="hidden" name="webgrade" value="'.
                    850: 		$webgrade.'" />';
                    851: 	    $result.=&webgrade_standard_info();
1.15      albertel  852: 	}
1.110     albertel  853: 	if ($target eq 'webgrade') {
1.120     albertel  854: 	    $result.="\n".'<div id="LC_GRADING_criterialist">';
1.194     albertel  855: 	    &Apache::lonxml::startredirection();
1.208     albertel  856: 	    &start_delay();
                    857: 	    $dimension{$top}{'result'}=$result;
                    858: 	    undef($result);
1.110     albertel  859: 	}
1.74      albertel  860:     } elsif ($target eq 'edit') {
1.141     albertel  861: 	$result.=$form_tag_start.
1.74      albertel  862: 	    &Apache::structuretags::problem_edit_header();
                    863: 	$Apache::lonxml::warnings_error_header=
                    864: 	    &mt("Editor Errors - these errors might not effect the running of the problem, but they will likely cause problems with further use of the Edit mode. Please use the EditXML mode to fix these errors.")."<br />";
1.225     albertel  865: 	$result.= &Apache::edit::text_arg('Required number of passed optional elements to pass the Task:','OptionalRequired',$token,10)." <br />\n";
                    866: 	$result.= &Apache::edit::insertlist($target,$token);
                    867:     } elsif ($target eq 'modified') {
                    868: 	my $constructtag=
                    869: 	    &Apache::edit::get_new_args($token,$parstack,$safeeval,
                    870: 					'OptionalRequired');
                    871: 	if ($constructtag) {
                    872: 	    $result = &Apache::edit::rebuild_tag($token);
                    873: 	}
1.1       albertel  874:     } else {
                    875: 	# page_start returned a starting result, delete it if we don't need it
                    876: 	$result = '';
                    877:     }
                    878:     return $result;
                    879: }
                    880: 
1.165     albertel  881: sub get_task_end_time {
                    882:     my ($queue_entry,$symb,$udom,$uname) = @_;
                    883: 
                    884:     my $end_time;
                    885:     if (my $slot = &slotted_access($queue_entry)) {
                    886: 	my %slot_data=&Apache::lonnet::get_slot($slot);
                    887: 	$end_time = $slot_data{'endtime'};
                    888:     } else {
                    889: 	$end_time = &Apache::lonhomework::due_date('0',$symb,
                    890: 						   $udom,$uname);
                    891:     }
                    892:     return $end_time;
                    893: }
                    894: 
1.32      albertel  895: sub get_key_todo {
                    896:     my ($target)=@_;
                    897:     my $todo;
1.33      albertel  898: 
1.231     albertel  899:     if ($env{'request.state'} eq 'construct') {
                    900: 	my ($symb,$cid,$udom,$uname) = &Apache::lonnet::whichuser();
                    901: 	my $gradingkey=&encode_queue_key($symb,$udom,$uname);
                    902: 	return ($gradingkey);
                    903:     }
                    904: 
1.33      albertel  905:     if (defined($env{'form.reviewasubmission'})) {
1.54      albertel  906: 	&Apache::lonxml::debug("review a submission....");
1.33      albertel  907: 	$env{'form.queue'}='reviewqueue';
                    908: 	return (undef,'show_list');
                    909:     }
                    910: 
                    911:     if (defined($env{'form.reviewagrading'})) {
                    912: 	&Apache::lonxml::debug("review a grading....");
                    913: 	$env{'form.queue'}='gradingqueue';
                    914: 	return (undef,'show_list');
                    915:     }
                    916: 
1.49      albertel  917:     if (defined($env{'form.regradeasubmission'})) {
                    918: 	&Apache::lonxml::debug("regrade a grading....");
                    919: 	$env{'form.queue'}='none';
                    920: 	return (undef,'select_user');
                    921:     }
                    922: 
1.105     albertel  923: 
1.138     albertel  924:     my $me=$env{'user.name'}.':'.$env{'user.domain'};
1.105     albertel  925: 
                    926:     #need to try both queues..
                    927:     if (defined($env{'form.regradeaspecificsubmission'}) &&
                    928: 	defined($env{'form.gradinguser'})               &&
                    929: 	defined($env{'form.gradingdomain'})               ) {
1.185     albertel  930: 	my ($symb,$cid)=&Apache::lonnet::whichuser();
1.105     albertel  931: 	my $cnum  = $env{'course.'.$cid.'.num'};
                    932: 	my $cdom  = $env{'course.'.$cid.'.domain'};
1.224     albertel  933: 	my $uname = &LONCAPA::clean_username($env{'form.gradinguser'});
                    934: 	my $udom  = &LONCAPA::clean_domain($env{'form.gradingdomain'});
1.237     albertel  935: 	
                    936: 	if (&section_restricted()) {
                    937: 	    my $classlist=&get_limited_classlist();
                    938: 	    if (!&allow_grade_user($classlist->{$uname.':'.$udom})) {
                    939: 		return (undef,'not_allowed',
                    940: 			&mt('Requested student ([_1]) is in a section you aren\'t allowed to grade.',$uname.':'.$udom));
                    941: 	    }
                    942: 	}
1.105     albertel  943: 	my $gradingkey=&encode_queue_key($symb,$udom,$uname);
                    944: 
                    945: 	my $queue;
                    946: 
                    947: 	if      (&in_queue('gradingqueue',$symb,$cdom,$cnum,$udom,$uname)) {
                    948: 	    $env{'form.queue'} = $queue = 'gradingqueue';
                    949: 	} elsif (&in_queue('reviewqueue' ,$symb,$cdom,$cnum,$udom,$uname)) {
                    950: 	    $env{'form.queue'} = $queue = 'reviewqueue';
                    951: 	}
                    952: 	
                    953: 	if (!$queue) {
                    954: 	    $env{'form.queue'} = $queue = 'none';
                    955: 	    #not queued so doing either a re or pre grade
1.164     albertel  956: 	    my %status = &Apache::lonnet::restore($symb,$cid,$udom,$uname);
                    957: 	    if ($status{'resource.0.version'} < 1) {
                    958: 		return (undef,'never_versioned');
                    959: 	    }
1.105     albertel  960: 	    return ($gradingkey);
                    961: 	}
                    962: 
1.165     albertel  963: 	if ($queue) {
                    964: 	    my $queue_entry = &get_queue_data($queue,$udom,$uname);
                    965: 	
                    966: 	    my $end_time = &get_task_end_time($queue_entry,$symb,
                    967: 					      $udom,$uname);
                    968: 	    if ($end_time > time) {
                    969: 		return (undef,"still_open:$end_time");
                    970: 	    }
                    971: 	}
                    972: 
1.105     albertel  973: 	my $who=&queue_key_locked($queue,$gradingkey);
                    974: 	if ($who eq $me) {
                    975: 	    #already have the lock
1.158     www       976: 	    $env{'form.gradingkey'}=&escape($gradingkey);
1.163     albertel  977: 	    &Apache::lonxml::debug("already locked");
1.105     albertel  978: 	    return ($gradingkey);
                    979: 	}
                    980: 	
                    981: 	if (!defined($who)) {
                    982: 	    if (&lock_key($queue,$gradingkey)) {
1.163     albertel  983: 		&Apache::lonxml::debug("newly locked");
1.105     albertel  984: 		return ($gradingkey);
                    985: 	    } else {
                    986: 		return (undef,'lock_failed');
                    987: 	    }
                    988: 	}
                    989: 
                    990: 	#otherwise (defined($who) && $who ne $me) some else has it...
                    991: 	return (undef,'not_allowed',
                    992: 		&mt('Another user ([_1]) currently has the record for [_2] locked.',
1.138     albertel  993: 		    $who,$env{'form.gradinguser'}.':'.$env{'form.gradingdomain'}));
1.105     albertel  994:     }
                    995: 
                    996: 
1.32      albertel  997:     my $queue=$env{'form.queue'};
1.33      albertel  998: 
1.32      albertel  999:     if (!defined($queue)) {
                   1000: 	$env{'form.queue'}=$queue='gradingqueue';
                   1001:     }
1.33      albertel 1002: 
1.158     www      1003:     my $gradingkey=&unescape($env{'form.gradingkey'});
1.33      albertel 1004: 
1.49      albertel 1005:     if ($env{'form.queue'} eq 'none') {
                   1006: 	if (defined($env{'form.gradingkey'})) {
                   1007: 	    if ($target eq 'webgrade') {
                   1008: 		if ($env{'form.stop'}) {
                   1009: 		    return (undef,'stop');
1.163     albertel 1010: 		} elsif ($env{'form.cancel'}) {
                   1011: 		    return (undef,'cancel');
1.254   ! raeburn  1012:                 } elsif ($env{'form.terminated'}) {
        !          1013:                     return (undef, 'terminated');
1.49      albertel 1014: 		} elsif ($env{'form.next'}) {
1.59      albertel 1015: 		    return (undef,'select_user');
1.49      albertel 1016: 		}
                   1017: 	    }
                   1018: 	    return ($gradingkey,'selected');
                   1019: 	} else {
1.59      albertel 1020: 	    return (undef,'select_user');
1.49      albertel 1021: 	}
                   1022:     }
1.32      albertel 1023:     if (defined($env{'form.queue'}) && defined($env{'form.gradingkey'})
1.33      albertel 1024: 	&& !defined($env{'form.gradingaction'}) 
                   1025: 	&& $env{'form.queuemode'} eq 'selected') {
                   1026: 	
                   1027: 	my $who=&queue_key_locked($queue,$gradingkey);
                   1028: 	if ($who eq $me) {
                   1029: 	    &Apache::lonxml::debug("Found a key was given to me");
                   1030: 	    return ($gradingkey,'selected');
                   1031: 	} else {
                   1032: 	    return (undef,'show_list');
                   1033: 	}
                   1034: 
                   1035:     }
                   1036: 
                   1037:     if ($target eq 'webgrade' && $env{'form.queuemode'} eq 'selected') {
                   1038: 	if ($env{'form.gradingaction'} eq 'resume') {
                   1039: 	    delete($env{'form.gradingaction'});
                   1040: 	    &Apache::lonxml::debug("Resuming a key");
1.32      albertel 1041: 	    return ($gradingkey);
1.33      albertel 1042: 	} elsif ($env{'form.gradingaction'} eq 'unlock') {
                   1043: 	    &Apache::lonxml::debug("Unlocking a key ".
                   1044: 				     &check_queue_unlock($queue,$gradingkey,1));
                   1045: 	    return (undef,'unlock');
                   1046: 	} elsif ($env{'form.gradingaction'} eq 'select') {
                   1047: 	    &Apache::lonxml::debug("Locking a key");
                   1048: 	    if (&lock_key($queue,$gradingkey)) {
                   1049: 		&Apache::lonxml::debug("Success $queue");
                   1050: 		return ($gradingkey);
                   1051: 	    }
                   1052: 	    &Apache::lonxml::debug("Failed $queue");
                   1053: 	    return (undef,'lock_failed');
1.32      albertel 1054: 	}
                   1055:     }
1.33      albertel 1056: 
                   1057:     if ($env{'form.queuemode'} ne 'selected') {
                   1058: 	# don't get something new from the queue if they hit the stop button
1.254   ! raeburn  1059:     	if (!(($env{'form.cancel'} || $env{'form.stop'} || $env{'form.terminated'}) 
1.163     albertel 1060: 	      && $target eq 'webgrade') 
1.33      albertel 1061: 	    && !$env{'form.gradingaction'}) {
                   1062: 	    &Apache::lonxml::debug("Getting anew $queue");
                   1063: 	    return (&get_from_queue($queue));
                   1064: 	} else {
1.254   ! raeburn  1065:             if ($env{'form.terminated'}) {
        !          1066:                 return (undef,'terminated');
        !          1067:             } else {
        !          1068:                 return (undef,'stop');
        !          1069:             }
1.33      albertel 1070: 	}
1.32      albertel 1071:     }
1.33      albertel 1072:     return (undef,undef)
1.32      albertel 1073: }
1.94      albertel 1074: 
                   1075: sub minimize_storage {
                   1076:     foreach my $key (keys(%Apache::lonhomework::results)) {
                   1077: 	if ($key =~ /regrader$/) { next; }
                   1078: 	if ($Apache::lonhomework::results{$key} eq
                   1079: 	    $Apache::lonhomework::history{$key}) {
                   1080: 	    delete($Apache::lonhomework::results{$key});
                   1081: 	}
                   1082:     }
                   1083: }
                   1084: 
1.1       albertel 1085: sub end_Task {
                   1086:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
                   1087:     my $result='';
                   1088:     my $status=$Apache::inputtags::status['-1'];
1.29      albertel 1089:     my ($version,$previous)=&get_version();
1.1       albertel 1090:     if ($target eq 'grade' || $target eq 'web' || $target eq 'answer' ||
1.15      albertel 1091: 	$target eq 'tex') {
1.69      albertel 1092: 	if ($target eq 'web' || $target eq 'answer' || $target eq 'tex') {
1.1       albertel 1093: 	    if ($target eq 'web') {
1.54      albertel 1094: 		if (&show_task($status,$previous)) {
                   1095: 		    $result.=&Apache::lonxml::endredirection();
                   1096: 		}
1.64      albertel 1097: 		if ($status eq 'CAN_ANSWER' && !$previous && 
                   1098: 		    !$env{'form.donescreen'}) {
1.252     raeburn  1099:                     my ($portheader,$porttext);
                   1100:                     if ($Apache::lonhomework::history{"resource.$version.0.bridgetask.portfiles"}) {
                   1101:                         $portheader = &mt('Submit Additional Portfolio Files for Grading');
                   1102:                         $porttext = &mt('Indicate which additional files from your portfolio are to be evaluated in grading this task.');
                   1103:                     } else {
                   1104:                         $portheader = &mt('Submit Portfolio Files for Grading');
                   1105:                         $porttext = &mt('Indicate the files from your portfolio to be evaluated in grading this task.');
                   1106:                     }
                   1107: 		    $result.="\n".'<p>'.&Apache::lonhtmlcommon::start_pick_box().
1.28      albertel 1108: 			&Apache::inputtags::file_selector("$version.0",
                   1109: 							  "bridgetask","*",
1.46      albertel 1110: 							  'portfolioonly',
1.252     raeburn  1111:                                                           '<h3>'.$portheader.'</h3><br />'.
                   1112:                                                           $porttext.'<br />').
                   1113: 			&Apache::lonhtmlcommon::end_pick_box().'</p>';
1.77      albertel 1114: 		}
1.78      albertel 1115: 		if (!$previous && $status ne 'SHOW_ANSWER' &&
                   1116: 		    &show_task($status,$previous)) {
1.232     albertel 1117: 		    $result.=&Apache::inputtags::gradestatus('0',$target,1);
1.199     albertel 1118: 		}
                   1119: 		
                   1120: 		$result.='</form>';
                   1121: 
                   1122: 		if (!$previous && $status ne 'SHOW_ANSWER' &&
                   1123: 		    &show_task($status,$previous)) {
1.116     albertel 1124: 		    my $action = &Apache::lonenc::check_encrypt($env{'request.uri'});
1.241     raeburn  1125:                     my $donetext = &mt('Done');
1.64      albertel 1126: 		    $result.=<<DONEBUTTON;
1.115     albertel 1127: <form name="done" method="post" action="$action">
1.64      albertel 1128:    <input type="hidden" name="donescreen" value="1" />
1.241     raeburn  1129:    <input type="submit" value="$donetext" />
1.64      albertel 1130: </form>
                   1131: DONEBUTTON
1.77      albertel 1132:                 }
1.56      albertel 1133: 		if (&show_task($status,$previous) &&
1.89      albertel 1134: 		    $Apache::lonhomework::history{"resource.$version.0.status"} =~ /^(pass|fail)$/) {
                   1135: 		    my $bt_status=$Apache::lonhomework::history{"resource.$version.0.status"};
1.231     albertel 1136: 		    my $title=&Apache::lonnet::gettitle($env{'request.uri'});
1.149     albertel 1137: 		    my $start_time;
                   1138: 
1.80      albertel 1139: 		    my $slot_name=
1.89      albertel 1140: 			$Apache::lonhomework::history{"resource.$version.0.checkedin.slot"};
1.149     albertel 1141: 		    if ($slot_name) {
                   1142: 			my %slot=&Apache::lonnet::get_slot($slot_name);
                   1143: 
                   1144: 			$start_time=$slot{'starttime'}
                   1145: 		    } else {
                   1146: 			$start_time= 
                   1147: 			    &Apache::lonnet::EXT('resource.0.opendate');
                   1148: 		    }
                   1149: 		    $start_time=&Apache::lonlocal::locallocaltime($start_time);
1.54      albertel 1150: 
1.200     albertel 1151: 		    my $status = 
1.213     albertel 1152: 			"\n<div class='LC_$bt_status LC_criteria LC_task_overall_status'>\n\t";
1.54      albertel 1153: 		    
1.213     albertel 1154: 		    my $dim = $top;
                   1155: 		    my %counts = &get_counts($dim,undef,$parstack,
                   1156: 					     $safeeval);
                   1157: 		    my $question_status ="\n\t<p>".
                   1158: 			&question_status_message(\%counts,-1).
                   1159: 			"</p>\n";
                   1160: 
1.54      albertel 1161: 		    if ($bt_status eq 'pass')  {
1.239     bisitz   1162: 			$status.='<h2>'
                   1163:                                 .&mt('You passed the [_1] given on [_2].',$title,$start_time)
                   1164:                                 .'</h2>';
1.213     albertel 1165: 			$status.=$question_status;
1.54      albertel 1166: 		    }
                   1167: 		    if ($bt_status eq 'fail')  {
1.239     bisitz   1168: 			$status.='<h2>'
                   1169:                                 .&mt('You did not pass the [_1] given on [_2].',$title,$start_time)
                   1170:                                 .'</h2>';
1.213     albertel 1171: 			$status.=$question_status;
1.54      albertel 1172: 			if (!$previous) {
                   1173: 			    $status.=&add_request_another_attempt_button();
                   1174: 			}
                   1175: 		    }
1.213     albertel 1176: 		    
1.200     albertel 1177: 		    $status.="\n".'</div>'."\n";
1.194     albertel 1178: 
                   1179: 		    foreach my $id (@{$dimension{$dim}{'criterias'}}) {
                   1180: 			my $type = $dimension{$dim}{'criteria.'.$id.'.type'};
                   1181: 			if ($type eq 'dimension') {
                   1182: 			    $result.=$dimension{$id}{'result'};
                   1183: 			    next;
                   1184: 			}
                   1185: 			my $criteria = 
                   1186: 			    &nested_parse(\$dimension{$dim}{'criteria.'.$id},
                   1187: 					  [@_]);
                   1188: 			$status .= &layout_web_Criteria($dim,$id,$criteria);
                   1189: 		    }
1.54      albertel 1190: 
                   1191: 		    my $internal_location=&internal_location();
                   1192: 		    $result=~s/\Q$internal_location\E/$status/;
                   1193: 		}
1.142     albertel 1194: 		$result.="\n</div>\n".
                   1195: 		    &Apache::loncommon::end_page({'discussion' => 1});
1.1       albertel 1196: 	    }
                   1197: 	}
1.181     albertel 1198: 
                   1199: 	my $useslots = &Apache::lonnet::EXT("resource.0.useslots");
                   1200: 	my %queue_data = ('type' => 'Task',
                   1201: 			  'time' => time,);
                   1202: 	if (defined($Apache::inputtags::slot_name)) {
                   1203: 	    $queue_data{'slot'} = $Apache::inputtags::slot_name;
                   1204: 	} elsif (defined($Apache::lonhomework::history{"resource.$version.0.checkedin.slot"})) {
                   1205: 	    $queue_data{'slot'} = $Apache::lonhomework::history{"resource.$version.0.checkedin.slot"};
                   1206: 	}
                   1207: 	
                   1208: 
1.215     albertel 1209: 	if ($target eq 'grade' && !$env{'form.webgrade'} && !$previous
                   1210: 	    && $status eq 'CAN_ANSWER') {
1.12      albertel 1211: 	    my $award='SUBMITTED';
1.252     raeburn  1212:             my $uploadedflag=0;
                   1213:             my $totalsize=0;
                   1214:             my @deletions = &Apache::loncommon::get_env_multiple('form.HWFILE'.$version.'_0_bridgetask_delete');
1.28      albertel 1215: 	    &Apache::essayresponse::file_submission("$version.0",'bridgetask',
1.252     raeburn  1216: 						    \$award,\$uploadedflag,\$totalsize,\@deletions);
1.14      albertel 1217: 	    if ($award eq 'SUBMITTED' &&
1.28      albertel 1218: 		$Apache::lonhomework::results{"resource.$version.0.bridgetask.portfiles"}) {
                   1219: 		$Apache::lonhomework::results{"resource.0.tries"}=
                   1220: 		    $Apache::lonhomework::results{"resource.$version.0.tries"}=
                   1221: 		    1+$Apache::lonhomework::history{"resource.$version.0.tries"};
                   1222: 
                   1223: 		$Apache::lonhomework::results{"resource.0.award"}=
                   1224: 		    $Apache::lonhomework::results{"resource.$version.0.award"}=
                   1225: 		    $award;
1.51      albertel 1226: 		$Apache::lonhomework::results{"resource.0.submission"}=
                   1227: 		    $Apache::lonhomework::results{"resource.$version.0.submission"}='';
1.64      albertel 1228: 	    } else {
1.252     raeburn  1229:                 unless($uploadedflag) {
                   1230:                     delete($Apache::lonhomework::results{"resource.$version.0.bridgetask.portfiles"});
                   1231:                 }
1.77      albertel 1232: 		$award = '';
1.10      albertel 1233: 	    }
1.4       albertel 1234: 	    &Apache::lonhomework::showhash(%Apache::lonhomework::results);
                   1235: 	    &Apache::structuretags::finalize_storage();
1.148     albertel 1236: 	    if ($award eq 'SUBMITTED') {
1.181     albertel 1237: 		&add_to_queue('gradingqueue',\%queue_data);
1.14      albertel 1238: 	    }
1.1       albertel 1239: 	}
1.163     albertel 1240: 	if ($target eq 'grade' && $env{'form.webgrade'} eq 'yes' 
                   1241: 	    && exists($env{'form.cancel'})) {
                   1242: 	    &check_queue_unlock($env{'form.queue'});
                   1243: 	    &Apache::lonxml::debug(" cancelled grading .".$env{'form.queue'});
                   1244: 	} elsif ($target eq 'grade' && $env{'form.webgrade'} eq 'yes' 
                   1245: 		 && !exists($env{'form.cancel'})) {
1.20      albertel 1246: 	    my $optional_required=
                   1247: 		&Apache::lonxml::get_param('OptionalRequired',$parstack,
                   1248: 					   $safeeval);
                   1249: 	    my $optional_passed=0;
                   1250: 	    my $mandatory_failed=0;
                   1251: 	    my $ungraded=0;
                   1252: 	    my $review=0;   
1.21      albertel 1253: 	    &Apache::lonhomework::showhash(%Apache::lonhomework::results);
1.194     albertel 1254: 	    my $dim = $top;
                   1255: 	    foreach my $id (@{$dimension{$dim}{'criterias'}}) {
                   1256: 		my $link=&link($id);
                   1257: 
                   1258: 		my $type = $dimension{$dim}{'criteria.'.$id.'.type'};
                   1259: 
                   1260: 		if ($type eq 'criteria') {
                   1261: 		    # dimensional 'criteria' don't get assigned grades
                   1262: 		    $Apache::lonhomework::results{"resource.$version.0.$id.status"}=$env{'form.HWVAL_'.$link};
                   1263: 		    $Apache::lonhomework::results{"resource.$version.0.$id.comment"}=$env{'form.HWVAL_comment_'.$link};
                   1264: 		} 
1.20      albertel 1265: 		my $status=
1.194     albertel 1266: 		    $Apache::lonhomework::results{"resource.$version.0.$id.status"};
                   1267: 		my $mandatory=($dimension{$dim}{'criteria.'.$id.'.mandatory'} ne 'N');
                   1268: 
1.20      albertel 1269: 		if ($status eq 'pass') {
                   1270: 		    if (!$mandatory) { $optional_passed++; }
                   1271: 		} elsif ($status eq 'fail') {
                   1272: 		    if ($mandatory) { $mandatory_failed++; }
1.194     albertel 1273: 		} elsif ($status eq 'review') {
                   1274: 		    $review++;
1.20      albertel 1275: 		} elsif ($status eq 'ungraded') {
                   1276: 		    $ungraded++;
1.49      albertel 1277: 		} else {
                   1278: 		    $ungraded++;
                   1279: 		}
1.20      albertel 1280: 	    }
                   1281: 	    if ($optional_passed < $optional_required) {
                   1282: 		$mandatory_failed++;
                   1283: 	    }
1.194     albertel 1284: 	    &Apache::lonxml::debug(" task results -> m_f $mandatory_failed o_p $optional_passed u $ungraded r $review");
1.89      albertel 1285: 	    $Apache::lonhomework::results{'resource.0.regrader'}=
1.138     albertel 1286: 		$env{'user.name'}.':'.$env{'user.domain'};
1.20      albertel 1287: 	    if ($review) {
1.89      albertel 1288: 		$Apache::lonhomework::results{"resource.$version.0.status"}='review';
1.20      albertel 1289: 	    } elsif ($ungraded) {
1.89      albertel 1290: 		$Apache::lonhomework::results{"resource.$version.0.status"}='ungraded';
1.20      albertel 1291: 	    } elsif ($mandatory_failed) {
1.89      albertel 1292: 		$Apache::lonhomework::results{"resource.$version.0.status"}='fail';
1.25      albertel 1293: 		$Apache::lonhomework::results{"resource.$version.0.solved"}='incorrect_by_override';
                   1294: 		$Apache::lonhomework::results{"resource.$version.0.award"}='INCORRECT';
                   1295: 		$Apache::lonhomework::results{"resource.$version.0.awarded"}='0';
1.185     albertel 1296: 		my ($symb,$courseid,$udom,$uname)=&Apache::lonnet::whichuser();
1.52      albertel 1297: 		
                   1298: 		if ($env{'form.regrade'} ne 'yes') {
                   1299: 		    $Apache::lonhomework::results{"resource.$version.0.bridgetask.portfiles"}=
                   1300: 			$Apache::lonhomework::history{"resource.$version.0.bridgetask.portfiles"};
                   1301: 		    &Apache::grades::version_portfiles(
                   1302: 						       \%Apache::lonhomework::results,
                   1303: 						       ["$version.0.bridgetask"],$courseid,
                   1304: 						       $symb,$udom,$uname,
                   1305: 						       ["$version.0.bridgetask"]);
                   1306: 		}
1.20      albertel 1307: 	    } else {
1.89      albertel 1308: 		$Apache::lonhomework::results{"resource.$version.0.status"}='pass';
1.25      albertel 1309: 		$Apache::lonhomework::results{"resource.$version.0.solved"}='correct_by_override';
                   1310: 		$Apache::lonhomework::results{"resource.$version.0.award"}='EXACT_ANS';
                   1311: 		$Apache::lonhomework::results{"resource.$version.0.awarded"}='1';
1.185     albertel 1312: 		my ($symb,$courseid,$udom,$uname)=&Apache::lonnet::whichuser();
1.52      albertel 1313: 		if ($env{'form.regrade'} ne 'yes') {
                   1314: 		    $Apache::lonhomework::results{"resource.$version.0.bridgetask.portfiles"}=
                   1315: 			$Apache::lonhomework::history{"resource.$version.0.bridgetask.portfiles"};
                   1316: 		    &Apache::grades::version_portfiles(
                   1317: 						       \%Apache::lonhomework::results,
                   1318: 						       ["$version.0.bridgetask"],$courseid,
                   1319: 						       $symb,$udom,$uname,
                   1320: 						       ["$version.0.bridgetask"]);
                   1321: 		}
1.20      albertel 1322: 	    }
1.89      albertel 1323: 	    $Apache::lonhomework::results{"resource.0.status"}=
                   1324: 		$Apache::lonhomework::results{"resource.$version.0.status"};
1.28      albertel 1325: 	    if (defined($Apache::lonhomework::results{"resource.$version.0.awarded"})) {
1.26      albertel 1326: 		$Apache::lonhomework::results{"resource.0.award"}=
1.50      albertel 1327: 		    $Apache::lonhomework::results{"resource.$version.0.award"};
1.26      albertel 1328: 		$Apache::lonhomework::results{"resource.0.awarded"}=
1.50      albertel 1329: 		    $Apache::lonhomework::results{"resource.$version.0.awarded"};
1.26      albertel 1330: 		$Apache::lonhomework::results{"resource.0.solved"}=
1.50      albertel 1331: 		    $Apache::lonhomework::results{"resource.$version.0.solved"};
1.25      albertel 1332: 	    }
1.94      albertel 1333: 	    &minimize_storage();
1.254   ! raeburn  1334:             my ($canstore,$domain,$name);
1.250     raeburn  1335:             if ($env{'form.gradingkey'}) {
1.254   ! raeburn  1336:                 (my $symb,my $courseid,$domain,$name) =
1.250     raeburn  1337:                     &Apache::lonnet::whichuser();
                   1338:                 my $todo=&unescape($env{'form.gradingkey'});
                   1339:                 my ($keysymb,$uname,$udom)=&decode_queue_key($todo);
                   1340:                 if ($symb eq $keysymb) {
                   1341:                     if (($domain eq $udom) && ($name eq $uname)) {
                   1342:                         $canstore = 1;           
                   1343:                     }
                   1344:                 }
                   1345:             }
                   1346:             if ($canstore) {
                   1347: 	        &Apache::structuretags::finalize_storage();
1.253     raeburn  1348: 	        # data stored, now handle queue
                   1349: 	        if ($review) {
                   1350: 		    if ($env{'form.queue'} eq 'reviewqueue') {
                   1351: 		        &check_queue_unlock($env{'form.queue'});
                   1352: 		        &Apache::lonxml::debug(" still needs review not changing status.");
                   1353: 		    } else {
                   1354: 		        if ($env{'form.queue'} ne 'none') {
                   1355: 			    &move_between_queues($env{'form.queue'},'reviewqueue');
                   1356: 		        } else {
                   1357: 			    &add_to_queue('reviewqueue',\%queue_data);
                   1358: 		        }
                   1359: 		    }
                   1360: 	        } elsif ($ungraded) {
                   1361: 		    if ($env{'form.queue'} eq 'reviewqueue') {
                   1362: 		        &Apache::lonxml::debug("moving back.");
                   1363: 		        &move_between_queues($env{'form.queue'},
                   1364: 					     'gradingqueue');
                   1365: 		    } elsif ($env{'form.queue'} eq 'none' ) {
                   1366: 		        &add_to_queue('gradingqueue',\%queue_data);	
                   1367: 		    } else {
                   1368: 		        &check_queue_unlock($env{'form.queue'});
                   1369: 		    }
                   1370: 	        } elsif ($mandatory_failed) {
                   1371: 		    &remove_from_queue($env{'form.queue'}); 
                   1372: 	        } else {
                   1373: 		    &remove_from_queue($env{'form.queue'});
                   1374: 	        }
1.250     raeburn  1375:             } else {
1.253     raeburn  1376:                 &check_queue_unlock($env{'form.queue'});
1.254   ! raeburn  1377:                 $env{'form.terminated'} = $name.':'.$domain;
1.250     raeburn  1378:             }
1.253     raeburn  1379:         }
1.184     albertel 1380: 	if (exists($Apache::lonhomework::results{'INTERNAL_store'})) {
1.240     bisitz   1381: 	    # instance generation occurred and hasn't yet been stored
1.184     albertel 1382: 	    &Apache::structuretags::finalize_storage();
                   1383: 	}
1.15      albertel 1384:     } elsif ($target eq 'webgrade') {
1.208     albertel 1385: 	if (&nest()) {
                   1386: 	    &Apache::lonxml::endredirection();
                   1387: 	    &end_delay();
                   1388: 	    $result.=$dimension{$top}{'result'};
                   1389: 	} else {
                   1390: 	    $result.=&Apache::lonxml::endredirection();
                   1391: 	}
1.194     albertel 1392: 	my $dim = $top;
                   1393: 	foreach my $id (@{$dimension{$dim}{'criterias'}} ) {
                   1394: 	    my $type = $dimension{$dim}{'criteria.'.$id.'.type'};
                   1395: 	    if ($type eq 'dimension') {
                   1396: 		# dimensional 'criteria' don't get assigned grades
                   1397: 		next;
                   1398: 	    } else {
                   1399: 		my $criteria =&nested_parse(\$dimension{$dim}{'criteria.'.$id},
                   1400: 					     [@_]);
                   1401: 		$criteria = &layout_webgrade_Criteria($dim,$id,$criteria);
                   1402: 		my $internal_location=&internal_location($id);
1.209     albertel 1403: 		if ($result =~ m/\Q$internal_location\E/) {
                   1404: 		    $result=~s/\Q$internal_location\E/$criteria/;
                   1405: 		} else {
                   1406: 		    $result.=$criteria;
                   1407: 		}
                   1408: 
1.194     albertel 1409: 	    }
                   1410: 	}
                   1411:         $result.="</div>";
1.20      albertel 1412: 	#$result.='<input type="submit" name="next" value="'.
                   1413: 	#    &mt('Save &amp; Next').'" /> ';
                   1414: 	#$result.='<input type="submit" name="end" value="'.
                   1415: 	#    &mt('Save &amp; Stop Grading').'" /> ';
                   1416: 	#$result.='<input type="submit" name="throwaway" value="'.
                   1417: 	#    &mt('Throw Away &amp; Stop Grading').'" /> ';
                   1418: 	#$result.='<input type="submit" name="save" value="'.
                   1419: 	#    &mt('Save Partial Grade and Continue Grading').'" /> ';
1.124     albertel 1420: 	$result.='</form>'."\n</div>\n</div>\n".
1.140     albertel 1421: 	    &Apache::loncommon::end_page();
1.1       albertel 1422:     } elsif ($target eq 'meta') {
1.70      albertel 1423: 	$result.=&Apache::response::meta_package_write('Task');
1.77      albertel 1424:         $result.=&Apache::response::meta_stores_write('solved','string',
                   1425: 						      'Problem Status');
                   1426: 	$result.=&Apache::response::meta_stores_write('tries','int_zeropos',
                   1427: 						      'Number of Attempts');
                   1428: 	$result.=&Apache::response::meta_stores_write('awarded','float',
                   1429: 						      'Partial Credit Factor');
                   1430: 	$result.=&Apache::response::meta_stores_write('status','string',
                   1431: 						      'Bridge Task Status');
1.182     albertel 1432:     } elsif ($target eq 'edit') {
1.227     albertel 1433: 	$result.= &Apache::structuretags::problem_edit_footer();
1.1       albertel 1434:     }
1.179     albertel 1435:     &Apache::structuretags::reset_problem_globals('Task');
1.4       albertel 1436:     undef($Apache::lonhomework::parsing_a_task);
1.250     raeburn  1437:     if ( ($target eq 'grade' && $env{'form.webgrade'}) ||
                   1438:           $target eq 'webgrade') {
                   1439:         delete($env{'form.grade_symb'});
                   1440:         delete($env{'form.grade_domain'});
                   1441:         delete($env{'form.grade_username'});
                   1442:         delete($env{'form.grade_courseid'});
                   1443:     }
1.1       albertel 1444:     return $result;
                   1445: }
                   1446: 
1.31      albertel 1447: sub move_between_queues {
                   1448:     my ($src_queue,$dest_queue)=@_;
1.49      albertel 1449:     my $cur_data;
                   1450:     if ($src_queue ne 'none') {
                   1451: 	$cur_data=&get_queue_data($src_queue);
                   1452: 	if (!$cur_data) { return 'not_exist'; }
                   1453:     } else {
                   1454: 	$cur_data = ['none'];
                   1455:     }
1.148     albertel 1456:     my $result=&add_to_queue($dest_queue,$cur_data);
1.31      albertel 1457:     if ($result ne 'ok') {
                   1458: 	return $result;
                   1459:     }
                   1460:     &check_queue_unlock($src_queue);
                   1461:     return &remove_from_queue($src_queue);
1.21      albertel 1462: }
                   1463: 
                   1464: sub check_queue_unlock {
1.32      albertel 1465:     my ($queue,$key,$allow_not_me)=@_;
1.49      albertel 1466:     if ($queue eq 'none') { return 'ok'; }
1.185     albertel 1467:     my ($symb,$cid,$udom,$uname)=&Apache::lonnet::whichuser();
1.32      albertel 1468:     if (!defined($key)) {
1.138     albertel 1469: 	$key="$symb\0queue\0$uname:$udom";
1.32      albertel 1470:     }
1.30      albertel 1471:     my $cnum=$env{'course.'.$cid.'.num'};
                   1472:     my $cdom=$env{'course.'.$cid.'.domain'};
1.138     albertel 1473:     my $me=$env{'user.name'}.':'.$env{'user.domain'};
1.30      albertel 1474:     my $who=&queue_key_locked($queue,$key,$cdom,$cnum);
                   1475:     if  ($who eq $me) {
1.163     albertel 1476: 	&Apache::lonxml::debug("unlocking my own $who");
1.32      albertel 1477: 	return &Apache::lonnet::del($queue,["$key\0locked"],$cdom,$cnum);
                   1478:     } elsif ($allow_not_me) {
1.33      albertel 1479: 	&Apache::lonxml::debug("unlocking $who by $me");
1.32      albertel 1480: 	return &Apache::lonnet::del($queue,["$key\0locked"],$cdom,$cnum);
1.30      albertel 1481:     }
1.32      albertel 1482:     return 'not_owner';
1.21      albertel 1483: }
                   1484: 
1.88      albertel 1485: sub in_queue {
                   1486:     my ($queue,$symb,$cdom,$cnum,$udom,$uname)=@_;
                   1487:     if ($queue eq 'none') { return 0; }
                   1488:     if (!defined($symb) || !defined($cdom) || !defined($cnum)
                   1489: 	|| !defined($udom) || !defined($uname)) {
1.185     albertel 1490: 	($symb,my $cid,$udom,$uname)=&Apache::lonnet::whichuser();
1.88      albertel 1491: 	$cnum=$env{'course.'.$cid.'.num'};
                   1492: 	$cdom=$env{'course.'.$cid.'.domain'};
                   1493:     }
                   1494: 
                   1495:     my $key=&encode_queue_key($symb,$udom,$uname);
                   1496:     my %results = &Apache::lonnet::get($queue,[$key],$cdom,$cnum);
                   1497: 
                   1498:     if (defined($results{$key})) {
                   1499: 	return 1;
                   1500:     }
                   1501:     return 0;
                   1502: }
                   1503: 
1.21      albertel 1504: sub remove_from_queue {
1.86      albertel 1505:     my ($queue,$symb,$cdom,$cnum,$udom,$uname)=@_;
1.49      albertel 1506:     if ($queue eq 'none') { return 'ok'; }
1.86      albertel 1507:     if (!defined($symb) || !defined($cdom) || !defined($cnum)
                   1508: 	|| !defined($udom) || !defined($uname)) {
1.185     albertel 1509: 	($symb,my $cid,$udom,$uname)=&Apache::lonnet::whichuser();
1.86      albertel 1510: 	$cnum=$env{'course.'.$cid.'.num'};
                   1511: 	$cdom=$env{'course.'.$cid.'.domain'};
                   1512:     }
1.88      albertel 1513:     if (!&in_queue($queue,$symb,$cdom,$cnum,$udom,$uname)) {
                   1514: 	return 'ok';
                   1515:     }
1.86      albertel 1516:     my $key=&encode_queue_key($symb,$udom,$uname);
1.27      albertel 1517:     my @keys=($key,"$key\0locked");
1.31      albertel 1518:     return &Apache::lonnet::del($queue,\@keys,$cdom,$cnum);
1.21      albertel 1519: }
                   1520: 
1.16      albertel 1521: sub setup_env_for_other_user {
                   1522:     my ($queue_key,$safeeval)=@_;
                   1523:     my ($symb,$uname,$udom)=&decode_queue_key($queue_key);
1.30      albertel 1524:     &Apache::lonxml::debug("setup_env for $queue_key");
1.16      albertel 1525:     $env{'form.grade_symb'}=$symb;
                   1526:     $env{'form.grade_domain'}=$udom;
                   1527:     $env{'form.grade_username'}=$uname;
                   1528:     $env{'form.grade_courseid'}=$env{'request.course.id'};
                   1529:     &Apache::lonxml::initialize_rndseed($safeeval);
                   1530: }
                   1531: 
1.31      albertel 1532: sub get_queue_data {
1.165     albertel 1533:     my ($queue,$udom,$uname)=@_;
1.185     albertel 1534:     my ($symb,$cid,$other_udom,$other_uname)=&Apache::lonnet::whichuser();
1.165     albertel 1535:     if (!$uname || !$udom) {
                   1536: 	$uname=$other_uname;
                   1537: 	$udom =$other_udom;
                   1538:     }
1.31      albertel 1539:     my $cnum=$env{'course.'.$cid.'.num'};
                   1540:     my $cdom=$env{'course.'.$cid.'.domain'};
1.138     albertel 1541:     my $todo="$symb\0queue\0$uname:$udom";
1.31      albertel 1542:     my ($key,$value)=&Apache::lonnet::get($queue,[$todo],$cdom,$cnum);
                   1543:     if ($key eq $todo && ref($value)) {
                   1544: 	return $value;
                   1545:     }
                   1546:     return undef;
                   1547: }
                   1548: 
1.84      albertel 1549: 
1.49      albertel 1550: sub check_queue_for_key {
1.84      albertel 1551:     my ($cdom,$cnum,$queue,$todo)=@_;
                   1552: 
1.49      albertel 1553:     my %results=
                   1554: 	&Apache::lonnet::get($queue,[$todo,"$todo\0locked"],$cdom,$cnum);
                   1555:     
                   1556:     if (exists($results{$todo}) && ref($results{$todo})) {
                   1557: 	if (defined($results{"$todo\0locked"})) {
                   1558: 	    return 'locked';
                   1559: 	}
1.148     albertel 1560: 	if (my $slot=&slotted_access($results{$todo})) {
1.86      albertel 1561: 	    my %slot_data=&Apache::lonnet::get_slot($slot);
                   1562: 	    if ($slot_data{'endtime'} > time) { 
                   1563: 		return 'in_progress';
                   1564: 	    }
1.148     albertel 1565: 	} else {
                   1566: 	    my ($symb) = &decode_queue_key($todo);
                   1567: 	    my $due_date = &Apache::lonhomework::due_date('0',$symb);
                   1568: 	    if ($due_date > time) {
                   1569: 		return 'in_progress';
                   1570: 	    }
1.58      albertel 1571: 	}
1.49      albertel 1572: 	return 'enqueued';
                   1573:     }
                   1574:     return undef;
                   1575: }
                   1576: 
1.14      albertel 1577: sub add_to_queue {
1.82      albertel 1578:     my ($queue,$user_data)=@_;
1.49      albertel 1579:     if ($queue eq 'none') { return 'ok'; }
1.185     albertel 1580:     my ($symb,$cid,$udom,$uname)=&Apache::lonnet::whichuser();
1.82      albertel 1581:     if (!$cid || $env{'request.state'} eq 'construct') {
                   1582: 	return 'no_queue';
                   1583:     }
1.14      albertel 1584:     my $cnum=$env{'course.'.$cid.'.num'};
                   1585:     my $cdom=$env{'course.'.$cid.'.domain'};
                   1586:     my %data;
1.138     albertel 1587:     $data{"$symb\0queue\0$uname:$udom"}=$user_data;
1.83      albertel 1588:     return &Apache::lonnet::cput($queue,\%data,$cdom,$cnum);
1.14      albertel 1589: }
                   1590: 
1.156     albertel 1591: sub get_limited_classlist {
                   1592:     my ($sections) = @_;
                   1593: 
                   1594:     my $classlist = &Apache::loncoursedata::get_classlist();
1.157     albertel 1595:     foreach my $student (keys(%$classlist)) {
                   1596: 	if ( $classlist->{$student}[&Apache::loncoursedata::CL_STATUS()]
                   1597: 	     ne 'Active') {
                   1598: 	    delete($classlist->{$student});
                   1599:        	}
                   1600:     }
1.156     albertel 1601: 
1.237     albertel 1602:     if (ref($sections) && !grep {$_ eq 'all'} (@{ $sections })) {
1.156     albertel 1603: 	foreach my $student (keys(%$classlist)) {
                   1604: 	    my $section  = 
                   1605: 		$classlist->{$student}[&Apache::loncoursedata::CL_SECTION()];
1.237     albertel 1606: 	    if (! grep {$_ eq $section} (@{ $sections })) {
1.156     albertel 1607: 		delete($classlist->{$student});
                   1608: 	    }
                   1609: 	}
                   1610:     }
                   1611:     return $classlist;
                   1612: }
                   1613: 
                   1614: 
1.14      albertel 1615: sub show_queue {
1.32      albertel 1616:     my ($queue,$with_selects)=@_;
1.14      albertel 1617:     my $result;
1.185     albertel 1618:     my ($symb,$cid,$udom,$uname)=&Apache::lonnet::whichuser();
1.14      albertel 1619:     my $cnum=$env{'course.'.$cid.'.num'};
                   1620:     my $cdom=$env{'course.'.$cid.'.domain'};
1.59      albertel 1621: 
1.237     albertel 1622:     my @chosen_sections = &get_allowed_sections();
1.156     albertel 1623: 
                   1624:     my $classlist = &get_limited_classlist(\@chosen_sections);
                   1625: 
1.63      albertel 1626:     if (!(grep(/^all$/,@chosen_sections))) {
1.239     bisitz   1627: 	$result.='<p>'
                   1628:                 .&mt('Showing only sections [_1].'
                   1629:                     ,'<tt>'.join(', ',@chosen_sections).'</tt>')
                   1630:                 ."</p>\n";
1.63      albertel 1631:     }
1.59      albertel 1632: 
1.156     albertel 1633:     my ($view,$view_section);
                   1634:     my $scope = $env{'request.course.id'};
                   1635:     if (!($view=&Apache::lonnet::allowed('vgr',$scope))) {
                   1636: 	$scope .= '/'.$env{'request.course.sec'};
                   1637: 	if ( $view = &Apache::lonnet::allowed('vgr',$scope)) {
                   1638: 	    $view_section=$env{'request.course.sec'};
                   1639: 	} else {
                   1640: 	    undef($view);
                   1641: 	}
                   1642:     }
                   1643: 
1.234     albertel 1644:     $result .= 
                   1645: 	'<p><a href="/adm/flip?postdata=return:">'.
                   1646: 	&mt('Return to resource').'</a></p><hr />'.
1.239     bisitz   1647: 	"\n<h3>".&mt('Current Queue - [_1]',$queue)."</h3>";
1.16      albertel 1648:     my $regexp="^$symb\0";
1.30      albertel 1649:     my %queue=&Apache::lonnet::dump($queue,$cdom,$cnum,$regexp);
1.31      albertel 1650:     my ($tmp)=%queue;
                   1651:     if ($tmp=~/^error: 2 /) {
1.234     albertel 1652: 	$result.=
1.159     albertel 1653: 	    &Apache::loncommon::start_data_table().
                   1654: 	    &Apache::loncommon::start_data_table_row().
                   1655: 	    '<td>'.&mt('Empty').'</td>'.
                   1656: 	    &Apache::loncommon::end_data_table_row().
                   1657: 	    &Apache::loncommon::end_data_table();
1.234     albertel 1658: 	return $result;
1.31      albertel 1659:     }
1.103     albertel 1660:     my $title=&Apache::lonnet::gettitle($symb);
1.234     albertel 1661:     $result.=
1.159     albertel 1662: 	&Apache::loncommon::start_data_table().
                   1663: 	&Apache::loncommon::start_data_table_header_row();
1.239     bisitz   1664:     if ($with_selects) { $result.='<th>'.&mt('Status').'</th><th></th>'; }
                   1665:     $result.='<th>'.&mt('User').'</th><th>'.&mt('Data').'</th>'.
1.159     albertel 1666: 	&Apache::loncommon::end_data_table_header_row();
1.14      albertel 1667:     foreach my $key (sort(keys(%queue))) {
1.59      albertel 1668: 	my ($symb,$uname,$udom) = &decode_queue_key($key);
1.235     albertel 1669: 	next if (!defined($classlist->{$uname.':'.$udom}));
1.237     albertel 1670: 	next if (!&allow_grade_user($classlist->{$uname.':'.$udom}));
1.156     albertel 1671: 	
                   1672: 	my $section = $classlist->{$uname.':'.$udom}[&Apache::loncoursedata::CL_SECTION()];
                   1673: 
                   1674: 	my $can_view=1;
                   1675: 	if (!$view
                   1676: 	    || ($view_section && !$section)
                   1677: 	    || ($view_section && $section && ($view_section ne $section))) {
                   1678: 	    $can_view=0;
                   1679: 	}
                   1680: 
1.32      albertel 1681: 	if ($key=~/locked$/ && !$with_selects) {
1.159     albertel 1682: 	    $result.= &Apache::loncommon::start_data_table_row().
                   1683: 		"<td>$uname</td>";
1.103     albertel 1684: 	    $result.='<td>'.$queue{$key}.'</td></tr>';
1.32      albertel 1685: 	} elsif ($key=~/timestamp$/ && !$with_selects) {
1.159     albertel 1686: 	    $result.=&Apache::loncommon::start_data_table_row()."<td></td>";
1.103     albertel 1687: 	    $result.='<td>'.
1.16      albertel 1688: 		&Apache::lonlocal::locallocaltime($queue{$key})."</td></tr>";
1.32      albertel 1689: 	} elsif ($key!~/(timestamp|locked)$/) {
1.159     albertel 1690: 	    $result.= &Apache::loncommon::start_data_table_row();
1.148     albertel 1691: 	    my ($end_time,$slot_text);
                   1692: 	    if (my $slot=&slotted_access($queue{$key})) {
                   1693: 		my %slot_data=&Apache::lonnet::get_slot($slot);
                   1694: 		$end_time = $slot_data{'endtime'};
                   1695: 		$slot_text = &mt('Slot: [_1]',$slot);
                   1696: 	    } else {
                   1697: 		$end_time = &Apache::lonhomework::due_date('0',$symb);
                   1698: 		$slot_text = '';
                   1699: 	    }
1.32      albertel 1700: 	    if ($with_selects) {
1.158     www      1701: 		my $ekey=&escape($key);
1.103     albertel 1702: 		my ($action,$description,$status)=('select',&mt('Select'));
1.32      albertel 1703: 		if (exists($queue{"$key\0locked"})) {
1.217     albertel 1704: 		    my ($locker,$time) = 
                   1705: 			&get_lock_info($queue{"$key\0locked"});
                   1706: 		    if ($time) {
1.214     albertel 1707: 			$time = 
                   1708: 			    &Apache::lonnavmaps::timeToHumanString($time,
                   1709: 								   'start');
                   1710: 		    }
1.138     albertel 1711: 		    my $me=$env{'user.name'}.':'.$env{'user.domain'};
1.239     bisitz   1712: 		    $status=&mt('Locked by [_1] [_2]','<tt>'.$locker.'</tt>',$time);
1.217     albertel 1713: 		    if ($me eq $locker) {
1.32      albertel 1714: 			($action,$description)=('resume',&mt('Resume'));
                   1715: 		    } else {
                   1716: 			($action,$description)=('unlock',&mt('Unlock'));
                   1717: 		    }
                   1718: 		}
1.62      albertel 1719: 		my $seclist;
                   1720: 		foreach my $sec (@chosen_sections) {
                   1721: 		    $seclist.='<input type="hidden" name="chosensections" 
                   1722:                                value="'.$sec.'" />';
                   1723: 		}
1.156     albertel 1724: 		if ($can_view && ($end_time ne '' && time > $end_time)) {
1.35      albertel 1725: 		    $result.=(<<FORM);
1.103     albertel 1726: <td>$status</td>
1.32      albertel 1727: <td>
1.115     albertel 1728: <form style="display: inline" method="post">
1.32      albertel 1729:  <input type="hidden" name="gradingkey" value="$ekey" />
                   1730:  <input type="hidden" name="queue" value="$queue" />
                   1731:  <input type="hidden" name="gradingaction" value="$action" />
                   1732:  <input type="hidden" name="webgrade" value="no" />
1.33      albertel 1733:  <input type="hidden" name="queuemode" value="selected" />
1.32      albertel 1734:  <input type="submit" name="submit" value="$description" />
1.62      albertel 1735:  $seclist
1.32      albertel 1736: </form>
                   1737: </td>
                   1738: FORM
1.156     albertel 1739:                 } elsif (!$can_view && ($end_time ne '' && time > $end_time)) {
                   1740: 		    $result.='<td>'.&mt("Not gradable").'</td><td>&nbsp;</td>'
1.35      albertel 1741:                 } else {
1.148     albertel 1742: 		    $result.='<td>'.&mt("In Progress").'</td><td>&nbsp;</td>'
1.35      albertel 1743: 		}
1.32      albertel 1744: 	    }
1.156     albertel 1745: 	    $result.= "<td>".$classlist->{$uname.':'.$udom}[&Apache::loncoursedata::CL_FULLNAME()].
1.138     albertel 1746: 		" <tt>($uname:$udom)</tt> </td>";
1.239     bisitz   1747:             $result.='<td>'.$slot_text.' '
                   1748:                     .&mt('End time: [_1]'
                   1749:                         ,&Apache::lonlocal::locallocaltime($end_time))
                   1750:                     .'</td>'
                   1751:                     .&Apache::loncommon::end_data_table_row();
1.16      albertel 1752: 	}
1.14      albertel 1753:     }
1.159     albertel 1754:     $result.= &Apache::loncommon::end_data_table()."<hr />\n";
1.14      albertel 1755:     return $result;
                   1756: }
                   1757: 
1.237     albertel 1758: sub get_allowed_sections {
                   1759:     my @chosen_sections;
                   1760:     if (&section_restricted()) {
                   1761: 	@chosen_sections = ($env{'request.course.sec'});
                   1762:     } else {
                   1763: 	@chosen_sections =
                   1764: 	    &Apache::loncommon::get_env_multiple('form.chosensections');
                   1765:     }
                   1766: 
                   1767:     return @chosen_sections;
                   1768: }
                   1769: 
1.235     albertel 1770: sub section_restricted {
1.237     albertel 1771:     my $cid =(&Apache::lonnet::whichuser())[1];
                   1772:     return (lc($env{'course.'.$cid.'.task_grading'}) eq 'section'
                   1773: 	    && $env{'request.course.sec'} ne '' );
                   1774: }
                   1775: 
                   1776: sub allow_grade_user {
1.235     albertel 1777:     my ($classlist_entry) = @_;
1.237     albertel 1778: 
                   1779:     if (&section_restricted()
1.235     albertel 1780: 	&& $env{'request.course.sec'} ne
                   1781: 	      $classlist_entry->[&Apache::loncoursedata::CL_SECTION()]) {
1.237     albertel 1782: 	return 0;
1.235     albertel 1783:     }
1.237     albertel 1784:     return 1;
1.235     albertel 1785: }
                   1786: 
1.34      albertel 1787: sub get_queue_counts {
                   1788:     my ($queue)=@_;
                   1789:     my $result;
1.185     albertel 1790:     my ($symb,$cid,$udom,$uname)=&Apache::lonnet::whichuser();
1.34      albertel 1791:     my $cnum=$env{'course.'.$cid.'.num'};
                   1792:     my $cdom=$env{'course.'.$cid.'.domain'};
1.156     albertel 1793: 
1.157     albertel 1794:     my $classlist=&get_limited_classlist();
1.156     albertel 1795: 
1.34      albertel 1796:     my $regexp="^$symb\0";
                   1797:     my %queue=&Apache::lonnet::dump($queue,$cdom,$cnum,$regexp);
                   1798:     my ($tmp)=%queue;
                   1799:     if ($tmp=~/^error: 2 /) {
                   1800: 	return (0,0,0);
                   1801:     }
1.235     albertel 1802: 
1.34      albertel 1803:     my ($entries,$ready_to_grade,$locks)=(0,0,0);
1.96      albertel 1804:     my %slot_cache;
1.34      albertel 1805:     foreach my $key (sort(keys(%queue))) {
1.156     albertel 1806: 	my ($symb,$uname,$udom) = &decode_queue_key($key);
1.235     albertel 1807: 	next if (!defined($classlist->{$uname.':'.$udom}));
1.237     albertel 1808: 	next if (!&allow_grade_user($classlist->{$uname.':'.$udom}));
1.235     albertel 1809: 
1.34      albertel 1810: 	if ($key=~/locked$/) {
                   1811: 	    $locks++;
                   1812: 	} elsif ($key=~/timestamp$/) {
                   1813: 	    #ignore
                   1814: 	} elsif ($key!~/(timestamp|locked)$/) {
                   1815: 	    $entries++;
1.148     albertel 1816: 	    if (my $slot=&slotted_access($queue{$key})) {
                   1817: 		if (!exists($slot_cache{$slot})) {
                   1818: 		    my %slot_data=&Apache::lonnet::get_slot($slot);
                   1819: 		    $slot_cache{$slot} = \%slot_data;
                   1820: 		}
                   1821: 		if (time > $slot_cache{$slot}{'endtime'}) {
                   1822: 		    $ready_to_grade++;
                   1823: 		}
                   1824: 	    } else {
                   1825: 		my $due_date = &Apache::lonhomework::due_date('0',$symb);
                   1826: 		if ($due_date ne '' && time > $due_date) {
                   1827: 		    $ready_to_grade++;
                   1828: 		}
1.34      albertel 1829: 	    }
                   1830: 	}
                   1831:     }
                   1832:     return ($entries,$ready_to_grade,$locks);
                   1833: }
                   1834: 
1.49      albertel 1835: sub encode_queue_key {
                   1836:     my ($symb,$udom,$uname)=@_;
1.138     albertel 1837:     return "$symb\0queue\0$uname:$udom";
1.49      albertel 1838: }
                   1839: 
1.14      albertel 1840: sub decode_queue_key {
                   1841:     my ($key)=@_;
                   1842:     my ($symb,undef,$user) = split("\0",$key);
1.138     albertel 1843:     my ($uname,$udom) = split(':',$user);
1.14      albertel 1844:     return ($symb,$uname,$udom);
                   1845: }
                   1846: 
                   1847: sub queue_key_locked {
1.30      albertel 1848:     my ($queue,$key,$cdom,$cnum)=@_;
1.33      albertel 1849:     if (!defined($cdom) || !defined($cnum)) {
1.185     albertel 1850: 	my (undef,$cid)=&Apache::lonnet::whichuser();
1.33      albertel 1851: 	$cnum=$env{'course.'.$cid.'.num'};
                   1852: 	$cdom=$env{'course.'.$cid.'.domain'};
                   1853:     }
1.14      albertel 1854:     my ($key_locked,$value)=
1.30      albertel 1855: 	&Apache::lonnet::get($queue,["$key\0locked"],$cdom,$cnum);
1.14      albertel 1856:     if ($key_locked eq "$key\0locked") {
1.217     albertel 1857: 	return &get_lock_info($value);
1.14      albertel 1858:     }
                   1859:     return undef;
                   1860: }
                   1861: 
1.148     albertel 1862: sub slotted_access {
                   1863:     my ($queue_entry) = @_;
                   1864:     if (ref($queue_entry) eq 'ARRAY') {
                   1865: 	if (defined($queue_entry->[0])) {
                   1866: 	    return $queue_entry->[0];
                   1867: 	}
                   1868: 	return undef;
                   1869:     } elsif (ref($queue_entry) eq 'HASH') {
                   1870: 	if (defined($queue_entry->{'slot'})) {
                   1871: 	    return $queue_entry->{'slot'};
                   1872: 	}
                   1873: 	return undef;
                   1874:     }
                   1875:     return undef;
                   1876: }
                   1877: 
1.14      albertel 1878: sub pick_from_queue_data {
1.156     albertel 1879:     my ($queue,$check_section,$queuedata,$cdom,$cnum,$classlist)=@_;
1.98      albertel 1880:     my @possible; # will hold queue entries that are valid to be selected
1.30      albertel 1881:     foreach my $key (keys(%$queuedata)) {
1.68      albertel 1882: 	if ($key =~ /\0locked$/) { next; }
                   1883: 	if ($key =~ /\0timestamp$/) { next; }
1.156     albertel 1884: 
1.14      albertel 1885: 	my ($symb,$uname,$udom)=&decode_queue_key($key);
1.235     albertel 1886: 	next if (!defined($classlist->{$uname.':'.$udom}));
1.237     albertel 1887: 	next if (!&allow_grade_user($classlist->{$uname.':'.$udom}));
1.156     albertel 1888: 
1.14      albertel 1889: 	if ($check_section) {
1.156     albertel 1890: 	    my $section =
                   1891: 		$classlist->{$uname.':'.$udom}[&Apache::loncoursedata::CL_SECTION()];
1.17      albertel 1892: 	    if ($section eq $check_section) {
1.33      albertel 1893: 		&Apache::lonxml::debug("my sec");
1.15      albertel 1894: 		next;
                   1895: 	    }
1.14      albertel 1896: 	}
1.148     albertel 1897: 	my $end_time;
                   1898: 	if (my $slot=&slotted_access($queuedata->{$key})) {
1.154     albertel 1899: 	    &Apache::lonxml::debug("looking at slot $slot");
1.148     albertel 1900: 	    my %slot_data=&Apache::lonnet::get_slot($slot);
                   1901: 	    if ($slot_data{'endtime'} < time) { 
                   1902: 		$end_time = $slot_data{'endtime'};
1.154     albertel 1903: 	    } else {
                   1904: 		&Apache::lonxml::debug("not time ".$slot_data{'endtime'});
                   1905: 		next;
1.148     albertel 1906: 	    }
                   1907: 	} else {
                   1908: 	    my $due_date = &Apache::lonhomework::due_date('0',$symb);
1.154     albertel 1909: 	    if ($due_date < time) {
1.148     albertel 1910: 		$end_time = $due_date;
1.154     albertel 1911: 	    } else {
                   1912: 		&Apache::lonxml::debug("not time $due_date");
                   1913: 		next;
1.148     albertel 1914: 	    }
                   1915: 	}
                   1916: 	
1.98      albertel 1917: 	if (exists($queuedata->{"$key\0locked"})) {
1.33      albertel 1918: 	    &Apache::lonxml::debug("someone already has um.");
1.15      albertel 1919: 	    next;
                   1920: 	}
1.148     albertel 1921: 	push(@possible,[$key,$end_time]);
1.98      albertel 1922:     }
                   1923:     if (@possible) {
                   1924:         # sort entries in order by slot end time
                   1925: 	@possible = sort { $a->[1] <=> $b->[1] } @possible;
1.137     albertel 1926: 	# pick one of the entries in the top 10% in small queues and one
                   1927: 	# of the first ten entries in large queues
1.139     albertel 1928: 	#my $ten_percent = int($#possible * 0.1);
                   1929: 	#if ($ten_percent < 1 ) { $ten_percent = 1;  }
                   1930: 	#if ($ten_percent > 10) { $ten_percent = 10; }
                   1931: 	#my $max=($#possible < $ten_percent) ? $#possible : $ten_percent;
1.137     albertel 1932: 	
1.139     albertel 1933: 	#return $possible[int(rand($max))][0];
                   1934: 	return $possible[0][0];
1.14      albertel 1935:     }
                   1936:     return undef;
                   1937: }
                   1938: 
1.217     albertel 1939: sub get_lock_info {
                   1940:     my ($lock_info) = @_;
                   1941:     if (wantarray) {
                   1942: 	if (ref($lock_info) eq 'ARRAY') {
                   1943: 	    return @{$lock_info};
                   1944: 	} else {
                   1945: 	    return ($lock_info);
                   1946: 	}
                   1947:     } else {
                   1948: 	if (ref($lock_info) eq 'ARRAY') {
                   1949: 	    return $lock_info->[0];
                   1950: 	} else {
                   1951: 	    return $lock_info;
                   1952: 	}
                   1953:     }
                   1954:     return;
                   1955: }
                   1956: 
1.15      albertel 1957: sub find_mid_grade {
1.30      albertel 1958:     my ($queue,$symb,$cdom,$cnum)=@_;
1.158     www      1959:     my $todo=&unescape($env{'form.gradingkey'});
1.138     albertel 1960:     my $me=$env{'user.name'}.':'.$env{'user.domain'};
1.15      albertel 1961:     if ($todo) {
1.30      albertel 1962: 	my $who=&queue_key_locked($queue,$todo,$cdom,$cnum);
1.15      albertel 1963: 	if ($who eq $me) { return $todo; }
                   1964:     }
                   1965:     my $regexp="^$symb\0.*\0locked\$";
1.30      albertel 1966:     my %locks=&Apache::lonnet::dump($queue,$cdom,$cnum,$regexp);
1.15      albertel 1967:     foreach my $key (keys(%locks)) {
1.217     albertel 1968: 	my $who= &get_lock_info($locks{$key});
1.15      albertel 1969: 	if ($who eq $me) {
                   1970: 	    $todo=$key;
                   1971: 	    $todo=~s/\0locked$//;
                   1972: 	    return $todo;
                   1973: 	}
                   1974:     }
                   1975:     return undef;
                   1976: }
                   1977: 
1.32      albertel 1978: sub lock_key {
                   1979:     my ($queue,$todo)=@_;
1.138     albertel 1980:     my $me=$env{'user.name'}.':'.$env{'user.domain'};
1.185     albertel 1981:     my (undef,$cid)=&Apache::lonnet::whichuser();
1.32      albertel 1982:     my $cnum=$env{'course.'.$cid.'.num'};
                   1983:     my $cdom=$env{'course.'.$cid.'.domain'};
1.214     albertel 1984:     my $success=&Apache::lonnet::newput($queue,{"$todo\0locked"=> [$me,time]},
1.32      albertel 1985: 					$cdom,$cnum);
1.33      albertel 1986:     &Apache::lonxml::debug("success $success $todo");
1.32      albertel 1987:     if ($success eq 'ok') {
                   1988: 	return 1;
                   1989:     }
                   1990:     return 0;
                   1991: }
                   1992: 
1.86      albertel 1993: sub get_queue_symb_status {
1.85      albertel 1994:     my ($queue,$symb,$cdom,$cnum) = @_;
                   1995:     if (!defined($cdom) || !defined($cnum)) {
1.235     albertel 1996: 	my (undef,$cid) =&Apache::lonnet::whichuser();
1.85      albertel 1997: 	$cnum=$env{'course.'.$cid.'.num'};
                   1998: 	$cdom=$env{'course.'.$cid.'.domain'};
                   1999:     }
1.157     albertel 2000:     my $classlist=&get_limited_classlist();
1.156     albertel 2001: 
1.85      albertel 2002:     my $regexp="^$symb\0";
                   2003:     my %queue=&Apache::lonnet::dump($queue,$cdom,$cnum,$regexp);
                   2004:     my ($tmp)=%queue;
                   2005:     if ($tmp=~/^error: 2 /) { return; }
                   2006:     my @users;
                   2007:     foreach my $key (sort(keys(%queue))) {
                   2008: 	next if ($key=~/locked$/);
                   2009: 	next if ($key=~/timestamp$/);
                   2010: 	my ($symb,$uname,$udom) = &decode_queue_key($key);
1.156     albertel 2011: 	next if (!defined($classlist->{$uname.':'.$udom}));
1.237     albertel 2012: 	next if (!&allow_grade_user($classlist->{$uname.':'.$udom}));
1.85      albertel 2013: 	push(@users,"$uname:$udom");
                   2014:     }
                   2015:     return @users;
                   2016: }
                   2017: 
1.14      albertel 2018: sub get_from_queue {
1.30      albertel 2019:     my ($queue)=@_;
1.14      albertel 2020:     my $result;
1.185     albertel 2021:     my ($symb,$cid,$udom,$uname)=&Apache::lonnet::whichuser();
1.14      albertel 2022:     my $cnum=$env{'course.'.$cid.'.num'};
                   2023:     my $cdom=$env{'course.'.$cid.'.domain'};
1.32      albertel 2024:     my $todo=&find_mid_grade($queue,$symb,$cdom,$cnum);
1.33      albertel 2025:     &Apache::lonxml::debug("found ".join(':',&decode_queue_key($todo)));
1.16      albertel 2026:     if ($todo) { return $todo; }
1.95      albertel 2027:     my $attempts=0;
1.156     albertel 2028: 
1.157     albertel 2029:     my $classlist=&get_limited_classlist();
1.156     albertel 2030: 
1.14      albertel 2031:     while (1) {
1.95      albertel 2032: 	if ($attempts > 2) {
                   2033: 	    # tried twice to get a queue entry, giving up
                   2034: 	    return (undef,'unable');
                   2035: 	}
1.14      albertel 2036: 	my $starttime=time;
1.83      albertel 2037: 	&Apache::lonnet::cput($queue,{"$symb\0timestamp"=>$starttime},
                   2038: 			      $cdom,$cnum);
1.33      albertel 2039: 	&Apache::lonxml::debug("$starttime");
1.14      albertel 2040: 	my $regexp="^$symb\0queue\0";
1.156     albertel 2041: 	#my $range= ($attempts < 1 ) ? '0-100' : '0-400';
1.97      albertel 2042: 
1.98      albertel 2043: 	my %queue=&Apache::lonnet::dump($queue,$cdom,$cnum,$regexp);
1.33      albertel 2044: 	#make a pass looking for a user _not_ in my section
1.14      albertel 2045: 	if ($env{'request.course.sec'}) {
1.33      albertel 2046: 	    &Apache::lonxml::debug("sce");
1.30      albertel 2047: 	    $todo=&pick_from_queue_data($queue,$env{'request.course.sec'},
1.156     albertel 2048: 					\%queue,$cdom,$cnum,$classlist);
1.33      albertel 2049: 	    &Apache::lonxml::debug("sce $todo");
1.14      albertel 2050: 	}
1.33      albertel 2051: 	# no one _not_ in our section so look for any user that is
                   2052: 	# ready for grading
1.14      albertel 2053: 	if (!$todo) {
1.33      albertel 2054: 	    &Apache::lonxml::debug("no sce");
1.156     albertel 2055: 	    $todo=&pick_from_queue_data($queue,undef,\%queue,$cdom,$cnum,
                   2056: 					$classlist);
1.33      albertel 2057: 	    &Apache::lonxml::debug("no sce $todo");
1.14      albertel 2058: 	}
                   2059: 	# no user to grade 
                   2060: 	if (!$todo) { last; }
1.33      albertel 2061: 	&Apache::lonxml::debug("got $todo");
1.14      albertel 2062: 	# otherwise found someone so lets try to lock them
1.32      albertel 2063: 	# unless someone else already picked them
1.95      albertel 2064: 	if (!&lock_key($queue,$todo)) {
                   2065: 	    $attempts++;
                   2066: 	    next;
                   2067: 	}
1.14      albertel 2068: 	my (undef,$endtime)=
1.30      albertel 2069: 	    &Apache::lonnet::get($queue,["$symb\0timestamp"],
1.14      albertel 2070: 				 $cdom,$cnum);
1.33      albertel 2071: 	&Apache::lonxml::debug("emd  $endtime");
1.14      albertel 2072: 	# someone else already modified the queue, 
                   2073: 	# perhaps our picked user wass already fully graded between
                   2074: 	# when we picked him and when we locked his record? so lets
                   2075: 	# double check.
                   2076: 	if ($endtime != $starttime) {
                   2077: 	    my ($key,$value)=
1.30      albertel 2078: 		&Apache::lonnet::get($queue,["$todo"],
1.14      albertel 2079: 				     $cdom,$cnum);
1.33      albertel 2080: 	    &Apache::lonxml::debug("check  $key .. $value");
1.14      albertel 2081: 	    if ($key eq $todo && ref($value)) {
                   2082: 	    } else {
1.30      albertel 2083: 		&Apache::lonnet::del($queue,["$todo\0locked"],
1.14      albertel 2084: 				     $cdom,$cnum);
1.33      albertel 2085: 		&Apache::lonxml::debug("del");
1.95      albertel 2086: 		$attempts++;
1.14      albertel 2087: 		next;
                   2088: 	    }
                   2089: 	}
1.33      albertel 2090: 	&Apache::lonxml::debug("last $todo");
1.14      albertel 2091: 	last;
                   2092:     }
                   2093:     return $todo;
                   2094: }
                   2095: 
1.49      albertel 2096: sub select_user {
1.185     albertel 2097:     my ($symb,$cid)=&Apache::lonnet::whichuser();
1.49      albertel 2098: 
1.237     albertel 2099:     my @chosen_sections = &get_allowed_sections();
1.156     albertel 2100:     my $classlist = &get_limited_classlist(\@chosen_sections);
1.63      albertel 2101:     
                   2102:     my $result;
                   2103:     if (!(grep(/^all$/,@chosen_sections))) {
1.239     bisitz   2104:         $result.='<p>'
                   2105:                 .&mt('Showing only sections [_1].'
                   2106:                     ,'<tt>'.join(', ',@chosen_sections).'</tt>')
                   2107:                 .'</p> '."\n";
1.63      albertel 2108:     }
1.159     albertel 2109:     $result.=&Apache::loncommon::start_data_table();
1.49      albertel 2110: 
1.156     albertel 2111:     foreach my $student (sort {lc($classlist->{$a}[&Apache::loncoursedata::CL_FULLNAME()]) cmp lc($classlist->{$b}[&Apache::loncoursedata::CL_FULLNAME()]) } (keys(%$classlist))) {
1.49      albertel 2112: 	my ($uname,$udom) = split(/:/,$student);
1.59      albertel 2113: 	
1.84      albertel 2114: 	my $cnum=$env{'course.'.$cid.'.num'};
                   2115: 	my $cdom=$env{'course.'.$cid.'.domain'};
1.88      albertel 2116: 	my %status = &get_student_status($symb,$cdom,$cnum,$udom,$uname,
                   2117: 					 'Task');
1.49      albertel 2118: 	my $queue = 'none';
1.58      albertel 2119: 	my $cannot_grade;
                   2120: 	if ($status{'reviewqueue'} =~ /^(in_progress|enqueue)$/) {
1.49      albertel 2121: 	    $queue = 'reviewqueue';
1.58      albertel 2122: 	    if ($status{'reviewqueue'} eq 'in_progress') {
                   2123: 		$cannot_grade=1;
                   2124: 	    }
                   2125: 	} elsif ($status{'gradingqueue'} =~ /^(in_progress|enqueue)$/) {
1.49      albertel 2126: 	    $queue = 'gradingqueue';
1.58      albertel 2127: 	    if ($status{'gradingqueue'} eq 'in_progress') {
                   2128: 		$cannot_grade=1;
                   2129: 	    }
1.49      albertel 2130: 	}
                   2131: 	my $todo = 
1.158     www      2132: 	    &escape(&encode_queue_key($symb,$udom,$uname));
1.58      albertel 2133: 	if ($cannot_grade) {
1.159     albertel 2134: 	    $result.=&Apache::loncommon::start_data_table_row().
                   2135: 		'<td>&nbsp;</td><td>'.$classlist->{$student}[&Apache::loncoursedata::CL_FULLNAME()].
1.58      albertel 2136: 		'</td><td>';
                   2137: 	} else {
1.62      albertel 2138: 	    my $seclist;
                   2139: 	    foreach my $sec (@chosen_sections) {
                   2140: 		$seclist.='<input type="hidden" name="chosensections" 
                   2141:                                value="'.$sec.'" />';
                   2142: 	    }
1.242     bisitz   2143:             my $buttontext=&mt('Regrade');
1.159     albertel 2144: 	    $result.=&Apache::loncommon::start_data_table_row();
1.58      albertel 2145: 	    $result.=<<RESULT;
1.49      albertel 2146:   <td>
1.115     albertel 2147:     <form style="display: inline" method="post">
1.49      albertel 2148:       <input type="hidden" name="gradingkey" value="$todo" />
                   2149:       <input type="hidden" name="queue" value="$queue" />
                   2150:       <input type="hidden" name="webgrade" value="no" />
1.52      albertel 2151:       <input type="hidden" name="regrade" value="yes" />
1.242     bisitz   2152:       <input type="submit" name="submit" value="$buttontext" />
1.62      albertel 2153:       $seclist
1.49      albertel 2154:     </form>
1.237     albertel 2155:   <td>$classlist->{$student}[&Apache::loncoursedata::CL_FULLNAME()] <tt>($student)</tt> Sec: $classlist->{$student}[&Apache::loncoursedata::CL_SECTION()]</td>
1.49      albertel 2156:   <td>
                   2157: RESULT
1.58      albertel 2158:         }
1.49      albertel 2159:         if ($status{'status'} eq 'pass') {
                   2160: 	    $result .= '<font color="green">'.&mt('Passed').'</font>';
                   2161: 	} elsif ($status{'status'} eq 'fail') {
                   2162: 	    $result .= '<font color="red">'.&mt('Failed').'</font>';
                   2163: 	} elsif ($status{'status'} eq 'review') {
                   2164: 	    $result .= '<font color="blue">'.&mt('Under Review').'</font>';
                   2165: 	} elsif ($status{'status'} eq 'ungraded') {
                   2166: 	    $result .= &mt('Ungraded');
                   2167: 	} elsif ($status{'status'} ne '') {
                   2168: 	    $result .= '<font color="orange">'.&mt('Unknown Status').'</font>';
                   2169: 	} else {
                   2170: 	    $result.="&nbsp;";
                   2171: 	}
                   2172: 	if ($status{'version'}) {
                   2173: 	    $result .= ' '.&mt('Version').' '.$status{'version'};
                   2174: 	}
1.101     albertel 2175: 	if ($status{'grader'}) {
                   2176: 	    $result .= ' '.&mt('(Graded by [_1])',$status{'grader'}).' ';
                   2177: 	}
1.49      albertel 2178: 	$result.= '</td><td>';
                   2179: 	if ($status{'reviewqueue'} eq 'enqueued') {
                   2180: 	    $result .= &mt('Awaiting Review');
                   2181: 	} elsif ($status{'reviewqueue'} eq 'locked') {
                   2182: 	    $result .= &mt('Under Review');
1.58      albertel 2183: 	} elsif ($status{'reviewqueue'} eq 'in_progress') {
                   2184: 	    $result .= &mt('Still being worked on.');
1.49      albertel 2185: 	} elsif ($status{'gradingqueue'} eq 'enqueued') {
                   2186: 	    $result .= &mt('Awaiting Grading');
                   2187: 	} elsif ($status{'gradingqueue'} eq 'locked') {
                   2188: 	    $result .= &mt('Being Graded');
1.58      albertel 2189: 	} elsif ($status{'gradingqueue'} eq 'in_progress') {
                   2190: 	    $result .= &mt('Still being worked on.');
1.49      albertel 2191: 	} else {
                   2192: 	    $result.="&nbsp;";
                   2193: 	}
1.159     albertel 2194: 	$result.= '</td>'.&Apache::loncommon::end_data_table_row();
1.49      albertel 2195:     }
1.159     albertel 2196:     $result.=&Apache::loncommon::end_data_table();
1.49      albertel 2197:     return $result;
                   2198: }
                   2199: 
                   2200: sub get_student_status {
1.86      albertel 2201:     my ($symb,$cdom,$cnum,$udom,$uname,$type)=@_;
                   2202: 
                   2203:     my %status;
                   2204: 
                   2205:     if ($type eq 'Task') {
                   2206: 	my %record = &Apache::lonnet::restore($symb,$env{'request.course.id'},
1.49      albertel 2207: 					  $udom,$uname);
1.89      albertel 2208: 	$status{'status'}=$record{'resource.0.status'};
                   2209: 	$status{'version'}=$record{'resource.0.version'};
                   2210: 	$status{'grader'}=$record{'resource.0.regrader'};
1.86      albertel 2211:     }
                   2212:     $status{'reviewqueue'}=
                   2213: 	&check_queue_for_key($cdom,$cnum,'reviewqueue',
                   2214: 			     &encode_queue_key($symb,$udom,$uname));
                   2215:     $status{'gradingqueue'}=
                   2216: 	&check_queue_for_key($cdom,$cnum,'gradingqueue',
                   2217: 			     &encode_queue_key($symb,$udom,$uname));
1.49      albertel 2218:     return %status;
                   2219: }
                   2220: 
1.1       albertel 2221: sub start_ClosingParagraph {
                   2222:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
                   2223:     my $result;
                   2224:     if ($target eq 'web') {
1.13      albertel 2225:     } elsif ($target eq 'webgrade') {
                   2226: 	&Apache::lonxml::startredirection();
1.225     albertel 2227:     } elsif ($target eq 'edit') {
                   2228: 	$result = &Apache::edit::tag_start($target,$token);
                   2229:     } elsif ($target eq 'modified') {
1.1       albertel 2230:     }
                   2231:     return $result;
                   2232: }
                   2233: 
                   2234: sub end_ClosingParagraph {
                   2235:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
                   2236:     my $result;
                   2237:     if ($target eq 'web') {
1.13      albertel 2238:     } elsif ($target eq 'webgrade') {
                   2239: 	&Apache::lonxml::endredirection();
1.1       albertel 2240:     }
                   2241:     return $result;
                   2242: }
                   2243: 
1.227     albertel 2244: sub insert_ClosingParagraph {
                   2245:     return '
                   2246: <ClosingParagraph>
                   2247:     <startouttext />
                   2248:     <endouttext />
                   2249: </ClosingParagraph>';
                   2250: }
                   2251: 
1.168     albertel 2252: sub get_dim_id {
1.194     albertel 2253:     if (@Apache::bridgetask::dimension) {
                   2254: 	return $Apache::bridgetask::dimension[-1];
                   2255:     } else {
                   2256: 	return $top;
                   2257:     }
1.168     albertel 2258: }
                   2259: 
1.19      albertel 2260: sub get_id {
                   2261:     my ($parstack,$safeeval)=@_;
1.236     albertel 2262:     return &Apache::lonxml::get_id($parstack,$safeeval);
1.19      albertel 2263: }
                   2264: 
1.162     albertel 2265: sub start_Setup {
                   2266:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
1.225     albertel 2267:     my $result;
1.168     albertel 2268:     my $dim = &get_id($parstack,$safeeval);
                   2269:     push(@Apache::bridgetask::dimension,$dim);
1.225     albertel 2270:     if ($target eq 'web' || $target eq 'webgrade' || $target eq 'grade') {
                   2271: 	&Apache::lonxml::startredirection();
                   2272:     } elsif ($target eq 'edit') {
                   2273: 	$result = &Apache::edit::tag_start($target,$token);
                   2274: 	$result.= &Apache::edit::text_arg('Id:','id',$token,10).
                   2275: 	    &Apache::edit::end_row().
                   2276: 	    &Apache::edit::start_spanning_row();
                   2277:     } elsif ($target eq 'modified') {
                   2278: 	my $constructtag=
                   2279: 	    &Apache::edit::get_new_args($token,$parstack,$safeeval,'id');
                   2280: 	if ($constructtag) {
                   2281: 	    $result = &Apache::edit::rebuild_tag($token);
                   2282: 	}
                   2283:     }
                   2284:     return $result;
1.162     albertel 2285: }
1.173     albertel 2286: 
                   2287: {
                   2288:     my @allowed;
                   2289:     sub enable_dimension_parsing {
                   2290: 	my ($id) = @_;
                   2291: 	push(@allowed,$id);
                   2292:     }
                   2293:     sub disable_dimension_parsing {
                   2294: 	pop(@allowed);
                   2295:     }
                   2296:     sub skip_dimension_parsing {
                   2297: 	my ($check) = @_;
                   2298: 	if (!@allowed) { return 0;}
                   2299: 	# if unspecified allow any id
                   2300: 	if ($allowed[-1] eq undef) { return 0;}
                   2301: 
                   2302: 	return ($check ne $allowed[-1]);
                   2303:     }
                   2304: }
                   2305: 
1.151     albertel 2306: sub start_Question { return &start_Dimension(@_); }
1.1       albertel 2307: sub start_Dimension {
1.173     albertel 2308:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.168     albertel 2309:     my $dim = &get_id($parstack,$safeeval);
                   2310:     my $previous_dim;
1.225     albertel 2311:     my $result;
                   2312:     if ($target eq 'grade' || $target eq 'web' || $target eq 'webgrade') {
                   2313: 	if (@Apache::bridgetask::dimension) {
                   2314: 	    $previous_dim = $Apache::bridgetask::dimension[-1];
                   2315: 	    push(@{$Apache::bridgetask::dimension{$previous_dim}{'contains'}},
                   2316: 		 $dim);
                   2317: 	    if(&skip_dimension_parsing($dim)) {
                   2318: 		$dimension{$previous_dim}{'criteria.'.$dim} =
                   2319: 		    $token->[4]
                   2320: 		    .&Apache::lonxml::get_all_text('/'.$tagstack->[-1],$parser,
                   2321: 						   $style)
                   2322: 		    .'</'.$tagstack->[-1].'>';
                   2323: 	    }
                   2324: 	    $dimension{$previous_dim}{'criteria.'.$dim.'.type'}='dimension';
                   2325: 	    $dimension{$previous_dim}{'criteria.'.$dim.'.mandatory'}=
                   2326: 		&Apache::lonxml::get_param('Mandatory',$parstack,$safeeval);
                   2327: 	    push(@{$dimension{$previous_dim}{'criterias'}},$dim);
                   2328: 	    $dimension{$dim}{'nested'}=$previous_dim;
                   2329: 	    $dimension{$dim}{'depth'} = 1 + $dimension{$previous_dim}{'depth'};
                   2330: 	    
                   2331: 	    &Apache::lonxml::debug("adding $dim as criteria to $previous_dim");
                   2332: 	} else {
                   2333: 	    $dimension{$top}{'depth'}=0;
                   2334: 	    $dimension{$top}{'criteria.'.$dim.'.type'}='dimension';
                   2335: 	    $dimension{$top}{'criteria.'.$dim.'.mandatory'}=
                   2336: 		&Apache::lonxml::get_param('Mandatory',$parstack,$safeeval);
                   2337: 	    push(@{$dimension{$top}{'criterias'}},$dim);
                   2338: 	    $dimension{$dim}{'nested'}=$top;
                   2339: 	}
                   2340:         push(@Apache::bridgetask::dimension,$dim);
                   2341: 	&Apache::lonxml::startredirection();
                   2342: 	if (!&skip_dimension_parsing($dim)) {
                   2343: 	    &enable_dimension_parsing($dim);
                   2344: 	}
                   2345:     } elsif ($target eq 'edit') {
                   2346:   	$result = &Apache::edit::tag_start($target,$token);
                   2347: 	$result.=  
                   2348: 	    &Apache::edit::text_arg('Id:','id',$token,10).' '.
                   2349: 	    &Apache::edit::select_arg('Passing is Mandatory:','Mandatory',
1.233     albertel 2350: 				      [['Y', 'Yes'],
                   2351: 				       ['N','No'],],
1.225     albertel 2352: 				      $token).' <br /> '.
                   2353: 	    &Apache::edit::text_arg('Required number of passed optional elements to pass the '.$token->[1].':',
                   2354: 				    'OptionalRequired',$token,4).
                   2355: 	    &Apache::edit::end_row().
                   2356: 	    &Apache::edit::start_spanning_row();
                   2357:     } elsif ($target eq 'modified') {
                   2358: 	my $constructtag=
                   2359: 	    &Apache::edit::get_new_args($token,$parstack,$safeeval,
                   2360: 					'id','Mandatory','OptionalRequired');
                   2361: 	if ($constructtag) {
                   2362: 	    $result = &Apache::edit::rebuild_tag($token);
                   2363: 	}
1.168     albertel 2364:     }
1.225     albertel 2365:     return $result;# &internal_location($dim);
1.1       albertel 2366: }
                   2367: 
1.160     albertel 2368: sub start_QuestionText {
                   2369:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.225     albertel 2370:     my $result;
                   2371:     if ($target eq 'grade' || $target eq 'web' || $target eq 'webgrade') {
                   2372: 	my $text=&Apache::lonxml::get_all_text('/questiontext',$parser,$style);
1.168     albertel 2373:     my $dim = &get_dim_id();
1.169     albertel 2374: 	$dimension{$dim}{'questiontext'}=$text;
1.225     albertel 2375:     } elsif ($target eq 'edit') {
                   2376: 	$result = &Apache::edit::tag_start($target,$token);
                   2377:     } elsif ($target eq 'modified') {
1.160     albertel 2378:     }
1.225     albertel 2379:     return $result;
1.160     albertel 2380: }
                   2381: 
                   2382: sub end_QuestionText {
                   2383:     return '';
                   2384: }
                   2385: 
1.227     albertel 2386: sub insert_QuestionText {
                   2387:     return '
                   2388: <QuestionText>
                   2389:     <startouttext />
                   2390:     <endouttext />
                   2391: </QuestionText>';
                   2392: }
                   2393: 
1.13      albertel 2394: sub get_instance {
1.75      albertel 2395:     my ($dim)=@_;
                   2396:     my $rand_alg=&Apache::lonnet::get_rand_alg();
                   2397:     if (!$rand_alg || $rand_alg eq '32bit' || $rand_alg eq '64bit' ||
                   2398: 	$rand_alg eq '64bit2' || $rand_alg eq '64bit3' ||
                   2399: 	$rand_alg eq '64bit4' ) {
                   2400: 	&Apache::response::pushrandomnumber();
1.169     albertel 2401: 	my @order=&Math::Random::random_permutation(@{$dimension{$dim}{'instances'}});
1.75      albertel 2402: 	my $num=@order;
                   2403: 	my $version=&get_version();
                   2404: 	my $which=($version-1)%$num;
                   2405: 	return $order[$which];
                   2406:     } else {
                   2407: 	my ($version,$previous) = &get_version();
                   2408: 	my $instance = 
                   2409: 	    $Apache::lonhomework::history{"resource.$version.0.$dim.instance"};
                   2410: 	if (defined($instance)) { return $instance; }
                   2411: 
                   2412: 	&Apache::response::pushrandomnumber();
1.173     albertel 2413: 	if (ref($dimension{$dim}{'instances'}) eq 'ARRAY') {
                   2414: 	    my @instances = @{$dimension{$dim}{'instances'}};
                   2415: 	    # remove disabled instances
                   2416: 	    for (my $i=0; $i < $#instances; $i++) {
                   2417: 		if ($dimension{$dim}{$instances[$i].'.disabled'}) {
                   2418: 		    splice(@instances,$i,1);
                   2419: 		    $i--;
                   2420: 		}
                   2421: 	    }
                   2422: 	    @instances = &Math::Random::random_permutation(@instances);
                   2423: 	    $instance  = $instances[($version-1)%scalar(@instances)];
                   2424: 	    if ($version =~ /^\d$/) {
                   2425: 		$Apache::lonhomework::results{"resource.$version.0.$dim.instance"} = 
                   2426: 		    $instance;
                   2427: 		$Apache::lonhomework::results{'INTERNAL_store'} = 1; 
1.75      albertel 2428: 	    }
                   2429: 	}
                   2430: 	&Apache::response::poprandomnumber();
                   2431: 	return $instance;
                   2432:     }
1.13      albertel 2433: }
                   2434: 
1.169     albertel 2435: sub get_criteria {
                   2436:     my ($what,$version,$dim,$id) = @_;
                   2437:     my $type = $dimension{$dim}{'criteria.'.$id.'.type'};
1.194     albertel 2438:     my $prefix = ($type eq 'criteria' && $dim ne $top) ? "$dim.$id"
                   2439: 	                                               : "$id";
1.169     albertel 2440:     my $entry = "resource.$version.0.$prefix.$what";
                   2441:     if (exists($Apache::lonhomework::results{$entry})) {
                   2442: 	return $Apache::lonhomework::results{$entry};
                   2443:     }
                   2444:     return $Apache::lonhomework::history{$entry};
                   2445: }
                   2446: 
1.194     albertel 2447: sub link {
                   2448:     my ($id) = @_;
                   2449:     $id =~ s/\./_/g;
                   2450:     return 'LC_GRADING_criteria_'.$id;
                   2451: }
                   2452: sub end_Question { return &end_Dimension(@_); }
                   2453: sub end_Dimension {
                   2454:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
1.225     albertel 2455:     my $result;
1.194     albertel 2456:     my $dim=&get_id($parstack,$safeeval);
1.225     albertel 2457:     if ($target eq 'grade' || $target eq 'web' || $target eq 'webgrade') {
                   2458: 	$result=&Apache::lonxml::endredirection();
                   2459: 	if (&skip_dimension_parsing($dim)) {
                   2460: 	    pop(@Apache::bridgetask::dimension);
                   2461: 	    return;
                   2462: 	}
1.122     albertel 2463:     }
1.194     albertel 2464:     my $instance=&get_instance($dim);
                   2465:     my $version=&get_version();
                   2466:     if ($target eq 'web') {
                   2467: 	$result .= &nested_parse(\$dimension{$dim}{'intro'},[@_]);
                   2468: 	my @instances = $instance;
                   2469: 	if (&Apache::response::showallfoils()) {
                   2470: 	    @instances = @{$dimension{$dim}{'instances'}};
1.173     albertel 2471: 	}
1.194     albertel 2472: 	my $shown_question_text;
                   2473: 	foreach my $instance (@instances) {
                   2474: 	    $result .= &nested_parse(\$dimension{$dim}{$instance.'.text'},
                   2475: 				     [@_]);
                   2476: 	    $result .= &nested_parse(\$dimension{$dim}{'questiontext'},
                   2477: 				     [@_],{'set_dim_id' => undef});
                   2478: 	    my $task_status = 
                   2479: 		$Apache::lonhomework::history{"resource.$version.0.status"};
                   2480: 	    if ($task_status ne 'pass' && $task_status ne 'fail') {
                   2481: 		
                   2482: 		foreach my $id (@{$dimension{$dim}{$instance.'.criterias'}},
                   2483: 				@{$dimension{$dim}{'criterias'}}) {
                   2484: 		    my $type = $dimension{$dim}{'criteria.'.$id.'.type'};
                   2485: 		    &Apache::lonxml::debug("$id is $type");
                   2486: 		    if ($type eq 'dimension') {
                   2487: 			$result.=
                   2488: 			    &nested_parse(\$dimension{$dim}{'criteria.'.$id},
                   2489: 					  [@_],{'set_dim_id' => $id});
1.173     albertel 2490: 		    }
1.194     albertel 2491: 		}
                   2492: 	    } else {
                   2493: 		my $dim_status=$Apache::lonhomework::history{"resource.$version.0.$dim.status"};
                   2494: 		my $mandatory='Mandatory';
                   2495: 		if (&Apache::lonxml::get_param('Mandatory',$parstack,$safeeval) eq 'N') {
                   2496: 		    $mandatory='Optional';
                   2497: 		}
1.200     albertel 2498: 		my $dim_info=
                   2499: 		    "\n<div class='LC_$dim_status LC_question_grade'>\n\t";
1.212     albertel 2500: 		my $ucquestion = 
                   2501: 		    my $question = 
                   2502: 		    ('sub' x $dimension{$dim}{'depth'}).'question';
                   2503: 		$ucquestion =~ s/^(.)/uc($1)/e;
1.194     albertel 2504: 		if ($dim_status eq 'pass') {
1.239     bisitz   2505:                     $dim_info.='<h3>'.$ucquestion.' : '
                   2506:                               .&mt('you passed this [_1] [_2]',$mandatory,$question)
                   2507:                               .'</h3>';
1.194     albertel 2508: 		}
                   2509: 		if ($dim_status eq 'fail') {
1.239     bisitz   2510:                     $dim_info.='<h3>'.$ucquestion.' : '
                   2511:                               .&mt('you did not pass this [_1] [_2]',$mandatory,$question)
                   2512:                               .'</h3>';
1.194     albertel 2513: 		}
1.197     albertel 2514: 		my %counts = &get_counts($dim,$instance,$parstack,
                   2515: 					 $safeeval);
                   2516: 
1.200     albertel 2517: 		$dim_info.="\n\t<p>"
1.197     albertel 2518: 		    .&question_status_message(\%counts,
                   2519: 					      $dimension{$dim}{'depth'})
1.200     albertel 2520: 		    ."</p>\n</div>\n";
1.194     albertel 2521: 		
                   2522: 		foreach my $id (@{$dimension{$dim}{$instance.'.criterias'}},
                   2523: 				@{$dimension{$dim}{'criterias'}}) {
                   2524: 		    my $type = $dimension{$dim}{'criteria.'.$id.'.type'};
                   2525: 		    if ($type eq 'dimension') {
1.205     albertel 2526: 			if (defined($dimension{$id}{'result'})) {
                   2527: 			    $result.=$dimension{$id}{'result'};
                   2528: 			    next;
                   2529: 			} else {
                   2530: 			    $dim_info .=
                   2531: 				&nested_parse(\$dimension{$dim}{'criteria.'.$id},
                   2532: 					      [@_],{'set_dim_id' => $id});
                   2533: 			}
                   2534: 		    } else {
                   2535: 			my $criteria =
                   2536: 			    &nested_parse(\$dimension{$dim}{'criteria.'.$id},
                   2537: 					  [@_]);
                   2538: 			$dim_info .= &layout_web_Criteria($dim,$id,$criteria);
1.194     albertel 2539: 		    }
1.169     albertel 2540: 		}
1.202     albertel 2541: 		# puts the results at the end of the dimension
1.226     albertel 2542: 		if ($result =~m{<QuestionGradeInfo\s*/>}) {
                   2543: 		    $result=~s{<QuestionGradeInfo\s*/>}{$dim_info};
                   2544: 		} else {
                   2545: 		    $result .= $dim_info;
                   2546: 		}
1.202     albertel 2547: 		# puts the results at the beginning of the dimension
                   2548: 		# my $internal_location=&internal_location($dim);
                   2549: 		# $result=~s/\Q$internal_location\E/$dim_info/;
1.19      albertel 2550: 	    }
1.194     albertel 2551: 	}
1.206     albertel 2552: 	if ($result !~ /^\s*$/s) {
1.209     albertel 2553: 	    # FIXME? this maybe unneccssary in the future, (CSE101 BT
                   2554: 	    # from Fall 2006 geenrate a div that attempts to hide some
                   2555: 	    # of the output in an odd way, this is a workaround so
                   2556: 	    # those old ones will continue to work.  # It puts the
                   2557: 	    # LC_question div to come after any starting closie div
                   2558: 	    # that the dimension produces
1.211     albertel 2559: 	    if ($result =~ m{^\s*</div>}) {
                   2560: 		$result =~ s{^(\s*</div>)}
1.210     albertel 2561: 		            {$1\n<div id="$dim" class="LC_question">};
1.209     albertel 2562: 	    } else {
1.210     albertel 2563: 		$result = "\n".'<div id="'.$dim.'" class="LC_question">'.
1.209     albertel 2564: 		    "\n".$result;
                   2565: 	    }
                   2566: 	    $result .= "\n</div>\n";
1.206     albertel 2567: 	}
1.194     albertel 2568:     } elsif ($target eq 'webgrade') {
                   2569: 	# in case of any side effects that we need
                   2570: 	&nested_parse(\$dimension{$dim}{'intro'},[@_]);
                   2571: 	&nested_parse(\$dimension{$dim}{$instance.'.text'},[@_]);
                   2572: 	$result.=
                   2573: 	    &nested_parse(\$dimension{$dim}{'questiontext'},[@_],
                   2574: 			  {'set_dim_id'          => undef,
1.195     albertel 2575: 			   'delayed_dim_results' => 1});
1.194     albertel 2576: 	foreach my $id (@{$dimension{$dim}{$instance.'.criterias'}},
                   2577: 			@{$dimension{$dim}{'criterias'}} ) {
                   2578: 	    my $type = $dimension{$dim}{'criteria.'.$id.'.type'};
                   2579: 	    if ($type eq 'dimension') {
                   2580: 		# dimensional 'criteria' don't get assigned grades
                   2581: 		$result.=
                   2582: 		    &nested_parse(\$dimension{$dim}{'criteria.'.$id},
                   2583: 				  [@_],{'set_dim_id' => $id});
                   2584: 		next;
                   2585: 	    } else {
                   2586: 		my $criteria =&nested_parse(\$dimension{$dim}{'criteria.'.$id},
                   2587: 					     [@_]);
                   2588: 		$criteria = &layout_webgrade_Criteria($dim,$id,$criteria);
                   2589: 		my $internal_location=&internal_location($id);
1.209     albertel 2590: 		if ($result =~ m/\Q$internal_location\E/) {
                   2591: 		    $result =~ s/\Q$internal_location\E/$criteria/;
                   2592: 		} else {
                   2593: 		    $result.=$criteria ;
                   2594: 		}
1.151     albertel 2595: 	    }
1.194     albertel 2596: 	}
                   2597: 	if (&nest()) {
                   2598: 	    &Apache::lonxml::debug(" for $dim stashing results into ".$dimension{$dim}{'nested'});
                   2599: 	    $dimension{$dimension{$dim}{'nested'}}{'result'}.=$result;
                   2600: 	    undef($result);
                   2601: 	}
                   2602:     } elsif ($target eq 'grade' && $env{'form.webgrade'}) {
                   2603: 	my $optional_passed=0;
                   2604: 	my $mandatory_failed=0;
                   2605: 	my $ungraded=0;
                   2606: 	my $review=0;
                   2607: 	
                   2608: 	$result .= &nested_parse(\$dimension{$dim}{'intro'},[@_]);
                   2609: 	$result .= &nested_parse(\$dimension{$dim}{$instance.'.text'},
                   2610: 				 [@_]);
                   2611: 	$result .= &nested_parse(\$dimension{$dim}{'questiontext'},
                   2612: 				 [@_],{'set_dim_id' => undef});
                   2613: 	
                   2614: 	foreach my $id (@{$dimension{$dim}{$instance.'.criterias'}},
                   2615: 			@{$dimension{$dim}{'criterias'}}) {
                   2616: 	    my $link=&link($id);
                   2617: 	    
                   2618: 	    my $type = $dimension{$dim}{'criteria.'.$id.'.type'};
                   2619: 	    if ($type eq 'criteria') {
                   2620: 		# dimensional 'criteria' don't get assigned grades
                   2621: 		$Apache::lonhomework::results{"resource.$version.0.$dim.$id.status"}=$env{'form.HWVAL_'.$link};
                   2622: 		$Apache::lonhomework::results{"resource.$version.0.$dim.$id.comment"}=$env{'form.HWVAL_comment_'.$link};
                   2623: 	    } else {
                   2624: 		$result .=
                   2625: 		    &nested_parse(\$dimension{$dim}{'criteria.'.$id},
                   2626: 				  [@_],{'set_dim_id' => $id});
1.20      albertel 2627: 	    }
1.194     albertel 2628: 	    my $status= &get_criteria('status',$version,$dim,$id);
                   2629: 	    
                   2630: 	    my $mandatory=($dimension{$dim}{'criteria.'.$id.'.mandatory'} ne 'N');
                   2631: 	    if ($status eq 'pass') {
                   2632: 		if (!$mandatory) { $optional_passed++; }
                   2633: 	    } elsif ($status eq 'fail') {
                   2634: 		if ($mandatory) { $mandatory_failed++; }
                   2635: 	    } elsif ($status eq 'review') {
                   2636: 		$review++;
                   2637: 	    } elsif ($status eq 'ungraded') {
                   2638: 		$ungraded++;
1.20      albertel 2639: 	    } else {
1.194     albertel 2640: 		$ungraded++;
1.20      albertel 2641: 	    }
1.194     albertel 2642: 	}
                   2643: 
                   2644: 	my $opt_req=$dimension{$dim}{$instance.'.optionalrequired'};
                   2645: 	if ($opt_req !~ /\S/) {
                   2646: 	    $opt_req=
                   2647: 		&Apache::lonxml::get_param('OptionalRequired',
                   2648: 					   $parstack,$safeeval);
                   2649: 	    if ($opt_req !~ /\S/) { $opt_req = 0; }
                   2650: 	}
                   2651: 	if ($optional_passed < $opt_req) {
                   2652: 	    $mandatory_failed++;
                   2653: 	}
                   2654: 	&Apache::lonxml::debug("all instance ".join(':',@{$dimension{$dim}{$instance.'.criterias'}})." results -> m_f $mandatory_failed o_p $optional_passed u $ungraded r $review");
                   2655: 	if ($review) {
                   2656: 	    $Apache::lonhomework::results{"resource.$version.0.$dim.status"}=
                   2657: 		'review';
                   2658: 	} elsif ($ungraded) {
                   2659: 	    $Apache::lonhomework::results{"resource.$version.0.$dim.status"}=
                   2660: 		'ungraded';
                   2661: 	} elsif ($mandatory_failed) {
                   2662: 	    $Apache::lonhomework::results{"resource.$version.0.$dim.status"}=
                   2663: 		'fail';
1.69      albertel 2664: 	} else {
1.194     albertel 2665: 	    $Apache::lonhomework::results{"resource.$version.0.$dim.status"}=
                   2666: 		'pass';
1.13      albertel 2667: 	}
1.225     albertel 2668:     } elsif ($target eq 'edit') {
                   2669:     } elsif ($target eq 'modified') {
1.194     albertel 2670:     } else {
                   2671: 	# any other targets no output
                   2672: 	undef($result);
1.1       albertel 2673:     }
1.225     albertel 2674:     if ($target eq 'grade' || $target eq 'web' || $target eq 'webgrade') {
                   2675: 	&disable_dimension_parsing();
                   2676: 	pop(@Apache::bridgetask::dimension);
                   2677:     }
1.194     albertel 2678:     return $result;
                   2679: }
1.162     albertel 2680: 
1.198     albertel 2681: sub question_status_message {
1.197     albertel 2682:     my ($counts,$depth) = @_;
                   2683:     my %req  = ('man' => 'mandatory',
                   2684: 		'opt' => 'optional',);
                   2685:     my %type = ('cri' => 'criteria',
                   2686: 		'dim' => ('sub'x($depth+1)).'questions',);
                   2687:     my @sections;
                   2688:     foreach my $req ('man','opt') {
                   2689: 	foreach my $type ('cri','dim') {
                   2690: 	    if ($counts->{$req.'_'.$type}) {
                   2691: 		push(@sections,
1.213     albertel 2692: 		     $counts->{$req.'_'.$type.'_passed'}.' of the '.
1.197     albertel 2693: 		     $counts->{$req.'_'.$type}.' '.
                   2694: 		     $req{$req}.' '.$type{$type});
                   2695: 	    }
                   2696: 	}
                   2697:     }
                   2698: 
                   2699:     my $status = 'You passed ';
                   2700:     if (@sections == -1) {
                   2701:     } elsif (@sections == 1) {
                   2702: 	$status .= $sections[0];
                   2703:     } elsif (@sections == 2) {
                   2704: 	$status .= $sections[0].' and '.$sections[1];
                   2705:     } else {
                   2706: 	my $last = pop(@sections);
                   2707: 	$status .= join(', ',@sections).', and '.$last;
                   2708:     }
                   2709:     $status .= '.';
                   2710:     if ($counts->{'opt'}) {
1.241     raeburn  2711:         if ($counts->{'opt_dim'} + $counts->{'man_dim'} < 1) {
                   2712:             $status .= ' '.&mt('You were required to pass [quant,_1,optional criterion,optional criteria].',$counts->{'opt_req'});
                   2713:         } else { 
                   2714:             $status .= ' '.&mt('You were required to pass [quant,_1,optional component].',$counts->{'opt_req'});
                   2715:         }
1.197     albertel 2716:     }
                   2717:     return $status;
                   2718: }
                   2719: 
                   2720: sub get_counts {
                   2721:     my ($dim,$instance,$parstack,$safeeval) = @_;
                   2722:     my %counts;
                   2723:     my @possible = ('man_cri','man_dim',
                   2724: 		    'opt_cri','opt_dim',
                   2725: 		    'man_cri_passed', 'man_dim_passed',
                   2726: 		    'opt_cri_passed', 'opt_dim_passed',
                   2727: 		    'man_passed',
                   2728: 		    'opt_passed',
                   2729: 		    'opt_req');
                   2730:     foreach my $which (@possible) { $counts{$which} = 0; }
                   2731: 
                   2732:     my $version = &get_version();
                   2733: 
                   2734:     foreach my $id ( @{$dimension{$dim}{$instance.'.criterias'}},
                   2735: 		     @{$dimension{$dim}{'criterias'}} ) {
                   2736: 	my $status = &get_criteria('status',$version,$dim,$id);
                   2737: 	my $which;
                   2738: 	if ($dimension{$dim}{'criteria.'.$id.'.mandatory'} 
                   2739: 	    eq 'N') {
                   2740: 	    $which = 'opt';
                   2741: 	} else {
                   2742: 	    $which = 'man';
                   2743: 	}
                   2744: 	$counts{$which}++;
                   2745: 	if ($status eq 'pass') { $counts{$which.'_passed'}++; }
                   2746: 	if ($dimension{$dim}{'criteria.'.$id.'.type'}
                   2747: 	    eq 'dimension') {
                   2748: 	    $which .= '_dim';
                   2749: 	} else {
                   2750: 	    $which .= '_cri';
                   2751: 	}
                   2752: 	$counts{$which}++;
                   2753: 	if ($status eq 'pass') { $counts{$which.'_passed'}++; }
                   2754: 
                   2755: 
                   2756:     }
                   2757:     if ($counts{'man_dim_passed'} eq $counts{'man_dim'}) {
                   2758: 	$counts{'man_dim_passed'}='all';
                   2759:     }
                   2760:     if ($counts{'man_cri_passed'} eq $counts{'man_cri'}) {
                   2761: 	$counts{'man_cri_passed'}='all';
                   2762:     }
                   2763:     
                   2764:     $counts{'opt_req'}=$dimension{$dim}{$instance.'.optionalrequired'};
                   2765:     if ($counts{'opt_req'} !~ /\S/) {
                   2766: 	$counts{'opt_req'}= &Apache::lonxml::get_param('OptionalRequired',
                   2767: 						       $parstack,$safeeval);
                   2768: 	if ($counts{'opt_req'} !~ /\S/) { $counts{'opt_req'} = 0; }
                   2769:     }
                   2770:     return %counts;
                   2771: }
                   2772: 
1.194     albertel 2773: sub end_Setup {
                   2774:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
1.225     albertel 2775:     my $result;
1.194     albertel 2776:     my $dim=&get_id($parstack,$safeeval);
                   2777:     my $instance=&get_instance($dim);
                   2778:     my $version=&get_version();
1.225     albertel 2779:     if ($target eq 'web' || $target eq 'webgrade' || $target eq 'grade') {
                   2780: 	$result=&Apache::lonxml::endredirection();
                   2781:     }
1.194     albertel 2782:     if ($target eq 'web') {
                   2783: 	@Apache::scripttag::parser_env = @_;
                   2784: 	$result.=&Apache::scripttag::xmlparse($dimension{$dim}{'intro'});
                   2785: 	my @instances = $instance;
                   2786: 	if (&Apache::response::showallfoils()) {
                   2787: 	    @instances = @{$dimension{$dim}{'instances'}};
                   2788: 	}
                   2789: 	foreach my $instance (@instances) {
1.162     albertel 2790: 	    @Apache::scripttag::parser_env = @_;
1.194     albertel 2791: 	    $result.=&Apache::scripttag::xmlparse($dimension{$dim}{$instance.'.text'});
1.162     albertel 2792: 	    @Apache::scripttag::parser_env = @_;
1.194     albertel 2793: 	    $result.=&Apache::scripttag::xmlparse($dimension{$dim}{'questiontext'});
1.162     albertel 2794: 	}
1.194     albertel 2795:     } elsif ($target eq 'webgrade' 
                   2796: 	     || $target eq 'grade' && $env{'form.webgrade'}) {
                   2797: 	# in case of any side effects that we need
                   2798: 	@Apache::scripttag::parser_env = @_;
                   2799: 	&Apache::scripttag::xmlparse($dimension{$dim}{'intro'});
                   2800: 	@Apache::scripttag::parser_env = @_;
                   2801: 	&Apache::scripttag::xmlparse($dimension{$dim}{$instance.'.text'});
                   2802: 	@Apache::scripttag::parser_env = @_;
                   2803: 	&Apache::scripttag::xmlparse($dimension{$dim}{'questiontext'});
                   2804:     } else {
                   2805: 	# any other targets no output
                   2806: 	undef($result);
1.162     albertel 2807:     }
1.194     albertel 2808:     pop(@Apache::bridgetask::dimension);
                   2809:     return $result;
1.1       albertel 2810: }
                   2811: 
1.113     albertel 2812: sub grading_history {
1.151     albertel 2813:     my ($version,$dim,$id) = @_;
1.235     albertel 2814:     if (!&Apache::lonnet::allowed('mgq',$env{'request.course.id'})
                   2815: 	&& !&Apache::lonnet::allowed('mgq',$env{'request.course.id'}.'/'.$env{'request.course.sec'})) {
1.113     albertel 2816: 	return '';
                   2817:     }
                   2818:     my ($result,$grader);
1.194     albertel 2819:     my $scope="resource.$version.0.";
                   2820:     $scope .= ($dim ne $top) ? "$dim.$id"
                   2821: 	                     : "$id";
1.113     albertel 2822:     foreach my $t (1..$Apache::lonhomework::history{'version'}) {
                   2823: 	if (exists($Apache::lonhomework::history{$t.':resource.0.regrader'})) {
                   2824: 	    my ($gname,$gdom) = 
1.138     albertel 2825: 		split(':',$Apache::lonhomework::history{$t.':resource.0.regrader'});
1.113     albertel 2826: 	    my $fullname = &Apache::loncommon::plainname($gname,$gdom);
                   2827: 	    $grader = &Apache::loncommon::aboutmewrapper($fullname,
                   2828: 							 $gname,$gdom);
                   2829: 	}
                   2830: 	my $entry;
                   2831: 	if (exists($Apache::lonhomework::history{"$t:$scope.status"})) {
                   2832: 	    $entry.="<tt>".$Apache::lonhomework::history{"$t:$scope.status"}.'</tt>';
                   2833: 	}
                   2834: 	if (exists($Apache::lonhomework::history{"$t:$scope.comment"})) {
                   2835: 	    $entry.=' comment: "'.$Apache::lonhomework::history{"$t:$scope.comment"}.'"';
                   2836: 	}
                   2837: 	if ($entry) {
1.200     albertel 2838: 	    $result.= "\n\t\t<li>\n\t\t\t$grader :\n\t\t\t $entry \n\t\t</li>";
1.113     albertel 2839: 	}
                   2840:     }
                   2841:     if ($result) {
1.200     albertel 2842: 	return "\n\t".'<ul class="LC_GRADING_pastgrading">'.$result.
                   2843: 	    "\n\t".'</ul>'."\n";
1.113     albertel 2844:     }
                   2845:     return '';
                   2846: }
                   2847: 
1.1       albertel 2848: sub start_IntroParagraph {
1.87      albertel 2849:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.1       albertel 2850:     my $result;
1.168     albertel 2851:     my $dim = &get_dim_id();
1.153     albertel 2852:     if ($target eq 'grade' || $target eq 'web' || $target eq 'webgrade') {
1.151     albertel 2853: 	if ($tagstack->[-2] eq 'Dimension' || $tagstack->[-2] eq 'Question' ) {
1.169     albertel 2854: 	    $dimension{$dim}{'intro'}=
1.151     albertel 2855: 		&Apache::lonxml::get_all_text('/introparagraph',
                   2856: 					      $parser,$style);
                   2857:        	} elsif ($tagstack->[-2] eq 'Task' && $target eq 'webgrade') {
1.127     albertel 2858: 	    &Apache::lonxml::startredirection();
1.1       albertel 2859: 	}
1.47      albertel 2860: 	
1.225     albertel 2861:     } elsif ($target eq 'edit') {
                   2862: 	$result = &Apache::edit::tag_start($target,$token);
                   2863:     } elsif ($target eq 'modified') {
1.1       albertel 2864:     }
                   2865:     return $result;
                   2866: }
                   2867: 
                   2868: sub end_IntroParagraph {
1.127     albertel 2869:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.128     albertel 2870:     if ($tagstack->[-2] eq 'Task' && $target eq 'webgrade') {
1.127     albertel 2871: 	my $result = &Apache::lonxml::endredirection();
                   2872:     }
1.1       albertel 2873: }
                   2874: 
1.227     albertel 2875: sub insert_IntroParagraph {
                   2876:     return '
                   2877: <IntroParagraph>
                   2878:     <startouttext />
                   2879:     <endouttext />
                   2880: </IntroParagraph>';
                   2881: }
                   2882: 
1.1       albertel 2883: sub start_Instance {
                   2884:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
1.168     albertel 2885:     my $dim = &get_dim_id();
                   2886:     my $id  = &get_id($parstack,$safeeval);
1.169     albertel 2887:     push(@{$dimension{$dim}{'instances'}},$id);
1.168     albertel 2888:     push(@{$Apache::bridgetask::instance{$dim}},$id);
1.19      albertel 2889:     push(@Apache::bridgetask::instancelist,$id);
1.169     albertel 2890:     $dimension{$dim}{$id.'.optionalrequired'}=
1.19      albertel 2891: 	&Apache::lonxml::get_param('OptionalRequired',$parstack,$safeeval);
1.75      albertel 2892:     my $disabled = &Apache::lonxml::get_param('Disabled',$parstack,$safeeval);
                   2893:     if (lc($disabled) eq 'yes') {
1.169     albertel 2894: 	$dimension{$dim}{$id.'.disabled'}='1';
1.75      albertel 2895:     }
1.225     albertel 2896:     my $result;
                   2897:     if ($target eq 'edit') {
                   2898: 	$result = &Apache::edit::tag_start($target,$token);
                   2899: 	$result.=  
                   2900: 	    &Apache::edit::text_arg('Id:','id',$token,10).' '.
                   2901: 	    &Apache::edit::select_arg('Instance is Disabled:','Disabled',
                   2902: 				      [['no', 'No'],
                   2903: 				       ['yes','Yes'],],
                   2904: 				      $token)
                   2905: 	    .' <br /> '.
                   2906: 	    &Apache::edit::text_arg('Required number of passed optional elements to pass the Instance:',
                   2907: 				    'OptionalRequired',$token,4)
                   2908: 	    .&Apache::edit::end_row().
                   2909: 	    &Apache::edit::start_spanning_row();
                   2910:     } elsif ($target eq 'modified') {
                   2911: 	my $constructtag=
                   2912: 	    &Apache::edit::get_new_args($token,$parstack,$safeeval,
                   2913: 					'id','OptionalRequired','Disabled');
                   2914: 	if ($constructtag) {
                   2915: 	    $result = &Apache::edit::rebuild_tag($token);
                   2916: 	}
                   2917:     }
                   2918:     return $result;
1.1       albertel 2919: }
                   2920: 
                   2921: sub end_Instance {
1.225     albertel 2922:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
                   2923:     my $result;
                   2924:     if ($target eq 'edit') {
                   2925: 	$result = &Apache::edit::tag_end($target,$token);
                   2926:     }
                   2927:     return $result;
1.1       albertel 2928: }
                   2929: 
                   2930: sub start_InstanceText {
1.87      albertel 2931:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.225     albertel 2932:     my $result;
1.153     albertel 2933:     if ($target eq 'grade' || $target eq 'web' || $target eq 'webgrade') {
1.225     albertel 2934: 	my $text=&Apache::lonxml::get_all_text('/instancetext',$parser,$style);
                   2935: 	my $dim = &get_dim_id();
                   2936: 	my $instance_id=$Apache::bridgetask::instance{$dim}[-1];
1.169     albertel 2937: 	$dimension{$dim}{$instance_id.'.text'}=$text;
1.225     albertel 2938:     } elsif ($target eq 'edit') {
                   2939: 	$result = &Apache::edit::tag_start($target,$token);
                   2940:     } elsif ($target eq 'modified') {
1.1       albertel 2941:     }
1.225     albertel 2942:     return $result;
1.1       albertel 2943: }
                   2944: 
                   2945: sub end_InstanceText {
                   2946:     return '';
                   2947: }
                   2948: 
1.227     albertel 2949: sub insert_InstanceText {
                   2950:     return '
                   2951: <InstanceText>
                   2952:     <startouttext />
                   2953:     <endouttext />
                   2954: </InstanceText>';
                   2955: }
                   2956: 
1.1       albertel 2957: sub start_Criteria {
1.87      albertel 2958:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.190     albertel 2959:     my $result = '';
1.21      albertel 2960:     if ($target eq 'web' || $target eq 'webgrade' || $target eq 'grade') {
1.225     albertel 2961: 	my $criteria=&Apache::lonxml::get_all_text('/criteria',$parser,$style);
1.168     albertel 2962: 	my $dim = &get_dim_id();
1.19      albertel 2963: 	my $id=&get_id($parstack,$safeeval);
1.194     albertel 2964: 	if ($target eq 'web' || $target eq 'webgrade') {
1.208     albertel 2965: 	    if ($target eq 'webgrade') {
1.195     albertel 2966: 		&Apache::lonxml::debug(" for $dim $id stashing results into $dim ");
                   2967: 		$dimension{$dim}{'result'} .= &internal_location($id);
                   2968: 	    } else {
                   2969: 		&Apache::lonxml::debug(" not stashing $dim $id");
1.206     albertel 2970: 		#$result .= &internal_location($id);
1.195     albertel 2971: 	    }
1.194     albertel 2972: 	}
1.169     albertel 2973: 	&Apache::lonxml::debug("Criteria $id with $dim");
1.151     albertel 2974: 	if (&Apache::londefdef::is_inside_of($tagstack,'Instance')) {
1.168     albertel 2975: 	    my $instance_id=$Apache::bridgetask::instance{$dim}[-1];
1.169     albertel 2976: 	    $dimension{$dim}{"criteria.$instance_id.$id"}=$criteria;
                   2977: 	    $dimension{$dim}{"criteria.$instance_id.$id.type"}='criteria';
                   2978: 	    $dimension{$dim}{"criteria.$instance_id.$id.mandatory"}=
1.151     albertel 2979: 		&Apache::lonxml::get_param('Mandatory',$parstack,$safeeval);
1.169     albertel 2980: 	    push(@{$dimension{$dim}{$instance_id.'.criterias'}},"$instance_id.$id");
1.151     albertel 2981: 	} else {
1.169     albertel 2982: 	    $dimension{$dim}{'criteria.'.$id}=$criteria;
                   2983: 	    $dimension{$dim}{'criteria.'.$id.'.type'}='criteria';
                   2984: 	    $dimension{$dim}{'criteria.'.$id.'.mandatory'}=
1.151     albertel 2985: 		&Apache::lonxml::get_param('Mandatory',$parstack,$safeeval);
1.169     albertel 2986: 	    push(@{$dimension{$dim}{'criterias'}},$id);
1.194     albertel 2987: 	}
1.225     albertel 2988:     } elsif ($target eq 'edit') {
                   2989: 	$result .=&Apache::edit::tag_start($target,$token);
                   2990: 	$result.=  
                   2991: 	    &Apache::edit::text_arg('Id:','id',$token,10).' '.
                   2992: 	    &Apache::edit::select_arg('Passing is Mandatory:','Mandatory',
1.233     albertel 2993: 				      [['Y', 'Yes'],
                   2994: 				       ['N','No'],],
1.225     albertel 2995: 				      $token)
                   2996: 	    .' <br /> '.&Apache::edit::end_row().
                   2997: 	    &Apache::edit::start_spanning_row();
                   2998:     } elsif ($target eq 'modified') {
                   2999: 	my $constructtag=
                   3000: 	    &Apache::edit::get_new_args($token,$parstack,$safeeval,
                   3001: 					'id','Mandatory');
                   3002: 	if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); }
1.194     albertel 3003:     }
                   3004:     return $result;
                   3005: }
                   3006: 
                   3007: sub layout_web_Criteria {
                   3008:     my ($dim,$id,$criteria) = @_;
1.190     albertel 3009: 
1.194     albertel 3010:     my $version = &get_version();
                   3011:     my $status= &get_criteria('status', $version,$dim,$id);
                   3012:     my $comment=&get_criteria('comment',$version,$dim,$id);
                   3013:     my $mandatory=($dimension{$dim}{'criteria.'.$id.'.mandatory'} ne 'N');
                   3014:     if ($mandatory) {
                   3015: 	$mandatory='Mandatory';
                   3016:     } else {
                   3017: 	$mandatory='Optional';
1.1       albertel 3018:     }
1.194     albertel 3019:     my $status_display=$status;
                   3020:     $status_display=~s/^([a-z])/uc($1)/e;
                   3021:     my $criteria_info.=
1.200     albertel 3022: 	'<div class="LC_'.$status.' LC_criteria">'."\n\t".'<h4>'
1.204     albertel 3023: 	.$mandatory.' Criteria</h4>'."\n\t".'<p class="LC_criteria_text">'
                   3024: 	."\n";
1.202     albertel 3025:     $criteria =~ s/^\s*//s;
                   3026:     $criteria =~ s/\s*$//s;
1.194     albertel 3027:     $criteria_info.= $criteria;
1.200     albertel 3028:     $criteria_info.="\n\t".'</p>'.
                   3029: 	"\n\t".'<p class="LC_grade">'.$status_display.'</p>';
1.194     albertel 3030:     if ($comment =~ /\w/) {
1.200     albertel 3031: 	$criteria_info.=
                   3032: 	    "\n\t".
                   3033: 	    '<p class="LC_comment">'.&mt('Comment: [_1]',$comment).'</p>';
1.194     albertel 3034:     }
1.200     albertel 3035:     $criteria_info.="\n".'</div>'."\n";
                   3036:     
1.194     albertel 3037:     return $criteria_info;
                   3038: }
                   3039: 
                   3040: sub layout_webgrade_Criteria {
                   3041:     my ($dim,$id,$criteria) = @_;
                   3042:     my $link=&link($id);
                   3043:     my $version = &get_version();
                   3044:     my $status  = &get_criteria('status',$version,$dim,$id);
1.245     bisitz   3045:     my %lt = &Apache::lonlocal::texthash(
                   3046:         'ungraded' => 'Ungraded',
                   3047:         'fail'     => 'Fail',
                   3048:         'pass'     => 'Pass',
                   3049:         'review'   => 'Review',
                   3050:         'comment'  => 'Additional Comment for Student',
                   3051:     );
1.200     albertel 3052:     my $comment = &get_criteria('comment',$version,$dim,$id);
                   3053:     $comment = &HTML::Entities::encode($comment,'<>"&');
                   3054:     my %checked;
                   3055:     foreach my $which ('ungraded','fail','pass','review') {
1.249     bisitz   3056: 	if ($status eq $which) { $checked{$which} = ' checked="checked"'; }
1.200     albertel 3057:     }
1.249     bisitz   3058:     if (!%checked) { $checked{'ungraded'} = ' checked="checked"'; }
1.201     albertel 3059:     my $buttons;
                   3060:     foreach my $which  ('ungraded','fail','pass','review') {
                   3061: 	$buttons .= <<END_BUTTON;
                   3062: 		<label class="LC_GRADING_$which">
1.249     bisitz   3063: 			<input type="radio" name="HWVAL_$link" value="$which"$checked{$which} />
1.201     albertel 3064: 			$lt{$which}
                   3065: 		</label>
                   3066: END_BUTTON
                   3067:     }
1.202     albertel 3068:     $criteria =~ s/^\s*//s;
                   3069:     $criteria =~ s/\s*$//s;
1.200     albertel 3070:     my $result = <<END_CRITERIA;
1.201     albertel 3071: <div class="LC_GRADING_criteria">
                   3072: 	<div class="LC_GRADING_criteriatext">
                   3073: 		$criteria
                   3074: 	</div>
                   3075: 	<div class="LC_GRADING_grade">
                   3076: $buttons
                   3077: 	</div>
                   3078: 	<label class="LC_GRADING_comment">
                   3079: 		$lt{'comment'}
                   3080: 		<textarea class="LC_GRADING_comment_area" name="HWVAL_comment_$link">$comment</textarea>
                   3081: 	</label>
                   3082: </div>
1.200     albertel 3083: END_CRITERIA
                   3084:     $result .= &grading_history($version,$dim,$id);
1.190     albertel 3085:     return $result;
1.1       albertel 3086: }
                   3087: 
1.47      albertel 3088: sub end_Criteria {
1.225     albertel 3089:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
                   3090:     if ($target eq 'edit') {
                   3091:     } elsif ($target eq 'modified') {
                   3092:     }
                   3093: }
1.227     albertel 3094: sub insert_Criteria {
                   3095:     return '
                   3096: <Criteria>
                   3097:     <CriteriaText>
                   3098:         <startouttext />
                   3099:         <endouttext />
                   3100:     </CriteriaText>
                   3101: </Criteria>';
                   3102: }
1.225     albertel 3103: 
                   3104: sub start_CriteriaText {
                   3105:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
                   3106:     my $result;
                   3107:     if ($target eq 'grade' || $target eq 'web' || $target eq 'webgrade') {
                   3108: 	
                   3109:     } elsif ($target eq 'edit') {
                   3110: 	$result = &Apache::edit::tag_start($target,$token);
                   3111:     } elsif ($target eq 'modified') {
                   3112:     }
                   3113:     return $result;
                   3114: }
                   3115: 
                   3116: sub end_CriteriaText {
                   3117:     return '';
1.47      albertel 3118: }
                   3119: 
1.227     albertel 3120: sub insert_CriteriaText {
                   3121:     return '
                   3122: <CriteriaText>
                   3123:     <startouttext />
                   3124:     <endouttext />
                   3125: </CriteriaText>';
                   3126: }
                   3127: 
1.186     albertel 3128: sub start_GraderNote {
                   3129:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.225     albertel 3130:     my $result;
1.186     albertel 3131:     if ($target eq 'webgrade') {
1.225     albertel 3132: 	$result = '<div class="LC_GRADING_gradernote"><b>'.
1.187     albertel 3133: 	    &mt('Note to graders:').'</b>';
1.225     albertel 3134:     } elsif ($target eq 'edit') {
                   3135: 	$result = &Apache::edit::tag_start($target,$token);
                   3136:     } elsif ($target eq 'modified') {
                   3137:     } elsif ($target eq 'web' || $target eq 'grade') {
                   3138: 	my $note=&Apache::lonxml::get_all_text('/gradernote',$parser,$style); 
1.186     albertel 3139:     }
1.225     albertel 3140:     return $result;
1.186     albertel 3141: }
                   3142: 
                   3143: sub end_GraderNote {
                   3144:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
                   3145: 
                   3146:     if ($target eq 'webgrade') {
                   3147: 	return '</div>';
                   3148:     }
                   3149:     return;
                   3150: }
                   3151: 
1.227     albertel 3152: sub insert_GraderNote {
                   3153:     return '
                   3154: <GraderNote>
                   3155:     <startouttext />
                   3156:     <endouttext />
                   3157: </GraderNote>';
                   3158: }
1.186     albertel 3159: 
                   3160: 
1.4       albertel 3161: sub proctor_validation_screen {
                   3162:     my ($slot) = @_;
1.185     albertel 3163:     my (undef,undef,$domain,$user) = &Apache::lonnet::whichuser();
1.5       albertel 3164:     my $url=&Apache::lonnet::studentphoto($domain,$user,'jpg');
1.230     albertel 3165:     if ($url ne '/adm/lonKaputt/lonlogo_broken.gif') {
                   3166: 	$url = "<tr><td colspan=\"2\"><img src=\"$url\" /></td></tr>";
                   3167:     } else {
                   3168: 	undef($url);
                   3169:     }
                   3170: 
1.44      albertel 3171:     my $name=&Apache::loncommon::plainname($user,$domain);
                   3172:     
1.4       albertel 3173:     my $msg;
1.11      albertel 3174:     if ($env{'form.proctorpassword'}) {
1.230     albertel 3175: 	$msg.='<p><span class="LC_warning">'
                   3176: 	    .&mt("Failed to authenticate the proctor.")
                   3177: 	    .'</span></p>';
1.4       albertel 3178:     }
1.230     albertel 3179: 
                   3180:     my $valid;
                   3181:     my @possible_proctors=split(",",$slot->{'proctor'});
                   3182:     foreach my $proctor (@possible_proctors) {
                   3183: 	if ($proctor =~ /$LONCAPA::username_re:$LONCAPA::domain_re/) {
                   3184: 	    $valid = 1;
                   3185: 	    last;
                   3186: 	}
                   3187:     }
                   3188:     if (!$valid) {
                   3189: 	$msg.='<p><span class="LC_error">'
1.239     bisitz   3190: 	    .&mt("No valid proctors are defined.")
1.230     albertel 3191: 	    .'</span></p>';
                   3192:     }
                   3193:     
1.47      albertel 3194:     if (!$env{'form.proctordomain'}) { $env{'form.proctordomain'}=$domain; }
1.229     albertel 3195:     my $uri = &Apache::lonenc::check_encrypt($env{'request.uri'});
                   3196:     $uri = &HTML::Entities::encode($uri,'<>&"');
1.241     raeburn  3197:     my %lt = &Apache::lonlocal::texthash(
                   3198:                             'prva' => "Proctor Validation",
                   3199:                             'yoro' => "Your room's proctor needs to validate your access to this resource.",
                   3200:                             'prus'  => "Proctor's Username:",
                   3201:                             'pasw'  => "Password:",
                   3202:                             'prdo'  => "Proctor's Domain:",
                   3203:                             'vali'  => 'Validate',
                   3204:                             'stui'  => "Student who should be logged in is:",
                   3205:                             'name'  => "Name:",
1.251     raeburn  3206:                             'sid'   => "Student/Employee ID",
1.241     raeburn  3207:                             'unam'  => "Username:",
                   3208:                            );
1.4       albertel 3209:     my $result= (<<ENDCHECKOUT);
1.241     raeburn  3210: <h2>$lt{'prva'}</h2>
                   3211:     <p>$lt{'yoro'}</p>
1.4       albertel 3212:     $msg
1.229     albertel 3213: <form name="checkout" method="post" action="$uri">
1.4       albertel 3214: <input type="hidden" name="validate" value="yes" />
                   3215: <input type="hidden" name="submitted" value="yes" />
                   3216: <table>
1.241     raeburn  3217:   <tr><td>$lt{'prus'}</td><td><input type="string" name="proctorname" value="$env{'form.proctorname'}" /></td></tr>
                   3218:   <tr><td>$lt{'pasw'}</td><td><input type="password" name="proctorpassword" value="" /></td></tr>
                   3219:   <tr><td>$lt{'prdo'}</td><td><input type="string" name="proctordomain" value="$env{'form.proctordomain'}" /></td></tr>
1.4       albertel 3220: </table>
1.241     raeburn  3221: <input type="submit" name="checkoutbutton" value="$lt{'vali'}"  /><br />
1.44      albertel 3222: <table border="1">
                   3223:   <tr><td>
                   3224:     <table>
1.241     raeburn  3225:       <tr><td colspan="2">$lt{'stui'}</td></tr>
                   3226:       <tr><td>$lt{'name'}</td><td>$name</td></tr>
                   3227:       <tr><td>$lt{'sid'}</td><td>$env{'environment.id'}</td></tr>
                   3228:       <tr><td>$lt{'unam'}</td><td>$user:$domain</td></tr>
1.230     albertel 3229:       $url
1.44      albertel 3230:     </table>
                   3231:   </tr></td>
                   3232: </table>
1.4       albertel 3233: </form>
                   3234: ENDCHECKOUT
1.241     raeburn  3235: 
1.4       albertel 3236:     return $result;
                   3237: }
                   3238: 
1.1       albertel 3239: 1;
                   3240: __END__

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>