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