Annotation of loncom/homework/bridgetask.pm, revision 1.165
1.1 albertel 1: # The LearningOnline Network with CAPA
2: # definition of tags that give a structure to a document
3: #
1.165 ! albertel 4: # $Id: bridgetask.pm,v 1.164 2006/06/09 23:09:01 albertel Exp $
1.1 albertel 5: #
6: # Copyright Michigan State University Board of Trustees
7: #
8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
9: #
10: # LON-CAPA is free software; you can redistribute it and/or modify
11: # it under the terms of the GNU General Public License as published by
12: # the Free Software Foundation; either version 2 of the License, or
13: # (at your option) any later version.
14: #
15: # LON-CAPA is distributed in the hope that it will be useful,
16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18: # GNU General Public License for more details.
19: #
20: # You should have received a copy of the GNU General Public License
21: # along with LON-CAPA; if not, write to the Free Software
22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23: #
24: # /home/httpd/html/adm/gpl.txt
25: #
26: # http://www.lon-capa.org/
27: #
28: ###
29:
30:
31: package Apache::bridgetask;
32:
33: use strict;
34: use Apache::lonnet;
35: use Apache::File();
36: use Apache::lonmenu;
37: use Apache::lonlocal;
38: use Apache::lonxml;
1.37 albertel 39: use Apache::slotrequest();
1.1 albertel 40: use Time::HiRes qw( gettimeofday tv_interval );
1.158 www 41: use lib '/home/httpd/lib/perl/';
42: use LONCAPA;
43:
1.9 albertel 44:
1.1 albertel 45: BEGIN {
1.162 albertel 46: &Apache::lonxml::register('Apache::bridgetask',('Task','IntroParagraph','Dimension','Question','QuestionText','Setup','Instance','InstanceText','Criteria','ClosingParagraph'));
1.1 albertel 47: }
48:
1.9 albertel 49: sub initialize_bridgetask {
50: # id of current Dimension, 0 means that no dimension is current
51: # (inside <Task> only)
52: $Apache::bridgetask::dimension='';
53: # list of all Dimension ids seen
54: @Apache::bridgetask::dimensionlist=();
1.20 albertel 55: # mandatory attribute of all Dimensions seen
56: %Apache::bridgetask::dimensionmandatory=();
1.9 albertel 57: # list of all current Instance ids
58: @Apache::bridgetask::instance=();
59: # list of all Instance ids seen in this problem
60: @Apache::bridgetask::instancelist=();
1.15 albertel 61: # key of queud user data that we are currently grading
62: $Apache::bridgetask::queue_key='';
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) {
86: &create_new_version($type,$user,$domain,$slot_name);
1.4 albertel 87: return 1;
88: }
89: }
90: }
91: return 0;
92: }
93:
1.150 albertel 94: sub create_new_version {
95: my ($type,$user,$domain,$slot_name) = @_;
96: if ($type eq 'Task') {
97: # increment version
98: my $version=
99: $Apache::lonhomework::history{'resource.0.version'};
100: $version++;
1.152 albertel 101: &Apache::lonxml::debug("Making version $version");
1.150 albertel 102: #clean out all current results
103: foreach my $key (keys(%Apache::lonhomework::history)) {
104: if ($key=~/^resource\.0\./) {
105: $Apache::lonhomework::results{$key}='';
106: }
107: }
108:
109: #setup new version and who did it
110: $Apache::lonhomework::results{'resource.0.version'}=$version;
111: if (defined($user) && defined($domain)) {
112: $Apache::lonhomework::results{"resource.$version.0.checkedin"}=
113: $user.':'.$domain;
1.152 albertel 114: } else {
115: $Apache::lonhomework::results{"resource.$version.0.checkedin"}=
116: $env{'user.name'}.':'.$env{'user.domain'};
1.150 albertel 117: }
118: if (defined($slot_name)) {
119: $Apache::lonhomework::results{"resource.$version.0.checkedin.slot"}=
120: $slot_name;
121: }
122: } elsif ($type eq 'problem') {
123: &Apache::lonxml::debug("authed $slot_name");
124: if (defined($user) && defined($domain)) {
125: $Apache::lonhomework::results{"resource.0.checkedin"}=
126: $user.':'.$domain;
127: }
128: if (defined($slot_name)) {
129: $Apache::lonhomework::results{"resource.0.checkedin.slot"}=
130: $slot_name;
131: }
132: }
133: }
134:
1.25 albertel 135: sub get_version {
1.29 albertel 136: my ($version,$previous);
1.25 albertel 137: if ($env{'form.previousversion'} &&
1.36 albertel 138: $env{'form.previousversion'} ne 'current' &&
1.89 albertel 139: defined($Apache::lonhomework::history{'resource.'.$env{'form.previousversion'}.'.0.status'})) {
1.29 albertel 140: $version=$env{'form.previousversion'};
141: $previous=1;
142: } else {
1.150 albertel 143: if (defined($Apache::lonhomework::results{'resource.0.version'})) {
144: $version=$Apache::lonhomework::results{'resource.0.version'};
145: } elsif (defined($Apache::lonhomework::history{'resource.0.version'})) {
146: $version=$Apache::lonhomework::history{'resource.0.version'};
147: }
1.29 albertel 148: $previous=0;
149: }
150: if (wantarray) {
151: return ($version,$previous);
1.25 albertel 152: }
1.29 albertel 153: return $version;
1.25 albertel 154: }
155:
1.8 albertel 156: sub add_previous_version_button {
1.25 albertel 157: my ($status)=@_;
1.8 albertel 158: my $result;
1.89 albertel 159: if ($Apache::lonhomework::history{'resource.0.version'} eq '') {
1.25 albertel 160: return '';
161: }
1.89 albertel 162: if ($Apache::lonhomework::history{'resource.0.version'} < 2 &&
1.29 albertel 163: $status ne 'NEEDS_CHECKIN') {
1.25 albertel 164: return '';
165: }
1.29 albertel 166: my $version=&get_version();
167: if ($env{'form.previousversion'} ne '' &&
168: $env{'form.previousversion'} eq $version) {
169: $result.="<h3>".&mt("Showing previous version [_1]",$version).
170: "</h3>\n";
171: }
172: my @to_show;
1.89 albertel 173: foreach my $test_version (1..$Apache::lonhomework::history{'resource.0.version'}) {
174: if (defined($Apache::lonhomework::history{'resource.'.$test_version.'.0.status'})) {
1.29 albertel 175: push(@to_show,$test_version);
176: }
177: }
178: my $list='<option>'.
179: join("</option>\n<option>",@to_show).
180: "</option>\n";
1.36 albertel 181: $list.='<option value="current">'.&mt('Current').'</option>';
1.115 albertel 182: $result.='<form name="getprevious" method="post" action="';
1.29 albertel 183: my $uri=$env{'request.uri'};
184: if ($env{'request.enc'}) { $uri=&Apache::lonenc::encrypted($uri); }
185: $result.=$uri.'">'.
186: &mt(' Show a previously done version: [_1]','<select onchange="this.form.submit()" name="previousversion">
187: <option>'.&mt('Pick one').'</option>
188: '.$list.'
189: </select>')."</form>";
1.8 albertel 190: return $result;
191: }
192:
1.13 albertel 193: sub add_grading_button {
1.59 albertel 194: my (undef,$cid)=&Apache::lonxml::whichuser();
195: my $cnum=$env{'course.'.$cid.'.num'};
196: my $cdom=$env{'course.'.$cid.'.domain'};
1.144 albertel 197: my %sections = &Apache::loncommon::get_sections($cdom,$cnum);
198:
1.59 albertel 199: my $size=5;
200: if (scalar(keys(%sections)) < 3) {
201: $size=scalar(keys(%sections))+2;
202: }
1.122 albertel 203: my $sec_select = '<select multiple="multiple" name="chosensections" size="'.$size.'">'."\n";
1.59 albertel 204: $sec_select .= "<option value='all' selected='selected'>all</option>\n";
205: foreach my $sec (sort {lc($a) cmp lc($b)} (keys(%sections))) {
1.122 albertel 206: $sec_select .= "<option value=\"$sec\">$sec</option>\n";
1.59 albertel 207: }
208: $sec_select .= "<option value='none'>none</option></select>\n";
209:
1.29 albertel 210: my $result=' <input type="submit" name="gradeasubmission" value="'.
1.13 albertel 211: &mt("Get a submission to grade").'" />';
212: $result.='<input type="hidden" name="grade_target" value="webgrade" />';
1.40 albertel 213: if (&Apache::lonnet::allowed('mgq',$env{'request.course.id'})) {
1.34 albertel 214: my ($entries,$ready,$locks)=&get_queue_counts('gradingqueue');
1.106 albertel 215: $result.='<table><tr>';
216: $result.='<td rowspan="4">Specify a section: </td><td rowspan="4">'.$sec_select.'</td>';
217: $result.='<td>'.' <input type="submit" name="reviewagrading" value="'.
218: &mt("Select an entry from the grading queue:").'" /> ';
1.34 albertel 219:
1.107 albertel 220: $result.= &mt("[_1] entries, [_2] ready, [_3] being graded",$entries,$ready,$locks).' </td></tr>'."\n";
1.34 albertel 221:
222: ($entries,$ready,$locks)=&get_queue_counts('reviewqueue');
1.106 albertel 223: $result.='<tr><td>'.
224: ' <input type="submit" name="reviewasubmission" value="'.
225: &mt("Select an entry from the review queue:").'" /> ';
226: $result.=&mt("[_1] entries, [_2] ready, [_3] being graded",
227: $entries,$ready,$locks).'</td></tr>'."\n";
228: $result.='<tr><td> <input type="submit" name="regradeasubmission" value="'.
229: &mt("List of user's grade status").'" /> </td></tr></table>'."\n";
1.105 albertel 230: $result.='<p> <input type="submit" name="regradeaspecificsubmission" value="'.
1.106 albertel 231: &mt("Regrade specific user:").'" />'."\n";
1.105 albertel 232: $result.='<input type="text" size="12" name="gradinguser" />';
233: $result.=&Apache::loncommon::select_dom_form($env{'user.domain'},
234: 'gradingdomain');
235: $result.=' '.
236: &Apache::loncommon::selectstudent_link('gradesubmission',
237: 'gradinguser',
238: 'gradingdomain');
239: $result.=&Apache::loncommon::studentbrowser_javascript();
1.123 albertel 240: $result.= '</p>';
1.144 albertel 241: }
1.13 albertel 242: return $result;
243: }
244:
1.22 albertel 245: sub add_request_another_attempt_button {
1.38 albertel 246: my ($text)=@_;
247: if (!$text) { $text="Request another attempt"; }
1.25 albertel 248: my $result;
1.36 albertel 249: my $symb=&Apache::lonnet::symbread();
1.149 albertel 250: # not a slot access based resource
251: my $useslots = &Apache::lonnet::EXT("resource.0.useslots",$symb);
252: if ($useslots =~ /^\s*no\s*$/i) {
253: return '';
254: }
255:
1.37 albertel 256: my ($slot_name,$slot)=&Apache::slotrequest::check_for_reservation($symb);
1.38 albertel 257: my $action='get_reservation';
1.37 albertel 258: if ($slot_name) {
1.38 albertel 259: $text="Change reservation.";
260: $action='change_reservation';
1.37 albertel 261: my $description=&Apache::slotrequest::get_description($slot_name,
262: $slot);
263: $result.=(<<STUFF);
264: <p> Will be next available: $description </p>
265: STUFF
266: }
1.38 albertel 267:
268: if ($env{'request.enc'}) { $symb=&Apache::lonenc::encrypted($symb); }
1.158 www 269: $symb=&escape($symb);
1.115 albertel 270: $result.='<form method="post" action="/adm/slotrequest">'.
1.38 albertel 271: '<input type="hidden" name="symb" value="'.$symb.'" />'.
272: '<input type="hidden" name="command" value="'.$action.'" />'.
273: '<input type="submit" name="requestattempt" value="'.
274: &mt($text).'" />'.
275: '</form>';
1.25 albertel 276: return $result;
1.22 albertel 277: }
278:
1.30 albertel 279: sub preserve_grade_info {
280: my $result;
281: # if we are viewing someone else preserve that info
282: if (defined $env{'form.grade_symb'}) {
283: foreach my $field ('symb','courseid','domain','username') {
284: $result .= '<input type="hidden" name="grade_'.$field.
285: '" value="'.$env{"form.grade_$field"}.'" />'."\n";
286: }
287: }
288: return $result;
289: }
290:
1.53 albertel 291: sub style {
1.125 albertel 292: my ($target) = @_;
293: if ($target eq 'web'
294: || $target eq 'webgrade') {
295: return (<<STYLE);
1.126 albertel 296: <link rel="stylesheet" type="text/css" href="/res/adm/includes/task.css" />
1.53 albertel 297: STYLE
1.125 albertel 298: }
299: return;
1.53 albertel 300: }
301:
1.54 albertel 302: sub show_task {
303: my ($status,$previous)=@_;
304: if (!$previous && (
305: ( $status eq 'CLOSED' ) ||
306: ( $status eq 'BANNED') ||
307: ( $status eq 'UNAVAILABLE') ||
308: ( $status eq 'NOT_IN_A_SLOT') ||
309: ( $status eq 'NEEDS_CHECKIN') ||
310: ( $status eq 'WAITING_FOR_GRADE') ||
1.150 albertel 311: ( $status eq 'INVALID_ACCESS') ||
312: ( &get_version() eq ''))) {
1.54 albertel 313: return 0;
314: }
1.64 albertel 315: if ($env{'form.donescreen'}) { return 0; }
1.54 albertel 316: return 1;
317: }
318:
319: sub internal_location {
320: my ($id)=@_;
321: return '<!-- LONCAPA_INTERNAL_ADD_TASK_STATUS'.$id.' -->';
322: }
323:
1.60 albertel 324: sub submission_time_stamp {
325: my ($symb,$courseid,$udom,$uname)=&Apache::lonxml::whichuser();
326: my $submissiontime;
1.89 albertel 327: my $version=$Apache::lonhomework::history{'resource.0.version'};
1.60 albertel 328: for (my $v=$Apache::lonhomework::history{'version'};$v>0;$v--) {
329: if (defined($Apache::lonhomework::history{$v.':resource.'.$version.'.0.bridgetask.portfiles'})) {
330: $submissiontime=$Apache::lonhomework::history{$v.':timestamp'};
331: }
332: }
333: my $result;
334: if ($submissiontime) {
1.89 albertel 335: my $slot_name=$Apache::lonhomework::history{'resource.'.$version.'.0.checkedin.slot'};
1.60 albertel 336: my %slot=&Apache::lonnet::get_slot($slot_name);
337: my $diff = $slot{'endtime'} - $submissiontime;
1.71 albertel 338: my ($color,$when)=('#FF6666','after');
339: if ($diff > 0) { ($color,$when)=('#336600','before'); }
1.60 albertel 340: my $info;
341: if ($diff%60) { $info=($diff%60).' seconds'; }
342: $diff=int($diff/60);
343: if ($diff%60) { $info=($diff%60).' minutes '.$info; }
344: $diff=int($diff/60);
345: if ($diff) { $info=$diff.' hours '.$info; }
346: $result='<p><font color="'.$color.'">'.
347: &mt('Student submitted [_1] [_2] the deadline.
348: (Submission was at [_3], end of period was [_4].)',
349: $info,$when,scalar(localtime($submissiontime)),
350: scalar(localtime($slot{'endtime'}))).
351: '</font></p>';
352: }
353: return $result;
354: }
355:
1.119 albertel 356: sub file_list {
357: my ($files,$uname,$udom) = @_;
358: if (!defined($uname) || !defined($udom)) {
359: (undef,undef,$udom,$uname) = &Apache::lonxml::whichuser();
360: }
1.70 albertel 361: my $file_url = '/uploaded/'.$udom.'/'.$uname.'/portfolio/';
1.119 albertel 362:
1.120 albertel 363: my $file_list="<ul class=\"LC_GRADING_handininfo\">\n";
1.119 albertel 364: foreach my $partial_file (split(',',$files)) {
1.70 albertel 365: my $file=$file_url.$partial_file;
366: $file=~s|/+|/|g;
367: &Apache::lonnet::allowuploaded('/adm/bridgetask',$file);
1.161 albertel 368: $file_list.='<li><span style="white-space: nowrap;"><a href="'.$file.'?rawmode=1" target="lonGRDs"><img src="'.
369: &Apache::loncommon::icon($file).'" alt="file icon" border="0" /> '.$file.
370: '</a></span></li>'."\n";
1.70 albertel 371: }
372: $file_list.="</ul>\n";
1.119 albertel 373: return $file_list;
374: }
375:
1.163 albertel 376: sub grade_mode {
377: if ($env{'form.regrade'} || $env{'form.regradeaspecificsubmission'}) {
378: return 'regrade';
379: }
380: return 'queue_grade';
381: }
382:
1.119 albertel 383: sub webgrade_standard_info {
384: my ($version)=&get_version();
385:
386: my $file_list = &file_list($Apache::lonhomework::history{"resource.$version.0.bridgetask.portfiles"});
1.70 albertel 387:
1.163 albertel 388: my %lt=('done' => 'Next Item',
389: 'stop' => 'Quit Grading',
390: 'fail' => 'Fail Rest',
391: 'cancel' => 'Cancel',
392: );
393: my %lt=&Apache::lonlocal::texthash(%lt);
394:
1.70 albertel 395: my $result=<<INFO;
1.120 albertel 396: <div class="LC_GRADING_maincontrols">
1.163 albertel 397: INFO
398:
399: if (&grade_mode() eq 'regrade') {
400: $result.=<<INFO;
401: <input type="submit" name="cancel" value="$lt{'cancel'}" />
402: INFO
403: }
404:
405: $result.=<<INFO;
1.111 albertel 406: <input type="submit" name="next" value="$lt{'done'}" />
407: <input type="submit" name="stop" value="$lt{'stop'}" />
1.143 albertel 408: <input type="button" name="fail" value="$lt{'fail'}"
409: onclick="javascript:onFailRest()" />
1.111 albertel 410: </div>
1.70 albertel 411: $file_list
412: INFO
413: return $result;
414: }
415:
1.1 albertel 416: sub start_Task {
1.87 albertel 417: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.1 albertel 418:
1.4 albertel 419: my ($status,$accessmsg,$slot);
1.16 albertel 420: if ($target ne 'webgrade') {
1.70 albertel 421: &Apache::structuretags::init_problem_globals('Task');
1.16 albertel 422: &Apache::structuretags::initialize_storage();
423: &Apache::lonhomework::showhash(%Apache::lonhomework::history);
1.74 albertel 424: if ($env{'request.state'} eq 'construct') {
425: &Apache::structuretags::setup_rndseed($safeeval);
426: }
1.16 albertel 427: }
428:
1.4 albertel 429: $Apache::lonhomework::parsing_a_task=1;
1.141 albertel 430:
431: my $name;
432: if ($target eq 'web' || $target eq 'webgrade') {
433: $name = &Apache::structuretags::get_resource_name($parstack,$safeeval);
434: }
435:
1.145 albertel 436: my ($result,$form_tag_start);
437: if ($target eq 'web' || $target eq 'webgrade' || $target eq 'tex'
438: || $target eq 'edit') {
439: ($result,$form_tag_start) =
440: &Apache::structuretags::page_start($target,$token,$tagstack,
441: $parstack,$parser,$safeeval,
1.146 albertel 442: $name,&style($target));
1.145 albertel 443: $result .= '<div class="LC_task">'."\n";
444: }
1.123 albertel 445:
1.74 albertel 446: if ($target eq 'web' && $env{'request.state'} ne 'construct') {
1.147 albertel 447: if ($Apache::lonhomework::queuegrade
448: || $Apache::lonhomework::modifygrades) {
1.141 albertel 449: $result.='<form name="gradesubmission" method="post" action="';
1.13 albertel 450: my $uri=$env{'request.uri'};
451: if ($env{'request.enc'}) { $uri=&Apache::lonenc::encrypted($uri); }
1.141 albertel 452: $result.=$uri.'">'.&add_grading_button()."</form>";
1.38 albertel 453: my $symb=&Apache::lonnet::symbread();
1.40 albertel 454: if (&Apache::lonnet::allowed('mgq',$env{'request.course.id'})) {
1.141 albertel 455: $result.='<form method="post" name="slotrequest" action="/adm/slotrequest">'.
1.40 albertel 456: '<input type="hidden" name="symb" value="'.$symb.'" />'.
457: '<input type="hidden" name="command" value="showslots" />'.
458: '<input type="submit" name="requestattempt" value="'.
459: &mt('Show Slot list').'" />'.
460: '</form>';
1.108 albertel 461: my $target_id =
462: &Apache::lonstathelpers::make_target_id({symb => $symb,
463: part => '0'});
1.141 albertel 464: $result.='<form method="post" name="gradingstatus" action="/adm/statistics">'.
1.108 albertel 465: '<input type="hidden" name="problemchoice" value="'.$target_id.'" />'.
466: '<input type="hidden" name="reportSelected" value="grading_analysis" />'.
467: '<input type="submit" name="grading" value="'.
468: &mt('Show Grading Status').'" />'.
469: '</form>';
1.40 albertel 470: }
1.13 albertel 471: }
1.8 albertel 472: }
1.74 albertel 473: if ($target eq 'web' && $env{'request.state'} eq 'construct') {
474: $form_tag_start.=&Apache::structuretags::problem_web_to_edit_header($env{'form.rndseed'});
475: }
1.163 albertel 476: if ($target eq 'web'
477: || ($target eq 'grade' && !$env{'form.webgrade'})
478: || $target eq 'answer'
479: || $target eq 'tex') {
1.29 albertel 480: my ($version,$previous)=&get_version();
1.14 albertel 481: ($status,$accessmsg,my $slot_name,$slot) =
1.81 albertel 482: &Apache::lonhomework::check_slot_access('0','Task');
1.152 albertel 483: if ($status eq 'CAN_ANSWER' && $version eq '') {
484: &create_new_version('Task',undef,undef,$slot_name);
485: &add_to_queue('gradingqueue',{'type' => 'Task',
486: 'time' => time,
487: 'slot' => $slot_name});
1.150 albertel 488: ($version,$previous)=&get_version();
489: }
490:
1.9 albertel 491: push(@Apache::inputtags::status,$status);
1.14 albertel 492: $Apache::inputtags::slot_name=$slot_name;
1.1 albertel 493: my $expression='$external::datestatus="'.$status.'";';
1.89 albertel 494: $expression.='$external::gradestatus="'.$Apache::lonhomework::history{"resource.$version.0.solved"}.'";';
1.1 albertel 495: &Apache::run::run($expression,$safeeval);
496: &Apache::lonxml::debug("Got $status");
1.141 albertel 497: $result.=&add_previous_version_button($status);
1.54 albertel 498: if (!&show_task($status,$previous)) {
1.87 albertel 499: my $bodytext=&Apache::lonxml::get_all_text("/task",$parser,$style);
1.1 albertel 500: if ( $target eq "web" ) {
1.74 albertel 501: if ($env{'request.state'} eq 'construct') {
502: $result.=$form_tag_start;
503: }
1.4 albertel 504: my $msg;
1.1 albertel 505: if ($status eq 'UNAVAILABLE') {
506: $msg.='<h1>'.&mt('Unable to determine if this resource is open due to network problems. Please try again later.').'</h1>';
1.3 albertel 507: } elsif ($status eq 'NOT_IN_A_SLOT') {
508: $msg.='<h1>'.&mt('You are not currently signed up to work at this time and/or place.').'</h1>';
1.38 albertel 509: $msg.=&add_request_another_attempt_button("Sign up for time to work.");
1.4 albertel 510: } elsif ($status eq 'NEEDS_CHECKIN') {
511: $msg.='<h1>'.&mt('You need the Proctor to validate you.').
512: '</h1>'.&proctor_validation_screen($slot);
1.22 albertel 513: } elsif ($status eq 'WAITING_FOR_GRADE') {
514: $msg.='<h1>'.&mt('Your submission is in the grading queue.').'</h1>';
1.64 albertel 515: } elsif ($env{'form.donescreen'}) {
516: my $title=&Apache::lonnet::gettitle();
1.67 albertel 517: my @files=split(',',$Apache::lonhomework::history{'resource.'.$version.'.0.bridgetask.portfiles'});
1.114 albertel 518: my (undef,undef,$domain,$user)=
519: &Apache::lonxml::whichuser();
520: my $files = '<ul>';
521: foreach my $file (@files) {
522: my $url="/uploaded/$domain/$user/portfolio$file";
1.130 albertel 523: if (! &Apache::lonnet::stat_file($url)) {
524: $file = &mt('<font color="red"> Nonexistant file:</font> <tt>[_1]</tt>',$file);
525: } else {
526: $file = '<tt>'.$file.'</tt>';
527: }
1.114 albertel 528: $files .= '<li>'.$file.'</li>';
529: }
530: $files.='</ul>';
531:
1.64 albertel 532: $result.=<<DONESCREEN;
533: <h2>$title</h2>
534: <p> Files submitted: $files </p>
1.67 albertel 535: <p> You are now done with this Bridge Task </p>
1.64 albertel 536: <hr />
537: <p> <a href="/adm/logout">Logout</a> </p>
538: <p> <a href="/adm/roles">Change to a different course</a> </p>
539: DONESCREEN
1.1 albertel 540: } elsif ($status ne 'NOT_YET_VIEWED') {
541: $msg.='<h1>'.&mt('Not open to be viewed').'</h1>';
542: }
543: if ($status eq 'CLOSED' || $status eq 'INVALID_ACCESS') {
544: $msg.='The problem '.$accessmsg;
545: }
546: $result.=$msg.'<br />';
547: } elsif ($target eq 'tex') {
548: $result.='\begin{document}\noindent \vskip 1 mm \begin{minipage}{\textwidth}\vskip 0 mm';
549: if ($status eq 'UNAVAILABLE') {
550: $result.=&mt('Unable to determine if this resource is open due to network problems. Please try again later.').'\vskip 0 mm ';
551: } else {
552: $result.=&mt('Problem is not open to be viewed. It')." $accessmsg \\vskip 0 mm ";
553: }
1.22 albertel 554: } elsif ($target eq 'grade' && !$env{'form.webgrade'}) {
1.4 albertel 555: if ($status eq 'NEEDS_CHECKIN') {
1.83 albertel 556: if(&proctor_check_auth($slot_name,$slot,'Task')
557: && defined($Apache::inputtags::slot_name)) {
1.148 albertel 558: my $result=
559: &add_to_queue('gradingqueue',
1.152 albertel 560: {'type' => 'Task',
1.148 albertel 561: 'time' => time,
562: 'slot' =>
563: $Apache::inputtags::slot_name});
1.77 albertel 564: &Apache::lonxml::debug("add_to_queue said $result");
565: }
1.4 albertel 566: }
1.1 albertel 567: }
568: } elsif ($target eq 'web') {
1.141 albertel 569:
1.57 albertel 570: $result.=&preserve_grade_info();
571: $result.=&internal_location();
1.36 albertel 572: $result.=$form_tag_start.
573: '<input type="hidden" name="submitted" value="yes" />';
1.54 albertel 574: &Apache::lonxml::startredirection();
1.1 albertel 575: }
1.21 albertel 576: } elsif ( ($target eq 'grade' && $env{'form.webgrade'}) ||
577: $target eq 'webgrade') {
1.32 albertel 578: my $webgrade='yes';
1.21 albertel 579: if ($target eq 'webgrade') {
1.141 albertel 580: $result.= "\n".'<div class="LC_GRADING_task">'."\n".
1.124 albertel 581: '<script type="text/javascript"
1.126 albertel 582: src="/res/adm/includes/task_grading.js"></script>';
1.49 albertel 583: #$result.='<br />Review'.&show_queue('reviewqueue');
584: #$result.='<br />Grade'.&show_queue('gradingqueue');
1.30 albertel 585: }
1.33 albertel 586: # FIXME Blast! still need to reorg this, need to reshow the
587: # queue being reviewed once done with the grade pass...
588: # Hrrm, vaildation pass should perhaps say 'not_locked'
589: # perhaps do a search if there is a key that is mine and if
590: # there isn't reshow the queue....
1.105 albertel 591: my ($todo,$status_code,$msg)=&get_key_todo($target);
1.33 albertel 592:
593: if ($todo) {
594: &setup_env_for_other_user($todo,$safeeval);
595: my ($symb,$uname,$udom)=&decode_queue_key($todo);
596: $result.="\n".'<table><tr><td>Found '.
597: &Apache::lonnet::gettitle($symb).' for '.$uname.' at '.$udom.'</td></tr></table>';
598: $form_tag_start.=
599: '<input type="hidden" name="gradingkey" value="'.
1.158 www 600: &escape($todo).'" />';
1.33 albertel 601: $Apache::bridgetask::queue_key=$todo;
602: &Apache::structuretags::initialize_storage();
603: &Apache::lonhomework::showhash(%Apache::lonhomework::history);
1.110 albertel 604: if ($target eq 'webgrade' && $status_code eq 'selected') {
605: $form_tag_start.=
606: '<input type="hidden" name="queuemode" value="selected" />';
1.33 albertel 607: }
1.15 albertel 608: } else {
1.33 albertel 609: if ($target eq 'webgrade') {
610: $result.="\n";
1.81 albertel 611: my $back='<p><a href="/adm/flip?postdata=return:">'.
612: &mt('Return to resource').'</a></p>';
1.33 albertel 613: if ($status_code eq 'stop') {
1.81 albertel 614: $result.='<b>'.&mt("Stopped grading.").'</b>'.$back;
1.163 albertel 615: } elsif ($status_code eq 'cancel') {
616: $result.='<b>'.&mt("Cancelled grading.").'</b>'.$back;
1.164 albertel 617: } elsif ($status_code eq 'never_versioned') {
618: $result.='<b>'.
619: &mt("Requested user has never accessed the task.").
620: '</b>'.$back;
1.165 ! albertel 621: } elsif ($status_code =~ /still_open:(.*)/) {
! 622: my $date = &Apache::lonlocal::locallocaltime($1);
! 623: $result.='<b>'.
! 624: &mt("Task is still open, will close at [_1].",$date).
! 625: '</b>'.$back;
1.33 albertel 626: } elsif ($status_code eq 'lock_failed') {
1.105 albertel 627: $result.='<b>'.&mt("Failed to lock the requested record.")
1.81 albertel 628: .'</b>'.$back;
1.33 albertel 629: } elsif ($status_code eq 'unlock') {
1.81 albertel 630: $result.='<b>'.&mt("Unlocked the requested record.")
631: .'</b>'.$back;
1.33 albertel 632: $result.=&show_queue($env{'form.queue'},1);
633: } elsif ($status_code eq 'show_list') {
634: $result.=&show_queue($env{'form.queue'},1);
1.49 albertel 635: } elsif ($status_code eq 'select_user') {
636: $result.=&select_user();
1.95 albertel 637: } elsif ($status_code eq 'unable') {
638: $result.='<b>'.&mt("Unable to aqcuire a user to grade.").'</b>'.$back;
1.105 albertel 639: } elsif ($status_code eq 'not_allowed') {
640: $result.='<b>'.&mt('Not allowed to grade the requested user.').' '.$msg.'</b>'.$back;
1.33 albertel 641: } else {
1.81 albertel 642: $result.='<b>'.&mt("No user to be graded.").'</b>'.$back;
1.32 albertel 643: }
1.21 albertel 644: }
1.33 albertel 645: $webgrade='no';
1.163 albertel 646: }
647: if (!$todo || $env{'form.cancel'}) {
1.87 albertel 648: my $bodytext=&Apache::lonxml::get_all_text("/task",$parser,$style);
1.32 albertel 649: }
650: if ($target eq 'webgrade' && defined($env{'form.queue'})) {
1.61 albertel 651: if ($webgrade eq 'yes') {
652: $result.=&submission_time_stamp();
653: }
1.32 albertel 654: $result.=$form_tag_start;
655: $result.='<input type="hidden" name="webgrade" value="'.
656: $webgrade.'" />';
657: $result.='<input type="hidden" name="queue" value="'.
658: $env{'form.queue'}.'" />';
1.52 albertel 659: if ($env{'form.regrade'}) {
660: $result.='<input type="hidden" name="regrade" value="'.
661: $env{'form.regrade'}.'" />';
662: }
1.62 albertel 663: if ($env{'form.chosensections'}) {
664: my @chosen_sections=
665: &Apache::loncommon::get_env_multiple('form.chosensections');
666: foreach my $sec (@chosen_sections) {
667: $result.='<input type="hidden" name="chosensections"
668: value="'.$sec.'" />';
669: }
670: }
1.70 albertel 671: if ($webgrade eq 'yes') { $result.=&webgrade_standard_info(); }
1.15 albertel 672: }
1.110 albertel 673: if ($target eq 'webgrade') {
1.120 albertel 674: $result.="\n".'<div id="LC_GRADING_criterialist">';
1.110 albertel 675: }
1.74 albertel 676: } elsif ($target eq 'edit') {
1.141 albertel 677: $result.=$form_tag_start.
1.74 albertel 678: &Apache::structuretags::problem_edit_header();
679: $Apache::lonxml::warnings_error_header=
680: &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 />";
681: my $temp=&Apache::edit::insertlist($target,$token);
682: $result.=$temp;
1.1 albertel 683: } else {
684: # page_start returned a starting result, delete it if we don't need it
685: $result = '';
686: }
687: return $result;
688: }
689:
1.165 ! albertel 690: sub get_task_end_time {
! 691: my ($queue_entry,$symb,$udom,$uname) = @_;
! 692:
! 693: my $end_time;
! 694: if (my $slot = &slotted_access($queue_entry)) {
! 695: my %slot_data=&Apache::lonnet::get_slot($slot);
! 696: $end_time = $slot_data{'endtime'};
! 697: } else {
! 698: $end_time = &Apache::lonhomework::due_date('0',$symb,
! 699: $udom,$uname);
! 700: }
! 701: return $end_time;
! 702: }
! 703:
1.32 albertel 704: sub get_key_todo {
705: my ($target)=@_;
706: my $todo;
1.33 albertel 707:
708: if (defined($env{'form.reviewasubmission'})) {
1.54 albertel 709: &Apache::lonxml::debug("review a submission....");
1.33 albertel 710: $env{'form.queue'}='reviewqueue';
711: return (undef,'show_list');
712: }
713:
714: if (defined($env{'form.reviewagrading'})) {
715: &Apache::lonxml::debug("review a grading....");
716: $env{'form.queue'}='gradingqueue';
717: return (undef,'show_list');
718: }
719:
1.49 albertel 720: if (defined($env{'form.regradeasubmission'})) {
721: &Apache::lonxml::debug("regrade a grading....");
722: $env{'form.queue'}='none';
723: return (undef,'select_user');
724: }
725:
1.105 albertel 726:
1.138 albertel 727: my $me=$env{'user.name'}.':'.$env{'user.domain'};
1.105 albertel 728:
729: #need to try both queues..
730: if (defined($env{'form.regradeaspecificsubmission'}) &&
731: defined($env{'form.gradinguser'}) &&
732: defined($env{'form.gradingdomain'}) ) {
733: my ($symb,$cid)=&Apache::lonxml::whichuser();
734: my $cnum = $env{'course.'.$cid.'.num'};
735: my $cdom = $env{'course.'.$cid.'.domain'};
736: my $uname = $env{'form.gradinguser'};
737: my $udom = $env{'form.gradingdomain'};
738:
739: my $gradingkey=&encode_queue_key($symb,$udom,$uname);
740:
741: my $queue;
742:
743: if (&in_queue('gradingqueue',$symb,$cdom,$cnum,$udom,$uname)) {
744: $env{'form.queue'} = $queue = 'gradingqueue';
745: } elsif (&in_queue('reviewqueue' ,$symb,$cdom,$cnum,$udom,$uname)) {
746: $env{'form.queue'} = $queue = 'reviewqueue';
747: }
748:
749: if (!$queue) {
750: $env{'form.queue'} = $queue = 'none';
751: #not queued so doing either a re or pre grade
1.164 albertel 752: my %status = &Apache::lonnet::restore($symb,$cid,$udom,$uname);
753: if ($status{'resource.0.version'} < 1) {
754: return (undef,'never_versioned');
755: }
1.105 albertel 756: return ($gradingkey);
757: }
758:
1.165 ! albertel 759: if ($queue) {
! 760: my $queue_entry = &get_queue_data($queue,$udom,$uname);
! 761:
! 762: my $end_time = &get_task_end_time($queue_entry,$symb,
! 763: $udom,$uname);
! 764: if ($end_time > time) {
! 765: return (undef,"still_open:$end_time");
! 766: }
! 767: }
! 768:
1.105 albertel 769: my $who=&queue_key_locked($queue,$gradingkey);
770: if ($who eq $me) {
771: #already have the lock
1.158 www 772: $env{'form.gradingkey'}=&escape($gradingkey);
1.163 albertel 773: &Apache::lonxml::debug("already locked");
1.105 albertel 774: return ($gradingkey);
775: }
776:
777: if (!defined($who)) {
778: if (&lock_key($queue,$gradingkey)) {
1.163 albertel 779: &Apache::lonxml::debug("newly locked");
1.105 albertel 780: return ($gradingkey);
781: } else {
782: return (undef,'lock_failed');
783: }
784: }
785:
786: #otherwise (defined($who) && $who ne $me) some else has it...
787: return (undef,'not_allowed',
788: &mt('Another user ([_1]) currently has the record for [_2] locked.',
1.138 albertel 789: $who,$env{'form.gradinguser'}.':'.$env{'form.gradingdomain'}));
1.105 albertel 790: }
791:
792:
1.32 albertel 793: my $queue=$env{'form.queue'};
1.33 albertel 794:
1.32 albertel 795: if (!defined($queue)) {
796: $env{'form.queue'}=$queue='gradingqueue';
797: }
1.33 albertel 798:
1.158 www 799: my $gradingkey=&unescape($env{'form.gradingkey'});
1.33 albertel 800:
1.49 albertel 801: if ($env{'form.queue'} eq 'none') {
802: if (defined($env{'form.gradingkey'})) {
803: if ($target eq 'webgrade') {
804: if ($env{'form.stop'}) {
805: return (undef,'stop');
1.163 albertel 806: } elsif ($env{'form.cancel'}) {
807: return (undef,'cancel');
1.49 albertel 808: } elsif ($env{'form.next'}) {
1.59 albertel 809: return (undef,'select_user');
1.49 albertel 810: }
811: }
812: return ($gradingkey,'selected');
813: } else {
1.59 albertel 814: return (undef,'select_user');
1.49 albertel 815: }
816: }
1.32 albertel 817: if (defined($env{'form.queue'}) && defined($env{'form.gradingkey'})
1.33 albertel 818: && !defined($env{'form.gradingaction'})
819: && $env{'form.queuemode'} eq 'selected') {
820:
821: my $who=&queue_key_locked($queue,$gradingkey);
822: if ($who eq $me) {
823: &Apache::lonxml::debug("Found a key was given to me");
824: return ($gradingkey,'selected');
825: } else {
826: return (undef,'show_list');
827: }
828:
829: }
830:
831: if ($target eq 'webgrade' && $env{'form.queuemode'} eq 'selected') {
832: if ($env{'form.gradingaction'} eq 'resume') {
833: delete($env{'form.gradingaction'});
834: &Apache::lonxml::debug("Resuming a key");
1.32 albertel 835: return ($gradingkey);
1.33 albertel 836: } elsif ($env{'form.gradingaction'} eq 'unlock') {
837: &Apache::lonxml::debug("Unlocking a key ".
838: &check_queue_unlock($queue,$gradingkey,1));
839: return (undef,'unlock');
840: } elsif ($env{'form.gradingaction'} eq 'select') {
841: &Apache::lonxml::debug("Locking a key");
842: if (&lock_key($queue,$gradingkey)) {
843: &Apache::lonxml::debug("Success $queue");
844: return ($gradingkey);
845: }
846: &Apache::lonxml::debug("Failed $queue");
847: return (undef,'lock_failed');
1.32 albertel 848: }
849: }
1.33 albertel 850:
851: if ($env{'form.queuemode'} ne 'selected') {
852: # don't get something new from the queue if they hit the stop button
1.163 albertel 853: if (!(($env{'form.cancel'} || $env{'form.stop'})
854: && $target eq 'webgrade')
1.33 albertel 855: && !$env{'form.gradingaction'}) {
856: &Apache::lonxml::debug("Getting anew $queue");
857: return (&get_from_queue($queue));
858: } else {
859: return (undef,'stop');
860: }
1.32 albertel 861: }
1.33 albertel 862: return (undef,undef)
1.32 albertel 863: }
1.94 albertel 864:
865: sub minimize_storage {
866: foreach my $key (keys(%Apache::lonhomework::results)) {
867: if ($key =~ /regrader$/) { next; }
868: if ($Apache::lonhomework::results{$key} eq
869: $Apache::lonhomework::history{$key}) {
870: delete($Apache::lonhomework::results{$key});
871: }
872: }
873: }
874:
1.1 albertel 875: sub end_Task {
876: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
877: my $result='';
878: my $status=$Apache::inputtags::status['-1'];
1.29 albertel 879: my ($version,$previous)=&get_version();
1.1 albertel 880: if ($target eq 'grade' || $target eq 'web' || $target eq 'answer' ||
1.15 albertel 881: $target eq 'tex') {
1.69 albertel 882: if ($target eq 'web' || $target eq 'answer' || $target eq 'tex') {
1.1 albertel 883: if ($target eq 'web') {
1.54 albertel 884: if (&show_task($status,$previous)) {
885: $result.=&Apache::lonxml::endredirection();
886: }
1.64 albertel 887: if ($status eq 'CAN_ANSWER' && !$previous &&
888: !$env{'form.donescreen'}) {
1.15 albertel 889: $result.="\n".'<table border="1">'.
1.28 albertel 890: &Apache::inputtags::file_selector("$version.0",
891: "bridgetask","*",
1.46 albertel 892: 'portfolioonly',
893: '
894: <h2>'.&mt('Submit Portfolio Files for Grading').'</h2>
895: <p>'.&mt('Indicate the files from your portfolio to be evaluated in grading this task.').'</p>').
1.9 albertel 896: "</table>";
1.77 albertel 897: }
1.78 albertel 898: if (!$previous && $status ne 'SHOW_ANSWER' &&
899: &show_task($status,$previous)) {
1.9 albertel 900: $result.=&Apache::inputtags::gradestatus('0');
1.64 albertel 901: $result.='</form>';
1.116 albertel 902: my $action = &Apache::lonenc::check_encrypt($env{'request.uri'});
1.64 albertel 903: $result.=<<DONEBUTTON;
1.115 albertel 904: <form name="done" method="post" action="$action">
1.64 albertel 905: <input type="hidden" name="donescreen" value="1" />
906: <input type="submit" value="Done" />
907: </form>
908: DONEBUTTON
1.77 albertel 909: }
1.56 albertel 910: if (&show_task($status,$previous) &&
1.89 albertel 911: $Apache::lonhomework::history{"resource.$version.0.status"} =~ /^(pass|fail)$/) {
912: my $bt_status=$Apache::lonhomework::history{"resource.$version.0.status"};
1.54 albertel 913: my $title=&Apache::lonnet::gettitle();
1.80 albertel 914:
1.149 albertel 915: my $start_time;
916:
1.80 albertel 917: my $slot_name=
1.89 albertel 918: $Apache::lonhomework::history{"resource.$version.0.checkedin.slot"};
1.149 albertel 919: if ($slot_name) {
920: my %slot=&Apache::lonnet::get_slot($slot_name);
921:
922: $start_time=$slot{'starttime'}
923: } else {
924: $start_time=
925: &Apache::lonnet::EXT('resource.0.opendate');
926: }
927: $start_time=&Apache::lonlocal::locallocaltime($start_time);
1.54 albertel 928:
1.116 albertel 929: my $status = "\n<div class='LC_$bt_status LC_criteria'>\n";
1.54 albertel 930:
931: if ($bt_status eq 'pass') {
932: $status.='<h2>You passed the '.$title.' given on '.
1.80 albertel 933: $start_time.'</h2>';
1.54 albertel 934: }
935: if ($bt_status eq 'fail') {
936: $status.='<h2>You did not pass the '.$title.' given on '.
1.80 albertel 937: $start_time.'</h2>';
1.54 albertel 938: if (!$previous) {
939: $status.=&add_request_another_attempt_button();
940: }
941: }
942: my $man_count=0;
943: my $opt_count=0;
944: my $opt_passed=0;
945: foreach my $dim_id (@Apache::bridgetask::dimensionlist) {
946: if ($Apache::bridgetask::dimensionmandatory{$dim_id}
947: eq 'N') {
948: $opt_count++;
1.89 albertel 949: if ($Apache::lonhomework::history{"resource.$version.0.$dim_id.status"} eq 'pass') {
1.54 albertel 950: $opt_passed++;
951: }
952: } else {
953: $man_count++;
954: }
955: }
1.151 albertel 956:
1.54 albertel 957: my $opt_req=&Apache::lonxml::get_param('OptionalRequired',
958: $parstack,$safeeval);
959: if ($opt_req !~ /\S/) { $opt_req='0'; }
1.99 albertel 960: $status.="\n<p>".&mt('You needed to pass all of the [_1] mandatory components and [_2] of the [_3] optional components, of which you passed [_4].',$man_count,$opt_req,$opt_count,$opt_passed)."</p></div>\n";
1.54 albertel 961:
962: my $internal_location=&internal_location();
963: $result=~s/\Q$internal_location\E/$status/;
964: }
1.142 albertel 965: $result.="\n</div>\n".
966: &Apache::loncommon::end_page({'discussion' => 1});
1.1 albertel 967: }
968: }
1.29 albertel 969: if ($target eq 'grade' && !$env{'form.webgrade'} && !$previous) {
1.12 albertel 970: my $award='SUBMITTED';
1.28 albertel 971: &Apache::essayresponse::file_submission("$version.0",'bridgetask',
1.20 albertel 972: 'portfiles',\$award);
1.14 albertel 973: if ($award eq 'SUBMITTED' &&
1.28 albertel 974: $Apache::lonhomework::results{"resource.$version.0.bridgetask.portfiles"}) {
975: $Apache::lonhomework::results{"resource.0.tries"}=
976: $Apache::lonhomework::results{"resource.$version.0.tries"}=
977: 1+$Apache::lonhomework::history{"resource.$version.0.tries"};
978:
979: $Apache::lonhomework::results{"resource.0.award"}=
980: $Apache::lonhomework::results{"resource.$version.0.award"}=
981: $award;
1.51 albertel 982: $Apache::lonhomework::results{"resource.0.submission"}=
983: $Apache::lonhomework::results{"resource.$version.0.submission"}='';
1.64 albertel 984: } else {
985: delete($Apache::lonhomework::results{"resource.$version.0.bridgetask.portfiles"});
1.77 albertel 986: $award = '';
1.10 albertel 987: }
1.4 albertel 988: &Apache::lonhomework::showhash(%Apache::lonhomework::results);
989: &Apache::structuretags::finalize_storage();
1.148 albertel 990: if ($award eq 'SUBMITTED') {
991: my $useslots = &Apache::lonnet::EXT("resource.0.useslots");
992: if ($useslots =~ /^\s*no\s*$/i) {
993: &add_to_queue('gradingqueue',
1.152 albertel 994: {'type' => 'Task',
1.148 albertel 995: 'time' => time});
996: } elsif (defined($Apache::inputtags::slot_name)) {
997: &add_to_queue('gradingqueue',
1.152 albertel 998: {'type' => 'Task',
1.148 albertel 999: 'time' => time,
1000: 'slot' => $Apache::inputtags::slot_name});
1001: }
1.14 albertel 1002: }
1.79 albertel 1003: } elsif ($Apache::lonhomework::results{'INTERNAL_store'}) {
1004: &Apache::structuretags::finalize_storage();
1.1 albertel 1005: }
1.163 albertel 1006: if ($target eq 'grade' && $env{'form.webgrade'} eq 'yes'
1007: && exists($env{'form.cancel'})) {
1008: &check_queue_unlock($env{'form.queue'});
1009: &Apache::lonxml::debug(" cancelled grading .".$env{'form.queue'});
1010: } elsif ($target eq 'grade' && $env{'form.webgrade'} eq 'yes'
1011: && !exists($env{'form.cancel'})) {
1.20 albertel 1012: my $optional_required=
1013: &Apache::lonxml::get_param('OptionalRequired',$parstack,
1014: $safeeval);
1015: my $optional_passed=0;
1016: my $mandatory_failed=0;
1017: my $ungraded=0;
1018: my $review=0;
1.21 albertel 1019: &Apache::lonhomework::showhash(%Apache::lonhomework::results);
1.20 albertel 1020: foreach my $dim_id (@Apache::bridgetask::dimensionlist) {
1021: my $status=
1.89 albertel 1022: $Apache::lonhomework::results{"resource.$version.0.$dim_id.status"};
1.20 albertel 1023: my $mandatory=
1024: ($Apache::bridgetask::dimensionmandatory{$dim_id} ne 'N');
1025: if ($status eq 'pass') {
1026: if (!$mandatory) { $optional_passed++; }
1027: } elsif ($status eq 'fail') {
1028: if ($mandatory) { $mandatory_failed++; }
1029: } elsif ($status eq 'ungraded') {
1030: $ungraded++;
1031: } elsif ($status eq 'review') {
1032: $review++;
1.49 albertel 1033: } else {
1034: $ungraded++;
1035: }
1.20 albertel 1036: }
1037: if ($optional_passed < $optional_required) {
1038: $mandatory_failed++;
1039: }
1.21 albertel 1040: &Apache::lonxml::debug("all dim ".join(':',@Apache::bridgetask::dimensionlist)."results -> m_f $mandatory_failed o_p $optional_passed u $ungraded r $review");
1.89 albertel 1041: $Apache::lonhomework::results{'resource.0.regrader'}=
1.138 albertel 1042: $env{'user.name'}.':'.$env{'user.domain'};
1.20 albertel 1043: if ($review) {
1.89 albertel 1044: $Apache::lonhomework::results{"resource.$version.0.status"}='review';
1.33 albertel 1045: if ($env{'form.queue'} eq 'reviewqueue') {
1046: &check_queue_unlock($env{'form.queue'});
1047: &Apache::lonxml::debug(" still needs review not changing status.");
1048: } else {
1.49 albertel 1049: &move_between_queues($env{'form.queue'},'reviewqueue');
1.33 albertel 1050: }
1.20 albertel 1051: } elsif ($ungraded) {
1.89 albertel 1052: $Apache::lonhomework::results{"resource.$version.0.status"}='ungraded';
1.49 albertel 1053: if ($env{'form.queue'} eq 'reviewqueue' ||
1054: $env{'form.queue'} eq 'none' ) {
1.33 albertel 1055: &Apache::lonxml::debug("moving back.");
1.49 albertel 1056: &move_between_queues($env{'form.queue'},'gradingqueue');
1.33 albertel 1057: } else {
1058: &check_queue_unlock($env{'form.queue'});
1059: }
1.20 albertel 1060: } elsif ($mandatory_failed) {
1.89 albertel 1061: $Apache::lonhomework::results{"resource.$version.0.status"}='fail';
1.25 albertel 1062: $Apache::lonhomework::results{"resource.$version.0.solved"}='incorrect_by_override';
1063: $Apache::lonhomework::results{"resource.$version.0.award"}='INCORRECT';
1064: $Apache::lonhomework::results{"resource.$version.0.awarded"}='0';
1.39 albertel 1065: &remove_from_queue($env{'form.queue'});
1066:
1067: my ($symb,$courseid,$udom,$uname)=&Apache::lonxml::whichuser();
1.52 albertel 1068:
1069: if ($env{'form.regrade'} ne 'yes') {
1070: $Apache::lonhomework::results{"resource.$version.0.bridgetask.portfiles"}=
1071: $Apache::lonhomework::history{"resource.$version.0.bridgetask.portfiles"};
1072: &Apache::grades::version_portfiles(
1073: \%Apache::lonhomework::results,
1074: ["$version.0.bridgetask"],$courseid,
1075: $symb,$udom,$uname,
1076: ["$version.0.bridgetask"]);
1077: }
1.20 albertel 1078: } else {
1.89 albertel 1079: $Apache::lonhomework::results{"resource.$version.0.status"}='pass';
1.25 albertel 1080: $Apache::lonhomework::results{"resource.$version.0.solved"}='correct_by_override';
1081: $Apache::lonhomework::results{"resource.$version.0.award"}='EXACT_ANS';
1082: $Apache::lonhomework::results{"resource.$version.0.awarded"}='1';
1.32 albertel 1083: &remove_from_queue($env{'form.queue'});
1.39 albertel 1084:
1085: my ($symb,$courseid,$udom,$uname)=&Apache::lonxml::whichuser();
1.52 albertel 1086: if ($env{'form.regrade'} ne 'yes') {
1087: $Apache::lonhomework::results{"resource.$version.0.bridgetask.portfiles"}=
1088: $Apache::lonhomework::history{"resource.$version.0.bridgetask.portfiles"};
1089: &Apache::grades::version_portfiles(
1090: \%Apache::lonhomework::results,
1091: ["$version.0.bridgetask"],$courseid,
1092: $symb,$udom,$uname,
1093: ["$version.0.bridgetask"]);
1094: }
1.20 albertel 1095: }
1.89 albertel 1096: $Apache::lonhomework::results{"resource.0.status"}=
1097: $Apache::lonhomework::results{"resource.$version.0.status"};
1.28 albertel 1098: if (defined($Apache::lonhomework::results{"resource.$version.0.awarded"})) {
1.26 albertel 1099: $Apache::lonhomework::results{"resource.0.award"}=
1.50 albertel 1100: $Apache::lonhomework::results{"resource.$version.0.award"};
1.26 albertel 1101: $Apache::lonhomework::results{"resource.0.awarded"}=
1.50 albertel 1102: $Apache::lonhomework::results{"resource.$version.0.awarded"};
1.26 albertel 1103: $Apache::lonhomework::results{"resource.0.solved"}=
1.50 albertel 1104: $Apache::lonhomework::results{"resource.$version.0.solved"};
1.25 albertel 1105: }
1.94 albertel 1106: &minimize_storage();
1.21 albertel 1107: &Apache::structuretags::finalize_storage();
1.20 albertel 1108: }
1.15 albertel 1109: } elsif ($target eq 'webgrade') {
1.131 albertel 1110: $result.="</div>";
1.20 albertel 1111: #$result.='<input type="submit" name="next" value="'.
1112: # &mt('Save & Next').'" /> ';
1113: #$result.='<input type="submit" name="end" value="'.
1114: # &mt('Save & Stop Grading').'" /> ';
1115: #$result.='<input type="submit" name="throwaway" value="'.
1116: # &mt('Throw Away & Stop Grading').'" /> ';
1117: #$result.='<input type="submit" name="save" value="'.
1118: # &mt('Save Partial Grade and Continue Grading').'" /> ';
1.124 albertel 1119: $result.='</form>'."\n</div>\n</div>\n".
1.140 albertel 1120: &Apache::loncommon::end_page();
1.1 albertel 1121: } elsif ($target eq 'meta') {
1.70 albertel 1122: $result.=&Apache::response::meta_package_write('Task');
1.77 albertel 1123: $result.=&Apache::response::meta_stores_write('solved','string',
1124: 'Problem Status');
1125: $result.=&Apache::response::meta_stores_write('tries','int_zeropos',
1126: 'Number of Attempts');
1127: $result.=&Apache::response::meta_stores_write('awarded','float',
1128: 'Partial Credit Factor');
1129: $result.=&Apache::response::meta_stores_write('status','string',
1130: 'Bridge Task Status');
1.1 albertel 1131: }
1.4 albertel 1132: undef($Apache::lonhomework::parsing_a_task);
1.1 albertel 1133: return $result;
1134: }
1135:
1.31 albertel 1136: sub move_between_queues {
1137: my ($src_queue,$dest_queue)=@_;
1.49 albertel 1138: my $cur_data;
1139: if ($src_queue ne 'none') {
1140: $cur_data=&get_queue_data($src_queue);
1141: if (!$cur_data) { return 'not_exist'; }
1142: } else {
1143: $cur_data = ['none'];
1144: }
1.148 albertel 1145: my $result=&add_to_queue($dest_queue,$cur_data);
1.31 albertel 1146: if ($result ne 'ok') {
1147: return $result;
1148: }
1149: &check_queue_unlock($src_queue);
1150: return &remove_from_queue($src_queue);
1.21 albertel 1151: }
1152:
1153: sub check_queue_unlock {
1.32 albertel 1154: my ($queue,$key,$allow_not_me)=@_;
1.49 albertel 1155: if ($queue eq 'none') { return 'ok'; }
1.30 albertel 1156: my ($symb,$cid,$udom,$uname)=&Apache::lonxml::whichuser();
1.32 albertel 1157: if (!defined($key)) {
1.138 albertel 1158: $key="$symb\0queue\0$uname:$udom";
1.32 albertel 1159: }
1.30 albertel 1160: my $cnum=$env{'course.'.$cid.'.num'};
1161: my $cdom=$env{'course.'.$cid.'.domain'};
1.138 albertel 1162: my $me=$env{'user.name'}.':'.$env{'user.domain'};
1.30 albertel 1163: my $who=&queue_key_locked($queue,$key,$cdom,$cnum);
1164: if ($who eq $me) {
1.163 albertel 1165: &Apache::lonxml::debug("unlocking my own $who");
1.32 albertel 1166: return &Apache::lonnet::del($queue,["$key\0locked"],$cdom,$cnum);
1167: } elsif ($allow_not_me) {
1.33 albertel 1168: &Apache::lonxml::debug("unlocking $who by $me");
1.32 albertel 1169: return &Apache::lonnet::del($queue,["$key\0locked"],$cdom,$cnum);
1.30 albertel 1170: }
1.32 albertel 1171: return 'not_owner';
1.21 albertel 1172: }
1173:
1.88 albertel 1174: sub in_queue {
1175: my ($queue,$symb,$cdom,$cnum,$udom,$uname)=@_;
1176: if ($queue eq 'none') { return 0; }
1177: if (!defined($symb) || !defined($cdom) || !defined($cnum)
1178: || !defined($udom) || !defined($uname)) {
1179: ($symb,my $cid,$udom,$uname)=&Apache::lonxml::whichuser();
1180: $cnum=$env{'course.'.$cid.'.num'};
1181: $cdom=$env{'course.'.$cid.'.domain'};
1182: }
1183:
1184: my $key=&encode_queue_key($symb,$udom,$uname);
1185: my %results = &Apache::lonnet::get($queue,[$key],$cdom,$cnum);
1186:
1187: if (defined($results{$key})) {
1188: return 1;
1189: }
1190: return 0;
1191: }
1192:
1.21 albertel 1193: sub remove_from_queue {
1.86 albertel 1194: my ($queue,$symb,$cdom,$cnum,$udom,$uname)=@_;
1.49 albertel 1195: if ($queue eq 'none') { return 'ok'; }
1.86 albertel 1196: if (!defined($symb) || !defined($cdom) || !defined($cnum)
1197: || !defined($udom) || !defined($uname)) {
1198: ($symb,my $cid,$udom,$uname)=&Apache::lonxml::whichuser();
1199: $cnum=$env{'course.'.$cid.'.num'};
1200: $cdom=$env{'course.'.$cid.'.domain'};
1201: }
1.88 albertel 1202: if (!&in_queue($queue,$symb,$cdom,$cnum,$udom,$uname)) {
1203: return 'ok';
1204: }
1.86 albertel 1205: my $key=&encode_queue_key($symb,$udom,$uname);
1.27 albertel 1206: my @keys=($key,"$key\0locked");
1.31 albertel 1207: return &Apache::lonnet::del($queue,\@keys,$cdom,$cnum);
1.21 albertel 1208: }
1209:
1.16 albertel 1210: sub setup_env_for_other_user {
1211: my ($queue_key,$safeeval)=@_;
1212: my ($symb,$uname,$udom)=&decode_queue_key($queue_key);
1.30 albertel 1213: &Apache::lonxml::debug("setup_env for $queue_key");
1.16 albertel 1214: $env{'form.grade_symb'}=$symb;
1215: $env{'form.grade_domain'}=$udom;
1216: $env{'form.grade_username'}=$uname;
1217: $env{'form.grade_courseid'}=$env{'request.course.id'};
1218: &Apache::lonxml::initialize_rndseed($safeeval);
1219: }
1220:
1.31 albertel 1221: sub get_queue_data {
1.165 ! albertel 1222: my ($queue,$udom,$uname)=@_;
! 1223: my ($symb,$cid,$other_udom,$other_uname)=&Apache::lonxml::whichuser();
! 1224: if (!$uname || !$udom) {
! 1225: $uname=$other_uname;
! 1226: $udom =$other_udom;
! 1227: }
1.31 albertel 1228: my $cnum=$env{'course.'.$cid.'.num'};
1229: my $cdom=$env{'course.'.$cid.'.domain'};
1.138 albertel 1230: my $todo="$symb\0queue\0$uname:$udom";
1.31 albertel 1231: my ($key,$value)=&Apache::lonnet::get($queue,[$todo],$cdom,$cnum);
1232: if ($key eq $todo && ref($value)) {
1233: return $value;
1234: }
1235: return undef;
1236: }
1237:
1.84 albertel 1238:
1.49 albertel 1239: sub check_queue_for_key {
1.84 albertel 1240: my ($cdom,$cnum,$queue,$todo)=@_;
1241:
1.49 albertel 1242: my %results=
1243: &Apache::lonnet::get($queue,[$todo,"$todo\0locked"],$cdom,$cnum);
1244:
1245: if (exists($results{$todo}) && ref($results{$todo})) {
1246: if (defined($results{"$todo\0locked"})) {
1247: return 'locked';
1248: }
1.148 albertel 1249: if (my $slot=&slotted_access($results{$todo})) {
1.86 albertel 1250: my %slot_data=&Apache::lonnet::get_slot($slot);
1251: if ($slot_data{'endtime'} > time) {
1252: return 'in_progress';
1253: }
1.148 albertel 1254: } else {
1255: my ($symb) = &decode_queue_key($todo);
1256: my $due_date = &Apache::lonhomework::due_date('0',$symb);
1257: if ($due_date > time) {
1258: return 'in_progress';
1259: }
1.58 albertel 1260: }
1.49 albertel 1261: return 'enqueued';
1262: }
1263: return undef;
1264: }
1265:
1.14 albertel 1266: sub add_to_queue {
1.82 albertel 1267: my ($queue,$user_data)=@_;
1.49 albertel 1268: if ($queue eq 'none') { return 'ok'; }
1.14 albertel 1269: my ($symb,$cid,$udom,$uname)=&Apache::lonxml::whichuser();
1.82 albertel 1270: if (!$cid || $env{'request.state'} eq 'construct') {
1271: return 'no_queue';
1272: }
1.14 albertel 1273: my $cnum=$env{'course.'.$cid.'.num'};
1274: my $cdom=$env{'course.'.$cid.'.domain'};
1275: my %data;
1.138 albertel 1276: $data{"$symb\0queue\0$uname:$udom"}=$user_data;
1.83 albertel 1277: return &Apache::lonnet::cput($queue,\%data,$cdom,$cnum);
1.14 albertel 1278: }
1279:
1.156 albertel 1280: sub get_limited_classlist {
1281: my ($sections) = @_;
1282:
1283: my $classlist = &Apache::loncoursedata::get_classlist();
1.157 albertel 1284: foreach my $student (keys(%$classlist)) {
1285: if ( $classlist->{$student}[&Apache::loncoursedata::CL_STATUS()]
1286: ne 'Active') {
1287: delete($classlist->{$student});
1288: }
1289: }
1.156 albertel 1290:
1.157 albertel 1291: if (ref($sections) && !grep('all',@{ $sections })) {
1.156 albertel 1292: foreach my $student (keys(%$classlist)) {
1293: my $section =
1294: $classlist->{$student}[&Apache::loncoursedata::CL_SECTION()];
1295: if (! grep($section,@{ $sections })) {
1296: delete($classlist->{$student});
1297: }
1298: }
1299: }
1300: return $classlist;
1301: }
1302:
1303:
1.14 albertel 1304: sub show_queue {
1.32 albertel 1305: my ($queue,$with_selects)=@_;
1.14 albertel 1306: my $result;
1307: my ($symb,$cid,$udom,$uname)=&Apache::lonxml::whichuser();
1308: my $cnum=$env{'course.'.$cid.'.num'};
1309: my $cdom=$env{'course.'.$cid.'.domain'};
1.59 albertel 1310:
1311: my @chosen_sections=
1312: &Apache::loncommon::get_env_multiple('form.chosensections');
1.156 albertel 1313:
1314: my $classlist = &get_limited_classlist(\@chosen_sections);
1315:
1.63 albertel 1316: if (!(grep(/^all$/,@chosen_sections))) {
1317: $result.='<p> Showing only sections <tt>'.join(', ',@chosen_sections).
1318: '</tt>.</p> '."\n";
1319: }
1.59 albertel 1320:
1.156 albertel 1321: my ($view,$view_section);
1322: my $scope = $env{'request.course.id'};
1323: if (!($view=&Apache::lonnet::allowed('vgr',$scope))) {
1324: $scope .= '/'.$env{'request.course.sec'};
1325: if ( $view = &Apache::lonnet::allowed('vgr',$scope)) {
1326: $view_section=$env{'request.course.sec'};
1327: } else {
1328: undef($view);
1329: }
1330: }
1331:
1.16 albertel 1332: my $regexp="^$symb\0";
1.30 albertel 1333: my %queue=&Apache::lonnet::dump($queue,$cdom,$cnum,$regexp);
1.31 albertel 1334: my ($tmp)=%queue;
1335: if ($tmp=~/^error: 2 /) {
1.159 albertel 1336: return "\n<h3>Current Queue - $queue</h3>".
1337: &Apache::loncommon::start_data_table().
1338: &Apache::loncommon::start_data_table_row().
1339: '<td>'.&mt('Empty').'</td>'.
1340: &Apache::loncommon::end_data_table_row().
1341: &Apache::loncommon::end_data_table();
1.31 albertel 1342: }
1.103 albertel 1343: my $title=&Apache::lonnet::gettitle($symb);
1.159 albertel 1344: $result.="\n<h3>Current Queue - $title $queue </h3>".
1345: &Apache::loncommon::start_data_table().
1346: &Apache::loncommon::start_data_table_header_row();
1.103 albertel 1347: if ($with_selects) { $result.="<th>Status</th><th></th>"; }
1.159 albertel 1348: $result.="<th>user</th><th>data</th>".
1349: &Apache::loncommon::end_data_table_header_row();
1.14 albertel 1350: foreach my $key (sort(keys(%queue))) {
1.59 albertel 1351: my ($symb,$uname,$udom) = &decode_queue_key($key);
1352: if (!defined($classlist->{$uname.':'.$udom})) { next; }
1.156 albertel 1353:
1354: my $section = $classlist->{$uname.':'.$udom}[&Apache::loncoursedata::CL_SECTION()];
1355:
1356: my $can_view=1;
1357: if (!$view
1358: || ($view_section && !$section)
1359: || ($view_section && $section && ($view_section ne $section))) {
1360: $can_view=0;
1361: }
1362:
1.32 albertel 1363: if ($key=~/locked$/ && !$with_selects) {
1.159 albertel 1364: $result.= &Apache::loncommon::start_data_table_row().
1365: "<td>$uname</td>";
1.103 albertel 1366: $result.='<td>'.$queue{$key}.'</td></tr>';
1.32 albertel 1367: } elsif ($key=~/timestamp$/ && !$with_selects) {
1.159 albertel 1368: $result.=&Apache::loncommon::start_data_table_row()."<td></td>";
1.103 albertel 1369: $result.='<td>'.
1.16 albertel 1370: &Apache::lonlocal::locallocaltime($queue{$key})."</td></tr>";
1.32 albertel 1371: } elsif ($key!~/(timestamp|locked)$/) {
1.159 albertel 1372: $result.= &Apache::loncommon::start_data_table_row();
1.148 albertel 1373: my ($end_time,$slot_text);
1374: if (my $slot=&slotted_access($queue{$key})) {
1375: my %slot_data=&Apache::lonnet::get_slot($slot);
1376: $end_time = $slot_data{'endtime'};
1377: $slot_text = &mt('Slot: [_1]',$slot);
1378: } else {
1379: $end_time = &Apache::lonhomework::due_date('0',$symb);
1380: $slot_text = '';
1381: }
1.32 albertel 1382: if ($with_selects) {
1.158 www 1383: my $ekey=&escape($key);
1.103 albertel 1384: my ($action,$description,$status)=('select',&mt('Select'));
1.32 albertel 1385: if (exists($queue{"$key\0locked"})) {
1.138 albertel 1386: my $me=$env{'user.name'}.':'.$env{'user.domain'};
1.103 albertel 1387: $status=&mt('Locked by <tt>[_1]</tt>',$queue{"$key\0locked"});
1.32 albertel 1388: if ($me eq $queue{"$key\0locked"}) {
1389: ($action,$description)=('resume',&mt('Resume'));
1390: } else {
1391: ($action,$description)=('unlock',&mt('Unlock'));
1392: }
1393: }
1.62 albertel 1394: my $seclist;
1395: foreach my $sec (@chosen_sections) {
1396: $seclist.='<input type="hidden" name="chosensections"
1397: value="'.$sec.'" />';
1398: }
1.156 albertel 1399: if ($can_view && ($end_time ne '' && time > $end_time)) {
1.35 albertel 1400: $result.=(<<FORM);
1.103 albertel 1401: <td>$status</td>
1.32 albertel 1402: <td>
1.115 albertel 1403: <form style="display: inline" method="post">
1.32 albertel 1404: <input type="hidden" name="gradingkey" value="$ekey" />
1405: <input type="hidden" name="queue" value="$queue" />
1406: <input type="hidden" name="gradingaction" value="$action" />
1407: <input type="hidden" name="webgrade" value="no" />
1.33 albertel 1408: <input type="hidden" name="queuemode" value="selected" />
1.32 albertel 1409: <input type="submit" name="submit" value="$description" />
1.62 albertel 1410: $seclist
1.32 albertel 1411: </form>
1412: </td>
1413: FORM
1.156 albertel 1414: } elsif (!$can_view && ($end_time ne '' && time > $end_time)) {
1415: $result.='<td>'.&mt("Not gradable").'</td><td> </td>'
1.35 albertel 1416: } else {
1.148 albertel 1417: $result.='<td>'.&mt("In Progress").'</td><td> </td>'
1.35 albertel 1418: }
1.32 albertel 1419: }
1.156 albertel 1420: $result.= "<td>".$classlist->{$uname.':'.$udom}[&Apache::loncoursedata::CL_FULLNAME()].
1.138 albertel 1421: " <tt>($uname:$udom)</tt> </td>";
1.148 albertel 1422: $result.='<td>'.$slot_text.' End time: '.
1423: &Apache::lonlocal::locallocaltime($end_time).
1.159 albertel 1424: "</td>".&Apache::loncommon::end_data_table_row();
1.16 albertel 1425: }
1.14 albertel 1426: }
1.159 albertel 1427: $result.= &Apache::loncommon::end_data_table()."<hr />\n";
1.14 albertel 1428: return $result;
1429: }
1430:
1.34 albertel 1431: sub get_queue_counts {
1432: my ($queue)=@_;
1433: my $result;
1434: my ($symb,$cid,$udom,$uname)=&Apache::lonxml::whichuser();
1435: my $cnum=$env{'course.'.$cid.'.num'};
1436: my $cdom=$env{'course.'.$cid.'.domain'};
1.156 albertel 1437:
1.157 albertel 1438: my $classlist=&get_limited_classlist();
1.156 albertel 1439:
1.34 albertel 1440: my $regexp="^$symb\0";
1441: my %queue=&Apache::lonnet::dump($queue,$cdom,$cnum,$regexp);
1442: my ($tmp)=%queue;
1443: if ($tmp=~/^error: 2 /) {
1444: return (0,0,0);
1445: }
1446: my ($entries,$ready_to_grade,$locks)=(0,0,0);
1.96 albertel 1447: my %slot_cache;
1.34 albertel 1448: foreach my $key (sort(keys(%queue))) {
1.156 albertel 1449: my ($symb,$uname,$udom) = &decode_queue_key($key);
1450: if (!defined($classlist->{$uname.':'.$udom})) { next; }
1451:
1.34 albertel 1452: if ($key=~/locked$/) {
1453: $locks++;
1454: } elsif ($key=~/timestamp$/) {
1455: #ignore
1456: } elsif ($key!~/(timestamp|locked)$/) {
1457: $entries++;
1.148 albertel 1458: if (my $slot=&slotted_access($queue{$key})) {
1459: if (!exists($slot_cache{$slot})) {
1460: my %slot_data=&Apache::lonnet::get_slot($slot);
1461: $slot_cache{$slot} = \%slot_data;
1462: }
1463: if (time > $slot_cache{$slot}{'endtime'}) {
1464: $ready_to_grade++;
1465: }
1466: } else {
1467: my $due_date = &Apache::lonhomework::due_date('0',$symb);
1468: if ($due_date ne '' && time > $due_date) {
1469: $ready_to_grade++;
1470: }
1.34 albertel 1471: }
1472: }
1473: }
1474: return ($entries,$ready_to_grade,$locks);
1475: }
1476:
1.49 albertel 1477: sub encode_queue_key {
1478: my ($symb,$udom,$uname)=@_;
1.138 albertel 1479: return "$symb\0queue\0$uname:$udom";
1.49 albertel 1480: }
1481:
1.14 albertel 1482: sub decode_queue_key {
1483: my ($key)=@_;
1484: my ($symb,undef,$user) = split("\0",$key);
1.138 albertel 1485: my ($uname,$udom) = split(':',$user);
1.14 albertel 1486: return ($symb,$uname,$udom);
1487: }
1488:
1489: sub queue_key_locked {
1.30 albertel 1490: my ($queue,$key,$cdom,$cnum)=@_;
1.33 albertel 1491: if (!defined($cdom) || !defined($cnum)) {
1492: my (undef,$cid)=&Apache::lonxml::whichuser();
1493: $cnum=$env{'course.'.$cid.'.num'};
1494: $cdom=$env{'course.'.$cid.'.domain'};
1495: }
1.14 albertel 1496: my ($key_locked,$value)=
1.30 albertel 1497: &Apache::lonnet::get($queue,["$key\0locked"],$cdom,$cnum);
1.14 albertel 1498: if ($key_locked eq "$key\0locked") {
1499: return $value;
1500: }
1501: return undef;
1502: }
1503:
1.148 albertel 1504: sub slotted_access {
1505: my ($queue_entry) = @_;
1506: if (ref($queue_entry) eq 'ARRAY') {
1507: if (defined($queue_entry->[0])) {
1508: return $queue_entry->[0];
1509: }
1510: return undef;
1511: } elsif (ref($queue_entry) eq 'HASH') {
1512: if (defined($queue_entry->{'slot'})) {
1513: return $queue_entry->{'slot'};
1514: }
1515: return undef;
1516: }
1517: return undef;
1518: }
1519:
1.14 albertel 1520: sub pick_from_queue_data {
1.156 albertel 1521: my ($queue,$check_section,$queuedata,$cdom,$cnum,$classlist)=@_;
1.98 albertel 1522: my @possible; # will hold queue entries that are valid to be selected
1.30 albertel 1523: foreach my $key (keys(%$queuedata)) {
1.68 albertel 1524: if ($key =~ /\0locked$/) { next; }
1525: if ($key =~ /\0timestamp$/) { next; }
1.156 albertel 1526:
1.14 albertel 1527: my ($symb,$uname,$udom)=&decode_queue_key($key);
1.156 albertel 1528: if (!defined($classlist->{$uname.':'.$udom})) { next; }
1529:
1.14 albertel 1530: if ($check_section) {
1.156 albertel 1531: my $section =
1532: $classlist->{$uname.':'.$udom}[&Apache::loncoursedata::CL_SECTION()];
1.17 albertel 1533: if ($section eq $check_section) {
1.33 albertel 1534: &Apache::lonxml::debug("my sec");
1.15 albertel 1535: next;
1536: }
1.14 albertel 1537: }
1.148 albertel 1538: my $end_time;
1539: if (my $slot=&slotted_access($queuedata->{$key})) {
1.154 albertel 1540: &Apache::lonxml::debug("looking at slot $slot");
1.148 albertel 1541: my %slot_data=&Apache::lonnet::get_slot($slot);
1542: if ($slot_data{'endtime'} < time) {
1543: $end_time = $slot_data{'endtime'};
1.154 albertel 1544: } else {
1545: &Apache::lonxml::debug("not time ".$slot_data{'endtime'});
1546: next;
1.148 albertel 1547: }
1548: } else {
1549: my $due_date = &Apache::lonhomework::due_date('0',$symb);
1.154 albertel 1550: if ($due_date < time) {
1.148 albertel 1551: $end_time = $due_date;
1.154 albertel 1552: } else {
1553: &Apache::lonxml::debug("not time $due_date");
1554: next;
1.148 albertel 1555: }
1556: }
1557:
1.98 albertel 1558: if (exists($queuedata->{"$key\0locked"})) {
1.33 albertel 1559: &Apache::lonxml::debug("someone already has um.");
1.15 albertel 1560: next;
1561: }
1.148 albertel 1562: push(@possible,[$key,$end_time]);
1.98 albertel 1563: }
1564: if (@possible) {
1565: # sort entries in order by slot end time
1566: @possible = sort { $a->[1] <=> $b->[1] } @possible;
1.137 albertel 1567: # pick one of the entries in the top 10% in small queues and one
1568: # of the first ten entries in large queues
1.139 albertel 1569: #my $ten_percent = int($#possible * 0.1);
1570: #if ($ten_percent < 1 ) { $ten_percent = 1; }
1571: #if ($ten_percent > 10) { $ten_percent = 10; }
1572: #my $max=($#possible < $ten_percent) ? $#possible : $ten_percent;
1.137 albertel 1573:
1.139 albertel 1574: #return $possible[int(rand($max))][0];
1575: return $possible[0][0];
1.14 albertel 1576: }
1577: return undef;
1578: }
1579:
1.15 albertel 1580: sub find_mid_grade {
1.30 albertel 1581: my ($queue,$symb,$cdom,$cnum)=@_;
1.158 www 1582: my $todo=&unescape($env{'form.gradingkey'});
1.138 albertel 1583: my $me=$env{'user.name'}.':'.$env{'user.domain'};
1.15 albertel 1584: if ($todo) {
1.30 albertel 1585: my $who=&queue_key_locked($queue,$todo,$cdom,$cnum);
1.15 albertel 1586: if ($who eq $me) { return $todo; }
1587: }
1588: my $regexp="^$symb\0.*\0locked\$";
1.30 albertel 1589: my %locks=&Apache::lonnet::dump($queue,$cdom,$cnum,$regexp);
1.15 albertel 1590: foreach my $key (keys(%locks)) {
1591: my $who=$locks{$key};
1592: if ($who eq $me) {
1593: $todo=$key;
1594: $todo=~s/\0locked$//;
1595: return $todo;
1596: }
1597: }
1598: return undef;
1599: }
1600:
1.32 albertel 1601: sub lock_key {
1602: my ($queue,$todo)=@_;
1.138 albertel 1603: my $me=$env{'user.name'}.':'.$env{'user.domain'};
1.32 albertel 1604: my (undef,$cid)=&Apache::lonxml::whichuser();
1605: my $cnum=$env{'course.'.$cid.'.num'};
1606: my $cdom=$env{'course.'.$cid.'.domain'};
1607: my $success=&Apache::lonnet::newput($queue,{"$todo\0locked"=> $me},
1608: $cdom,$cnum);
1.33 albertel 1609: &Apache::lonxml::debug("success $success $todo");
1.32 albertel 1610: if ($success eq 'ok') {
1611: return 1;
1612: }
1613: return 0;
1614: }
1615:
1.86 albertel 1616: sub get_queue_symb_status {
1.85 albertel 1617: my ($queue,$symb,$cdom,$cnum) = @_;
1618: if (!defined($cdom) || !defined($cnum)) {
1619: my (undef,$cid)=&Apache::lonxml::whichuser();
1620: $cnum=$env{'course.'.$cid.'.num'};
1621: $cdom=$env{'course.'.$cid.'.domain'};
1622: }
1.157 albertel 1623: my $classlist=&get_limited_classlist();
1.156 albertel 1624:
1.85 albertel 1625: my $regexp="^$symb\0";
1626: my %queue=&Apache::lonnet::dump($queue,$cdom,$cnum,$regexp);
1627: my ($tmp)=%queue;
1628: if ($tmp=~/^error: 2 /) { return; }
1629: my @users;
1630: foreach my $key (sort(keys(%queue))) {
1631: next if ($key=~/locked$/);
1632: next if ($key=~/timestamp$/);
1633: my ($symb,$uname,$udom) = &decode_queue_key($key);
1.156 albertel 1634: next if (!defined($classlist->{$uname.':'.$udom}));
1.85 albertel 1635: push(@users,"$uname:$udom");
1636: }
1637: return @users;
1638: }
1639:
1.14 albertel 1640: sub get_from_queue {
1.30 albertel 1641: my ($queue)=@_;
1.14 albertel 1642: my $result;
1643: my ($symb,$cid,$udom,$uname)=&Apache::lonxml::whichuser();
1644: my $cnum=$env{'course.'.$cid.'.num'};
1645: my $cdom=$env{'course.'.$cid.'.domain'};
1.32 albertel 1646: my $todo=&find_mid_grade($queue,$symb,$cdom,$cnum);
1.33 albertel 1647: &Apache::lonxml::debug("found ".join(':',&decode_queue_key($todo)));
1.16 albertel 1648: if ($todo) { return $todo; }
1.95 albertel 1649: my $attempts=0;
1.156 albertel 1650:
1.157 albertel 1651: my $classlist=&get_limited_classlist();
1.156 albertel 1652:
1.14 albertel 1653: while (1) {
1.95 albertel 1654: if ($attempts > 2) {
1655: # tried twice to get a queue entry, giving up
1656: return (undef,'unable');
1657: }
1.14 albertel 1658: my $starttime=time;
1.83 albertel 1659: &Apache::lonnet::cput($queue,{"$symb\0timestamp"=>$starttime},
1660: $cdom,$cnum);
1.33 albertel 1661: &Apache::lonxml::debug("$starttime");
1.14 albertel 1662: my $regexp="^$symb\0queue\0";
1.156 albertel 1663: #my $range= ($attempts < 1 ) ? '0-100' : '0-400';
1.97 albertel 1664:
1.98 albertel 1665: my %queue=&Apache::lonnet::dump($queue,$cdom,$cnum,$regexp);
1.33 albertel 1666: #make a pass looking for a user _not_ in my section
1.14 albertel 1667: if ($env{'request.course.sec'}) {
1.33 albertel 1668: &Apache::lonxml::debug("sce");
1.30 albertel 1669: $todo=&pick_from_queue_data($queue,$env{'request.course.sec'},
1.156 albertel 1670: \%queue,$cdom,$cnum,$classlist);
1.33 albertel 1671: &Apache::lonxml::debug("sce $todo");
1.14 albertel 1672: }
1.33 albertel 1673: # no one _not_ in our section so look for any user that is
1674: # ready for grading
1.14 albertel 1675: if (!$todo) {
1.33 albertel 1676: &Apache::lonxml::debug("no sce");
1.156 albertel 1677: $todo=&pick_from_queue_data($queue,undef,\%queue,$cdom,$cnum,
1678: $classlist);
1.33 albertel 1679: &Apache::lonxml::debug("no sce $todo");
1.14 albertel 1680: }
1681: # no user to grade
1682: if (!$todo) { last; }
1.33 albertel 1683: &Apache::lonxml::debug("got $todo");
1.14 albertel 1684: # otherwise found someone so lets try to lock them
1.32 albertel 1685: # unless someone else already picked them
1.95 albertel 1686: if (!&lock_key($queue,$todo)) {
1687: $attempts++;
1688: next;
1689: }
1.14 albertel 1690: my (undef,$endtime)=
1.30 albertel 1691: &Apache::lonnet::get($queue,["$symb\0timestamp"],
1.14 albertel 1692: $cdom,$cnum);
1.33 albertel 1693: &Apache::lonxml::debug("emd $endtime");
1.14 albertel 1694: # someone else already modified the queue,
1695: # perhaps our picked user wass already fully graded between
1696: # when we picked him and when we locked his record? so lets
1697: # double check.
1698: if ($endtime != $starttime) {
1699: my ($key,$value)=
1.30 albertel 1700: &Apache::lonnet::get($queue,["$todo"],
1.14 albertel 1701: $cdom,$cnum);
1.33 albertel 1702: &Apache::lonxml::debug("check $key .. $value");
1.14 albertel 1703: if ($key eq $todo && ref($value)) {
1704: } else {
1.30 albertel 1705: &Apache::lonnet::del($queue,["$todo\0locked"],
1.14 albertel 1706: $cdom,$cnum);
1.33 albertel 1707: &Apache::lonxml::debug("del");
1.95 albertel 1708: $attempts++;
1.14 albertel 1709: next;
1710: }
1711: }
1.33 albertel 1712: &Apache::lonxml::debug("last $todo");
1.14 albertel 1713: last;
1714: }
1715: return $todo;
1716: }
1717:
1.49 albertel 1718: sub select_user {
1719: my ($symb,$cid)=&Apache::lonxml::whichuser();
1720:
1.59 albertel 1721: my @chosen_sections=
1722: &Apache::loncommon::get_env_multiple('form.chosensections');
1.156 albertel 1723:
1724: my $classlist = &get_limited_classlist(\@chosen_sections);
1.63 albertel 1725:
1726: my $result;
1727: if (!(grep(/^all$/,@chosen_sections))) {
1728: $result.='<p> Showing only sections <tt>'.join(', ',@chosen_sections).
1729: '</tt>.</p> '."\n";
1730: }
1.159 albertel 1731: $result.=&Apache::loncommon::start_data_table();
1.49 albertel 1732:
1.156 albertel 1733: foreach my $student (sort {lc($classlist->{$a}[&Apache::loncoursedata::CL_FULLNAME()]) cmp lc($classlist->{$b}[&Apache::loncoursedata::CL_FULLNAME()]) } (keys(%$classlist))) {
1.49 albertel 1734: my ($uname,$udom) = split(/:/,$student);
1.59 albertel 1735:
1.84 albertel 1736: my $cnum=$env{'course.'.$cid.'.num'};
1737: my $cdom=$env{'course.'.$cid.'.domain'};
1.88 albertel 1738: my %status = &get_student_status($symb,$cdom,$cnum,$udom,$uname,
1739: 'Task');
1.49 albertel 1740: my $queue = 'none';
1.58 albertel 1741: my $cannot_grade;
1742: if ($status{'reviewqueue'} =~ /^(in_progress|enqueue)$/) {
1.49 albertel 1743: $queue = 'reviewqueue';
1.58 albertel 1744: if ($status{'reviewqueue'} eq 'in_progress') {
1745: $cannot_grade=1;
1746: }
1747: } elsif ($status{'gradingqueue'} =~ /^(in_progress|enqueue)$/) {
1.49 albertel 1748: $queue = 'gradingqueue';
1.58 albertel 1749: if ($status{'gradingqueue'} eq 'in_progress') {
1750: $cannot_grade=1;
1751: }
1.49 albertel 1752: }
1753: my $todo =
1.158 www 1754: &escape(&encode_queue_key($symb,$udom,$uname));
1.58 albertel 1755: if ($cannot_grade) {
1.159 albertel 1756: $result.=&Apache::loncommon::start_data_table_row().
1757: '<td> </td><td>'.$classlist->{$student}[&Apache::loncoursedata::CL_FULLNAME()].
1.58 albertel 1758: '</td><td>';
1759: } else {
1.62 albertel 1760: my $seclist;
1761: foreach my $sec (@chosen_sections) {
1762: $seclist.='<input type="hidden" name="chosensections"
1763: value="'.$sec.'" />';
1764: }
1.159 albertel 1765: $result.=&Apache::loncommon::start_data_table_row();
1.58 albertel 1766: $result.=<<RESULT;
1.49 albertel 1767: <td>
1.115 albertel 1768: <form style="display: inline" method="post">
1.49 albertel 1769: <input type="hidden" name="gradingkey" value="$todo" />
1770: <input type="hidden" name="queue" value="$queue" />
1771: <input type="hidden" name="webgrade" value="no" />
1.52 albertel 1772: <input type="hidden" name="regrade" value="yes" />
1.62 albertel 1773: <input type="submit" name="submit" value="Regrade" />
1774: $seclist
1.49 albertel 1775: </form>
1.155 albertel 1776: <td>$classlist->{$student}[&Apache::loncoursedata::CL_FULLNAME()] <tt>($student)</tt></td>
1.49 albertel 1777: <td>
1778: RESULT
1.58 albertel 1779: }
1.49 albertel 1780: if ($status{'status'} eq 'pass') {
1781: $result .= '<font color="green">'.&mt('Passed').'</font>';
1782: } elsif ($status{'status'} eq 'fail') {
1783: $result .= '<font color="red">'.&mt('Failed').'</font>';
1784: } elsif ($status{'status'} eq 'review') {
1785: $result .= '<font color="blue">'.&mt('Under Review').'</font>';
1786: } elsif ($status{'status'} eq 'ungraded') {
1787: $result .= &mt('Ungraded');
1788: } elsif ($status{'status'} ne '') {
1789: $result .= '<font color="orange">'.&mt('Unknown Status').'</font>';
1790: } else {
1791: $result.=" ";
1792: }
1793: if ($status{'version'}) {
1794: $result .= ' '.&mt('Version').' '.$status{'version'};
1795: }
1.101 albertel 1796: if ($status{'grader'}) {
1797: $result .= ' '.&mt('(Graded by [_1])',$status{'grader'}).' ';
1798: }
1.49 albertel 1799: $result.= '</td><td>';
1800: if ($status{'reviewqueue'} eq 'enqueued') {
1801: $result .= &mt('Awaiting Review');
1802: } elsif ($status{'reviewqueue'} eq 'locked') {
1803: $result .= &mt('Under Review');
1.58 albertel 1804: } elsif ($status{'reviewqueue'} eq 'in_progress') {
1805: $result .= &mt('Still being worked on.');
1.49 albertel 1806: } elsif ($status{'gradingqueue'} eq 'enqueued') {
1807: $result .= &mt('Awaiting Grading');
1808: } elsif ($status{'gradingqueue'} eq 'locked') {
1809: $result .= &mt('Being Graded');
1.58 albertel 1810: } elsif ($status{'gradingqueue'} eq 'in_progress') {
1811: $result .= &mt('Still being worked on.');
1.49 albertel 1812: } else {
1813: $result.=" ";
1814: }
1.159 albertel 1815: $result.= '</td>'.&Apache::loncommon::end_data_table_row();
1.49 albertel 1816: }
1.159 albertel 1817: $result.=&Apache::loncommon::end_data_table();
1.49 albertel 1818: return $result;
1819: }
1820:
1821: sub get_student_status {
1.86 albertel 1822: my ($symb,$cdom,$cnum,$udom,$uname,$type)=@_;
1823:
1824: my %status;
1825:
1826: if ($type eq 'Task') {
1827: my %record = &Apache::lonnet::restore($symb,$env{'request.course.id'},
1.49 albertel 1828: $udom,$uname);
1.89 albertel 1829: $status{'status'}=$record{'resource.0.status'};
1830: $status{'version'}=$record{'resource.0.version'};
1831: $status{'grader'}=$record{'resource.0.regrader'};
1.86 albertel 1832: }
1833: $status{'reviewqueue'}=
1834: &check_queue_for_key($cdom,$cnum,'reviewqueue',
1835: &encode_queue_key($symb,$udom,$uname));
1836: $status{'gradingqueue'}=
1837: &check_queue_for_key($cdom,$cnum,'gradingqueue',
1838: &encode_queue_key($symb,$udom,$uname));
1.49 albertel 1839: return %status;
1840: }
1841:
1.1 albertel 1842: sub start_ClosingParagraph {
1843: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
1844: my $result;
1845: if ($target eq 'web') {
1.13 albertel 1846: } elsif ($target eq 'webgrade') {
1847: &Apache::lonxml::startredirection();
1.1 albertel 1848: }
1849: return $result;
1850: }
1851:
1852: sub end_ClosingParagraph {
1853: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
1854: my $result;
1855: if ($target eq 'web') {
1.13 albertel 1856: } elsif ($target eq 'webgrade') {
1857: &Apache::lonxml::endredirection();
1.1 albertel 1858: }
1859: return $result;
1860: }
1861:
1.19 albertel 1862: sub get_id {
1863: my ($parstack,$safeeval)=@_;
1864: my $id=&Apache::lonxml::get_param('id',$parstack,$safeeval);
1865: if (!$id) { $id=$Apache::lonxml::curdepth; }
1866: return $id;
1867: }
1868:
1.1 albertel 1869: my %dimension;
1.162 albertel 1870: sub start_Setup {
1871: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
1872: undef(%dimension);
1873: my $dim_id=&get_id($parstack,$safeeval);
1874: $Apache::bridgetask::dimension=$dim_id;
1875: undef(@Apache::bridgetask::instance);
1876: &Apache::lonxml::startredirection();
1877: return &internal_location($dim_id);
1878: }
1.151 albertel 1879: sub start_Question { return &start_Dimension(@_); }
1.1 albertel 1880: sub start_Dimension {
1881: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
1882: undef(%dimension);
1.19 albertel 1883: my $dim_id=&get_id($parstack,$safeeval);
1.9 albertel 1884: $Apache::bridgetask::dimension=$dim_id;
1885: push(@Apache::bridgetask::dimensionlist,$dim_id);
1886: undef(@Apache::bridgetask::instance);
1.20 albertel 1887: $Apache::bridgetask::dimensionmandatory{$dim_id}=
1888: &Apache::lonxml::get_param('Mandatory',$parstack,$safeeval);
1.54 albertel 1889: &Apache::lonxml::startredirection();
1890: return &internal_location($dim_id);
1.1 albertel 1891: }
1892:
1.160 albertel 1893: sub start_QuestionText {
1894: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1895: my $dim_id=$Apache::bridgetask::dimension;
1896: my $text=&Apache::lonxml::get_all_text('/questiontext',$parser,$style);
1897: if ($target eq 'grade' || $target eq 'web' || $target eq 'webgrade') {
1898: $dimension{'questiontext'}=$text;
1899: }
1900: return '';
1901: }
1902:
1903: sub end_QuestionText {
1904: return '';
1905: }
1906:
1.13 albertel 1907: sub get_instance {
1.75 albertel 1908: my ($dim)=@_;
1909: my $rand_alg=&Apache::lonnet::get_rand_alg();
1910: if (!$rand_alg || $rand_alg eq '32bit' || $rand_alg eq '64bit' ||
1911: $rand_alg eq '64bit2' || $rand_alg eq '64bit3' ||
1912: $rand_alg eq '64bit4' ) {
1913: &Apache::response::pushrandomnumber();
1914: my @order=&Math::Random::random_permutation(@{$dimension{'instances'}});
1915: my $num=@order;
1916: my $version=&get_version();
1917: my $which=($version-1)%$num;
1918: return $order[$which];
1919: } else {
1920: my ($version,$previous) = &get_version();
1921: my $instance =
1922: $Apache::lonhomework::history{"resource.$version.0.$dim.instance"};
1923: if (defined($instance)) { return $instance; }
1924:
1925: &Apache::response::pushrandomnumber();
1926: my @instances = @{$dimension{'instances'}};
1927: # remove disabled instances
1928: for (my $i=0; $i < $#instances; $i++) {
1929: if ($dimension{$instances[$i].'.disabled'}) {
1930: splice(@instances,$i,1);
1931: $i--;
1932: }
1933: }
1934: @instances = &Math::Random::random_permutation(@instances);
1935: $instance = $instances[($version-1)%scalar(@instances)];
1.150 albertel 1936: if ($version =~ /^\d$/) {
1937: $Apache::lonhomework::results{"resource.$version.0.$dim.instance"} =
1938: $instance;
1939: $Apache::lonhomework::results{'INTERNAL_store'} = 1;
1940: }
1.75 albertel 1941: &Apache::response::poprandomnumber();
1942: return $instance;
1943: }
1.13 albertel 1944: }
1945:
1.18 albertel 1946: {
1947: my $last_link;
1.122 albertel 1948: sub link {
1.151 albertel 1949: my ($id) = @_;
1950: $id =~ s/\./_/g;
1951: return 'LC_GRADING_criteria_'.$id;
1.122 albertel 1952: }
1.151 albertel 1953: sub end_Question { return &end_Dimension(@_); }
1.18 albertel 1954: sub end_Dimension {
1955: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
1.54 albertel 1956: my $result=&Apache::lonxml::endredirection();
1.25 albertel 1957: my $dim=&get_id($parstack,$safeeval);
1.75 albertel 1958: my $instance=&get_instance($dim);
1.25 albertel 1959: my $version=&get_version();
1.18 albertel 1960: if ($target eq 'web') {
1.47 albertel 1961: @Apache::scripttag::parser_env = @_;
1962: $result.=&Apache::scripttag::xmlparse($dimension{'intro'});
1.76 albertel 1963: my @instances = $instance;
1964: if (&Apache::response::showallfoils()) {
1965: @instances = @{$dimension{'instances'}};
1966: }
1.160 albertel 1967: my $shown_question_text;
1.76 albertel 1968: foreach my $instance (@instances) {
1969: @Apache::scripttag::parser_env = @_;
1970: $result.=&Apache::scripttag::xmlparse($dimension{$instance.'.text'});
1.160 albertel 1971: @Apache::scripttag::parser_env = @_;
1972: $result.=&Apache::scripttag::xmlparse($dimension{'questiontext'});
1.89 albertel 1973: if ($Apache::lonhomework::history{"resource.$version.0.status"} eq 'pass' ||
1974: $Apache::lonhomework::history{"resource.$version.0.status"} eq 'fail') {
1.76 albertel 1975:
1.89 albertel 1976: my $dim_status=$Apache::lonhomework::history{"resource.$version.0.$dim.status"};
1.76 albertel 1977: my $mandatory='Mandatory';
1978: if ($Apache::bridgetask::dimensionmandatory{$dim} eq 'N') {
1979: $mandatory='Optional';
1980: }
1.116 albertel 1981: my $dim_info="<div class='LC_$dim_status LC_question_grade'>\n";
1.76 albertel 1982: if ($dim_status eq 'pass') {
1983: $dim_info.='<h3>Question : you passed this '.$mandatory.' question</h3>';
1.54 albertel 1984: }
1.76 albertel 1985: if ($dim_status eq 'fail') {
1986: $dim_info.='<h3>Question : you did not pass this '.$mandatory.' question</h3>';
1.53 albertel 1987: }
1.76 albertel 1988: my $man_count=0;
1989: my $man_passed=0;
1990: my $opt_count=0;
1991: my $opt_passed=0;
1.151 albertel 1992: foreach my $id ( @{$dimension{$instance.'.criterias'}},
1993: @{$dimension{'criterias'}} ) {
1994: if ($dimension{'criteria.'.$id.'.mandatory'}
1.76 albertel 1995: eq 'N') {
1996: $opt_count++;
1.151 albertel 1997: if ($Apache::lonhomework::history{"resource.$version.0.$dim.$id.status"} eq 'pass') {
1.76 albertel 1998: $opt_passed++;
1999: }
2000: } else {
2001: $man_count++;
1.89 albertel 2002: if ($Apache::lonhomework::history{"resource.$version.0.$dim.$instance.$id.status"} eq 'pass') {
1.76 albertel 2003: $man_passed++;
2004: }
2005: }
1.22 albertel 2006: }
1.76 albertel 2007: if ($man_passed eq $man_count) { $man_passed='all'; }
1.151 albertel 2008:
1.76 albertel 2009: my $opt_req=$dimension{$instance.'.optionalrequired'};
1.151 albertel 2010: if ($opt_req !~ /\S/) {
2011: $opt_req=
2012: &Apache::lonxml::get_param('OptionalRequired',
2013: $parstack,$safeeval);
2014: if ($opt_req !~ /\S/) { $opt_req = 0; }
2015: }
1.76 albertel 2016: $dim_info.="\n<p>".&mt('You passed [_1] of the [_2] mandatory components and [_3] of the [_4] optional components, of which you were required to pass [_5].',$man_passed,$man_count,$opt_passed,$opt_count,$opt_req)."</p>\n</div>";
2017:
2018: my $internal_location=&internal_location($dim);
2019: $result=~s/\Q$internal_location\E/$dim_info/;
2020:
1.151 albertel 2021: foreach my $id (@{$dimension{$instance.'.criterias'}},
2022: @{$dimension{'criterias'}}) {
2023: my $status=$Apache::lonhomework::history{"resource.$version.0.$dim.$id.status"};
2024: my $comment=$Apache::lonhomework::history{"resource.$version.0.$dim.$id.comment"};
2025: my $mandatory=($dimension{'criteria.'.$id.'.mandatory'} ne 'N');
1.76 albertel 2026: if ($mandatory) {
2027: $mandatory='Mandatory';
2028: } else {
2029: $mandatory='Optional';
2030: }
2031: if ($status eq 'fail') {
2032: } elsif ($status eq 'pass') {
2033: } else {
2034: &Apache::lonxml::error("Student viewing a graded bridgetask was shown a status of $status");
2035: }
2036: my $status_display=$status;
2037: $status_display=~s/^([a-z])/uc($1)/e;
1.116 albertel 2038: $result.=
2039: '<div class="LC_'.$status.' LC_criteria"><h4>'
2040: .$mandatory.' Criteria</h4><p>';
1.76 albertel 2041: @Apache::scripttag::parser_env = @_;
1.151 albertel 2042: $result.=&Apache::scripttag::xmlparse($dimension{'criteria.'.$id});
1.116 albertel 2043: $result.='</p><p class="LC_grade">'.$status_display.'</p>';
1.151 albertel 2044: if ($Apache::lonhomework::history{"resource.$version.0.$dim.$id.comment"}) {
2045: $result.='<p class="LC_comment">'.&mt('Comment: [_1]',$Apache::lonhomework::history{"resource.$version.0.$dim.$id.comment"}).'</p>';
1.76 albertel 2046: }
2047: $result.='</div>';
1.22 albertel 2048: }
2049: }
2050: }
1.18 albertel 2051: } elsif ($target eq 'webgrade') {
1.47 albertel 2052: # in case of any side effects that we need
2053: @Apache::scripttag::parser_env = @_;
2054: &Apache::scripttag::xmlparse($dimension{'intro'});
2055: @Apache::scripttag::parser_env = @_;
2056: &Apache::scripttag::xmlparse($dimension{$instance.'.text'});
1.160 albertel 2057: @Apache::scripttag::parser_env = @_;
2058: &Apache::scripttag::xmlparse($dimension{'questiontext'});
1.151 albertel 2059: foreach my $id (@{$dimension{$instance.'.criterias'}},
2060: @{$dimension{'criterias'}} ) {
2061: my $link=&link($id);
2062: my $status=$Apache::lonhomework::history{"resource.$version.0.$dim.$id.status"};
1.120 albertel 2063: $result.='<div class="LC_GRADING_criteria" id="'.$link.'">'."\n".
1.136 albertel 2064: '<div class="LC_GRADING_criteriatext" id="next_'.$last_link.'">'."\n";
1.47 albertel 2065: @Apache::scripttag::parser_env = @_;
1.151 albertel 2066: $result.=&Apache::scripttag::xmlparse($dimension{'criteria.'.$id});
1.111 albertel 2067: $result.='</div>'."\n".
1.151 albertel 2068: #$dimension{'criteria.'.$id}.
1.120 albertel 2069: '<div class="LC_GRADING_grade">'."\n".
2070: '<label class="LC_GRADING_ungraded"><input type="radio" name="HWVAL_'.$link.'" value="ungraded" '.($status eq 'ungraded' || !$status ? 'checked="checked"':'').' />'.&mt('Ungraded').'</label>'."\n".
2071: '<label class="LC_GRADING_fail"><input type="radio" name="HWVAL_'.$link.'" value="fail" '.($status eq 'fail' ? 'checked="checked"':'').' />'.&mt('Fail').'</label>'."\n".
2072: '<label class="LC_GRADING_pass"><input type="radio" name="HWVAL_'.$link.'" value="pass" '.($status eq 'pass' ? 'checked="checked"':'').' />'.&mt('Pass').'</label>'."\n".
2073: '<label class="LC_GRADING_review"><input type="radio" name="HWVAL_'.$link.'" value="review" '.($status eq 'review' ? 'checked="checked"':'').' />'.&mt('Review').'</label>'."\n".
1.111 albertel 2074: '</div>'."\n".
1.120 albertel 2075: '<label class="LC_GRADING_comment">'.&mt('Additional Comment for Student')."\n".
1.151 albertel 2076: '<textarea class="LC_GRADING_comment_area" name="HWVAL_comment_'.$link.'">'.&HTML::Entities::encode($Apache::lonhomework::history{"resource.$version.0.$dim.$id.comment"}).'</textarea>'."\n".
1.111 albertel 2077: '</label>'."\n".
1.120 albertel 2078: '<ul class="LC_GRADING_navbuttons">'."\n".
1.111 albertel 2079: '<li><a href="#'.$last_link.'">Prev</a></li>'."\n".
2080: '<li><a href="#next_'.$link.'">Next</a></li>'."\n".
2081: '</ul>'."\n".
2082: '</div>'."\n";
1.151 albertel 2083: $result.=&grading_history($version,$dim,$id);
1.18 albertel 2084: $last_link=$link;
2085: }
1.22 albertel 2086: } elsif ($target eq 'grade' && $env{'form.webgrade'}) {
1.19 albertel 2087: my $optional_passed=0;
1.20 albertel 2088: my $mandatory_failed=0;
2089: my $ungraded=0;
2090: my $review=0;
1.153 albertel 2091:
2092: @Apache::scripttag::parser_env = @_;
2093: $result.=&Apache::scripttag::xmlparse($dimension{'intro'});
1.160 albertel 2094: @Apache::scripttag::parser_env = @_;
2095: $result.=&Apache::scripttag::xmlparse($dimension{$instance.'.text'});
2096: @Apache::scripttag::parser_env = @_;
2097: &Apache::scripttag::xmlparse($dimension{'questiontext'});
2098:
1.151 albertel 2099: foreach my $id (@{$dimension{$instance.'.criterias'}},
2100: @{$dimension{'criterias'}}) {
2101: my $link=&link($id);
2102: my $status=$Apache::lonhomework::results{"resource.$version.0.$dim.$id.status"}=$env{'form.HWVAL_'.$link};
2103: $Apache::lonhomework::results{"resource.$version.0.$dim.$id.comment"}=$env{'form.HWVAL_comment_'.$link};
2104: my $mandatory=($dimension{'criteria.'.$id.'.mandatory'} ne 'N');
1.20 albertel 2105: if ($status eq 'pass') {
2106: if (!$mandatory) { $optional_passed++; }
2107: } elsif ($status eq 'fail') {
2108: if ($mandatory) { $mandatory_failed++; }
1.21 albertel 2109: } elsif ($status eq 'review') {
2110: $review++;
1.20 albertel 2111: } elsif ($status eq 'ungraded') {
2112: $ungraded++;
1.21 albertel 2113: } else {
1.47 albertel 2114: $ungraded++;
1.19 albertel 2115: }
2116: }
1.151 albertel 2117: # FIXME optional required can apply to only <instance> right now...
2118: my $opt_req=$dimension{$instance.'.optionalrequired'};
2119: if ($opt_req !~ /\S/) {
2120: $opt_req=
2121: &Apache::lonxml::get_param('OptionalRequired',
2122: $parstack,$safeeval);
2123: if ($opt_req !~ /\S/) { $opt_req = 0; }
2124: }
2125: if ($optional_passed < $opt_req) {
1.20 albertel 2126: $mandatory_failed++;
2127: }
1.21 albertel 2128: &Apache::lonxml::debug("all instance ".join(':',@{$dimension{$instance.'.criterias'}})." results -> m_f $mandatory_failed o_p $optional_passed u $ungraded r $review");
1.20 albertel 2129: if ($review) {
1.89 albertel 2130: $Apache::lonhomework::results{"resource.$version.0.$dim.status"}=
1.22 albertel 2131: 'review';
1.20 albertel 2132: } elsif ($ungraded) {
1.89 albertel 2133: $Apache::lonhomework::results{"resource.$version.0.$dim.status"}=
1.22 albertel 2134: 'ungraded';
1.20 albertel 2135: } elsif ($mandatory_failed) {
1.89 albertel 2136: $Apache::lonhomework::results{"resource.$version.0.$dim.status"}=
1.22 albertel 2137: 'fail';
1.20 albertel 2138: } else {
1.91 albertel 2139: $Apache::lonhomework::results{"resource.$version.0.$dim.status"}=
1.22 albertel 2140: 'pass';
1.20 albertel 2141: }
1.69 albertel 2142: } else {
2143: # any other targets no output
2144: undef($result);
1.13 albertel 2145: }
1.18 albertel 2146: return $result;
1.1 albertel 2147: }
1.162 albertel 2148:
2149: sub end_Setup {
2150: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
2151: my $result=&Apache::lonxml::endredirection();
2152: my $dim=&get_id($parstack,$safeeval);
2153: my $instance=&get_instance($dim);
2154: my $version=&get_version();
2155: if ($target eq 'web') {
2156: @Apache::scripttag::parser_env = @_;
2157: $result.=&Apache::scripttag::xmlparse($dimension{'intro'});
2158: my @instances = $instance;
2159: if (&Apache::response::showallfoils()) {
2160: @instances = @{$dimension{'instances'}};
2161: }
2162: foreach my $instance (@instances) {
2163: @Apache::scripttag::parser_env = @_;
2164: $result.=&Apache::scripttag::xmlparse($dimension{$instance.'.text'});
2165: @Apache::scripttag::parser_env = @_;
2166: $result.=&Apache::scripttag::xmlparse($dimension{'questiontext'});
2167: }
2168: } elsif ($target eq 'webgrade'
2169: || $target eq 'grade' && $env{'form.webgrade'}) {
2170: # in case of any side effects that we need
2171: @Apache::scripttag::parser_env = @_;
2172: &Apache::scripttag::xmlparse($dimension{'intro'});
2173: @Apache::scripttag::parser_env = @_;
2174: &Apache::scripttag::xmlparse($dimension{$instance.'.text'});
2175: @Apache::scripttag::parser_env = @_;
2176: &Apache::scripttag::xmlparse($dimension{'questiontext'});
2177: } else {
2178: # any other targets no output
2179: undef($result);
2180: }
2181: return $result;
2182: }
1.1 albertel 2183: }
2184:
1.113 albertel 2185: sub grading_history {
1.151 albertel 2186: my ($version,$dim,$id) = @_;
1.113 albertel 2187: if (!&Apache::lonnet::allowed('mgq',$env{'request.course.id'})) {
2188: return '';
2189: }
2190: my ($result,$grader);
1.151 albertel 2191: my $scope="resource.$version.0.$dim.$id";
1.113 albertel 2192: foreach my $t (1..$Apache::lonhomework::history{'version'}) {
2193: if (exists($Apache::lonhomework::history{$t.':resource.0.regrader'})) {
2194: my ($gname,$gdom) =
1.138 albertel 2195: split(':',$Apache::lonhomework::history{$t.':resource.0.regrader'});
1.113 albertel 2196: my $fullname = &Apache::loncommon::plainname($gname,$gdom);
2197: $grader = &Apache::loncommon::aboutmewrapper($fullname,
2198: $gname,$gdom);
2199: }
2200: my $entry;
2201: if (exists($Apache::lonhomework::history{"$t:$scope.status"})) {
2202: $entry.="<tt>".$Apache::lonhomework::history{"$t:$scope.status"}.'</tt>';
2203: }
2204: if (exists($Apache::lonhomework::history{"$t:$scope.comment"})) {
2205: $entry.=' comment: "'.$Apache::lonhomework::history{"$t:$scope.comment"}.'"';
2206: }
2207: if ($entry) {
2208: $result.= "<li>$grader : $entry </li>";
2209: }
2210: }
2211: if ($result) {
1.120 albertel 2212: return '<ul class="LC_GRADING_pastgrading">'.$result.'</ul>';
1.113 albertel 2213: }
2214: return '';
2215: }
2216:
1.1 albertel 2217: sub start_IntroParagraph {
1.87 albertel 2218: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.1 albertel 2219: my $result;
1.153 albertel 2220: if ($target eq 'grade' || $target eq 'web' || $target eq 'webgrade') {
1.151 albertel 2221: if ($tagstack->[-2] eq 'Dimension' || $tagstack->[-2] eq 'Question' ) {
2222: $dimension{'intro'}=
2223: &Apache::lonxml::get_all_text('/introparagraph',
2224: $parser,$style);
2225: } elsif ($tagstack->[-2] eq 'Task' && $target eq 'webgrade') {
1.127 albertel 2226: &Apache::lonxml::startredirection();
1.1 albertel 2227: }
1.47 albertel 2228:
1.1 albertel 2229: }
2230: return $result;
2231: }
2232:
2233: sub end_IntroParagraph {
1.127 albertel 2234: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.128 albertel 2235: if ($tagstack->[-2] eq 'Task' && $target eq 'webgrade') {
1.127 albertel 2236: my $result = &Apache::lonxml::endredirection();
2237: }
1.1 albertel 2238: }
2239:
2240: sub start_Instance {
2241: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
1.19 albertel 2242: my $id=&get_id($parstack,$safeeval);
2243: push(@{$dimension{'instances'}},$id);
2244: push(@Apache::bridgetask::instance,$id);
2245: push(@Apache::bridgetask::instancelist,$id);
1.20 albertel 2246: $dimension{$id.'.optionalrequired'}=
1.19 albertel 2247: &Apache::lonxml::get_param('OptionalRequired',$parstack,$safeeval);
1.75 albertel 2248: my $disabled = &Apache::lonxml::get_param('Disabled',$parstack,$safeeval);
2249: if (lc($disabled) eq 'yes') {
2250: $dimension{$id.'.disabled'}='1';
2251: }
1.1 albertel 2252: return '';
2253: }
2254:
2255: sub end_Instance {
2256: }
2257:
2258: sub start_InstanceText {
1.87 albertel 2259: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.47 albertel 2260: my $instance_id=$Apache::bridgetask::instance[-1];
1.87 albertel 2261: my $text=&Apache::lonxml::get_all_text('/instancetext',$parser,$style);
1.153 albertel 2262: if ($target eq 'grade' || $target eq 'web' || $target eq 'webgrade') {
1.47 albertel 2263: $dimension{$instance_id.'.text'}=$text;
1.1 albertel 2264: }
2265: return '';
2266: }
2267:
2268: sub end_InstanceText {
2269: return '';
2270: }
2271:
2272: sub start_Criteria {
1.87 albertel 2273: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
2274: my $criteria=&Apache::lonxml::get_all_text('/criteria',$parser,$style);
1.21 albertel 2275: if ($target eq 'web' || $target eq 'webgrade' || $target eq 'grade') {
1.19 albertel 2276: my $id=&get_id($parstack,$safeeval);
1.151 albertel 2277: if (&Apache::londefdef::is_inside_of($tagstack,'Instance')) {
2278: my $instance_id=$Apache::bridgetask::instance[-1];
2279: $dimension{"criteria.$instance_id.$id"}=$criteria;
2280: $dimension{"criteria.$instance_id.$id.mandatory"}=
2281: &Apache::lonxml::get_param('Mandatory',$parstack,$safeeval);
2282: push(@{$dimension{$instance_id.'.criterias'}},"$instance_id.$id");
2283: } else {
2284: $dimension{'criteria.'.$id}=$criteria;
2285: $dimension{'criteria.'.$id.'.mandatory'}=
2286: &Apache::lonxml::get_param('Mandatory',$parstack,$safeeval);
2287: push(@{$dimension{'criterias'}},$id);
2288: }
1.1 albertel 2289: }
2290: return '';
2291: }
2292:
1.47 albertel 2293: sub end_Criteria {
2294: }
2295:
1.4 albertel 2296: sub proctor_validation_screen {
2297: my ($slot) = @_;
2298: my (undef,undef,$domain,$user) = &Apache::lonxml::whichuser();
1.5 albertel 2299: my $url=&Apache::lonnet::studentphoto($domain,$user,'jpg');
1.44 albertel 2300: my $name=&Apache::loncommon::plainname($user,$domain);
2301:
1.4 albertel 2302: my $msg;
1.11 albertel 2303: if ($env{'form.proctorpassword'}) {
1.4 albertel 2304: $msg='<p><font color="red">'.&mt("Failed to authenticate the proctor.")
2305: .'</font></p>';
2306: }
1.47 albertel 2307: if (!$env{'form.proctordomain'}) { $env{'form.proctordomain'}=$domain; }
1.4 albertel 2308: my $result= (<<ENDCHECKOUT);
2309: <h2>Proctor Validation</h2>
2310: <p>Your room's proctor needs to validate your access to this resource.</p>
2311: $msg
1.115 albertel 2312: <form name="checkout" method="post" action="$env{'request.uri'}">
1.4 albertel 2313: <input type="hidden" name="validate" value="yes" />
2314: <input type="hidden" name="submitted" value="yes" />
2315: <table>
1.44 albertel 2316: <tr><td>Proctor's Username:</td><td><input type="string" name="proctorname" value="$env{'form.proctorname'}" /></td></tr>
1.4 albertel 2317: <tr><td>Password:</td><td><input type="password" name="proctorpassword" value="" /></td></tr>
1.46 albertel 2318: <tr><td>Proctor's Domain:</td><td><input type="string" name="proctordomain" value="$env{'form.proctordomain'}" /></td></tr>
1.4 albertel 2319: </table>
2320: <input type="submit" name="checkoutbutton" value="Validate" /><br />
1.44 albertel 2321: <table border="1">
2322: <tr><td>
2323: <table>
2324: <tr><td colspan="2">Student who should be logged in is:</td></tr>
2325: <tr><td>Name:</td><td>$name</td></tr>
1.45 albertel 2326: <tr><td>Student ID:</td><td>$env{'environment.id'}</td></tr>
1.138 albertel 2327: <tr><td>Usename</td><td>$user:$domain</td></tr>
1.44 albertel 2328: <tr><td colspan="2"><img src="$url" /></td></tr>
2329: </table>
2330: </tr></td>
2331: </table>
1.4 albertel 2332: </form>
2333: ENDCHECKOUT
2334: return $result;
2335: }
2336:
1.1 albertel 2337: 1;
2338: __END__
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>