--- loncom/enrollment/localenroll.pm 2003/12/05 17:03:05 1.1 +++ loncom/enrollment/localenroll.pm 2006/02/07 04:54:17 1.11 @@ -1,90 +1,338 @@ +# functions to glue school database system into Lon-CAPA for +# automated enrollment +# $Id: localenroll.pm,v 1.11 2006/02/07 04:54:17 raeburn Exp $ +# +# Copyright Michigan State University Board of Trustees +# +# This file is part of the LearningOnline Network with CAPA (LON-CAPA). +# +# LON-CAPA is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# LON-CAPA is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with LON-CAPA; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# /home/httpd/html/adm/gpl.txt +# +# http://www.lon-capa.org/ +# package localenroll; use strict; -use DBI; -use LONCAPA::Configuration; -sub fetch_enrollment { - my ($dom,$affiliatesref,$replyref) = @_; - $ENV{SYBASE} = '/usr/local/freetds'; +################################ +# sub run +# set this to return 1 if you want the auto enrollment to run +################################ + +sub run() { + my $dom = shift; + return 0; +} - my $DB_PATH = "dbi:Sybase:server=ESDB1;database=RO_ClassList"; - my $DB_USER =""; # Not stored in CVS - my $DB_PASSWD = ""; # Not stored in CVS - - my $configvars = &LONCAPA::Configuration::read_conf('loncapa.conf'); - - my $dbh= DBI->connect($DB_PATH,$DB_USER,$DB_PASSWD); - my $dbflag = 0; - if (defined $dbh) { - $dbflag = 1; - foreach my $crs (sort keys %{$affiliatesref}) { - my $xmlfile = $$configvars{'lonDaemons'}."/tmp/".$dom."_".$crs."_classlist.xml"; - $$replyref{$crs} = &write_class_data ($dbh,$xmlfile,\@{$$affiliatesref{$crs}}); - } - $dbh->disconnect; - } - return $dbflag; -} - -sub write_class_data { - my ($dbh,$xmlfile,$coursesref) = @_; - my $stucount = 0; - open(FILE, ">$xmlfile"); - print FILE qq| - - -|; - foreach my $class (@{$coursesref}) { - if ($class =~ m/^([suf]s\d{2})(\w{2,3})(\d{3,4}\w?)(\d{3})$/) { - my $sth = $dbh->prepare("SELECT Pid,Pilot_Id,Student_Name FROM LONCAPA_ClassList WHERE Term_Code = '$1' AND Subj_Code = '$2' AND Crse_Code = '$3' AND Sctn_Code = '$4' ORDER BY Student_Name"); - $sth->execute(); - while ( my($pid,$pilot,$name) = $sth->fetchrow_array ) { - $stucount ++; - $name =~ s/^\s//g; - $name =~ s/\s$//g; - my ($last,$given,$first,$middle); - $last = substr($name,0,index($name,",")); - $given = substr($name,index($name,",")+1); - $given =~ s/^\s//g; - if ($given =~ m/\w\s\w/) { - $first = substr($given,0,index($given," ")); - $middle = substr($given,index($given," ")+1); - $middle =~ s/\s//g; - } else { - $first = $given; - } - $first =~ s/\s$//g; - print FILE qq| - MSU.EDU - krb4 - $pilot\@msu.edu - - $first - - $class - $last - $middle - - $pid - -|; -# Format for startdate is YYYY:MM:DD:HH:MM:SS -# Format forenddate is YYYY:MM:DD:HH:MM:SS -# Authentication is one of: krb4, krb5, int or loc -# Password is either the password for int, or Kerberos domain (for krb4 or krb5), or argument (for loc). -# If authentication, password, startdate or enddate are blank, the default for the course is used. These defaults can be modified using the Automated Enrollment Manager. - } - $sth->finish; - } - } - print FILE qq||; - close(FILE); - return $stucount; +################################ +# sub fetch_enrollment +# +# connects to the institutional classlist data source, +# reads classlist data and stores in an XML file +# in /home/httpd/perl/tmp/ +# +# classlist files are named as follows: +# +# DOMAIN_COURSE_INSTITUTIONALCODE_classlist.xml +# +# e.g., msu_43551dedcd43febmsul1_fs03nop590001_classlist.xml +# where DOMAIN = msu COURSE = 43551dedcd43febmsul1 +# INSTITUTIONALCODE = fs03nop590001 +# (MSU's course naming scheme - fs03 = Fall semester 2003, nop = +# department name, 590 = course number, 001 = section number.) +# +# fetch_enrollment requires three arguments - +# $dom - DOMAIN e.g., msu +# $affiliatesref - a reference to a hash of arrays that contains LON-CAPA +# courses that are to be updated as keys, and institutional coursecodes +# contributing enrollment to that LON-CAPA course as elements in each array. +# $replyref - a reference to a hash that contains LON-CAPA courses +# that are to be updated as keys, and the total enrollment count in all +# affiliated sections, as determined from institutional data as hash elements. +# +# As an example, if fetch_enrollment is called to retrieve institutional +# classlists for a single LON-CAPA course - 43551dedcd43febmsul1 which +# corresponds to fs03nop590, sections 001, 601 and 602 , and the course +# also accommodates enrollment from a crosslisted course in the ost +# department - fs03ost580002: +# +# the affiliatesref would be a reference to %affiliates which would be: +# +# @{$affiliates{'43551dedcd43febmsul1'}} = +# ("fs03nop590001","fs03nop590601","fs03nop590602","fs03ost580002"); +# +# fetch_enrollment would create four files in /home/httpd/perl/tmp/. +# msu_43551dedcd43febmsul1_fs03nop590001_classlist.xml +# msu_43551dedcd43febmsul1_fs03nop590601_classlist.xml +# msu_43551dedcd43febmsul1_fs03nop590602_classlist.xml +# msu_43551dedcd43febmsul1_fs03ost580002_classlist.xml +# +# In each file, student data would be stored in the following format +# +# +# MSU.EDU +# krb4 +# smith@msu.edu +# +# John +# II +# fs03nop590001 +# Smith +# D +# +# A12345678 +# +# +# with the following at the top of the file +# +# +# +# +# (all comment - #s removed) +# +# and a closing: +# +# +# The and the are the activation date and expiration date +# for this student's role. If they are absent, then the default access start and +# default access end dates are used. The default access dates can be set when +# the course is created, and can be modified using the Automated Enrollment +# Manager, or via the 'Upload a class list','Enroll a single student' or +# 'Modify student data' utilities in the Enrollment Manager, by checking the +# 'make these dates the default for future enrollment' checkbox. If no default +# dates have been set, then the tudent role will be active immediately, and will +# remain active until the role is explicitly expired using ENRL -> Drop students. +# If dates are to included in the XML file, they should be in the format +# YYYY:MM:DD:HH:MM:SS (: separators required). +# +# If there were 10 students in fs03nop590001, 5 students in fs03nop59o601, +# 8 students in fs03nop590602, and 2 students in fs03ost580002, +# then $$reply{'43551dedcd43febmsul1'} = 25 +# +# The purpose of the %reply hash is to detect cases where the institutional +# enrollment is 0 (most likely due to a problem with the data source). +# In such a case, the LON-CAPA course roster is left unchanged (i.e., no +# students are expired, even if automated drops is enabled. +# +# fetch_enrollment should return a 0 or 1, depending on whether a connection +# could be established to the institutional data source. +# 0 is returned if no connection could be made. +# 1 is returned if connection was successful +# +# A return of 1 is required for the calling modules to perform LON-CAPA +# roster changes based on the contents of the XML classlist file(s), e,g,, +# msu_43551dedcd43febmsul1_fs03nop590001_classlist.xml +# +# XML classlist files are temporary. They are deleted after the enrollment +# update process in the calling module is complete. +# +################################ + +sub fetch_enrollment { + my ($dom,$affiliatesref,$replyref) = @_; + foreach my $crs (sort keys %{$affiliatesref}) { + $$replyref{$crs} = 0; + } + my $okflag = 0; + return $okflag; } +############################### +# sub get_sections +# +# This is called by the Automated Enrollment Manager interface +# (lonpopulate.pm) to create an array of valid sections for +# a specific institutional coursecode. +# e.g., for MSU coursecode: fs03nop590 +# ("001","601","602") would be returned +# +# If the array returned contains at least one element, then +# the interface offerred to the course coordinator, lists +# official sections and provides a checkbox to use to +# select enrollment in the LON-CAPA course from each official section. +# +# get_sections takes two arguments - (a) the institutional coursecode +# (in the MSU case this is a concatenation of semester code, department +# and course number), and (b) the LON-CAPA domain that contains the course. +# +# If there is no access to official course sections at your institution, +# then an empty array is returned, and the Automated Enrollment Manager +# interface will allow the course coordinator to enter section numbers +# in text boxes. +# +############################### + sub get_sections { + my ($coursecode,$dom) = @_; + my @secs = (); + return @secs; +} + +############################### +# sub new_course +# +# This is called by loncreatecourse.pm and +# lonpopulate.pm to record that fact that a new course section +# has been added to LON-CAPA that requires access to institutional data +# At MSU, this is required, as institutional classlists can only made +# available to faculty who are officially assigned to a course. +# +# The new_course subroutine is used to check that the course owner +# of the LON-CAPA course is permitted to access the institutional +# classlist for any course sections and crosslisted classes that +# the course coordinator wishes to have affiliated with the course. +# +# If access is permitted, then 'ok' is returned. +# The course section or crosslisted course will only be added to the list of +# affiliates if 'ok' is returned. +# +# new_course takes three arguments - +# (a) the institutional courseID (in the MSU case this is a concatenation of +# semester code, department code, course number, and section number +# e.g., fs03nop590001). +# (b) the course owner. This is the LON-CAPA username of the course coordinator +# assigned to the course when it is first created. +# (c) the LON-CAPA domain that contains the course +# +################################# + +sub new_course { + my ($course_id,$owner,$dom) = @_; + my $outcome = 'ok'; + return $outcome; +} + +############################### +# sub validate_courseID +# +# This is called whenever a new course section or crosslisted course +# is being affiliated with a LON-CAPA course (i.e., by loncreatecourse.pm +# and the Automated Enrollment Manager in lonpopulate.pm). +# A check is made that the courseID that the course coordinator wishes +# to affiliate with the course is valid according to the institutional +# schedule of official classes +# +# A valid courseID is confirmed by returning 'ok' +# +# validate_courseID takes two arguments - +# (a) the institutional courseID (in the MSU case this is a concatenation of +# semester code, department code, course number, and section number +# e.g., fs03nop590001). +# (b) the LON-CAPA domain that contains the course +# +############################### + +sub validate_courseID { + my ($course_id,$dom) = @_; + my $outcome = 'ok'; + return $outcome; +} + +############################### +# sub create_password +# +# This is called when the authentication method set for the automated +# enrollment process when enrolling new users in the domain is "localauth". +# This could be signalled for the specific user by the value of localauth +# for the tag from the classlist.xml files, or if this is blank, +# the default authtype, set by the domain coordinator when creating the course +# with loncreatecourse.pm. +# +# create_password takes three arguments - +# (a) $authparam - the value of from the classlist.xml files, +# or if this blank, the default autharg, set by the domain coordinator when +# creating the course with loncreatecourse.pm +# (b) $username - the username of the new user +# (b) $dom - the domain of the new user. +# +# Four values are returned: +# (a) the value of $authparam - which might have been changed +# (b) a flag to indicate whether a password had been created +# 0 means no password created +# 1 means password created. In this case the calling module - Enrollment.pm +# will send the LON-CAPA username and password to the new user's e-mail +# (if one was provided), or to the course owner (if one was not provided and +# the new user was created by the automated process), or to the active +# course coordinator (if the new user was created using the 'update roster +# now' interface included in the Automated Enrollment Manager). +# (c) a flag to indicate that the authentication method is correct - 'ok'. +# If $authchk is not set to 'ok' then account creation and enrollment of the +# new user will not occur. +# (d) if a password was created it can be sent along. This is the password +# which will be included in the e-mail sent to the new user, or made available +# to the course owner/course coordinator if no e-mail address is provided. If +# you do not wish to send a password, but want to give instructions on obtaining +# one, you could set $newpasswd as those instructions. (e.g., +# $newpasswd = '(Please visit room 212, ACNS Bldg. to obtain your password)'; +# The value of $newpasswd is NOT written in the user's LON-CAPA passwd file in +# /home/httpd/lonUsers/$dom/a/b/c/abcuser/passwd, which in the case of a user +# employing localauth will contain 'localauth:$authparam'. If you need to include +# a parameter in the user's passwd file, you should return it as $authparam, +# i.e., the first of the variables returned by create_password(). +############################### + +sub create_password { + my ($authparam,$username,$dom) = @_; + my $authchk = 'ok'; + my $newpasswd = ''; + my $create_passwd = 0; + return ($authparam,$create_passwd,$authchk,$newpasswd); +} + +############################### +# sub instcode_format +# +# Split coursecodes into constituent parts. +# e.g., INSTITUTIONALCODE = fs03nop590, LON-CAPA COURSEID: 43551dedcd43febmsul1 +# (MSU's course naming scheme - fs03 = Fall semester 2003, nop = +# department name, 590 = course number) +# +# Incoming data: +# $dom (domain) +# $$instcodes{'43551dedcd43febmsul1'} = 'Title of course' (hash of courseIDs) +# +# fs03nop590 would be split as follows +# @{$codetitles} = ("year","semester","department","number") +# $$codes{{'year'} = '2003' +# $$codes{'semester'} = 'Fall' +# $$codes{'department'} = 'nop' +# $$codes{'number'} = '590' +# +# requires six arguments: +# domain ($dom) +# reference to hash of institutional course IDs ($instcodes) +# reference to hash of codes ($codes) +# reference to array of titles ($codetitles) +# reference to hash of abbreviations used in categories +# reference to hash of arrays specifying sort order used in category titles +# +# e.g., %{$$cat_titles{'Semester'}} = ( +# fs => 'Fall', +# ss => 'Spring', +# us => 'Summer'); +# +# e.g., @{$$cat_order{'Semester'}} = ('ss','us','fs'); +# returns 1 parameter: 'ok' if no processing errors. +############################### +sub instcode_format () { + my ($dom,$instcodes,$codes,$codetitles,$cat_titles,$cat_order) = @_; + my $outcome = 'ok'; + return $outcome; } 1;