File:  [LON-CAPA] / loncom / interface / slotrequest.pm
Revision 1.25: download - view: text, annotated - select for diffs
Mon Oct 17 21:21:39 2005 UTC (18 years, 7 months ago) by albertel
Branches: MAIN
CVS tags: HEAD
- Can now edit a slot

# The LearningOnline Network with CAPA
# Handler for requesting to have slots added to a students record
#
# $Id: slotrequest.pm,v 1.25 2005/10/17 21:21:39 albertel Exp $
#
# Copyright Michigan State University Board of Trustees
#
# This file is part of the LearningOnline Network with CAPA (LON-CAPA).
#
# LON-CAPA is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# LON-CAPA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LON-CAPA; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# /home/httpd/html/adm/gpl.txt
#
# http://www.lon-capa.org/
#
###

package Apache::slotrequest;

use strict;
use Apache::Constants qw(:common :http :methods);
use Apache::loncommon();
use Apache::lonlocal;
use Apache::lonnet;
use Date::Manip;

sub fail {
    my ($r,$code)=@_;
    if ($code eq 'not_valid') {
	$r->print('<p>'.&mt('Unable to understand what resource you wanted to sign up for.').'</p>');

    } elsif ($code eq 'not_allowed') {
	$r->print('<p>'.&mt('Not allowed to sign up or change reservations at this time.').'</p>');
    } else {
	$r->print('<p>'.&mt('Failed.').'</p>');
    }
    
    $r->print('<p><a href="/adm/flip?postdata=return:">'.
	      &mt('Return to last resource').'</a></p>');
    &end_page($r);
}

sub start_page {
    my ($r)=@_;
    my $html=&Apache::lonxml::xmlbegin();
    $r->print($html.'<head><title>'.
	      &mt('Request another Worktime').'</title></head>');
    $r->print(&Apache::loncommon::bodytag('Requesting another Worktime'));
}

sub end_page {
    my ($r)=@_;
    $r->print(&Apache::loncommon::endbodytag().'</html>');
}

=pod

 slot_reservations db
   - keys are 
    - slotname\0id -> value is an hashref of
                         name -> user@domain of holder
                         timestamp -> timestamp of reservation
                         symb -> symb of resource that it is reserved for

=cut

sub get_course {
    (undef,my $courseid)=&Apache::lonxml::whichuser();
    my $cdom=$env{'course.'.$courseid.'.domain'};
    my $cnum=$env{'course.'.$courseid.'.num'};
    return ($cnum,$cdom);
}

sub get_reservation_ids {
    my ($slot_name)=@_;
    
    my ($cnum,$cdom)=&get_course();

    my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,
				       "^$slot_name\0");
    
    my ($tmp)=%consumed;
    if ($tmp=~/^error: 2 / ) {
	return 0;
    }
    return keys(%consumed);
}

sub space_available {
    my ($slot_name,$slot)=@_;
    my $max=$slot->{'maxspace'};

    if (!defined($max)) { return 1; }

    my $consumed=scalar(&get_reservation_ids($slot_name));
    if ($consumed < $max) {
	return 1
    }
    return 0;
}

sub check_for_reservation {
    my ($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'});
    my @slots = (split(/:/,$student), split(/:/, $course));

    &Apache::lonxml::debug(" slot list is ".join(':',@slots));

    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}));
	&Apache::lonxml::debug(time." $slot_name ".
			       $slots{$slot_name}->{'starttime'}." -- ".
			       $slots{$slot_name}->{'startreserve'});
	if ($slots{$slot_name}->{'endtime'} > time &&
	    $slots{$slot_name}->{'startreserve'} < time) {
	    # between start of reservation times and end of slot
	    return($slot_name, $slots{$slot_name});
	}
    }
    return (undef,undef);
}

sub check_for_conflict {
    my ($symb,$new_slot_name)=@_;
    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'});
    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'}) ||
		 !ref($slots{$slot_name}->{'uniqueperiod'}));
	my ($start,$end)=@{$slots{$slot_name}->{'uniqueperiod'}};
	if ($start<time && time < $end) {
	    return $slot_name;
	}
    }
    return undef;

}

