Annotation of loncom/interface/londropadd.pm, revision 1.7
1.1 www 1: # The LearningOnline Network with CAPA
2: # Handler to drop and add students in courses
3: #
4: # (Handler to set parameters for assessments
5: #
6: # (Handler to resolve ambiguous file locations
7: #
8: # (TeX Content Handler
9: #
10: # 05/29/00,05/30,10/11 Gerd Kortemeyer)
11: #
12: # 10/11,10/12,10/16 Gerd Kortemeyer)
13: #
14: # 11/20,11/21,11/22,11/23,11/24,11/25,11/27,11/28,
15: # 12/08,12/12 Gerd Kortemeyer)
16: #
1.7 ! www 17: # 12/26,12/27,12/28,
! 18: # 01/01/01 Gerd Kortemeyer
1.1 www 19:
20: package Apache::londropadd;
21:
22: use strict;
23: use Apache::lonnet;
24: use Apache::Constants qw(:common :http REDIRECT);
25:
26:
27: # ================================================================ Main Handler
28:
29: sub handler {
30: my $r=shift;
31:
32: if ($r->header_only) {
33: $r->content_type('text/html');
34: $r->send_http_header;
35: return OK;
36: }
37:
38: # ----------------------------------------------------- Needs to be in a course
39:
40: if (($ENV{'request.course.fn'}) &&
41: (&Apache::lonnet::allowed('cst',$ENV{'request.course.id'}))) {
42:
43: # ------------------------------------------------------------------ Start page
44: $r->content_type('text/html');
45: $r->send_http_header;
46: $r->print(<<ENDHEAD);
47: <html>
48: <head>
49: <title>LON-CAPA Student Drop/Add</title>
50: </head>
51: <body bgcolor="#FFFFFF">
52: <img align=right src=/adm/lonIcons/lonlogos.gif>
53: <h1>Drop/Add Students</h1>
54: <form method="post" enctype="multipart/form-data"
55: action="/adm/dropadd" name="studentform">
56: <h2>Course: $ENV{'course.'.$ENV{'request.course.id'}.'.description'}</h2>
57: ENDHEAD
1.2 www 58: # --------------------------------------------------- Phase one, initial screen
59: unless ($ENV{'form.phase'}) {
60: $r->print(<<ENDUPFORM);
61: <input type=hidden name=phase value=two>
62: <hr>
63: <h3>Upload a courselist</h3>
64: <input type=file name=upfile size=50>
65: <br>Type: <select name=upfiletype>
66: <option value=csv>CSV (comma separated values, spreadsheet)</option>
67: <option value=space>Space separated</option>
68: <option value=tab>Tabulator separated</option>
69: <option value=xml>HTML/XML</option>
70: </select>
71: <p><input type=submit name=fileupload value="Upload Courselist">
72: <hr>
73: <h3>Enroll a single student</h3>
74: <p><input type=submit name=enroll value="Enroll Student">
75: <hr>
76: <h3>Drop a student</h3>
77: <p><input type=submit name=drop value="Drop Student">
78: ENDUPFORM
79: }
80: # ------------------------------------------------------------------- Phase two
81: if ($ENV{'form.phase'} eq 'two') {
82: if ($ENV{'form.fileupload'}) {
1.4 www 83: my $datatoken=$ENV{'user.name'}.'_'.$ENV{'user.domain'}.
84: '_enroll_'.$ENV{'request.course.id'}.'_'.time.'_'.$$;
85: {
86: my $fh=Apache::File->new('>'.$r->dir_config('lonDaemons').
87: '/tmp/'.$datatoken.'.tmp');
88: print $fh $ENV{'form.upfile'};
89: }
1.2 www 90: my $separator='';
91: my $remove='';
92: if ($ENV{'form.upfiletype'} eq 'csv') {
93: $separator='\"\,\s*\"';
94: $remove='"';
95: } elsif ($ENV{'form.upfiletype'} eq 'space') {
96: $separator='\s+';
97: } elsif ($ENV{'form.upfiletype'} eq 'tab') {
98: $separator='\t+';
99: } elsif ($ENV{'form.upfiletype'} eq 'xml') {
100: }
101: my @lines=split(/\n/,$ENV{'form.upfile'});
1.4 www 102: my $total=$#lines;
1.3 www 103: $ENV{'SERVER_NAME'}=~/(\w+\.\w+)$/;
104: my $krbdefdom=$1;
105: $krbdefdom=~tr/a-z/A-Z/;
1.4 www 106: my $today=time;
107: my $halfyear=$today+15552000;
108: my $defdom=$r->dir_config('lonDefDomain');
1.2 www 109: $r->print(<<ENDPICK);
110: <input type=hidden name=phase value=three>
111: <input type=hidden name=datatoken value="$datatoken">
112: <input type=hidden name=upfiletype value=$ENV{'form.upfiletype'}>
113: <hr>
114: <h3>Identify fields</h3>
1.4 www 115: Total number of records found in file: $total
1.3 www 116: <script>
117: function verify(vf) {
118: var founduname=0;
119: var foundpwd=0;
120: var foundname=0;
121: var foundid=0;
122: var foundsec=0;
123: var foundatype=0;
124: var tw;
125: var message='';
126: for (i=0;i<=vf.nfields.value;i++) {
127: tw=eval('vf.f'+i+'.selectedIndex');
128: if (tw==1) { founduname=1; }
129: if ((tw>=2) && (tw<=6)) { foundname=1; }
130: if (tw==7) { foundid=1; }
131: if (tw==8) { foundsec=1; }
132: if (tw==9) { foundpwd=1; }
133: }
134: if (founduname==0) {
135: alert('You need to specify at least the username field');
136: return;
137: }
138: if (vf.login[0].checked) {
139: foundatype=1;
140: if (vf.krbdom.value=='') {
141: alert('You need to specify the Kerberos domain');
142: return;
143: }
144: }
145: if (vf.login[1].checked) {
146: foundatype=1;
147: if ((vf.intpwd.value=='') && (foundpwd==0)) {
148: alert('You need to specify the initial password');
149: return;
150: }
151: }
152: if (foundatype==0) {
153: alert('You need to set the login type');
154: return;
155: }
156: if (foundname==0) { message='No name fields specified. '; }
157: if (foundid==0) { message+='No ID or student number field specified. '; }
158: if (foundsec==0) { message+='No section or group field specified. '; }
1.4 www 159: if (vf.startdate.value=='') {
160: message+='No starting date set. ';
1.3 www 161: }
1.4 www 162: if (vf.enddate.value=='') {
163: message+='No ending date set. ';
164: }
165: if ((vf.enddate.value!='') && (vf.startdate.value!='')) {
166: if (vf.enddate.value<vf.startdate.value) {
167: alert('Ending date is before starting date');
168: return;
169: }
170: }
171: if (message!='') {
172: message+='Continue enrollment?';
173: if (confirm(message)) {
174: pclose();
175: vf.submit();
176: }
177: } else {
178: pclose();
179: vf.submit();
180: }
1.3 www 181: }
182:
183: function flip(vf,tf) {
184: var nw=eval('vf.f'+tf+'.selectedIndex');
185: var i;
186: for (i=0;i<=vf.nfields.value;i++) {
187: if ((i!=tf) && (eval('vf.f'+i+'.selectedIndex')==nw)) {
188: eval('vf.f'+i+'.selectedIndex=0;')
189: }
190: }
191: if (nw==2) {
192: for (i=0;i<=vf.nfields.value;i++) {
193: if ((eval('vf.f'+i+'.selectedIndex')>=3) &&
194: (eval('vf.f'+i+'.selectedIndex')<=6)) {
195: eval('vf.f'+i+'.selectedIndex=0;')
196: }
197: }
198: }
199: if ((nw>=3) && (nw<=6)) {
200: for (i=0;i<=vf.nfields.value;i++) {
201: if (eval('vf.f'+i+'.selectedIndex')==2) {
202: eval('vf.f'+i+'.selectedIndex=0;')
203: }
204: }
205: }
206: if (nw==9) {
207: vf.login[1].checked=true;
208: vf.intpwd.value='';
209: vf.krbdom.value='';
210: }
211:
212: }
213:
214: function clearpwd(vf) {
215: var i;
216: for (i=0;i<=vf.nfields.value;i++) {
217: if (eval('vf.f'+i+'.selectedIndex')==9) {
218: eval('vf.f'+i+'.selectedIndex=0;')
219: }
220: }
221: }
222:
223: function setkrb(vf) {
224: if (vf.krbdom.value!='') {
225: clearpwd(vf);
226: vf.login[0].checked=true;
227: vf.krbdom.value=vf.krbdom.value.toUpperCase();
228: vf.intpwd.value='';
229: }
230: }
231:
232: function setint(vf) {
233: if (vf.intpwd.value!='') {
234: clearpwd(vf);
235: vf.login[1].checked=true;
236: vf.krbdom.value='';
237: }
238: }
239:
240: function clickkrb(vf) {
241: vf.krbdom.value='$krbdefdom';
242: clearpwd(vf);
243: vf.intpwd.value='';
244: }
245:
246: function clickint(vf) {
247: vf.krbdom.value='';
248: }
249:
1.4 www 250: function pclose() {
251: parmwin=window.open("/adm/rat/empty.html","LONCAPAparms",
252: "height=350,width=350,scrollbars=no,menubar=no");
253: parmwin.close();
254: }
255:
256: function pjump(type,dis,value,marker,ret,call) {
257: parmwin=window.open("/adm/rat/parameter.html?type="+escape(type)
258: +"&value="+escape(value)+"&marker="+escape(marker)
259: +"&return="+escape(ret)
260: +"&call="+escape(call)+"&name="+escape(dis),"LONCAPAparms",
261: "height=350,width=350,scrollbars=no,menubar=no");
262:
263: }
264:
265: function dateset() {
266: if (document.studentform.pres_marker.value=='end') {
267: document.studentform.enddate.value=
268: document.studentform.pres_value.value;
269: }
270: if (document.studentform.pres_marker.value=='start') {
271: document.studentform.startdate.value=
272: document.studentform.pres_value.value;
273: }
274: pclose();
275: }
1.3 www 276:
277: </script>
1.2 www 278: <table border=2><tr><th>Field</th><th>Samples</th></tr>
279: ENDPICK
280: my @sone; my @stwo; my @sthree; my $nfields=0;
281: if ($#lines>=0) {
282: $lines[0]=~s/^$remove//;
283: $lines[0]=~s/$remove$//;
284: @sone=split(/$separator/,$lines[0]);
285: $nfields=$#sone;
286: if ($#lines>=1) {
287: $lines[1]=~s/^$remove//;
288: $lines[1]=~s/$remove$//;
289: @stwo=split(/$separator/,$lines[1]);
290: $nfields=$#stwo;
291: }
292: if ($#lines>=2) {
293: $lines[2]=~s/^$remove//;
294: $lines[2]=~s/$remove$//;
295: @sthree=split(/$separator/,$lines[2]);
296: $nfields=$#sthree;
297: }
298: my $i;
299: for ($i=0;$i<=$nfields;$i++) {
1.3 www 300: $r->print('<tr><td><select name=f'.$i.
301: ' onChange="flip(this.form,'.$i.');">');
1.2 www 302: map {
303: my ($value,$display)=split(/\:/,$_);
304: $r->print('<option value='.$value.'>'.$display.
305: '</option>');
306: } ('none: ','username:Username',
307: 'names:Last Name, First Names',
308: 'fname:First Name','mname:Middle Names/Initials',
309: 'lname:Last Name','gen:Generation',
1.3 www 310: 'id:ID/Student Number','sec:Group/Section',
311: 'ipwd:Initial Password');
1.2 www 312: $r->print('</select></td><td>');
313: if (defined($sone[$i])) {
314: $r->print($sone[$i]."</br>\n");
315: }
316: if (defined($stwo[$i])) {
317: $r->print($stwo[$i]."</br>\n");
318: }
319: if (defined($sthree[$i])) {
320: $r->print($sthree[$i]."</br>\n");
321: }
322: $r->print('</td></tr>');
323: }
324: }
1.3 www 325: $r->print(<<ENDPICK);
326: </table>
327: <input type=hidden name=nfields value=$nfields>
328: <h3>Login Type</h3>
329: <input type=radio name=login value=krb onClick="clickkrb(this.form);">
330: Kerberos authenticated with domain
331: <input type=text size=10 name=krbdom onChange="setkrb(this.form);"><p>
332: <input type=radio name=login value=int onClick="clickint(this.form);">
333: Internally authenticated (with initial password
1.5 www 334: <input type=text size=10 name=intpwd onChange="setint(this.form);">)
335: <h3>LON-CAPA Domain for Students</h3>
1.4 www 336: LON-CAPA domain: <input type=text size=10 value=$defdom name=lcdomain><p>
1.5 www 337: <h3>Starting and Ending Dates</h3>
1.4 www 338: <input type="hidden" value='' name="pres_value">
339: <input type="hidden" value='' name="pres_type">
340: <input type="hidden" value='' name="pres_marker">
341: <input type="hidden" value='$today' name=startdate>
342: <input type="hidden" value='$halfyear' name=enddate>
343: <a
344: href="javascript:pjump('date_start','Enrollment Starting Date',document.studentform.startdate.value,'start','studentform.pres','dateset');"
345: >Set Starting Date</a><p>
346:
347: <a
348: href="javascript:pjump('date_end','Enrollment Ending Date',document.studentform.enddate.value,'end','studentform.pres','dateset');"
349: >Set Ending Date</a><p>
1.5 www 350: <h3>Full Update</h3>
351: <input type=checkbox name=fullup value=yes> Full update
352: (also dropping students)<p>
1.6 www 353: <input type=button onClick="verify(this.form)" value="Update Courselist"><br>
354: Note: for large courses, this operation might be time consuming.
1.3 www 355: ENDPICK
1.2 www 356: } elsif ($ENV{'form.enroll'}) {
357: } elsif ($ENV{'form.drop'}) {
358: }
359: }
360: # ----------------------------------------------------------------- Phase three
361: if ($ENV{'form.phase'} eq 'three') {
362: if ($ENV{'form.datatoken'}) {
363: my $separator='';
364: my $remove='';
365: if ($ENV{'form.upfiletype'} eq 'csv') {
366: $separator='\"\,\s*\"';
367: $remove='"';
368: } elsif ($ENV{'form.upfiletype'} eq 'space') {
369: $separator='\s+';
370: } elsif ($ENV{'form.upfiletype'} eq 'tab') {
371: $separator='\t+';
372: } elsif ($ENV{'form.upfiletype'} eq 'xml') {
373: }
1.4 www 374: my %fields=();
375: for (my $i=0;$i<=$ENV{'form.nfields'};$i++) {
376: $fields{$ENV{'form.f'.$i}}=$i;
377: }
378: my $startdate=$ENV{'form.startdate'};
379: my $enddate=$ENV{'form.enddate'};
380: if ($startdate=~/\D/) { $startdate=''; }
381: if ($enddate=~/\D/) { $enddate=''; }
1.5 www 382: my $domain=$ENV{'form.lcdomain'};
383: my $amode='';
384: my $genpwd='';
385: if ($ENV{'form.login'} eq 'krb') {
386: $amode='krb4';
387: $genpwd=$ENV{'form.krbdom'};
388: } elsif ($ENV{'form.login'} eq 'int') {
389: $amode='internal';
390: if ((defined($ENV{'form.intpwd'})) && ($ENV{'form.intpwd'})) {
391: $genpwd=$ENV{'form.intpwd'};
392: }
393: }
394: unless (($domain=~/\W/) || ($amode eq '')) {
395: $r->print('<h3>Enrolling Students</h3>');
1.7 ! www 396: my $count=0;
! 397: my $flushc=0;
! 398: my %student=();
1.5 www 399: # ----------------------------------------------------------- Get new classlist
400: my @studentdata=();
1.4 www 401: {
402: my $fh;
403: if ($fh=Apache::File->new($r->dir_config('lonDaemons').
404: '/tmp/'.$ENV{'form.datatoken'}.'.tmp')) {
405: @studentdata=<$fh>;
406: }
407: }
1.5 www 408: # --------------------------------------------------------- Enroll new students
1.2 www 409: map {
1.4 www 410: my $line=$_;
411: chomp($line);
412: $line=~s/^$remove//;
413: $line=~s/$remove$//;
414: my @entries=split(/$separator/,$line);
415: unless (($entries[$fields{'username'}] eq '') ||
416: (!defined($entries[$fields{'username'}]))) {
417: my $fname=''; my $mname=''; my $lname=''; my $gen='';
418: if (defined($fields{'names'})) {
419: ($lname,$fname,$mname)=
420: ($entries[$fields{'names'}]=~/([^\,]+)\,\s*(\w+)\s*(.*)$/);
421: } else {
422: if (defined($fields{'fname'})) {
423: $fname=$entries[$fields{'fname'}];
424: }
425: if (defined($fields{'mname'})) {
426: $mname=$entries[$fields{'mname'}];
427: }
428: if (defined($fields{'lname'})) {
429: $lname=$entries[$fields{'lname'}];
430: }
431: if (defined($fields{'gen'})) {
432: $gen=$entries[$fields{'gen'}];
433: }
434: }
435: if ($entries[$fields{'username'}]=~/\W/) {
436: $r->print('<p><b>Unacceptable username: '.
437: $entries[$fields{'username'}].' for user '.
438: $fname.' '.$mname.' '.$lname.' '.$gen.'</b><p>');
1.5 www 439: } else {
440: my $sec='';
441: my $username=$entries[$fields{'username'}];
442: if (defined($fields{'sec'})) {
443: if (defined($entries[$fields{'sec'}])) {
444: $sec=$entries[$fields{'sec'}];
445: }
446: }
447: my $id='';
448: if (defined($fields{'id'})) {
449: if (defined($entries[$fields{'id'}])) {
450: $id=$entries[$fields{'id'}];
451: }
452: $id=~tr/A-Z/a-z/;
453: }
454: my $password='';
455: if ($genpwd) {
456: $password=$genpwd;
457: } else {
458: if (defined($fields{'ipwd'})) {
459: if ($entries[$fields{'ipwd'}]) {
460: $password=$entries[$fields{'ipwd'}];
461: }
462: }
463: }
464: if ($password) {
465: my $reply=&Apache::lonnet::modifystudent(
466: $domain,$username,$id,$amode,$password,
467: $fname,$mname,$lname,$gen,$sec,$enddate,$startdate);
468: unless ($reply eq 'ok') {
469: $r->print(
470: "<p><b>Error enrolling $username: $reply</b><p>");
1.6 www 471: } else {
1.7 ! www 472: $count++; $flushc++;
! 473: $student{$username}=1;
1.6 www 474: $r->print('. ');
1.7 ! www 475: if ($flushc>15) {
! 476: $r->rflush;
! 477: $flushc=0;
! 478: }
1.6 www 479: }
1.5 www 480: } else {
481: $r->print(
482: "<p><b>No password for $username</b><p>");
483: }
1.4 www 484: }
485: }
486: } @studentdata;
1.7 ! www 487: $r->print('<p>Processed Students: '.$count);
1.5 www 488: # --------------------------------------------------------------- Drop students
489: if ($ENV{'form.fullup'} eq 'yes') {
490: $r->print('<h3>Dropping Students</h3>');
491: # ------------------------------------------------------- Get current classlist
492: my $cid=$ENV{'request.course.id'};
493: my $classlst=&Apache::lonnet::reply
494: ('dump:'.$ENV{'course.'.$cid.'.domain'}.':'.
495: $ENV{'course.'.$cid.'.num'}.':classlist',
496: $ENV{'course.'.$cid.'.home'});
497: my %currentlist=();
498: my $now=time;
499: unless ($classlst=~/^error\:/) {
1.7 ! www 500: map {
! 501: my ($name,$value)=split(/\=/,$_);
! 502: my ($end,$start)=split(/\_/,
! 503: &Apache::lonnet::unescape($value));
! 504: my $active=1;
! 505: if (($end) && ($now>$end)) { $active=0; }
! 506: if ($active) {
! 507: $currentlist{&Apache::lonnet::unescape($name)}=1;
! 508: }
! 509: } split(/\&/,$classlst);
! 510:
1.5 www 511: } else {
512: $r->print(
513: '<font color=red><h3>Could not access classlist: '.$classlst.
514: '</h3></font>');
515: }
516: }
517: # ------------------------------------------------------------------------ Done
1.2 www 518: }
1.5 www 519: }
1.2 www 520: }
521: # ------------------------------------------------------------------------- End
1.1 www 522: $r->print('</form></body></html>');
523: } else {
524: # ----------------------------- Not in a course, or not allowed to modify parms
525: $ENV{'user.error.msg'}=
526: "/adm/dropadd:cst:0:0:Cannot drop or add students";
527: return HTTP_NOT_ACCEPTABLE;
528: }
529: return OK;
530: }
531:
532: 1;
533: __END__
534:
535:
536:
537:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>