Annotation of loncom/automation/batchcreatecourse.pm, revision 1.6

1.4       albertel    1: #
1.6     ! raeburn     2: # $Id: batchcreatecourse.pm,v 1.5 2005/06/01 19:20:32 raeburn Exp $
1.4       albertel    3: #
                      4: # Copyright Michigan State University Board of Trustees
                      5: #
                      6: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                      7: #
                      8: # LON-CAPA is free software; you can redistribute it and/or modify
                      9: # it under the terms of the GNU General Public License as published by
                     10: # the Free Software Foundation; either version 2 of the License, or
                     11: # (at your option) any later version.
                     12: #
                     13: # LON-CAPA is distributed in the hope that it will be useful,
                     14: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     15: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     16: # GNU General Public License for more details.
                     17: #
                     18: # You should have received a copy of the GNU General Public License
                     19: # along with LON-CAPA; if not, write to the Free Software
                     20: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     21: #
                     22: # /home/httpd/html/adm/gpl.txt
                     23: #
                     24: # http://www.lon-capa.org/
                     25: #
                     26: 
1.1       raeburn    27: package LONCAPA::batchcreatecourse;
                     28: use LONCAPA::Configuration;
                     29: use LONCAPA::Enrollment;
                     30: use HTML::Parser;
                     31: use Time::Local;
                     32: use Apache::Constants; 
                     33: use Apache::lonnet;
1.2       raeburn    34: use Apache::loncommon;
1.1       raeburn    35: use Apache::loncreatecourse;
1.2       raeburn    36: use Apache::loncreateuser;
1.1       raeburn    37: use Apache::lonlocal;
                     38: 
                     39: # Collection of routines used for batch creation of courses and users.
                     40: # &create_courses() should be called by an Autocreate.pl
                     41: # script via a cron entry, or alternatively from a web page, after upload 
                     42: # of a file containing an XML description of a course request (lonbatchccrs.pm).
                     43: # 
                     44: # XML file(s) describing courses that are to be created in domain $dom are stored in