sub make_reservation {
    my ($slot_name,$slot,$symb)=@_;

    my ($cnum,$cdom)=&get_course();

    my $value=&Apache::lonnet::EXT("resource.0.availablestudent",$symb,
				   $env{'user.domain'},$env{'user.name'});
    &Apache::lonxml::debug("value is  $value<br />");
    foreach my $other_slot (split(/:/, $value)) {
	if ($other_slot eq $slot_name) {
	    my %consumed=&Apache::lonnet::dump('slot_reservations', $cdom,
					       $cnum, "^$slot_name\0");   

	    my $me=$env{'user.name'}.'@'.$env{'user.domain'};
	    foreach my $key (keys(%consumed)) {
		if ($consumed{$key}->{'name'} eq $me) {
		    my $num=(split('\0',$key))[1];
		    return -$num;
		}
	    }
	}
    }

    my $max=$slot->{'maxspace'};
    if (!defined($max)) { $max=99999; }

    my (@ids)=&get_reservation_ids($slot_name);

    my $last=0;
    foreach my $id (@ids) {
	my $num=(split('\0',$id))[1];
	if ($num > $last) { $last=$num; }
    }
    
    my $wanted=$last+1;
    &Apache::lonxml::debug("wanted $wanted<br />");
    if (scalar(@ids) >= $max) {
	# full up
	return undef;
    }
    
    my %reservation=('name'      => $env{'user.name'}.'@'.$env{'user.domain'},
		     'timestamp' => time,
		     'symb'      => $symb);

    my $success=&Apache::lonnet::newput('slot_reservations',
					{"$slot_name\0$wanted" =>
					     \%reservation},
					$cdom, $cnum);

    if ($success eq 'ok') {
	my $new_value=$slot_name;
	if ($value) {
	    $new_value=$value.':'.$new_value;
	}
	my $result=&Apache::lonparmset::storeparm_by_symb($symb,
						      '0_availablestudent',
						       1, $new_value, 'string',
						       $env{'user.name'},
					               $env{'user.domain'});
	&Apache::lonxml::debug("hrrm $result");
	return $wanted;
    }

    # someone else got it
    return undef;
}

sub release_slot {
    my ($r,$symb,$slot_name,$inhibit_return_link)=@_;

    if ($slot_name eq '') { $slot_name=$env{'form.slotname'}; }
    my ($cnum,$cdom)=&get_course();

    # get parameter string, check for existance, rebuild string with the slot
				       
    my @slots = split(/:/,&Apache::lonnet::EXT("resource.0.availablestudent",
					       $symb,$env{'user.domain'},
					       $env{'user.name'}));
    my @new_slots;
    foreach my $exist_slot (@slots) {
	if ($exist_slot eq $slot_name) { next; }
	push(@new_slots,$exist_slot);
    }
    my $new_param = join(':',@new_slots);

    # get slot reservations, check if user has one, if so remove reservation
    my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,
				       "^$slot_name\0");
    foreach my $entry (keys(%consumed)) {
	if ( $consumed{$entry}->{'name'} eq 
	     ($env{'user.name'}.'@'.$env{'user.domain'}) ) {
	    &Apache::lonnet::del('slot_reservations',[$entry],
				 $cdom,$cnum);
	}
    }
    # store new parameter string
    my $result=&Apache::lonparmset::storeparm_by_symb($symb,
						      '0_availablestudent',
						      1, $new_param, 'string',
						      $env{'user.name'},
						      $env{'user.domain'});
    my %slot=&Apache::lonnet::get_slot($slot_name);
    my $description=&get_description($env{'form.slotname'},\%slot);
    $r->print("<p>Released Reservation: $description</p>");
    if (!$inhibit_return_link) {
	$r->print('<p><a href="/adm/flip?postdata=return:">'.
		  &mt('Return to last resource').'</a></p>');
    }
    return 1;
}

