Annotation of loncom/interface/slotrequest.pm, revision 1.26
1.1 albertel 1: # The LearningOnline Network with CAPA
2: # Handler for requesting to have slots added to a students record
3: #
1.26 ! banghart 4: # $Id: slotrequest.pm,v 1.25 2005/10/17 21:21:39 albertel Exp $
1.1 albertel 5: #
6: # Copyright Michigan State University Board of Trustees
7: #
8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
9: #
10: # LON-CAPA is free software; you can redistribute it and/or modify
11: # it under the terms of the GNU General Public License as published by
12: # the Free Software Foundation; either version 2 of the License, or
13: # (at your option) any later version.
14: #
15: # LON-CAPA is distributed in the hope that it will be useful,
16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18: # GNU General Public License for more details.
19: #
20: # You should have received a copy of the GNU General Public License
21: # along with LON-CAPA; if not, write to the Free Software
22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23: #
24: # /home/httpd/html/adm/gpl.txt
25: #
26: # http://www.lon-capa.org/
27: #
28: ###
29:
30: package Apache::slotrequest;
31:
32: use strict;
33: use Apache::Constants qw(:common :http :methods);
34: use Apache::loncommon();
35: use Apache::lonlocal;
36: use Apache::lonnet;
1.26 ! banghart 37: # use Date::Manip;
1.1 albertel 38:
39: sub fail {
40: my ($r,$code)=@_;
1.2 albertel 41: if ($code eq 'not_valid') {
1.8 albertel 42: $r->print('<p>'.&mt('Unable to understand what resource you wanted to sign up for.').'</p>');
1.2 albertel 43:
1.8 albertel 44: } elsif ($code eq 'not_allowed') {
45: $r->print('<p>'.&mt('Not allowed to sign up or change reservations at this time.').'</p>');
46: } else {
47: $r->print('<p>'.&mt('Failed.').'</p>');
1.2 albertel 48: }
1.8 albertel 49:
1.2 albertel 50: $r->print('<p><a href="/adm/flip?postdata=return:">'.
51: &mt('Return to last resource').'</a></p>');
1.1 albertel 52: &end_page($r);
53: }
54:
55: sub start_page {
56: my ($r)=@_;
57: my $html=&Apache::lonxml::xmlbegin();
58: $r->print($html.'<head><title>'.
59: &mt('Request another Worktime').'</title></head>');
60: $r->print(&Apache::loncommon::bodytag('Requesting another Worktime'));
61: }
62:
63: sub end_page {
64: my ($r)=@_;
65: $r->print(&Apache::loncommon::endbodytag().'</html>');
66: }
67:
1.2 albertel 68: =pod
69:
70: slot_reservations db
71: - keys are
72: - slotname\0id -> value is an hashref of
73: name -> user@domain of holder
74: timestamp -> timestamp of reservation
75: symb -> symb of resource that it is reserved for
76:
77: =cut
78:
79: sub get_course {
80: (undef,my $courseid)=&Apache::lonxml::whichuser();
81: my $cdom=$env{'course.'.$courseid.'.domain'};
82: my $cnum=$env{'course.'.$courseid.'.num'};
83: return ($cnum,$cdom);
84: }
85:
86: sub get_reservation_ids {
87: my ($slot_name)=@_;
88:
89: my ($cnum,$cdom)=&get_course();
90:
91: my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,
92: "^$slot_name\0");
93:
94: my ($tmp)=%consumed;
95: if ($tmp=~/^error: 2 / ) {
96: return 0;
97: }
98: return keys(%consumed);
99: }
100:
101: sub space_available {
102: my ($slot_name,$slot)=@_;
103: my $max=$slot->{'maxspace'};
104:
105: if (!defined($max)) { return 1; }
106:
107: my $consumed=scalar(&get_reservation_ids($slot_name));
108: if ($consumed < $max) {
109: return 1
110: }
111: return 0;
112: }
1.3 albertel 113:
1.4 albertel 114: sub check_for_reservation {
115: my ($symb)=@_;
116: my $student = &Apache::lonnet::EXT("resource.0.availablestudent", $symb,
117: $env{'user.domain'}, $env{'user.name'});
118:
119: my $course = &Apache::lonnet::EXT("resource.0.available", $symb,
120: $env{'user.domain'}, $env{'user.name'});
121: my @slots = (split(/:/,$student), split(/:/, $course));
122:
123: &Apache::lonxml::debug(" slot list is ".join(':',@slots));
124:
125: my ($cnum,$cdom)=&get_course();
126: my %slots=&Apache::lonnet::get('slots', [@slots], $cdom, $cnum);
127:
128: foreach my $slot_name (@slots) {
129: next if (!defined($slots{$slot_name}) ||
130: !ref($slots{$slot_name}));
131: &Apache::lonxml::debug(time." $slot_name ".
132: $slots{$slot_name}->{'starttime'}." -- ".
133: $slots{$slot_name}->{'startreserve'});
1.7 albertel 134: if ($slots{$slot_name}->{'endtime'} > time &&
1.4 albertel 135: $slots{$slot_name}->{'startreserve'} < time) {
1.7 albertel 136: # between start of reservation times and end of slot
1.4 albertel 137: return($slot_name, $slots{$slot_name});
138: }
139: }
140: return (undef,undef);
141: }
142:
1.5 albertel 143: sub check_for_conflict {
144: my ($symb,$new_slot_name)=@_;
145: my $student = &Apache::lonnet::EXT("resource.0.availablestudent", $symb,
146: $env{'user.domain'}, $env{'user.name'});
147: my $course = &Apache::lonnet::EXT("resource.0.available", $symb,
148: $env{'user.domain'}, $env{'user.name'});
149: my @slots = (split(/:/,$student), split(/:/, $course));
150: my ($cnum,$cdom)=&get_course();
151: my %slots=&Apache::lonnet::get('slots', [@slots], $cdom, $cnum);
152: foreach my $slot_name (@slots) {
153: next if (!defined($slots{$slot_name}) ||
154: !ref($slots{$slot_name}));
155:
156: next if (!defined($slots{$slot_name}->{'uniqueperiod'}) ||
157: !ref($slots{$slot_name}->{'uniqueperiod'}));
158: my ($start,$end)=@{$slots{$slot_name}->{'uniqueperiod'}};
159: if ($start<time && time < $end) {
160: return $slot_name;
161: }
162: }
163: return undef;
164:
165: }
166:
1.2 albertel 167: sub make_reservation {
168: my ($slot_name,$slot,$symb)=@_;
1.3 albertel 169:
170: my ($cnum,$cdom)=&get_course();
171:
172: my $value=&Apache::lonnet::EXT("resource.0.availablestudent",$symb,
173: $env{'user.domain'},$env{'user.name'});
174: &Apache::lonxml::debug("value is $value<br />");
175: foreach my $other_slot (split(/:/, $value)) {
176: if ($other_slot eq $slot_name) {
177: my %consumed=&Apache::lonnet::dump('slot_reservations', $cdom,
178: $cnum, "^$slot_name\0");
179:
180: my $me=$env{'user.name'}.'@'.$env{'user.domain'};
181: foreach my $key (keys(%consumed)) {
182: if ($consumed{$key}->{'name'} eq $me) {
183: my $num=(split('\0',$key))[1];
184: return -$num;
185: }
186: }
187: }
188: }
189:
1.2 albertel 190: my $max=$slot->{'maxspace'};
1.3 albertel 191: if (!defined($max)) { $max=99999; }
1.2 albertel 192:
193: my (@ids)=&get_reservation_ids($slot_name);
194:
195: my $last=0;
196: foreach my $id (@ids) {
197: my $num=(split('\0',$id))[1];
198: if ($num > $last) { $last=$num; }
199: }
200:
201: my $wanted=$last+1;
1.3 albertel 202: &Apache::lonxml::debug("wanted $wanted<br />");
1.7 albertel 203: if (scalar(@ids) >= $max) {
1.2 albertel 204: # full up
1.7 albertel 205: return undef;
1.2 albertel 206: }
207:
208: my %reservation=('name' => $env{'user.name'}.'@'.$env{'user.domain'},
209: 'timestamp' => time,
210: 'symb' => $symb);
211:
212: my $success=&Apache::lonnet::newput('slot_reservations',
213: {"$slot_name\0$wanted" =>
214: \%reservation},
1.3 albertel 215: $cdom, $cnum);
216:
1.2 albertel 217: if ($success eq 'ok') {
1.3 albertel 218: my $new_value=$slot_name;
219: if ($value) {
220: $new_value=$value.':'.$new_value;
221: }
222: my $result=&Apache::lonparmset::storeparm_by_symb($symb,
223: '0_availablestudent',
224: 1, $new_value, 'string',
225: $env{'user.name'},
226: $env{'user.domain'});
227: &Apache::lonxml::debug("hrrm $result");
1.2 albertel 228: return $wanted;
229: }
1.3 albertel 230:
1.2 albertel 231: # someone else got it
1.3 albertel 232: return undef;
233: }
234:
1.5 albertel 235: sub release_slot {
1.6 albertel 236: my ($r,$symb,$slot_name,$inhibit_return_link)=@_;
237:
238: if ($slot_name eq '') { $slot_name=$env{'form.slotname'}; }
239: my ($cnum,$cdom)=&get_course();
240:
1.5 albertel 241: # get parameter string, check for existance, rebuild string with the slot
1.6 albertel 242:
243: my @slots = split(/:/,&Apache::lonnet::EXT("resource.0.availablestudent",
244: $symb,$env{'user.domain'},
245: $env{'user.name'}));
246: my @new_slots;
247: foreach my $exist_slot (@slots) {
248: if ($exist_slot eq $slot_name) { next; }
249: push(@new_slots,$exist_slot);
250: }
251: my $new_param = join(':',@new_slots);
1.5 albertel 252:
253: # get slot reservations, check if user has one, if so remove reservation
1.6 albertel 254: my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,
255: "^$slot_name\0");
256: foreach my $entry (keys(%consumed)) {
257: if ( $consumed{$entry}->{'name'} eq
258: ($env{'user.name'}.'@'.$env{'user.domain'}) ) {
259: &Apache::lonnet::del('slot_reservations',[$entry],
260: $cdom,$cnum);
261: }
262: }
1.5 albertel 263: # store new parameter string
1.6 albertel 264: my $result=&Apache::lonparmset::storeparm_by_symb($symb,
265: '0_availablestudent',
266: 1, $new_param, 'string',
267: $env{'user.name'},
268: $env{'user.domain'});
269: my %slot=&Apache::lonnet::get_slot($slot_name);
270: my $description=&get_description($env{'form.slotname'},\%slot);
271: $r->print("<p>Released Reservation: $description</p>");
1.7 albertel 272: if (!$inhibit_return_link) {
1.6 albertel 273: $r->print('<p><a href="/adm/flip?postdata=return:">'.
274: &mt('Return to last resource').'</a></p>');
275: }
276: return 1;
1.5 albertel 277: }
278:
1.3 albertel 279: sub get_slot {
280: my ($r,$symb)=@_;
281:
1.5 albertel 282: my $slot_name=&check_for_conflict($symb,$env{'form.slotname'});
283: if ($slot_name) {
284: my %slot=&Apache::lonnet::get_slot($slot_name);
1.6 albertel 285: my $description1=&get_description($slot_name,\%slot);
286: %slot=&Apache::lonnet::get_slot($env{'form.slotname'});
287: my $description2=&get_description($env{'form.slotname'},\%slot);
288: $r->print("<p>Already have a reservation: $description1</p>");
1.7 albertel 289: if ($slot_name ne $env{'form.slotname'}) {
290: $r->print(<<STUFF);
1.6 albertel 291: <form method="POST" action="/adm/slotrequest">
292: <input type="hidden" name="symb" value="$env{'form.symb'}" />
293: <input type="hidden" name="slotname" value="$env{'form.slotname'}" />
294: <input type="hidden" name="releaseslot" value="$slot_name" />
295: <input type="hidden" name="command" value="change" />
296: STUFF
1.7 albertel 297: $r->print("<p>You can either ");
298: $r->print(<<STUFF);
1.6 albertel 299: <input type="submit" name="change" value="Change" />
300: STUFF
1.7 albertel 301: $r->print(' your reservation from <b>'.$description1.'</b> to <b>'.
302: $description2.
303: '</b> <br />or <a href="/adm/flip?postdata=return:">'.
304: &mt('Return to last resource').'</a></p>');
305: $r->print(<<STUFF);
1.6 albertel 306: </form>
307: STUFF
1.7 albertel 308: } else {
309: $r->print('<p><a href="/adm/flip?postdata=return:">'.
310: &mt('Return to last resource').'</a></p>');
311: }
1.5 albertel 312: return;
313: }
1.3 albertel 314: my %slot=&Apache::lonnet::get_slot($env{'form.slotname'});
315: my $reserved=&make_reservation($env{'form.slotname'},
316: \%slot,$symb);
317: my $description=&get_description($env{'form.slotname'},\%slot);
1.7 albertel 318: if (defined($reserved)) {
319: if ($reserved > -1) {
320: $r->print("<p>Success: $description</p>");
321: $r->print('<p><a href="/adm/flip?postdata=return:">'.
322: &mt('Return to last resource').'</a></p>');
323: return;
324: } elsif ($reserved < 0) {
325: $r->print("<p>Already reserved: $description</p>");
326: $r->print('<p><a href="/adm/flip?postdata=return:">'.
327: &mt('Return to last resource').'</a></p>');
328: return;
329: }
1.3 albertel 330: }
331:
1.7 albertel 332: my %lt=('request'=>"Availibility list",
1.3 albertel 333: 'try' =>'Try again');
334: %lt=&Apache::lonlocal::texthash(%lt);
335:
336: $r->print(<<STUFF);
337: <p> <font color="red">Failed</font> to reserve a spot for $description. </p>
338: <p>
339: <form method="POST" action="/adm/slotrequest">
340: <input type="submit" name="Try Again" value="$lt{'try'}" />
341: <input type="hidden" name="symb" value="$env{'form.symb'}" />
342: <input type="hidden" name="slotname" value="$env{'form.slotname'}" />
343: <input type="hidden" name="command" value="get" />
344: </form>
345: ?
346: </p>
347: <p>
348: or
349: <form method="POST" action="/adm/slotrequest">
350: <input type="hidden" name="symb" value="$env{'form.symb'}" />
351: <input type="submit" name="requestattempt" value="$lt{'request'}" />
352: </form>
353: </p>
354: or
355: STUFF
356: $r->print('<p><a href="/adm/flip?postdata=return:">'.
357: &mt('Return to last resource').'</a></p>');
358: return;
359: }
360:
361: sub allowed_slot {
362: my ($slot_name,$slot,$symb)=@_;
363: #already started
364: if ($slot->{'starttime'} < time) {
1.5 albertel 365: # all open slot to be schedulable
366: #return 0;
1.3 albertel 367: }
1.5 albertel 368: &Apache::lonxml::debug("$slot_name starttime good");
1.3 albertel 369: #already ended
370: if ($slot->{'endtime'} < time) {
371: return 0;
372: }
1.5 albertel 373: &Apache::lonxml::debug("$slot_name endtime good");
1.3 albertel 374: # not allowed to pick this one
375: if (defined($slot->{'type'})
376: && $slot->{'type'} ne 'schedulable_student') {
377: return 0;
378: }
1.5 albertel 379: &Apache::lonxml::debug("$slot_name type good");
1.3 albertel 380: # not allowed for this resource
381: if (defined($slot->{'symb'})
382: && $slot->{'symb'} ne $symb) {
383: return 0;
384: }
1.5 albertel 385: &Apache::lonxml::debug("$slot_name symb good");
1.3 albertel 386: return 1;
1.2 albertel 387: }
388:
1.3 albertel 389: sub get_description {
390: my ($slot_name,$slot)=@_;
391: my $description=$slot->{'description'};
392: if (!defined($description)) {
1.4 albertel 393: $description=&mt('[_1] From [_2] to [_3]',$slot_name,
1.3 albertel 394: &Apache::lonlocal::locallocaltime($slot->{'starttime'}),
395: &Apache::lonlocal::locallocaltime($slot->{'endtime'}));
396: }
397: return $description;
398: }
1.2 albertel 399:
400: sub show_choices {
401: my ($r,$symb)=@_;
402:
403: my ($cnum,$cdom)=&get_course();
404: my %slots=&Apache::lonnet::dump('slots',$cdom,$cnum);
1.3 albertel 405: my $available;
1.2 albertel 406: $r->print('<table border="1">');
1.5 albertel 407: &Apache::lonxml::debug("Checking Slots");
408: my ($got_slot)=&check_for_reservation($symb);
1.2 albertel 409: foreach my $slot (sort
410: { return $slots{$a}->{'starttime'} <=> $slots{$b}->{'starttime'} }
411: (keys(%slots))) {
1.5 albertel 412:
413: &Apache::lonxml::debug("Checking Slot $slot");
1.3 albertel 414: next if (!&allowed_slot($slot,$slots{$slot}));
415:
416: $available++;
417:
418: my $description=&get_description($slot,$slots{$slot});
1.2 albertel 419:
420: my $form=&mt('Unavailable');
1.7 albertel 421: if (($slot eq $got_slot) ||
422: &space_available($slot,$slots{$slot},$symb)) {
1.5 albertel 423: my $text=&mt('Select');
424: my $command='get';
425: if ($slot eq $got_slot) {
426: $text=&mt('Free Reservation');
427: $command='release';
428: }
1.3 albertel 429: my $escsymb=&Apache::lonnet::escape($symb);
1.2 albertel 430: $form=<<STUFF;
1.3 albertel 431: <form method="POST" action="/adm/slotrequest">
1.5 albertel 432: <input type="submit" name="Select" value="$text" />
1.3 albertel 433: <input type="hidden" name="symb" value="$escsymb" />
434: <input type="hidden" name="slotname" value="$slot" />
1.5 albertel 435: <input type="hidden" name="command" value="$command" />
1.2 albertel 436: </form>
437: STUFF
438: }
439: $r->print(<<STUFF);
440: <tr>
441: <td>$form</td>
442: <td>$description</td>
443: </tr>
444: STUFF
445: }
1.3 albertel 446:
447: if (!$available) {
1.5 albertel 448: $r->print('<tr><td>No available times. <a href="/adm/flip?postdata=return:">'.
1.3 albertel 449: &mt('Return to last resource').'</a></td></tr>');
450: }
1.2 albertel 451: $r->print('</table>');
452: }
453:
1.5 albertel 454: sub show_table {
1.19 albertel 455: my ($r,$mgr)=@_;
1.5 albertel 456:
457: my ($cnum,$cdom)=&get_course();
458: my %slots=&Apache::lonnet::dump('slots',$cdom,$cnum);
1.19 albertel 459: if ( (keys(%slots))[0] =~ /^error: 2 /) {
460: undef(%slots);
461: }
1.5 albertel 462: my $available;
1.14 albertel 463: if ($mgr eq 'F') {
464: $r->print('<form method="POST" action="/adm/slotrequest">
465: <input type="hidden" name="command" value="uploadstart" />
466: <input type="submit" name="start" value="'.&mt('Upload Slot List').'" />
467: </form>');
468: }
1.21 albertel 469: my $linkstart='<a href="/adm/slotrequest?command=showslots&order=';
1.10 albertel 470: $r->print('<table border="1">
471: <tr>
1.19 albertel 472: <th></th>
1.23 albertel 473: <th>'.$linkstart.'name" >Slot name</a></th>
474: <th>'.$linkstart.'type" >Type</a></th>
475: <th>'.$linkstart.'description" >Description</a></th>
476: <th>'.$linkstart.'starttime" >Start Time</a></th>
477: <th>'.$linkstart.'endtime" >End Time</a></th>
478: <th>'.$linkstart.'startreserve">Time Students Can Start Reserving</a></th>
479: <th>'.$linkstart.'secret" >Secret</a></th>
480: <th>'.$linkstart.'maxspace" >Max space</a></th>
481: <th> Scheduled Students</th>
482: <th>'.$linkstart.'unique" >Unique Period</a></th>
1.10 albertel 483: </tr>');
1.21 albertel 484: my %name_cache;
485: my $slotsort = sub {
1.23 albertel 486: if ($env{'form.order'}=~/^(type|description|endtime|maxspace)$/) {
1.21 albertel 487: if (lc($slots{$a}->{$env{'form.order'}})
488: ne lc($slots{$b}->{$env{'form.order'}})) {
489: return (lc($slots{$a}->{$env{'form.order'}})
490: cmp lc($slots{$b}->{$env{'form.order'}}));
491: }
1.23 albertel 492: } elsif ($env{'form.order'} eq 'name') {
493: if (lc($a) cmp lc($b)) {
494: return lc($a) cmp lc($b);
495: }
1.21 albertel 496: } elsif ($env{'form.order'} eq 'unique') {
497:
498: if ($slots{$a}->{'uniqueperiod'}[0]
499: ne $slots{$b}->{'uniqueperiod'}[0]) {
500: return ($slots{$a}->{'uniqueperiod'}[0]
501: cmp $slots{$b}->{'uniqueperiod'}[0]);
502: }
503: if ($slots{$a}->{'uniqueperiod'}[1]
504: ne $slots{$b}->{'uniqueperiod'}[1]) {
505: return ($slots{$a}->{'uniqueperiod'}[1]
506: cmp $slots{$b}->{'uniqueperiod'}[1]);
507: }
508: }
509: return $slots{$a}->{'starttime'} <=> $slots{$b}->{'starttime'};
510: };
511: foreach my $slot (sort $slotsort (keys(%slots))) {
1.5 albertel 512: if (defined($slots{$slot}->{'type'})
513: && $slots{$slot}->{'type'} ne 'schedulable_student') {
1.13 albertel 514: #next;
1.5 albertel 515: }
516: my $description=&get_description($slot,$slots{$slot});
517: my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,
518: "^$slot\0");
519: my $ids;
520: foreach my $entry (sort(keys(%consumed))) {
521: my (undef,$id)=split("\0",$entry);
522: $ids.= $id.'-> '.$consumed{$entry}->{'name'}.'<br />';
523: }
1.24 albertel 524: my $start=($slots{$slot}->{'starttime'}?
525: &Apache::lonlocal::locallocaltime($slots{$slot}->{'starttime'}):'');
526: my $end=($slots{$slot}->{'endtime'}?
527: &Apache::lonlocal::locallocaltime($slots{$slot}->{'endtime'}):'');
528: my $start_reserve=($slots{$slot}->{'endtime'}?
529: &Apache::lonlocal::locallocaltime($slots{$slot}->{'startreserve'}):'');
530:
1.14 albertel 531: my $unique;
532: if (ref($slots{$slot}{'uniqueperiod'})) {
533: $unique=localtime($slots{$slot}{'uniqueperiod'}[0]).','.
534: localtime($slots{$slot}{'uniqueperiod'}[1]);
535: }
1.20 albertel 536: my @proctors = map {
537: my ($uname,$udom)=split(/@/,$_);
1.21 albertel 538: my $fullname=$name_cache{$_};
539: if (!defined($fullname)) {
540: &Apache::lonnet::logthis("Gettign $uname $udom");
541: $fullname = &Apache::loncommon::plainname($uname,$udom);
542: $fullname =~s/\s/ /g;
543: $name_cache{$_} = $fullname;
544: }
1.20 albertel 545: &Apache::loncommon::aboutmewrapper($fullname,$uname,$udom);
546: } (split(/\s*,\s*/,$slots{$slot}->{'proctor'}));
547:
548: my $proctors=join(', ',@proctors);
1.14 albertel 549:
1.19 albertel 550: my $edit=(<<EDITFORM);
1.25 albertel 551: <form method="POST" action="/adm/helper/newslot.helper">
552: <input type="hidden" name="name" value="$slot" />
1.19 albertel 553: <input type="submit" name="Edit" value="Edit" />
554: </form>
555: EDITFORM
1.5 albertel 556: $r->print(<<STUFF);
557: <tr>
1.21 albertel 558: <td rowspan="2">$edit</td>
1.5 albertel 559: <td>$slot</td>
1.10 albertel 560: <td>$slots{$slot}->{'type'}</td>
1.5 albertel 561: <td>$description</td>
562: <td>$start</td>
563: <td>$end</td>
1.23 albertel 564: <td>$start_reserve</td>
1.22 albertel 565: <td>$slots{$slot}->{'secret'}</td>
1.5 albertel 566: <td>$slots{$slot}->{'maxspace'}</td>
567: <td>$ids</td>
1.14 albertel 568: <td>$unique</td>
1.5 albertel 569: </tr>
1.21 albertel 570: <tr>
1.23 albertel 571: <td colspan="10">$proctors</td>
1.21 albertel 572: </tr>
1.5 albertel 573: STUFF
574: }
575: $r->print('</table>');
576: }
577:
1.14 albertel 578: sub upload_start {
1.19 albertel 579: my ($r)=@_;
1.14 albertel 580: $r->print(&Apache::grades::checkforfile_js());
581: my $result.='<table width=100% border=0><tr bgcolor="#e6ffff"><td>'."\n";
582: $result.=' <b>'.
583: &mt('Specify a file containing the slot definitions.').
584: '</b></td></tr>'."\n";
585: $result.='<tr bgcolor=#ffffe6><td>'."\n";
586: my $upfile_select=&Apache::loncommon::upfile_select_html();
587: my $ignore=&mt('Ignore First Line');
588: $result.=<<ENDUPFORM;
589: <form method="post" enctype="multipart/form-data" action="/adm/slotrequest" name="slotupload">
590: <input type="hidden" name="command" value="csvuploadmap" />
591: $upfile_select
592: <br /><input type="button" onClick="javascript:checkUpload(this.form);" value="Upload Data" />
593: <label><input type="checkbox" name="noFirstLine" />$ignore</label>
594: </form>
595: ENDUPFORM
596: $result.='</td></tr></table>'."\n";
597: $result.='</td></tr></table>'."\n";
598: $r->print($result);
599: }
600:
601: sub csvuploadmap_header {
1.19 albertel 602: my ($r,$datatoken,$distotal)= @_;
1.14 albertel 603: my $javascript;
604: if ($env{'form.upfile_associate'} eq 'reverse') {
605: $javascript=&csvupload_javascript_reverse_associate();
606: } else {
607: $javascript=&csvupload_javascript_forward_associate();
608: }
609:
610: my $checked=(($env{'form.noFirstLine'})?' checked="checked"':'');
611: my $ignore=&mt('Ignore First Line');
612: $r->print(<<ENDPICK);
613: <form method="post" enctype="multipart/form-data" action="/adm/slotrequest" name="slotupload">
614: <h3>Identify fields</h3>
615: Total number of records found in file: $distotal <hr />
616: Enter as many fields as you can. The system will inform you and bring you back
617: to this page if the data selected is insufficient to create the slots.<hr />
618: <input type="button" value="Reverse Association" onClick="javascript:this.form.associate.value='Reverse Association';submit(this.form);" />
619: <label><input type="checkbox" name="noFirstLine" $checked />$ignore</label>
620: <input type="hidden" name="associate" value="" />
621: <input type="hidden" name="datatoken" value="$datatoken" />
622: <input type="hidden" name="fileupload" value="$env{'form.fileupload'}" />
623: <input type="hidden" name="upfiletype" value="$env{'form.upfiletype'}" />
624: <input type="hidden" name="upfile_associate"
625: value="$env{'form.upfile_associate'}" />
626: <input type="hidden" name="command" value="csvuploadassign" />
627: <hr />
628: <script type="text/javascript" language="Javascript">
629: $javascript
630: </script>
631: ENDPICK
632: return '';
633:
634: }
635:
636: sub csvuploadmap_footer {
637: my ($request,$i,$keyfields) =@_;
638: $request->print(<<ENDPICK);
639: </table>
640: <input type="hidden" name="nfields" value="$i" />
641: <input type="hidden" name="keyfields" value="$keyfields" />
642: <input type="button" onClick="javascript:verify(this.form)" value="Create Slots" /><br />
643: </form>
644: ENDPICK
645: }
646:
647: sub csvupload_javascript_reverse_associate {
648: my $error1=&mt('You need to specify the name, starttime, endtime and a type');
649: return(<<ENDPICK);
650: function verify(vf) {
651: var foundstart=0;
652: var foundend=0;
653: var foundname=0;
654: var foundtype=0;
655: for (i=0;i<=vf.nfields.value;i++) {
656: tw=eval('vf.f'+i+'.selectedIndex');
657: if (i==0 && tw!=0) { foundname=1; }
658: if (i==1 && tw!=0) { foundtype=1; }
659: if (i==2 && tw!=0) { foundstat=1; }
660: if (i==3 && tw!=0) { foundend=1; }
661: }
662: if (foundstart==0 && foundend==0 && foundtype==0 && foundname==0) {
663: alert('$error1');
664: return;
665: }
666: vf.submit();
667: }
668: function flip(vf,tf) {
669: }
670: ENDPICK
671: }
672:
673: sub csvupload_javascript_forward_associate {
674: my $error1=&mt('You need to specify the name, starttime, endtime and a type');
675: return(<<ENDPICK);
676: function verify(vf) {
677: var foundstart=0;
678: var foundend=0;
679: var foundname=0;
680: var foundtype=0;
681: for (i=0;i<=vf.nfields.value;i++) {
682: tw=eval('vf.f'+i+'.selectedIndex');
683: if (tw==1) { foundname=1; }
684: if (tw==2) { foundtype=1; }
685: if (tw==3) { foundstat=1; }
686: if (tw==4) { foundend=1; }
687: }
688: if (foundstart==0 && foundend==0 && foundtype==0 && foundname==0) {
689: alert('$error1');
690: return;
691: }
692: vf.submit();
693: }
694: function flip(vf,tf) {
695: }
696: ENDPICK
697: }
698:
699: sub csv_upload_map {
1.19 albertel 700: my ($r)= @_;
1.14 albertel 701:
702: my $datatoken;
703: if (!$env{'form.datatoken'}) {
704: $datatoken=&Apache::loncommon::upfile_store($r);
705: } else {
706: $datatoken=$env{'form.datatoken'};
707: &Apache::loncommon::load_tmp_file($r);
708: }
709: my @records=&Apache::loncommon::upfile_record_sep();
710: if ($env{'form.noFirstLine'}) { shift(@records); }
1.19 albertel 711: &csvuploadmap_header($r,$datatoken,$#records+1);
1.14 albertel 712: my ($i,$keyfields);
713: if (@records) {
714: my @fields=&csvupload_fields();
715:
716: if ($env{'form.upfile_associate'} eq 'reverse') {
717: &Apache::loncommon::csv_print_samples($r,\@records);
718: $i=&Apache::loncommon::csv_print_select_table($r,\@records,
719: \@fields);
720: foreach (@fields) { $keyfields.=$_->[0].','; }
721: chop($keyfields);
722: } else {
723: unshift(@fields,['none','']);
724: $i=&Apache::loncommon::csv_samples_select_table($r,\@records,
725: \@fields);
726: my %sone=&Apache::loncommon::record_sep($records[0]);
727: $keyfields=join(',',sort(keys(%sone)));
728: }
729: }
730: &csvuploadmap_footer($r,$i,$keyfields);
731:
732: return '';
733: }
734:
735: sub csvupload_fields {
736: return (['name','Slot name'],
737: ['type','Type of slot'],
738: ['starttime','Start Time of slot'],
739: ['endtime','End Time of slot'],
1.15 albertel 740: ['startreserve','Reservation Start Time'],
1.14 albertel 741: ['ip','IP or DNS restriction'],
742: ['proctor','List of proctor ids'],
743: ['description','Slot Description'],
744: ['maxspace','Maximum number of reservations'],
745: ['symb','Resource Restriction'],
746: ['uniqueperiod','Date range of slot exclusion'],
747: ['secret','Secret word proctor uses to validate']);
748: }
749:
750: sub csv_upload_assign {
1.19 albertel 751: my ($r,$mgr)= @_;
1.14 albertel 752: &Apache::loncommon::load_tmp_file($r);
753: my @slotdata = &Apache::loncommon::upfile_record_sep();
754: if ($env{'form.noFirstLine'}) { shift(@slotdata); }
755: my %fields=&Apache::grades::get_fields();
756: $r->print('<h3>Creating Slots</h3>');
757: my $cname=$env{'course.'.$env{'request.course.id'}.'.num'};
758: my $cdom=$env{'course.'.$env{'request.course.id'}.'.domain'};
759: my $countdone=0;
760: foreach my $slot (@slotdata) {
761: my %slot;
762: my %entries=&Apache::loncommon::record_sep($slot);
763: my $domain;
764: my $name=$entries{$fields{'name'}};
765: if ($entries{$fields{'type'}}) {
766: $slot{'type'}=$entries{$fields{'type'}};
767: } else {
768: $slot{'type'}='preassigned';
769: }
770: if ($entries{$fields{'starttime'}}) {
771: $slot{'starttime'}=&UnixDate($entries{$fields{'starttime'}},"%s");
772: }
773: if ($entries{$fields{'endtime'}}) {
1.16 albertel 774: $slot{'endtime'}=&UnixDate($entries{$fields{'endtime'}},"%s");
1.14 albertel 775: }
1.23 albertel 776: if ($entries{$fields{'startreserve'}}) {
777: $slot{'startreserve'}=
778: &UnixDate($entries{$fields{'startreserve'}},"%s");
779: }
1.14 albertel 780: foreach my $key ('ip','proctor','description','maxspace',
781: 'secret','symb') {
782: if ($entries{$fields{$key}}) {
783: $slot{$key}=$entries{$fields{$key}};
784: }
785: }
786: if ($entries{$fields{'uniqueperiod'}}) {
787: my ($start,$end)=split(',',$entries{$fields{'uniqueperiod'}});
788: my @times=(&UnixDate($start,"%s"),
789: &UnixDate($end,"%s"));
790: $slot{'uniqueperiod'}=\@times;
791: }
792:
793: &Apache::lonnet::cput('slots',{$name=>\%slot},$cdom,$cname);
794: $r->print('.');
795: $r->rflush();
796: $countdone++;
797: }
798: $r->print("<br />Created $countdone slots\n");
799: $r->print("<br />\n");
1.19 albertel 800: &show_table($r,$mgr);
1.14 albertel 801: return '';
802: }
803:
1.1 albertel 804: sub handler {
805: my $r=shift;
806:
1.8 albertel 807: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'});
1.1 albertel 808: &start_page($r);
1.12 albertel 809: my $vgr=&Apache::lonnet::allowed('vgr',$env{'request.course.id'});
1.14 albertel 810: my $mgr=&Apache::lonnet::allowed('mgr',$env{'request.course.id'});
1.8 albertel 811: if ($env{'form.command'} eq 'showslots' && $vgr eq 'F') {
1.19 albertel 812: &show_table($r,$mgr);
1.14 albertel 813: } elsif ($env{'form.command'} eq 'uploadstart' && $mgr eq 'F') {
1.19 albertel 814: &upload_start($r);
1.14 albertel 815: } elsif ($env{'form.command'} eq 'csvuploadmap' && $mgr eq 'F') {
1.19 albertel 816: &csv_upload_map($r);
1.14 albertel 817: } elsif ($env{'form.command'} eq 'csvuploadassign' && $mgr eq 'F') {
818: if ($env{'form.associate'} ne 'Reverse Association') {
1.19 albertel 819: &csv_upload_assign($r,$mgr);
1.14 albertel 820: } else {
821: if ( $env{'form.upfile_associate'} ne 'reverse' ) {
822: $env{'form.upfile_associate'} = 'reverse';
823: } else {
824: $env{'form.upfile_associate'} = 'forward';
825: }
1.19 albertel 826: &csv_upload_map($r);
1.14 albertel 827: }
1.19 albertel 828: } elsif ($env{'form.command'} eq 'editslot' && $mgr eq 'F') {
829: &show_slot_edit($r);
1.8 albertel 830: } else {
1.19 albertel 831: my $symb=&Apache::lonnet::unescape($env{'form.symb'});
832: my (undef,undef,$res)=&Apache::lonnet::decode_symb($symb);
833: if ($res !~ /\.task$/) {
834: &fail($r,'not_valid');
835: return OK;
836: }
837: $env{'request.symb'}=$symb;
1.11 albertel 838: my ($status) = &Apache::lonhomework::check_task_access('0');
839: if ($status eq 'CAN_ANSWER' ||
840: $status eq 'NEEDS_CHECKIN' ||
841: $status eq 'WAITING_FOR_GRADE') {
842: &fail($r,'not_allowed');
843: return OK;
844: }
845: if ($env{'form.requestattempt'}) {
846: &show_choices($r,$symb);
847: } elsif ($env{'form.command'} eq 'release') {
848: &release_slot($r,$symb);
849: } elsif ($env{'form.command'} eq 'get') {
850: &get_slot($r,$symb);
851: } elsif ($env{'form.command'} eq 'change') {
852: &release_slot($r,$symb,$env{'form.releaseslot'},1);
853: &get_slot($r,$symb);
854: } else {
855: $r->print("<p>Unknown command: ".$env{'form.command'}."</p>");
856: }
1.2 albertel 857: }
1.1 albertel 858: &end_page($r);
859: return OK;
860: }
1.3 albertel 861:
862: 1;
863: __END__
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>