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

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

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