File:  [LON-CAPA] / loncom / interface / Attic / londropadd.pm
Revision 1.16: download - view: text, annotated - select for diffs
Tue Sep 25 18:12:43 2001 UTC (22 years, 9 months ago) by www
Branches: MAIN
CVS tags: stable_2001_fall, HEAD
Dropping students who are not in sections

    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: # YEAR=2000
   11: # 05/29/00,05/30,10/11 Gerd Kortemeyer)
   12: #
   13: # 10/11,10/12,10/16 Gerd Kortemeyer)
   14: #
   15: # 11/20,11/21,11/22,11/23,11/24,11/25,11/27,11/28,
   16: # 12/08,12/12 Gerd Kortemeyer)
   17: #
   18: # 12/26,12/27,12/28,
   19: # YEAR=2001
   20: # 01/01/01,01/15,02/10,02/13,02/14,02/22 Gerd Kortemeyer
   21: # 8/6 Scott Harrison
   22: # Guy Albertelli
   23: # 9/25 Gerd Kortemeyer
   24: 
   25: package Apache::londropadd;
   26: 
   27: use strict;
   28: use Apache::lonnet;
   29: use Apache::Constants qw(:common :http REDIRECT);
   30: 
   31: # ================================================================ Print header
   32: 
   33: sub header {
   34:     my $r=shift;
   35:     $r->print(<<ENDHEAD);
   36: <html>
   37: <head>
   38: <title>LON-CAPA Student Drop/Add</title>
   39: </head>
   40: <body bgcolor="#FFFFFF">
   41: <img align=right src=/adm/lonIcons/lonlogos.gif>
   42: <h1>Drop/Add Students</h1>
   43: <form method="post" enctype="multipart/form-data"
   44: action="/adm/dropadd" name="studentform">
   45: <h2>Course: $ENV{'course.'.$ENV{'request.course.id'}.'.description'}</h2>
   46: ENDHEAD
   47: }
   48: 
   49: # ========================================================= Store uploaded file
   50: # needs $ENV{'form.upfile'}
   51: # return $datatoken to be put into hidden field
   52: 
   53: sub upfile_store {
   54:     my $r=shift;
   55:     $ENV{'form.upfile'}=~s/\r/\n/gs;
   56:     $ENV{'form.upfile'}=~s/\f/\n/gs;
   57:     $ENV{'form.upfile'}=~s/\n+/\n/gs;
   58:     $ENV{'form.upfile'}=~s/\n+$//gs;
   59: 	      
   60:     my $datatoken=$ENV{'user.name'}.'_'.$ENV{'user.domain'}.
   61: 		  '_enroll_'.$ENV{'request.course.id'}.'_'.time.'_'.$$;
   62:     {
   63:        my $fh=Apache::File->new('>'.$r->dir_config('lonDaemons').
   64:                                    '/tmp/'.$datatoken.'.tmp');
   65:        print $fh $ENV{'form.upfile'};
   66:     }
   67:     return $datatoken;
   68: }
   69: 
   70: # ================================================= Load uploaded file from tmp
   71: # needs $ENV{'form.datatoken'}
   72: # sets $ENV{'form.upfile'}
   73: 
   74: sub load_tmp_file {
   75:     my $r=shift;
   76:     my @studentdata=();
   77:     {
   78:       my $fh;
   79:       if ($fh=Apache::File->new($r->dir_config('lonDaemons').
   80: 	  '/tmp/'.$ENV{'form.datatoken'}.'.tmp')) {
   81: 	     @studentdata=<$fh>;
   82:       }
   83:     }
   84:     $ENV{'form.upfile'}=join('',@studentdata);
   85: }
   86: 
   87: # ========================================= Separate uploaded file into records
   88: # returns array of records
   89: 
   90: sub upfile_record_sep {
   91:     if ($ENV{'form.upfiletype'} eq 'xml') {
   92:     } else {
   93:        return split(/\n/,$ENV{'form.upfile'});
   94:     }
   95: }
   96: 
   97: # =============================================== Separate a record into fields
   98: 
   99: sub record_sep {
  100:     my $record=shift;
  101:     my %components=();
  102:     if ($ENV{'form.upfiletype'} eq 'xml') {
  103:     } elsif ($ENV{'form.upfiletype'} eq 'space') {
  104:         my $i=0;
  105:         map {
  106:             my $field=$_;
  107:             $field=~s/^(\"|\')//;
  108:             $field=~s/(\"|\')$//;
  109:             $components{$i}=$field;
  110:             $i++;
  111:         } split(/\s+/,$record);
  112:     } elsif ($ENV{'form.upfiletype'} eq 'tab') {
  113:         my $i=0;
  114:         map {
  115:             my $field=$_;
  116:             $field=~s/^(\"|\')//;
  117:             $field=~s/(\"|\')$//;
  118:             $components{$i}=$field;
  119:             $i++;
  120:         } split(/\t+/,$record);        
  121:     } else {
  122:         my @allfields=split(/\,/,$record);
  123:         my $i=0;
  124:         my $j;
  125:         for ($j=0;$j<=$#allfields;$j++) {
  126:             my $field=$allfields[$j];
  127:             if ($field=~/^\s*(\"|\')/) {
  128: 		my $delimiter=$1;
  129:                 while (($field!~/$delimiter$/) && ($j<$#allfields)) {
  130: 		    $j++;
  131: 		    $field.=','.$allfields[$j];
  132: 		}
  133:                 $field=~s/^\s*$delimiter//;
  134:                 $field=~s/$delimiter\s*$//;
  135:             }
  136:             $components{$i}=$field;
  137: 	    $i++;
  138:         }
  139:     }
  140:     return %components;
  141: }
  142: 
  143: # =========== Drop student from all sections of a course, except optional $csec
  144: 
  145: sub dropstudent {
  146:      my ($udom,$unam,$courseid,$csec)=@_;
  147:      $courseid=~s/\_/\//g;
  148:      $courseid=~s/^(\w)/\/$1/;
  149:      map {
  150:         my ($key,$value)=split(/\=/,$_);
  151:         $key=&Apache::lonnet::unescape($key);
  152:         if ($key=~/^$courseid(?:\/)*(\w+)*\_st$/) {
  153:           my $section=$1;
  154:           if ($key eq $courseid.'_st') { $section=''; }
  155:           if (((!$section) && (!$csec)) || ($section ne $csec)) {
  156: 	    my ($dummy,$end,$start)=split(/\_/,
  157:                                     &Apache::lonnet::unescape($value));
  158:             my $now=time;
  159:             my $notactive=0;
  160:             if ($start) {
  161: 		if ($now<$start) { $notactive=1; }
  162:             }
  163:             if ($end) {
  164:                 if ($now>$end) { $notactive=1; }
  165:             } 
  166:             unless ($notactive) {
  167:                 my $reply=&Apache::lonnet::modifystudent(
  168:                                    $udom,$unam,'','','',
  169: 			           '','','','',$section,time);
  170:             }
  171: 	  }
  172:         }
  173:     } split(/\&/,&Apache::lonnet::reply('dump:'.$udom.':'.$unam.':roles',
  174:                                  &Apache::lonnet::homeserver($unam,$udom)));
  175: }
  176: 
  177: # ============================================================== Menu Phase One
  178: 
  179: sub menu_phase_one {
  180:     my $r=shift;
  181:     $r->print(<<ENDUPFORM);
  182: <input type=hidden name=phase value=two>
  183: <hr>
  184: <h3>Upload a courselist</h3>
  185: <input type=file name=upfile size=50>
  186: <br>Type: <select name=upfiletype>
  187: <option value=csv>CSV (comma separated values, spreadsheet)</option>
  188: <option value=space>Space separated</option>
  189: <option value=tab>Tabulator separated</option>
  190: <option value=xml>HTML/XML</option>
  191: </select>
  192: <p><input type=submit name=fileupload value="Upload Courselist">
  193: <hr>
  194: <h3>Enroll a single student</h3>
  195: <p><input type=submit name=enroll value="Enroll Student">
  196: <hr>
  197: <h3>Drop students</h3>
  198: <p><input type=submit name=drop value="Selection List">
  199: ENDUPFORM
  200: }
  201: 
  202: # ======================================================= Menu Phase Two Upload
  203: 
  204: sub menu_phase_two_upload {
  205:     my $r=shift;
  206: 
  207:     my $datatoken=&upfile_store($r);
  208: 
  209:     my @records=&upfile_record_sep();
  210:     my $total=$#records;
  211:     my $distotal=$total+1;
  212:     
  213:     $ENV{'SERVER_NAME'}=~/(\w+\.\w+)$/;
  214:     my $krbdefdom=$1;
  215:     $krbdefdom=~tr/a-z/A-Z/;
  216: 
  217:     my $today=time;
  218:     my $halfyear=$today+15552000;
  219: 
  220:     my $defdom=$r->dir_config('lonDefDomain');
  221: 
  222:     $r->print(<<ENDPICK);
  223: <input type=hidden name=phase value=three>
  224: <input type=hidden name=datatoken value="$datatoken">
  225: <input type=hidden name=upfiletype value=$ENV{'form.upfiletype'}>
  226: <hr>
  227: <h3>Identify fields</h3>
  228: Total number of records found in file: $distotal
  229: <script>
  230: function verify(vf) {
  231:     var founduname=0;
  232:     var foundpwd=0;
  233:     var foundname=0;
  234:     var foundid=0;
  235:     var foundsec=0;
  236:     var foundatype=0;
  237:     var tw;
  238:     var message='';
  239:     for (i=0;i<=vf.nfields.value;i++) {
  240:         tw=eval('vf.f'+i+'.selectedIndex');
  241:         if (tw==1) { founduname=1; }
  242:         if ((tw>=2) && (tw<=6)) { foundname=1; }
  243:         if (tw==7) { foundid=1; }
  244:         if (tw==8) { foundsec=1; } 
  245:         if (tw==9) { foundpwd=1; }
  246:     }
  247:     if (founduname==0) {
  248: 	alert('You need to specify at least the username field');
  249:         return;
  250:     }
  251:     if (vf.login[0].checked) {
  252: 	foundatype=1;
  253:         if (vf.krbdom.value=='') {
  254: 	    alert('You need to specify the Kerberos domain');
  255:             return;
  256:         }
  257:     }
  258:     if (vf.login[1].checked) {
  259: 	foundatype=1;
  260:         if ((vf.intpwd.value=='') && (foundpwd==0)) {
  261: 	    alert('You need to specify the initial password');
  262:             return;
  263:         }
  264:     }
  265:     if (vf.login[2].checked) {
  266: 	foundatype=1;
  267: 	//An argument is not required
  268:     }
  269:     if (foundatype==0) {
  270: 	alert('You need to set the login type');
  271:         return;
  272:     }
  273:     if (foundname==0) { message='No name fields specified. '; }
  274:     if (foundid==0) { message+='No ID or student number field specified. '; }
  275:     if (foundsec==0) { message+='No section or group field specified. '; }
  276:     if (vf.startdate.value=='') {
  277: 	message+='No starting date set. ';
  278:     }
  279:     if (vf.enddate.value=='') {
  280:         message+='No ending date set. ';
  281:     }
  282:     if ((vf.enddate.value!='') && (vf.startdate.value!='')) {
  283:        if (Math.round(vf.enddate.value)<Math.round(vf.startdate.value)) {
  284:           alert('Ending date is before starting date');
  285:           return;
  286:        }
  287:     }
  288:     if (message!='') {
  289:        message+='Continue enrollment?';
  290:        if (confirm(message)) {
  291: 	  pclose();
  292: 	  vf.submit();
  293:        }
  294:     } else {
  295:       pclose();
  296:       vf.submit();
  297:     }   
  298: }
  299: 
  300: function flip(vf,tf) {
  301:    var nw=eval('vf.f'+tf+'.selectedIndex');
  302:    var i;
  303:    for (i=0;i<=vf.nfields.value;i++) {
  304:       if ((i!=tf) && (eval('vf.f'+i+'.selectedIndex')==nw)) {
  305:           eval('vf.f'+i+'.selectedIndex=0;')      
  306:       } 
  307:    }
  308:    if (nw==2) {
  309:       for (i=0;i<=vf.nfields.value;i++) {
  310:          if ((eval('vf.f'+i+'.selectedIndex')>=3) &&
  311:              (eval('vf.f'+i+'.selectedIndex')<=6)) {
  312:              eval('vf.f'+i+'.selectedIndex=0;')
  313:          }
  314:       }      
  315:    }
  316:    if ((nw>=3) && (nw<=6)) {
  317:       for (i=0;i<=vf.nfields.value;i++) {
  318:          if (eval('vf.f'+i+'.selectedIndex')==2) {
  319:              eval('vf.f'+i+'.selectedIndex=0;')
  320:          }
  321:       }      
  322:    }
  323:    if (nw==9) {
  324:        vf.login[1].checked=true;
  325:        vf.intpwd.value='';
  326:        vf.krbdom.value='';
  327:        vf.locarg.value='';
  328:    }
  329: 
  330: }
  331: 
  332: function clearpwd(vf) {
  333:     var i;
  334:     for (i=0;i<=vf.nfields.value;i++) {
  335:         if (eval('vf.f'+i+'.selectedIndex')==9) {
  336:             eval('vf.f'+i+'.selectedIndex=0;')
  337:         }
  338:     }      
  339: }
  340: 
  341: function setkrb(vf) {
  342:     if (vf.krbdom.value!='') {
  343:        clearpwd(vf);
  344:        vf.login[0].checked=true;
  345:        vf.krbdom.value=vf.krbdom.value.toUpperCase();
  346:        vf.intpwd.value='';
  347:    }
  348: }
  349: 
  350: function setint(vf) {
  351:     if (vf.intpwd.value!='') {
  352:        clearpwd(vf);
  353:        vf.login[1].checked=true;
  354:        vf.krbdom.value='';
  355:    }
  356: }
  357: 
  358: function clickkrb(vf) {
  359:     vf.krbdom.value='$krbdefdom';
  360:     clearpwd(vf);
  361:     vf.intpwd.value='';
  362: }
  363: 
  364: function clickint(vf) {
  365:     vf.krbdom.value='';
  366: }
  367: 
  368:     function pclose() {
  369:         parmwin=window.open("/adm/rat/empty.html","LONCAPAparms",
  370:                  "height=350,width=350,scrollbars=no,menubar=no");
  371:         parmwin.close();
  372:     }
  373: 
  374:     function pjump(type,dis,value,marker,ret,call) {
  375:         parmwin=window.open("/adm/rat/parameter.html?type="+escape(type)
  376:                  +"&value="+escape(value)+"&marker="+escape(marker)
  377:                  +"&return="+escape(ret)
  378:                  +"&call="+escape(call)+"&name="+escape(dis),"LONCAPAparms",
  379:                  "height=350,width=350,scrollbars=no,menubar=no");
  380: 
  381:     }
  382: 
  383:     function dateset() {
  384:         if (document.studentform.pres_marker.value=='end') {
  385:            document.studentform.enddate.value=
  386: 	       document.studentform.pres_value.value;
  387:         }
  388:         if (document.studentform.pres_marker.value=='start') {
  389:            document.studentform.startdate.value=
  390: 	       document.studentform.pres_value.value;
  391:         }
  392:         pclose();
  393:     }
  394: 
  395: </script>
  396: <table border=2><tr><th>Field</th><th>Samples</th></tr>
  397: ENDPICK
  398:              my %sone; my %stwo; my %sthree;
  399:              my $i=0;
  400: 
  401:              if ($total>=0) {
  402:                 %sone=&record_sep($records[0]);
  403:                 if ($total>=1) {
  404:                    %stwo=&record_sep($records[1]);
  405:                    
  406: 	        }
  407:                 if ($total>=2) {
  408:                    %sthree=&record_sep($records[2]);
  409: 	        }
  410:                 map {
  411:                    $r->print('<tr><td><select name=f'.$i.
  412:                        ' onChange="flip(this.form,'.$i.');">');
  413:                    map {
  414:                       my ($value,$display)=split(/\:/,$_);
  415:                       $r->print('<option value='.$value.'>'.$display.
  416:                               '</option>');
  417:                    } ('none: ','username:Username',
  418:                       'names:Last Name, First Names',
  419:                       'fname:First Name','mname:Middle Names/Initials',
  420:                       'lname:Last Name','gen:Generation',
  421:                       'id:ID/Student Number','sec:Group/Section',
  422:                       'ipwd:Initial Password');
  423:                    $r->print('</select></td><td>');
  424:                    if (defined($sone{$_})) { 
  425:                       $r->print($sone{$_}."</br>\n"); 
  426:                    }
  427: 	           if (defined($stwo{$_})) { 
  428:                       $r->print($stwo{$_}."</br>\n"); 
  429:                    }
  430: 	           if (defined($sthree{$_})) { 
  431:                       $r->print($sthree{$_}."</br>\n"); 
  432:                    }
  433:                    $r->print('</td></tr>');
  434:                    $i++;
  435: 	       } sort keys %sone;
  436: 	       $i--;
  437: 	     }
  438:              my $keyfields=join(',',sort keys %sone);
  439:              $r->print(<<ENDPICK);
  440: </table>
  441: <input type=hidden name=nfields value=$i>
  442: <input type=hidden name=keyfields value="$keyfields">
  443: <h3>Login Type</h3>
  444: <p>Note: this will not take effect if the user already exists</p>
  445: <p>
  446: <input type=radio name=login value=krb onClick="clickkrb(this.form);" />
  447: Kerberos authenticated with domain
  448: <input type=text size=10 name=krbdom onChange="setkrb(this.form);" />
  449: </p>
  450: <p>
  451: <input type=radio name=login value=int onClick="clickint(this.form);" />
  452: Internally authenticated (with initial password 
  453: <input type=text size=10 name=intpwd onChange="setint(this.form);" />)
  454: </p>
  455: <p>
  456: <input type=radio name=login value=loc onClick="clickloc(this.form);" />
  457: Local Authentication with argument
  458: <input type=text size=10 name=locarg onChange="setloc(this.form);" />
  459: </p>
  460: <h3>LON-CAPA Domain for Students</h3>
  461: LON-CAPA domain: <input type=text size=10 value=$defdom name=lcdomain><p>
  462: <h3>Starting and Ending Dates</h3>
  463: <input type="hidden" value='' name="pres_value">
  464: <input type="hidden" value='' name="pres_type">
  465: <input type="hidden" value='' name="pres_marker">
  466: <input type="hidden" value='$today' name=startdate>
  467: <input type="hidden" value='$halfyear' name=enddate>
  468: <a 
  469:  href="javascript:pjump('date_start','Enrollment Starting Date',document.studentform.startdate.value,'start','studentform.pres','dateset');"
  470: >Set Starting Date</a><p>
  471: 
  472: <a 
  473:  href="javascript:pjump('date_end','Enrollment Ending Date',document.studentform.enddate.value,'end','studentform.pres','dateset');"
  474: >Set Ending Date</a><p>
  475: <h3>Full Update</h3>
  476: <input type=checkbox name=fullup value=yes> Full update 
  477: (also print list of users not enrolled anymore)<p>
  478: <input type=button onClick="verify(this.form)" value="Update Courselist"><br>
  479: Note: for large courses, this operation might be time consuming.
  480: ENDPICK
  481: }
  482: 
  483: # ======================================================= Enroll single student
  484: 
  485: sub enroll_single_student {
  486:     my $r=shift;
  487:     $r->print('<h3>Enrolling Student</h3>');
  488:     if (($ENV{'form.cuname'})&&($ENV{'form.cuname'}!~/\W/)&&
  489:         ($ENV{'form.cdomain'})&&($ENV{'form.cdomain'}!~/\W/)) {
  490: 	my $amode='';
  491:         my $genpwd='';
  492:         if ($ENV{'form.login'} eq 'krb') {
  493:            $amode='krb4';
  494:            $genpwd=$ENV{'form.krbdom'};
  495:         } elsif ($ENV{'form.login'} eq 'int') {
  496:            $amode='internal';
  497:            $genpwd=$ENV{'form.intpwd'};
  498:         }  elsif ($ENV{'form.login'} eq 'loc') {
  499: 	    $amode='localauth';
  500: 	    $genpwd=$ENV{'form.locarg'};
  501: 	    if (!$genpwd) { $genpwd=" "; }
  502: 	}
  503:         if (($amode) && ($genpwd)) {
  504:  	  &dropstudent($ENV{'form.cdomain'},$ENV{'form.cuname'},
  505: 		       $ENV{'request.course.id'},$ENV{'form.csec'});
  506:           $r->print(&Apache::lonnet::modifystudent(
  507:                       $ENV{'form.cdomain'},$ENV{'form.cuname'},
  508:                       $ENV{'form.cstid'},$amode,$genpwd,
  509:  	              $ENV{'form.cfirst'},$ENV{'form.cmiddle'},
  510:                       $ENV{'form.clast'},$ENV{'form.cgen'},
  511:                       $ENV{'form.csec'},$ENV{'form.enddate'},
  512:                       $ENV{'form.startdate'}));
  513: 	} else {
  514:            $r->print('Invalid login mode or password');    
  515:         }          
  516:     } else {
  517:         $r->print('Invalid username or domain');
  518:     }    
  519: }
  520: 
  521: # ======================================================= Menu Phase Two Enroll
  522: 
  523: sub menu_phase_two_enroll {
  524:     my $r=shift;
  525:     
  526:     $ENV{'SERVER_NAME'}=~/(\w+\.\w+)$/;
  527:     my $krbdefdom=$1;
  528:     $krbdefdom=~tr/a-z/A-Z/;
  529: 
  530:     my $today=time;
  531:     my $halfyear=$today+15552000;
  532: 
  533:     my $defdom=$r->dir_config('lonDefDomain');
  534: 
  535:     $r->print(<<ENDSENROLL);
  536: <script>
  537: function verify(vf) {
  538:     var founduname=0;
  539:     var foundpwd=0;
  540:     var foundname=0;
  541:     var foundid=0;
  542:     var foundsec=0;
  543:     var foundatype=0;
  544:     var tw;
  545:     var message='';
  546:     if ((typeof(vf.cuname.value)!="undefined") && (vf.cuname.value!='') && 
  547: 	(typeof(vf.cdomain.value)!="undefined") && (vf.cdomain.value!='')) {
  548:         founduname=1;
  549:     }
  550:     if ((typeof(vf.cfirst.value)!="undefined") && (vf.cfirst.value!='') &&
  551: 	(typeof(vf.clast.value)!="undefined") && (vf.clast.value!='')) {
  552:         foundname=1;
  553:     }
  554:     if ((typeof(vf.csec.value)!="undefined") && (vf.csec.value!='')) {
  555:         foundsec=1;
  556:     }
  557:     if ((typeof(vf.cstid.value)!="undefined") && (vf.cstid.value!='')) {
  558: 	foundid=1;
  559:     }
  560:     if (founduname==0) {
  561: 	alert('You need to specify at least the username and domain fields');
  562:         return;
  563:     }
  564:     if (vf.login[0].checked) {
  565: 	foundatype=1;
  566:         if (vf.krbdom.value=='') {
  567: 	    alert('You need to specify the Kerberos domain');
  568:             return;
  569:         }
  570:     }
  571:     if (vf.login[1].checked) {
  572: 	foundatype=1;
  573:         if ((vf.intpwd.value=='') && (foundpwd==0)) {
  574: 	    alert('You need to specify the initial password');
  575:             return;
  576:         }
  577:     }
  578:     if (vf.login[2].checked) {
  579: 	foundatype=1;
  580: 	//An argument is not required
  581:     }
  582:     if (foundatype==0) {
  583: 	alert('You need to set the login type');
  584:         return;
  585:     }
  586:     if (foundname==0) { message='No first and last name specified. '; }
  587:     if (foundid==0) { message+='No ID or student number field specified. '; }
  588:     if (foundsec==0) { message+='No section or group field specified. '; }
  589:     if (vf.startdate.value=='') {
  590: 	message+='No starting date set. ';
  591:     }
  592:     if (vf.enddate.value=='') {
  593:         message+='No ending date set. ';
  594:     }
  595:     if ((vf.enddate.value!='') && (vf.startdate.value!='')) {
  596:        if (Math.round(vf.enddate.value)<Math.round(vf.startdate.value)) {
  597:           alert('Ending date is before starting date');
  598:           return;
  599:        }
  600:     }
  601:     if (message!='') {
  602:        message+='Continue enrollment?';
  603:        if (confirm(message)) {
  604: 	  pclose();
  605: 	  vf.submit();
  606:        }
  607:     } else {
  608:       pclose();
  609:       vf.submit();
  610:     }   
  611: }
  612: 
  613: function setkrb(vf) {
  614:     if (vf.krbdom.value!='') {
  615:        vf.login[0].checked=true;
  616:        vf.krbdom.value=vf.krbdom.value.toUpperCase();
  617:        vf.intpwd.value='';
  618:        vf.locarg.value='';
  619:    }
  620: }
  621: 
  622: function setint(vf) {
  623:     if (vf.intpwd.value!='') {
  624:        vf.login[1].checked=true;
  625:        vf.krbdom.value='';
  626:        vf.locarg.value='';
  627:    }
  628: }
  629: 
  630: function setloc(vf) {
  631:     if (vf.locarg.value!='') {
  632:        vf.login[2].checked=true;
  633:        vf.krbdom.value='';
  634:        vf.intpwd.value='';
  635:    }
  636: }
  637: 
  638: function clickkrb(vf) {
  639:     vf.krbdom.value='$krbdefdom';
  640:     vf.intpwd.value='';
  641:     vf.locarg.value='';
  642: }
  643: 
  644: function clickint(vf) {
  645:     vf.krbdom.value='';
  646:     vf.locarg.value='';
  647: }
  648: 
  649: function clickloc(vf) {
  650:     vf.krbdom.value='';
  651:     vf.intpwd.value='';
  652: }
  653: 
  654:     function pclose() {
  655:         parmwin=window.open("/adm/rat/empty.html","LONCAPAparms",
  656:                  "height=350,width=350,scrollbars=no,menubar=no");
  657:         parmwin.close();
  658:     }
  659: 
  660:     function pjump(type,dis,value,marker,ret,call) {
  661:         parmwin=window.open("/adm/rat/parameter.html?type="+escape(type)
  662:                  +"&value="+escape(value)+"&marker="+escape(marker)
  663:                  +"&return="+escape(ret)
  664:                  +"&call="+escape(call)+"&name="+escape(dis),"LONCAPAparms",
  665:                  "height=350,width=350,scrollbars=no,menubar=no");
  666: 
  667:     }
  668: 
  669:     function dateset() {
  670:         if (document.studentform.pres_marker.value=='end') {
  671:            document.studentform.enddate.value=
  672: 	       document.studentform.pres_value.value;
  673:         }
  674:         if (document.studentform.pres_marker.value=='start') {
  675:            document.studentform.startdate.value=
  676: 	       document.studentform.pres_value.value;
  677:         }
  678:         pclose();
  679:     }
  680: 
  681: </script>
  682: <h3>Personal Data</h3>
  683: First Name: <input type=text name=cfirst size=15><br>
  684: Middle Name: <input type=text name=cmiddle size=15><br>
  685: Last Name: <input type=text name=clast size=15><br>
  686: Generation: <input type=text name=cgen size=5><p>
  687: 
  688: ID/Student Number: <input type=text name=cstid size=10><p>
  689: 
  690: Group/Section: <input type=text name=csec size=5><p>
  691: 
  692: <h3>Login Data</h3>
  693: Username: <input type=text name=cuname size=15><p>
  694: Domain: <input type=text size=10 value=$defdom name=cdomain><p>
  695: Note: login settings below  will not take effect if the user already exists<p>
  696: 
  697: <input type=radio name=login value=krb onClick="clickkrb(this.form);">
  698: Kerberos authenticated with domain
  699: <input type=text size=10 name=krbdom onChange="setkrb(this.form);"><p>
  700: <input type=radio name=login value=int onClick="clickint(this.form);"> 
  701: Internally authenticated (with initial password 
  702: <input type=text size=10 name=intpwd onChange="setint(this.form);">)
  703: <p>
  704: <input type=radio name=login value=loc onClick="clickloc(this.form);" />
  705: Local Authentication with argument
  706: <input type=text size=10 name=locarg onChange="setloc(this.form);" />
  707: </p>
  708: <h3>Starting and Ending Dates</h3>
  709: <input type="hidden" value='' name="pres_value">
  710: <input type="hidden" value='' name="pres_type">
  711: <input type="hidden" value='' name="pres_marker">
  712: <input type="hidden" value='$today' name=startdate>
  713: <input type="hidden" value='$halfyear' name=enddate>
  714: <a 
  715:  href="javascript:pjump('date_start','Enrollment Starting Date',document.studentform.startdate.value,'start','studentform.pres','dateset');"
  716: >Set Starting Date</a><p>
  717: 
  718: <a 
  719:  href="javascript:pjump('date_end','Enrollment Ending Date',document.studentform.enddate.value,'end','studentform.pres','dateset');"
  720: >Set Ending Date</a><p>
  721: <input type=button onClick="verify(this.form)" value="Enroll as student"><br>
  722: <input type=hidden name=phase value=five>
  723: ENDSENROLL
  724: }
  725: 
  726: # ========================================================= Menu Phase Two Drop
  727: 
  728: sub menu_phase_two_drop {
  729:     my $r=shift;
  730:     my $cid=$ENV{'request.course.id'};
  731:                  my $classlst=&Apache::lonnet::reply
  732:                  ('dump:'.$ENV{'course.'.$cid.'.domain'}.':'.
  733: 	                  $ENV{'course.'.$cid.'.num'}.':classlist',
  734: 	                  $ENV{'course.'.$cid.'.home'});
  735:                  my %currentlist=();
  736:                  my $now=time;
  737:                  unless ($classlst=~/^error\:/) {
  738:                      map {
  739:                         my ($name,$value)=split(/\=/,$_);
  740:                         my ($end,$start)=split(/\:/,
  741:                                             &Apache::lonnet::unescape($value));
  742:                         my $active=1;
  743:                         if (($end) && ($now>$end)) { $active=0; }
  744:                         if ($active) {
  745: 		           $currentlist{&Apache::lonnet::unescape($name)}=1;
  746:                         }
  747:                      } split(/\&/,$classlst);
  748: # ----------------------------------------------------------- Print out choices
  749:                      &show_drop_list($r,%currentlist);
  750: 	         } else {
  751:                      $r->print(
  752:                   '<font color=red><h3>Could not access classlist: '.$classlst.
  753:                   '</h3></font>');
  754:                  }
  755: }
  756: 
  757: # =================================================== Show student list to drop
  758: 
  759: sub show_drop_list {
  760:     my ($r,%currentlist)=@_;
  761:     my $cid=$ENV{'request.course.id'};
  762: 
  763:     $r->print('<input type=hidden name=phase value=four>');
  764:                      $r->print('<table border=2>');
  765:                      map {
  766:                          my ($sname,$sdom)=split(/\:/,$_);
  767:                          my %reply=&Apache::lonnet::idrget($sdom,$sname);
  768:                          my $ssec=&Apache::lonnet::usection($sdom,$sname,$cid);
  769:                          my @reply=split(/[\&\=]/,&Apache::lonnet::reply(
  770:                            'get:'.$sdom.':'.$sname.
  771: 		      ':environment:firstname&middlename&lastname&generation',
  772:                            &Apache::lonnet::homeserver($sname,$sdom)));
  773:  			 $r->print(
  774:                   '<tr><td><input type=checkbox name="drop:'.$_.'"></td><td>'.
  775:                                    $sname.'</td><td>'.$sdom.'</td><td>'.
  776:                                    $reply{$sname}.'</td><td>'.
  777:                                    &Apache::lonnet::unescape($reply[2]).' '.
  778:                                    &Apache::lonnet::unescape($reply[3]).', '.
  779:                                    &Apache::lonnet::unescape($reply[0]).' '.
  780:                                    &Apache::lonnet::unescape($reply[1]).
  781:                                    '</td><td>'.
  782:                                    $ssec."</td></tr>\n");
  783:                      } sort keys %currentlist;
  784:                      $r->print('</table><br>');
  785:                      $r->print('<input type=submit value="Drop Students">');
  786: }
  787: 
  788: # ================================================= Drop/Add from uploaded file
  789: 
  790: sub upfile_drop_add {
  791:     my $r=shift;
  792: 
  793:     &load_tmp_file($r);
  794:     my @studentdata=&upfile_record_sep();
  795: 
  796:     my @keyfields=split(/\,/,$ENV{'form.keyfields'});
  797:     my $cid=$ENV{'request.course.id'};
  798: 
  799:              my %fields=();
  800:              for (my $i=0;$i<=$ENV{'form.nfields'};$i++) {
  801:                  $fields{$ENV{'form.f'.$i}}=$keyfields[$i];
  802:              }
  803:              my $startdate=$ENV{'form.startdate'};
  804:              my $enddate=$ENV{'form.enddate'};
  805:              if ($startdate=~/\D/) { $startdate=''; }
  806:              if ($enddate=~/\D/) { $enddate=''; }
  807:              my $domain=$ENV{'form.lcdomain'};
  808:              my $amode='';
  809:              my $genpwd='';
  810:              if ($ENV{'form.login'} eq 'krb') {
  811:                  $amode='krb4';
  812:                  $genpwd=$ENV{'form.krbdom'};
  813:              } elsif ($ENV{'form.login'} eq 'int') {
  814:                  $amode='internal';
  815:                  if ((defined($ENV{'form.intpwd'})) && ($ENV{'form.intpwd'})) {
  816: 		     $genpwd=$ENV{'form.intpwd'};
  817:                  }
  818:              } elsif ($ENV{'form.login'} eq 'loc') {
  819: 		 $amode='localauth';
  820: 		 if ((defined($ENV{'form.locarg'})) && ($ENV{'form.locarg'})) {
  821: 		     $genpwd=$ENV{'form.locarg'};
  822:                  }
  823: 	     }
  824:              unless (($domain=~/\W/) || ($amode eq '')) {
  825:               $r->print('<h3>Enrolling Students</h3>');
  826:               my $count=0;
  827:               my $flushc=0;
  828:               my %student=();
  829: # ----------------------------------------------------------- Get new classlist
  830: # --------------------------------------------------------- Enroll new students
  831: 	      map {
  832: 		  my %entries=&record_sep($_);
  833: 
  834:                 unless (($entries{$fields{'username'}} eq '') ||
  835:                         (!defined($entries{$fields{'username'}}))) {
  836:                   my $fname=''; my $mname=''; my $lname=''; my $gen='';
  837:                   if (defined($fields{'names'})) {
  838: 		      ($lname,$fname,$mname)=
  839: 	            ($entries{$fields{'names'}}=~/([^\,]+)\,\s*(\w+)\s*(.*)$/);
  840:                   } else {
  841:                       if (defined($fields{'fname'})) {
  842: 		         $fname=$entries{$fields{'fname'}};
  843: 		      }
  844:                       if (defined($fields{'mname'})) {
  845: 		         $mname=$entries{$fields{'mname'}};
  846: 		      }
  847:                       if (defined($fields{'lname'})) {
  848: 		         $lname=$entries{$fields{'lname'}};
  849: 		      }
  850:                       if (defined($fields{'gen'})) {
  851: 		         $gen=$entries{$fields{'gen'}};
  852: 		      }
  853:                   }
  854:                   if ($entries{$fields{'username'}}=~/\W/) {
  855:                      $r->print('<p><b>Unacceptable username: '.
  856:                               $entries{$fields{'username'}}.' for user '.
  857:                               $fname.' '.$mname.' '.$lname.' '.$gen.'</b><p>');
  858: 		  } else {
  859:                       my $sec='';
  860:                       my $username=$entries{$fields{'username'}};
  861:                       if (defined($fields{'sec'})) {
  862:                          if (defined($entries{$fields{'sec'}})) {
  863: 			     $sec=$entries{$fields{'sec'}};
  864:                          }
  865:                       }
  866:                       my $id='';
  867:                       if (defined($fields{'id'})) {
  868:                          if (defined($entries{$fields{'id'}})) {
  869: 			     $id=$entries{$fields{'id'}};
  870:                          }
  871:                          $id=~tr/A-Z/a-z/;
  872:                       }
  873:                       my $password='';
  874:                       if ($genpwd) { 
  875:                          $password=$genpwd; 
  876: 		      } else {
  877:                          if (defined($fields{'ipwd'})) {
  878: 			     if ($entries{$fields{'ipwd'}}) {
  879: 				 $password=$entries{$fields{'ipwd'}};
  880:                              }
  881:                          }
  882:                       }
  883:                       if ($password) {
  884: 			 &dropstudent($domain,$username,$cid,$sec);
  885:                          my $reply=&Apache::lonnet::modifystudent(
  886:                           $domain,$username,$id,$amode,$password,
  887: 			   $fname,$mname,$lname,$gen,$sec,$enddate,$startdate);
  888:                          unless ($reply eq 'ok') {
  889:                             $r->print(
  890:                              "<p><b>Error enrolling $username: $reply</b><p>");
  891:          		} else {
  892:                             $count++; $flushc++;
  893:                             $student{$username}=1;
  894:                             $r->print('. ');
  895:                             if ($flushc>15) {
  896: 				$r->rflush;
  897:                                 $flushc=0;
  898:                             }
  899:                         }
  900:                      } else {
  901:                             $r->print(
  902:                              "<p><b>No password for $username</b><p>");
  903:                      }
  904:                   }
  905:                  }                 
  906:               } @studentdata;
  907:               $r->print('<p>Processed Students: '.$count);
  908: # --------------------------------------------------------------- Drop students
  909:               if ($ENV{'form.fullup'} eq 'yes') {
  910: 		 $r->print('<h3>Dropping Students</h3>');
  911: # ------------------------------------------------------- Get current classlist
  912:                  my $classlst=&Apache::lonnet::reply
  913:                  ('dump:'.$ENV{'course.'.$cid.'.domain'}.':'.
  914: 	                  $ENV{'course.'.$cid.'.num'}.':classlist',
  915: 	                  $ENV{'course.'.$cid.'.home'});
  916:                  my %currentlist=();
  917:                  my $now=time;
  918:                  unless ($classlst=~/^error\:/) {
  919:                      map {
  920:                         my ($name,$value)=split(/\=/,$_);
  921:                         my ($end,$start)=split(/\:/,
  922:                                             &Apache::lonnet::unescape($value));
  923:                         my $active=1;
  924:                         if (($end) && ($now>$end)) { $active=0; }
  925:                         if ($active) {
  926: 		           $currentlist{&Apache::lonnet::unescape($name)}=1;
  927:                         }
  928:                      } split(/\&/,$classlst);
  929: # ------------------------------------------------ Now got up-to-date classlist
  930:                      map {
  931:  	                my %entries=&record_sep($_);
  932:                         unless (($entries{$fields{'username'}} eq '') ||
  933:                           (!defined($entries{$fields{'username'}}))) {
  934: 			   delete($currentlist{
  935:                             $entries{$fields{'username'}}.':'.
  936:                             $domain});
  937: 		        }
  938:                      } @studentdata;
  939: # ----------------------------------------------------------- Print out choices
  940:                      &show_drop_list($r,%currentlist);
  941: 	         } else {
  942:                      $r->print(
  943:                   '<font color=red><h3>Could not access classlist: '.$classlst.
  944:                   '</h3></font>');
  945:                  }
  946: 	     }
  947: # ------------------------------------------------------------------------ Done
  948: 
  949: 	  }
  950: }
  951: 
  952: # ================================================================== Phase four
  953: 
  954: sub drop_student_list {
  955:     my $r=shift;
  956:     my $count=0;
  957:     map {
  958: 	if ($_=~/^form\.drop\:/) {
  959: 	    my ($dummy,$uname,$udom)=split(/\:/,$_);
  960:             &dropstudent($udom,$uname,$ENV{'request.course.id'});
  961:             $r->print('Dropped '.$uname.' at '.$udom.'<br>');
  962:             $count++;
  963:         }
  964:     } keys %ENV;
  965:     $r->print('<p><b>Dropped '.$count.' student(s).</b>');
  966:     $r->print('<p>Re-enrollment will re-activate data.');
  967: }
  968: 
  969: # ================================================================ Main Handler
  970: 
  971: sub handler {
  972:    my $r=shift;
  973: 
  974:    if ($r->header_only) {
  975:       $r->content_type('text/html');
  976:       $r->send_http_header;
  977:       return OK;
  978:    }
  979: 
  980: # ----------------------------------------------------- Needs to be in a course
  981: 
  982:    if (($ENV{'request.course.fn'}) && 
  983:        (&Apache::lonnet::allowed('cst',$ENV{'request.course.id'}))) {
  984: 
  985: # ------------------------------------------------------------------ Start page
  986:       $r->content_type('text/html');
  987:       $r->send_http_header;
  988:       &header($r);
  989: 
  990: # --------------------------------------------------- Phase one, initial screen
  991:       unless ($ENV{'form.phase'}) {
  992: 	  &menu_phase_one($r);
  993:       }
  994: # ------------------------------------------------------------------- Phase two
  995:       if ($ENV{'form.phase'} eq 'two') {
  996: 	 if ($ENV{'form.fileupload'}) {
  997: 	     &menu_phase_two_upload($r);
  998:          } elsif ($ENV{'form.enroll'}) {
  999:              &menu_phase_two_enroll($r);
 1000:          } elsif ($ENV{'form.drop'}) {
 1001:              &menu_phase_two_drop($r);
 1002:          }
 1003:       }
 1004: 
 1005: 
 1006: 
 1007: 
 1008: # ----------------------------------------------------------------- Phase three
 1009:       if ($ENV{'form.phase'} eq 'three') {
 1010: 	  if ($ENV{'form.datatoken'}) {
 1011: 	      &upfile_drop_add($r);
 1012:           }
 1013:       }
 1014: # ------------------------------------------------------------------ Phase four
 1015:       if ($ENV{'form.phase'} eq 'four') {
 1016: 	  &drop_student_list($r);
 1017:       }
 1018: # ------------------------------------------------------------------ Phase four
 1019:       if ($ENV{'form.phase'} eq 'five') {
 1020: 	  &enroll_single_student($r);
 1021:       }
 1022: # ------------------------------------------------------------------------- End
 1023:       $r->print('</form></body></html>');
 1024:    } else {
 1025: # ----------------------------- Not in a course, or not allowed to modify parms
 1026:       $ENV{'user.error.msg'}=
 1027:         "/adm/dropadd:cst:0:0:Cannot drop or add students";
 1028:       return HTTP_NOT_ACCEPTABLE; 
 1029:    }
 1030:    return OK;
 1031: }
 1032: 
 1033: 1;
 1034: __END__
 1035: 
 1036: 
 1037: 
 1038: 

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