Annotation of loncom/homework/bridgetask.pm, revision 1.158
1.1 albertel 1: # The LearningOnline Network with CAPA
2: # definition of tags that give a structure to a document
3: #
1.158 ! www 4: # $Id: bridgetask.pm,v 1.157 2006/05/25 20:08:18 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.151 albertel 46: &Apache::lonxml::register('Apache::bridgetask',('Task','IntroParagraph','Dimension','Question','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.33 albertel 1260: return "\n<h3>Current Queue - $queue</h3><table border='1'><tr><td>Empty</td></tr></table>";
1.31 albertel 1261: }
1.103 albertel 1262: my $title=&Apache::lonnet::gettitle($symb);
1263: $result.="\n<h3>Current Queue - $title $queue </h3><table border='1'><tr>";
1264: if ($with_selects) { $result.="<th>Status</th><th></th>"; }
1265: $result.="<th>user</th><th>data</th></tr>";
1.14 albertel 1266: foreach my $key (sort(keys(%queue))) {
1.59 albertel 1267: my ($symb,$uname,$udom) = &decode_queue_key($key);
1268: if (!defined($classlist->{$uname.':'.$udom})) { next; }
1.156 albertel 1269:
1270: my $section = $classlist->{$uname.':'.$udom}[&Apache::loncoursedata::CL_SECTION()];
1271:
1272: my $can_view=1;
1273: if (!$view
1274: || ($view_section && !$section)
1275: || ($view_section && $section && ($view_section ne $section))) {
1276: $can_view=0;
1277: }
1278:
1.32 albertel 1279: if ($key=~/locked$/ && !$with_selects) {
1.103 albertel 1280: $result.="<tr><td>$uname</td>";
1281: $result.='<td>'.$queue{$key}.'</td></tr>';
1.32 albertel 1282: } elsif ($key=~/timestamp$/ && !$with_selects) {
1.103 albertel 1283: $result.="<tr><td></td>";
1284: $result.='<td>'.
1.16 albertel 1285: &Apache::lonlocal::locallocaltime($queue{$key})."</td></tr>";
1.32 albertel 1286: } elsif ($key!~/(timestamp|locked)$/) {
1287: $result.="<tr>";
1.148 albertel 1288: my ($end_time,$slot_text);
1289: if (my $slot=&slotted_access($queue{$key})) {
1290: my %slot_data=&Apache::lonnet::get_slot($slot);
1291: $end_time = $slot_data{'endtime'};
1292: $slot_text = &mt('Slot: [_1]',$slot);
1293: } else {
1294: $end_time = &Apache::lonhomework::due_date('0',$symb);
1295: $slot_text = '';
1296: }
1.32 albertel 1297: if ($with_selects) {
1.158 ! www 1298: my $ekey=&escape($key);
1.103 albertel 1299: my ($action,$description,$status)=('select',&mt('Select'));
1.32 albertel 1300: if (exists($queue{"$key\0locked"})) {
1.138 albertel 1301: my $me=$env{'user.name'}.':'.$env{'user.domain'};
1.103 albertel 1302: $status=&mt('Locked by <tt>[_1]</tt>',$queue{"$key\0locked"});
1.32 albertel 1303: if ($me eq $queue{"$key\0locked"}) {
1304: ($action,$description)=('resume',&mt('Resume'));
1305: } else {
1306: ($action,$description)=('unlock',&mt('Unlock'));
1307: }
1308: }
1.62 albertel 1309: my $seclist;
1310: foreach my $sec (@chosen_sections) {
1311: $seclist.='<input type="hidden" name="chosensections"
1312: value="'.$sec.'" />';
1313: }
1.156 albertel 1314: if ($can_view && ($end_time ne '' && time > $end_time)) {
1.35 albertel 1315: $result.=(<<FORM);
1.103 albertel 1316: <td>$status</td>
1.32 albertel 1317: <td>
1.115 albertel 1318: <form style="display: inline" method="post">
1.32 albertel 1319: <input type="hidden" name="gradingkey" value="$ekey" />
1320: <input type="hidden" name="queue" value="$queue" />
1321: <input type="hidden" name="gradingaction" value="$action" />
1322: <input type="hidden" name="webgrade" value="no" />
1.33 albertel 1323: <input type="hidden" name="queuemode" value="selected" />
1.32 albertel 1324: <input type="submit" name="submit" value="$description" />
1.62 albertel 1325: $seclist
1.32 albertel 1326: </form>
1327: </td>
1328: FORM
1.156 albertel 1329: } elsif (!$can_view && ($end_time ne '' && time > $end_time)) {
1330: $result.='<td>'.&mt("Not gradable").'</td><td> </td>'
1.35 albertel 1331: } else {
1.148 albertel 1332: $result.='<td>'.&mt("In Progress").'</td><td> </td>'
1.35 albertel 1333: }
1.32 albertel 1334: }
1.156 albertel 1335: $result.= "<td>".$classlist->{$uname.':'.$udom}[&Apache::loncoursedata::CL_FULLNAME()].
1.138 albertel 1336: " <tt>($uname:$udom)</tt> </td>";
1.148 albertel 1337: $result.='<td>'.$slot_text.' End time: '.
1338: &Apache::lonlocal::locallocaltime($end_time).
1.20 albertel 1339: "</td></tr>";
1.16 albertel 1340: }
1.14 albertel 1341: }
1.15 albertel 1342: $result.="</table><hr />\n";
1.14 albertel 1343: return $result;
1344: }
1345:
1.34 albertel 1346: sub get_queue_counts {
1347: my ($queue)=@_;
1348: my $result;
1349: my ($symb,$cid,$udom,$uname)=&Apache::lonxml::whichuser();
1350: my $cnum=$env{'course.'.$cid.'.num'};
1351: my $cdom=$env{'course.'.$cid.'.domain'};
1.156 albertel 1352:
1.157 albertel 1353: my $classlist=&get_limited_classlist();
1.156 albertel 1354:
1.34 albertel 1355: my $regexp="^$symb\0";
1356: my %queue=&Apache::lonnet::dump($queue,$cdom,$cnum,$regexp);
1357: my ($tmp)=%queue;
1358: if ($tmp=~/^error: 2 /) {
1359: return (0,0,0);
1360: }
1361: my ($entries,$ready_to_grade,$locks)=(0,0,0);
1.96 albertel 1362: my %slot_cache;
1.34 albertel 1363: foreach my $key (sort(keys(%queue))) {
1.156 albertel 1364: my ($symb,$uname,$udom) = &decode_queue_key($key);
1365: if (!defined($classlist->{$uname.':'.$udom})) { next; }
1366:
1.34 albertel 1367: if ($key=~/locked$/) {
1368: $locks++;
1369: } elsif ($key=~/timestamp$/) {
1370: #ignore
1371: } elsif ($key!~/(timestamp|locked)$/) {
1372: $entries++;
1.148 albertel 1373: if (my $slot=&slotted_access($queue{$key})) {
1374: if (!exists($slot_cache{$slot})) {
1375: my %slot_data=&Apache::lonnet::get_slot($slot);
1376: $slot_cache{$slot} = \%slot_data;
1377: }
1378: if (time > $slot_cache{$slot}{'endtime'}) {
1379: $ready_to_grade++;
1380: }
1381: } else {
1382: my $due_date = &Apache::lonhomework::due_date('0',$symb);
1383: if ($due_date ne '' && time > $due_date) {
1384: $ready_to_grade++;
1385: }
1.34 albertel 1386: }
1387: }
1388: }
1389: return ($entries,$ready_to_grade,$locks);
1390: }
1391:
1.49 albertel 1392: sub encode_queue_key {
1393: my ($symb,$udom,$uname)=@_;
1.138 albertel 1394: return "$symb\0queue\0$uname:$udom";
1.49 albertel 1395: }
1396:
1.14 albertel 1397: sub decode_queue_key {
1398: my ($key)=@_;
1399: my ($symb,undef,$user) = split("\0",$key);
1.138 albertel 1400: my ($uname,$udom) = split(':',$user);
1.14 albertel 1401: return ($symb,$uname,$udom);
1402: }
1403:
1404: sub queue_key_locked {
1.30 albertel 1405: my ($queue,$key,$cdom,$cnum)=@_;
1.33 albertel 1406: if (!defined($cdom) || !defined($cnum)) {
1407: my (undef,$cid)=&Apache::lonxml::whichuser();
1408: $cnum=$env{'course.'.$cid.'.num'};
1409: $cdom=$env{'course.'.$cid.'.domain'};
1410: }
1.14 albertel 1411: my ($key_locked,$value)=
1.30 albertel 1412: &Apache::lonnet::get($queue,["$key\0locked"],$cdom,$cnum);
1.14 albertel 1413: if ($key_locked eq "$key\0locked") {
1414: return $value;
1415: }
1416: return undef;
1417: }
1418:
1.148 albertel 1419: sub slotted_access {
1420: my ($queue_entry) = @_;
1421: if (ref($queue_entry) eq 'ARRAY') {
1422: if (defined($queue_entry->[0])) {
1423: return $queue_entry->[0];
1424: }
1425: return undef;
1426: } elsif (ref($queue_entry) eq 'HASH') {
1427: if (defined($queue_entry->{'slot'})) {
1428: return $queue_entry->{'slot'};
1429: }
1430: return undef;
1431: }
1432: return undef;
1433: }
1434:
1.14 albertel 1435: sub pick_from_queue_data {
1.156 albertel 1436: my ($queue,$check_section,$queuedata,$cdom,$cnum,$classlist)=@_;
1.98 albertel 1437: my @possible; # will hold queue entries that are valid to be selected
1.30 albertel 1438: foreach my $key (keys(%$queuedata)) {
1.68 albertel 1439: if ($key =~ /\0locked$/) { next; }
1440: if ($key =~ /\0timestamp$/) { next; }
1.156 albertel 1441:
1.14 albertel 1442: my ($symb,$uname,$udom)=&decode_queue_key($key);
1.156 albertel 1443: if (!defined($classlist->{$uname.':'.$udom})) { next; }
1444:
1.14 albertel 1445: if ($check_section) {
1.156 albertel 1446: my $section =
1447: $classlist->{$uname.':'.$udom}[&Apache::loncoursedata::CL_SECTION()];
1.17 albertel 1448: if ($section eq $check_section) {
1.33 albertel 1449: &Apache::lonxml::debug("my sec");
1.15 albertel 1450: next;
1451: }
1.14 albertel 1452: }
1.148 albertel 1453: my $end_time;
1454: if (my $slot=&slotted_access($queuedata->{$key})) {
1.154 albertel 1455: &Apache::lonxml::debug("looking at slot $slot");
1.148 albertel 1456: my %slot_data=&Apache::lonnet::get_slot($slot);
1457: if ($slot_data{'endtime'} < time) {
1458: $end_time = $slot_data{'endtime'};
1.154 albertel 1459: } else {
1460: &Apache::lonxml::debug("not time ".$slot_data{'endtime'});
1461: next;
1.148 albertel 1462: }
1463: } else {
1464: my $due_date = &Apache::lonhomework::due_date('0',$symb);
1.154 albertel 1465: if ($due_date < time) {
1.148 albertel 1466: $end_time = $due_date;
1.154 albertel 1467: } else {
1468: &Apache::lonxml::debug("not time $due_date");
1469: next;
1.148 albertel 1470: }
1471: }
1472:
1.98 albertel 1473: if (exists($queuedata->{"$key\0locked"})) {
1.33 albertel 1474: &Apache::lonxml::debug("someone already has um.");
1.15 albertel 1475: next;
1476: }
1.148 albertel 1477: push(@possible,[$key,$end_time]);
1.98 albertel 1478: }
1479: if (@possible) {
1480: # sort entries in order by slot end time
1481: @possible = sort { $a->[1] <=> $b->[1] } @possible;
1.137 albertel 1482: # pick one of the entries in the top 10% in small queues and one
1483: # of the first ten entries in large queues
1.139 albertel 1484: #my $ten_percent = int($#possible * 0.1);
1485: #if ($ten_percent < 1 ) { $ten_percent = 1; }
1486: #if ($ten_percent > 10) { $ten_percent = 10; }
1487: #my $max=($#possible < $ten_percent) ? $#possible : $ten_percent;
1.137 albertel 1488:
1.139 albertel 1489: #return $possible[int(rand($max))][0];
1490: return $possible[0][0];
1.14 albertel 1491: }
1492: return undef;
1493: }
1494:
1.15 albertel 1495: sub find_mid_grade {
1.30 albertel 1496: my ($queue,$symb,$cdom,$cnum)=@_;
1.158 ! www 1497: my $todo=&unescape($env{'form.gradingkey'});
1.138 albertel 1498: my $me=$env{'user.name'}.':'.$env{'user.domain'};
1.15 albertel 1499: if ($todo) {
1.30 albertel 1500: my $who=&queue_key_locked($queue,$todo,$cdom,$cnum);
1.15 albertel 1501: if ($who eq $me) { return $todo; }
1502: }
1503: my $regexp="^$symb\0.*\0locked\$";
1.30 albertel 1504: my %locks=&Apache::lonnet::dump($queue,$cdom,$cnum,$regexp);
1.15 albertel 1505: foreach my $key (keys(%locks)) {
1506: my $who=$locks{$key};
1507: if ($who eq $me) {
1508: $todo=$key;
1509: $todo=~s/\0locked$//;
1510: return $todo;
1511: }
1512: }
1513: return undef;
1514: }
1515:
1.32 albertel 1516: sub lock_key {
1517: my ($queue,$todo)=@_;
1.138 albertel 1518: my $me=$env{'user.name'}.':'.$env{'user.domain'};
1.32 albertel 1519: my (undef,$cid)=&Apache::lonxml::whichuser();
1520: my $cnum=$env{'course.'.$cid.'.num'};
1521: my $cdom=$env{'course.'.$cid.'.domain'};
1522: my $success=&Apache::lonnet::newput($queue,{"$todo\0locked"=> $me},
1523: $cdom,$cnum);
1.33 albertel 1524: &Apache::lonxml::debug("success $success $todo");
1.32 albertel 1525: if ($success eq 'ok') {
1526: return 1;
1527: }
1528: return 0;
1529: }
1530:
1.86 albertel 1531: sub get_queue_symb_status {
1.85 albertel 1532: my ($queue,$symb,$cdom,$cnum) = @_;
1533: if (!defined($cdom) || !defined($cnum)) {
1534: my (undef,$cid)=&Apache::lonxml::whichuser();
1535: $cnum=$env{'course.'.$cid.'.num'};
1536: $cdom=$env{'course.'.$cid.'.domain'};
1537: }
1.157 albertel 1538: my $classlist=&get_limited_classlist();
1.156 albertel 1539:
1.85 albertel 1540: my $regexp="^$symb\0";
1541: my %queue=&Apache::lonnet::dump($queue,$cdom,$cnum,$regexp);
1542: my ($tmp)=%queue;
1543: if ($tmp=~/^error: 2 /) { return; }
1544: my @users;
1545: foreach my $key (sort(keys(%queue))) {
1546: next if ($key=~/locked$/);
1547: next if ($key=~/timestamp$/);
1548: my ($symb,$uname,$udom) = &decode_queue_key($key);
1.156 albertel 1549: next if (!defined($classlist->{$uname.':'.$udom}));
1.85 albertel 1550: push(@users,"$uname:$udom");
1551: }
1552: return @users;
1553: }
1554:
1.14 albertel 1555: sub get_from_queue {
1.30 albertel 1556: my ($queue)=@_;
1.14 albertel 1557: my $result;
1558: my ($symb,$cid,$udom,$uname)=&Apache::lonxml::whichuser();
1559: my $cnum=$env{'course.'.$cid.'.num'};
1560: my $cdom=$env{'course.'.$cid.'.domain'};
1.32 albertel 1561: my $todo=&find_mid_grade($queue,$symb,$cdom,$cnum);
1.33 albertel 1562: &Apache::lonxml::debug("found ".join(':',&decode_queue_key($todo)));
1.16 albertel 1563: if ($todo) { return $todo; }
1.95 albertel 1564: my $attempts=0;
1.156 albertel 1565:
1.157 albertel 1566: my $classlist=&get_limited_classlist();
1.156 albertel 1567:
1.14 albertel 1568: while (1) {
1.95 albertel 1569: if ($attempts > 2) {
1570: # tried twice to get a queue entry, giving up
1571: return (undef,'unable');
1572: }
1.14 albertel 1573: my $starttime=time;
1.83 albertel 1574: &Apache::lonnet::cput($queue,{"$symb\0timestamp"=>$starttime},
1575: $cdom,$cnum);
1.33 albertel 1576: &Apache::lonxml::debug("$starttime");
1.14 albertel 1577: my $regexp="^$symb\0queue\0";
1.156 albertel 1578: #my $range= ($attempts < 1 ) ? '0-100' : '0-400';
1.97 albertel 1579:
1.98 albertel 1580: my %queue=&Apache::lonnet::dump($queue,$cdom,$cnum,$regexp);
1.33 albertel 1581: #make a pass looking for a user _not_ in my section
1.14 albertel 1582: if ($env{'request.course.sec'}) {
1.33 albertel 1583: &Apache::lonxml::debug("sce");
1.30 albertel 1584: $todo=&pick_from_queue_data($queue,$env{'request.course.sec'},
1.156 albertel 1585: \%queue,$cdom,$cnum,$classlist);
1.33 albertel 1586: &Apache::lonxml::debug("sce $todo");
1.14 albertel 1587: }
1.33 albertel 1588: # no one _not_ in our section so look for any user that is
1589: # ready for grading
1.14 albertel 1590: if (!$todo) {
1.33 albertel 1591: &Apache::lonxml::debug("no sce");
1.156 albertel 1592: $todo=&pick_from_queue_data($queue,undef,\%queue,$cdom,$cnum,
1593: $classlist);
1.33 albertel 1594: &Apache::lonxml::debug("no sce $todo");
1.14 albertel 1595: }
1596: # no user to grade
1597: if (!$todo) { last; }
1.33 albertel 1598: &Apache::lonxml::debug("got $todo");
1.14 albertel 1599: # otherwise found someone so lets try to lock them
1.32 albertel 1600: # unless someone else already picked them
1.95 albertel 1601: if (!&lock_key($queue,$todo)) {
1602: $attempts++;
1603: next;
1604: }
1.14 albertel 1605: my (undef,$endtime)=
1.30 albertel 1606: &Apache::lonnet::get($queue,["$symb\0timestamp"],
1.14 albertel 1607: $cdom,$cnum);
1.33 albertel 1608: &Apache::lonxml::debug("emd $endtime");
1.14 albertel 1609: # someone else already modified the queue,
1610: # perhaps our picked user wass already fully graded between
1611: # when we picked him and when we locked his record? so lets
1612: # double check.
1613: if ($endtime != $starttime) {
1614: my ($key,$value)=
1.30 albertel 1615: &Apache::lonnet::get($queue,["$todo"],
1.14 albertel 1616: $cdom,$cnum);
1.33 albertel 1617: &Apache::lonxml::debug("check $key .. $value");
1.14 albertel 1618: if ($key eq $todo && ref($value)) {
1619: } else {
1.30 albertel 1620: &Apache::lonnet::del($queue,["$todo\0locked"],
1.14 albertel 1621: $cdom,$cnum);
1.33 albertel 1622: &Apache::lonxml::debug("del");
1.95 albertel 1623: $attempts++;
1.14 albertel 1624: next;
1625: }
1626: }
1.33 albertel 1627: &Apache::lonxml::debug("last $todo");
1.14 albertel 1628: last;
1629: }
1630: return $todo;
1631: }
1632:
1.49 albertel 1633: sub select_user {
1634: my ($symb,$cid)=&Apache::lonxml::whichuser();
1635:
1.59 albertel 1636: my @chosen_sections=
1637: &Apache::loncommon::get_env_multiple('form.chosensections');
1.156 albertel 1638:
1639: my $classlist = &get_limited_classlist(\@chosen_sections);
1.63 albertel 1640:
1641: my $result;
1642: if (!(grep(/^all$/,@chosen_sections))) {
1643: $result.='<p> Showing only sections <tt>'.join(', ',@chosen_sections).
1644: '</tt>.</p> '."\n";
1645: }
1646: $result.='<table border="1">';
1.49 albertel 1647:
1.156 albertel 1648: foreach my $student (sort {lc($classlist->{$a}[&Apache::loncoursedata::CL_FULLNAME()]) cmp lc($classlist->{$b}[&Apache::loncoursedata::CL_FULLNAME()]) } (keys(%$classlist))) {
1.49 albertel 1649: my ($uname,$udom) = split(/:/,$student);
1.59 albertel 1650:
1.84 albertel 1651: my $cnum=$env{'course.'.$cid.'.num'};
1652: my $cdom=$env{'course.'.$cid.'.domain'};
1.88 albertel 1653: my %status = &get_student_status($symb,$cdom,$cnum,$udom,$uname,
1654: 'Task');
1.49 albertel 1655: my $queue = 'none';
1.58 albertel 1656: my $cannot_grade;
1657: if ($status{'reviewqueue'} =~ /^(in_progress|enqueue)$/) {
1.49 albertel 1658: $queue = 'reviewqueue';
1.58 albertel 1659: if ($status{'reviewqueue'} eq 'in_progress') {
1660: $cannot_grade=1;
1661: }
1662: } elsif ($status{'gradingqueue'} =~ /^(in_progress|enqueue)$/) {
1.49 albertel 1663: $queue = 'gradingqueue';
1.58 albertel 1664: if ($status{'gradingqueue'} eq 'in_progress') {
1665: $cannot_grade=1;
1666: }
1.49 albertel 1667: }
1668: my $todo =
1.158 ! www 1669: &escape(&encode_queue_key($symb,$udom,$uname));
1.58 albertel 1670: if ($cannot_grade) {
1.156 albertel 1671: $result.='<tr><td> </td><td>'.$classlist->{$student}[&Apache::loncoursedata::CL_FULLNAME()].
1.58 albertel 1672: '</td><td>';
1673: } else {
1.62 albertel 1674: my $seclist;
1675: foreach my $sec (@chosen_sections) {
1676: $seclist.='<input type="hidden" name="chosensections"
1677: value="'.$sec.'" />';
1678: }
1.58 albertel 1679: $result.=<<RESULT;
1.49 albertel 1680: <tr>
1681: <td>
1.115 albertel 1682: <form style="display: inline" method="post">
1.49 albertel 1683: <input type="hidden" name="gradingkey" value="$todo" />
1684: <input type="hidden" name="queue" value="$queue" />
1685: <input type="hidden" name="webgrade" value="no" />
1.52 albertel 1686: <input type="hidden" name="regrade" value="yes" />
1.62 albertel 1687: <input type="submit" name="submit" value="Regrade" />
1688: $seclist
1.49 albertel 1689: </form>
1.155 albertel 1690: <td>$classlist->{$student}[&Apache::loncoursedata::CL_FULLNAME()] <tt>($student)</tt></td>
1.49 albertel 1691: <td>
1692: RESULT
1.58 albertel 1693: }
1.49 albertel 1694: if ($status{'status'} eq 'pass') {
1695: $result .= '<font color="green">'.&mt('Passed').'</font>';
1696: } elsif ($status{'status'} eq 'fail') {
1697: $result .= '<font color="red">'.&mt('Failed').'</font>';
1698: } elsif ($status{'status'} eq 'review') {
1699: $result .= '<font color="blue">'.&mt('Under Review').'</font>';
1700: } elsif ($status{'status'} eq 'ungraded') {
1701: $result .= &mt('Ungraded');
1702: } elsif ($status{'status'} ne '') {
1703: $result .= '<font color="orange">'.&mt('Unknown Status').'</font>';
1704: } else {
1705: $result.=" ";
1706: }
1707: if ($status{'version'}) {
1708: $result .= ' '.&mt('Version').' '.$status{'version'};
1709: }
1.101 albertel 1710: if ($status{'grader'}) {
1711: $result .= ' '.&mt('(Graded by [_1])',$status{'grader'}).' ';
1712: }
1.49 albertel 1713: $result.= '</td><td>';
1714: if ($status{'reviewqueue'} eq 'enqueued') {
1715: $result .= &mt('Awaiting Review');
1716: } elsif ($status{'reviewqueue'} eq 'locked') {
1717: $result .= &mt('Under Review');
1.58 albertel 1718: } elsif ($status{'reviewqueue'} eq 'in_progress') {
1719: $result .= &mt('Still being worked on.');
1.49 albertel 1720: } elsif ($status{'gradingqueue'} eq 'enqueued') {
1721: $result .= &mt('Awaiting Grading');
1722: } elsif ($status{'gradingqueue'} eq 'locked') {
1723: $result .= &mt('Being Graded');
1.58 albertel 1724: } elsif ($status{'gradingqueue'} eq 'in_progress') {
1725: $result .= &mt('Still being worked on.');
1.49 albertel 1726: } else {
1727: $result.=" ";
1728: }
1729: $result.= '</td></tr>';
1730: }
1731: $result.='</table>';
1732: return $result;
1733: }
1734:
1735: sub get_student_status {
1.86 albertel 1736: my ($symb,$cdom,$cnum,$udom,$uname,$type)=@_;
1737:
1738: my %status;
1739:
1740: if ($type eq 'Task') {
1741: my %record = &Apache::lonnet::restore($symb,$env{'request.course.id'},
1.49 albertel 1742: $udom,$uname);
1.89 albertel 1743: $status{'status'}=$record{'resource.0.status'};
1744: $status{'version'}=$record{'resource.0.version'};
1745: $status{'grader'}=$record{'resource.0.regrader'};
1.86 albertel 1746: }
1747: $status{'reviewqueue'}=
1748: &check_queue_for_key($cdom,$cnum,'reviewqueue',
1749: &encode_queue_key($symb,$udom,$uname));
1750: $status{'gradingqueue'}=
1751: &check_queue_for_key($cdom,$cnum,'gradingqueue',
1752: &encode_queue_key($symb,$udom,$uname));
1.49 albertel 1753: return %status;
1754: }
1755:
1.1 albertel 1756: sub start_ClosingParagraph {
1757: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
1758: my $result;
1759: if ($target eq 'web') {
1.13 albertel 1760: } elsif ($target eq 'webgrade') {
1761: &Apache::lonxml::startredirection();
1.1 albertel 1762: }
1763: return $result;
1764: }
1765:
1766: sub end_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::endredirection();
1.1 albertel 1772: }
1773: return $result;
1774: }
1775:
1.19 albertel 1776: sub get_id {
1777: my ($parstack,$safeeval)=@_;
1778: my $id=&Apache::lonxml::get_param('id',$parstack,$safeeval);
1779: if (!$id) { $id=$Apache::lonxml::curdepth; }
1780: return $id;
1781: }
1782:
1.1 albertel 1783: my %dimension;
1.151 albertel 1784: sub start_Question { return &start_Dimension(@_); }
1.1 albertel 1785: sub start_Dimension {
1786: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
1787: undef(%dimension);
1.19 albertel 1788: my $dim_id=&get_id($parstack,$safeeval);
1.9 albertel 1789: $Apache::bridgetask::dimension=$dim_id;
1790: push(@Apache::bridgetask::dimensionlist,$dim_id);
1791: undef(@Apache::bridgetask::instance);
1.20 albertel 1792: $Apache::bridgetask::dimensionmandatory{$dim_id}=
1793: &Apache::lonxml::get_param('Mandatory',$parstack,$safeeval);
1.54 albertel 1794: &Apache::lonxml::startredirection();
1795: return &internal_location($dim_id);
1.1 albertel 1796: }
1797:
1.13 albertel 1798: sub get_instance {
1.75 albertel 1799: my ($dim)=@_;
1800: my $rand_alg=&Apache::lonnet::get_rand_alg();
1801: if (!$rand_alg || $rand_alg eq '32bit' || $rand_alg eq '64bit' ||
1802: $rand_alg eq '64bit2' || $rand_alg eq '64bit3' ||
1803: $rand_alg eq '64bit4' ) {
1804: &Apache::response::pushrandomnumber();
1805: my @order=&Math::Random::random_permutation(@{$dimension{'instances'}});
1806: my $num=@order;
1807: my $version=&get_version();
1808: my $which=($version-1)%$num;
1809: return $order[$which];
1810: } else {
1811: my ($version,$previous) = &get_version();
1812: my $instance =
1813: $Apache::lonhomework::history{"resource.$version.0.$dim.instance"};
1814: if (defined($instance)) { return $instance; }
1815:
1816: &Apache::response::pushrandomnumber();
1817: my @instances = @{$dimension{'instances'}};
1818: # remove disabled instances
1819: for (my $i=0; $i < $#instances; $i++) {
1820: if ($dimension{$instances[$i].'.disabled'}) {
1821: splice(@instances,$i,1);
1822: $i--;
1823: }
1824: }
1825: @instances = &Math::Random::random_permutation(@instances);
1826: $instance = $instances[($version-1)%scalar(@instances)];
1.150 albertel 1827: if ($version =~ /^\d$/) {
1828: $Apache::lonhomework::results{"resource.$version.0.$dim.instance"} =
1829: $instance;
1830: $Apache::lonhomework::results{'INTERNAL_store'} = 1;
1831: }
1.75 albertel 1832: &Apache::response::poprandomnumber();
1833: return $instance;
1834: }
1.13 albertel 1835: }
1836:
1.18 albertel 1837: {
1838: my $last_link;
1.122 albertel 1839: sub link {
1.151 albertel 1840: my ($id) = @_;
1841: $id =~ s/\./_/g;
1842: return 'LC_GRADING_criteria_'.$id;
1.122 albertel 1843: }
1.151 albertel 1844: sub end_Question { return &end_Dimension(@_); }
1.18 albertel 1845: sub end_Dimension {
1846: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
1.54 albertel 1847: my $result=&Apache::lonxml::endredirection();
1.25 albertel 1848: my $dim=&get_id($parstack,$safeeval);
1.75 albertel 1849: my $instance=&get_instance($dim);
1.25 albertel 1850: my $version=&get_version();
1.18 albertel 1851: if ($target eq 'web') {
1.47 albertel 1852: @Apache::scripttag::parser_env = @_;
1853: $result.=&Apache::scripttag::xmlparse($dimension{'intro'});
1.76 albertel 1854: my @instances = $instance;
1855: if (&Apache::response::showallfoils()) {
1856: @instances = @{$dimension{'instances'}};
1857: }
1858: foreach my $instance (@instances) {
1859: @Apache::scripttag::parser_env = @_;
1860: $result.=&Apache::scripttag::xmlparse($dimension{$instance.'.text'});
1.89 albertel 1861: if ($Apache::lonhomework::history{"resource.$version.0.status"} eq 'pass' ||
1862: $Apache::lonhomework::history{"resource.$version.0.status"} eq 'fail') {
1.76 albertel 1863:
1.89 albertel 1864: my $dim_status=$Apache::lonhomework::history{"resource.$version.0.$dim.status"};
1.76 albertel 1865: my $mandatory='Mandatory';
1866: if ($Apache::bridgetask::dimensionmandatory{$dim} eq 'N') {
1867: $mandatory='Optional';
1868: }
1.116 albertel 1869: my $dim_info="<div class='LC_$dim_status LC_question_grade'>\n";
1.76 albertel 1870: if ($dim_status eq 'pass') {
1871: $dim_info.='<h3>Question : you passed this '.$mandatory.' question</h3>';
1.54 albertel 1872: }
1.76 albertel 1873: if ($dim_status eq 'fail') {
1874: $dim_info.='<h3>Question : you did not pass this '.$mandatory.' question</h3>';
1.53 albertel 1875: }
1.76 albertel 1876: my $man_count=0;
1877: my $man_passed=0;
1878: my $opt_count=0;
1879: my $opt_passed=0;
1.151 albertel 1880: foreach my $id ( @{$dimension{$instance.'.criterias'}},
1881: @{$dimension{'criterias'}} ) {
1882: if ($dimension{'criteria.'.$id.'.mandatory'}
1.76 albertel 1883: eq 'N') {
1884: $opt_count++;
1.151 albertel 1885: if ($Apache::lonhomework::history{"resource.$version.0.$dim.$id.status"} eq 'pass') {
1.76 albertel 1886: $opt_passed++;
1887: }
1888: } else {
1889: $man_count++;
1.89 albertel 1890: if ($Apache::lonhomework::history{"resource.$version.0.$dim.$instance.$id.status"} eq 'pass') {
1.76 albertel 1891: $man_passed++;
1892: }
1893: }
1.22 albertel 1894: }
1.76 albertel 1895: if ($man_passed eq $man_count) { $man_passed='all'; }
1.151 albertel 1896:
1.76 albertel 1897: my $opt_req=$dimension{$instance.'.optionalrequired'};
1.151 albertel 1898: if ($opt_req !~ /\S/) {
1899: $opt_req=
1900: &Apache::lonxml::get_param('OptionalRequired',
1901: $parstack,$safeeval);
1902: if ($opt_req !~ /\S/) { $opt_req = 0; }
1903: }
1.76 albertel 1904: $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>";
1905:
1906: my $internal_location=&internal_location($dim);
1907: $result=~s/\Q$internal_location\E/$dim_info/;
1908:
1.151 albertel 1909: foreach my $id (@{$dimension{$instance.'.criterias'}},
1910: @{$dimension{'criterias'}}) {
1911: my $status=$Apache::lonhomework::history{"resource.$version.0.$dim.$id.status"};
1912: my $comment=$Apache::lonhomework::history{"resource.$version.0.$dim.$id.comment"};
1913: my $mandatory=($dimension{'criteria.'.$id.'.mandatory'} ne 'N');
1.76 albertel 1914: if ($mandatory) {
1915: $mandatory='Mandatory';
1916: } else {
1917: $mandatory='Optional';
1918: }
1919: if ($status eq 'fail') {
1920: } elsif ($status eq 'pass') {
1921: } else {
1922: &Apache::lonxml::error("Student viewing a graded bridgetask was shown a status of $status");
1923: }
1924: my $status_display=$status;
1925: $status_display=~s/^([a-z])/uc($1)/e;
1.116 albertel 1926: $result.=
1927: '<div class="LC_'.$status.' LC_criteria"><h4>'
1928: .$mandatory.' Criteria</h4><p>';
1.76 albertel 1929: @Apache::scripttag::parser_env = @_;
1.151 albertel 1930: $result.=&Apache::scripttag::xmlparse($dimension{'criteria.'.$id});
1.116 albertel 1931: $result.='</p><p class="LC_grade">'.$status_display.'</p>';
1.151 albertel 1932: if ($Apache::lonhomework::history{"resource.$version.0.$dim.$id.comment"}) {
1933: $result.='<p class="LC_comment">'.&mt('Comment: [_1]',$Apache::lonhomework::history{"resource.$version.0.$dim.$id.comment"}).'</p>';
1.76 albertel 1934: }
1935: $result.='</div>';
1.22 albertel 1936: }
1937: }
1938: }
1.18 albertel 1939: } elsif ($target eq 'webgrade') {
1.47 albertel 1940: # in case of any side effects that we need
1941: @Apache::scripttag::parser_env = @_;
1942: &Apache::scripttag::xmlparse($dimension{'intro'});
1943: @Apache::scripttag::parser_env = @_;
1944: &Apache::scripttag::xmlparse($dimension{$instance.'.text'});
1.151 albertel 1945: foreach my $id (@{$dimension{$instance.'.criterias'}},
1946: @{$dimension{'criterias'}} ) {
1947: my $link=&link($id);
1948: my $status=$Apache::lonhomework::history{"resource.$version.0.$dim.$id.status"};
1.120 albertel 1949: $result.='<div class="LC_GRADING_criteria" id="'.$link.'">'."\n".
1.136 albertel 1950: '<div class="LC_GRADING_criteriatext" id="next_'.$last_link.'">'."\n";
1.47 albertel 1951: @Apache::scripttag::parser_env = @_;
1.151 albertel 1952: $result.=&Apache::scripttag::xmlparse($dimension{'criteria.'.$id});
1.111 albertel 1953: $result.='</div>'."\n".
1.151 albertel 1954: #$dimension{'criteria.'.$id}.
1.120 albertel 1955: '<div class="LC_GRADING_grade">'."\n".
1956: '<label class="LC_GRADING_ungraded"><input type="radio" name="HWVAL_'.$link.'" value="ungraded" '.($status eq 'ungraded' || !$status ? 'checked="checked"':'').' />'.&mt('Ungraded').'</label>'."\n".
1957: '<label class="LC_GRADING_fail"><input type="radio" name="HWVAL_'.$link.'" value="fail" '.($status eq 'fail' ? 'checked="checked"':'').' />'.&mt('Fail').'</label>'."\n".
1958: '<label class="LC_GRADING_pass"><input type="radio" name="HWVAL_'.$link.'" value="pass" '.($status eq 'pass' ? 'checked="checked"':'').' />'.&mt('Pass').'</label>'."\n".
1959: '<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 1960: '</div>'."\n".
1.120 albertel 1961: '<label class="LC_GRADING_comment">'.&mt('Additional Comment for Student')."\n".
1.151 albertel 1962: '<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 1963: '</label>'."\n".
1.120 albertel 1964: '<ul class="LC_GRADING_navbuttons">'."\n".
1.111 albertel 1965: '<li><a href="#'.$last_link.'">Prev</a></li>'."\n".
1966: '<li><a href="#next_'.$link.'">Next</a></li>'."\n".
1967: '</ul>'."\n".
1968: '</div>'."\n";
1.151 albertel 1969: $result.=&grading_history($version,$dim,$id);
1.18 albertel 1970: $last_link=$link;
1971: }
1.22 albertel 1972: } elsif ($target eq 'grade' && $env{'form.webgrade'}) {
1.19 albertel 1973: my $optional_passed=0;
1.20 albertel 1974: my $mandatory_failed=0;
1975: my $ungraded=0;
1976: my $review=0;
1.153 albertel 1977:
1978: @Apache::scripttag::parser_env = @_;
1979: $result.=&Apache::scripttag::xmlparse($dimension{'intro'});
1.151 albertel 1980: foreach my $id (@{$dimension{$instance.'.criterias'}},
1981: @{$dimension{'criterias'}}) {
1982: my $link=&link($id);
1.153 albertel 1983: @Apache::scripttag::parser_env = @_;
1984: $result.=&Apache::scripttag::xmlparse($dimension{$instance.'.text'});
1.151 albertel 1985: my $status=$Apache::lonhomework::results{"resource.$version.0.$dim.$id.status"}=$env{'form.HWVAL_'.$link};
1986: $Apache::lonhomework::results{"resource.$version.0.$dim.$id.comment"}=$env{'form.HWVAL_comment_'.$link};
1987: my $mandatory=($dimension{'criteria.'.$id.'.mandatory'} ne 'N');
1.20 albertel 1988: if ($status eq 'pass') {
1989: if (!$mandatory) { $optional_passed++; }
1990: } elsif ($status eq 'fail') {
1991: if ($mandatory) { $mandatory_failed++; }
1.21 albertel 1992: } elsif ($status eq 'review') {
1993: $review++;
1.20 albertel 1994: } elsif ($status eq 'ungraded') {
1995: $ungraded++;
1.21 albertel 1996: } else {
1.47 albertel 1997: $ungraded++;
1.19 albertel 1998: }
1999: }
1.151 albertel 2000: # FIXME optional required can apply to only <instance> right now...
2001: my $opt_req=$dimension{$instance.'.optionalrequired'};
2002: if ($opt_req !~ /\S/) {
2003: $opt_req=
2004: &Apache::lonxml::get_param('OptionalRequired',
2005: $parstack,$safeeval);
2006: if ($opt_req !~ /\S/) { $opt_req = 0; }
2007: }
2008: if ($optional_passed < $opt_req) {
1.20 albertel 2009: $mandatory_failed++;
2010: }
1.21 albertel 2011: &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 2012: if ($review) {
1.89 albertel 2013: $Apache::lonhomework::results{"resource.$version.0.$dim.status"}=
1.22 albertel 2014: 'review';
1.20 albertel 2015: } elsif ($ungraded) {
1.89 albertel 2016: $Apache::lonhomework::results{"resource.$version.0.$dim.status"}=
1.22 albertel 2017: 'ungraded';
1.20 albertel 2018: } elsif ($mandatory_failed) {
1.89 albertel 2019: $Apache::lonhomework::results{"resource.$version.0.$dim.status"}=
1.22 albertel 2020: 'fail';
1.20 albertel 2021: } else {
1.91 albertel 2022: $Apache::lonhomework::results{"resource.$version.0.$dim.status"}=
1.22 albertel 2023: 'pass';
1.20 albertel 2024: }
1.69 albertel 2025: } else {
2026: # any other targets no output
2027: undef($result);
1.13 albertel 2028: }
1.18 albertel 2029: return $result;
1.1 albertel 2030: }
2031: }
2032:
1.113 albertel 2033: sub grading_history {
1.151 albertel 2034: my ($version,$dim,$id) = @_;
1.113 albertel 2035: if (!&Apache::lonnet::allowed('mgq',$env{'request.course.id'})) {
2036: return '';
2037: }
2038: my ($result,$grader);
1.151 albertel 2039: my $scope="resource.$version.0.$dim.$id";
1.113 albertel 2040: foreach my $t (1..$Apache::lonhomework::history{'version'}) {
2041: if (exists($Apache::lonhomework::history{$t.':resource.0.regrader'})) {
2042: my ($gname,$gdom) =
1.138 albertel 2043: split(':',$Apache::lonhomework::history{$t.':resource.0.regrader'});
1.113 albertel 2044: my $fullname = &Apache::loncommon::plainname($gname,$gdom);
2045: $grader = &Apache::loncommon::aboutmewrapper($fullname,
2046: $gname,$gdom);
2047: }
2048: my $entry;
2049: if (exists($Apache::lonhomework::history{"$t:$scope.status"})) {
2050: $entry.="<tt>".$Apache::lonhomework::history{"$t:$scope.status"}.'</tt>';
2051: }
2052: if (exists($Apache::lonhomework::history{"$t:$scope.comment"})) {
2053: $entry.=' comment: "'.$Apache::lonhomework::history{"$t:$scope.comment"}.'"';
2054: }
2055: if ($entry) {
2056: $result.= "<li>$grader : $entry </li>";
2057: }
2058: }
2059: if ($result) {
1.120 albertel 2060: return '<ul class="LC_GRADING_pastgrading">'.$result.'</ul>';
1.113 albertel 2061: }
2062: return '';
2063: }
2064:
1.1 albertel 2065: sub start_IntroParagraph {
1.87 albertel 2066: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.1 albertel 2067: my $result;
1.153 albertel 2068: if ($target eq 'grade' || $target eq 'web' || $target eq 'webgrade') {
1.151 albertel 2069: if ($tagstack->[-2] eq 'Dimension' || $tagstack->[-2] eq 'Question' ) {
2070: $dimension{'intro'}=
2071: &Apache::lonxml::get_all_text('/introparagraph',
2072: $parser,$style);
2073: } elsif ($tagstack->[-2] eq 'Task' && $target eq 'webgrade') {
1.127 albertel 2074: &Apache::lonxml::startredirection();
1.1 albertel 2075: }
1.47 albertel 2076:
1.1 albertel 2077: }
2078: return $result;
2079: }
2080:
2081: sub end_IntroParagraph {
1.127 albertel 2082: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.128 albertel 2083: if ($tagstack->[-2] eq 'Task' && $target eq 'webgrade') {
1.127 albertel 2084: my $result = &Apache::lonxml::endredirection();
2085: }
1.1 albertel 2086: }
2087:
2088: sub start_Instance {
2089: my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
1.19 albertel 2090: my $id=&get_id($parstack,$safeeval);
2091: push(@{$dimension{'instances'}},$id);
2092: push(@Apache::bridgetask::instance,$id);
2093: push(@Apache::bridgetask::instancelist,$id);
1.20 albertel 2094: $dimension{$id.'.optionalrequired'}=
1.19 albertel 2095: &Apache::lonxml::get_param('OptionalRequired',$parstack,$safeeval);
1.75 albertel 2096: my $disabled = &Apache::lonxml::get_param('Disabled',$parstack,$safeeval);
2097: if (lc($disabled) eq 'yes') {
2098: $dimension{$id.'.disabled'}='1';
2099: }
1.1 albertel 2100: return '';
2101: }
2102:
2103: sub end_Instance {
2104: }
2105:
2106: sub start_InstanceText {
1.87 albertel 2107: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.47 albertel 2108: my $instance_id=$Apache::bridgetask::instance[-1];
1.87 albertel 2109: my $text=&Apache::lonxml::get_all_text('/instancetext',$parser,$style);
1.153 albertel 2110: if ($target eq 'grade' || $target eq 'web' || $target eq 'webgrade') {
1.47 albertel 2111: $dimension{$instance_id.'.text'}=$text;
1.1 albertel 2112: }
2113: return '';
2114: }
2115:
2116: sub end_InstanceText {
2117: return '';
2118: }
2119:
2120: sub start_Criteria {
1.87 albertel 2121: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
2122: my $criteria=&Apache::lonxml::get_all_text('/criteria',$parser,$style);
1.21 albertel 2123: if ($target eq 'web' || $target eq 'webgrade' || $target eq 'grade') {
1.19 albertel 2124: my $id=&get_id($parstack,$safeeval);
1.151 albertel 2125: if (&Apache::londefdef::is_inside_of($tagstack,'Instance')) {
2126: my $instance_id=$Apache::bridgetask::instance[-1];
2127: $dimension{"criteria.$instance_id.$id"}=$criteria;
2128: $dimension{"criteria.$instance_id.$id.mandatory"}=
2129: &Apache::lonxml::get_param('Mandatory',$parstack,$safeeval);
2130: push(@{$dimension{$instance_id.'.criterias'}},"$instance_id.$id");
2131: } else {
2132: $dimension{'criteria.'.$id}=$criteria;
2133: $dimension{'criteria.'.$id.'.mandatory'}=
2134: &Apache::lonxml::get_param('Mandatory',$parstack,$safeeval);
2135: push(@{$dimension{'criterias'}},$id);
2136: }
1.1 albertel 2137: }
2138: return '';
2139: }
2140:
1.47 albertel 2141: sub end_Criteria {
2142: }
2143:
1.4 albertel 2144: sub proctor_validation_screen {
2145: my ($slot) = @_;
2146: my (undef,undef,$domain,$user) = &Apache::lonxml::whichuser();
1.5 albertel 2147: my $url=&Apache::lonnet::studentphoto($domain,$user,'jpg');
1.44 albertel 2148: my $name=&Apache::loncommon::plainname($user,$domain);
2149:
1.4 albertel 2150: my $msg;
1.11 albertel 2151: if ($env{'form.proctorpassword'}) {
1.4 albertel 2152: $msg='<p><font color="red">'.&mt("Failed to authenticate the proctor.")
2153: .'</font></p>';
2154: }
1.47 albertel 2155: if (!$env{'form.proctordomain'}) { $env{'form.proctordomain'}=$domain; }
1.4 albertel 2156: my $result= (<<ENDCHECKOUT);
2157: <h2>Proctor Validation</h2>
2158: <p>Your room's proctor needs to validate your access to this resource.</p>
2159: $msg
1.115 albertel 2160: <form name="checkout" method="post" action="$env{'request.uri'}">
1.4 albertel 2161: <input type="hidden" name="validate" value="yes" />
2162: <input type="hidden" name="submitted" value="yes" />
2163: <table>
1.44 albertel 2164: <tr><td>Proctor's Username:</td><td><input type="string" name="proctorname" value="$env{'form.proctorname'}" /></td></tr>
1.4 albertel 2165: <tr><td>Password:</td><td><input type="password" name="proctorpassword" value="" /></td></tr>
1.46 albertel 2166: <tr><td>Proctor's Domain:</td><td><input type="string" name="proctordomain" value="$env{'form.proctordomain'}" /></td></tr>
1.4 albertel 2167: </table>
2168: <input type="submit" name="checkoutbutton" value="Validate" /><br />
1.44 albertel 2169: <table border="1">
2170: <tr><td>
2171: <table>
2172: <tr><td colspan="2">Student who should be logged in is:</td></tr>
2173: <tr><td>Name:</td><td>$name</td></tr>
1.45 albertel 2174: <tr><td>Student ID:</td><td>$env{'environment.id'}</td></tr>
1.138 albertel 2175: <tr><td>Usename</td><td>$user:$domain</td></tr>
1.44 albertel 2176: <tr><td colspan="2"><img src="$url" /></td></tr>
2177: </table>
2178: </tr></td>
2179: </table>
1.4 albertel 2180: </form>
2181: ENDCHECKOUT
2182: return $result;
2183: }
2184:
1.1 albertel 2185: 1;
2186: __END__
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>