sub get_slot {
    my ($r,$symb)=@_;

    my $slot_name=&check_for_conflict($symb,$env{'form.slotname'});
    if ($slot_name) {
	my %slot=&Apache::lonnet::get_slot($slot_name);
	my $description1=&get_description($slot_name,\%slot);
	%slot=&Apache::lonnet::get_slot($env{'form.slotname'});
	my $description2=&get_description($env{'form.slotname'},\%slot);
	$r->print("<p>Already have a reservation: $description1</p>");
	if ($slot_name ne $env{'form.slotname'}) {
	    $r->print(<<STUFF);
<form method="POST" action="/adm/slotrequest">
   <input type="hidden" name="symb" value="$env{'form.symb'}" />
   <input type="hidden" name="slotname" value="$env{'form.slotname'}" />
   <input type="hidden" name="releaseslot" value="$slot_name" />
   <input type="hidden" name="command" value="change" />
STUFF
            $r->print("<p>You can either ");
	    $r->print(<<STUFF);
   <input type="submit" name="change" value="Change" />
STUFF
	    $r->print(' your reservation from <b>'.$description1.'</b> to <b>'.
		      $description2.
		      '</b> <br />or <a href="/adm/flip?postdata=return:">'.
		      &mt('Return to last resource').'</a></p>');
	    $r->print(<<STUFF);
</form>
STUFF
        } else {
	    $r->print('<p><a href="/adm/flip?postdata=return:">'.
		      &mt('Return to last resource').'</a></p>');
	}
	return;
    }
    my %slot=&Apache::lonnet::get_slot($env{'form.slotname'});
    my $reserved=&make_reservation($env{'form.slotname'},
				   \%slot,$symb);
    my $description=&get_description($env{'form.slotname'},\%slot);
    if (defined($reserved)) {
	if ($reserved > -1) {
	    $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) {
	    $r->print("<p>Already reserved: $description</p>");
	    $r->print('<p><a href="/adm/flip?postdata=return:">'.
		      &mt('Return to last resource').'</a></p>');
	    return;
	}
    }

    my %lt=('request'=>"Availibility list",
	    'try'    =>'Try again');
    %lt=&Apache::lonlocal::texthash(%lt);

    $r->print(<<STUFF);
<p> <font color="red">Failed</font> to reserve a spot for $description. </p>
<p>
<form method="POST" action="/adm/slotrequest">
   <input type="submit" name="Try Again" value="$lt{'try'}" />
   <input type="hidden" name="symb" value="$env{'form.symb'}" />
   <input type="hidden" name="slotname" value="$env{'form.slotname'}" />
   <input type="hidden" name="command" value="get" />
</form>
?
</p>
<p>
or
<form method="POST" action="/adm/slotrequest">
    <input type="hidden" name="symb" value="$env{'form.symb'}" />
    <input type="submit" name="requestattempt" value="$lt{'request'}" />
</form>
</p>
or
STUFF
    $r->print('<p><a href="/adm/flip?postdata=return:">'.
	      &mt('Return to last resource').'</a></p>');
    return;
}

sub allowed_slot {
    my ($slot_name,$slot,$symb)=@_;
    #already started
    if ($slot->{'starttime'} < time) {
	# all open slot to be schedulable
	#return 0;
    }
    &Apache::lonxml::debug("$slot_name starttime good");
    #already ended
    if ($slot->{'endtime'} < time) {
	return 0;
    }
    &Apache::lonxml::debug("$slot_name endtime good");
    # not allowed to pick this one
    if (defined($slot->{'type'})
	&& $slot->{'type'} ne 'schedulable_student') {
	return 0;
    }
    &Apache::lonxml::debug("$slot_name type good");
    # not allowed for this resource
    if (defined($slot->{'symb'})
	&& $slot->{'symb'} ne $symb) {
	return 0;
    }
    &Apache::lonxml::debug("$slot_name symb good");
    return 1;
}

sub get_description {
    my ($slot_name,$slot)=@_;
    my $description=$slot->{'description'};
    if (!defined($description)) {
	$description=&mt('[_1] From [_2] to [_3]',$slot_name,
			 &Apache::lonlocal::locallocaltime($slot->{'starttime'}),
			 &Apache::lonlocal::locallocaltime($slot->{'endtime'}));
    }
    return $description;
}

