--- loncom/interface/lonnavmaps.pm 2008/12/06 20:36:51 1.420 +++ loncom/interface/lonnavmaps.pm 2009/08/15 18:46:22 1.423.2.2 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Navigate Maps Handler # -# $Id: lonnavmaps.pm,v 1.420 2008/12/06 20:36:51 schafran Exp $ +# $Id: lonnavmaps.pm,v 1.423.2.2 2009/08/15 18:46:22 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -31,7 +31,7 @@ =head1 NAME -Apache::lonnavmaps.pm +Apache::lonnavmaps - Subroutines to handle and render the navigation =head1 SYNOPSIS @@ -530,6 +530,9 @@ my %colormap = # is not yet done and due in less than 24 hours my $hurryUpColor = "#FF0000"; +my $future_slots_checked = 0; +my $future_slots = 0; + sub close { if ($env{'environment.remotenavmap'} ne 'on') { return ''; } return(<OPEN_LATER) { return &mt("Open ") .timeToHumanString($open,'start'); } + if ($res->simpleStatus($part) == $res->OPEN) { + unless (&Apache::lonnet::allowed('mgr',$env{'request.course.id'})) { + my ($slot_status,$slot_time,$slot_name)=$res->check_for_slot($part); + if ($slot_status == $res->UNKNOWN) { + return &mt('Reservation status unknown'); + } elsif ($slot_status == $res->RESERVED) { + return &mt('Reserved - ends [_1]', + timeToHumanString($slot_time,'end')); + } elsif ($slot_status == $res->RESERVED_LOCATION) { + return &mt('Reserved - specific location(s) - ends [_1]', + timeToHumanString($slot_time,'end')); + } elsif ($slot_status == $res->RESERVED_LATER) { + return &mt('Reserved - next open [_1]', + timeToHumanString($slot_time,'start')); + } elsif ($slot_status == $res->RESERVABLE) { + return &mt('Reservable ending [_1]', + timeToHumanString($slot_time,'end')); + } elsif ($slot_status == $res->RESERVABLE_LATER) { + return &mt('Reservable starting [_1]', + timeToHumanString($slot_time,'start')); + } elsif ($slot_status == $res->NOT_IN_A_SLOT) { + return &mt('Reserve a time/place to work'); + } elsif ($slot_status == $res->NOTRESERVABLE) { + return &mt('Reservation not available'); + } elsif ($slot_status == $res->WAITING_FOR_GRADE) { + return &mt('Submission in grading queue'); + } + } + } if ($status == $res->OPEN) { if ($due) { if ($res->is_practice()) { @@ -670,7 +702,7 @@ sub getDescription { my $maxtries = $res->maxtries($part); my $triesString = ""; if ($tries && $maxtries) { - $triesString = '('.&mt('[_1] of [_2] tries used',$tries,$maxtries).')'; + $triesString = '('.&mt('[_1] of [quant,_2,try,tries] used',$tries,$maxtries).')'; if ($maxtries > 1 && $maxtries - $tries == 1) { $triesString = "$triesString"; } @@ -865,7 +897,8 @@ sub render_resource { my $location=&Apache::loncommon::lonhttpdurl("/adm/lonIcons"); # If this is a new branch, label it so if ($params->{'isNewBranch'}) { - $newBranchText = "Branch"; + $newBranchText = ''.
+                         &mt('Branch').''; } # links to open and close the folder @@ -1269,7 +1302,7 @@ sub render { if (!defined($navmap)) { $navmap = Apache::lonnavmaps::navmap->new(); if (!defined($navmap)) { - # no londer in course + # no longer in course return ''.&mt('No course selected').'
'.&mt('Select a course').'
'; } @@ -1337,6 +1370,11 @@ sub render { # Step 1: Check to see if we have a navmap if (!defined($navmap)) { $navmap = Apache::lonnavmaps::navmap->new(); + if (!defined($navmap)) { + # no longer in course + return ''.&mt('No course selected').'
+ '.&mt('Select a course').'
'; + } } # See if we're being passed a specific map @@ -1389,15 +1427,15 @@ sub render { my $location=&Apache::loncommon::lonhttpdurl("/adm/lonMisc"); if ($navmap->{LAST_CHECK}) { $result .= - ' '.&mt('New discussion since').' '. + ' '.&mt('New discussion since').' '. strftime("%A, %b %e at %I:%M %P", localtime($navmap->{LAST_CHECK})). '  '. - ' '.&mt('New message (click to open)').'

'. + ' '.&mt('New message (click to open)').'

'. ''; } else { $result .= '  '. - ' '.&mt('Discussions').''. - '   '.&mt('New message (click to open)'). + ' '.&mt('Discussions').''. + '   '.&mt('New message (click to open)'). ''; } @@ -1828,7 +1866,7 @@ ENDBLOCK $result.='}

- '."\n"; foreach my $link (@linkorder) { if (defined($linkitems->{$link})) { if ($linkitems->{$link}{'text'} ne '') { @@ -1839,7 +1877,7 @@ ENDBLOCK } $result .= '  -
'."\n"; + '."\n"; return $result; } @@ -3939,6 +3977,35 @@ sub awarded { if (!defined($part)) { $part = '0'; } return $self->{NAV_MAP}->{STUDENT_DATA}->{$self->symb()}->{'resource.'.$part.'.awarded'}; } +sub taskversion { + my $self = shift; my $part = shift; + $self->{NAV_MAP}->get_user_data(); + if (!defined($part)) { $part = '0'; } + return $self->{NAV_MAP}->{STUDENT_DATA}->{$self->symb()}->{'resource.'.$part.'.version'}; +} +sub taskstatus { + my $self = shift; my $part = shift; + $self->{NAV_MAP}->get_user_data(); + if (!defined($part)) { $part = '0'; } + return $self->{NAV_MAP}->{STUDENT_DATA}->{$self->symb()}->{'resource.'.$self->taskversion($part).'.'.$part.'.status'}; +} +sub solved { + my $self = shift; my $part = shift; + $self->{NAV_MAP}->get_user_data(); + if (!defined($part)) { $part = '0'; } + return $self->{NAV_MAP}->{STUDENT_DATA}->{$self->symb()}->{'resource.'.$part.'.solved'}; +} +sub checkedin { + my $self = shift; my $part = shift; + $self->{NAV_MAP}->get_user_data(); + if (!defined($part)) { $part = '0'; } + if ($self->is_task()) { + my $version = $self->taskversion($part); + return ($self->{NAV_MAP}->{STUDENT_DATA}->{$self->symb()}->{'resource.'.$version .'.'.$part.'.checkedin'},$self->{NAV_MAP}->{STUDENT_DATA}->{$self->symb()}->{'resource.'.$version .'.'.$part.'.checkedin.slot'}); + } else { + return ($self->{NAV_MAP}->{STUDENT_DATA}->{$self->symb()}->{'resource.'.$part.'.checkedin'},$self->{NAV_MAP}->{STUDENT_DATA}->{$self->symb()}->{'resource.'.$part.'.checkedin.slot'}); + } +} # this should work exactly like the copy in lonhomework.pm sub duedate { (my $self, my $part) = @_; @@ -4034,6 +4101,14 @@ sub part_display { } return $display; } +sub slot_control { + my $self=shift(); my $part = shift(); + if (!defined($part)) { $part = '0'; } + my $useslots = $self->parmval("useslots", $part); + my $availablestudent = $self->parmval("availablestudent", $part); + my $available = $self->parmval("available", $part); + return ($useslots,$availablestudent,$available); +} # Multiple things need this sub getReturnHash { @@ -4682,6 +4757,17 @@ sub TRIES_LEFT { return 20; } sub ANSWER_SUBMITTED { return 21; } sub PARTIALLY_CORRECT{ return 22; } +sub RESERVED_LATER { return 30; } +sub RESERVED { return 31; } +sub RESERVED_LOCATION { return 32; } +sub RESERVABLE { return 33; } +sub RESERVABLE_LATER { return 34; } +sub NOTRESERVABLE { return 35; } +sub NOT_IN_A_SLOT { return 36; } +sub NEEDS_CHECKIN { return 37; } +sub WAITING_FOR_GRADE { return 38; } +sub UNKNOWN { return 39; } + sub status { my $self = shift; my $part = shift; @@ -4773,6 +4859,108 @@ sub status { return OPEN; } +sub check_for_slot { + my $self = shift; + my $part = shift; + my ($use_slots,$available,$availablestudent) = $self->slot_control($part); + if (($use_slots ne '') && ($use_slots !~ /^\s*no\s*$/i)) { + my @slots = (split(/:/,$availablestudent),split(/:/,$available)); + my $cid=$env{'request.course.id'}; + my $cdom=$env{'course.'.$cid.'.domain'}; + my $cnum=$env{'course.'.$cid.'.num'}; + my $now = time; + if (@slots > 0) { + my %slots=&Apache::lonnet::get('slots',[@slots],$cdom,$cnum); + if (&Apache::lonnet::error(%slots)) { + return (UNKNOWN); + } + my @sorted_slots = &Apache::loncommon::sorted_slots(\@slots,\%slots); + my ($checkedin,$checkedinslot); + foreach my $slot_name (@sorted_slots) { + next if (!defined($slots{$slot_name}) || + !ref($slots{$slot_name})); + my $end = $slots{$slot_name}->{'endtime'}; + my $start = $slots{$slot_name}->{'starttime'}; + my $ip = $slots{$slot_name}->{'ip'}; + if ($self->simpleStatus() == OPEN) { + my $startreserve = $slots{$slot_name}->{'startreserve'}; + my @proctors; + if ($slots{$slot_name}->{'proctor'} ne '') { + @proctors = split(',',$slots{$slot_name}->{'proctor'}); + } + if ($end > $now) { + ($checkedin,$checkedinslot) = $self->checkedin(); + if ($startreserve < $now) { + if ($start > $now) { + return (RESERVED_LATER,$start,$slot_name); + } else { + if ($ip ne '') { + if (!&Apache::loncommon::check_ip_acc($ip)) { + return (RESERVED_LOCATION,$ip,$slot_name); + } + } + if (@proctors > 0) { + unless ((grep(/^\Q$checkedin\E/,@proctors)) && + ($checkedinslot eq $slot_name)) { + return (NEEDS_CHECKIN,undef,$slot_name); + } + } + return (RESERVED,$end,$slot_name); + } + } else { + if ($start > $now) { + return (RESERVABLE,$startreserve,$slot_name); + } + } + } + } + } + my ($is_correct,$got_grade); + if ($self->is_task()) { + my $taskstatus = $self->taskstatus(); + $is_correct = (($taskstatus eq 'pass') || + ($self->solved() =~ /^correct_/)); + $got_grade = ($self->solved() =~ /^(?:pass|fail)$/); + } else { + $got_grade = 1; + $is_correct = ($self->solved() =~ /^correct_/); + } + ($checkedin,$checkedinslot) = $self->checkedin(); + if ($checkedin) { + if (!$got_grade) { + return (WAITING_FOR_GRADE); + } elsif ($is_correct) { + return (CORRECT); + } + } + return(NOT_IN_A_SLOT); + } else { + if (!$future_slots_checked) { + $future_slots = &get_future_slots($cdom,$cnum,$now); + $future_slots_checked = 1; + } + if ($future_slots) { + return(NOT_IN_A_SLOT); + } + return(NOTRESERVABLE); + } + } + return; +} + +sub get_future_slots { + my ($cdom,$cnum,$now) = @_; + my %slots=&Apache::lonnet::dump('slots',$cdom,$cnum); + my $future_slots = 0; + foreach my $slot (keys(%slots)) { + if (($slots{$slot}->{'starttime'} > $now) && + ($slots{$slot}->{'endtime'} > $now)) { + $future_slots ++; + } + } + return $future_slots; +} + sub CLOSED { return 23; } sub ERROR { return 24; } 500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.