--- loncom/interface/slotrequest.pm 2006/04/24 23:23:02 1.58
+++ loncom/interface/slotrequest.pm 2009/01/23 21:34:47 1.86
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Handler for requesting to have slots added to a students record
#
-# $Id: slotrequest.pm,v 1.58 2006/04/24 23:23:02 albertel Exp $
+# $Id: slotrequest.pm,v 1.86 2009/01/23 21:34:47 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -36,12 +36,15 @@ use Apache::lonlocal;
use Apache::lonnet;
use Apache::lonnavmaps();
use Date::Manip;
+use lib '/home/httpd/lib/perl/';
+use LONCAPA;
sub fail {
my ($r,$code)=@_;
if ($code eq 'not_valid') {
$r->print('
'.&mt('Unable to understand what resource you wanted to sign up for.').'
');
-
+ } elsif ($code eq 'not_available') {
+ $r->print(''.&mt('No slots are available.').'
');
} elsif ($code eq 'not_allowed') {
$r->print(''.&mt('Not allowed to sign up or change reservations at this time.').'
');
} else {
@@ -74,7 +77,7 @@ sub end_page {
=cut
sub get_course {
- (undef,my $courseid)=&Apache::lonxml::whichuser();
+ (undef,my $courseid)=&Apache::lonnet::whichuser();
my $cdom=$env{'course.'.$courseid.'.domain'};
my $cnum=$env{'course.'.$courseid.'.num'};
return ($cnum,$cdom);
@@ -87,7 +90,7 @@ sub get_reservation_ids {
my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,
"^$slot_name\0");
- if (&network_error(%consumed)) {
+ if (&Apache::lonnet::error(%consumed)) {
return 'error: Unable to determine current status';
}
my ($tmp)=%consumed;
@@ -124,8 +127,9 @@ sub check_for_reservation {
my ($cnum,$cdom)=&get_course();
my %slots=&Apache::lonnet::get('slots', [@slots], $cdom, $cnum);
- if (&network_error($student) || &network_error($course) ||
- &network_error(%slots)) {
+ if (&Apache::lonnet::error($student)
+ || &Apache::lonnet::error($course)
+ || &Apache::lonnet::error(%slots)) {
return 'error: Unable to determine current status';
}
my @got;
@@ -161,6 +165,9 @@ sub check_for_reservation {
sub get_consumed_uniqueperiods {
my ($slots) = @_;
my $navmap=Apache::lonnavmaps::navmap->new;
+ if (!defined($navmap)) {
+ return 'error: Unable to determine current status';
+ }
my @problems = $navmap->retrieveResources(undef,
sub { $_[0]->is_problem() },1,0);
my %used_slots;
@@ -172,7 +179,8 @@ sub get_consumed_uniqueperiods {
my $course = &Apache::lonnet::EXT("resource.0.available",
$symb, $env{'user.domain'},
$env{'user.name'});
- if (&network_error($student) || &network_error($course)) {
+ if (&Apache::lonnet::error($student)
+ || &Apache::lonnet::error($course)) {
return 'error: Unable to determine current status';
}
foreach my $slot (split(/:/,$student), split(/:/, $course)) {
@@ -183,7 +191,7 @@ sub get_consumed_uniqueperiods {
if (!ref($slots)) {
my ($cnum,$cdom)=&get_course();
my %slots=&Apache::lonnet::get('slots', [keys(%used_slots)], $cdom, $cnum);
- if (&network_error(%slots)) {
+ if (&Apache::lonnet::error(%slots)) {
return 'error: Unable to determine current status';
}
$slots = \%slots;
@@ -209,9 +217,13 @@ sub check_for_conflict {
if (!ref($consumed_uniqueperiods)) {
$consumed_uniqueperiods = &get_consumed_uniqueperiods($slots);
- if (&network_error(%$consumed_uniqueperiods)) {
- return 'error: Unable to determine current status';
- }
+ if (ref($consumed_uniqueperiods) eq 'HASH') {
+ if (&Apache::lonnet::error(%$consumed_uniqueperiods)) {
+ return 'error: Unable to determine current status';
+ }
+ } else {
+ return 'error: Unable to determine current status';
+ }
}
my ($new_uniq_start,$new_uniq_end) = @{$new_slot->{'uniqueperiod'}};
@@ -224,15 +236,6 @@ sub check_for_conflict {
}
}
return undef;
-
-}
-
-sub network_error {
- my ($result) = @_;
- if ($result =~ /^(con_lost|no_such_host|error: [^2])/) {
- return 1;
- }
- return 0;
}
sub make_reservation {
@@ -243,15 +246,29 @@ sub make_reservation {
my $value=&Apache::lonnet::EXT("resource.0.availablestudent",$symb,
$env{'user.domain'},$env{'user.name'});
&Apache::lonxml::debug("value is $value ");
- if (&network_error($value)) {
+
+ my $use_slots = &Apache::lonnet::EXT("resource.0.useslots",$symb,
+ $env{'user.domain'},$env{'user.name'});
+ &Apache::lonxml::debug("use_slots is $use_slots ");
+
+ if (&Apache::lonnet::error($value)
+ || &Apache::lonnet::error($use_slots)) {
return 'error: Unable to determine current status';
}
+ my $parm_symb = $symb;
+ my $parm_level = 1;
+ if ($use_slots eq 'map' || $use_slots eq 'map_map') {
+ my ($map) = &Apache::lonnet::decode_symb($symb);
+ $parm_symb = &Apache::lonnet::symbread($map);
+ $parm_level = 2;
+ }
+
foreach my $other_slot (split(/:/, $value)) {
if ($other_slot eq $slot_name) {
my %consumed=&Apache::lonnet::dump('slot_reservations', $cdom,
$cnum, "^$slot_name\0");
- if (&network_error($value)) {
+ if (&Apache::lonnet::error($value)) {
return 'error: Unable to determine current status';
}
my $me=$env{'user.name'}.':'.$env{'user.domain'};
@@ -268,7 +285,7 @@ sub make_reservation {
if (!defined($max)) { $max=99999; }
my (@ids)=&get_reservation_ids($slot_name);
- if (&network_error(@ids)) {
+ if (&Apache::lonnet::error(@ids)) {
return 'error: Unable to determine current status';
}
my $last=0;
@@ -286,7 +303,7 @@ sub make_reservation {
my %reservation=('name' => $env{'user.name'}.':'.$env{'user.domain'},
'timestamp' => time,
- 'symb' => $symb);
+ 'symb' => $parm_symb);
my $success=&Apache::lonnet::newput('slot_reservations',
{"$slot_name\0$wanted" =>
@@ -300,7 +317,8 @@ sub make_reservation {
}
my $result=&Apache::lonparmset::storeparm_by_symb($symb,
'0_availablestudent',
- 1, $new_value, 'string',
+ $parm_level, $new_value,
+ 'string',
$env{'user.name'},
$env{'user.domain'});
&Apache::lonxml::debug("hrrm $result");
@@ -322,8 +340,8 @@ sub remove_registration {
my ($cnum,$cdom)=&get_course();
my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,
"^$slot_name\0");
- if (&network_error(%consumed)) {
- $r->print("".&mt('A network error has occured.').'
');
+ if (&Apache::lonnet::error(%consumed)) {
+ $r->print("".&mt('A network error has occurred.').'
');
return;
}
if (!%consumed) {
@@ -369,13 +387,13 @@ sub remove_registration_confirmation {
'no' => 'No',);
$r->print(<<"END_CONFIRM");
$msg
-
-
@@ -401,7 +419,11 @@ sub release_all_slot {
my ($result,$msg) =
&release_reservation($slot_name,$uname,$udom,
$consumed{$entry}{'symb'},$mgr);
- $r->print("$msg
");
+ if (!$result) {
+ $r->print(''.&mt($msg).'
');
+ } else {
+ $r->print("$msg
");
+ }
$r->rflush();
}
$r->print(''.
@@ -422,12 +444,16 @@ sub release_slot {
if ($mgr eq 'F'
&& defined($env{'form.symb'})) {
- $symb = $env{'form.symb'};
+ $symb = &unescape($env{'form.symb'});
}
my ($result,$msg) =
&release_reservation($slot_name,$uname,$udom,$symb,$mgr);
- $r->print("$msg
");
+ if (!$result) {
+ $r->print(''.&mt($msg).'
');
+ } else {
+ $r->print("$msg
");
+ }
if ($mgr eq 'F') {
$r->print(''.
@@ -448,9 +474,25 @@ sub release_reservation {
return (0,&mt('Not allowed to release Reservation: [_1], as it has already ended.',$description));
}
}
+
+ # if the reservation symb is for a map get a resource in that map
+ # to check slot parameters on
+ my $navmap=Apache::lonnavmaps::navmap->new;
+ if (!defined($navmap)) {
+ return (0,'error: Unable to determine current status');
+ }
+ my $passed_resource = $navmap->getBySymb($symb);
+ if ($passed_resource->is_map()) {
+ my ($a_resource) =
+ $navmap->retrieveResources($passed_resource,
+ sub {$_[0]->is_problem()},0,1);
+ $symb = $a_resource->symb();
+ }
+
# get parameter string, check for existance, rebuild string with the slot
- my @slots = split(/:/,&Apache::lonnet::EXT("resource.0.availablestudent",
- $symb,$udom,$uname));
+ my $student = &Apache::lonnet::EXT("resource.0.availablestudent",
+ $symb,$udom,$uname);
+ my @slots = split(/:/,$student);
my @new_slots;
foreach my $exist_slot (@slots) {
@@ -471,11 +513,23 @@ sub release_reservation {
}
}
+ my $use_slots = &Apache::lonnet::EXT("resource.0.useslots",
+ $symb,$udom,$uname);
+ &Apache::lonxml::debug("use_slots is $use_slots ");
+
+ if (&Apache::lonnet::error($use_slots)) {
+ return (0,'error: Unable to determine current status');
+ }
+
+ my $parm_level = 1;
+ if ($use_slots eq 'map' || $use_slots eq 'map_map') {
+ $parm_level = 2;
+ }
# store new parameter string
my $result=&Apache::lonparmset::storeparm_by_symb($symb,
'0_availablestudent',
- 1, $new_param, 'string',
- $uname,$udom);
+ $parm_level, $new_param,
+ 'string', $uname, $udom);
my $msg;
if ($mgr eq 'F') {
@@ -505,7 +559,7 @@ sub delete_slot {
if ($ret eq 'ok') {
$r->print("Slot $slot_name marked as deleted.
");
} else {
- $r->print(" An error ($ret) occurse when attempting to delete Slot $slot_name .
");
+ $r->print(" An error ($ret) occurse when attempting to delete Slot $slot_name .
");
}
} else {
if (%consumed) {
@@ -526,17 +580,19 @@ sub return_link {
}
sub get_slot {
- my ($r,$symb)=@_;
+ my ($r,$symb,$conflictable_slot,$inhibit_return_link)=@_;
my %slot=&Apache::lonnet::get_slot($env{'form.slotname'});
my $slot_name=&check_for_conflict($symb,$env{'form.slotname'},\%slot);
if ($slot_name =~ /^error: (.*)/) {
- $r->print("An error occured while attempting to make a reservation. ($1)
");
+ $r->print(''
+ .&mt('An error occurred while attempting to make a reservation. ([_1])',$1)
+ .'
');
&return_link($r);
- return;
+ return 0;
}
- if ($slot_name) {
+ if ($slot_name && $slot_name ne $conflictable_slot) {
my %slot=&Apache::lonnet::get_slot($slot_name);
my $description1=&get_description($slot_name,\%slot);
%slot=&Apache::lonnet::get_slot($env{'form.slotname'});
@@ -544,7 +600,7 @@ sub get_slot {
$r->print("Already have a reservation: $description1
");
if ($slot_name ne $env{'form.slotname'}) {
$r->print(<
+
+ Failed to reserve a spot for $description.
-
?
or
-
@@ -607,8 +673,8 @@ or
or
STUFF
- &return_link($r);
- return;
+ if (!$inhibit_return_link) { &return_link($r); }
+ return 0;
}
sub allowed_slot {
@@ -616,8 +682,7 @@ sub allowed_slot {
#already started
if ($slot->{'starttime'} < time) {
- # all open slot to be schedulable
- #return 0;
+ return 0;
}
&Apache::lonxml::debug("$slot_name starttime good");
@@ -653,6 +718,16 @@ sub allowed_slot {
split(',',$slot->{'allowedsections'}))) {
$userallowed=1;
}
+ if (defined($env{'request.course.groups'})) {
+ my @groups = split(/:/,$env{'request.course.groups'});
+ my @allowed_sec = split(',',$slot->{'allowedsections'});
+ foreach my $group (@groups) {
+ if (grep {$_ eq $group} (@allowed_sec)) {
+ $userallowed=1;
+ last;
+ }
+ }
+ }
}
&Apache::lonxml::debug("$slot_name sections is $userallowed");
@@ -679,7 +754,9 @@ sub allowed_slot {
my $conflict = &check_for_conflict($symb,$slot_name,$slot,$slots,
$consumed_uniqueperiods);
- if ($conflict) {
+ if ($conflict =~ /^error: /) {
+ return 0;
+ } elsif ($conflict ne '') {
if ($slots->{$conflict}{'starttime'} < time) {
return 0;
}
@@ -705,10 +782,29 @@ sub show_choices {
my ($cnum,$cdom)=&get_course();
my %slots=&Apache::lonnet::dump('slots',$cdom,$cnum);
my $consumed_uniqueperiods = &get_consumed_uniqueperiods(\%slots);
+ if (ref($consumed_uniqueperiods) eq 'HASH') {
+ if (&Apache::lonnet::error(%$consumed_uniqueperiods)) {
+ $r->print(''.
+ &mt('An error occurred determining slot availability').
+ ' ');
+ return;
+ }
+ } elsif ($consumed_uniqueperiods =~ /^error: /) {
+ $r->print(''.
+ &mt('An error occurred determining slot availability').
+ ' ');
+ return;
+ }
my $available;
- $r->print('');
&Apache::lonxml::debug("Checking Slots");
my @got_slots=&check_for_reservation($symb,'allslots');
+ if ($got_slots[0] =~ /^error: /) {
+ $r->print(''.
+ &mt('An error occurred determining slot availability').
+ ' ');
+ return;
+ }
+ $r->print('');
foreach my $slot (sort
{ return $slots{$a}->{'starttime'} <=> $slots{$b}->{'starttime'} }
(keys(%slots))) {
@@ -727,20 +823,26 @@ sub show_choices {
my $text=&mt('Select');
my $command='get';
if (grep(/^\Q$slot\E$/,@got_slots)) {
- $text=&mt('Free Reservation');
+ $text=&mt('Drop Reservation');
$command='release';
} else {
my $conflict = &check_for_conflict($symb,$slot,$slots{$slot},
\%slots,
$consumed_uniqueperiods);
- if ($conflict) {
- $text=&mt('Change Reservation');
- $command='get';
- }
+ if ($conflict) {
+ if ($conflict =~ /^error: /) {
+ $r->print(''
+ .&mt('Slot: [_1] has unknown status.',$description)
+ .' ');
+ } else {
+ $text=&mt('Change Reservation');
+ $command='get';
+ }
+ }
}
- my $escsymb=&Apache::lonnet::escape($symb);
+ my $escsymb=&escape($symb);
$form=<
+
+ $r->print('
');
$r->print('');
$r->print('
@@ -1001,23 +1111,28 @@ sub show_table {
$r->print('');
$r->print('
');
my $linkstart='
-
- ');
+ $r->print(&Apache::loncommon::start_data_table().
+ &Apache::loncommon::start_data_table_header_row().'
+ ');
foreach my $which (@show_order) {
if ($which ne 'proctor' && exists($show{$which})) {
$r->print(''.$linkstart.$which.'">'.$show_fields{$which}.' ');
}
}
+ $r->print(&Apache::loncommon::end_data_table_header_row());
my %name_cache;
my $slotsort = sub {
- if ($env{'form.order'}=~/^(type|description|endtime|startreserve|maxspace|ip|symb|allowedsections|allowedusers)$/) {
+ if ($env{'form.order'}=~/^(type|description|endtime|startreserve|ip|symb|allowedsections|allowedusers)$/) {
if (lc($slots{$a}->{$env{'form.order'}})
ne lc($slots{$b}->{$env{'form.order'}})) {
return (lc($slots{$a}->{$env{'form.order'}})
cmp lc($slots{$b}->{$env{'form.order'}}));
}
+ } elsif ($env{'form.order'} eq 'space') {
+ if ($slots{$a}{'maxspace'} ne $slots{$b}{'maxspace'}) {
+ return ($slots{$a}{'maxspace'} cmp $slots{$b}{'maxspace'});
+ }
} elsif ($env{'form.order'} eq 'name') {
if (lc($a) cmp lc($b)) {
return lc($a) cmp lc($b);
@@ -1037,6 +1152,14 @@ sub show_table {
}
return $slots{$a}->{'starttime'} <=> $slots{$b}->{'starttime'};
};
+
+ my %consumed;
+ if (exists($show{'scheduled'}) || exists($show{'space'}) ) {
+ %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum);
+ my ($tmp)=%consumed;
+ if ($tmp =~ /^error: /) { undef(%consumed); }
+ }
+
foreach my $slot (sort $slotsort (keys(%slots))) {
if (!&to_show($slot,$slots{$slot},$when,
$env{'form.deleted'},$name_filter)) { next; }
@@ -1045,18 +1168,19 @@ sub show_table {
#next;
}
my $description=&get_description($slot,$slots{$slot});
- my $ids;
- if (exists($show{'scheduled'})) {
- my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,
- "^$slot\0");
- my ($tmp)=%consumed;
- if ($tmp !~ /^error: /) {
+ my ($id_count,$ids);
+
+ if (exists($show{'scheduled'}) || exists($show{'space'}) ) {
+ my $re_str = "$slot\0";
+ my @this_slot = grep(/^\Q$re_str\E/,keys(%consumed));
+ $id_count = scalar(@this_slot);
+ if (exists($show{'scheduled'})) {
foreach my $entry (sort { $consumed{$a}{name} cmp
$consumed{$b}{name} }
- (keys(%consumed))) {
+ (@this_slot)) {
my (undef,$id)=split("\0",$entry);
my ($uname,$udom) = split(':',$consumed{$entry}{'name'});
- $ids.= '';
+ $ids.= '';
foreach my $item (@stu_display_order) {
if ($stu_display{$item}) {
if ($item eq 'fullname') {
@@ -1067,7 +1191,7 @@ sub show_table {
}
}
$ids.=&remove_link($slot,$entry,$uname,$udom,
- $consumed{$entry}{'symb'}).' ';
+ $consumed{$entry}{'symb'}).' ';
}
}
}
@@ -1081,7 +1205,7 @@ sub show_table {
my $unique;
if (ref($slots{$slot}{'uniqueperiod'})) {
- $unique=localtime($slots{$slot}{'uniqueperiod'}[0]).','.
+ $unique=localtime($slots{$slot}{'uniqueperiod'}[0]).', '.
localtime($slots{$slot}{'uniqueperiod'}[1]);
}
@@ -1122,7 +1246,7 @@ sub show_table {
if (exists($show{'proctor'})) {
$rowspan=2;
@proctors= map {
- my ($uname,$udom)=split(/@/,$_);
+ my ($uname,$udom)=split(/:/,$_);
my $fullname=$name_cache{$_};
if (!defined($fullname)) {
$fullname = &Apache::loncommon::plainname($uname,$udom);
@@ -1139,7 +1263,7 @@ sub show_table {
EDITLINK
my $delete=(<<"DELETELINK");
-Delete
+Delete
DELETELINK
my $remove_all=&remove_link($slot,'remove all').' ';
@@ -1150,7 +1274,10 @@ DELETELINK
undef($remove_all);
}
- $r->print(" \n$edit $delete \n");
+ my $row_start=&Apache::loncommon::start_data_table_row();
+ my $row_end=&Apache::loncommon::end_data_table_row();
+ $r->print($row_start.
+ "\n$edit $delete \n");
if (exists($show{'name'})) {
$colspan++;$r->print("$slot ");
}
@@ -1172,8 +1299,15 @@ DELETELINK
if (exists($show{'secret'})) {
$colspan++;$r->print("$slots{$slot}{'secret'} \n");
}
- if (exists($show{'maxspace'})) {
- $colspan++;$r->print("$slots{$slot}{'maxspace'} \n");
+ if (exists($show{'space'})) {
+ my $display = $id_count;
+ if ($slots{$slot}{'maxspace'}>0) {
+ $display.='/'.$slots{$slot}{'maxspace'};
+ if ($slots{$slot}{'maxspace'} <= $id_count) {
+ $display = ''.$display.' (full) ';
+ }
+ }
+ $colspan++;$r->print("$display \n");
}
if (exists($show{'ip'})) {
$colspan++;$r->print("$slots{$slot}{'ip'} \n");
@@ -1187,18 +1321,22 @@ DELETELINK
if (exists($show{'allowedusers'})) {
$colspan++;$r->print("$allowedusers \n");
}
+ if (exists($show{'uniqueperiod'})) {
+ $colspan++;$r->print("$unique \n");
+ }
if (exists($show{'scheduled'})) {
- $colspan++;$r->print("$remove_all $ids \n \n");
+ $colspan++;$r->print(" $remove_all $ids \n");
}
+ $r->print("$row_end\n");
if (exists($show{'proctor'})) {
$r->print(<
+$row_start
$proctors
-
+$row_end
STUFF
}
}
- $r->print('
');
+ $r->print('
');
}
sub upload_start {
@@ -1235,9 +1373,11 @@ sub csvuploadmap_header {
my $checked=(($env{'form.noFirstLine'})?' checked="checked"':'');
my $ignore=&mt('Ignore First Line');
+ my $help_field = &Apache::loncommon::help_open_topic('Slot SelectingField');
+
$r->print(<
-Identify fields
+Identify fields $help_field
Total number of records found in file: $distotal
Enter as many fields as you can. The system will inform you and bring you back
to this page if the data selected is insufficient to create the slots.
@@ -1471,7 +1611,7 @@ sub csv_upload_assign {
}
$r->print("Created $countdone slots\n
");
foreach my $error (@errors) {
- $r->print("$error\n
");
+ $r->print("$error
\n");
}
&show_table($r,$mgr);
return '';
@@ -1525,11 +1665,17 @@ sub handler {
&csv_upload_map($r);
}
} else {
- my $symb=&Apache::lonnet::unescape($env{'form.symb'});
+ my $symb=&unescape($env{'form.symb'});
+ if (!defined($symb)) {
+ &fail($r,'not_valid');
+ return OK;
+ }
my (undef,undef,$res)=&Apache::lonnet::decode_symb($symb);
my $useslots = &Apache::lonnet::EXT("resource.0.useslots",$symb);
- if ($useslots ne 'resource') {
- &fail($r,'not_valid');
+ if ($useslots ne 'resource'
+ && $useslots ne 'map'
+ && $useslots ne 'map_map') {
+ &fail($r,'not_available');
return OK;
}
$env{'request.symb'}=$symb;
@@ -1549,8 +1695,8 @@ sub handler {
} elsif ($env{'form.command'} eq 'get') {
&get_slot($r,$symb);
} elsif ($env{'form.command'} eq 'change') {
- if (&release_slot($r,$symb,$env{'form.releaseslot'},1)) {
- &get_slot($r,$symb);
+ if (&get_slot($r,$symb,$env{'form.releaseslot'},1)) {
+ &release_slot($r,$symb,$env{'form.releaseslot'});
}
} else {
$r->print("Unknown command: ".$env{'form.command'}."
");