sub show_choices {
    my ($r,$symb)=@_;

    my ($cnum,$cdom)=&get_course();
    my %slots=&Apache::lonnet::dump('slots',$cdom,$cnum);
    my $available;
    $r->print('<table border="1">');
    &Apache::lonxml::debug("Checking Slots");
    my ($got_slot)=&check_for_reservation($symb);
    foreach my $slot (sort 
		      { return $slots{$a}->{'starttime'} <=> $slots{$b}->{'starttime'} }
		      (keys(%slots)))  {

	&Apache::lonxml::debug("Checking Slot $slot");
	next if (!&allowed_slot($slot,$slots{$slot}));

	$available++;

	my $description=&get_description($slot,$slots{$slot});

	my $form=&mt('Unavailable');
	if (($slot eq $got_slot) ||
	    &space_available($slot,$slots{$slot},$symb)) {
	    my $text=&mt('Select');
	    my $command='get';
	    if ($slot eq $got_slot) {
		$text=&mt('Free Reservation');
		$command='release';
	    }
	    my $escsymb=&Apache::lonnet::escape($symb);
	    $form=<<STUFF;
   <form method="POST" action="/adm/slotrequest">
     <input type="submit" name="Select" value="$text" />
     <input type="hidden" name="symb" value="$escsymb" />
     <input type="hidden" name="slotname" value="$slot" />
     <input type="hidden" name="command" value="$command" />
   </form>
STUFF
	}
	$r->print(<<STUFF);
<tr>
 <td>$form</td>
 <td>$description</td>
</tr>
STUFF
    }

    if (!$available) {
	$r->print('<tr><td>No available times. <a href="/adm/flip?postdata=return:">'.
		  &mt('Return to last resource').'</a></td></tr>');
    }
    $r->print('</table>');
}

sub show_table {
    my ($r,$mgr)=@_;

    my ($cnum,$cdom)=&get_course();
    my %slots=&Apache::lonnet::dump('slots',$cdom,$cnum);
    if ( (keys(%slots))[0] =~ /^error: 2 /) {
	undef(%slots);
    } 
    my $available;
    if ($mgr eq 'F') {
	$r->print('<form method="POST" action="/adm/slotrequest">
<input type="hidden" name="command" value="uploadstart" />
<input type="submit" name="start" value="'.&mt('Upload Slot List').'" />
</form>');
    }
    my $linkstart='<a href="/adm/slotrequest?command=showslots&amp;order=';
    $r->print('<table border="1">
<tr>
  <th></th>
  <th>'.$linkstart.'name"        >Slot name</a></th>
  <th>'.$linkstart.'type"        >Type</a></th>
  <th>'.$linkstart.'description" >Description</a></th>
  <th>'.$linkstart.'starttime"   >Start Time</a></th>
  <th>'.$linkstart.'endtime"     >End Time</a></th>
  <th>'.$linkstart.'startreserve">Time Students Can Start Reserving</a></th>
  <th>'.$linkstart.'secret"      >Secret</a></th>
  <th>'.$linkstart.'maxspace"    >Max space</a></th>
  <th>                            Scheduled Students</th>
  <th>'.$linkstart.'unique"      >Unique Period</a></th>
</tr>');
    my %name_cache;
    my $slotsort = sub {
	if ($env{'form.order'}=~/^(type|description|endtime|maxspace)$/) {
	    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 'name') {
	    if (lc($a) cmp lc($b)) {
		return lc($a) cmp lc($b);
	    }
	} elsif ($env{'form.order'} eq 'unique') {
	    
	    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'};
    };
    foreach my $slot (sort $slotsort (keys(%slots)))  {
	if (defined($slots{$slot}->{'type'})
	    && $slots{$slot}->{'type'} ne 'schedulable_student') {
	    #next;
	}
	my $description=&get_description($slot,$slots{$slot});
	my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,
					   "^$slot\0");
	my $ids;
	foreach my $entry (sort(keys(%consumed))) {
	    my (undef,$id)=split("\0",$entry);
	    $ids.= $id.'-> '.$consumed{$entry}->{'name'}.'<br />';
	}
	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}->{'endtime'}?
			   &Apache::lonlocal::locallocaltime($slots{$slot}->{'startreserve'}):'');
	
	my $unique;
	if (ref($slots{$slot}{'uniqueperiod'})) {
	    $unique=localtime($slots{$slot}{'uniqueperiod'}[0]).','.
		localtime($slots{$slot}{'uniqueperiod'}[1]);
	}
	my @proctors = map {
	    my ($uname,$udom)=split(/@/,$_);
	    my $fullname=$name_cache{$_};
	    if (!defined($fullname)) {
		&Apache::lonnet::logthis("Gettign $uname $udom");
		$fullname = &Apache::loncommon::plainname($uname,$udom);
		$fullname =~s/\s/&nbsp;/g;
		$name_cache{$_} = $fullname;
	    }
	    &Apache::loncommon::aboutmewrapper($fullname,$uname,$udom);
	} (split(/\s*,\s*/,$slots{$slot}->{'proctor'}));
	
	my $proctors=join(', ',@proctors);

	my $edit=(<<EDITFORM);
<form method="POST" action="/adm/helper/newslot.helper">
  <input type="hidden" name="name" value="$slot" />
  <input type="submit" name="Edit" value="Edit" />
</form>
EDITFORM
	$r->print(<<STUFF);
<tr>
 <td rowspan="2">$edit</td>
 <td>$slot</td>
 <td>$slots{$slot}->{'type'}</td>
 <td>$description</td>
 <td>$start</td>
 <td>$end</td>
 <td>$start_reserve</td>
 <td>$slots{$slot}->{'secret'}</td>
 <td>$slots{$slot}->{'maxspace'}</td>
 <td>$ids</td>
 <td>$unique</td>
</tr>
<tr>
 <td colspan="10">$proctors</td>
</tr>
STUFF
    }
    $r->print('</table>');
}

