Annotation of loncom/homework/bridgetask.pm, revision 1.163
1.1 albertel 1: # The LearningOnline Network with CAPA
2: # definition of tags that give a structure to a document
3: #
1.163 ! albertel 4: # $Id: bridgetask.pm,v 1.162 2006/06/06 21:05:56 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.33 albertel 617: } elsif ($status_code eq 'lock_failed') {
1.105 albertel 618: $result.='<b>'.&mt("Failed to lock the requested record.")
1.81 albertel 619: .'</b>'.$back;
1.33 albertel 620: } elsif ($status_code eq 'unlock') {
1.81 albertel 621: $result.='<b>'.&mt("Unlocked the requested record.")
622: .'</b>'.$back;
1.33 albertel 623: $result.=&show_queue($env{'form.queue'},1);
624: } elsif ($status_code eq 'show_list') {
625: $result.=&show_queue($env{'form.queue'},1);
1.49 albertel 626: } elsif ($status_code eq 'select_user') {
627: $result.=&select_user();
1.95 albertel 628: } elsif ($status_code eq 'unable') {
629: $result.='<b>'.&mt("Unable to aqcuire a user to grade.").'</b>'.$back;
1.105 albertel 630: } elsif ($status_code eq 'not_allowed') {
631: $result.='<b>'.&mt('Not allowed to grade the requested user.').' '.$msg.'</b>'.$back;
1.33 albertel 632: } else {
1.81 albertel 633: $result.='<b>'.&mt("No user to be graded.").'</b>'.$back;
1.32 albertel 634: }
1.21 albertel 635: }
1.33 albertel 636: $webgrade='no';
1.163 ! albertel 637: }
! 638: if (!$todo || $env{'form.cancel'}) {
1.87 albertel 639: my $bodytext=&Apache::lonxml::get_all_text("/task",$parser,$style);
1.32 albertel 640: }
641: if ($target eq 'webgrade' && defined($env{'form.queue'})) {
1.61 albertel 642: if ($webgrade eq 'yes') {
643: $result.=&submission_time_stamp();
644: }
1.32 albertel 645: $result.=$form_tag_start;
646: $result.='<input type="hidden" name="webgrade" value="'.
647: $webgrade.'" />';
648: $result.='<input type="hidden" name="queue" value="'.
649: $env{'form.queue'}.'" />';
1.52 albertel 650: if ($env{'form.regrade'}) {
651: $result.='<input type="hidden" name="regrade" value="'.
652: $env{'form.regrade'}.'" />';
653: }
1.62 albertel 654: if ($env{'form.chosensections'}) {
655: my @chosen_sections=
656: &Apache::loncommon::get_env_multiple('form.chosensections');
657: foreach my $sec (@chosen_sections) {
658: $result.='<input type="hidden" name="chosensections"
659: value="'.$sec.'" />';
660: }
661: }
1.70 albertel 662: if ($webgrade eq 'yes') { $result.=&webgrade_standard_info(); }
1.15 albertel 663: }
1.110 albertel 664: if ($target eq 'webgrade') {
1.120 albertel 665: $result.="\n".'<div id="LC_GRADING_criterialist">';
1.110 albertel 666: }
1.74 albertel 667: } elsif ($target eq 'edit') {
1.141 albertel 668: $result.=$form_tag_start.
1.74 albertel 669: &Apache::structuretags::problem_edit_header();
670: $Apache::lonxml::warnings_error_header=
671: &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 />";
672: my $temp=&Apache::edit::insertlist($target,$token);
673: $result.=$temp;
1.1 albertel 674: } else {
675: # page_start returned a starting result, delete it if we don't need it
676: $result = '';
677: }
678: return $result;
679: }
680:
1.32 albertel 681: sub get_key_todo {
682: my ($target)=@_;
683: my $todo;
1.33 albertel 684:
685: if (defined($env{'form.reviewasubmission'})) {
1.54 albertel 686: &Apache::lonxml::debug("review a submission....");
1.33 albertel 687: $env{'form.queue'}='reviewqueue';
688: return (undef,'show_list');
689: }
690:
691: if (defined($env{'form.reviewagrading'})) {
692: &Apache::lonxml::debug("review a grading....");
693: $env{'form.queue'}='gradingqueue';
694: return (undef,'show_list');
695: }
696:
1.49 albertel 697: if (defined($env{'form.regradeasubmission'})) {
698: &Apache::lonxml::debug("regrade a grading....");
699: $env{'form.queue'}='none';
700: return (undef,'select_user');
701: }
702:
1.105 albertel 703:
1.138 albertel 704: my $me=$env{'user.name'}.':'.$env{'user.domain'};
1.105 albertel 705:
706: #need to try both queues..
707: if (defined($env{'form.regradeaspecificsubmission'}) &&
708: defined($env{'form.gradinguser'}) &&
709: defined($env{'form.gradingdomain'}) ) {
710: my ($symb,$cid)=&Apache::lonxml::whichuser();
711: my $cnum = $env{'course.'.$cid.'.num'};
712: my $cdom = $env{'course.'.$cid.'.domain'};
713: my $uname = $env{'form.gradinguser'};
714: my $udom = $env{'form.gradingdomain'};
715:
716: my $gradingkey=&encode_queue_key($symb,$udom,$uname);
717:
718: my $queue;
719:
720: if (&in_queue('gradingqueue',$symb,$cdom,$cnum,$udom,$uname)) {
721: $env{'form.queue'} = $queue = 'gradingqueue';
722: } elsif (&in_queue('reviewqueue' ,$symb,$cdom,$cnum,$udom,$uname)) {
723: $env{'form.queue'} = $queue = 'reviewqueue';
724: }
725:
726: if (!$queue) {
727: $env{'form.queue'} = $queue = 'none';
728: #not queued so doing either a re or pre grade
1.163 ! albertel 729: #FIXME don't allow pregrade
! 730: &Apache::lonxml::debug("not in queue no lock");
1.105 albertel 731: return ($gradingkey);
732: }
733:
734: my $who=&queue_key_locked($queue,$gradingkey);
735: if ($who eq $me) {
736: #already have the lock
1.158 www 737: $env{'form.gradingkey'}=&escape($gradingkey);
1.163 ! albertel 738: &Apache::lonxml::debug("already locked");
1.105 albertel 739: return ($gradingkey);
740: }
741:
742: if (!defined($who)) {
743: if (&lock_key($queue,$gradingkey)) {
1.163 ! albertel 744: &Apache::lonxml::debug("newly locked");
1.105 albertel 745: return ($gradingkey);
746: } else {
747: return (undef,'lock_failed');
748: }
749: }
750:
751: #otherwise (defined($who) && $who ne $me) some else has it...
752: return (undef,'not_allowed',
753: &mt('Another user ([_1]) currently has the record for [_2] locked.',
1.138 albertel 754: $who,$env{'form.gradinguser'}.':'.$env{'form.gradingdomain'}));
1.105 albertel 755: }
756:
757:
1.32 albertel 758: my $queue=$env{'form.queue'};
1.33 albertel 759:
1.32 albertel 760: if (!defined($queue)) {
761: $env{'form.queue'}=$queue='gradingqueue';
762: }
1.33 albertel 763:
1.158 www 764: my $gradingkey=&unescape($env{'form.gradingkey'});
1.33 albertel 765:
1.49 albertel 766: if ($env{'form.queue'} eq 'none') {
767: if (defined($env{'form.gradingkey'})) {
768: if ($target eq 'webgrade') {
769: if ($env{'form.stop'}) {
770: return (undef,'stop');
1.163 ! albertel 771: } elsif ($env{'form.cancel'}) {
! 772: return (undef,'cancel');
1.49 albertel 773: } elsif ($env{'form.next'}) {
1.59 albertel 774: return (undef,'select_user');
1.49 albertel 775: }
776: }
777: return ($gradingkey,'selected');
778: } else {
1.59 albertel 779: return (undef,'select_user');
1.49 albertel 780: }
781: }
1.32 albertel 782: if (defined($env{'form.queue'}) && defined($env{'form.gradingkey'})
1.33 albertel 783: && !defined($env{'form.gradingaction'})
784: && $env{'form.queuemode'} eq 'selected') {
785:
786: my $who=&queue_key_locked($queue,$gradingkey);
787: if ($who eq $me) {
788: &Apache::lonxml::debug("Found a key was given to me");
789: return ($gradingkey,'selected');
790: } else {
791: return (undef,'show_list');
792: }
793:
794: }
795:
796: if ($target eq 'webgrade' && $env{'form.queuemode'} eq 'selected') {
797: if ($env{'form.gradingaction'} eq 'resume') {
798: delete($env{'form.gradingaction'});
799: &Apache::lonxml::debug("Resuming a key");
1.32 albertel 800: return ($gradingkey);
1.33 albertel 801: } elsif ($env{'form.gradingaction'} eq 'unlock') {
802: &Apache::lonxml::debug("Unlocking a key ".
803: &check_queue_unlock($queue,$gradingkey,1));
804: return (undef,'unlock');
805: } elsif ($env{'form.gradingaction'} eq 'select') {
806: &Apache::lonxml::debug("Locking a key");
807: if (&lock_key($queue,$gradingkey)) {
808: &Apache::lonxml::debug("Success $queue");
809: return ($gradingkey);
810: }
811: &Apache::lonxml::debug("Failed $queue");
812: return (undef,'lock_failed');
1.32 albertel 813: }
814: }
1.33 albertel 815:
816: if ($env{'form.queuemode'} ne 'selected') {
817: # don't get something new from the queue if they hit the stop button
1.163 ! albertel 818: if (!(($env{'form.cancel'} || $env{'form.stop'})
! 819: && $target eq 'webgrade')
1.33 albertel 820: && !$env{'form.gradingaction'}) {
821: &Apache::lonxml::debug("Getting anew $queue");
822: return (&get_from_queue($queue));
823: } else {
824: return (undef,'stop');
825: }
1.32 albertel 826: }
1.33 albertel 827: return (undef,undef)
1.32 albertel 828: }
1.94 albertel 829:
830: sub minimize_storage {
831: foreach my $key (keys(%Apache::lonhomework::results)) {
832: if ($key =~ /regrader$/) { next; }
833: if ($Apache::lonhomework::results{$key} eq
834: $Apache::lonhomework::history{$key}) {
835: delete($Apache::lonhomework::results{$key});
836: }
837: }
838: }
839:
1.1 albertel 840: sub end_Task {
841: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
842: my $result='';
843: my $status=$Apache::inputtags::status['-1'];
1.29 albertel 844: my ($version,$previous)=&get_version();
1.1 albertel 845: if ($target eq 'grade' || $target eq 'web' || $target eq 'answer' ||
1.15 albertel 846: $target eq 'tex') {
1.69 albertel 847: if ($target eq 'web' || $target eq 'answer' || $target eq 'tex') {
1.1 albertel 848: if ($target eq 'web') {
1.54 albertel 849: if (&show_task($status,$previous)) {
850: $result.=&Apache::lonxml::endredirection();
851: }
1.64 albertel 852: if ($status eq 'CAN_ANSWER' && !$previous &&
853: !$env{'form.donescreen'}) {
1.15 albertel 854: $result.="\n".'<table border="1">'.
1.28 albertel 855: &Apache::inputtags::file_selector("$version.0",
856: "bridgetask","*",
1.46 albertel 857: 'portfolioonly',
858: '
859: <h2>'.&mt('Submit Portfolio Files for Grading').'</h2>
860: <p>'.&mt('Indicate the files from your portfolio to be evaluated in grading this task.').'</p>').
1.9 albertel 861: "</table>";
1.77 albertel 862: }
1.78 albertel 863: if (!$previous && $status ne 'SHOW_ANSWER' &&
864: &show_task($status,$previous)) {
1.9 albertel 865: $result.=&Apache::inputtags::gradestatus('0');
1.64 albertel 866: $result.='</form>';
1.116 albertel 867: my $action = &Apache::lonenc::check_encrypt($env{'request.uri'});
1.64 albertel 868: $result.=<<DONEBUTTON;
1.115 albertel 869: <form name="done" method="post" action="$action">
1.64 albertel 870: <input type="hidden" name="donescreen" value="1" />
871: <input type="submit" value="Done" />
872: </form>
873: DONEBUTTON
1.77 albertel 874: }
1.56 albertel 875: if (&show_task($status,$previous) &&
1.89 albertel 876: $Apache::lonhomework::history{"resource.$version.0.status"} =~ /^(pass|fail)$/) {
877: my $bt_status=$Apache::lonhomework::history{"resource.$version.0.status"};
1.54 albertel 878: my $title=&Apache::lonnet::gettitle();
1.80 albertel 879:
1.149 albertel 880: my $start_time;
881:
1.80 albertel 882: my $slot_name=
1.89 albertel 883: $Apache::lonhomework::history{"resource.$version.0.checkedin.slot"};
1.149 albertel 884: if ($slot_name) {
885: my %slot=&Apache::lonnet::get_slot($slot_name);
886:
887: $start_time=$slot{'starttime'}
888: } else {
889: $start_time=
890: &Apache::lonnet::EXT('resource.0.opendate');
891: }
892: $start_time=&Apache::lonlocal::locallocaltime($start_time);
1.54 albertel 893:
1.116 albertel 894: my $status = "\n<div class='LC_$bt_status LC_criteria'>\n";
1.54 albertel 895:
896: if ($bt_status eq 'pass') {
897: $status.='<h2>You passed the '.$title.' given on '.
1.80 albertel 898: $start_time.'</h2>';
1.54 albertel 899: }
900: if ($bt_status eq 'fail') {
901: $status.='<h2>You did not pass the '.$title.' given on '.
1.80 albertel 902: $start_time.'</h2>';
1.54 albertel 903: if (!$previous) {
904: $status.=&add_request_another_attempt_button();
905: }
906: }
907: my $man_count=0;
908: my $opt_count=0;
909: my $opt_passed=0;
910: foreach my $dim_id (@Apache::bridgetask::dimensionlist) {
911: if ($Apache::bridgetask::dimensionmandatory{$dim_id}
912: eq 'N') {
913: $opt_count++;
1.89 albertel 914: if ($Apache::lonhomework::history{"resource.$version.0.$dim_id.status"} eq 'pass') {
1.54 albertel 915: $opt_passed++;
916: }
917: } else {
918: $man_count++;
919: }
920: }
1.151 albertel 921:
1.54 albertel 922: my $opt_req=&Apache::lonxml::get_param('OptionalRequired',
923: $parstack,$safeeval);
924: if ($opt_req !~ /\S/) { $opt_req='0'; }
1.99 albertel 925: $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 926:
927: my $internal_location=&internal_location();
928: $result=~s/\Q$internal_location\E/$status/;
929: }
1.142 albertel 930: $result.="\n</div>\n".
931: &Apache::loncommon::end_page({'discussion' => 1});
1.1 albertel 932: }
933: }
1.29 albertel 934: if ($target eq 'grade' && !$env{'form.webgrade'} && !$previous) {
1.12 albertel 935: my $award='SUBMITTED';
1.28 albertel 936: &Apache::essayresponse::file_submission("$version.0",'bridgetask',
1.20 albertel 937: 'portfiles',\$award);
1.14 albertel 938: if ($award eq 'SUBMITTED' &&
1.28 albertel 939: $Apache::lonhomework::results{"resource.$version.0.bridgetask.portfiles"}) {
940: $Apache::lonhomework::results{"resource.0.tries"}=
941: $Apache::lonhomework::results{"resource.$version.0.tries"}=
942: 1+$Apache::lonhomework::history{"resource.$version.0.tries"};
943:
944: $Apache::lonhomework::results{"resource.0.award"}=
945: $Apache::lonhomework::results{"resource.$version.0.award"}=
946: $award;
1.51 albertel 947: $Apache::lonhomework::results{"resource.0.submission"}=
948: $Apache::lonhomework::results{"resource.$version.0.submission"}='';
1.64 albertel 949: } else {
950: delete($Apache::lonhomework::results{"resource.$version.0.bridgetask.portfiles"});
1.77 albertel 951: $award = '';
1.10 albertel 952: }
1.4 albertel 953: &Apache::lonhomework::showhash(%Apache::lonhomework::results);
954: &Apache::structuretags::finalize_storage();
1.148 albertel 955: if ($award eq 'SUBMITTED') {
956: my $useslots = &Apache::lonnet::EXT("resource.0.useslots");
957: if ($useslots =~ /^\s*no\s*$/i) {
958: &add_to_queue('gradingqueue',
1.152 albertel 959: {'type' => 'Task',
1.148 albertel 960: 'time' => time});
961: } elsif (defined($Apache::inputtags::slot_name)) {
962: &add_to_queue('gradingqueue',
1.152 albertel 963: {'type' => 'Task',
1.148 albertel 964: 'time' => time,
965: 'slot' => $Apache::inputtags::slot_name});
966: }
1.14 albertel 967: }
1.79 albertel 968: } elsif ($Apache::lonhomework::results{'INTERNAL_store'}) {
969: &Apache::structuretags::finalize_storage();
1.1 albertel 970: }
1.163 ! albertel 971: if ($target eq 'grade' && $env{'form.webgrade'} eq 'yes'
! 972: && exists($env{'form.cancel'})) {
! 973: &check_queue_unlock($env{'form.queue'});
! 974: &Apache::lonxml::debug(" cancelled grading .".$env{'form.queue'});
! 975: } elsif ($target eq 'grade' && $env{'form.webgrade'} eq 'yes'
! 976: && !exists($env{'form.cancel'})) {
1.20 albertel 977: my $optional_required=
978: &Apache::lonxml::get_param('OptionalRequired',$parstack,
979: $safeeval);
980: my $optional_passed=0;
981: my $mandatory_failed=0;
982: my $ungraded=0;
983: my $review=0;
1.21 albertel 984: &Apache::lonhomework::showhash(%Apache::lonhomework::results);
1.20 albertel 985: foreach my $dim_id (@Apache::bridgetask::dimensionlist) {
986: my $status=
1.89 albertel 987: $Apache::lonhomework::results{"resource.$version.0.$dim_id.status"};
1.20 albertel 988: my $mandatory=
989: ($Apache::bridgetask::dimensionmandatory{$dim_id} ne 'N');
990: if ($status eq 'pass') {
991: if (!$mandatory) { $optional_passed++; }
992: } elsif ($status eq 'fail') {
993: if ($mandatory) { $mandatory_failed++; }
994: } elsif ($status eq 'ungraded') {
995: $ungraded++;
996: } elsif ($status eq 'review') {
997: $review++;
1.49 albertel 998: } else {
999: $ungraded++;
1000: }
1.20 albertel 1001: }
1002: if ($optional_passed < $optional_required) {
1003: $mandatory_failed++;
1004: }
1.21 albertel 1005: &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 1006: $Apache::lonhomework::results{'resource.0.regrader'}=
1.138 albertel 1007: $env{'user.name'}.':'.$env{'user.domain'};
1.20 albertel 1008: if ($review) {
1.89 albertel 1009: $Apache::lonhomework::results{"resource.$version.0.status"}='review';
1.33 albertel 1010: if ($env{'form.queue'} eq 'reviewqueue') {
1011: &check_queue_unlock($env{'form.queue'});
1012: &Apache::lonxml::debug(" still needs review not changing status.");
1013: } else {
1.49 albertel 1014: &move_between_queues($env{'form.queue'},'reviewqueue');
1.33 albertel 1015: }
1.20 albertel 1016: } elsif ($ungraded) {
1.89 albertel 1017: $Apache::lonhomework::results{"resource.$version.0.status"}='ungraded';
1.49 albertel 1018: if ($env{'form.queue'} eq 'reviewqueue' ||
1019: $env{'form.queue'} eq 'none' ) {
1.33 albertel 1020: &Apache::lonxml::debug("moving back.");
1.49 albertel 1021: &move_between_queues($env{'form.queue'},'gradingqueue');
1.33 albertel 1022: } else {
1023: &check_queue_unlock($env{'form.queue'});
1024: }
1.20 albertel 1025: } elsif ($mandatory_failed) {
1.89 albertel 1026: $Apache::lonhomework::results{"resource.$version.0.status"}='fail';
1.25 albertel 1027: $Apache::lonhomework::results{"resource.$version.0.solved"}='incorrect_by_override';
1028: $Apache::lonhomework::results{"resource.$version.0.award"}='INCORRECT';
1029: $Apache::lonhomework::results{"resource.$version.0.awarded"}='0';
1.39 albertel 1030: &remove_from_queue($env{'form.queue'});
1031:
1032: my ($symb,$courseid,$udom,$uname)=&Apache::lonxml::whichuser();
1.52 albertel 1033:
1034: if ($env{'form.regrade'} ne 'yes') {
1035: $Apache::lonhomework::results{"resource.$version.0.bridgetask.portfiles"}=
1036: $Apache::lonhomework::history{"resource.$version.0.bridgetask.portfiles"};
1037: &Apache::grades::version_portfiles(
1038: \%Apache::lonhomework::results,
1039: ["$version.0.bridgetask"],$courseid,
1040: $symb,$udom,$uname,
1041: ["$version.0.bridgetask"]);
1042: }
1.20 albertel 1043: } else {
1.89 albertel 1044: $Apache::lonhomework::results{"resource.$version.0.status"}='pass';
1.25 albertel 1045: $Apache::lonhomework::results{"resource.$version.0.solved"}='correct_by_override';
1046: $Apache::lonhomework::results{"resource.$version.0.award"}='EXACT_ANS';
1047: $Apache::lonhomework::results{"resource.$version.0.awarded"}='1';
1.32 albertel 1048: &remove_from_queue($env{'form.queue'});
1.39 albertel 1049:
1050: my ($symb,$courseid,$udom,$uname)=&Apache::lonxml::whichuser();
1.52 albertel 1051: if ($env{'form.regrade'} ne 'yes') {
1052: $Apache::lonhomework::results{"resource.$version.0.bridgetask.portfiles"}=
1053: $Apache::lonhomework::history{"resource.$version.0.bridgetask.portfiles"};
1054: &Apache::grades::version_portfiles(
1055: \%Apache::lonhomework::results,
1056: ["$version.0.bridgetask"],$courseid,
1057: $symb,$udom,$uname,
1058: ["$version.0.bridgetask"]);
1059: }
1.20 albertel 1060: }
1.89 albertel 1061: $Apache::lonhomework::results{"resource.0.status"}=
1062: $Apache::lonhomework::results{"resource.$version.0.status"};
1.28 albertel 1063: if (defined($Apache::lonhomework::results{"resource.$version.0.awarded"})) {
1.26 albertel 1064: $Apache::lonhomework::results{"resource.0.award"}=
1.50 albertel 1065: $Apache::lonhomework::results{"resource.$version.0.award"};
1.26 albertel 1066: $Apache::lonhomework::results{"resource.0.awarded"}=
1.50 albertel 1067: $Apache::lonhomework::results{"resource.$version.0.awarded"};
1.26 albertel 1068: $Apache::lonhomework::results{"resource.0.solved"}=
1.50 albertel 1069: $Apache::lonhomework::results{"resource.$version.0.solved"};
1.25 albertel 1070: }
1.94 albertel 1071: &minimize_storage();
1.21 albertel 1072: &Apache::structuretags::finalize_storage();
1.20 albertel 1073: }
1.15 albertel 1074: } elsif ($target eq 'webgrade') {
1.131 albertel 1075: $result.="</div>";
1.20 albertel 1076: #$result.='<input type="submit" name="next" value="'.
1077: # &mt('Save & Next').'" /> ';
1078: #$result.='<input type="submit" name="end" value="'.
1079: # &mt('Save & Stop Grading').'" /> ';
1080: #$result.='<input type="submit" name="throwaway" value="'.
1081: # &mt('Throw Away & Stop Grading').'" /> ';
1082: #$result.='<input type="submit" name="save" value="'.
1083: # &mt('Save Partial Grade and Continue Grading').'" /> ';
1.124 albertel 1084: $result.='</form>'."\n</div>\n</div>\n".
1.140 albertel 1085: &Apache::loncommon::end_page();
1.1 albertel 1086: } elsif ($target eq 'meta') {
1.70 albertel 1087: $result.=&Apache::response::meta_package_write('Task');
1.77 albertel 1088: $result.=&Apache::response::meta_stores_write('solved','string',
1089: 'Problem Status');
1090: $result.=&Apache::response::meta_stores_write('tries','int_zeropos',
1091: 'Number of Attempts');
1092: $result.=&Apache::response::meta_stores_write('awarded','float',
1093: 'Partial Credit Factor');
1094: $result.=&Apache::response::meta_stores_write('status','string',
1095: 'Bridge Task Status');
1.1 albertel 1096: }
1.4 albertel 1097: undef($Apache::lonhomework::parsing_a_task);
1.1 albertel 1098: return $result;
1099: }
1100:
1.31 albertel 1101: sub move_between_queues {
1102: my ($src_queue,$dest_queue)=@_;
1.49 albertel 1103: my $cur_data;
1104: if ($src_queue ne 'none') {
1105: $cur_data=&get_queue_data($src_queue);
1106: if (!$cur_data) { return 'not_exist'; }
1107: } else {
1108: $cur_data = ['none'];
1109: }
1.148 albertel 1110: my $result=&add_to_queue($dest_queue,$cur_data);
1.31 albertel 1111: if ($result ne 'ok') {
1112: return $result;
1113: }
1114: &check_queue_unlock($src_queue);
1115: return &remove_from_queue($src_queue);
1.21 albertel 1116: }
1117:
1118: sub check_queue_unlock {
1.32 albertel 1119: my ($queue,$key,$allow_not_me)=@_;
1.49 albertel 1120: if ($queue eq 'none') { return 'ok'; }
1.30 albertel 1121: my ($symb,$cid,$udom,$uname)=&Apache::lonxml::whichuser();
1.32 albertel 1122: if (!defined($key)) {
1.138 albertel 1123: $key="$symb\0queue\0$uname:$udom";
1.32 albertel 1124: }
1.30 albertel 1125: my $cnum=$env{'course.'.$cid.'.num'};
1126: my $cdom=$env{'course.'.$cid.'.domain'};
1.138 albertel 1127: my $me=$env{'user.name'}.':'.$env{'user.domain'};
1.30 albertel 1128: my $who=&queue_key_locked($queue,$key,$cdom,$cnum);
1129: if ($who eq $me) {
1.163 ! albertel 1130: &Apache::lonxml::debug("unlocking my own $who");
1.32 albertel 1131: return &Apache::lonnet::del($queue,["$key\0locked"],$cdom,$cnum);
1132: } elsif ($allow_not_me) {
1.33 albertel 1133: &Apache::lonxml::debug("unlocking $who by $me");
1.32 albertel 1134: return &Apache::lonnet::del($queue,["$key\0locked"],$cdom,$cnum);
1.30 albertel 1135: }
1.32 albertel 1136: return 'not_owner';
1.21 albertel 1137: }
1138:
1.88 albertel 1139: sub in_queue {
1140: my ($queue,$symb,$cdom,$cnum,$udom,$uname)=@_;
1141: if ($queue eq 'none') { return 0; }
1142: if (!defined($symb) || !defined($cdom) || !defined($cnum)
1143: || !defined($udom) || !defined($uname)) {
1144: ($symb,my $cid,$udom,$uname)=&Apache::lonxml::whichuser();
1145: $cnum=$env{'course.'.$cid.'.num'};
1146: $cdom=$env{'course.'.$cid.'.domain'};
1147: }
1148:
1149: my $key=&encode_queue_key($symb,$udom,$uname);
1150: my %results = &Apache::lonnet::get($queue,[$key],$cdom,$cnum);
1151:
1152: if (defined($results{$key})) {
1153: return 1;
1154: }
1155: return 0;
1156: }
1157:
1.21 albertel 1158: sub remove_from_queue {
1.86 albertel 1159: my ($queue,$symb,$cdom,$cnum,$udom,$uname)=@_;
1.49 albertel 1160: if ($queue eq 'none') { return 'ok'; }
1.86 albertel 1161: if (!defined($symb) || !defined($cdom) || !defined($cnum)
1162: || !defined($udom) || !defined($uname)) {
1163: ($symb,my $cid,$udom,$uname)=&Apache::lonxml::whichuser();
1164: $cnum=$env{'course.'.$cid.'.num'};
1165: $cdom=$env{'course.'.$cid.'.domain'};
1166: }
1.88 albertel 1167: if (!&in_queue($queue,$symb,$cdom,$cnum,$udom,$uname)) {
1168: return 'ok';
1169: }
1.86 albertel 1170: my $key=&encode_queue_key($symb,$udom,$uname);
1.27 albertel 1171: my @keys=($key,"$key\0locked");
1.31 albertel 1172: return &Apache::lonnet::del($queue,\@keys,$cdom,$cnum);
1.21 albertel 1173: }
1174:
1.16 albertel 1175: sub setup_env_for_other_user {
1176: my ($queue_key,$safeeval)=@_;
1177: my ($symb,$uname,$udom)=&decode_queue_key($queue_key);
1.30 albertel 1178: &Apache::lonxml::debug("setup_env for $queue_key");
1.16 albertel 1179: $env{'form.grade_symb'}=$symb;
1180: $env{'form.grade_domain'}=$udom;
1181: $env{'form.grade_username'}=$uname;
1182: $env{'form.grade_courseid'}=$env{'request.course.id'};
1183: &Apache::lonxml::initialize_rndseed($safeeval);
1184: }
1185:
1.31 albertel 1186: sub get_queue_data {
1187: my ($queue)=@_;
1188: my ($symb,$cid,$udom,$uname)=&Apache::lonxml::whichuser();
1189: my $cnum=$env{'course.'.$cid.'.num'};
1190: my $cdom=$env{'course.'.$cid.'.domain'};
1.138 albertel 1191: my $todo="$symb\0queue\0$uname:$udom";
1.31 albertel 1192: my ($key,$value)=&Apache::lonnet::get($queue,[$todo],$cdom,$cnum);
1193: if ($key eq $todo && ref($value)) {
1194: return $value;
1195: }
1196: return undef;
1197: }
1198:
1.84 albertel 1199:
1.49 albertel 1200: sub check_queue_for_key {
1.84 albertel 1201: my ($cdom,$cnum,$queue,$todo)=@_;
1202:
1.49 albertel 1203: my %results=
1204: &Apache::lonnet::get($queue,[$todo,"$todo\0locked"],$cdom,$cnum);
1205:
1206: if (exists($results{$todo}) && ref($results{$todo})) {
1207: if (defined($results{"$todo\0locked"})) {
1208: return 'locked';
1209: }
1.148 albertel 1210: if (my $slot=&slotted_access($results{$todo})) {
1.86 albertel 1211: my %slot_data=&Apache::lonnet::get_slot($slot);
1212: if ($slot_data{'endtime'} > time) {
1213: return 'in_progress';
1214: }
1.148 albertel 1215: } else {
1216: my ($symb) = &decode_queue_key($todo);
1217: my $due_date = &Apache::lonhomework::due_date('0',$symb);
1218: if ($due_date > time) {
1219: return 'in_progress';
1220: }
1.58 albertel 1221: }
1.49 albertel 1222: return 'enqueued';
1223: }
1224: return undef;
1225: }
1226:
1.14 albertel 1227: sub add_to_queue {
1.82 albertel 1228: my ($queue,$user_data)=@_;
1.49 albertel 1229: if ($queue eq 'none') { return 'ok'; }
1.14 albertel 1230: my ($symb,$cid,$udom,$uname)=&Apache::lonxml::whichuser();
1.82 albertel 1231: if (!$cid || $env{'request.state'} eq 'construct') {
1232: return 'no_queue';
1233: }
1.14 albertel 1234: my $cnum=$env{'course.'.$cid.'.num'};
1235: my $cdom=$env{'course.'.$cid.'.domain'};
1236: my %data;
1.138 albertel 1237: $data{"$symb\0queue\0$uname:$udom"}=$user_data;
1.83 albertel 1238: return &Apache::lonnet::cput($queue,\%data,$cdom,$cnum);
1.14 albertel 1239: }
1240:
1.156 albertel 1241: sub get_limited_classlist {
1242: my ($sections) = @_;
1243:
1244: my $classlist = &Apache::loncoursedata::get_classlist();
1.157 albertel 1245: foreach my $student (keys(%$classlist)) {
1246: if ( $classlist->{$student}[&Apache::loncoursedata::CL_STATUS()]
1247: ne 'Active') {
1248: delete($classlist->{$student});
1249: }
1250: }
1.156 albertel 1251:
1.157 albertel 1252: if (ref($sections) && !grep('all',@{ $sections })) {
1.156 albertel 1253: foreach my $student (keys(%$classlist)) {
1254: my $section =
1255: $classlist->{$student}[&Apache::loncoursedata::CL_SECTION()];
1256: if (! grep($section,@{ $sections })) {
1257: delete($classlist->{$student});
1258: }
1259: }
1260: }
1261: return $classlist;
1262: }
1263:
1264:
1.14 albertel 1265: sub show_queue {
1.32 albertel 1266: my ($queue,$with_selects)=@_;
1.14 albertel 1267: my $result;
1268: my ($symb,$cid,$udom,$uname)=&Apache::lonxml::whichuser();
1269: my $cnum=$env{'course.'.$cid.'.num'};
1270: my $cdom=$env{'course.'.$cid.'.domain'};
1.59 albertel 1271:
1272: my @chosen_sections=
1273: &Apache::loncommon::get_env_multiple('form.chosensections');
1.156 albertel 1274:
1275: my $classlist = &get_limited_classlist(\@chosen_sections);
1276:
1.63 albertel 1277: if (!(grep(/^all$/,@chosen_sections))) {
1278: $result.='<p> Showing only sections <tt>'.join(', ',@chosen_sections).
1279: '</tt>.</p> '."\n";
1280: }
1.59 albertel 1281:
1.156 albertel 1282: my ($view,$view_section);
1283: my $scope = $env{'request.course.id'};
1284: if (!($view=&Apache::lonnet::allowed('vgr',$scope))) {
1285: $scope .= '/'.$env{'request.course.sec'};
1286: if ( $view = &Apache::lonnet::allowed('vgr',$scope)) {
1287: $view_section=$env{'request.course.sec'};
1288: } else {
1289: undef($view);
1290: }
1291: }
1292:
1.16 albertel 1293: my $regexp="^$symb\0";
1.30 albertel 1294: my %queue=&Apache::lonnet::dump($queue,$cdom,$cnum,$regexp);
1.31 albertel 1295: my ($tmp)=%queue;
1296: if ($tmp=~/^error: 2 /) {
1.159 albertel 1297: return "\n<h3>Current Queue - $queue</h3>".
1298: &Apache::loncommon::start_data_table().
1299: &Apache::loncommon::start_data_table_row().
1300: '<td>'.&mt('Empty').'</td>'.
1301: &Apache::loncommon::end_data_table_row().
1302: &Apache::loncommon::end_data_table();
1.31 albertel 1303: }
1.103 albertel 1304: my $title=&Apache::lonnet::gettitle($symb);
1.159 albertel 1305: $result.="\n<h3>Current Queue - $title $queue </h3>".
1306: &Apache::loncommon::start_data_table().
1307: &Apache::loncommon::start_data_table_header_row();
1.103 albertel 1308: if ($with_selects) { $result.="<th>Status</th><th></th>"; }
1.159 albertel 1309: $result.="<th>user</th><th>data</th>".
1310: &Apache::loncommon::end_data_table_header_row();
1.14 albertel 1311: foreach my $key (sort(keys(%queue))) {
1.59 albertel 1312: my ($symb,$uname,$udom) = &decode_queue_key($key);
1313: if (!defined($classlist->{$uname.':'.$udom})) { next; }
1.156 albertel 1314:
1315: my $section = $classlist->{$uname.':'.$udom}[&Apache::loncoursedata::CL_SECTION()];
1316:
1317: my $can_view=1;
1318: if (!$view
1319: || ($view_section && !$section)
1320: || ($view_section && $section && ($view_section ne $section))) {
1321: $can_view=0;
1322: }
1323:
1.32 albertel 1324: if ($key=~/locked$/ && !$with_selects) {
1.159 albertel 1325: $result.= &Apache::loncommon::start_data_table_row().
1326: "<td>$uname</td>";
1.103 albertel 1327: $result.='<td>'.$queue{$key}.'</td></tr>';
1.32 albertel 1328: } elsif ($key=~/timestamp$/ && !$with_selects) {
1.159 albertel 1329: $result.=&Apache::loncommon::start_data_table_row()."<td></td>";
1.103 albertel 1330: $result.='<td>'.
1.16 albertel 1331: &Apache::lonlocal::locallocaltime($queue{$key})."</td></tr>";
1.32 albertel 1332: } elsif ($key!~/(timestamp|locked)$/) {
1.159 albertel 1333: $result.= &Apache::loncommon::start_data_table_row();
1.148 albertel 1334: my ($end_time,$slot_text);
1335: if (my $slot=&slotted_access($queue{$key})) {
1336: my %slot_data=&Apache::lonnet::get_slot($slot);
1337: $end_time = $slot_data{'endtime'};
1338: $slot_text = &mt('Slot: [_1]',$slot);
1339: } else {
1340: $end_time = &Apache::lonhomework::due_date('0',$symb);
1341: $slot_text = '';
1342: }
1.32 albertel 1343: if ($with_selects) {
1.158 www 1344: my $ekey=&escape($key);
1.103 albertel 1345: my ($action,$description,$status)=('select',&mt('Select'));
1.32 albertel 1346: if (exists($queue{"$key\0locked"})) {
1.138 albertel 1347: my $me=$env{'user.name'}.':'.$env{'user.domain'};
1.103 albertel 1348: $status=&mt('Locked by <tt>[_1]</tt>',$queue{"$key\0locked"});
1.32 albertel 1349: if ($me eq $queue{"$key\0locked"}) {
1350: ($action,$description)=('resume',&mt('Resume'));
1351: } else {
1352: ($action,$description)=('unlock',&mt('Unlock'));
1353: }
1354: }
1.62 albertel 1355: my $seclist;
1356: foreach my $sec (@chosen_sections) {
1357: $seclist.='<input type="hidden" name="chosensections"
1358: value="'.$sec.'" />';
1359: }
1.156 albertel 1360: if ($can_view && ($end_time ne '' && time > $end_time)) {
1.35 albertel 1361: $result.=(<<FORM);
1.103 albertel 1362: <td>$status</td>
1.32 albertel 1363: <td>
1.115 albertel 1364: <form style="display: inline" method="post">
1.32 albertel 1365: <input type="hidden" name="gradingkey" value="$ekey" />
1366: <input type="hidden" name="queue" value="$queue" />
1367: <input type="hidden" name="gradingaction" value="$action" />
1368: <input type="hidden" name="webgrade" value="no" />
1.33 albertel 1369: <input type="hidden" name="queuemode" value="selected" />
1.32 albertel 1370: <input type="submit" name="submit" value="$description" />
1.62 albertel 1371: $seclist
1.32 albertel 1372: </form>
1373: </td>
1374: FORM
1.156 albertel 1375: } elsif (!$can_view && ($end_time ne '' && time > $end_time)) {
1376: $result.='<td>'.&mt("Not gradable").'</td><td> </td>'
1.35 albertel 1377: } else {
1.148 albertel 1378: $result.='<td>'.&mt("In Progress").'</td><td> </td>'
1.35 albertel 1379: }
1.32 albertel 1380: }
1.156 albertel 1381: $result.= "<td>".$classlist->{$uname.':'.$udom}[&Apache::loncoursedata::CL_FULLNAME()].
1.138 albertel 1382: " <tt>($uname:$udom)</tt> </td>";
1.148 albertel 1383: $result.='<td>'.$slot_text.' End time: '.
1384: &Apache::lonlocal::locallocaltime($end_time).
1.159 albertel 1385: "</td>".&Apache::loncommon::end_data_table_row();
1.16 albertel 1386: }
1.14 albertel 1387: }
1.159 albertel 1388: $result.= &Apache::loncommon::end_data_table()."<hr />\n";
1.14 albertel 1389: return $result;
1390: }
1391:
1.34 albertel 1392: sub get_queue_counts {
1393: my ($queue)=@_;
1394: my $result;
1395: my ($symb,$cid,$udom,$uname)=&Apache::lonxml::whichuser();
1396: my $cnum=$env{'course.'.$cid.'.num'};
1397: my $cdom=$env{'course.'.$cid.'.domain'};
1.156 albertel 1398:
1.157 albertel 1399: my $classlist=&get_limited_classlist();
1.156 albertel 1400:
1.34 albertel 1401: my $regexp="^$symb\0";
1402: my %queue=&Apache::lonnet::dump($queue,$cdom,$cnum,$regexp);
1403: my ($tmp)=%queue;
1404: if ($tmp=~/^error: 2 /) {
1405: return (0,0,0);
1406: }
1407: my ($entries,$ready_to_grade,$locks)=(0,0,0);
1.96 albertel 1408: my %slot_cache;
1.34 albertel 1409: foreach my $key (sort(keys(%queue))) {
1.156 albertel 1410: my ($symb,$uname,$udom) = &decode_queue_key($key);
1411: if (!defined($classlist->{$uname.':'.$udom})) { next; }
1412:
1.34 albertel 1413: if ($key=~/locked$/) {
1414: $locks++;
1415: } elsif ($key=~/timestamp$/) {
1416: #ignore
1417: } elsif ($key!~/(timestamp|locked)$/) {
1418: $entries++;
1.148 albertel 1419: if (my $slot=&slotted_access($queue{$key})) {
1420: if (!exists($slot_cache{$slot})) {
1421: my %slot_data=&Apache::lonnet::get_slot($slot);
1422: $slot_cache{$slot} = \%slot_data;
1423: }
1424: if (time > $slot_cache{$slot}{'endtime'}) {
1425: $ready_to_grade++;
1426: }
1427: } else {
1428: my $due_date = &Apache::lonhomework::due_date('0',$symb);
1429: if ($due_date ne '' && time > $due_date) {
1430: $ready_to_grade++;
1431: }
1.34 albertel 1432: }
1433: }
1434: }
1435: return ($entries,$ready_to_grade,$locks);
1436: }
1437:
1.49 albertel 1438: sub encode_queue_key {
1439: my ($symb,$udom,$uname)=@_;
1.138 albertel 1440: return "$symb\0queue\0$uname:$udom";
1.49 albertel 1441: }
1442:
1.14 albertel 1443: sub decode_queue_key {
1444: my ($key)=@_;
1445: my ($symb,undef,$user) = split("\0",$key);
1.138 albertel 1446: my ($uname,$udom) = split(':',$user);
1.14 albertel 1447: return ($symb,$uname,$udom);
1448: }
1449:
1450: sub queue_key_locked {
1.30 albertel 1451: my ($queue,$key,$cdom,$cnum)=@_;
1.33 albertel 1452: if (!defined($cdom) || !defined($cnum)) {
1453: my (undef,$cid)=&Apache::lonxml::whichuser();
1454: $cnum=$env{'course.'.$cid.'.num'};
1455: $cdom=$env{'course.'.$cid.'.domain'};
1456: }
1.14 albertel 1457: my ($key_locked,$value)=
1.30 albertel 1458: &Apache::lonnet::get($queue,["$key\0locked"],$cdom,$cnum);
1.14 albertel 1459: if ($key_locked eq "$key\0locked") {
1460: return $value;
1461: }
1462: return undef;
1463: }
1464:
1.148 albertel 1465: sub slotted_access {
1466: my ($queue_entry) = @_;
1467: if (ref($queue_entry) eq 'ARRAY') {
1468: if (defined($queue_entry->[0])) {
1469: return $queue_entry->[0];
1470: }
1471: return undef;
1472: } elsif (ref($queue_entry) eq 'HASH') {
1473: if (defined($queue_entry->{'slot'})) {
1474: return $queue_entry->{'slot'};
1475: }
1476: return undef;
1477: }
1478: return undef;
1479: }
1480:
1.14 albertel 1481: sub pick_from_queue_data {
1.156 albertel 1482: my ($queue,$check_section,$queuedata,$cdom,$cnum,$classlist)=@_;
1.98 albertel 1483: my @possible; # will hold queue entries that are valid to be selected
1.30 albertel 1484: foreach my $key (keys(%$queuedata)) {
1.68 albertel 1485: if ($key =~ /\0locked$/) { next; }
1486: if ($key =~ /\0timestamp$/) { next; }
1.156 albertel 1487:
1.14 albertel 1488: my ($symb,$uname,$udom)=&decode_queue_key($key);
1.156 albertel 1489: if (!defined($classlist->{$uname.':'.$udom})) { next; }
1490:
1.14 albertel 1491: if ($check_section) {
1.156 albertel 1492: my $section =
1493: $classlist->{$uname.':'.$udom}[&Apache::loncoursedata::CL_SECTION()];
1.17 albertel 1494: if ($section eq $check_section) {
1.33 albertel 1495: &Apache::lonxml::debug("my sec");
1.15 albertel 1496: next;
1497: }
1.14 albertel 1498: }
1.148 albertel 1499: my $end_time;
1500: if (my $slot=&slotted_access($queuedata->{$key})) {
1.154 albertel 1501: &Apache::lonxml::debug("looking at slot $slot");
1.148 albertel 1502: my %slot_data=&Apache::lonnet::get_slot($slot);
1503: if ($slot_data{'endtime'} < time) {
1504: $end_time = $slot_data{'endtime'};
1.154 albertel 1505: } else {
1506: &Apache::lonxml::debug("not time ".$slot_data{'endtime'});
1507: next;
1.148 albertel 1508: }
1509: } else {
1510: my $due_date = &Apache::lonhomework::due_date('0',$symb);
1.154 albertel 1511: if ($due_date < time) {
1.148 albertel 1512: $end_time = $due_date;
1.154 albertel 1513: } else {
1514: &Apache::lonxml::debug("not time $due_date");
1515: next;
1.148 albertel 1516: }
1517: }
1518:
1.98 albertel 1519: if (exists($queuedata->{"$key\0locked"})) {
1.33 albertel 1520: &Apache::lonxml::debug("someone already has um.");
1.15 albertel 1521: next;
1522: }
1.148 albertel 1523: push(@possible,[$key,$end_time]);
1.98 albertel 1524: }
1525: if (@possible) {
1526: # sort entries in order by slot end time
1527: @possible = sort { $a->[1] <=> $b->[1] } @possible;
1.137 albertel 1528: # pick one of the entries in the top 10% in small queues and one
1529: # of the first ten entries in large queues
1.139 albertel 1530: #my $ten_percent = int($#possible * 0.1);
1531: #if ($ten_percent < 1 ) { $ten_percent = 1; }
1532: #if ($ten_percent > 10) { $ten_percent = 10; }
1533: #my $max=($#possible < $ten_percent) ? $#possible : $ten_percent;
1.137 albertel 1534:
1.139 albertel 1535: #return $possible[int(rand($max))][0];
1536: return $possible[0][0];
1.14 albertel 1537: }
1538: return undef;
1539: }
1540:
1.15 albertel 1541: sub find_mid_grade {
1.30 albertel 1542: my ($queue,$symb,$cdom,$cnum)=@_;
1.158 www 1543: my $todo=&unescape($env{'form.gradingkey'});
1.138 albertel 1544: my $me=$env{'user.name'}.':'.$env{'user.domain'};
1.15 albertel 1545: if ($todo) {
1.30 albertel 1546: my $who=&queue_key_locked($queue,$todo,$cdom,$cnum);
1.15 albertel 1547: if ($who eq $me) { return $todo; }
1548: }
1549: my $regexp="^$symb\0.*\0locked\$";
1.30 albertel 1550: my %locks=&Apache::lonnet::dump($queue,$cdom,$cnum,$regexp);
1.15 albertel 1551: foreach my $key (keys(%locks)) {
1552: my $who=$locks{$key};
1553: if ($who eq $me) {
1554: $todo=$key;
1555: $todo=~s/\0locked$//;
1556: return $todo;
1557: }
1558: }
1559: return undef;
1560: }
1561:
1.32 albertel 1562: sub lock_key {
1563: my ($queue,$todo)=@_;
1.138 albertel 1564: my $me=$env{'user.name'}.':'.$env{'user.domain'};
1.32 albertel 1565: my (undef,$cid)=&Apache::lonxml::whichuser();
1566: my $cnum=$env{'course.'.$cid.'.num'};
1567: my $cdom=$env{'course.'.$cid.'.domain'};
1568: my $success=&Apache::lonnet::newput($queue,{"$todo\0locked"=> $me},
1569: $cdom,$cnum);
1.33 albertel 1570: &Apache::lonxml::debug("success $success $todo");
1.32 albertel 1571: if ($success eq 'ok') {
1572: return 1;
1573: }
1574: return 0;
1575: }
1576:
1.86 albertel 1577: sub get_queue_symb_status {
1.85 albertel 1578: my ($queue,$symb,$cdom,$cnum) = @_;
1579: if (!defined($cdom) || !defined($cnum)) {
1580: my (undef,$cid)=&Apache::lonxml::whichuser();
1581: $cnum=$env{'course.'.$cid.'.num'};
1582: $cdom=$env{'course.'.$cid.'.domain'};
1583: }
1.157 albertel 1584: my $classlist=&get_limited_classlist();
1.156 albertel 1585:
1.85 albertel 1586: my $regexp="^$symb\0";
1587: my %queue=&Apache::lonnet::dump($queue,$cdom,$cnum,$regexp);
1588: my ($tmp)=%queue;
1589: if ($tmp=~/^error: 2 /) { return; }
1590: my @users;
1591: foreach my $key (sort(keys(%queue))) {
1592: next if ($key=~/locked$/);
1593: next if ($key=~/timestamp$/);
1594: my ($symb,$uname,$udom) = &decode_queue_key($key);
1.156 albertel 1595: next if (!defined($classlist->{$uname.':'.$udom}));
1.85 albertel 1596: push(@users,"$uname:$udom");
1597: }
1598: return @users;
1599: }
1600:
1.14 albertel 1601: sub get_from_queue {
1.30 albertel 1602: my ($queue)=@_;
1.14 albertel 1603: my $result;
1604: my ($symb,$cid,$udom,$uname)=&Apache::lonxml::whichuser();
1605: my $cnum=$env{'course.'.$cid.'.num'};
1606: my $cdom=$env{'course.'.$cid.'.domain'};
1.32 albertel 1607: my $todo=&find_mid_grade($queue,$symb,$cdom,$cnum);
1.33 albertel 1608: &Apache::lonxml::debug("found ".join(':',&decode_queue_key($todo)));
1.16 albertel 1609: if ($todo) { return $todo; }
1.95 albertel 1610: my $attempts=0;
1.156 albertel 1611:
1.157 albertel 1612: my $classlist=&get_limited_classlist();
1.156 albertel 1613:
1.14 albertel 1614: while (1) {
1.95 albertel 1615: if ($attempts > 2) {
1616: # tried twice to get a queue entry, giving up
1617: return (undef,'unable');
1618: }
1.14 albertel 1619: my $starttime=time;
1.83 albertel 1620: &Apache::lonnet::cput($queue,{"$symb\0timestamp"=>$starttime},
1621: $cdom,$cnum);
1.33 albertel 1622: &Apache::lonxml::debug("$starttime");
1.14 albertel 1623: my $regexp="^$symb\0queue\0";
1.156 albertel 1624: #my $range= ($attempts < 1 ) ? '0-100' : '0-400';
1.97 albertel 1625:
1.98 albertel 1626: my %queue=&Apache::lonnet::dump($queue,$cdom,$cnum,$regexp);
1.33 albertel 1627: #make a pass looking for a user _not_ in my section
1.14 albertel 1628: if ($env{'request.course.sec'}) {
1.33 albertel 1629: &Apache::lonxml::debug("sce");
1.30 albertel 1630: $todo=&pick_from_queue_data($queue,$env{'request.course.sec'},
1.156 albertel 1631: \%queue,$cdom,$cnum,$classlist);
1.33 albertel 1632: &Apache::lonxml::debug("sce $todo");
1.14 albertel 1633: }
1.33 albertel 1634: # no one _not_ in our section so look for any user that is
1635: # ready for grading
1.14 albertel 1636: if (!$todo) {
1.33 albertel 1637: &Apache::lonxml::debug("no sce");
1.156 albertel 1638: $todo=&pick_from_queue_data($queue,undef,\%queue,$cdom,$cnum,
1639: $classlist);
1.33 albertel 1640: &Apache::lonxml::debug("no sce $todo");
1.14 albertel 1641: }
1642: # no user to grade
1643: if (!$todo) { last; }
1.33 albertel 1644: &Apache::lonxml::debug("got $todo");
1.14 albertel 1645: # otherwise found someone so lets try to lock them
1.32 albertel 1646: # unless someone else already picked them
1.95 albertel 1647: if (!&lock_key($queue,$todo)) {
1648: $attempts++;
1649: next;
1650: }
1.14 albertel 1651: my (undef,$endtime)=
1.30 albertel 1652: &Apache::lonnet::get($queue,["$symb\0timestamp"],
1.14 albertel 1653: $cdom,$cnum);
1.33 albertel 1654: &Apache::lonxml::debug("emd $endtime");
1.14 albertel 1655: # someone else already modified the queue,
1656: # perhaps our picked user wass already fully graded between
1657: # when we picked him and when we locked his record? so lets
1658: # double check.
1659: if ($endtime != $starttime) {
1660: my ($key,$value)=
1.30 albertel 1661: &Apache::lonnet::get($queue,["$todo"],
1.14 albertel 1662: $cdom,$cnum);
1.33 albertel 1663: &Apache::lonxml::debug("check $key .. $value");
1.14 albertel 1664: if ($key eq $todo && ref($value)) {
1665: } else {
1.30 albertel 1666: &Apache::lonnet::del($queue,["$todo\0locked"],
1.14 albertel 1667: $cdom,$cnum);
1.33 albertel 1668: &Apache::lonxml::debug("del");
1.95 albertel 1669: $attempts++;
1.14 albertel 1670: next;
1671: }
1672: }
1.33 albertel 1673: &Apache::lonxml::debug("last $todo");
1.14 albertel 1674: last;
1675: }
1676: return $todo;
1677: }
1678:
1.49 albertel 1679: sub select_user {
1680: my ($symb,$cid)=&Apache::lonxml::whichuser();
1681:
1.59 albertel 1682: my @chosen_sections=
1683: &Apache::loncommon::get_env_multiple('form.chosensections');
1.156 albertel 1684:
1685: my $classlist = &get_limited_classlist(\@chosen_sections);
1.63 albertel 1686:
1687: my $result;
1688: if (!(grep(/^all$/,@chosen_sections))) {
1689: $result.='<p> Showing only sections <tt>'.join(', ',@chosen_sections).
1690: '</tt>.</p> '."\n";
1691: }
1.159 albertel 1692: $result.=&Apache::loncommon::start_data_table();
1.49 albertel 1693:
1.156 albertel 1694: foreach my $student (sort {lc($classlist->{$a}[&Apache::loncoursedata::CL_FULLNAME()]) cmp lc($classlist->{$b}[&Apache::loncoursedata::CL_FULLNAME()]) } (keys(%$classlist))) {
1.49 albertel 1695: my ($uname,$udom) = split(/:/,$student);
1.59 albertel 1696:
1.84 albertel 1697: my $cnum=$env{'course.'.$cid.'.num'};
1698: my $cdom=$env{'course.'.$cid.'.domain'};
1.88 albertel 1699: my %status = &get_student_status($symb,$cdom,$cnum,$udom,$uname,
1700: 'Task');
1.49 albertel 1701: my $queue = 'none';
1.58 albertel 1702: my $cannot_grade;
1703: if ($status{'reviewqueue'} =~ /^(in_progress|enqueue)$/) {
1.49 albertel 1704: $queue = 'reviewqueue';
1.58 albertel 1705: if ($status{'reviewqueue'} eq 'in_progress') {
1706: $cannot_grade=1;
1707: }
1708: } elsif ($status{'gradingqueue'} =~ /^(in_progress|enqueue)$/) {
1.49 albertel 1709: $queue = 'gradingqueue';
1.58 albertel 1710: if ($status{'gradingqueue'} eq 'in_progress') {
1711: $cannot_grade=1;
1712: }
1.49 albertel 1713: }
1714: my $todo =
1.158 www 1715: &escape(&encode_queue_key($symb,$udom,$uname));
1.58 albertel 1716: if ($cannot_grade) {
1.159 albertel 1717: $result.=&Apache::loncommon::start_data_table_row().
1718: '<td> </td><td>'.$classlist->{$student}[&Apache::loncoursedata::CL_FULLNAME()].
1.58 albertel 1719: '</td><td>';
1720: } else {
1.62 albertel 1721: my $seclist;
1722: foreach my $sec (@chosen_sections) {
1723: $seclist.='<input type="hidden" name="chosensections"
1724: value="'.$sec.'" />';
1725: }
1.159 albertel 1726: $result.=&Apache::loncommon::start_data_table_row();
1.58 albertel 1727: $result.=<<RESULT;
1.49 albertel 1728: <td>
1.115 albertel 1729: <form style="display: inline" method="post">
1.49 albertel 1730: <input type="hidden" name="gradingkey" value="$todo" />
1731: <input type="hidden" name="queue" value="$queue" />
1732: <input type="hidden" name="webgrade" value="no" />
1.52 albertel 1733: <input type="hidden" name="regrade" value="yes" />
1.62 albertel 1734: <input type="submit" name="submit" value="Regrade" />
1735: $seclist
1.49 albertel 1736: </form>
1.155 albertel 1737: <td>$classlist->{$student}[&Apache::loncoursedata::CL_FULLNAME()] <tt>($student)</tt></td>
1.49 albertel 1738: <td>
1739: RESULT
1.58 albertel 1740: }
1.49 albertel 1741: if ($status{'status'} eq 'pass') {
1742: $result .= '<font color="green">'.&mt('Passed').'</font>';
1743: } elsif ($status{'status'} eq 'fail') {
1744: $result .= '<font color="red">'.&mt('Failed').'</font>';
1745: } elsif ($status{'status'} eq 'review') {
1746: $result .= '<font color="blue">'.&mt('Under Review').'</font>';
1747: } elsif ($status{'status'} eq 'ungraded') {
1748: $result .= &mt('Ungraded');
1749: } elsif ($status{'status'} ne '') {
1750: $result .= '<font color="orange">'.&mt('Unknown Status').'</font>';
1751: } else {
1752: $result.=" ";
1753: }
1754: if ($status{'version'}) {
1755: $result .= ' '.&mt('Version').' '.$status{'version'};
1756: }
1.101 albertel 1757: if ($status{'grader'}) {
1758: $result .= ' '.&mt('(Graded by [_1])',$status{'grader'}).' ';
1759: }
1.49 albertel 1760: $result.= '</td><td>';
1761: if ($status{'reviewqueue'} eq 'enqueued') {
1762: $result .= &mt('Awaiting Review');
1763: } elsif ($status{'reviewqueue'} eq 'locked') {
1764: $result .= &mt('Under Review');
1.58 albertel 1765: } elsif ($status{'reviewqueue'} eq 'in_progress') {
1766: $result .= &mt('Still being worked on.');
1.49 albertel 1767: } elsif ($status{'gradingqueue'} eq 'enqueued') {
1768: $result .= &mt('Awaiting Grading');
1769: } elsif ($status{'gradingqueue'} eq 'locked') {
1770: $result .= &mt('Being Graded');
1.58 albertel 1771: } elsif ($status{'gradingqueue'} eq 'in_progress') {
1772: $result .= &mt('Still being worked on.');
1.49 albertel 1773: } else {
1774: $result.=" ";
1775: }
1.159 albertel 1776: $result.= '</td>'.&Apache::loncommon::end_data_table_row();
1.49 albertel 1777: }
1.159 albertel 1778: $result.=&Apache::loncommon::end_data_table();
1.49 albertel 1779: return $result;
1780: }
1781:
1782: sub get_student_status {
1.86 albertel 1783: my ($symb,$cdom,$cnum,$udom,$uname,$type)=@_;
1784:
1785: my %status;
1786:
1787: if ($type eq 'Task') {
1788: my %record = &Apache::lonnet::restore($symb,$env{'request.course.id'},
1.49 albertel 1789: $udom,$uname);
1.89 albertel 1790: $status{'status'}=$record{'resource.0.status'};
1791: $status{'version'}=$record{'resource.0.version'};
1792: $status{'grader'}=$record{'resource.0.regrader'};
1.86 albertel 1793: }
1794: $status{'reviewqueue'}=
1795: &check_queue_for_key($cdom,$cnum,'reviewqueue',
1796: &encode_queue_key($symb,$udom,$uname));
1797: $status{'gradingqueue'}=
1798: &check_queue_for_key($cdom,$cnum,'gradingqueue',
1799: &encode_queue_key($symb,$udom,$uname));
1.49 albertel 1800: return %status;
1801: }
1802:
1.1 albertel 1803: sub start_ClosingParagraph {
1804: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
1805: my $result;
1806: if ($target eq 'web') {
1.13 albertel 1807: } elsif ($target eq 'webgrade') {
1808: &Apache::lonxml::startredirection();
1.1 albertel 1809: }
1810: return $result;
1811: }
1812:
1813: sub end_ClosingParagraph {
1814: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
1815: my $result;
1816: if ($target eq 'web') {
1.13 albertel 1817: } elsif ($target eq 'webgrade') {
1818: &Apache::lonxml::endredirection();
1.1 albertel 1819: }
1820: return $result;
1821: }
1822:
1.19 albertel 1823: sub get_id {
1824: my ($parstack,$safeeval)=@_;
1825: my $id=&Apache::lonxml::get_param('id',$parstack,$safeeval);
1826: if (!$id) { $id=$Apache::lonxml::curdepth; }
1827: return $id;
1828: }
1829:
1.1 albertel 1830: my %dimension;
1.162 albertel 1831: sub start_Setup {
1832: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
1833: undef(%dimension);
1834: my $dim_id=&get_id($parstack,$safeeval);
1835: $Apache::bridgetask::dimension=$dim_id;
1836: undef(@Apache::bridgetask::instance);
1837: &Apache::lonxml::startredirection();
1838: return &internal_location($dim_id);
1839: }
1.151 albertel 1840: sub start_Question { return &start_Dimension(@_); }
1.1 albertel 1841: sub start_Dimension {
1842: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
1843: undef(%dimension);
1.19 albertel 1844: my $dim_id=&get_id($parstack,$safeeval);
1.9 albertel 1845: $Apache::bridgetask::dimension=$dim_id;
1846: push(@Apache::bridgetask::dimensionlist,$dim_id);
1847: undef(@Apache::bridgetask::instance);
1.20 albertel 1848: $Apache::bridgetask::dimensionmandatory{$dim_id}=
1849: &Apache::lonxml::get_param('Mandatory',$parstack,$safeeval);
1.54 albertel 1850: &Apache::lonxml::startredirection();
1851: return &internal_location($dim_id);
1.1 albertel 1852: }
1853:
1.160 albertel 1854: sub start_QuestionText {
1855: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1856: my $dim_id=$Apache::bridgetask::dimension;
1857: my $text=&Apache::lonxml::get_all_text('/questiontext',$parser,$style);
1858: if ($target eq 'grade' || $target eq 'web' || $target eq 'webgrade') {
1859: $dimension{'questiontext'}=$text;
1860: }
1861: return '';
1862: }
1863:
1864: sub end_QuestionText {
1865: return '';
1866: }
1867:
1.13 albertel 1868: sub get_instance {
1.75 albertel 1869: my ($dim)=@_;
1870: my $rand_alg=&Apache::lonnet::get_rand_alg();
1871: if (!$rand_alg || $rand_alg eq '32bit' || $rand_alg eq '64bit' ||
1872: $rand_alg eq '64bit2' || $rand_alg eq '64bit3' ||
1873: $rand_alg eq '64bit4' ) {
1874: &Apache::response::pushrandomnumber();
1875: my @order=&Math::Random::random_permutation(@{$dimension{'instances'}});
1876: my $num=@order;
1877: my $version=&get_version();
1878: my $which=($version-1)%$num;
1879: return $order[$which];
1880: } else {
1881: my ($version,$previous) = &get_version();
1882: my $instance =
1883: $Apache::lonhomework::history{"resource.$version.0.$dim.instance"};
1884: if (defined($instance)) { return $instance; }
1885:
1886: &Apache::response::pushrandomnumber();
1887: my @instances = @{$dimension{'instances'}};
1888: # remove disabled instances
1889: for (my $i=0; $i < $#instances; $i++) {
1890: if ($dimension{$instances[$i].'.disabled'}) {
1891: splice(@instances,$i,1);
1892: $i--;
1893: }
1894: }
1895: @instances = &Math::Random::random_permutation(@instances);
1896: $instance = $instances[($version-1)%scalar(@instances)];
1.150 albertel 1897: if ($version =~ /^\d$/) {
1898: $Apache::lonhomework::results{"resource.$version.0.$dim.instance"} =
1899: $instance;
1900: $Apache::lonhomework::results{'INTERNAL_store'} = 1;
1901: }
1.75 albertel 1902: &Apache::response::poprandomnumber();
1903: return $instance;
1904: }
1.13 albertel 1905: }
1906:
1.18 albertel 1907: {
1908: my $last_link;
1.122 albertel 1909: sub link {
1.151 albertel 1910: my ($id) = @_;
1911: $id =~ s/\./_/g;
1912: return 'LC_GRADING_criteria_'.$id;
1.122 albertel 1913: }
1.151 albertel 1914: sub end_Question { return &end_Dimension(@_); }
1.18 albertel 1915: sub end_Dimension {
1916: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
1.54 albertel 1917: my $result=&Apache::lonxml::endredirection();
1.25 albertel 1918: my $dim=&get_id($parstack,$safeeval);
1.75 albertel 1919: my $instance=&get_instance($dim);
1.25 albertel 1920: my $version=&get_version();
1.18 albertel 1921: if ($target eq 'web') {
1.47 albertel 1922: @Apache::scripttag::parser_env = @_;
1923: $result.=&Apache::scripttag::xmlparse($dimension{'intro'});
1.76 albertel 1924: my @instances = $instance;
1925: if (&Apache::response::showallfoils()) {
1926: @instances = @{$dimension{'instances'}};
1927: }
1.160 albertel 1928: my $shown_question_text;
1.76 albertel 1929: foreach my $instance (@instances) {
1930: @Apache::scripttag::parser_env = @_;
1931: $result.=&Apache::scripttag::xmlparse($dimension{$instance.'.text'});
1.160 albertel 1932: @Apache::scripttag::parser_env = @_;
1933: $result.=&Apache::scripttag::xmlparse($dimension{'questiontext'});
1.89 albertel 1934: if ($Apache::lonhomework::history{"resource.$version.0.status"} eq 'pass' ||
1935: $Apache::lonhomework::history{"resource.$version.0.status"} eq 'fail') {
1.76 albertel 1936:
1.89 albertel 1937: my $dim_status=$Apache::lonhomework::history{"resource.$version.0.$dim.status"};
1.76 albertel 1938: my $mandatory='Mandatory';
1939: if ($Apache::bridgetask::dimensionmandatory{$dim} eq 'N') {
1940: $mandatory='Optional';
1941: }
1.116 albertel 1942: my $dim_info="<div class='LC_$dim_status LC_question_grade'>\n";
1.76 albertel 1943: if ($dim_status eq 'pass') {
1944: $dim_info.='<h3>Question : you passed this '.$mandatory.' question</h3>';
1.54 albertel 1945: }
1.76 albertel 1946: if ($dim_status eq 'fail') {
1947: $dim_info.='<h3>Question : you did not pass this '.$mandatory.' question</h3>';
1.53 albertel 1948: }
1.76 albertel 1949: my $man_count=0;
1950: my $man_passed=0;
1951: my $opt_count=0;
1952: my $opt_passed=0;
1.151 albertel 1953: foreach my $id ( @{$dimension{$instance.'.criterias'}},
1954: @{$dimension{'criterias'}} ) {
1955: if ($dimension{'criteria.'.$id.'.mandatory'}
1.76 albertel 1956: eq 'N') {
1957: $opt_count++;
1.151 albertel 1958: if ($Apache::lonhomework::history{"resource.$version.0.$dim.$id.status"} eq 'pass') {
1.76 albertel 1959: $opt_passed++;
1960: }
1961: } else {
1962: $man_count++;
1.89 albertel 1963: if ($Apache::lonhomework::history{"resource.$version.0.$dim.$instance.$id.status"} eq 'pass') {
1.76 albertel 1964: $man_passed++;
1965: }
1966: }
1.22 albertel 1967: }
1.76 albertel 1968: if ($man_passed eq $man_count) { $man_passed='all'; }
1.151 albertel 1969:
1.76 albertel 1970: my $opt_req=$dimension{$instance.'.optionalrequired'};
1.151 albertel 1971: if ($opt_req !~ /\S/) {
1972: $opt_req=
1973: &Apache::lonxml::get_param('OptionalRequired',
1974: $parstack,$safeeval);
1975: if ($opt_req !~ /\S/) { $opt_req = 0; }
1976: }
1.76 albertel 1977: $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>";
1978:
1979: my $internal_location=&internal_location($dim);
1980: $result=~s/\Q$internal_location\E/$dim_info/;
1981:
1.151 albertel 1982: foreach my $id (@{$dimension{$instance.'.criterias'}},
1983: @{$dimension{'criterias'}}) {
1984: my $status=$Apache::lonhomework::history{"resource.$version.0.$dim.$id.status"};
1985: my $comment=$Apache::lonhomework::history{"resource.$version.0.$dim.$id.comment"};
1986: my $mandatory=($dimension{'criteria.'.$id.'.mandatory'} ne 'N');
1.76 albertel 1987: if ($mandatory) {
1988: $mandatory='Mandatory';
1989: } else {
1990: $mandatory='Optional';
1991: }
1992: if ($status eq 'fail') {
1993: } elsif ($status eq 'pass') {
1994: } else {
1995: &Apache::lonxml::error("Student viewing a graded bridgetask was shown a status of $status");
1996: }
1997: my $status_display=$status;
1998: $status_display=~s/^([a-z])/uc($1)/e;
1.116 albertel 1999: $result.=
2000: '<div class="LC_'.$status.' LC_criteria"><h4>'
2001: .$mandatory.' Criteria</h4><p>';
1.76 albertel 2002: @Apache::scripttag::parser_env = @_;
1.151 albertel 2003: $result.=&Apache::scripttag::xmlparse($dimension{'criteria.'.$id});
1.116 albertel 2004: $result.='</p><p class="LC_grade">'.$status_display.'</p>';
1.151 albertel 2005: if ($Apache::lonhomework::history{"resource.$version.0.$dim.$id.comment"}) {
2006: $result.='<p class="LC_comment">'.&mt('Comment: [_1]',$Apache::lonhomework::history{"resource.$version.0.$dim.$id.comment"}).'</p>';
1.76 albertel 2007: }
2008: $result.='</div>';
1.22 albertel 2009: }
2010: }
2011: }
1.18 albertel 2012: } elsif ($target eq 'webgrade') {
1.47 albertel 2013: # in case of any side effects that we need
2014: @Apache::scripttag::parser_env = @_;
2015: &Apache::scripttag::xmlparse($dimension{'intro'});
2016: @Apache::scripttag::parser_env = @_;
2017: &Apache::scripttag::xmlparse($dimension{$instance.'.text'});
1.160 albertel 2018: @Apache::scripttag::parser_env = @_;
2019: &Apache::scripttag::xmlparse($dimension{'questiontext'});
1.151 albertel 2020: foreach my $id (@{$dimension{$instance.'.criterias'}},
2021: @{$dimension{'criterias'}} ) {
2022: my $link=&link($id);
2023: my $status=$Apache::lonhomework::history{"resource.$version.0.$dim.$id.status"};
1.120 albertel 2024: $result.='<div class="LC_GRADING_criteria" id="'.$link.'">'."\n".
1.136 albertel 2025: '<div class="LC_GRADING_criteriatext" id="next_'.$last_link.'">'."\n";
1.47 albertel 2026: @Apache::scripttag::parser_env = @_;
1.151 albertel 2027: $result.=&Apache::scripttag::xmlparse($dimension{'criteria.'.$id});
1.111 albertel 2028: $result.='</div>'."\n".
1.151 albertel 2029: #$dimension{'criteria.'.$id}.
1.120 albertel 2030: '<div class="LC_GRADING_grade">'."\n".
2031: '<label class="LC_GRADING_ungraded"><input type="radio" name="HWVAL_'.$link.'" value="ungraded" '.($status eq 'ungraded' || !$status ? 'checked="checked"':'').' />'.&mt('Ungraded').'</label>'."\n".
2032: '<label class="LC_GRADING_fail"><input type="radio" name="HWVAL_'.$link.'" value="fail" '.($status eq 'fail' ? 'checked="checked"':'').' />'.&mt('Fail').'</label>'."\n".
2033: '<label class="LC_GRADING_pass"><input type="radio" name="HWVAL_'.$link.'" value="pass" '.($status eq 'pass' ? 'checked="checked"':'').' />'.&mt('Pass').'</label>'."\n".
2034: '<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 2035: '</div>'."\n".
1.120 albertel 2036: '<label class="LC_GRADING_comment">'.&mt('Additional Comment for Student')."\n".
1.151 albertel 2037: '<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 2038: '</label>'."\n".
1.120 albertel 2039: '<ul class="LC_GRADING_navbuttons">'."\n".
1.111 albertel 2040: '<li><a href="#'.$last_link.'">Prev</a></li>'."\n".
2041: '<li><a href="#next_'.$link.'">Next</a></li>'."\n".
2042: '</ul>'."\n".
2043: '</div>'."\n";
1.151 albertel 2044: $result.=&grading_history($version,$dim,$id);
1.18 albertel 2045: $last_link=$link;
2046: }
1.22 albertel 2047: } elsif ($target eq 'grade' && $env{'form.webgrade'}) {
1.19 albertel 2048: my $optional_passed=0;
1.20 albertel 2049: my $mandatory_failed=0;
2050: my $ungraded=0;
2051: my $review=0;
1.153 albertel 2052:
2053: @Apache::scripttag::parser_env = @_;
2054: $result.=&Apache::scripttag::xmlparse($dimension{'intro'});
1.160 albertel 2055: @Apache::scripttag::parser_env = @_;
2056: $result.=&Apache::scripttag::xmlparse($dimension{$instance.'.text'});
2057: @Apache::scripttag::parser_env = @_;
2058: &Apache::scripttag::xmlparse($dimension{'questiontext'});
2059:
1.151 albertel 2060: foreach my $id (@{$dimension{$instance.'.criterias'}},
2061: @{$dimension{'criterias'}}) {
2062: my $link=&link($id);
2063: my $status=$Apache::lonhomework::results{"resource.$version.0.$dim.$id.status"}=$env{'form.HWVAL_'.$link};
2064: $Apache::lonhomework::results{"resource.$version.0.$dim.$id.comment"}=$env{'form.HWVAL_comment_'.$link};
2065: my $mandatory=($dimension{'criteria.'.$id.'.mandatory'} ne 'N');
1.20 albertel 2066: if ($status eq 'pass') {
2067: if (!$mandatory) { $optional_passed++; }
2068: } elsif ($status eq 'fail') {
2069: if ($mandatory) { $mandatory_failed++; }
1.21 albertel 2070: } elsif ($status eq 'review') {
2071: $review++;
1.20 albertel 2072: } elsif ($status eq 'ungraded') {
2073: $ungraded++;
1.21 albertel 2074: } else {
1.47 albertel 2075: $ungraded++;
1.19 albertel 2076: }
2077: }
1.151 albertel 2078: # FIXME optional required can apply to only <instance> right now...
2079: my $opt_req=$dimension{$instance.'.optionalrequired'};
2080: if ($opt_req !~ /\S/) {
2081: $opt_req=
2082: &Apache::lonxml::get_param('OptionalRequired',
2083: $parstack,$safeeval);
2084: if ($opt_req !~ /\S/) { $opt_req = 0; }
2085: }
2086: if ($optional_passed < $opt_req) {
1.20 albertel 2087: $mandatory_failed++;
2088: }
1.21 albertel 2089: &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 2090: if ($review) {
1.89 albertel 2091: $Apache::lonhomework::results{"resource.$version.0.$dim.status"}=
1.22 albertel 2092: 'review';
1.20 albertel 2093: } elsif ($ungraded) {
1.89 albertel 2094: $Apache::lonhomework::results{"resource.$version.0.$dim.status"}=
1.22 albertel 2095: 'ungraded';
1.20 albertel 2096: } elsif ($mandatory_failed) {
1.89 albertel 2097: $Apache::lonhomework::results{"resource.$version.0.$dim.status"}=
1.22 albertel 2098: 'fail';
1.20 albertel 2099: } else {
1.91 albertel 2100: $Apache::lonhomework::results{"resource.$version.0.$dim.status"}=
1.22 albertel 2101: 'pass';
1.20 albertel 2102: }
1.69 albertel 2103: } else {
2104: # any other targets no output
2105: undef($result);
1.13 albertel 2106: }
1.18 albertel 2107: return $result;
1.1 albertel 2108: }
1.162 albertel 2109:
2110: sub end_Setup {
2111: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
2112: my $result=&Apache::lonxml::endredirection();
2113: my $dim=&get_id($parstack,$safeeval);
2114: my $instance=&get_instance($dim);
2115: my $version=&get_version();
2116: if ($target eq 'web') {
2117: @Apache::scripttag::parser_env = @_;
2118: $result.=&Apache::scripttag::xmlparse($dimension{'intro'});
2119: my @instances = $instance;
2120: if (&Apache::response::showallfoils()) {
2121: @instances = @{$dimension{'instances'}};
2122: }
2123: foreach my $instance (@instances) {
2124: @Apache::scripttag::parser_env = @_;
2125: $result.=&Apache::scripttag::xmlparse($dimension{$instance.'.text'});
2126: @Apache::scripttag::parser_env = @_;
2127: $result.=&Apache::scripttag::xmlparse($dimension{'questiontext'});
2128: }
2129: } elsif ($target eq 'webgrade'
2130: || $target eq 'grade' && $env{'form.webgrade'}) {
2131: # in case of any side effects that we need
2132: @Apache::scripttag::parser_env = @_;
2133: &Apache::scripttag::xmlparse($dimension{'intro'});
2134: @Apache::scripttag::parser_env = @_;
2135: &Apache::scripttag::xmlparse($dimension{$instance.'.text'});
2136: @Apache::scripttag::parser_env = @_;
2137: &Apache::scripttag::xmlparse($dimension{'questiontext'});
2138: } else {
2139: # any other targets no output
2140: undef($result);
2141: }
2142: return $result;
2143: }
1.1 albertel 2144: }
2145:
1.113 albertel 2146: sub grading_history {
1.151 albertel 2147: my ($version,$dim,$id) = @_;
1.113 albertel 2148: if (!&Apache::lonnet::allowed('mgq',$env{'request.course.id'})) {
2149: return '';
2150: }
2151: my ($result,$grader);
1.151 albertel 2152: my $scope="resource.$version.0.$dim.$id";
1.113 albertel 2153: foreach my $t (1..$Apache::lonhomework::history{'version'}) {
2154: if (exists($Apache::lonhomework::history{$t.':resource.0.regrader'})) {
2155: my ($gname,$gdom) =
1.138 albertel 2156: split(':',$Apache::lonhomework::history{$t.':resource.0.regrader'});
1.113 albertel 2157: my $fullname = &Apache::loncommon::plainname($gname,$gdom);
2158: $grader = &Apache::loncommon::aboutmewrapper($fullname,
2159: $gname,$gdom);
2160: }
2161: my $entry;
2162: if (exists($Apache::lonhomework::history{"$t:$scope.status"})) {
2163: $entry.="<tt>".$Apache::lonhomework::history{"$t:$scope.status"}.'</tt>';
2164: }
2165: if (exists($Apache::lonhomework::history{"$t:$scope.comment"})) {
2166: $entry.=' comment: "'.$Apache::lonhomework::history{"$t:$scope.comment"}.'"';
2167: }
2168: if ($entry) {
2169: $result.= "<li>$grader : $entry </li>";
2170: }
2171: }
2172: if ($result) {
1.120 albertel 2173: return '<ul class="LC_GRADING_pastgrading">'.$result.'</ul>';
1.113 albertel 2174: }
2175: return '';
2176: }
2177:
1.1 albertel 2178: sub start_IntroParagraph {
1.87 albertel 2179: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.1 albertel 2180: my $result;
1.153 albertel 2181: if ($target eq 'grade' || $target eq 'web' || $target eq 'webgrade') {
1.151 albertel 2182: if ($tagstack->[-2] eq 'Dimension' || $tagstack->[-2] eq 'Question' ) {
2183: $dimension{'intro'}=
2184: &Apache::lonxml::get_all_text('/introparagraph',
2185: $parser,$style);
2186: } elsif ($tagstack->[-2] eq 'Task' && $target eq 'webgrade') {
1.127 albertel 2187: &Apache::lonxml::startredirection();
1.1 albertel 2188: }
1.47 albertel 2189:
1.1 albertel 2190: }
2191: return $result;
2192: }
2193:
2194: sub end_IntroParagraph {
1.127 albertel 2195: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.128 albertel 2196: if ($tagstack->[-2] eq 'Task' && $target eq 'webgrade') {
1.127 albertel 2197: my $result = &Apache::lonxml::endredirection();
2198: }
1.1 albertel 2199: }
2200:
2201: sub start_Instance {
2202: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
1.19 albertel 2203: my $id=&get_id($parstack,$safeeval);
2204: push(@{$dimension{'instances'}},$id);
2205: push(@Apache::bridgetask::instance,$id);
2206: push(@Apache::bridgetask::instancelist,$id);
1.20 albertel 2207: $dimension{$id.'.optionalrequired'}=
1.19 albertel 2208: &Apache::lonxml::get_param('OptionalRequired',$parstack,$safeeval);
1.75 albertel 2209: my $disabled = &Apache::lonxml::get_param('Disabled',$parstack,$safeeval);
2210: if (lc($disabled) eq 'yes') {
2211: $dimension{$id.'.disabled'}='1';
2212: }
1.1 albertel 2213: return '';
2214: }
2215:
2216: sub end_Instance {
2217: }
2218:
2219: sub start_InstanceText {
1.87 albertel 2220: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.47 albertel 2221: my $instance_id=$Apache::bridgetask::instance[-1];
1.87 albertel 2222: my $text=&Apache::lonxml::get_all_text('/instancetext',$parser,$style);
1.153 albertel 2223: if ($target eq 'grade' || $target eq 'web' || $target eq 'webgrade') {
1.47 albertel 2224: $dimension{$instance_id.'.text'}=$text;
1.1 albertel 2225: }
2226: return '';
2227: }
2228:
2229: sub end_InstanceText {
2230: return '';
2231: }
2232:
2233: sub start_Criteria {
1.87 albertel 2234: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
2235: my $criteria=&Apache::lonxml::get_all_text('/criteria',$parser,$style);
1.21 albertel 2236: if ($target eq 'web' || $target eq 'webgrade' || $target eq 'grade') {
1.19 albertel 2237: my $id=&get_id($parstack,$safeeval);
1.151 albertel 2238: if (&Apache::londefdef::is_inside_of($tagstack,'Instance')) {
2239: my $instance_id=$Apache::bridgetask::instance[-1];
2240: $dimension{"criteria.$instance_id.$id"}=$criteria;
2241: $dimension{"criteria.$instance_id.$id.mandatory"}=
2242: &Apache::lonxml::get_param('Mandatory',$parstack,$safeeval);
2243: push(@{$dimension{$instance_id.'.criterias'}},"$instance_id.$id");
2244: } else {
2245: $dimension{'criteria.'.$id}=$criteria;
2246: $dimension{'criteria.'.$id.'.mandatory'}=
2247: &Apache::lonxml::get_param('Mandatory',$parstack,$safeeval);
2248: push(@{$dimension{'criterias'}},$id);
2249: }
1.1 albertel 2250: }
2251: return '';
2252: }
2253:
1.47 albertel 2254: sub end_Criteria {
2255: }
2256:
1.4 albertel 2257: sub proctor_validation_screen {
2258: my ($slot) = @_;
2259: my (undef,undef,$domain,$user) = &Apache::lonxml::whichuser();
1.5 albertel 2260: my $url=&Apache::lonnet::studentphoto($domain,$user,'jpg');
1.44 albertel 2261: my $name=&Apache::loncommon::plainname($user,$domain);
2262:
1.4 albertel 2263: my $msg;
1.11 albertel 2264: if ($env{'form.proctorpassword'}) {
1.4 albertel 2265: $msg='<p><font color="red">'.&mt("Failed to authenticate the proctor.")
2266: .'</font></p>';
2267: }
1.47 albertel 2268: if (!$env{'form.proctordomain'}) { $env{'form.proctordomain'}=$domain; }
1.4 albertel 2269: my $result= (<<ENDCHECKOUT);
2270: <h2>Proctor Validation</h2>
2271: <p>Your room's proctor needs to validate your access to this resource.</p>
2272: $msg
1.115 albertel 2273: <form name="checkout" method="post" action="$env{'request.uri'}">
1.4 albertel 2274: <input type="hidden" name="validate" value="yes" />
2275: <input type="hidden" name="submitted" value="yes" />
2276: <table>
1.44 albertel 2277: <tr><td>Proctor's Username:</td><td><input type="string" name="proctorname" value="$env{'form.proctorname'}" /></td></tr>
1.4 albertel 2278: <tr><td>Password:</td><td><input type="password" name="proctorpassword" value="" /></td></tr>
1.46 albertel 2279: <tr><td>Proctor's Domain:</td><td><input type="string" name="proctordomain" value="$env{'form.proctordomain'}" /></td></tr>
1.4 albertel 2280: </table>
2281: <input type="submit" name="checkoutbutton" value="Validate" /><br />
1.44 albertel 2282: <table border="1">
2283: <tr><td>
2284: <table>
2285: <tr><td colspan="2">Student who should be logged in is:</td></tr>
2286: <tr><td>Name:</td><td>$name</td></tr>
1.45 albertel 2287: <tr><td>Student ID:</td><td>$env{'environment.id'}</td></tr>
1.138 albertel 2288: <tr><td>Usename</td><td>$user:$domain</td></tr>
1.44 albertel 2289: <tr><td colspan="2"><img src="$url" /></td></tr>
2290: </table>
2291: </tr></td>
2292: </table>
1.4 albertel 2293: </form>
2294: ENDCHECKOUT
2295: return $result;
2296: }
2297:
1.1 albertel 2298: 1;
2299: __END__
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>