1.3       raeburn    45: # /home/httpd/perl/tmp/addcourse/$dom
1.1       raeburn    46: #
                     47: # &create_courses() will create an account for the course owner 
                     48: # (if one does not currently exist), will create the course (cloning if necessary),
                     49: # and will add additional instructional staff (creating accounts if necessary).
                     50: #
                     51: # Example of XML file (which could contain more than one class to be created):
                     52: #
                     53: #<?xml version="1.0" encoding="UTF-8"?>
                     54: #<!DOCTYPE text>
                     55: #<class id="ss05ubw101">
                     56: # <title>Underwater Basket Weaving</title>
                     57: # <coursecode>ss05ubw101</coursecode>
                     58: # <coursehome>msul1</coursehome>
                     59: # <coursedomain>msu</coursedomain>
                     60: # <reshome>/res/msu/</reshome>
                     61: # <optional_id></optional_id>
                     62: # <adds>1</adds>
                     63: # <drops>1</drops>
                     64: # <enrollstart>2005:01:04:10:30</enrollstart>
                     65: # <enrollend>2005:07:04:20:30</enrollend>
                     66: # <accessstart>2005:01:10:10:30</accessstart>
                     67: # <accessend>2005:05:31:10:30</accessend>
                     68: # <authentication>
                     69: #  <method>krb4</method>
                     70: #  <param>MSU.EDU</param>
                     71: # </authentication>
                     72: # <nonstandard></nonstandard>
                     73: # <topmap></topmap>
                     74: # <firstres>nav</firstres>
                     75: # <clonecrs>466011437c34194msul1</clonecrs>
                     76: # <clonedom>msu</clonedom>
                     77: # <showphotos></showphotos>
                     78: # <setpolicy>1</setpolicy>
                     79: # <setcontent>1</setcontent>
                     80: # <setkeys>0</setkeys>
                     81: # <keyauth>keyadmin@msu</keyauth>
                     82: # <disresdis>1</disresdis>
                     83: # <disablechat>1</disablechat>
                     84: # <openall></openall>
                     85: # <notify_dc>1</notify_dc>
                     86: # <notify_owner>1</notify_owner>
                     87: # <owner>
                     88: #  <username>sparty</username>
                     89: #  <domain>msu</domain>
                     90: #  <authtype>krb4</authtype>
                     91: #  <autharg>MSU.EDU</autharg>
                     92: # </owner>
                     93: # <sections>
                     94: #  <section>
                     95: #   <inst>001</inst>
                     96: #   <loncapa>1</loncapa>
                     97: #  </section>
                     98: #  <section>
                     99: #   <inst>002</inst>
                    100: #   <loncapa>2</loncapa>
                    101: #  </section>
                    102: # </sections>
                    103: # <crosslists>
                    104: #  <xlist>
                    105: #   <inst>ss05zzz101001</inst>
                    106: #   <loncapa>1</loncapa>
                    107: #  </xlist>
                    108: # </crosslists>
                    109: # <users>
                    110: #  <user>
                    111: #   <username>sparty</username>
                    112: #   <domain>msu</domain>
                    113: #   <email>sparty@msu.edu</email>
                    114: #   <authtype>krb4</authtype>
                    115: #   <autharg></autharg>
                    116: #   <firstname>MSU</firstname>
                    117: #   <generation></generation>
                    118: #   <lastname>Spartan</lastname>x
                    119: #   <middlename></middlename>
                    120: #   <studentID></studentID>
                    121: #   <roles></roles>
                    122: #  </user>
                    123: #  <user>
                    124: #   <username>itds0001</username>
                    125: #   <domain>northwood5</domain>
                    126: #   <email>itds0001@msu.edu</email>
                    127: #   <authtype>int</authtype>
                    128: #   <autharg></autharg>
                    129: #   <firstname>Info</firstname>
                    130: #   <generation></generation>
                    131: #   <lastname>Techc</lastname>x
                    132: #   <middlename></middlename>
                    133: #   <studentID></studentID>
                    134: #   <roles>
                    135: #    <role id='in'>
                    136: #     <start>2005:01:01:12:10</start>
                    137: #     <end>2005:12:01:12:10</end>
                    138: #     <usec>1</usec>
                    139: #     <usec>2</usec>
                    140: #    </role>
                    141: #   </roles>
                    142: #  </user>
                    143: # </users>
                    144: #</class>
                    145: #
                    146: # Many of these are binary options (corresponding to either checkboxes or
                    147: # radio buttons in the interactive CCRS page).  Examples include:
                    148: # setpolicy, setcontent, setkeys, disableresdis, disablechat, openall
                    149: #
                    150: # A value of 1 between opening and closing tags is equivalent to a 
                    151: # checked checkbox or 'Yes' response in the original CCRS web page.
                    152: # A value of 0 or blank is equivalent to an unchecked box or 'No'
                    153: # response. Dates are in format YYYY:MM:DD:HH:MM:SS (:separators required)
                    154: #
                    155: # firstres can be nav, syl , or blank for "Navigate Contents", Syllabus, or
                    156: # no entry respectively.
                    157: # For format of other parameters, refer to the interactive CCRS page
                    158: # and view how the equivalent parameter is displayed in the web form.  
                    159: #  
                    160: ##############################################################
                    161: # create_courses() - creates courses described in @$requests,
                    162: #                    files listed in @$requests are deleted
                    163: #                    after the files have been parsed.
                    164: #
1.3       raeburn   165: #                    Directory for retrieval of files listed in @$requests is: 
                    166: #                    /home/httpd/perl/tmp/addcourse/$dom/auto/pending if $context = auto
                    167: #                    /home/httpd/perl/tmp/addcourse/$dom/web/$udom_$uname if $context = web
1.1       raeburn   168: #                    
                    169: # inputs (five)  -  requests - ref to array of filename(s) containing course requests 
                    170: #                   courseids - ref to hash to store LON-CAPA course ids of new courses 
                    171: #                   context - auto if called from command line, web if called from browser
                    172: #                   dom - domain for which the course is being created
1.3       raeburn   173: #                   uname - username of DC who is requesting course creation
                    174: #                   udom - domain of DC who is requesting course creation