sub upload_start {
    my ($r)=@_;    
    $r->print(&Apache::grades::checkforfile_js());
    my $result.='<table width=100% border=0><tr bgcolor="#e6ffff"><td>'."\n";
    $result.='&nbsp;<b>'.
	&mt('Specify a file containing the slot definitions.').
	'</b></td></tr>'."\n";
    $result.='<tr bgcolor=#ffffe6><td>'."\n";
    my $upfile_select=&Apache::loncommon::upfile_select_html();
    my $ignore=&mt('Ignore First Line');
    $result.=<<ENDUPFORM;
<form method="post" enctype="multipart/form-data" action="/adm/slotrequest" name="slotupload">
<input type="hidden" name="command" value="csvuploadmap" />
$upfile_select
<br /><input type="button" onClick="javascript:checkUpload(this.form);" value="Upload Data" />
<label><input type="checkbox" name="noFirstLine" />$ignore</label>
</form>
ENDUPFORM
    $result.='</td></tr></table>'."\n";
    $result.='</td></tr></table>'."\n";
    $r->print($result);
}

sub csvuploadmap_header {
    my ($r,$datatoken,$distotal)= @_;
    my $javascript;
    if ($env{'form.upfile_associate'} eq 'reverse') {
	$javascript=&csvupload_javascript_reverse_associate();
    } else {
	$javascript=&csvupload_javascript_forward_associate();
    }

    my $checked=(($env{'form.noFirstLine'})?' checked="checked"':'');
    my $ignore=&mt('Ignore First Line');
    $r->print(<<ENDPICK);
<form method="post" enctype="multipart/form-data" action="/adm/slotrequest" name="slotupload">
<h3>Identify fields</h3>
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
to this page if the data selected is insufficient to create the slots.<hr />
<input type="button" value="Reverse Association" onClick="javascript:this.form.associate.value='Reverse Association';submit(this.form);" />
<label><input type="checkbox" name="noFirstLine" $checked />$ignore</label>
<input type="hidden" name="associate"  value="" />
<input type="hidden" name="datatoken"  value="$datatoken" />
<input type="hidden" name="fileupload" value="$env{'form.fileupload'}" />
<input type="hidden" name="upfiletype" value="$env{'form.upfiletype'}" />
<input type="hidden" name="upfile_associate" 
                                       value="$env{'form.upfile_associate'}" />
<input type="hidden" name="command"    value="csvuploadassign" />
<hr />
<script type="text/javascript" language="Javascript">
$javascript
</script>
ENDPICK
    return '';

}

sub csvuploadmap_footer {
    my ($request,$i,$keyfields) =@_;
    $request->print(<<ENDPICK);
</table>
<input type="hidden" name="nfields" value="$i" />
<input type="hidden" name="keyfields" value="$keyfields" />
<input type="button" onClick="javascript:verify(this.form)" value="Create Slots" /><br />
</form>
ENDPICK
}

