--- loncom/homework/bridgetask.pm 2005/12/21 19:10:33 1.93 +++ loncom/homework/bridgetask.pm 2006/03/06 19:48:42 1.110.2.1 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # definition of tags that give a structure to a document # -# $Id: bridgetask.pm,v 1.93 2005/12/21 19:10:33 albertel Exp $ +# $Id: bridgetask.pm,v 1.110.2.1 2006/03/06 19:48:42 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -188,19 +188,32 @@ sub add_grading_button { $result.=''; if (&Apache::lonnet::allowed('mgq',$env{'request.course.id'})) { my ($entries,$ready,$locks)=&get_queue_counts('gradingqueue'); - $result.='

Specify a section: '.$sec_select.'

'; - $result.='

'.&mt("Grading Queue has [_1] entries. [_2] of them are ready to be graded and [_3] of them are currently being graded",$entries,$ready,$locks); + $result.=''; + $result.=''; + $result.=''."\n"; ($entries,$ready,$locks)=&get_queue_counts('reviewqueue'); - $result.='

'.&mt("Review Queue has [_1] entries. [_2] of them are ready to be graded and [_3] of them are currently being graded",$entries,$ready,$locks); - $result.='

'."\n"; - $result.='

'."\n"; - } + $result.=''."\n"; + $result.='
Specify a section: '.$sec_select.''.' '; - $result.='

'."\n"; + $result.= &mt("[_1] entries, [_2] ready, [_3] being graded",$entries,$ready,$locks).'
'. + ' '; + $result.=&mt("[_1] entries, [_2] ready, [_3] being graded", + $entries,$ready,$locks).'
'."\n"; + $result.='

