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

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

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