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