[system] / trunk / webwork / system / cgi / cgi-scripts / profImportClasslistDatabase.pl Repository:
ViewVC logotype

Annotation of /trunk/webwork/system/cgi/cgi-scripts/profImportClasslistDatabase.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6 - (view) (download) (as text)

1 : gage 6 #!/usr/local/bin/perl
2 : sam 2
3 :     ## This file is profExportClasslistDatabase.pl
4 :     ##
5 :    
6 :     ####################################################################
7 :     # Copyright @ 1995-2000 University of Rochester
8 :     # All Rights Reserved
9 :     ####################################################################
10 :    
11 : gage 6 use lib '/ww/webwork/gage_system/webwork/system/lib/'; # mainWeBWorKDirectory
12 : sam 2 use CGI qw(:standard);
13 :     use Global;
14 :     use Auth;
15 :     use strict;
16 :     use GDBM_File;
17 :    
18 :     my $cgi = new CGI;
19 :     my %inputs = $cgi->Vars();
20 :    
21 :     # get information from CGI inputs (see also below for additional information)
22 :    
23 :     my $Course = $inputs{'course'};
24 :     my $User = $inputs{'user'};
25 :     my $Session_key = $inputs{'key'};
26 :    
27 :     # verify that information has been received
28 :     unless($Course && $User && $Session_key) {
29 :     &wwerror("$0","The script did not receive the proper input data.","","");
30 :     }
31 :    
32 :     # establish environment for this script
33 :    
34 :     &Global::getCourseEnvironment($Course);
35 :    
36 :    
37 :     my $scriptsDirectory = getWebworkScriptDirectory;
38 :     my $databaseDirectory = getCourseDatabaseDirectory;
39 :     my $templateDirectory = getCourseTemplateDirectory;
40 :     my $cgiURL = getWebworkCgiURL;
41 :     my $CL_Database = $Global::CL_Database;
42 :     my $path_to_CL_DB = "${databaseDirectory}$CL_Database";
43 :     # File names
44 :    
45 :     require "${scriptsDirectory}$Global::HTMLglue_pl";
46 :     require "${scriptsDirectory}$Global::DBglue_pl";
47 :     require "${scriptsDirectory}$Global::classlist_DBglue_pl";
48 :     require "${scriptsDirectory}$Global::FILE_pl";;
49 :     my $DELIM = $Global::delim;
50 :    
51 :     # log access
52 :     &Global::log_info('', query_string);
53 :    
54 :     my $passwordFile = &Global::getCoursePasswordFile($Course);
55 :     my $permissionsFile = &Global::getCoursePermissionsFile($Course);
56 :     my $permissions = &get_permissions($inputs{'user'}, $permissionsFile);
57 :     my $keyFile = &Global::getCourseKeyFile($Course);
58 :    
59 :     #verify session key
60 :     &verify_key($inputs{'user'}, $inputs{'key'}, $keyFile, $Course);
61 :    
62 :     # verify permissions are correct
63 :     if ($permissions != $Global::instructor_permissions ) {
64 :     print "permissions = $permissions instructor_permissions = $Global::instructor_permissions\n";
65 :     print &html_NO_PERMISSION;
66 :     exit(0);
67 :     }
68 :     # get the rest of the information from the submitted form
69 :    
70 :     my $classlistFilename = $inputs{'classList'};
71 :     my $update_firstName = $inputs{'update_firstName'};
72 :     my $update_lastName = $inputs{'update_lastName'};
73 :     my $update_status = $inputs{'update_status'};
74 :     my $update_comment = $inputs{'update_comment'};
75 :     my $update_section = $inputs{'update_section'};
76 :     my $update_recitation = $inputs{'update_recitation'};
77 :     my $update_email_address = $inputs{'update_email_address'};
78 :     my $update_drop = $inputs{'update_drop'}; ## either 'drop', 'leave', or 'remove'
79 :    
80 :     $update_firstName = 0 unless defined $update_firstName;
81 :     $update_lastName = 0 unless defined $update_lastName;
82 :     $update_status = 0 unless defined $update_status;
83 :     $update_comment = 0 unless defined $update_comment;
84 :     $update_section = 0 unless defined $update_section;
85 :     $update_recitation = 0 unless defined $update_recitation;
86 :     $update_email_address = 0 unless defined $update_email_address;
87 :    
88 :     my $CL_status = get_CL_database_status();
89 :     wwerror('Classlist Database is unlocked', 'You must go back and lock the classlist database
90 :     before you can export it to an ascii file.') unless $CL_status eq 'locked';
91 :    
92 :     wwerror('No classlist file selected', 'You must go back and select a classlist file.')
93 :     unless $classlistFilename =~ /\w/;
94 :    
95 :     my $msg1 = updateClasslistDB($classlistFilename);
96 :    
97 :     my $msg2 = initial_passwords();
98 :    
99 :     my $msg3 = "$msg1" . "$msg2";
100 :    
101 :     uploadSuccess("$msg3");
102 :    
103 :     exit; ## end of main script
104 :    
105 :     sub updateClasslistDB { ## builds the classlist DB and returns a message
106 :    
107 :     my ($classlistFilename) = @_;
108 :    
109 :     #get data from class list.
110 :     my $fileName="${templateDirectory}$classlistFilename"; ## e.g. fileName=m161.lst
111 :    
112 :     my $message = "\nGetting classlist file from: $fileName <BR>\n";
113 :     checkClasslistFile($Global::noOfFieldsInClasslist,$fileName);
114 :     open(FILE, "$fileName") || wwerror($0, "Can't open $fileName");
115 :     my @classList=<FILE>;
116 :     close(FILE);
117 :    
118 :     ###################################
119 :     # Before updating the database we back it up
120 :     ###################################
121 :     if ( -e "$path_to_CL_DB" ) {
122 :     $message .= "Backing up current classlist database to: ${path_to_CL_DB}_bak1 <BR>\n";
123 :     &backup($path_to_CL_DB);
124 :     }
125 :    
126 :     my %loginName_StudentID_Hash = %{getLoginName_StudentID_Hash()};
127 :     my %studentID_LoginName_Hash =%{getStudentID_LoginName_Hash()};
128 :    
129 : gage 6 # my $WW_DB_exists = 0;
130 :     # $WW_DB_exists = 1 if ( -e "${databaseDirectory}$Global::database" );
131 : sam 2
132 : gage 6 # my %loginName_StudentID_Hash_from_WW_DB =();
133 :     # my %studentID_LoginName_Hash_from_WW_DB =();
134 : sam 2
135 : gage 6 # if ($WW_DB_exists) {
136 :     # %loginName_StudentID_Hash_from_WW_DB =%{getLoginName_StudentID_Hash_from_WW_DB()};
137 :     # %studentID_LoginName_Hash_from_WW_DB = reverse %loginName_StudentID_Hash_from_WW_DB;
138 :     # }
139 : sam 2
140 :     my $errors ='';
141 :     my %new_good_classlist_students =(); ## students in new classlist without conflicts
142 :     my %new_bad_classlist_students =(); ## students in new classlist with conflicts
143 :    
144 :    
145 :     foreach (@classList) { ## read through classlist and create
146 :     ## class list database
147 :     unless ($_ =~ /\S/) {next;} ## skip blank lines
148 :     chomp;
149 :     my @classListRecord=&getRecord($_);
150 :     my ($studentID, $lastName, $firstName, $status, $comment, $section, $recitation, $email_address, $login_name)
151 :     = @classListRecord;
152 :    
153 :     ## First we get a list of any conflicts with current students
154 :     if ((defined $loginName_StudentID_Hash{$login_name})
155 :     and ($loginName_StudentID_Hash{$login_name} ne $studentID)) {
156 :     $errors .= "$firstName $lastName, $login_name, $studentID <BR>\n ";
157 :     $new_bad_classlist_students{$login_name} =1;
158 :     next;
159 :     }
160 :    
161 :     if ((defined $studentID_LoginName_Hash{$studentID})
162 :     and ($studentID_LoginName_Hash{$studentID} ne $login_name)) {
163 :     $errors .= "$firstName $lastName, $login_name, $studentID <BR>\n ";
164 :     $new_bad_classlist_students{$login_name} =1;
165 :     next;
166 :     }
167 :    
168 :    
169 : gage 6
170 : sam 2 ## OK, the student record has no conflicts
171 :    
172 :     $new_good_classlist_students{$login_name} =1;
173 :    
174 :     ## Handle students already in classlist DB
175 :     if (defined $loginName_StudentID_Hash{$login_name}) {
176 :     &attachCLRecord($login_name);
177 :     &CL_putStudentLastName ($lastName, $login_name) if $update_firstName;
178 :     &CL_putStudentFirstName ($firstName, $login_name) if $update_lastName;
179 :     &CL_putStudentStatus ($status, $login_name) if $update_status;
180 :     &CL_putComment ($comment, $login_name) if $update_comment;
181 :     &CL_putClassSection ($section,$login_name) if $update_section;
182 :     &CL_putClassRecitation ($recitation,$login_name) if $update_recitation;
183 :     &CL_putStudentEmailAddress ($email_address, $login_name) if $update_email_address;
184 :     $Global::over_ride_CLBD_lock = 1;
185 :     &saveCLRecord($login_name);
186 :     $Global::over_ride_CLBD_lock = 0;
187 :    
188 : gage 6
189 :     }
190 :     else { ## Handle new students
191 : sam 2 &CL_putStudentID ($studentID, $login_name);
192 :     &CL_putStudentLastName ($lastName, $login_name);
193 :     &CL_putStudentFirstName ($firstName, $login_name);
194 :     &CL_putStudentStatus ($status, $login_name);
195 :     &CL_putComment ($comment, $login_name);
196 :     &CL_putClassSection ($section,$login_name);
197 :     &CL_putClassRecitation ($recitation,$login_name);
198 :     &CL_putStudentEmailAddress ($email_address, $login_name);
199 :     $Global::over_ride_CLBD_lock = 1;
200 :     &saveCLRecord($login_name);
201 :     $Global::over_ride_CLBD_lock = 0;
202 :     }
203 :     }
204 :    
205 :     ## Now we take care of students who are in the current classlist database but are not in
206 :     ## the classlist file.
207 :    
208 :     my %drop_list =();
209 :     my $login_name;
210 :     %loginName_StudentID_Hash = %{getLoginName_StudentID_Hash()};
211 :     foreach $login_name (keys %loginName_StudentID_Hash) {
212 :     $drop_list{$login_name} = 1 unless (
213 :     (defined ($new_good_classlist_students{$login_name})) or (defined ($new_bad_classlist_students{$login_name}))
214 :     );
215 :     }
216 :     if ($update_drop eq 'drop') {
217 :     my $status = 'D';
218 :     $status = $Global::statusDrop[0] if defined $Global::statusDrop[0];
219 :     foreach $login_name (keys %drop_list) {
220 :     &attachCLRecord($login_name);
221 :     &CL_putStudentStatus($status, $login_name);
222 :     $Global::over_ride_CLBD_lock = 1;
223 :     &saveCLRecord($login_name);
224 :     $Global::over_ride_CLBD_lock = 0;
225 :     }
226 :     }
227 :     elsif ($update_drop eq 'remove') {
228 :     foreach $login_name (keys %drop_list) {
229 :     $Global::over_ride_CLBD_lock = 1;
230 :     deleteClassListRecord($login_name);
231 :     $Global::over_ride_CLBD_lock = 0;
232 :     }
233 :     }
234 :     else { ## if this case $update_drop eq 'leave' and we do nothing
235 :     }
236 :    
237 :     unlock_CL_database();
238 :     if ($errors) {
239 :     $message .= '<BR>The following students HAVE NOT BEEN ENTERED IN THE CLASSLIST DATABASE
240 :     because of a conflict with entries in the WeBWorK problem set database or the classlist database.
241 :     These students have a studentID or a loginName that conflicts with a current student.
242 :     Enter this information again from the Add Student(s) Page to get a more detailed error message
243 :     and instructions on how to correct the problem.<BR><BR>';
244 :     $message .= "\n $errors<BR>";
245 :     }
246 :     $message;
247 :     }
248 :    
249 :     sub initial_passwords {
250 :     my %studentsinclass=();
251 :     my @classListRecord=();
252 :     my $msg ='';
253 :    
254 :     # Check that the files exist:
255 :     # The permissions file must exist and have both read and write privilages.
256 :     # The password file must exist and have both read and write privilages.
257 :    
258 :    
259 :     unless ( -r $passwordFile and -w $passwordFile) {
260 :     wwerror ($0, "Permissions set incorrectly on $passwordFile or its directory.
261 :     Cannot access file to both read and write.");
262 :     }
263 :    
264 :     unless ( -r $permissionsFile and -w $permissionsFile) {
265 :     wwerror ($0, "Permissions set incorrectly on $permissionsFile or its directory.
266 :     Cannot access file to both read and write.");
267 :     }
268 :    
269 :     my $login_name;
270 : gage 6
271 : sam 2 my @classList = @{getAllLoginNames()};
272 :    
273 :     $msg .= "\n<BR><BR> Modifying the password file :\n $passwordFile <BR>\n ";
274 :    
275 :     foreach $login_name (@classList) { ## read through classlist database and create
276 :     ## passwords for all active students
277 :     ## except if passwords already exist for student
278 :     attachCLRecord($login_name);
279 :    
280 :     my $status = CL_getStudentStatus($login_name);
281 :     my $studentID = CL_getStudentID($login_name);
282 :    
283 :     $studentsinclass{$login_name}++ unless(&dropStatus($status));
284 :    
285 :     if(&dropStatus($status)) {
286 :     $msg .= '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'."$login_name not added because status is $status <BR>\n ";
287 :     }
288 :     elsif (&get_password($login_name, $passwordFile)) {
289 :     $msg .= '&nbsp;&nbsp;&nbsp;'."$login_name not added because password already exists <BR>\n ";
290 :     }
291 :     else {
292 :     &new_password($login_name, $studentID, $passwordFile);
293 :     &put_permissions(0,$login_name,$permissionsFile);
294 :     $msg .= "added: $login_name, $studentID <BR>\n ";
295 :     }
296 :     }
297 :    
298 :     my @pwStudents = &get_keys_from_db($passwordFile);
299 :     my ($ans,$student);
300 :    
301 :    
302 :     $msg .= "\n<BR<BR><BR> The following login's (if any) in the password and permissions databases are either\n ";
303 :     $msg .= "(1) not listed in the new class list database file \n";
304 :     $msg .= "or (2) have DROP status in the new class list database file.\n";
305 :     $msg .= "They will all be removed from the password and permissions databases.<BR><BR>\n ";
306 :    
307 :     foreach $student (@pwStudents) {
308 :     next if defined($studentsinclass{$student});
309 :    
310 :     &delete_password($student,$passwordFile);
311 :     &delete_permissions($student,$permissionsFile);
312 :     $msg .= "$student<BR>\n ";
313 :     }
314 :    
315 :     # ## if the owner of the password file is running this script (e.g. when the password file is first created)
316 :     # ## set the permissions correctly
317 :     #
318 :     # open (PASSWORDFILE, "$passwordFile") or wwerror($0, "Can't open $passwordFile");
319 :     # my @stat = stat PASSWORDFILE;
320 :     # close PASSWORDFILE;
321 :     #
322 :     # if ($< == $stat[4]) {
323 :     #
324 :     # chmod($Global::password_permission, $passwordFile) or
325 :     # wwerror($0, "Can't do chmod($Global::password_permission, $passwordFile)");
326 :     # chown(-1,$Global::numericalGroupID,$passwordFile) or
327 :     # wwerror($0, "Can't do chown(-1,$Global::numericalGroupID,$passwordFile)");
328 :     # }
329 :     #
330 :     # open (PERMISSIONSFILE, "$permissionsFile") or wwerror($0, "Can't open $permissionsFile");
331 :     # @stat = stat PERMISSIONSFILE;
332 :     # close PERMISSIONSFILE;
333 :     #
334 :     # if ($< == $stat[4]) {
335 :     #
336 :     # chmod($Global::permissions_permission, $permissionsFile) or
337 :     # wwerror($0, "Can't do chmod($Global::permissions_permission, $permissionsFile)");
338 :     # chown(-1,$Global::numericalGroupID,$permissionsFile) or
339 :     # wwerror($0, "Can't do chown(-1,$Global::numericalGroupID,$permissionsFile)");
340 :     # }
341 :     $msg;
342 :     }
343 :    
344 :    
345 :     sub uploadSuccess {
346 :     my ($msg) = @_;
347 :     print"content-type: text/html\n\n<H2>Success, the classlist database has been updated. </H2>\n";
348 : gage 6 print $msg;
349 : sam 2 print &htmlBOTTOM("profImportClasslistDatabase.pl", \%inputs);
350 :     }
351 :    
352 :     sub backup {
353 :     ## takes as a parameter the full path name
354 :     ## makes upto two backups of the file with _bak1, or _bak2
355 :     ## appended to filename where _bak1 is the most recent backup
356 :     use File::Copy;
357 :     my $fileName =$_[0];
358 :    
359 :     if (-e "${fileName}_bak1") {
360 :     rename("${fileName}_bak1","${fileName}_bak2") or
361 :     &wwerror("$0","can't rename ${fileName}_bak1");
362 :     }
363 :    
364 :     if (-e "${fileName}") {
365 :     copy("${fileName}","${fileName}_bak1") or
366 :     &wwerror("$0","can't copy ${fileName}");
367 :     }
368 :     }
369 :    

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9