#!/usr/local/bin/webwork-perl #################################################################### # Copyright @ 1995-1999 University of Rochester # All Rights Reserved #################################################################### BEGIN { my $useLibDir = '.'; if ($0 =~ m|^(/.*)/|) { $useLibDir = $1; } elsif ($0 =~ m|^(\..*)/|) { $useLibDir = $1; } elsif ($0 =~ m|^(.+)/|) { $useLibDir = "./$1"; } unshift @INC, $useLibDir; } use webworkInit; # WeBWorKInitLine use Global; use Auth; use strict; use GDBM_File; if (@ARGV != 2) { print "\nSyntax is import_classlist-database.pl courseID textCL_Database\n"; print " (e.g. import_classlist-database.pl demoCourse textDataBase)\n\n"; exit(0); } sub getAns { my $ans = ; $ans =~ s/^\s*//; $ans = substr($ans, 0, 1); return lc($ans); } print qq{ This command line script will create a classlist database from a classlist file. It should only be used if no classlist database exists which means that you can not log into the course. Usually this only occurs when setting up the demoCourse for a new WeBWorK system. The most standard procedure for creating other new courses is to copy an existing course (e.g. the demoCourse) and in the process you copy the classlist database also. If you want to update (or even replace) an existing claslist database with data from a classlist file, go to the classlist page from the Professor page and use the web based "Import the classlist database from a classlist file". That procedure gives you much more control over how information is updated. This command line script will totally replace the classlist database (if it exists) with data from the classlist file. Do you wish to continue with the command line script \? (y or n) }; exit(0) if &getAns ne 'y'; my $course = $ARGV[0]; my $textCL_Database = $ARGV[1]; # establish environment for this script &Global::getCourseEnvironment($course); # Directory paths my $databaseDirectory = getCourseDatabaseDirectory(); my $scriptDirectory = getWebworkScriptDirectory(); my $passwordFile = &Global::getCoursePasswordFile($course); my $permissionsFile = &Global::getCoursePermissionsFile($course); my $DELIM = $Global::delim; # File names require "${scriptDirectory}$Global::classlist_DBglue_pl"; # require "${scriptDirectory}$Global::HTMLglue_pl"; require "${scriptDirectory}$Global::FILE_pl"; my $msg = buildClasslistDB($course,$textCL_Database); print $msg; $msg = initial_passwords(); print $msg; exit; ## end of main script sub buildClasslistDB { ## builds the classlist DB and returns a message my ($classID,$classlistFilename) = @_; my $scriptDirectory = $Global::scriptDirectory; &Global::getCourseEnvironment("$classID"); my $databaseDirectory = $Global::databaseDirectory; my $templateDirectory = $Global::templateDirectory; my $CL_Database = $Global::CL_Database; my $path_to_CL_DB = "${databaseDirectory}$CL_Database"; require "${scriptDirectory}$Global::DBglue_pl"; require "${scriptDirectory}$Global::classlist_DBglue_pl"; require "${scriptDirectory}$Global::FILE_pl"; #get data from class list. my $fileName="${templateDirectory}$classlistFilename"; ## e.g. fileName=m161.lst my $message = "\nGetting class list from $fileName\n"; checkClasslistFile($Global::noOfFieldsInClasslist,$fileName); open(FILE, "$fileName") || wwerror($0, "Can't open $fileName"); my @classList=; close(FILE); ################################### # Before building the database we pause to check that the database file exists. # If so, we back it up # (if not we create it). ################################### if ( -e "$path_to_CL_DB" ) { my $CL_status = get_CL_database_status(); wwerror("Classlist Database is unlocked", "You must lock the classlist database (or move it) before you can import a new claslist database.") unless $CL_status eq 'locked'; $message .= "Backing up current class list data base: $path_to_CL_DB\n\n"; &backup($path_to_CL_DB); } $message .= "Creating new data base $path_to_CL_DB .\n"; create_db("$path_to_CL_DB", $Global::webwork_database_permission); if ( -e "$path_to_CL_DB" ) { chmod($Global::webwork_database_permission,"$path_to_CL_DB") || wwerror($0, "Can't do chmod($Global::webwork_database_permission,$path_to_CL_DB)"); chown(-1,$Global::numericalGroupID,"$path_to_CL_DB") || wwerror($0,"Can't do chown(-1,$Global::numericalGroupID,$path_to_CL_DB)"); $message .= "New classlist data base created\n"; } else { wwerror($0,"New classlist data base $path_to_CL_DB could not be created."); } # my $WW_DB_exists = 0; # $WW_DB_exists = 1 if ( -e "${databaseDirectory}$Global::database" ); # # my %loginName_StudentID_Hash_from_WW_DB; # my %studentID_LoginName_Hash_from_WW_DB; # # if ($WW_DB_exists) { # %loginName_StudentID_Hash_from_WW_DB =%{getLoginName_StudentID_Hash_from_WW_DB()}; # %studentID_LoginName_Hash_from_WW_DB = reverse %loginName_StudentID_Hash_from_WW_DB; # } foreach (@classList) { ## read through classlist and create ## class list database unless ($_ =~ /\S/) {next;} ## skip blank lines chomp; my @classListRecord=&getRecord($_); my ($studentID, $lastName, $firstName, $status, $comment, $section, $recitation, $email_address, $login_name) = @classListRecord; # if (($WW_DB_exists) and (defined $loginName_StudentID_Hash_from_WW_DB{$login_name}) # and ($loginName_StudentID_Hash_from_WW_DB{$login_name} ne $studentID)) { # $message .= "\n $firstName $lastName, $login_name, $studentID HAS NOT BEEN ENTERED # IN THE CLASSLIST DATABASE because of a conflict with entries in the WeBWorK problem set database. # Enter this information again from the Add Student(s) Page to get a more detailed error message # and instructions on how to correct the problem."; # next; # } # # if (($WW_DB_exists) and (defined $studentID_LoginName_Hash_from_WW_DB{$studentID}) # and ($studentID_LoginName_Hash_from_WW_DB{$studentID} ne $login_name)) { # $message .= "\n$firstName $lastName, $login_name, $studentID HAS NOT BEEN ENTERED IN THE CLASSLIST DATABASE # because of a conflict with entries in the WeBWorK problem set database. # Enter this information again from the Add Student(s) Page to get a more detailed error message # and instructions on how to correct the problem.\n"; # next; # } &CL_putStudentID ($studentID, $login_name); &CL_putStudentLastName ($lastName, $login_name); &CL_putStudentFirstName ($firstName, $login_name); &CL_putStudentStatus ($status, $login_name); &CL_putComment ($comment, $login_name); &CL_putClassSection ($section,$login_name); &CL_putClassRecitation ($recitation,$login_name); &CL_putStudentEmailAddress ($email_address, $login_name); &saveCLRecord($login_name); } unlock_CL_database(); $message; } sub backup { ## takes as a parameter the full path name ## makes upto two backups of the file with _bak1, or _bak2 ## appended to filename where _bak1 is the most recent backup my $fileName =$_[0]; if (-e "${fileName}_bak1") { rename("${fileName}_bak1","${fileName}_bak2") or &wwerror("$0","can't rename ${fileName}_bak1"); } if (-e "${fileName}") { rename("${fileName}","${fileName}_bak1") or &wwerror("$0","can't rename ${fileName}"); } } sub initial_passwords { my %studentsinclass=(); my @classListRecord=(); my $msg =''; # Check that the files exist: # The permissions file must exist and have both read and write privilages. # The permissions file must exist and have both read and write privilages. unless ( -r "${databaseDirectory}$Global::CL_Database" ) { wwerror ($0, "Can't read the class list database file ${databaseDirectory}$Global::CL_Database"); } unless ( -e $permissionsFile) { &create_db($permissionsFile,$Global::standard_tie_permission); $msg .= "Permissions file does not exist.\n Creating permissions file:\n $permissionsFile\n"; } unless ( -e $passwordFile) { &create_db($passwordFile,$Global::standard_tie_permission); $msg .= "Password file does not exist.\n Creating password file:\n $passwordFile\n"; } unless ( -r $passwordFile and -w $passwordFile) { wwerror ($0, "Permissions set incorrectly on $passwordFile or its directory. Cannot access file to both read and write."); } unless ( -r $permissionsFile and -w $permissionsFile) { wwerror ($0, "Permissions set incorrectly on $permissionsFile or its directory. Cannot access file to both read and write."); } my $login_name; $msg .= "\nLoading classlist database: ${databaseDirectory}$Global::CL_Database\n\n"; my @classList = @{getAllLoginNames()}; $msg .= "\n Modifying the password file :\n $passwordFile\n\n"; foreach $login_name (@classList) { ## read through classlist database and create ## problems for all active students ## except if problems already exist for attachCLRecord($login_name); ## student my $status = CL_getStudentStatus($login_name); my $studentID = CL_getStudentID($login_name); $studentsinclass{$login_name}++ unless(&dropStatus($status)); if(&dropStatus($status)) { $msg .= " $login_name not added because status is $status\n"; } elsif (&get_password($login_name, $passwordFile)) { $msg .= " $login_name not added because password already exists\n"; } else { &new_password($login_name, $studentID, $passwordFile); &put_permissions(0,$login_name,$permissionsFile); $msg .= "added: $login_name, $studentID\n"; } } my @pwStudents = &get_keys_from_db($passwordFile); my ($ans,$student); $msg .= "\n The following login's (if any) in the password and permissions databases are either\n"; $msg .= " (1) not listed in the class list database file \n"; $msg .= " ${databaseDirectory}$Global::CL_Database or\n"; $msg .= " (2) have DROP status in the class list database file.\n"; $msg .= "They will all be removed from the password and permissions databases.\n\n"; foreach $student (@pwStudents) { next if defined($studentsinclass{$student}); &delete_password($student,$passwordFile); &delete_permissions($student,$permissionsFile); $msg .= " $student removed from password and permissions databases\n"; } ## if the owner of the password file is running this script (e.g. when the password file is first created) ## set the permissions correctly open (PASSWORDFILE, "$passwordFile") or wwerror($0, "Can't open $passwordFile"); my @stat = stat PASSWORDFILE; close PASSWORDFILE; if ($< == $stat[4]) { chmod($Global::password_permission, $passwordFile) or wwerror($0, "Can't do chmod($Global::password_permission, $passwordFile)"); chown(-1,$Global::numericalGroupID,$passwordFile) or wwerror($0, "Can't do chown(-1,$Global::numericalGroupID,$passwordFile)"); } open (PERMISSIONSFILE, "$permissionsFile") or wwerror($0, "Can't open $permissionsFile"); @stat = stat PERMISSIONSFILE; close PERMISSIONSFILE; if ($< == $stat[4]) { chmod($Global::permissions_permission, $permissionsFile) or wwerror($0, "Can't do chmod($Global::permissions_permission, $permissionsFile)"); chown(-1,$Global::numericalGroupID,$permissionsFile) or wwerror($0, "Can't do chown(-1,$Global::numericalGroupID,$permissionsFile)"); } $msg; }