Diff for /loncom/interface/slotrequest.pm between versions 1.15 and 1.74

version 1.15, 2005/09/13 07:31:08 version 1.74, 2007/04/10 23:26:49
Line 34  use Apache::Constants qw(:common :http : Line 34  use Apache::Constants qw(:common :http :
 use Apache::loncommon();  use Apache::loncommon();
 use Apache::lonlocal;  use Apache::lonlocal;
 use Apache::lonnet;  use Apache::lonnet;
   use Apache::lonnavmaps();
 use Date::Manip;  use Date::Manip;
   use lib '/home/httpd/lib/perl/';
   use LONCAPA;
   
 sub fail {  sub fail {
     my ($r,$code)=@_;      my ($r,$code)=@_;
     if ($code eq 'not_valid') {      if ($code eq 'not_valid') {
  $r->print('<p>'.&mt('Unable to understand what resource you wanted to sign up for.').'</p>');   $r->print('<p>'.&mt('Unable to understand what resource you wanted to sign up for.').'</p>');
       } elsif ($code eq 'not_available') {
    $r->print('<p>'.&mt('No slots are available.').'</p>');
     } elsif ($code eq 'not_allowed') {      } elsif ($code eq 'not_allowed') {
  $r->print('<p>'.&mt('Not allowed to sign up or change reservations at this time.').'</p>');   $r->print('<p>'.&mt('Not allowed to sign up or change reservations at this time.').'</p>');
     } else {      } else {
  $r->print('<p>'.&mt('Failed.').'</p>');   $r->print('<p>'.&mt('Failed.').'</p>');
     }      }
           
     $r->print('<p><a href="/adm/flip?postdata=return:">'.      &return_link($r);
       &mt('Return to last resource').'</a></p>');  
     &end_page($r);      &end_page($r);
 }  }
   
 sub start_page {  sub start_page {
     my ($r)=@_;      my ($r,$title)=@_;
     my $html=&Apache::lonxml::xmlbegin();      $r->print(&Apache::loncommon::start_page($title));
     $r->print($html.'<head><title>'.  
       &mt('Request another Worktime').'</title></head>');  
     $r->print(&Apache::loncommon::bodytag('Requesting another Worktime'));  
     $r->print('<p>'.$env{'form.command'}.'</p>');  
 }  }
   
 sub end_page {  sub end_page {
     my ($r)=@_;      my ($r)=@_;
     $r->print(&Apache::loncommon::endbodytag().'</html>');      $r->print(&Apache::loncommon::end_page());
 }  }
   
 =pod  =pod
Line 78  sub end_page { Line 77  sub end_page {
 =cut  =cut
   
 sub get_course {  sub get_course {
     (undef,my $courseid)=&Apache::lonxml::whichuser();      (undef,my $courseid)=&Apache::lonnet::whichuser();
     my $cdom=$env{'course.'.$courseid.'.domain'};      my $cdom=$env{'course.'.$courseid.'.domain'};
     my $cnum=$env{'course.'.$courseid.'.num'};      my $cnum=$env{'course.'.$courseid.'.num'};
     return ($cnum,$cdom);      return ($cnum,$cdom);
Line 91  sub get_reservation_ids { Line 90  sub get_reservation_ids {
   
     my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,      my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,
        "^$slot_name\0");         "^$slot_name\0");
           if (&Apache::lonnet::error(%consumed)) { 
    return 'error: Unable to determine current status';
       }
     my ($tmp)=%consumed;      my ($tmp)=%consumed;
     if ($tmp=~/^error: 2 / ) {      if ($tmp=~/^error: 2 / ) {
  return 0;   return 0;
Line 113  sub space_available { Line 114  sub space_available {
 }  }
   
 sub check_for_reservation {  sub check_for_reservation {
     my ($symb)=@_;      my ($symb,$mode)=@_;
     my $student = &Apache::lonnet::EXT("resource.0.availablestudent", $symb,      my $student = &Apache::lonnet::EXT("resource.0.availablestudent", $symb,
        $env{'user.domain'}, $env{'user.name'});         $env{'user.domain'}, $env{'user.name'});
   
Line 126  sub check_for_reservation { Line 127  sub check_for_reservation {
     my ($cnum,$cdom)=&get_course();      my ($cnum,$cdom)=&get_course();
     my %slots=&Apache::lonnet::get('slots', [@slots], $cdom, $cnum);      my %slots=&Apache::lonnet::get('slots', [@slots], $cdom, $cnum);
   
     foreach my $slot_name (@slots) {      if (&Apache::lonnet::error($student) 
    || &Apache::lonnet::error($course)
    || &Apache::lonnet::error(%slots)) {
    return 'error: Unable to determine current status';
       }    
       my @got;
       foreach my $slot_name (sort {
    if (ref($slots{$a}) && ref($slots{$b})) {
       return $slots{$a}{'starttime'} <=> $slots{$b}{'starttime'}
    }
    if (ref($slots{$a})) { return -1;}
    if (ref($slots{$b})) { return 1;}
    return 0;
       } @slots) {
  next if (!defined($slots{$slot_name}) ||   next if (!defined($slots{$slot_name}) ||
  !ref($slots{$slot_name}));   !ref($slots{$slot_name}));
  &Apache::lonxml::debug(time." $slot_name ".   &Apache::lonxml::debug(time." $slot_name ".
Line 135  sub check_for_reservation { Line 149  sub check_for_reservation {
  if ($slots{$slot_name}->{'endtime'} > time &&   if ($slots{$slot_name}->{'endtime'} > time &&
     $slots{$slot_name}->{'startreserve'} < time) {      $slots{$slot_name}->{'startreserve'} < time) {
     # between start of reservation times and end of slot      # between start of reservation times and end of slot
     return($slot_name, $slots{$slot_name});      if ($mode eq 'allslots') {
    push(@got,$slot_name);
       } else {
    return($slot_name, $slots{$slot_name});
       }
  }   }
     }      }
       if ($mode eq 'allslots' && @got) {
    return @got;
       }
     return (undef,undef);      return (undef,undef);
 }  }
   
   sub get_consumed_uniqueperiods {
       my ($slots) = @_;
       my $navmap=Apache::lonnavmaps::navmap->new;
       my @problems = $navmap->retrieveResources(undef,
         sub { $_[0]->is_problem() },1,0);
       my %used_slots;
       foreach my $problem (@problems) {
    my $symb = $problem->symb();
    my $student = &Apache::lonnet::EXT("resource.0.availablestudent",
      $symb, $env{'user.domain'},
      $env{'user.name'});
    my $course =  &Apache::lonnet::EXT("resource.0.available",
      $symb, $env{'user.domain'},
      $env{'user.name'});
    if (&Apache::lonnet::error($student) 
       || &Apache::lonnet::error($course)) {
       return 'error: Unable to determine current status';
    }
    foreach my $slot (split(/:/,$student), split(/:/, $course)) {
       $used_slots{$slot}=1;
    }
       }
   
       if (!ref($slots)) {
    my ($cnum,$cdom)=&get_course();
    my %slots=&Apache::lonnet::get('slots', [keys(%used_slots)], $cdom, $cnum);
    if (&Apache::lonnet::error(%slots)) {
       return 'error: Unable to determine current status';
    }
    $slots = \%slots;
       }
   
       my %consumed_uniqueperiods;
       foreach my $slot_name (keys(%used_slots)) {
    next if (!defined($slots->{$slot_name}) ||
    !ref($slots->{$slot_name}));
   
           next if (!defined($slots->{$slot_name}{'uniqueperiod'}) ||
    !ref($slots->{$slot_name}{'uniqueperiod'}));
    $consumed_uniqueperiods{$slot_name} = 
       $slots->{$slot_name}{'uniqueperiod'};
       }
       return \%consumed_uniqueperiods;
   }
   
 sub check_for_conflict {  sub check_for_conflict {
     my ($symb,$new_slot_name)=@_;      my ($symb,$new_slot_name,$new_slot,$slots,$consumed_uniqueperiods)=@_;
     my $student = &Apache::lonnet::EXT("resource.0.availablestudent", $symb,  
        $env{'user.domain'}, $env{'user.name'});      if (!defined($new_slot->{'uniqueperiod'})) { return undef; }
     my $course = &Apache::lonnet::EXT("resource.0.available", $symb,  
       $env{'user.domain'}, $env{'user.name'});  
     my @slots = (split(/:/,$student), split(/:/, $course));  
     my ($cnum,$cdom)=&get_course();  
     my %slots=&Apache::lonnet::get('slots', [@slots], $cdom, $cnum);  
     foreach my $slot_name (@slots) {  
  next if (!defined($slots{$slot_name}) ||  
  !ref($slots{$slot_name}));  
   
         next if (!defined($slots{$slot_name}->{'uniqueperiod'}) ||      if (!ref($consumed_uniqueperiods)) {
  !ref($slots{$slot_name}->{'uniqueperiod'}));   $consumed_uniqueperiods = &get_consumed_uniqueperiods($slots);
  my ($start,$end)=@{$slots{$slot_name}->{'uniqueperiod'}};   if (&Apache::lonnet::error(%$consumed_uniqueperiods)) {
  if ($start<time && time < $end) {      return 'error: Unable to determine current status';
    }
       }
       
       my ($new_uniq_start,$new_uniq_end) = @{$new_slot->{'uniqueperiod'}};
       foreach my $slot_name (keys(%$consumed_uniqueperiods)) {
    my ($start,$end)=@{$consumed_uniqueperiods->{$slot_name}};
    if (!
       ($start < $new_uniq_start &&  $end < $new_uniq_start) ||
       ($start > $new_uniq_end   &&  $end > $new_uniq_end  )) {
     return $slot_name;      return $slot_name;
  }   }
     }      }
Line 173  sub make_reservation { Line 240  sub make_reservation {
     my $value=&Apache::lonnet::EXT("resource.0.availablestudent",$symb,      my $value=&Apache::lonnet::EXT("resource.0.availablestudent",$symb,
    $env{'user.domain'},$env{'user.name'});     $env{'user.domain'},$env{'user.name'});
     &Apache::lonxml::debug("value is  $value<br />");      &Apache::lonxml::debug("value is  $value<br />");
   
       my $use_slots = &Apache::lonnet::EXT("resource.0.useslots");
       &Apache::lonxml::debug("use_slots is  $use_slots<br />");
   
       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)) {      foreach my $other_slot (split(/:/, $value)) {
  if ($other_slot eq $slot_name) {   if ($other_slot eq $slot_name) {
     my %consumed=&Apache::lonnet::dump('slot_reservations', $cdom,      my %consumed=&Apache::lonnet::dump('slot_reservations', $cdom,
        $cnum, "^$slot_name\0");            $cnum, "^$slot_name\0");   
       if (&Apache::lonnet::error($value)) { 
     my $me=$env{'user.name'}.'@'.$env{'user.domain'};   return 'error: Unable to determine current status';
       }
       my $me=$env{'user.name'}.':'.$env{'user.domain'};
     foreach my $key (keys(%consumed)) {      foreach my $key (keys(%consumed)) {
  if ($consumed{$key}->{'name'} eq $me) {   if ($consumed{$key}->{'name'} eq $me) {
     my $num=(split('\0',$key))[1];      my $num=(split('\0',$key))[1];
Line 192  sub make_reservation { Line 278  sub make_reservation {
     if (!defined($max)) { $max=99999; }      if (!defined($max)) { $max=99999; }
   
     my (@ids)=&get_reservation_ids($slot_name);      my (@ids)=&get_reservation_ids($slot_name);
       if (&Apache::lonnet::error(@ids)) { 
    return 'error: Unable to determine current status';
       }
     my $last=0;      my $last=0;
     foreach my $id (@ids) {      foreach my $id (@ids) {
  my $num=(split('\0',$id))[1];   my $num=(split('\0',$id))[1];
Line 206  sub make_reservation { Line 294  sub make_reservation {
  return undef;   return undef;
     }      }
           
     my %reservation=('name'      => $env{'user.name'}.'@'.$env{'user.domain'},      my %reservation=('name'      => $env{'user.name'}.':'.$env{'user.domain'},
      'timestamp' => time,       'timestamp' => time,
      'symb'      => $symb);       'symb'      => $parm_symb);
   
     my $success=&Apache::lonnet::newput('slot_reservations',      my $success=&Apache::lonnet::newput('slot_reservations',
  {"$slot_name\0$wanted" =>   {"$slot_name\0$wanted" =>
Line 222  sub make_reservation { Line 310  sub make_reservation {
  }   }
  my $result=&Apache::lonparmset::storeparm_by_symb($symb,   my $result=&Apache::lonparmset::storeparm_by_symb($symb,
       '0_availablestudent',        '0_availablestudent',
        1, $new_value, 'string',         $parm_level, $new_value,
          'string',
        $env{'user.name'},         $env{'user.name'},
                $env{'user.domain'});                 $env{'user.domain'});
  &Apache::lonxml::debug("hrrm $result");   &Apache::lonxml::debug("hrrm $result");
Line 233  sub make_reservation { Line 322  sub make_reservation {
     return undef;      return undef;
 }  }
   
   sub remove_registration {
       my ($r) = @_;
       if ($env{'form.entry'} ne 'remove all') {
    return &remove_registration_user($r);
       }
       my $slot_name = $env{'form.slotname'};
       my %slot=&Apache::lonnet::get_slot($slot_name);
   
       my ($cnum,$cdom)=&get_course();
       my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,
          "^$slot_name\0");
       if (&Apache::lonnet::error(%consumed)) {
    $r->print("<p>".&mt('A network error has occured.').'</p>');
    return;
       }
       if (!%consumed) {
    $r->print("<p>".&mt('Slot <tt>[_1]</tt> has no reservations.',
       $slot_name)."</p>");
    return;
       }
   
       my @names = map { $consumed{$_}{'name'} } (sort(keys(%consumed)));
       my $names = join(' ',@names);
   
       my $msg = &mt('Remove all of [_1] from slot [_2]?',$names,$slot_name);
       &remove_registration_confirmation($r,$msg,['entry','slotname']);
   }
   
   sub remove_registration_user {
       my ($r) = @_;
       
       my $slot_name = $env{'form.slotname'};
   
       my $name = &Apache::loncommon::plainname($env{'form.uname'},
        $env{'form.udom'});
   
       my $title = &Apache::lonnet::gettitle($env{'form.symb'});
   
       my $msg = &mt('Remove [_1] from slot [_2] for [_3]',
     $name,$slot_name,$title);
       
       &remove_registration_confirmation($r,$msg,['uname','udom','slotname',
          'entry','symb']);
   }
   
   sub remove_registration_confirmation {
       my ($r,$msg,$inputs) =@_;
   
       my $hidden_input;
       foreach my $parm (@{$inputs}) {
    $hidden_input .=
       '<input type="hidden" name="'.$parm.'" value="'
       .&HTML::Entities::encode($env{'form.'.$parm},'"<>&\'').'" />'."\n";
       }
       my %lt = &Apache::lonlocal::texthash('yes' => 'Yes',
    'no'  => 'No',);
       $r->print(<<"END_CONFIRM");
   <p> $msg </p>
   <form action="/adm/slotrequest" method="post">
       <input type="hidden" name="command" value="release" />
       <input type="hidden" name="button" value="yes" />
       $hidden_input
       <input type="submit" value="$lt{'yes'}" />
   </form>
   <form action="/adm/slotrequest" method="post">
       <input type="hidden" name="command" value="showslots" />
       <input type="submit" value="$lt{'no'}" />
   </form>
   END_CONFIRM
   
   }
   
   sub release_all_slot {
       my ($r,$mgr)=@_;
       
       my $slot_name = $env{'form.slotname'};
   
       my ($cnum,$cdom)=&get_course();
   
       my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,
          "^$slot_name\0");
       
       $r->print('<p>'.&mt('Releasing reservations').'</p>');
   
       foreach my $entry (sort { $consumed{$a}{'name'} cmp 
     $consumed{$b}{'name'} } (keys(%consumed))) {
    my ($uname,$udom) = split(':',$consumed{$entry}{'name'});
    my ($result,$msg) =
       &release_reservation($slot_name,$uname,$udom,
    $consumed{$entry}{'symb'},$mgr);
    $r->print("<p>$msg</p>");
    $r->rflush();
       }
       $r->print('<p><a href="/adm/slotrequest?command=showslots">'.
         &mt('Return to slot list').'</a></p>');
       &return_link($r);
   }
   
 sub release_slot {  sub release_slot {
     my ($r,$symb,$slot_name,$inhibit_return_link)=@_;      my ($r,$symb,$slot_name,$inhibit_return_link,$mgr)=@_;
   
     if ($slot_name eq '') { $slot_name=$env{'form.slotname'}; }      if ($slot_name eq '') { $slot_name=$env{'form.slotname'}; }
     my ($cnum,$cdom)=&get_course();  
   
       my ($uname,$udom) = ($env{'user.name'}, $env{'user.domain'});
       if ($mgr eq 'F' 
    && defined($env{'form.uname'}) && defined($env{'form.udom'})) {
    ($uname,$udom) = ($env{'form.uname'}, $env{'form.udom'});
       }
   
       if ($mgr eq 'F' 
    && defined($env{'form.symb'})) {
    $symb = &unescape($env{'form.symb'});
       }
   
       my ($result,$msg) =
    &release_reservation($slot_name,$uname,$udom,$symb,$mgr);
       $r->print("<p>$msg</p>");
       
       if ($mgr eq 'F') {
    $r->print('<p><a href="/adm/slotrequest?command=showslots">'.
     &mt('Return to slot list').'</a></p>');
       }
   
       if (!$inhibit_return_link) { &return_link($r);  }
       return $result;
   }
   
   sub release_reservation {
       my ($slot_name,$uname,$udom,$symb,$mgr) = @_;
       my %slot=&Apache::lonnet::get_slot($slot_name);
       my $description=&get_description($slot_name,\%slot);
   
       if ($mgr ne 'F') {
    if ($slot{'starttime'} < time) {
       return (0,&mt('Not allowed to release Reservation: [_1], as it has already ended.',$description));
    }
       }
     # get parameter string, check for existance, rebuild string with the slot      # get parameter string, check for existance, rebuild string with the slot
          
     my @slots = split(/:/,&Apache::lonnet::EXT("resource.0.availablestudent",      my @slots = split(/:/,&Apache::lonnet::EXT("resource.0.availablestudent",
        $symb,$env{'user.domain'},         $symb,$udom,$uname));
        $env{'user.name'}));  
     my @new_slots;      my @new_slots;
     foreach my $exist_slot (@slots) {      foreach my $exist_slot (@slots) {
  if ($exist_slot eq $slot_name) { next; }   if ($exist_slot eq $slot_name) { next; }
Line 251  sub release_slot { Line 470  sub release_slot {
     }      }
     my $new_param = join(':',@new_slots);      my $new_param = join(':',@new_slots);
   
       my ($cnum,$cdom)=&get_course();
   
     # get slot reservations, check if user has one, if so remove reservation      # get slot reservations, check if user has one, if so remove reservation
     my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,      my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,
        "^$slot_name\0");         "^$slot_name\0");
     foreach my $entry (keys(%consumed)) {      foreach my $entry (keys(%consumed)) {
  if ( $consumed{$entry}->{'name'} eq    if ( $consumed{$entry}->{'name'} eq ($uname.':'.$udom) ) {
      ($env{'user.name'}.'@'.$env{'user.domain'}) ) {  
     &Apache::lonnet::del('slot_reservations',[$entry],      &Apache::lonnet::del('slot_reservations',[$entry],
  $cdom,$cnum);   $cdom,$cnum);
  }   }
     }      }
   
       my $use_slots = &Apache::lonnet::EXT("resource.0.useslots");
       &Apache::lonxml::debug("use_slots is  $use_slots<br />");
   
       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      # store new parameter string
     my $result=&Apache::lonparmset::storeparm_by_symb($symb,      my $result=&Apache::lonparmset::storeparm_by_symb($symb,
       '0_availablestudent',        '0_availablestudent',
       1, $new_param, 'string',        $parm_level, $new_param,
       $env{'user.name'},        'string', $uname, $udom);
       $env{'user.domain'});  
       my $msg;
       if ($mgr eq 'F') {
    $msg = &mt('Released Reservation for user: [_1]',"$uname:$udom");
       } else {
    $msg = &mt('Released Reservation: [_1]',$description);
       }
       return (1,$msg);
   }
   
   sub delete_slot {
       my ($r)=@_;
   
       my $slot_name = $env{'form.slotname'};
     my %slot=&Apache::lonnet::get_slot($slot_name);      my %slot=&Apache::lonnet::get_slot($slot_name);
     my $description=&get_description($env{'form.slotname'},\%slot);  
     $r->print("<p>Released Reservation: $description</p>");      my ($cnum,$cdom)=&get_course();
     if (!$inhibit_return_link) {      my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,
  $r->print('<p><a href="/adm/flip?postdata=return:">'.         "^$slot_name\0");
   &mt('Return to last resource').'</a></p>');      my ($tmp) = %consumed;
       if ($tmp =~ /error: 2/) { undef(%consumed); }
   
       if (%slot && !%consumed) {
    $slot{'type'} = 'deleted';
    my $ret = &Apache::lonnet::cput('slots', {$slot_name => \%slot},
    $cdom, $cnum);
    if ($ret eq 'ok') {
       $r->print("<p>Slot <tt>$slot_name</tt> marked as deleted.</p>");
    } else {
       $r->print("<p> An error ($ret) occurse when attempting to delete Slot <tt>$slot_name</tt>.</p>");
    }
       } else {
    if (%consumed) {
       $r->print("<p>Slot <tt>$slot_name</tt> has active reservations.</p>");
    } else {
       $r->print("<p>Slot <tt>$slot_name</tt> does not exist.</p>");
    }
     }      }
     return 1;      $r->print('<p><a href="/adm/slotrequest?command=showslots">'.
         &mt('Return to slot list').'</a></p>');
       &return_link($r);
   }
   
   sub return_link {
       my ($r) = @_;
       $r->print('<p><a href="/adm/flip?postdata=return:">'.
         &mt('Return to last resource').'</a></p>');
 }  }
   
 sub get_slot {  sub get_slot {
     my ($r,$symb)=@_;      my ($r,$symb)=@_;
   
     my $slot_name=&check_for_conflict($symb,$env{'form.slotname'});      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("<p>An error occured while attempting to make a reservation. ($1)</p>");
    &return_link($r);
    return;
       }
     if ($slot_name) {      if ($slot_name) {
  my %slot=&Apache::lonnet::get_slot($slot_name);   my %slot=&Apache::lonnet::get_slot($slot_name);
  my $description1=&get_description($slot_name,\%slot);   my $description1=&get_description($slot_name,\%slot);
Line 289  sub get_slot { Line 566  sub get_slot {
  $r->print("<p>Already have a reservation: $description1</p>");   $r->print("<p>Already have a reservation: $description1</p>");
  if ($slot_name ne $env{'form.slotname'}) {   if ($slot_name ne $env{'form.slotname'}) {
     $r->print(<<STUFF);      $r->print(<<STUFF);
 <form method="POST" action="/adm/slotrequest">  <form method="post" action="/adm/slotrequest">
    <input type="hidden" name="symb" value="$env{'form.symb'}" />     <input type="hidden" name="symb" value="$env{'form.symb'}" />
    <input type="hidden" name="slotname" value="$env{'form.slotname'}" />     <input type="hidden" name="slotname" value="$env{'form.slotname'}" />
    <input type="hidden" name="releaseslot" value="$slot_name" />     <input type="hidden" name="releaseslot" value="$slot_name" />
Line 301  STUFF Line 578  STUFF
 STUFF  STUFF
     $r->print(' your reservation from <b>'.$description1.'</b> to <b>'.      $r->print(' your reservation from <b>'.$description1.'</b> to <b>'.
       $description2.        $description2.
       '</b> <br />or <a href="/adm/flip?postdata=return:">'.        '</b> <br />or </p>');
       &mt('Return to last resource').'</a></p>');      &return_link($r);
     $r->print(<<STUFF);      $r->print(<<STUFF);
 </form>  </form>
 STUFF  STUFF
         } else {          } else {
     $r->print('<p><a href="/adm/flip?postdata=return:">'.      &return_link($r);
       &mt('Return to last resource').'</a></p>');  
  }   }
  return;   return;
     }      }
     my %slot=&Apache::lonnet::get_slot($env{'form.slotname'});  
     my $reserved=&make_reservation($env{'form.slotname'},      my $reserved=&make_reservation($env{'form.slotname'},
    \%slot,$symb);     \%slot,$symb);
     my $description=&get_description($env{'form.slotname'},\%slot);      my $description=&get_description($env{'form.slotname'},\%slot);
     if (defined($reserved)) {      if (defined($reserved)) {
  if ($reserved > -1) {   if ($slot_name =~ /^error: (.*)/) {
       $r->print("<p>An error occured while attempting to make a reservation. ($1)</p>");
    } elsif ($reserved > -1) {
     $r->print("<p>Success: $description</p>");      $r->print("<p>Success: $description</p>");
     $r->print('<p><a href="/adm/flip?postdata=return:">'.  
       &mt('Return to last resource').'</a></p>');  
     return;  
  } elsif ($reserved < 0) {   } elsif ($reserved < 0) {
     $r->print("<p>Already reserved: $description</p>");      $r->print("<p>Already reserved: $description</p>");
     $r->print('<p><a href="/adm/flip?postdata=return:">'.  
       &mt('Return to last resource').'</a></p>');  
     return;  
  }   }
    &return_link($r);
    return;
     }      }
   
     my %lt=('request'=>"Availibility list",      my %lt=('request'=>"Availibility list",
Line 337  STUFF Line 611  STUFF
     $r->print(<<STUFF);      $r->print(<<STUFF);
 <p> <font color="red">Failed</font> to reserve a spot for $description. </p>  <p> <font color="red">Failed</font> to reserve a spot for $description. </p>
 <p>  <p>
 <form method="POST" action="/adm/slotrequest">  <form method="post" action="/adm/slotrequest">
    <input type="submit" name="Try Again" value="$lt{'try'}" />     <input type="submit" name="Try Again" value="$lt{'try'}" />
    <input type="hidden" name="symb" value="$env{'form.symb'}" />     <input type="hidden" name="symb" value="$env{'form.symb'}" />
    <input type="hidden" name="slotname" value="$env{'form.slotname'}" />     <input type="hidden" name="slotname" value="$env{'form.slotname'}" />
Line 347  STUFF Line 621  STUFF
 </p>  </p>
 <p>  <p>
 or  or
 <form method="POST" action="/adm/slotrequest">  <form method="post" action="/adm/slotrequest">
     <input type="hidden" name="symb" value="$env{'form.symb'}" />      <input type="hidden" name="symb" value="$env{'form.symb'}" />
     <input type="submit" name="requestattempt" value="$lt{'request'}" />      <input type="submit" name="requestattempt" value="$lt{'request'}" />
 </form>  </form>
 </p>  </p>
 or  or
 STUFF  STUFF
     $r->print('<p><a href="/adm/flip?postdata=return:">'.  
       &mt('Return to last resource').'</a></p>');      &return_link($r);
     return;      return;
 }  }
   
 sub allowed_slot {  sub allowed_slot {
     my ($slot_name,$slot,$symb)=@_;      my ($slot_name,$slot,$symb,$slots,$consumed_uniqueperiods)=@_;
   
     #already started      #already started
     if ($slot->{'starttime'} < time) {      if ($slot->{'starttime'} < time) {
  # all open slot to be schedulable   # all open slot to be schedulable
  #return 0;   #return 0;
     }      }
     &Apache::lonxml::debug("$slot_name starttime good");      &Apache::lonxml::debug("$slot_name starttime good");
   
     #already ended      #already ended
     if ($slot->{'endtime'} < time) {      if ($slot->{'endtime'} < time) {
  return 0;   return 0;
     }      }
     &Apache::lonxml::debug("$slot_name endtime good");      &Apache::lonxml::debug("$slot_name endtime good");
   
     # not allowed to pick this one      # not allowed to pick this one
     if (defined($slot->{'type'})      if (defined($slot->{'type'})
  && $slot->{'type'} ne 'schedulable_student') {   && $slot->{'type'} ne 'schedulable_student') {
  return 0;   return 0;
     }      }
     &Apache::lonxml::debug("$slot_name type good");      &Apache::lonxml::debug("$slot_name type good");
   
       # reserve time not yet started
       if ($slot->{'startreserve'} > time) {
    return 0;
       }
       &Apache::lonxml::debug("$slot_name reserve good");
   
       my $userallowed=0;
       # its for a different set of users
       if (defined($slot->{'allowedsections'})) {
    if (!defined($env{'request.role.sec'})
       && grep(/^No section assigned$/,
       split(',',$slot->{'allowedsections'}))) {
       $userallowed=1;
    }
    if (defined($env{'request.role.sec'})
       && grep(/^\Q$env{'request.role.sec'}\E$/,
       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");
   
       # its for a different set of users
       if (defined($slot->{'allowedusers'})
    && grep(/^\Q$env{'user.name'}:$env{'user.domain'}\E$/,
    split(',',$slot->{'allowedusers'}))) {
    $userallowed=1;
       }
   
       if (!defined($slot->{'allowedusers'})
    && !defined($slot->{'allowedsections'})) {
    $userallowed=1;
       }
   
       &Apache::lonxml::debug("$slot_name user is $userallowed");
       return 0 if (!$userallowed);
   
     # not allowed for this resource      # not allowed for this resource
     if (defined($slot->{'symb'})      if (defined($slot->{'symb'})
  && $slot->{'symb'} ne $symb) {   && $slot->{'symb'} ne $symb) {
  return 0;   return 0;
     }      }
   
       my $conflict = &check_for_conflict($symb,$slot_name,$slot,$slots,
          $consumed_uniqueperiods);
       if ($conflict) {
    if ($slots->{$conflict}{'starttime'} < time) {
       return 0;
    }
       }
     &Apache::lonxml::debug("$slot_name symb good");      &Apache::lonxml::debug("$slot_name symb good");
     return 1;      return 1;
 }  }
Line 403  sub show_choices { Line 736  sub show_choices {
   
     my ($cnum,$cdom)=&get_course();      my ($cnum,$cdom)=&get_course();
     my %slots=&Apache::lonnet::dump('slots',$cdom,$cnum);      my %slots=&Apache::lonnet::dump('slots',$cdom,$cnum);
       my $consumed_uniqueperiods = &get_consumed_uniqueperiods(\%slots);
     my $available;      my $available;
     $r->print('<table border="1">');      $r->print('<table border="1">');
     &Apache::lonxml::debug("Checking Slots");      &Apache::lonxml::debug("Checking Slots");
     my ($got_slot)=&check_for_reservation($symb);      my @got_slots=&check_for_reservation($symb,'allslots');
     foreach my $slot (sort       foreach my $slot (sort 
       { return $slots{$a}->{'starttime'} <=> $slots{$b}->{'starttime'} }        { return $slots{$a}->{'starttime'} <=> $slots{$b}->{'starttime'} }
       (keys(%slots)))  {        (keys(%slots)))  {
   
  &Apache::lonxml::debug("Checking Slot $slot");   &Apache::lonxml::debug("Checking Slot $slot");
  next if (!&allowed_slot($slot,$slots{$slot}));   next if (!&allowed_slot($slot,$slots{$slot},undef,\%slots,
    $consumed_uniqueperiods));
   
  $available++;   $available++;
   
  my $description=&get_description($slot,$slots{$slot});   my $description=&get_description($slot,$slots{$slot});
   
  my $form=&mt('Unavailable');   my $form=&mt('Unavailable');
  if (($slot eq $got_slot) ||   if ((grep(/^\Q$slot\E$/,@got_slots)) ||
     &space_available($slot,$slots{$slot},$symb)) {      &space_available($slot,$slots{$slot},$symb)) {
     my $text=&mt('Select');      my $text=&mt('Select');
     my $command='get';      my $command='get';
     if ($slot eq $got_slot) {      if (grep(/^\Q$slot\E$/,@got_slots)) {
  $text=&mt('Free Reservation');   $text=&mt('Drop Reservation');
  $command='release';   $command='release';
       } else {
    my $conflict = &check_for_conflict($symb,$slot,$slots{$slot},
      \%slots,
      $consumed_uniqueperiods);
    if ($conflict) {
       $text=&mt('Change Reservation');
       $command='get';
    }
     }      }
     my $escsymb=&Apache::lonnet::escape($symb);      my $escsymb=&escape($symb);
     $form=<<STUFF;      $form=<<STUFF;
    <form method="POST" action="/adm/slotrequest">     <form method="post" action="/adm/slotrequest">
      <input type="submit" name="Select" value="$text" />       <input type="submit" name="Select" value="$text" />
      <input type="hidden" name="symb" value="$escsymb" />       <input type="hidden" name="symb" value="$escsymb" />
      <input type="hidden" name="slotname" value="$slot" />       <input type="hidden" name="slotname" value="$slot" />
Line 452  STUFF Line 795  STUFF
     $r->print('</table>');      $r->print('</table>');
 }  }
   
   sub to_show {
       my ($slotname,$slot,$when,$deleted,$name) = @_;
       my $time=time;
       my $week=60*60*24*7;
   
       if ($deleted eq 'hide' && $slot->{'type'} eq 'deleted') {
    return 0;
       }
   
       if ($name && $name->{'value'} =~ /\w/) {
    if ($name->{'type'} eq 'substring') {
       if ($slotname !~ /\Q$name->{'value'}\E/) {
    return 0;
       }
    }
    if ($name->{'type'} eq 'exact') {
       if ($slotname eq $name->{'value'}) {
    return 0;
       }
    }
       }
   
       if ($when eq 'any') {
    return 1;
       } elsif ($when eq 'now') {
    if ($time > $slot->{'starttime'} &&
       $time < $slot->{'endtime'}) {
       return 1;
    }
    return 0;
       } elsif ($when eq 'nextweek') {
    if ( ($time        < $slot->{'starttime'} &&
         ($time+$week) > $slot->{'starttime'})
        ||
        ($time        < $slot->{'endtime'} &&
         ($time+$week) > $slot->{'endtime'}) ) {
       return 1;
    }
    return 0;
       } elsif ($when eq 'lastweek') {
    if ( ($time        > $slot->{'starttime'} &&
         ($time-$week) < $slot->{'starttime'})
        ||
        ($time        > $slot->{'endtime'} &&
         ($time-$week) < $slot->{'endtime'}) ) {
       return 1;
    }
    return 0;
       } elsif ($when eq 'willopen') {
    if ($time < $slot->{'starttime'}) {
       return 1;
    }
    return 0;
       } elsif ($when eq 'wereopen') {
    if ($time > $slot->{'endtime'}) {
       return 1;
    }
    return 0;
       }
       
       return 1;
   }
   
   sub remove_link {
       my ($slotname,$entry,$uname,$udom,$symb) = @_;
   
       my $remove = &mt('Remove');
   
       if ($entry eq 'remove all') {
    $remove = &mt('Remove All');
    undef($uname);
    undef($udom);
       }
   
       $slotname  = &escape($slotname);
       $entry     = &escape($entry);
       $uname     = &escape($uname);
       $udom      = &escape($udom);
       $symb      = &escape($symb);
   
       return <<"END_LINK";
    <a href="/adm/slotrequest?command=remove_registration&amp;slotname=$slotname&amp;entry=$entry&amp;uname=$uname&amp;udom=$udom&amp;symb=$symb"
      >($remove)</a>
   END_LINK
   
   }
   
 sub show_table {  sub show_table {
     my ($r,$symb,$mgr)=@_;      my ($r,$mgr)=@_;
   
     my ($cnum,$cdom)=&get_course();      my ($cnum,$cdom)=&get_course();
     my %slots=&Apache::lonnet::dump('slots',$cdom,$cnum);      my %slots=&Apache::lonnet::dump('slots',$cdom,$cnum);
       if ( (keys(%slots))[0] =~ /^error: 2 /) {
    undef(%slots);
       } 
     my $available;      my $available;
     if ($mgr eq 'F') {      if ($mgr eq 'F') {
  $r->print('<form method="POST" action="/adm/slotrequest">      # FIXME: This line should be deleted once Slots uses breadcrumbs
       $r->print(&Apache::loncommon::help_open_topic('Slot About', 'Help on slots'));
   
    $r->print('<div>');
    $r->print('<form method="post" action="/adm/slotrequest">
 <input type="hidden" name="command" value="uploadstart" />  <input type="hidden" name="command" value="uploadstart" />
 <input type="hidden" name="symb" value="'.$env{'form.symb'}.'" />  
 <input type="submit" name="start" value="'.&mt('Upload Slot List').'" />  <input type="submit" name="start" value="'.&mt('Upload Slot List').'" />
 </form>');  </form>');
    $r->print(&Apache::loncommon::help_open_topic('Slot CommaDelimited'));
    $r->print('<form method="post" action="/adm/helper/newslot.helper">
   <input type="submit" name="newslot" value="'.&mt('Create a New Slot').'" />
   </form>');
    $r->print(&Apache::loncommon::help_open_topic('Slot AddInterface'));
    $r->print('</div>');
     }      }
     $r->print('<table border="1">      
 <tr>      my %Saveable_Parameters = ('show'              => 'array',
   <th>Slot name</th>         'when'              => 'scalar',
   <th>Type</th>         'order'             => 'scalar',
   <th>Description</th>         'deleted'           => 'scalar',
   <th>Start Time</th>         'name_filter_type'  => 'scalar',
   <th>End Time</th>         'name_filter_value' => 'scalar',
   <th>Max space</th>         );
   <th>Scheduled Students</th>      &Apache::loncommon::store_course_settings('slotrequest',
   <th>Proctors</th>        \%Saveable_Parameters);
   <th>Unique Period</th>      &Apache::loncommon::restore_course_settings('slotrequest',
 </tr>');   \%Saveable_Parameters);
     foreach my $slot (sort       &Apache::grades::init_perm();
       { return $slots{$a}->{'starttime'} <=> $slots{$b}->{'starttime'} }      my ($classlist,$section,$fullname)=&Apache::grades::getclasslist('all');
       (keys(%slots)))  {      &Apache::grades::reset_perm();
   
       # what to display filtering
       my %show_fields=&Apache::lonlocal::texthash(
        'name'            => 'Slot Name',
        'description'     => 'Description',
        'type'            => 'Type',
        'starttime'       => 'Start time',
        'endtime'         => 'End Time',
                'startreserve'    => 'Time students can start reserving',
        'secret'          => 'Secret Word',
        'space'           => '# of students/max',
        'ip'              => 'IP or DNS restrictions',
        'symb'            => 'Resource slot is restricted to.',
        'allowedsections' => 'Sections slot is restricted to.',
        'allowedusers'    => 'Users slot is restricted to.',
        'uniqueperiod'    => 'Period of time slot is unique',
        'scheduled'       => 'Scheduled Students',
        'proctor'         => 'List of proctors');
       my @show_order=('name','description','type','starttime','endtime',
       'startreserve','secret','space','ip','symb',
       'allowedsections','allowedusers','uniqueperiod',
       'scheduled','proctor');
       my @show = 
    (exists($env{'form.show'})) ? &Apache::loncommon::get_env_multiple('form.show')
                               : keys(%show_fields);
       my %show =  map { $_ => 1 } (@show);
   
       #when filtering setup
       my %when_fields=&Apache::lonlocal::texthash(
        'now'      => 'Open now',
        'nextweek' => 'Open within the next week',
        'lastweek' => 'Were open last week',
        'willopen' => 'Will open later',
        'wereopen' => 'Were open',
        'any'      => 'Anytime',
    );
       my @when_order=('any','now','nextweek','lastweek','willopen','wereopen');
       $when_fields{'select_form_order'} = \@when_order;
       my $when = (exists($env{'form.when'})) ? $env{'form.when'}
                                               : 'now';
   
       #display of students setup
       my %stu_display_fields=
    &Apache::lonlocal::texthash('username' => 'User name',
       'fullname' => 'Full name',
       );
       my @stu_display_order=('fullname','username');
       my @stu_display = 
    (exists($env{'form.studisplay'})) ? &Apache::loncommon::get_env_multiple('form.studisplay')
                                     : keys(%stu_display_fields);
       my %stu_display =  map { $_ => 1 } (@stu_display);
   
       #name filtering setup
       my %name_filter_type_fields=
    &Apache::lonlocal::texthash('substring' => 'Substring',
       'exact'     => 'Exact',
       #'reg'       => 'Regular Expression',
       );
       my @name_filter_type_order=('substring','exact');
   
       $name_filter_type_fields{'select_form_order'} = \@name_filter_type_order;
       my $name_filter_type = 
    (exists($env{'form.name_filter_type'})) ? $env{'form.name_filter_type'}
                                                   : 'substring';
       my $name_filter = {'type'  => $name_filter_type,
          'value' => $env{'form.name_filter_value'},};
   
       
       #deleted slot filtering
       #default to hide if no value
       $env{'form.deleted'} ||= 'hide';
       my $hide_radio = 
    &Apache::lonhtmlcommon::radio('deleted',$env{'form.deleted'},'hide');
       my $show_radio = 
    &Apache::lonhtmlcommon::radio('deleted',$env{'form.deleted'},'show');
   
       $r->print('<form method="post" action="/adm/slotrequest">
   <input type="hidden" name="command" value="showslots" />');
       $r->print('<div>');
       $r->print('<table class="inline">
         <tr><th>'.&mt('Show').'</th>
             <th>'.&mt('Student Display').'</th>
             <th>'.&mt('Open').'</th>
             <th>'.&mt('Slot Name Filter').'</th>
             <th>'.&mt('Options').'</th>
         </tr>
         <tr><td>'.&Apache::loncommon::multiple_select_form('show',\@show,6,\%show_fields,\@show_order).
         '</td>
              <td>
            '.&Apache::loncommon::multiple_select_form('studisplay',\@stu_display,
       6,\%stu_display_fields,
       \@stu_display_order).'
              </td>
              <td>'.&Apache::loncommon::select_form($when,'when',%when_fields).
             '</td>
              <td>'.&Apache::loncommon::select_form($name_filter_type,
    'name_filter_type',
    %name_filter_type_fields).
         '<br />'.
         &Apache::lonhtmlcommon::textbox('name_filter_value',
         $env{'form.name_filter_value'},
         15).
             '</td>
              <td>
               <table>
                 <tr>
                   <td rowspan="2">Deleted slots:</td>
                   <td><label>'.$show_radio.'Show</label></td>
                 </tr>
                 <tr>
                   <td><label>'.$hide_radio.'Hide</label></td>
                 </tr>
               </table>
     </td>
          </tr>
       </table>');
       $r->print('</div>');
       $r->print('<p><input type="submit" name="start" value="'.&mt('Update Display').'" /></p>');
       my $linkstart='<a href="/adm/slotrequest?command=showslots&amp;order=';
       $r->print(&Apache::loncommon::start_data_table().
         &Apache::loncommon::start_data_table_header_row().'
          <th></th>');
       foreach my $which (@show_order) {
    if ($which ne 'proctor' && exists($show{$which})) {
       $r->print('<th>'.$linkstart.$which.'">'.$show_fields{$which}.'</a></th>');
    }
       }
       $r->print(&Apache::loncommon::end_data_table_header_row());
   
       my %name_cache;
       my $slotsort = sub {
    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);
       }
    } elsif ($env{'form.order'} eq 'uniqueperiod') {
       
       if ($slots{$a}->{'uniqueperiod'}[0] 
    ne $slots{$b}->{'uniqueperiod'}[0]) {
    return ($slots{$a}->{'uniqueperiod'}[0]
    cmp $slots{$b}->{'uniqueperiod'}[0]);
       }
       if ($slots{$a}->{'uniqueperiod'}[1] 
    ne $slots{$b}->{'uniqueperiod'}[1]) {
    return ($slots{$a}->{'uniqueperiod'}[1]
    cmp $slots{$b}->{'uniqueperiod'}[1]);
       }
    }
    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; }
  if (defined($slots{$slot}->{'type'})   if (defined($slots{$slot}->{'type'})
     && $slots{$slot}->{'type'} ne 'schedulable_student') {      && $slots{$slot}->{'type'} ne 'schedulable_student') {
     #next;      #next;
  }   }
  my $description=&get_description($slot,$slots{$slot});   my $description=&get_description($slot,$slots{$slot});
  my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,   my ($id_count,$ids);
    "^$slot\0");      
  my $ids;   if (exists($show{'scheduled'}) || exists($show{'space'}) ) {
  foreach my $entry (sort(keys(%consumed))) {      my @this_slot = grep(/^$slot\0/,keys(%consumed));
     my (undef,$id)=split("\0",$entry);      $id_count = scalar(@this_slot);
     $ids.= $id.'-> '.$consumed{$entry}->{'name'}.'<br />';      if (exists($show{'scheduled'})) {
    foreach my $entry (sort { $consumed{$a}{name} cmp 
         $consumed{$b}{name} }
      (keys(%consumed))) {
       my (undef,$id)=split("\0",$entry);
       my ($uname,$udom) = split(':',$consumed{$entry}{'name'});
       $ids.= '<nobr>';
       foreach my $item (@stu_display_order) {
    if ($stu_display{$item}) {
       if ($item eq 'fullname') {
    $ids.=$fullname->{"$uname:$udom"}.' ';
       } elsif ($item eq 'username') {
    $ids.="<tt>$uname:$udom</tt> ";
       }
    }
       }
       $ids.=&remove_link($slot,$entry,$uname,$udom,
          $consumed{$entry}{'symb'}).'</nobr><br />';
    }
       }
  }   }
  my $start=localtime($slots{$slot}->{'starttime'});  
  my $end=localtime($slots{$slot}->{'endtime'});   my $start=($slots{$slot}->{'starttime'}?
      &Apache::lonlocal::locallocaltime($slots{$slot}->{'starttime'}):'');
    my $end=($slots{$slot}->{'endtime'}?
    &Apache::lonlocal::locallocaltime($slots{$slot}->{'endtime'}):'');
    my $start_reserve=($slots{$slot}->{'startreserve'}?
      &Apache::lonlocal::locallocaltime($slots{$slot}->{'startreserve'}):'');
   
  my $unique;   my $unique;
  if (ref($slots{$slot}{'uniqueperiod'})) {   if (ref($slots{$slot}{'uniqueperiod'})) {
     $unique=localtime($slots{$slot}{'uniqueperiod'}[0]).','.      $unique=localtime($slots{$slot}{'uniqueperiod'}[0]).', '.
  localtime($slots{$slot}{'uniqueperiod'}[1]);   localtime($slots{$slot}{'uniqueperiod'}[1]);
  }   }
   
  $r->print(<<STUFF);   my $title;
 <tr>   if (exists($slots{$slot}{'symb'})) {
  <td>$slot</td>      my (undef,undef,$res)=
  <td>$slots{$slot}->{'type'}</td>   &Apache::lonnet::decode_symb($slots{$slot}{'symb'});
  <td>$description</td>      $res =   &Apache::lonnet::clutter($res);
  <td>$start</td>      $title = &Apache::lonnet::gettitle($slots{$slot}{'symb'});
  <td>$end</td>      $title='<a href="'.$res.'?symb='.$slots{$slot}{'symb'}.'">'.$title.'</a>';
  <td>$slots{$slot}->{'maxspace'}</td>   }
  <td>$ids</td>  
  <td>$slots{$slot}->{'proctor'}</td>   my $allowedsections;
  <td>$unique</td>   if (exists($show{'allowedsections'})) {
 </tr>      $allowedsections = 
    join(', ',sort(split(/\s*,\s*/,
        $slots{$slot}->{'allowedsections'})));
    }
   
    my @allowedusers;
    if (exists($show{'allowedusers'})) {
       @allowedusers= map {
    my ($uname,$udom)=split(/:/,$_);
    my $fullname=$name_cache{$_};
    if (!defined($fullname)) {
       $fullname = &Apache::loncommon::plainname($uname,$udom);
       $fullname =~s/\s/&nbsp;/g;
       $name_cache{$_} = $fullname;
    }
    &Apache::loncommon::aboutmewrapper($fullname,$uname,$udom);
       } (sort(split(/\s*,\s*/,$slots{$slot}->{'allowedusers'})));
    }
    my $allowedusers=join(', ',@allowedusers);
   
    my @proctors;
    my $rowspan=1;
    my $colspan=1;
    if (exists($show{'proctor'})) {
       $rowspan=2;
       @proctors= map {
    my ($uname,$udom)=split(/:/,$_);
    my $fullname=$name_cache{$_};
    if (!defined($fullname)) {
       $fullname = &Apache::loncommon::plainname($uname,$udom);
       $fullname =~s/\s/&nbsp;/g;
       $name_cache{$_} = $fullname;
    }
    &Apache::loncommon::aboutmewrapper($fullname,$uname,$udom);
       } (sort(split(/\s*,\s*/,$slots{$slot}->{'proctor'})));
    }
    my $proctors=join(', ',@proctors);
   
    my $edit=(<<"EDITLINK");
   <a href="/adm/helper/newslot.helper?name=$slot">Edit</a>
   EDITLINK
   
    my $delete=(<<"DELETELINK");
   <a href="/adm/slotrequest?command=delete&amp;slotname=$slot">Delete</a>
   DELETELINK
   
           my $remove_all=&remove_link($slot,'remove all').'<br />';
   
           if ($ids ne '') { undef($delete); }
    if ($slots{$slot}{'type'} ne 'schedulable_student' 
       || $ids eq '') { 
       undef($remove_all);
    }
   
    my $row_start=&Apache::loncommon::start_data_table_row();
    my $row_end=&Apache::loncommon::end_data_table_row();
           $r->print($row_start.
     "\n<td rowspan=\"$rowspan\">$edit $delete</td>\n");
    if (exists($show{'name'})) {
       $colspan++;$r->print("<td>$slot</td>");
    }
    if (exists($show{'description'})) {
       $colspan++;$r->print("<td>$description</td>\n");
    }
    if (exists($show{'type'})) {
       $colspan++;$r->print("<td>$slots{$slot}->{'type'}</td>\n");
    }
    if (exists($show{'starttime'})) {
       $colspan++;$r->print("<td>$start</td>\n");
    }
    if (exists($show{'endtime'})) {
       $colspan++;$r->print("<td>$end</td>\n");
    }
    if (exists($show{'startreserve'})) {
       $colspan++;$r->print("<td>$start_reserve</td>\n");
    }
    if (exists($show{'secret'})) {
       $colspan++;$r->print("<td>$slots{$slot}{'secret'}</td>\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 = '<strong>'.$display.' (full) </strong>';
    }
       }
       $colspan++;$r->print("<td>$display</td>\n");
    }
    if (exists($show{'ip'})) {
       $colspan++;$r->print("<td>$slots{$slot}{'ip'}</td>\n");
    }
    if (exists($show{'symb'})) {
       $colspan++;$r->print("<td>$title</td>\n");
    }
    if (exists($show{'allowedsections'})) {
       $colspan++;$r->print("<td>$allowedsections</td>\n");
    }
    if (exists($show{'allowedusers'})) {
       $colspan++;$r->print("<td>$allowedusers</td>\n");
    }
    if (exists($show{'uniqueperiod'})) {
       $colspan++;$r->print("<td>$unique</td>\n");
    }
    if (exists($show{'scheduled'})) {
       $colspan++;$r->print("<td>$remove_all $ids</td>\n");
    }
    $r->print("$row_end\n");
    if (exists($show{'proctor'})) {
       $r->print(<<STUFF);
   $row_start
    <td colspan="$colspan">$proctors</td>
   $row_end
 STUFF  STUFF
           }
     }      }
     $r->print('</table>');      $r->print('</table></form>');
 }  }
   
 sub upload_start {  sub upload_start {
     my ($r,$symb)=@_;          my ($r)=@_;    
     $r->print(&Apache::grades::checkforfile_js());      $r->print(&Apache::grades::checkforfile_js());
     my $result.='<table width=100% border=0><tr bgcolor="#e6ffff"><td>'."\n";      my $result.='<table width=100% border=0><tr bgcolor="#e6ffff"><td>'."\n";
     $result.='&nbsp;<b>'.      $result.='&nbsp;<b>'.
Line 529  sub upload_start { Line 1280  sub upload_start {
     my $ignore=&mt('Ignore First Line');      my $ignore=&mt('Ignore First Line');
     $result.=<<ENDUPFORM;      $result.=<<ENDUPFORM;
 <form method="post" enctype="multipart/form-data" action="/adm/slotrequest" name="slotupload">  <form method="post" enctype="multipart/form-data" action="/adm/slotrequest" name="slotupload">
 <input type="hidden" name="symb" value="$symb" />  
 <input type="hidden" name="command" value="csvuploadmap" />  <input type="hidden" name="command" value="csvuploadmap" />
 $upfile_select  $upfile_select
 <br /><input type="button" onClick="javascript:checkUpload(this.form);" value="Upload Data" />  <br /><input type="button" onClick="javascript:checkUpload(this.form);" value="Upload Data" />
Line 542  ENDUPFORM Line 1292  ENDUPFORM
 }  }
   
 sub csvuploadmap_header {  sub csvuploadmap_header {
     my ($r,$symb,$datatoken,$distotal)= @_;      my ($r,$datatoken,$distotal)= @_;
     my $javascript;      my $javascript;
     if ($env{'form.upfile_associate'} eq 'reverse') {      if ($env{'form.upfile_associate'} eq 'reverse') {
  $javascript=&csvupload_javascript_reverse_associate();   $javascript=&csvupload_javascript_reverse_associate();
Line 552  sub csvuploadmap_header { Line 1302  sub csvuploadmap_header {
   
     my $checked=(($env{'form.noFirstLine'})?' checked="checked"':'');      my $checked=(($env{'form.noFirstLine'})?' checked="checked"':'');
     my $ignore=&mt('Ignore First Line');      my $ignore=&mt('Ignore First Line');
    my $help_field = &Apache::loncommon::help_open_topic('Slot SelectingField');
   
     $r->print(<<ENDPICK);      $r->print(<<ENDPICK);
 <form method="post" enctype="multipart/form-data" action="/adm/slotrequest" name="slotupload">  <form method="post" enctype="multipart/form-data" action="/adm/slotrequest" name="slotupload">
 <h3>Identify fields</h3>  <h3>Identify fields $help_field</h3>
 Total number of records found in file: $distotal <hr />  Total number of records found in file: $distotal <hr />
 Enter as many fields as you can. The system will inform you and bring you back  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.<hr />  to this page if the data selected is insufficient to create the slots.<hr />
Line 566  to this page if the data selected is ins Line 1318  to this page if the data selected is ins
 <input type="hidden" name="upfiletype" value="$env{'form.upfiletype'}" />  <input type="hidden" name="upfiletype" value="$env{'form.upfiletype'}" />
 <input type="hidden" name="upfile_associate"   <input type="hidden" name="upfile_associate" 
                                        value="$env{'form.upfile_associate'}" />                                         value="$env{'form.upfile_associate'}" />
 <input type="hidden" name="symb"       value="$symb" />  
 <input type="hidden" name="command"    value="csvuploadassign" />  <input type="hidden" name="command"    value="csvuploadassign" />
 <hr />  <hr />
 <script type="text/javascript" language="Javascript">  <script type="text/javascript" language="Javascript">
Line 641  ENDPICK Line 1392  ENDPICK
 }  }
   
 sub csv_upload_map {  sub csv_upload_map {
     my ($r,$symb)= @_;      my ($r)= @_;
   
     my $datatoken;      my $datatoken;
     if (!$env{'form.datatoken'}) {      if (!$env{'form.datatoken'}) {
Line 652  sub csv_upload_map { Line 1403  sub csv_upload_map {
     }      }
     my @records=&Apache::loncommon::upfile_record_sep();      my @records=&Apache::loncommon::upfile_record_sep();
     if ($env{'form.noFirstLine'}) { shift(@records); }      if ($env{'form.noFirstLine'}) { shift(@records); }
     &csvuploadmap_header($r,$symb,$datatoken,$#records+1);      &csvuploadmap_header($r,$datatoken,$#records+1);
     my ($i,$keyfields);      my ($i,$keyfields);
     if (@records) {      if (@records) {
  my @fields=&csvupload_fields();   my @fields=&csvupload_fields();
Line 688  sub csvupload_fields { Line 1439  sub csvupload_fields {
     ['maxspace','Maximum number of reservations'],      ['maxspace','Maximum number of reservations'],
     ['symb','Resource Restriction'],      ['symb','Resource Restriction'],
     ['uniqueperiod','Date range of slot exclusion'],      ['uniqueperiod','Date range of slot exclusion'],
     ['secret','Secret word proctor uses to validate']);      ['secret','Secret word proctor uses to validate'],
       ['allowedsections','Sections slot is restricted to'],
       ['allowedusers','Users slot is restricted to'],
       );
 }  }
   
 sub csv_upload_assign {  sub csv_upload_assign {
     my ($r,$symb)= @_;      my ($r,$mgr)= @_;
     &Apache::loncommon::load_tmp_file($r);      &Apache::loncommon::load_tmp_file($r);
     my @slotdata = &Apache::loncommon::upfile_record_sep();      my @slotdata = &Apache::loncommon::upfile_record_sep();
     if ($env{'form.noFirstLine'}) { shift(@slotdata); }      if ($env{'form.noFirstLine'}) { shift(@slotdata); }
Line 701  sub csv_upload_assign { Line 1455  sub csv_upload_assign {
     my $cname=$env{'course.'.$env{'request.course.id'}.'.num'};      my $cname=$env{'course.'.$env{'request.course.id'}.'.num'};
     my $cdom=$env{'course.'.$env{'request.course.id'}.'.domain'};      my $cdom=$env{'course.'.$env{'request.course.id'}.'.domain'};
     my $countdone=0;      my $countdone=0;
       my @errors;
     foreach my $slot (@slotdata) {      foreach my $slot (@slotdata) {
  my %slot;   my %slot;
  my %entries=&Apache::loncommon::record_sep($slot);   my %entries=&Apache::loncommon::record_sep($slot);
  my $domain;   my $domain;
  my $name=$entries{$fields{'name'}};   my $name=$entries{$fields{'name'}};
    if ($name=~/^\s*$/) {
       push(@errors,"Did not create slot with no name");
       next;
    }
    if ($name=~/\s/) { 
       push(@errors,"$name not created -- Name must not contain spaces");
       next;
    }
    if ($name=~/\W/) { 
       push(@errors,"$name not created -- Name must contain only letters, numbers and _");
       next;
    }
  if ($entries{$fields{'type'}}) {   if ($entries{$fields{'type'}}) {
     $slot{'type'}=$entries{$fields{'type'}};      $slot{'type'}=$entries{$fields{'type'}};
  } else {   } else {
     $slot{'type'}='preassigned';      $slot{'type'}='preassigned';
  }   }
    if ($slot{'type'} ne 'preassigned' &&
       $slot{'type'} ne 'schedulable_student') {
       push(@errors,"$name not created -- invalid type ($slot{'type'}) must be either preassigned or schedulable_student");
       next;
    }
  if ($entries{$fields{'starttime'}}) {   if ($entries{$fields{'starttime'}}) {
     $slot{'starttime'}=&UnixDate($entries{$fields{'starttime'}},"%s");      $slot{'starttime'}=&UnixDate($entries{$fields{'starttime'}},"%s");
  }   }
  if ($entries{$fields{'endtime'}}) {   if ($entries{$fields{'endtime'}}) {
     $slot{'endtime'}=&UnixDate($entries{$fields{'starttime'}},"%s");      $slot{'endtime'}=&UnixDate($entries{$fields{'endtime'}},"%s");
    }
   
    # start/endtime must be defined and greater than zero
    if (!$slot{'starttime'}) {
       push(@errors,"$name not created -- Invalid start time");
       next;
    }
    if (!$slot{'endtime'}) {
       push(@errors,"$name not created -- Invalid end time");
       next;
    }
    if ($slot{'starttime'} > $slot{'endtime'}) {
       push(@errors,"$name not created -- Slot starts after it ends");
       next;
  }   }
   
    if ($entries{$fields{'startreserve'}}) {
       $slot{'startreserve'}=
    &UnixDate($entries{$fields{'startreserve'}},"%s");
    }
    if (defined($slot{'startreserve'})
       && $slot{'startreserve'} > $slot{'starttime'}) {
       push(@errors,"$name not created -- Slot's reservation start time is after the slot's start time.");
       next;
    }
   
  foreach my $key ('ip','proctor','description','maxspace',   foreach my $key ('ip','proctor','description','maxspace',
  'secret','symb') {   'secret','symb') {
     if ($entries{$fields{$key}}) {      if ($entries{$fields{$key}}) {
  $slot{$key}=$entries{$fields{$key}};   $slot{$key}=$entries{$fields{$key}};
     }      }
  }   }
   
  if ($entries{$fields{'uniqueperiod'}}) {   if ($entries{$fields{'uniqueperiod'}}) {
     my ($start,$end)=split(',',$entries{$fields{'uniqueperiod'}});      my ($start,$end)=split(',',$entries{$fields{'uniqueperiod'}});
     my @times=(&UnixDate($start,"%s"),      my @times=(&UnixDate($start,"%s"),
        &UnixDate($end,"%s"));         &UnixDate($end,"%s"));
     $slot{'uniqueperiod'}=\@times;      $slot{'uniqueperiod'}=\@times;
  }   }
    if (defined($slot{'uniqueperiod'})
       && $slot{'uniqueperiod'}[0] > $slot{'uniqueperiod'}[1]) {
       push(@errors,"$name not created -- Slot's unique period start time is later than the unique period's end time.");
       next;
    }
   
  &Apache::lonnet::cput('slots',{$name=>\%slot},$cdom,$cname);   &Apache::lonnet::cput('slots',{$name=>\%slot},$cdom,$cname);
  $r->print('.');   $r->print('.');
  $r->rflush();   $r->rflush();
  $countdone++;   $countdone++;
     }      }
     $r->print("<br />Created $countdone slots\n");      $r->print("<p>Created $countdone slots\n</p>");
     $r->print("<br />\n");      foreach my $error (@errors) {
     &show_table($r,$symb);   $r->print("<p>$error\n</p>");
       }
       &show_table($r,$mgr);
     return '';      return '';
 }  }
   
 sub handler {  sub handler {
     my $r=shift;      my $r=shift;
   
     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'});      &Apache::loncommon::content_type($r,'text/html');
     &start_page($r);      &Apache::loncommon::no_cache($r);
     my $symb=&Apache::lonnet::unescape($env{'form.symb'});      if ($r->header_only()) {
     my (undef,undef,$res)=&Apache::lonnet::decode_symb($symb);   $r->send_http_header();
     if ($res !~ /\.task$/) {  
  &fail($r,'not_valid');  
  return OK;   return OK;
     }      }
     $env{'request.symb'}=$symb;  
       &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'});
       
     my $vgr=&Apache::lonnet::allowed('vgr',$env{'request.course.id'});      my $vgr=&Apache::lonnet::allowed('vgr',$env{'request.course.id'});
     my $mgr=&Apache::lonnet::allowed('mgr',$env{'request.course.id'});      my $mgr=&Apache::lonnet::allowed('mgr',$env{'request.course.id'});
       my $title='Requesting Another Worktime';
       if ($env{'form.command'} =~ /^(showslots|uploadstart|csvuploadmap|csvuploadassign)$/ && $vgr eq 'F') {
    $title = 'Managing Slots';
       }
       &start_page($r,$title);
   
     if ($env{'form.command'} eq 'showslots' && $vgr eq 'F') {      if ($env{'form.command'} eq 'showslots' && $vgr eq 'F') {
  &show_table($r,$symb,$mgr);   &show_table($r,$mgr);
       } elsif ($env{'form.command'} eq 'remove_registration' && $mgr eq 'F') {
    &remove_registration($r);
       } elsif ($env{'form.command'} eq 'release' && $mgr eq 'F') {
    if ($env{'form.entry'} eq 'remove all') {
       &release_all_slot($r,$mgr);
    } else {
       &release_slot($r,undef,undef,undef,$mgr);
    }
       } elsif ($env{'form.command'} eq 'delete' && $mgr eq 'F') {
    &delete_slot($r);
     } elsif ($env{'form.command'} eq 'uploadstart' && $mgr eq 'F') {      } elsif ($env{'form.command'} eq 'uploadstart' && $mgr eq 'F') {
  &upload_start($r,$symb);   &upload_start($r);
     } elsif ($env{'form.command'} eq 'csvuploadmap' && $mgr eq 'F') {      } elsif ($env{'form.command'} eq 'csvuploadmap' && $mgr eq 'F') {
  &csv_upload_map($r,$symb);   &csv_upload_map($r);
     } elsif ($env{'form.command'} eq 'csvuploadassign' && $mgr eq 'F') {      } elsif ($env{'form.command'} eq 'csvuploadassign' && $mgr eq 'F') {
  if ($env{'form.associate'} ne 'Reverse Association') {   if ($env{'form.associate'} ne 'Reverse Association') {
     &csv_upload_assign($r,$symb);      &csv_upload_assign($r,$mgr);
  } else {   } else {
     if ( $env{'form.upfile_associate'} ne 'reverse' ) {      if ( $env{'form.upfile_associate'} ne 'reverse' ) {
  $env{'form.upfile_associate'} = 'reverse';   $env{'form.upfile_associate'} = 'reverse';
     } else {      } else {
  $env{'form.upfile_associate'} = 'forward';   $env{'form.upfile_associate'} = 'forward';
     }      }
     &csv_upload_map($r,$symb);      &csv_upload_map($r);
  }   }
     } else {      } else {
  my ($status) = &Apache::lonhomework::check_task_access('0');   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' 
       && $useslots ne 'map' 
       && $useslots ne 'map_map') {
       &fail($r,'not_available');
       return OK;
    }
    $env{'request.symb'}=$symb;
    my $type = ($res =~ /\.task$/) ? 'Task'
                                  : 'problem';
    my ($status) = &Apache::lonhomework::check_slot_access('0',$type);
  if ($status eq 'CAN_ANSWER' ||   if ($status eq 'CAN_ANSWER' ||
     $status eq 'NEEDS_CHECKIN' ||      $status eq 'NEEDS_CHECKIN' ||
     $status eq 'WAITING_FOR_GRADE') {      $status eq 'WAITING_FOR_GRADE') {
Line 787  sub handler { Line 1624  sub handler {
  } elsif ($env{'form.command'} eq 'get') {   } elsif ($env{'form.command'} eq 'get') {
     &get_slot($r,$symb);      &get_slot($r,$symb);
  } elsif ($env{'form.command'} eq 'change') {   } elsif ($env{'form.command'} eq 'change') {
     &release_slot($r,$symb,$env{'form.releaseslot'},1);      if (&release_slot($r,$symb,$env{'form.releaseslot'},1)) {
     &get_slot($r,$symb);   &get_slot($r,$symb);
       }
  } else {   } else {
     $r->print("<p>Unknown command: ".$env{'form.command'}."</p>");      $r->print("<p>Unknown command: ".$env{'form.command'}."</p>");
  }   }

Removed from v.1.15  
changed lines
  Added in v.1.74


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>