sub csvupload_javascript_reverse_associate {
    my $error1=&mt('You need to specify the name, starttime, endtime and a type');
    return(<<ENDPICK);
  function verify(vf) {
    var foundstart=0;
    var foundend=0;
    var foundname=0;
    var foundtype=0;
    for (i=0;i<=vf.nfields.value;i++) {
      tw=eval('vf.f'+i+'.selectedIndex');
      if (i==0 && tw!=0) { foundname=1; }
      if (i==1 && tw!=0) { foundtype=1; }
      if (i==2 && tw!=0) { foundstat=1; }
      if (i==3 && tw!=0) { foundend=1; }
    }
    if (foundstart==0 && foundend==0 && foundtype==0 && foundname==0) {
	alert('$error1');
	return;
    }
    vf.submit();
  }
  function flip(vf,tf) {
  }
ENDPICK
}

sub csvupload_javascript_forward_associate {
    my $error1=&mt('You need to specify the name, starttime, endtime and a type');
  return(<<ENDPICK);
  function verify(vf) {
    var foundstart=0;
    var foundend=0;
    var foundname=0;
    var foundtype=0;
    for (i=0;i<=vf.nfields.value;i++) {
      tw=eval('vf.f'+i+'.selectedIndex');
      if (tw==1) { foundname=1; }
      if (tw==2) { foundtype=1; }
      if (tw==3) { foundstat=1; }
      if (tw==4) { foundend=1; }
    }
    if (foundstart==0 && foundend==0 && foundtype==0 && foundname==0) {
	alert('$error1');
	return;
    }
    vf.submit();
  }
  function flip(vf,tf) {
  }
ENDPICK
}