1.1       raeburn   175: #  
                    176: # outputs (three)  -  output - text recording user roles added etc.
                    177: #                     logmsg - text to be logged
                    178: #                     keysmsg - text containing link(s) to manage keys page(s) 
                    179: #############################################################
                    180: 
                    181: sub create_courses {
1.3       raeburn   182:     my ($requests,$courseids,$context,$dom,$uname,$udom) = @_;
1.1       raeburn   183:     my $output;
                    184:     my $perlvarref = LONCAPA::Configuration::read_conf('loncapa.conf');
                    185: # Get role names
                    186:     my %longroles = ();
                    187:     open(FILE,"<$perlvarref{'lonTabDir'}.'/rolesplain.tab");
                    188:     my @rolesplain = <FILE>;
                    189:     close(FILE);
                    190:     foreach (@rolesplain) {
                    191:         if ($_ =~ /^(st|ta|ex|ad|in|cc):([\w\s]+)$/) {
                    192:             $longroles{$1} = $2;
                    193:         }
                    194:     }
                    195:     my ($logmsg,$keysmsg,$newusermsg,$addresult);
                    196:     my %enrollcount = ();
                    197:     my $newcoursedir = $$perlvarref{'lonDaemons'}.'/tmp/addcourse/'.$dom.'/'.$context;
1.3       raeburn   198:     if ($context eq 'auto') {
                    199:         $newcoursedir .= '/pending';
                    200:     } else {
                    201:         if ($uname && $udom) {
                    202:             $newcoursedir .= '/'.$udom.'_'.$uname;
                    203:         } else {
                    204:             $logmsg = "batchcreatecourse::create_courses() called without username and/or domain of requesting Domain Coordinator";
1.1       raeburn   205:         }
                    206:     }
                    207:     if (@{$requests} > 0) {
                    208:         foreach my $request (@{$requests}) {
                    209:             my %details = ();
                    210:             if (-e $newcoursedir.'/'.$request) {
                    211:                 &parse_coursereqs($newcoursedir.'/'.$request, \%details);
                    212:                 foreach my $num (sort keys %details) {
                    213:                     my $courseid = &build_course($dom,$num,$context,\%details,\%longroles,\$logmsg,\$newusermsg,\$addresult,\%enrollcount,\$output,\$keysmsg);
1.5       raeburn   214:                     $$courseids{$courseid} = $details{$num}{'class'};
1.1       raeburn   215:                 }
                    216:             }
                    217:         }
                    218:     }
                    219:     return ($output,$logmsg,$keysmsg);
                    220: }
                    221: 
                    222: #############################################################
                    223: #
                    224: # parse_coursereqs() 
                    225: # inputs (two) - coursefile - path to XML file containing course(s) to be created.
                    226: #              - details - reference to hash containing extracted information.
                    227: # outputs (none)
                    228: #
                    229: ############################################################
                    230: 
                    231: sub parse_coursereqs {
                    232:     my ($coursefile,$details) = @_;
                    233: #   Note all start and end dates should be in this format:
                    234: #   YYYY:MM:DD:HH:MM:SS (:separators required).
                    235:     my $uname = '';
                    236:     my @state = ();
                    237:     my $num = 0;
                    238:     my $secid = 0;
                    239:     my $xlist = 0;
                    240:     my $userkey = '';
                    241:     my $role = '';
                    242:     my @items = ('title','optional_id','coursecode','coursehome','reshome','nonstandard','adds','drops','topmap','firstres','clonecrs','clonedom','showphotos','setpolicy','setcontent','setkeys','keyauth','disresdis','disablechat','openall','notify_owner','notify_dc');
                    243:     my @dateitems = ('enrollstart','enrollend','accessstart','accessend');
                    244:     my @useritems = ('autharg','authtype','firstname','generation','lastname','middlename','studentID');
                    245:     my $p = HTML::Parser->new
                    246:     (
                    247:         xml_mode => 1,
                    248:         start_h =>
                    249:             [sub {
                    250:                  my ($tagname, $attr) = @_;
                    251:                  push(@state, $tagname);
                    252:                  if ("@state" eq "class") {
                    253:                      %{$$details{$num}} = ();
                    254:                      $$details{$num}{'class'} = $attr->{id};
                    255:                      %{$$details{$num}{'users'}} = ();
                    256:                      %{$$details{$num}{'sections'}} = ();
                    257:                      $secid = 0;
                    258:                      $xlist = 0;
                    259:                  }
                    260:                  if ("@state" eq "class users user roles role") {
                    261:                      $role = $attr->{id};
                    262:                      if ($role =~ /^(st|ad|ep|ta|in|cc)$/) {
                    263:                          push(@{$$details{$num}{'users'}{$userkey}{'roles'}}, $role);  
                    264:                          %{$$details{$num}{'users'}{$userkey}{$role}} = ();
                    265:                          @{$$details{$num}{'users'}{$userkey}{$role}{'usec'}} = ();
                    266:                      }
                    267:                  }
                    268:                  if ("@state" eq "class sections section") {
                    269:                      $secid ++;
                    270:                      %{$$details{$num}{'sections'}{$secid}} = ();
                    271:                  }
                    272:                  if ("@state" eq "class crosslists xlist") {
                    273:                      $xlist ++;
                    274:                      %{$$details{$num}{'crosslists'}{$xlist}} = ();
                    275:                  }
                    276:             }, "tagname, attr"],
                    277:          text_h =>
                    278:              [sub {
                    279:                  my ($text) = @_;
                    280:                  if ("@state" eq "class owner username") {
                    281:                      $$details{$num}{'owner'} = $text;
                    282:                  } elsif ("@state" eq "class owner domain") {
                    283:                     $$details{$num}{'domain'} = $text;
                    284:                  } elsif ("@state" eq "class sections section inst") {
                    285:                     $$details{$num}{'sections'}{$secid}{'inst'} = $text;
                    286:                  } elsif ("@state" eq "class sections section loncapa") {
                    287:                     $$details{$num}{'sections'}{$secid}{'loncapa'} = $text;
                    288:                  } elsif ("@state" eq "class crosslists xlist inst") {
                    289:                     $$details{$num}{'crosslists'}{$xlist}{'inst'} = $text;
                    290:                  } elsif ("@state" eq "class crosslists xlist loncapa") {
                    291:                     $$details{$num}{'crosslists'}{$xlist}{'loncapa'} = $text;
                    292:                  } elsif ("@state" eq "class owner authtype") {
                    293:                     $$details{$num}{'ownerauthtype'} = $text;
                    294:                  } elsif ("@state" eq "class owner autharg") {
1.5       raeburn   295:                     $$details{$num}{'ownerauthparam'} = $text;
1.1       raeburn   296:                  } elsif ("@state" eq "class authentication method") {
                    297:                     $$details{$num}{'authtype'} = $text;
                    298:                  } elsif ("@state" eq "class authentication param") {
                    299:                     $$details{$num}{'authparam'} = $text;
                    300:                  } elsif ("@state" eq "class users user username") {
                    301:                     $userkey = $text;
                    302:                  } elsif ("@state" eq "class users user domain") {
                    303:                     $userkey .= ':'.$text;
                    304:                     %{$$details{$num}{'users'}{$userkey}} = ();
                    305:                     @{$$details{$num}{'users'}{$userkey}{'roles'}} = ();
                    306:                  } elsif ("@state" eq "class users user email") {
                    307:                     $$details{$num}{'users'}{$userkey}{'emailaddr'} = $text;
                    308:                     $$details{$num}{'users'}{$userkey}{'emailenc'} = &Apache::lonnet::escape($text); 
                    309:                  } elsif ("@state" eq "class users user roles role start") {
                    310:                      if ($role =~ /^(st|ad|ep|ta|in|cc)$/) {
                    311:                          $$details{$num}{'users'}{$userkey}{$role}{'start'} = &process_date($text);
                    312:                      }
                    313:                  } elsif ("@state" eq "class users user roles role end") {
                    314:                      if ($role =~ /^(st|ad|ep|ta|in|cc)$/) {
                    315:                          $$details{$num}{'users'}{$userkey}{$role}{'end'} = &process_date($text);
                    316:                      }
                    317:                  } elsif ("@state" eq "class users user roles role usec") {
                    318:                      if ($role =~ /^(st|ad|ep|ta|in|cc)$/) {
                    319:                          unless ($text eq '') {
                    320:                              push(@{$$details{$num}{'users'}{$userkey}{$role}{'usec'}},$text);
                    321:                          }
                    322:                      }
                    323:                  } else {
                    324:                      foreach my $item (@items) {
                    325:                          if ("@state" eq "class $item") {
                    326:                              $$details{$num}{$item} = $text;
                    327:                          }
                    328:                      }
                    329:                      foreach my $item (@dateitems) {
                    330:                          if ("@state" eq "class $item") {
                    331:                              $$details{$num}{$item} = &process_date($text);
                    332:                          }
                    333:                      }
                    334:                      foreach my $item (@useritems) {
                    335:                          if ("@state" eq "class users user $item") {
                    336:                              $$details{$num}{'users'}{$userkey}{$item} = $text;
                    337:                          }
                    338:                      }
                    339:                  }
                    340:                }, "dtext"],
                    341:          end_h =>
                    342:                [sub {
                    343:                    my ($tagname) = @_;
                    344:                    if ("@state" eq "class") {
                    345:                        $num ++;
                    346:                    }
                    347:                    pop @state;
                    348:                 }, "tagname"],
                    349:     );
                    350: 
                    351:     $p->parse_file($coursefile);
                    352:     $p->eof;
                    353:     return;
                    354: }
                    355: 
                    356: #########################################################
                    357: #
                    358: # build_course() 
                    359: #
                    360: # inputs
                    361: #   domain
                    362: #   course request number
                    363: #   context - auto if called from command line, web if called from DC web interface
                    364: #   ref to hash of course creation information
                    365: #   ref to hash of role descriptions
                    366: #   ref to scalar used to accumulate log messages
                    367: #   ref to scalar used to accumulate messages sent to new users
                    368: #   ref to scalar used to accumulate results of new user additions
                    369: #   ref to hash of enrollment counts for different roles
                    370: #   ref to scalar used to accumulate iformation about added roles
                    371: #   ref to scalar used to accumulate 
                    372: #
                    373: # outputs
                    374: #   LON-CAPA courseID for new (created) course
                    375: #
                    376: #########################################################
                    377: 
                    378: sub build_course {
1.3       raeburn   379:     my ($cdom,$num,$context,$details,$longoles,$logmsg,$newusermsg,$addresult,$enrollcount,$output,$keysmsg,$udom,$uname) = @_;
1.1       raeburn   380:     my $owner_uname = $$details{$num}{'owner'};
                    381:     my $owner_domain = $$details{$num}{'domain'};
                    382:     my $owner = $owner_uname.':'.$owner_domain;
                    383:     my $sectionstr = '';
                    384:     my $xliststr = '';
                    385:     my $noenddate = '';
                    386:     my $outcome;
                    387:     my ($courseid,$crsudom,$crsunum);
                    388:     my $linefeed;
                    389:     if ($context eq 'auto') {
                    390:         $linefeed = "\n";
                    391:     } else {
                    392:         $linefeed = "<br />\n";
                    393:     }
                    394:     if ($$details{$num}{'accessend'} eq '') {
                    395:         $noenddate = 1;
                    396:     }
                    397:     my $reshome = $$details{$num}{'reshome'};
                    398:     if ($reshome eq '') {
                    399:         $reshome = '/res/'.$cdom;
                    400:     }
                    401:     my $firstres =  $$details{$num}{'firstres'};
                    402:     if ($firstres eq '') {
                    403:         $firstres = 'syl';
                    404:     }
                    405:     foreach my $secid (sort keys %{$$details{$num}{'sections'}}) {
1.5       raeburn   406:         $sectionstr .= $$details{$num}{'sections'}{$secid}{'inst'}.':'.$$details{$num}{'sections'}{$secid}{'loncapa'}.',';
1.1       raeburn   407:     }
1.5       raeburn   408:     $sectionstr =~ s/,$//;
1.1       raeburn   409: 
                    410:     foreach my $xlist (sort keys %{$$details{$num}{'crosslists'}}) {
1.5       raeburn   411:         $xliststr .= $$details{$num}{'crosslists'}{$xlist}{'inst'}.':'.$$details{$num}{'crosslists'}{$xlist}{'loncapa'}.',';
1.1       raeburn   412:     }
1.5       raeburn   413:     $xliststr =~ s/,$//;
1.1       raeburn   414: 
                    415:     my %courseinfo = (
                    416:                       inst_code => $$details{$num}{'coursecode'},
                    417:                       description => $$details{$num}{'title'}
                    418:                      ); 
                    419:     if (&Apache::lonnet::homeserver($$details{$num}{'owner'},$$details{$num}{'domain'}) eq 'no_host') { # Add user if no account
1.5       raeburn   420:         my $ownerargs = {'auth' => $$details{$num}{'ownerauthtype'},
1.1       raeburn   421:                     'authparam' => $$details{$num}{'ownerauthparam'},
                    422:                     'emailenc' => $$details{$num}{'emailenc'},
                    423:                     'dom' => $$details{$num}{'domain'},
                    424:                     'uname' => $$details{$num}{'owner'},
                    425:                     'pid' => '',
                    426:                     'first' => $$details{$num}{'users'}{$owner}{'first'},
                    427:                     'middle' => $$details{$num}{'users'}{$owner}{'middle'},
                    428:                     'last' => $$details{$num}{'users'}{$owner}{'last'},
                    429:                     'gene' => $$details{$num}{'users'}{$owner}{'gene'},
                    430:                     'usec' => '',
                    431:                     'end' => '',
                    432:                     'start' => '',
                    433:                     'emailaddr' => $$details{$num}{'users'}{$owner}{'email'},
                    434:                     'cid' => '',
                    435:                     'context' => 'createowner',
                    436:                     'linefeed' => $linefeed,
1.5       raeburn   437:                     'role' => 'cc',
                    438:                    };
1.6     ! raeburn   439:         $outcome = &LONCAPA::Enrollment::create_newuser($ownerargs,$logmsg,$newusermsg,$enrollcount,$addresult,$longroles,\%courseinfo);
1.1       raeburn   440:     } else {
                    441:         $outcome = 'ok';
                    442:     }
                    443: 
1.6     ! raeburn   444:     if ($outcome eq 'ok') {
        !           445:         my $courseargs = {
1.1       raeburn   446:                ccuname => $$details{$num}{'owner'},
                    447:                ccdomain => $$details{$num}{'domain'},
                    448:                cdescr => $$details{$num}{'title'},
                    449:                curl => $$details{$num}{'topmap'},
                    450:                course_domain => $cdom,
                    451:                course_home =>  $$details{$num}{'coursehome'},
                    452:                nonstandard => $$details{$num}{'nonstandard'},
                    453:                crscode => $$details{$num}{'coursecode'},
                    454:                clonecourse => $$details{$num}{'clonecrs'},
                    455:                clonedomain => $$details{$num}{'clonedom'},
                    456:                crsid => $$details{$num}{'optional_id'},
                    457:                curruser => $$details{$num}{'owner'},
                    458:                crssections => $sectionstr,
                    459:                crsxlist => $xliststr,
                    460:                autoadds => $$details{$num}{'adds'},
                    461:                autodrops => $$details{$num}{'drops'},
                    462:                notify => $$details{$num}{'notify_owner'},
                    463:                notify_dc => $$details{$num}{'notify_dc'},
                    464:                no_end_date => $noenddate,
                    465:                showphotos => $$details{$num}{'showphotos'},
                    466:                authtype => $$details{$num}{'authtype'},
                    467:                autharg => $$details{$num}{'authparam'},
                    468:                enrollstart => $$details{$num}{'enrollstart'},
                    469:                enrollend => $$details{$num}{'enrollend'},
                    470:                startaccess => $$details{$num}{'accessstart'},
                    471:                endaccess => $$details{$num}{'accessend'},
                    472:                setpolicy => $Sdetails{$num}{'setpolicy'},
                    473:                setcontent => $$details{$num}{'setcontent'},
                    474:                reshome => $reshome,
                    475:                setkeys => $$details{$num}{'setkeys'},
                    476:                keyauth => $$details{$num}{'keyauth'},
                    477:                disresdis => $$details{$num}{'disresdis'},
                    478:                disablechat => $$details{$num}{'disablechat'},
                    479:                openall => $$details{$num}{'openall'},
                    480:                firstres => $firstres
                    481:                };
                    482: 
                    483:         my %host_servers = &Apache::loncommon::get_library_servers($cdom);
                    484:         if (! exists($host_servers{$$details{$num}{'coursehome'}})) {
                    485:             $$logmsg .= &mt('Invalid home server for course').': '.$$details{$num}{'coursehome'};
                    486:             return;
                    487:         }
                    488: 
1.3       raeburn   489:         &Apache::loncreatecourse::construct_course($courseargs,$logmsg,\$courseid,\$crsudom,\$crsunum,$udom,$uname);
1.1       raeburn   490:     } else {
                    491:         return;
                    492:     }
                    493:     
                    494: #
                    495: # Make owner a course coordinator
                    496: #
                    497:     if (($owner_domain) && ($owner_uname)) {
                    498:         &Apache::lonnet::assignrole($owner_domain,$owner_uname,$courseid,'cc');
                    499:     }
                    500: 
                    501: #
                    502: # Process other reqested users
                    503: #
                    504:     my $stulogmsg = '';
                    505:     foreach my $userkey (sort keys %{$$details{$num}{'users'}}) {
                    506:         my $url = '/'.$crsudom.'/'.$crsunum;
                    507:         if (@{$$details{$num}{'users'}{$userkey}{'roles'}} > 0) {
                    508:             my ($username,$userdom) = split/:/,$userkey;
                    509:             if (&Apache::lonnet::homeserver($username,$userdom) eq 'no_host') { # Add user if no account
                    510:                 my $firstrole = $$details{$num}{'users'}{$userkey}{'roles'}[0];
                    511:                 my $firssec = $$details{$num}{'users'}{$userkey}{$firstrole}{'usec'}[0];
1.5       raeburn   512:                 my $userargs = {
                    513:                     'auth' => $$details{$num}{'users'}{$userkey}{'authtype'},
                    514:                     'authparam' => $$details{$num}{'users'}{$userkey}{'autharg'},
1.1       raeburn   515:                     'emailenc' => $$details{$num}{'users'}{$userkey}{'emailenc'},
                    516:                     'dom' => $userdom,
                    517:                     'uname' => $username,
                    518:                     'pid' => $$details{$num}{'users'}{$userkey}{'studentID'},
                    519:                     'first' => $$details{$num}{'users'}{$userkey}{'first'},
                    520:                     'middle' => $$details{$num}{'users'}{$userkey}{'middle'},
                    521:                     'last' => $$details{$num}{'users'}{$userkey}{'last'},
                    522:                     'gene' => $$details{$num}{'users'}{$userkey}{'gene'},
                    523:                     'usec' => $firstsec,
                    524:                     'end' => $$details{$num}{'users'}{$userkey}{'end'},
                    525:                     'start' => $$details{$num}{'users'}{$userkey}{'start'},
                    526:                     'emailaddr' => $$details{$num}{'users'}{$userkey}{'email'},
                    527:                     'cid' => $courseid,
                    528:                     'context' => 'createcourse',
                    529:                     'linefeed' => $linefeed,
                    530:                     'role' => $$details{$num}{'users'}{$userkey}{'roles'}[0], 
1.5       raeburn   531:                    };
1.6     ! raeburn   532:                 $outcome = &LONCAPA::Enrollment::create_newuser($userargs,$logmsg,$newusermsg,$enrollcount,$addresult,$longroles,\%courseinfo);
1.1       raeburn   533: # now add other roles and other sections.
                    534:                 if ($outcome eq 'ok') {
                    535:                     if (($firstrole ne 'st') && (@{$$details{$num}{'users'}{$userkey}{$firstrole}{'usec'}} > 1)) {
                    536:                         for (my $i=1; $i<@{$$details{$num}{'users'}{$userkey}{$firstrole}{'usec'}}; $i++) {
                    537:                             my $curr_role = $firstrole;
                    538:                             my $start = $$details{$num}{'users'}{$userkey}{$curr_role}{'start'};
                    539:                             my $end = $$details{$num}{'users'}{$userkey}{$curr_role}{'end'};
                    540:                             my $usec = $$details{$num}{'users'}{$userkey}{$firstrole}{'usec'}[$i];
                    541:                             $url = '/'.$crsudom.'/'.$crsunum;
                    542:                             if ($usec ne '') {
                    543:                                 $url .= '/'.$usec;
                    544:                             }
                    545:                             $$output .= &Apache::loncreateuser::commit_standardrole($userdom,$username,$url,$curr_role,$start,$end,$crsudom,$crsunum,$usec);
                    546:                         }
                    547:                     }
                    548:                     if (@{$$details{$num}{'users'}{$userkey}{'roles'}} > 1) {
                    549:                         for (my $j=1; $j<@{$$details{$num}{'users'}{$userkey}{'roles'}}; $j++) {
                    550:                             my $curr_role = $$details{$num}{'users'}{$userkey}{'roles'}[$j];
                    551:                             my $start = $$details{$num}{'users'}{$userkey}{$curr_role}{'start'};
                    552:                             my $end = $$details{$num}{'users'}{$userkey}{$curr_role}{'end'};
                    553:                             if ($curr_role eq 'st') {
                    554:                                 my $usec = $$details{$num}{'users'}{$userkey}{$curr_role}{'usec'}[0];
                    555:                                 $url = '/'.$crsudom.'/'.$crsunum;
                    556:                                 if ($usec ne '') {
                    557:                                     $url .= '/'.$usec;
                    558:                                 }
                    559:                                 $$output .= &Apache::loncreateuser::commit_studentrole(\$stulogmsg,$userdom,$username,$url,$curr_role,$start,$end,$crsudom,$crsunum,$usec);
                    560:                             } else {
                    561:                                 foreach my $usec (@{$$details{$num}{'users'}{$userkey}{$curr_role}{'usec'}}) {
                    562:                                     $url = '/'.$crsudom.'/'.$crsunum;
                    563:                                     if ($usec ne '') {
                    564:                                         $url .= '/'.$usec;
                    565:                                     }
                    566:                                     $$output .= &Apache::loncreateuser::commit_standardrole($userdom,$username,$url,$curr_role,$start,$end,$crsudom,$crsunum,$usec);
                    567:                                 }
                    568:                             }
                    569:                         }
                    570:                     }
                    571:                 }
                    572:             } else {
                    573:                 foreach my $curr_role (@{$$details{$num}{'users'}{$userkey}{'roles'}}) {
                    574:                     my $start = $$details{$num}{'users'}{$userkey}{$curr_role}{'start'};
                    575:                     my $end = $$details{$num}{'users'}{$userkey}{$curr_role}{'end'};
                    576:                     if ($curr_role eq 'st') {
                    577:                         my $usec = $$details{$num}{'users'}{$userkey}{$curr_role}{'usec'}[0];
                    578:                         $url = '/'.$crsudom.'/'.$crsunum;
                    579:                         if ($usec ne '') {
                    580:                             $url .= '/'.$usec;
                    581:                         }
                    582:                         $$output .= &Apache::loncreateuser::commit_studentrole(\$stulogmsg,$userdom,$username,$url,$curr_role,$start,$end,$crsudom,$crsunum,$usec);
                    583:                     } else {
                    584:                         if (@{$$details{$num}{'users'}{$userkey}{$curr_role}{'usec'}} > 0) {
                    585:                             foreach my $usec (@{$$details{$num}{'users'}{$userkey}{$curr_role}{'usec'}}) {
                    586:                                 $url = '/'.$crsudom.'/'.$crsunum;
                    587:                                 if ($usec ne '') {
                    588:                                     $url .= '/'.$usec;
                    589:                                 }
1.5       raeburn   590:                                 my $stdresult = &Apache::loncreateuser::commit_standardrole($userdom,$username,$url,$curr_role,$start,$end,$crsudom,$crsunum,$usec);
                    591:                                 $$output .= $stdresult;
1.1       raeburn   592:                             }
                    593:                         } else {
1.5       raeburn   594:                             $url = '/'.$crsudom.'/'.$crsunum;
1.1       raeburn   595:                             $$output .= &Apache::loncreateuser::commit_standardrole($userdom,$username,$url,$curr_role,$start,$end,$crsudom,$crsunum,'');
                    596:                         }
                    597:                     }
                    598:                 }
                    599:             }
                    600:         }
                    601:     }
                    602: 
                    603: # Information about keys.
                    604:     if ($$details{$num}{'setkeys'}) {
                    605:         $$keysmsg .=
                    606:  '<a href="/adm/managekeys?cid='.$crsudom.'_'.$crsunum.'">'.&mt('Manage Access Keys').'</a> for '.$$details{$num}{'title'}.$linefeed;
                    607:     }
                    608: # Flush the course logs so reverse user roles immediately updated
                    609:     &Apache::lonnet::flushcourselogs();
                    610:     return $courseid;
                    611: }
                    612: 
                    613: #########################################################
                    614: #
                    615: # process_date()
                    616: # 
                    617: # input - date/time string in format YYYY:MM:DD:HH:MM:SS (:separators required).
                    618: # output - corresponding UNIX time (seconds since epoch). 
                    619: #
                    620: #########################################################
                    621: 
                    622: sub process_date {
                    623:     my $timestr = shift;
                    624:     my $timestamp = '';
1.5       raeburn   625:     if ($timestr !~ /:/) {
1.1       raeburn   626:         $timestamp = '';
                    627:     } else {
                    628:         my @entries = split/:/,$timestr;
                    629:         for (my $j=0; $j<@entries; $j++) {
                    630:             if ( length($entries[$j]) > 1 ) {
                    631:                 $entries[$j] =~ s/^0//;
                    632:             }
                    633:         }
1.5       raeburn   634:         if ($entries[1] > 0) {  
                    635:             $entries[1] = $entries[1] - 1;
                    636:         }
1.1       raeburn   637:         $timestamp =  timelocal($entries[5],$entries[4],$entries[3],$entries[2],$entries[1],$entries[0]);
                    638:     }
                    639:     return $timestamp;
                    640: }
                    641: 
                    642: 1;

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.