'."\n"; + $result.=''; + $result.=&Apache::loncommon::select_dom_form($env{'user.domain'}, + 'gradingdomain'); + $result.=' '. + &Apache::loncommon::selectstudent_link('gradesubmission', + 'gradinguser', + 'gradingdomain'); + $result.=&Apache::loncommon::studentbrowser_javascript(); + } return $result; } @@ -368,13 +381,13 @@ sub webgrade_standard_info { $file=~s|/+|/|g; &Apache::lonnet::allowuploaded('/adm/bridgetask',$file); $file_list.='

  • '.$file. + &Apache::loncommon::icon($file).'" border="0"> '.$file. '
  • '."\n"; } $file_list.="\n"; - my %lt=&Apache::lonlocal::texthash('done' => 'Done', - 'stop' => 'Stop', + my %lt=&Apache::lonlocal::texthash('done' => 'Next Item', + 'stop' => 'Quit Grading', ); my $result=<'.&add_grading_button().""; my $symb=&Apache::lonnet::symbread(); if (&Apache::lonnet::allowed('mgq',$env{'request.course.id'})) { - $body_tag_start.='
    '. + $body_tag_start.=''. ''. ''. ''. '
    '; + my $target_id = + &Apache::lonstathelpers::make_target_id({symb => $symb, + part => '0'}); + $body_tag_start.='
    '. + ''. + ''. + ''. + '
    '; } } } @@ -506,7 +528,7 @@ DONESCREEN $target eq 'webgrade') { my $webgrade='yes'; if ($target eq 'webgrade') { - $result.=$head_tag_start.$body_tag_start; + $result.=$head_tag_start.''.$body_tag_start; #$result.='
    Review'.&show_queue('reviewqueue'); #$result.='
    Grade'.&show_queue('gradingqueue'); } @@ -515,7 +537,7 @@ DONESCREEN # Hrrm, vaildation pass should perhaps say 'not_locked' # perhaps do a search if there is a key that is mine and if # there isn't reshow the queue.... - my ($todo,$status_code)=&get_key_todo($target); + my ($todo,$status_code,$msg)=&get_key_todo($target); if ($todo) { &setup_env_for_other_user($todo,$safeeval); @@ -528,13 +550,9 @@ DONESCREEN $Apache::bridgetask::queue_key=$todo; &Apache::structuretags::initialize_storage(); &Apache::lonhomework::showhash(%Apache::lonhomework::history); - if ($target eq 'webgrade') { - #$result.='
    After -'.&show_queue($env{'form.queue'}); - $result.="\n".''; - if ($status_code eq 'selected') { - $form_tag_start.= - ''; - } + if ($target eq 'webgrade' && $status_code eq 'selected') { + $form_tag_start.= + ''; } } else { if ($target eq 'webgrade') { @@ -544,7 +562,7 @@ DONESCREEN if ($status_code eq 'stop') { $result.=''.&mt("Stopped grading.").''.$back; } elsif ($status_code eq 'lock_failed') { - $result.=''.&mt("Failed to lock the request record.") + $result.=''.&mt("Failed to lock the requested record.") .''.$back; } elsif ($status_code eq 'unlock') { $result.=''.&mt("Unlocked the requested record.") @@ -554,6 +572,10 @@ DONESCREEN $result.=&show_queue($env{'form.queue'},1); } elsif ($status_code eq 'select_user') { $result.=&select_user(); + } elsif ($status_code eq 'unable') { + $result.=''.&mt("Unable to aqcuire a user to grade.").''.$back; + } elsif ($status_code eq 'not_allowed') { + $result.=''.&mt('Not allowed to grade the requested user.').' '.$msg.''.$back; } else { $result.=''.&mt("No user to be graded.").''.$back; } @@ -584,6 +606,9 @@ DONESCREEN } if ($webgrade eq 'yes') { $result.=&webgrade_standard_info(); } } + if ($target eq 'webgrade') { + $result.="\n".'
    '; + } } elsif ($target eq 'edit') { $result.=$head_tag_start."".$body_tag_start.$form_tag_start. &Apache::structuretags::problem_edit_header(); @@ -620,6 +645,57 @@ sub get_key_todo { return (undef,'select_user'); } + + my $me=$env{'user.name'}.'@'.$env{'user.domain'}; + + #need to try both queues.. + if (defined($env{'form.regradeaspecificsubmission'}) && + defined($env{'form.gradinguser'}) && + defined($env{'form.gradingdomain'}) ) { + my ($symb,$cid)=&Apache::lonxml::whichuser(); + my $cnum = $env{'course.'.$cid.'.num'}; + my $cdom = $env{'course.'.$cid.'.domain'}; + my $uname = $env{'form.gradinguser'}; + my $udom = $env{'form.gradingdomain'}; + + my $gradingkey=&encode_queue_key($symb,$udom,$uname); + + my $queue; + + if (&in_queue('gradingqueue',$symb,$cdom,$cnum,$udom,$uname)) { + $env{'form.queue'} = $queue = 'gradingqueue'; + } elsif (&in_queue('reviewqueue' ,$symb,$cdom,$cnum,$udom,$uname)) { + $env{'form.queue'} = $queue = 'reviewqueue'; + } + + if (!$queue) { + $env{'form.queue'} = $queue = 'none'; + #not queued so doing either a re or pre grade + return ($gradingkey); + } + + my $who=&queue_key_locked($queue,$gradingkey); + if ($who eq $me) { + #already have the lock + $env{'form.gradingkey'}=&Apache::lonnet::escape($gradingkey); + return ($gradingkey); + } + + if (!defined($who)) { + if (&lock_key($queue,$gradingkey)) { + return ($gradingkey); + } else { + return (undef,'lock_failed'); + } + } + + #otherwise (defined($who) && $who ne $me) some else has it... + return (undef,'not_allowed', + &mt('Another user ([_1]) currently has the record for [_2] locked.', + $who,$env{'form.gradinguser'}.'@'.$env{'form.gradingdomain'})); + } + + my $queue=$env{'form.queue'}; if (!defined($queue)) { @@ -647,7 +723,6 @@ sub get_key_todo { && $env{'form.queuemode'} eq 'selected') { my $who=&queue_key_locked($queue,$gradingkey); - my $me=$env{'user.name'}.'@'.$env{'user.domain'}; if ($who eq $me) { &Apache::lonxml::debug("Found a key was given to me"); return ($gradingkey,'selected'); @@ -689,6 +764,17 @@ sub get_key_todo { } return (undef,undef) } + +sub minimize_storage { + foreach my $key (keys(%Apache::lonhomework::results)) { + if ($key =~ /regrader$/) { next; } + if ($Apache::lonhomework::results{$key} eq + $Apache::lonhomework::history{$key}) { + delete($Apache::lonhomework::results{$key}); + } + } +} + sub end_Task { my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_; my $result=''; @@ -764,7 +850,7 @@ DONEBUTTON my $opt_req=&Apache::lonxml::get_param('OptionalRequired', $parstack,$safeeval); if ($opt_req !~ /\S/) { $opt_req='0'; } - $status.="\n

    ".&mt('You needed to pass all of the [_1] mandatory components and [_2] of the [_3] optional components, of which you were required to pass [_4] on the bridge task.',$man_count,$opt_passed,$opt_count,$opt_req)."

    \n"; + $status.="\n

    ".&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)."

    \n"; my $internal_location=&internal_location(); $result=~s/\Q$internal_location\E/$status/; @@ -897,6 +983,7 @@ DONEBUTTON $Apache::lonhomework::results{"resource.0.solved"}= $Apache::lonhomework::results{"resource.$version.0.solved"}; } + &minimize_storage(); &Apache::structuretags::finalize_storage(); } } elsif ($target eq 'webgrade') { @@ -1087,32 +1174,30 @@ sub show_queue { if ($tmp=~/^error: 2 /) { return "\n

    Current Queue - $queue

    Empty
    "; } - $result.="\n

    Current Queue - $symb $queue

    "; - if ($with_selects) { $result.=""; } - $result.=""; + my $title=&Apache::lonnet::gettitle($symb); + $result.="\n

    Current Queue - $title $queue

    resourceusertypedata
    "; + if ($with_selects) { $result.=""; } + $result.=""; foreach my $key (sort(keys(%queue))) { my ($symb,$uname,$udom) = &decode_queue_key($key); if (!defined($classlist->{$uname.':'.$udom})) { next; } if ($key=~/locked$/ && !$with_selects) { - my $title=&Apache::lonnet::gettitle($symb); - $result.=""; - $result.=''; + $result.=""; + $result.=''; } elsif ($key=~/timestamp$/ && !$with_selects) { - my ($symb,undef) = split("\0",$key); - my $title=&Apache::lonnet::gettitle($symb); - $result.=""; - $result.='"; + $result.='"; } elsif ($key!~/(timestamp|locked)$/) { - my $title=&Apache::lonnet::gettitle($symb); $result.=""; my $slot=$queue{$key}->[0]; my %slot_data=&Apache::lonnet::get_slot($slot); if ($with_selects) { my $ekey=&Apache::lonnet::escape($key); - my ($action,$description)=('select',&mt('Select')); + my ($action,$description,$status)=('select',&mt('Select')); if (exists($queue{"$key\0locked"})) { my $me=$env{'user.name'}.'@'.$env{'user.domain'}; + $status=&mt('Locked by [_1]',$queue{"$key\0locked"}); if ($me eq $queue{"$key\0locked"}) { ($action,$description)=('resume',&mt('Resume')); } else { @@ -1126,8 +1211,9 @@ sub show_queue { } if (time > $slot_data{'endtime'}) { $result.=(<$status ' } } - $result.=""; - $result.='"; + $result.='"; } @@ -1166,6 +1253,7 @@ sub get_queue_counts { return (0,0,0); } my ($entries,$ready_to_grade,$locks)=(0,0,0); + my %slot_cache; foreach my $key (sort(keys(%queue))) { if ($key=~/locked$/) { $locks++; @@ -1175,8 +1263,11 @@ sub get_queue_counts { my ($symb,$uname,$udom) = &decode_queue_key($key); $entries++; my $slot=$queue{$key}->[0]; - my %slot_data=&Apache::lonnet::get_slot($slot); - if (time > $slot_data{'endtime'}) { + if (!exists($slot_cache{$slot})) { + my %slot_data=&Apache::lonnet::get_slot($slot); + $slot_cache{$slot} = \%slot_data; + } + if (time > $slot_cache{$slot}{'endtime'}) { $ready_to_grade++; } } @@ -1213,6 +1304,7 @@ sub queue_key_locked { sub pick_from_queue_data { my ($queue,$check_section,$queuedata,$cdom,$cnum)=@_; + my @possible; # will hold queue entries that are valid to be selected foreach my $key (keys(%$queuedata)) { if ($key =~ /\0locked$/) { next; } if ($key =~ /\0timestamp$/) { next; } @@ -1230,11 +1322,18 @@ sub pick_from_queue_data { &Apache::lonxml::debug("not time"); next; } - if (&queue_key_locked($queue,$key,$cdom,$cnum)) { + if (exists($queuedata->{"$key\0locked"})) { &Apache::lonxml::debug("someone already has um."); next; } - return $key; + push(@possible,[$key,$slot_data{'endtime'}]); + } + if (@possible) { + # sort entries in order by slot end time + @possible = sort { $a->[1] <=> $b->[1] } @possible; + # pick one of the first ten entries + my $max=($#possible < 10) ? $#possible : 10; + return $possible[int(rand($max))][0]; } return undef; } @@ -1305,12 +1404,19 @@ sub get_from_queue { my $todo=&find_mid_grade($queue,$symb,$cdom,$cnum); &Apache::lonxml::debug("found ".join(':',&decode_queue_key($todo))); if ($todo) { return $todo; } + my $attempts=0; while (1) { + if ($attempts > 2) { + # tried twice to get a queue entry, giving up + return (undef,'unable'); + } my $starttime=time; &Apache::lonnet::cput($queue,{"$symb\0timestamp"=>$starttime}, $cdom,$cnum); &Apache::lonxml::debug("$starttime"); my $regexp="^$symb\0queue\0"; + my $range= ($attempts < 1 ) ? '0-100' : '0-400'; + my %queue=&Apache::lonnet::dump($queue,$cdom,$cnum,$regexp); #make a pass looking for a user _not_ in my section if ($env{'request.course.sec'}) { @@ -1323,8 +1429,7 @@ sub get_from_queue { # ready for grading if (!$todo) { &Apache::lonxml::debug("no sce"); - $todo=&pick_from_queue_data($queue,$env{'request.course.sec'}, - \%queue,$cdom,$cnum); + $todo=&pick_from_queue_data($queue,undef,\%queue,$cdom,$cnum); &Apache::lonxml::debug("no sce $todo"); } # no user to grade @@ -1332,7 +1437,10 @@ sub get_from_queue { &Apache::lonxml::debug("got $todo"); # otherwise found someone so lets try to lock them # unless someone else already picked them - if (!&lock_key($queue,$todo)) { next; } + if (!&lock_key($queue,$todo)) { + $attempts++; + next; + } my (undef,$endtime)= &Apache::lonnet::get($queue,["$symb\0timestamp"], $cdom,$cnum); @@ -1351,6 +1459,7 @@ sub get_from_queue { &Apache::lonnet::del($queue,["$todo\0locked"], $cdom,$cnum); &Apache::lonxml::debug("del"); + $attempts++; next; } } @@ -1407,10 +1516,12 @@ sub select_user { $seclist.=''; } + my $studentdis = $student; + $studentdis =~ tr/:/@/; $result.=< +
    Statususerdata
    $title$unamelock'.$queue{$key}.'
    $uname'.$queue{$key}.'
    $titlelast queue modification time'. + $result.="
    '. &Apache::lonlocal::locallocaltime($queue{$key})."
    -
    + @@ -1143,8 +1229,9 @@ FORM $result.='
    '.&mt("In Progress").'$title$unamequeue entrySlot: '.$slot.' End time: '. + $result.= "".$fullname->{$uname.':'.$udom}. + " ($uname\@$udom) Slot: '.$slot.' End time: '. &Apache::lonlocal::locallocaltime($slot_data{'endtime'}). "
    - + @@ -1418,7 +1529,7 @@ sub select_user { $seclist - $fullname->{$student}$fullname->{$student} ($studentdis) RESULT } @@ -1438,6 +1549,9 @@ RESULT if ($status{'version'}) { $result .= ' '.&mt('Version').' '.$status{'version'}; } + if ($status{'grader'}) { + $result .= ' '.&mt('(Graded by [_1])',$status{'grader'}).' '; + } $result.= ''; if ($status{'reviewqueue'} eq 'enqueued') { $result .= &mt('Awaiting Review'); @@ -1641,7 +1755,7 @@ sub get_instance { $result.=&Apache::scripttag::xmlparse($dimension{$instance.'.criteria.'.$id}); $result.='

    '.$status_display.'

    '; if ($Apache::lonhomework::history{"resource.$version.0.$dim.$instance.$id.comment"}) { - $result.='

    '.$Apache::lonhomework::history{"resource.$version.0.$dim.$instance.$id.comment"}.'

    '; + $result.='

    '.&mt('Comment: [_1]',$Apache::lonhomework::history{"resource.$version.0.$dim.$instance.$id.comment"}).'

    '; } $result.=''; }