sub csv_upload_map {
    my ($r)= @_;

    my $datatoken;
    if (!$env{'form.datatoken'}) {
	$datatoken=&Apache::loncommon::upfile_store($r);
    } else {
	$datatoken=$env{'form.datatoken'};
	&Apache::loncommon::load_tmp_file($r);
    }
    my @records=&Apache::loncommon::upfile_record_sep();
    if ($env{'form.noFirstLine'}) { shift(@records); }
    &csvuploadmap_header($r,$datatoken,$#records+1);
    my ($i,$keyfields);
    if (@records) {
	my @fields=&csvupload_fields();

	if ($env{'form.upfile_associate'} eq 'reverse') {	
	    &Apache::loncommon::csv_print_samples($r,\@records);
	    $i=&Apache::loncommon::csv_print_select_table($r,\@records,
							  \@fields);
	    foreach (@fields) { $keyfields.=$_->[0].','; }
	    chop($keyfields);
	} else {
	    unshift(@fields,['none','']);
	    $i=&Apache::loncommon::csv_samples_select_table($r,\@records,
							    \@fields);
	    my %sone=&Apache::loncommon::record_sep($records[0]);
	    $keyfields=join(',',sort(keys(%sone)));
	}
    }
    &csvuploadmap_footer($r,$i,$keyfields);

    return '';
}

sub csvupload_fields {
    return (['name','Slot name'],
	    ['type','Type of slot'],
	    ['starttime','Start Time of slot'],
	    ['endtime','End Time of slot'],
	    ['startreserve','Reservation Start Time'],
	    ['ip','IP or DNS restriction'],
	    ['proctor','List of proctor ids'],
	    ['description','Slot Description'],
	    ['maxspace','Maximum number of reservations'],
	    ['symb','Resource Restriction'],
	    ['uniqueperiod','Date range of slot exclusion'],
	    ['secret','Secret word proctor uses to validate']);
}

sub csv_upload_assign {
    my ($r,$mgr)= @_;
    &Apache::loncommon::load_tmp_file($r);
    my @slotdata = &Apache::loncommon::upfile_record_sep();
    if ($env{'form.noFirstLine'}) { shift(@slotdata); }
    my %fields=&Apache::grades::get_fields();
    $r->print('<h3>Creating Slots</h3>');
    my $cname=$env{'course.'.$env{'request.course.id'}.'.num'};
    my $cdom=$env{'course.'.$env{'request.course.id'}.'.domain'};
    my $countdone=0;
    foreach my $slot (@slotdata) {
	my %slot;
	my %entries=&Apache::loncommon::record_sep($slot);
	my $domain;
	my $name=$entries{$fields{'name'}};
	if ($entries{$fields{'type'}}) {
	    $slot{'type'}=$entries{$fields{'type'}};
	} else {
	    $slot{'type'}='preassigned';
	}
	if ($entries{$fields{'starttime'}}) {
	    $slot{'starttime'}=&UnixDate($entries{$fields{'starttime'}},"%s");
	}
	if ($entries{$fields{'endtime'}}) {
	    $slot{'endtime'}=&UnixDate($entries{$fields{'endtime'}},"%s");
	}
	if ($entries{$fields{'startreserve'}}) {
	    $slot{'startreserve'}=
		&UnixDate($entries{$fields{'startreserve'}},"%s");
	}
	foreach my $key ('ip','proctor','description','maxspace',
			 'secret','symb') {
	    if ($entries{$fields{$key}}) {
		$slot{$key}=$entries{$fields{$key}};
	    }
	}
	if ($entries{$fields{'uniqueperiod'}}) {
	    my ($start,$end)=split(',',$entries{$fields{'uniqueperiod'}});
	    my @times=(&UnixDate($start,"%s"),
		       &UnixDate($end,"%s"));
	    $slot{'uniqueperiod'}=\@times;
	}

	&Apache::lonnet::cput('slots',{$name=>\%slot},$cdom,$cname);
	$r->print('.');
	$r->rflush();
	$countdone++;
    }
    $r->print("<br />Created $countdone slots\n");
    $r->print("<br />\n");
    &show_table($r,$mgr);
    return '';
}

sub handler {
    my $r=shift;

    &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'});
    &start_page($r);
    my $vgr=&Apache::lonnet::allowed('vgr',$env{'request.course.id'});
    my $mgr=&Apache::lonnet::allowed('mgr',$env{'request.course.id'});
    if ($env{'form.command'} eq 'showslots' && $vgr eq 'F') {
	&show_table($r,$mgr);
    } elsif ($env{'form.command'} eq 'uploadstart' && $mgr eq 'F') {
	&upload_start($r);
    } elsif ($env{'form.command'} eq 'csvuploadmap' && $mgr eq 'F') {
	&csv_upload_map($r);
    } elsif ($env{'form.command'} eq 'csvuploadassign' && $mgr eq 'F') {
	if ($env{'form.associate'} ne 'Reverse Association') {
	    &csv_upload_assign($r,$mgr);
	} else {
	    if ( $env{'form.upfile_associate'} ne 'reverse' ) {
		$env{'form.upfile_associate'} = 'reverse';
	    } else {
		$env{'form.upfile_associate'} = 'forward';
	    }
	    &csv_upload_map($r);
	}
    } elsif ($env{'form.command'} eq 'editslot' && $mgr eq 'F') {
	&show_slot_edit($r);
    } else {
	my $symb=&Apache::lonnet::unescape($env{'form.symb'});
	my (undef,undef,$res)=&Apache::lonnet::decode_symb($symb);
	if ($res !~ /\.task$/) {
	    &fail($r,'not_valid');
	    return OK;
	}
	$env{'request.symb'}=$symb;
	my ($status) = &Apache::lonhomework::check_task_access('0');
	if ($status eq 'CAN_ANSWER' ||
	    $status eq 'NEEDS_CHECKIN' ||
	    $status eq 'WAITING_FOR_GRADE') {
	    &fail($r,'not_allowed');
	    return OK;
	}
	if ($env{'form.requestattempt'}) {
	    &show_choices($r,$symb);
	} elsif ($env{'form.command'} eq 'release') {
	    &release_slot($r,$symb);
	} elsif ($env{'form.command'} eq 'get') {
	    &get_slot($r,$symb);
	} elsif ($env{'form.command'} eq 'change') {
	    &release_slot($r,$symb,$env{'form.releaseslot'},1);
	    &get_slot($r,$symb);
	} else {
	    $r->print("<p>Unknown command: ".$env{'form.command'}."</p>");
	}
    }
    &end_page($r);
    return OK;
}

1;
__END__

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
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.