| 1 | #!/usr/bin/env perl |
1 | #!/usr/bin/env perl |
| 2 | ################################################################################ |
2 | ################################################################################ |
| 3 | # WeBWorK Online Homework Delivery System |
3 | # WeBWorK Online Homework Delivery System |
| 4 | # Copyright © 2000-2003 The WeBWorK Project, http://openwebwork.sf.net/ |
4 | # Copyright © 2000-2003 The WeBWorK Project, http://openwebwork.sf.net/ |
| 5 | # $CVSHeader: webwork-modperl/bin/addcourse,v 1.5 2004/01/03 20:07:02 sh002i Exp $ |
5 | # $CVSHeader: webwork-modperl/bin/addcourse,v 1.11 2004/05/05 22:02:50 sh002i Exp $ |
| 6 | # |
6 | # |
| 7 | # This program is free software; you can redistribute it and/or modify it under |
7 | # This program is free software; you can redistribute it and/or modify it under |
| 8 | # the terms of either: (a) the GNU General Public License as published by the |
8 | # the terms of either: (a) the GNU General Public License as published by the |
| 9 | # Free Software Foundation; either version 2, or (at your option) any later |
9 | # Free Software Foundation; either version 2, or (at your option) any later |
| 10 | # version, or (b) the "Artistic License" which comes with this package. |
10 | # version, or (b) the "Artistic License" which comes with this package. |
| … | |
… | |
| 23 | |
23 | |
| 24 | addcourse [options] COURSEID |
24 | addcourse [options] COURSEID |
| 25 | |
25 | |
| 26 | =head1 DESCRIPTION |
26 | =head1 DESCRIPTION |
| 27 | |
27 | |
| 28 | Add a course to the courses directory. The required directories will be |
28 | Add a course to the courses directory. The required directories will be created. |
| 29 | created. Optionally, a database can be populated with users and the |
29 | Optionally, a database can be populated with users. Also, one or more users can |
| 30 | F<templates> directory can be populated with the contents of another directory. |
30 | be granted professor privileges. |
| 31 | Also, one or more users can be granted professor privileges. |
|
|
| 32 | |
31 | |
| 33 | =head1 OPTIONS |
32 | =head1 OPTIONS |
| 34 | |
33 | |
| 35 | =over |
34 | =over |
| 36 | |
35 | |
| 37 | =item B<--templates>=I<DIR> |
|
|
| 38 | |
|
|
| 39 | The contents of the directory I<DIR> will be copied to the F<templates> |
|
|
| 40 | directory of the new course. |
|
|
| 41 | |
|
|
| 42 | =item B<--db-layout>=I<LAYOUT> |
36 | =item B<--db-layout>=I<LAYOUT> |
| 43 | |
37 | |
| 44 | The specified database layout will be used in place of the default specified in |
38 | The specified database layout will be used in place of the default specified in |
| 45 | F<global.conf>. Please note that if you specify a layout other than the default |
39 | F<global.conf>. |
| 46 | given in F<global.conf>, you will need to manually create a F<course.conf> file |
|
|
| 47 | in the new course's directory containing the following line: |
|
|
| 48 | |
40 | |
| 49 | *dbLayout = $dbLayouts{layoutName}; |
41 | If B<--db-layout> is set to C<gdbm>, the following options are valid: |
| 50 | |
42 | |
| 51 | This is described in greater detail in the F<global.conf> and F<database.conf> |
43 | =over |
| 52 | files. |
44 | |
|
|
45 | =item B<--global-user>=I<USERID> |
|
|
46 | |
|
|
47 | Specifies that the user ID of the global user will be I<USERID>, overriding the |
|
|
48 | value set in F<database.conf>. Applicable only to courses using the C<gdbm> |
|
|
49 | database layout. |
|
|
50 | |
|
|
51 | =back |
|
|
52 | |
|
|
53 | If B<--db-layout> is set to C<sql>, the following options are valid: |
|
|
54 | |
|
|
55 | =over |
|
|
56 | |
|
|
57 | =item B<--sql-host>=I<HOST> |
|
|
58 | |
|
|
59 | Specifies the hostname of the SQL server on which to create the course database. |
|
|
60 | If not specified, the default for your RDBMS will be used. |
|
|
61 | |
|
|
62 | =item B<--sql-port>=I<PORT> |
|
|
63 | |
|
|
64 | Specifies the port of the SQL server on which to create the course database. If |
|
|
65 | not specified, the default for your RDBMS will be used. |
|
|
66 | |
|
|
67 | =item B<--sql-user>=I<USER> |
|
|
68 | |
|
|
69 | Specifies the username to use when connecting to the SQL server to create the |
|
|
70 | course database. This user must have CREATE, DELETE, FILE, INSERT, SELECT, and |
|
|
71 | UPDATE privileges, WITH GRANT OPTION. |
|
|
72 | |
|
|
73 | =item B<--sql-pass>=I<PASS> |
|
|
74 | |
|
|
75 | Specifies the password to use when connecting to the SQL server. |
|
|
76 | |
|
|
77 | =item B<--sql-db>=I<DBNAME> |
|
|
78 | |
|
|
79 | Specifies the name of the database to create. (This is usually |
|
|
80 | "webwork_COURSENAME", but can be overridden by changing the database layout in |
|
|
81 | F<global.conf>.) |
|
|
82 | |
|
|
83 | =item B<--sql-wwhost>=I<WWHOST> |
|
|
84 | |
|
|
85 | Specifies the host from which the webwork database users will be allowed to |
|
|
86 | connect. (if B<--sql-host> is set to localhost, this should be set to localhost |
|
|
87 | too.) |
|
|
88 | |
|
|
89 | =back |
| 53 | |
90 | |
| 54 | =item B<--users>=I<FILE> |
91 | =item B<--users>=I<FILE> |
| 55 | |
92 | |
| 56 | The users listed in the comma-separated text file I<FILE> will be added to the |
93 | The users listed in the comma-separated text file I<FILE> will be added to the |
| 57 | user list of the new course. The format of this file is the same as user lists |
94 | user list of the new course. The format of this file is the same as user lists |
| … | |
… | |
| 68 | |
105 | |
| 69 | =back |
106 | =back |
| 70 | |
107 | |
| 71 | =cut |
108 | =cut |
| 72 | |
109 | |
|
|
110 | BEGIN { |
|
|
111 | # hide arguments (there could be passwords there!) |
|
|
112 | $0 = "$0"; |
|
|
113 | } |
|
|
114 | |
| 73 | use strict; |
115 | use strict; |
| 74 | use warnings; |
116 | use warnings; |
| 75 | use Getopt::Long; |
117 | use Getopt::Long; |
| 76 | |
118 | |
| 77 | BEGIN { |
119 | BEGIN { |
| … | |
… | |
| 80 | } |
122 | } |
| 81 | |
123 | |
| 82 | use lib "$ENV{WEBWORK_ROOT}/lib"; |
124 | use lib "$ENV{WEBWORK_ROOT}/lib"; |
| 83 | use WeBWorK::CourseEnvironment; |
125 | use WeBWorK::CourseEnvironment; |
| 84 | use WeBWorK::DB; |
126 | use WeBWorK::DB; |
| 85 | use WeBWorK::Utils qw(readFile cryptPassword); |
127 | use WeBWorK::Utils qw(runtime_use readFile cryptPassword); |
|
|
128 | use WeBWorK::Utils::CourseManagement qw(addCourse deleteCourse listCourses); |
| 86 | |
129 | |
| 87 | sub usage { |
130 | sub usage { |
| 88 | print STDERR "usage: $0 [options] COURSEID\n"; |
131 | print STDERR "usage: $0 [options] COURSEID\n"; |
| 89 | print STDERR "Options:\n"; |
132 | print STDERR "Options:\n"; |
| 90 | print STDERR " [--templates=DIR]\n"; |
|
|
| 91 | print STDERR " [--db-layout=LAYOUT]\n"; |
133 | print STDERR " [--db-layout=LAYOUT]\n"; |
|
|
134 | print STDERR " for \"sql\" database layout:\n"; |
|
|
135 | print STDERR " [--sql-host=HOST] [--sql-port=port]\n"; |
|
|
136 | print STDERR " --sql-user=USER --sql-pass=PASS\n"; |
|
|
137 | print STDERR " --sql-db=DBNAME --sql-wwhost=WWHOST\n"; |
|
|
138 | print STDERR " for \"gdbm\" database layout:\n"; |
|
|
139 | print STDERR " [--global-user=USERID]\n"; |
| 92 | print STDERR " [--users=FILE [--professors=USERID[,USERID]...] ]\n"; |
140 | print STDERR " [--users=FILE [--professors=USERID[,USERID]...] ]\n"; |
| 93 | exit; |
141 | exit; |
| 94 | } |
142 | } |
| 95 | |
143 | |
| 96 | my $templates = ""; |
144 | sub usage_error { |
|
|
145 | print STDERR "$0: @_\n"; |
|
|
146 | usage(); |
|
|
147 | } |
|
|
148 | |
| 97 | my $dbLayout = ""; |
149 | my $dbLayout = ""; |
|
|
150 | my $sql_host = ""; |
|
|
151 | my $sql_port = ""; |
|
|
152 | my $sql_user = ""; |
|
|
153 | my $sql_pass = ""; |
|
|
154 | my $sql_db = ""; |
|
|
155 | my $sql_wwhost = ""; |
|
|
156 | my $globalUserID = ""; |
| 98 | my $users = ""; |
157 | my $users = ""; |
| 99 | my @professors = (); |
158 | my @professors = (); |
| 100 | |
159 | |
|
|
160 | ##### get command-line options ##### |
|
|
161 | |
| 101 | GetOptions( |
162 | GetOptions( |
| 102 | "templates=s" => \$templates, |
|
|
| 103 | "db-layout=s" => \$dbLayout, |
163 | "db-layout=s" => \$dbLayout, |
|
|
164 | "sql-host=s" => \$sql_host, |
|
|
165 | "sql-port=s" => \$sql_port, |
|
|
166 | "sql-user=s" => \$sql_user, |
|
|
167 | "sql-pass=s" => \$sql_pass, |
|
|
168 | "sql-db=s" => \$sql_db, |
|
|
169 | "sql-wwhost=s" => \$sql_wwhost, |
|
|
170 | "global-user=s" => \$globalUserID, |
| 104 | "users=s" => \$users, |
171 | "users=s" => \$users, |
| 105 | "professors=s" => \@professors, |
172 | "professors=s" => \@professors, |
| 106 | ); |
173 | ); |
| 107 | my %professors = map { $_ => 1 } map { split /,/ } @professors; |
174 | my %professors = map { $_ => 1 } map { split /,/ } @professors; |
| 108 | my $courseID = shift; |
175 | my $courseID = shift; |
| 109 | |
176 | |
| 110 | unless ($courseID) { |
177 | ##### perform sanity checks ##### |
| 111 | print STDERR "$0: must specify COURSEID.\n"; |
|
|
| 112 | usage(); |
|
|
| 113 | }; |
|
|
| 114 | |
178 | |
| 115 | if (@professors and not $users) { |
179 | usage_error("must specify COURSEID.") unless $courseID; |
| 116 | print STDERR "$0: can't specify --professors without also specifying --users.\n"; |
|
|
| 117 | usage(); |
|
|
| 118 | } |
|
|
| 119 | |
180 | |
| 120 | # bring up a minimal course environment |
181 | # bring up a minimal course environment |
| 121 | my $ce = WeBWorK::CourseEnvironment->new($ENV{WEBWORK_ROOT}, "FAKE_URL_ROOT", |
182 | my $ce = WeBWorK::CourseEnvironment->new($ENV{WEBWORK_ROOT}, "FAKE_URL_ROOT", |
| 122 | "FAKE_PG_ROOT", $courseID); |
183 | "FAKE_PG_ROOT", $courseID); |
| 123 | |
184 | |
| 124 | if ($dbLayout) { |
185 | if ($dbLayout) { |
| 125 | die "Database layout $dbLayout does not exist in the course environment.", |
186 | die "Database layout $dbLayout does not exist in the course environment.", |
| 126 | " (It must be defined in global.conf.)\n" |
187 | " (It must be defined in global.conf.)\n" |
| 127 | unless exists $ce->{dbLayouts}->{$dbLayout}; |
188 | unless exists $ce->{dbLayouts}->{$dbLayout}; |
|
|
189 | } else { |
|
|
190 | # use default value |
|
|
191 | $dbLayout = $ce->{dbLayoutName}; |
| 128 | } |
192 | } |
| 129 | |
193 | |
| 130 | # collect some data |
194 | if ($dbLayout eq "sql") { |
| 131 | my $coursesDir = $ce->{webworkDirs}->{courses}; |
195 | usage_error("must specify --sql-user.") unless $sql_user; |
| 132 | my $courseDir = "$coursesDir/$courseID"; |
196 | usage_error("must specify --sql-pass.") unless $sql_pass; |
| 133 | |
197 | usage_error("must specify --sql-db.") unless $sql_db; |
| 134 | # make sure the course doesn't already exist |
198 | usage_error("must specify --sql-wwhost.") unless $sql_wwhost; |
| 135 | if (-e $courseDir) { |
199 | } elsif ($dbLayout eq "gdbm") { |
| 136 | die "$courseID: course exists\n"; |
200 | # no required params, apparently... |
| 137 | } |
201 | } |
| 138 | |
202 | |
| 139 | # create required directories |
203 | usage_error("can't specify --professors without also specifying --users.") |
| 140 | my @subDirs = sort values %{ $ce->{courseDirs} }; |
204 | if @professors and not $users; |
| 141 | foreach my $subDir (@subDirs) { |
205 | |
| 142 | print "mkdir $subDir\n"; |
206 | ##### set up parameters to pass to addCourse() ##### |
| 143 | mkdir "$subDir" |
207 | |
| 144 | or die "Failed to create course directory $subDir: $!\n"; |
208 | my %courseOptions = ( dbLayoutName => $dbLayout ); |
|
|
209 | if ($dbLayout eq "gdbm") { |
|
|
210 | $courseOptions{globalUserID} = $globalUserID if $globalUserID ne ""; |
| 145 | } |
211 | } |
|
|
212 | |
|
|
213 | my %dbOptions; |
|
|
214 | if ($dbLayout eq "sql") { |
|
|
215 | $dbOptions{host} = $sql_host if $sql_host ne ""; |
|
|
216 | $dbOptions{port} = $sql_port if $sql_port ne ""; |
|
|
217 | $dbOptions{username} = $sql_user; |
|
|
218 | $dbOptions{password} = $sql_pass; |
|
|
219 | $dbOptions{database} = $sql_db; |
|
|
220 | $dbOptions{wwhost} = $sql_wwhost; |
|
|
221 | } |
|
|
222 | |
|
|
223 | my @users; |
|
|
224 | if ($users) { |
|
|
225 | # this is a hack to create records without bringing up a DB object |
|
|
226 | #my $db = WeBWorK::DB->new($ce->{dbLayouts}->{$dbLayout}); |
|
|
227 | my $userClass = $ce->{dbLayouts}->{$dbLayout}->{user}->{record}; |
|
|
228 | my $passwordClass = $ce->{dbLayouts}->{$dbLayout}->{password}->{record}; |
|
|
229 | my $permissionClass = $ce->{dbLayouts}->{$dbLayout}->{permission}->{record}; |
|
|
230 | |
|
|
231 | runtime_use($userClass); |
|
|
232 | runtime_use($passwordClass); |
|
|
233 | runtime_use($permissionClass); |
|
|
234 | |
|
|
235 | my @contents = split /\n/, readFile($users); |
|
|
236 | |
|
|
237 | # much of this code is burgled from UserList.pm |
|
|
238 | foreach my $string (@contents) { |
|
|
239 | $string =~ s/^\s+//; |
|
|
240 | $string =~ s/\s+$//; |
|
|
241 | my ( |
|
|
242 | $student_id, $last_name, $first_name, $status, $comment, |
|
|
243 | $section, $recitation, $email_address, $user_id |
|
|
244 | ) = split /\s*,\s*/, $string; |
|
|
245 | |
|
|
246 | my $User = $userClass->new(); |
|
|
247 | $User->user_id($user_id); |
|
|
248 | $User->first_name($first_name); |
|
|
249 | $User->last_name($last_name); |
|
|
250 | $User->email_address($email_address); |
|
|
251 | $User->student_id($student_id); |
|
|
252 | $User->status($status); |
|
|
253 | $User->section($section); |
|
|
254 | $User->recitation($recitation); |
|
|
255 | $User->comment($comment); |
|
|
256 | |
|
|
257 | my $Password = $passwordClass->new; |
|
|
258 | $Password->user_id($user_id); |
|
|
259 | $Password->password(cryptPassword($student_id)); |
|
|
260 | |
|
|
261 | my $PermissionLevel = $permissionClass->new; |
|
|
262 | $PermissionLevel->user_id($user_id); |
|
|
263 | if (exists $professors{$user_id}) { |
|
|
264 | $PermissionLevel->permission(10); |
|
|
265 | delete $professors{$user_id}; |
|
|
266 | } else { |
|
|
267 | $PermissionLevel->permission(0); |
|
|
268 | } |
|
|
269 | |
|
|
270 | push @users, [ $User, $Password, $PermissionLevel ]; |
|
|
271 | } |
|
|
272 | |
|
|
273 | if (my @ids = keys %professors) { |
|
|
274 | print STDERR "warning: @ids not in imported user list.\n"; |
|
|
275 | } |
|
|
276 | } |
|
|
277 | |
|
|
278 | ##### call addCourse(), handle errors ##### |
|
|
279 | |
|
|
280 | eval { |
|
|
281 | addCourse( |
|
|
282 | courseID => $courseID, |
|
|
283 | ce => $ce, |
|
|
284 | courseOptions => \%courseOptions, |
|
|
285 | dbOptions => \%dbOptions, |
|
|
286 | users => \@users, |
|
|
287 | ); |
|
|
288 | }; |
|
|
289 | |
|
|
290 | if ($@) { |
|
|
291 | my $error = $@; |
|
|
292 | print STDERR "$error\n"; |
|
|
293 | exit; |
|
|
294 | } |
|
|
295 | |
|
|
296 | __END__ |
| 146 | |
297 | |
| 147 | if ($templates) { |
298 | if ($templates) { |
| 148 | unless (-d "$courseDir/templates") { |
299 | unless (-d "$courseDir/templates") { |
| 149 | warn "$courseDir/templates: not found, creating:\n"; |
300 | warn "$courseDir/templates: not found, creating:\n"; |
| 150 | print "mkdir $courseDir/templates\n"; |
301 | print "mkdir $courseDir/templates\n"; |
| … | |
… | |
| 167 | # use the default layout |
318 | # use the default layout |
| 168 | $db = WeBWorK::DB->new($ce->{dbLayout}); |
319 | $db = WeBWorK::DB->new($ce->{dbLayout}); |
| 169 | } |
320 | } |
| 170 | |
321 | |
| 171 | my @contents = split /\n/, readFile($users); |
322 | my @contents = split /\n/, readFile($users); |
|
|
323 | |
|
|
324 | my $globalUserPresent = 0; |
| 172 | |
325 | |
| 173 | foreach my $string (@contents) { |
326 | foreach my $string (@contents) { |
| 174 | $string =~ s/^\s+//; |
327 | $string =~ s/^\s+//; |
| 175 | $string =~ s/\s+$//; |
328 | $string =~ s/\s+$//; |
| 176 | my ( |
329 | my ( |
| … | |
… | |
| 203 | |
356 | |
| 204 | $db->addUser($User); |
357 | $db->addUser($User); |
| 205 | $db->addPermissionLevel($PermissionLevel); |
358 | $db->addPermissionLevel($PermissionLevel); |
| 206 | $db->addPassword($Password); |
359 | $db->addPassword($Password); |
| 207 | |
360 | |
|
|
361 | if ($user_id eq $globalUserID) { |
|
|
362 | $globalUserPresent = 1; |
|
|
363 | } |
|
|
364 | |
| 208 | if (exists $professors{$user_id}) { |
365 | if (exists $professors{$user_id}) { |
| 209 | print "add professor $user_id\n"; |
366 | print "add professor $user_id\n"; |
| 210 | delete $professors{$user_id}; |
367 | delete $professors{$user_id}; |
| 211 | } else { |
368 | } else { |
| 212 | print "add user $user_id\n"; |
369 | print "add user $user_id\n"; |
| … | |
… | |
| 214 | } |
371 | } |
| 215 | |
372 | |
| 216 | if (my @ids = keys %professors) { |
373 | if (my @ids = keys %professors) { |
| 217 | print STDERR "warning: @ids not in imported user list.\n"; |
374 | print STDERR "warning: @ids not in imported user list.\n"; |
| 218 | } |
375 | } |
|
|
376 | |
|
|
377 | unless ($globalUserPresent) { |
|
|
378 | warn "warning: global user $globalUserID not in imported user list.\n", |
|
|
379 | " please add a user with this user ID manually.\n"; |
|
|
380 | } |
| 219 | } |
381 | } |
|
|
382 | |
|
|
383 | my $courseEnvFile = $ce->{courseFiles}->{environment}; |
|
|
384 | print "writing $courseEnvFile... "; |
|
|
385 | open my $fh, ">", $courseEnvFile |
|
|
386 | or die "failed to open $courseEnvFile for writing.\n"; |
|
|
387 | |
|
|
388 | print $fh <<EOF; |
|
|
389 | #!perl |
|
|
390 | ################################################################################ |
|
|
391 | # WeBWorK Online Homework Delivery System |
|
|
392 | # Copyright © 2000-2003 The WeBWorK Project, http://openwebwork.sf.net/ |
|
|
393 | # |
|
|
394 | # This program is free software; you can redistribute it and/or modify it under |
|
|
395 | # the terms of either: (a) the GNU General Public License as published by the |
|
|
396 | # Free Software Foundation; either version 2, or (at your option) any later |
|
|
397 | # version, or (b) the "Artistic License" which comes with this package. |
|
|
398 | # |
|
|
399 | # This program is distributed in the hope that it will be useful, but WITHOUT |
|
|
400 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
|
|
401 | # FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the |
|
|
402 | # Artistic License for more details. |
|
|
403 | ################################################################################ |
|
|
404 | |
|
|
405 | # This file is used to override the global WeBWorK course environment for |
|
|
406 | # requests to this course. All package variables set in this file are added to |
|
|
407 | # the course environment. If you wish to set a variable here but omit it from |
|
|
408 | # the course environment, use the "my" keyword. Commonly changed configuration |
|
|
409 | # options are noted below. The commented-out values are the values which were |
|
|
410 | # set in the global configuration file at the time this course was created. |
|
|
411 | |
|
|
412 | EOF |
|
|
413 | |
|
|
414 | print $fh <<EOF; |
|
|
415 | # Database layout -- if this course uses a different database layout than the |
|
|
416 | # one defined in the global configuration file, set it here. |
|
|
417 | # |
|
|
418 | # Example: \$dbLayoutName = "sql"; |
|
|
419 | # \*dbLayout = \$dbLayouts{sql}; |
|
|
420 | # |
|
|
421 | EOF |
| 220 | |
422 | |
| 221 | if ($dbLayout) { |
423 | if ($dbLayout) { |
| 222 | print "Don't forget to set dbLayout to \"$dbLayout\" in course.conf!\n"; |
424 | print $fh "\$dbLayoutName = '$dbLayout';\n"; |
|
|
425 | print $fh "\*dbLayout = \$dbLayouts{$dbLayout};\n"; |
|
|
426 | } else { |
|
|
427 | my $defaultLayoutName = $ce->{dbLayoutName}; |
|
|
428 | if ($defaultLayoutName) { |
|
|
429 | print $fh "#\$dbLayoutName = '$defaultLayoutName';\n"; |
|
|
430 | print $fh "#\*dbLayout = \$dbLayouts{\$dbLayoutName};\n"; |
|
|
431 | } else { |
|
|
432 | print $fh "#\$dbLayoutName = '#NOT#FOUND#';\n"; |
|
|
433 | print $fh "#\*dbLayout = \$dbLayouts#NOT#FOUND#;\n"; |
|
|
434 | warn "default database layout name (\$dbLayoutName) not found in course environment.\n"; |
|
|
435 | } |
| 223 | } |
436 | } |
| 224 | |
437 | |
| 225 | =head1 BUGS |
438 | print $fh <<EOF; |
| 226 | |
439 | |
| 227 | Databases are created using the database layout specified in the global |
440 | # Global user ID - denotes the ID of the user that the GlobalTableEmulator will |
| 228 | configuration file (F<global.conf>), which requires users to temporarily modify |
441 | # use to store data for the set and problem tables. only applicable when using |
| 229 | their system's configuration in order to create a course with a nonstandard |
442 | # the GDBM database layout. |
| 230 | database layout. |
443 | # |
|
|
444 | # Example: \$dbLayouts{gdbm}->{set}->{params}->{globalUserID} = 'some_user'; |
|
|
445 | # \$dbLayouts{gdbm}->{problem}->{params}->{globalUserID} = 'some_user'; |
|
|
446 | # |
|
|
447 | EOF |
| 231 | |
448 | |
| 232 | Also, some database drivers are unable to create storage for their data. The |
449 | if ($globalUserID) { |
| 233 | GDBM backend can do this, but the SQL backend cannot (currently). |
450 | print $fh "\$dbLayouts{gdbm}->{set}->{params}->{globalUserID} = '$globalUserID';\n"; |
|
|
451 | print $fh "\$dbLayouts{gdbm}->{problem}->{params}->{globalUserID} = '$globalUserID';\n"; |
|
|
452 | } else { |
|
|
453 | my $defaultGlobalUserID = $ce->{dbLayouts}->{gdbm}->{set}->{params}->{globalUserID}; |
|
|
454 | if (defined $defaultGlobalUserID) { |
|
|
455 | print $fh "#\$dbLayouts{gdbm}->{set}->{params}->{globalUserID} = '$defaultGlobalUserID';\n"; |
|
|
456 | print $fh "#\$dbLayouts{gdbm}->{problem}->{params}->{globalUserID} = '$defaultGlobalUserID';\n"; |
|
|
457 | } else { |
|
|
458 | print $fh "#\$dbLayouts{gdbm}->{set}->{params}->{globalUserID} = '#NOT#FOUND#';\n"; |
|
|
459 | print $fh "#\$dbLayouts{gdbm}->{problem}->{params}->{globalUserID} = '#NOT#FOUND#';\n"; |
|
|
460 | warn "default GDBM global user ID not found in course environment.\n"; |
|
|
461 | } |
|
|
462 | } |
|
|
463 | |
|
|
464 | print $fh <<EOF; |
|
|
465 | |
|
|
466 | # Allowed mail recipients - list of email addresses that the PG system is |
|
|
467 | # allowed to send mail to. (This prevents subtle PG exploits.) If this is not |
|
|
468 | # set somewhere, mail from the PG system (i.e. questionaires, essay questions) |
|
|
469 | # will fail. |
|
|
470 | # |
|
|
471 | # Example: \$mail{allowedRecipients} = [ 'gage\@math.rochester.edu', 'apizer\@math.rochester.edu' ]; |
|
|
472 | # |
|
|
473 | EOF |
|
|
474 | |
|
|
475 | if (defined $ce->{mail}->{allowedRecipients}) { |
|
|
476 | my $value = join ", ", map { "'$_'" } @{ $ce->{mail}->{allowedRecipients} }; |
|
|
477 | print $fh "#\$mail{allowedRecipients} = [ $value ];\n"; |
|
|
478 | } else { |
|
|
479 | print $fh "#\$mail{allowedRecipients} = [ ];\n"; |
|
|
480 | } |
|
|
481 | |
|
|
482 | print $fh <<EOF; |
|
|
483 | |
|
|
484 | # Feedback recipients - list of email addresses to send feedback to. If not |
|
|
485 | # defined, mail is sent to all professors and TAs. |
|
|
486 | # |
|
|
487 | # Example: \$mail{feedbackRecipients} = [ 'gage\@math.rochester.edu', 'apizer\@math.rochester.edu', 'feedback-list\@lists.webwork.rochester.edu' ]; |
|
|
488 | # |
|
|
489 | EOF |
|
|
490 | |
|
|
491 | if (defined $ce->{mail}->{feedbackRecipients}) { |
|
|
492 | my $value = join ", ", map { "'$_'" } @{ $ce->{mail}->{feedbackRecipients} }; |
|
|
493 | print $fh "#\$mail{feedbackRecipients} = [ $value ];\n"; |
|
|
494 | } else { |
|
|
495 | print $fh "#\$mail{feedbackRecipients} = [ ];\n"; |
|
|
496 | } |
|
|
497 | |
|
|
498 | print $fh <<EOF; |
|
|
499 | |
|
|
500 | # Special PG environment variable: PRINT_FILE_NAMES_FOR - List the user IDs of |
|
|
501 | # users who should get PG source file names in their rendered problems. This is |
|
|
502 | # usually set to the list of professors and TAs in the course. |
|
|
503 | # |
|
|
504 | # Example: \$pg{specialPGEnvironmentVars}->{PRINT_FILE_NAMES_FOR} = [ 'gage', 'apizer', 'voloshin' ]; |
|
|
505 | # |
|
|
506 | EOF |
|
|
507 | |
|
|
508 | if (defined $ce->{pg}->{specialPGEnvironmentVars}->{PRINT_FILE_NAMES_FOR}) { |
|
|
509 | my $value = join ", ", map { "'$_'" } |
|
|
510 | @{ $ce->{pg}->{specialPGEnvironmentVars}->{PRINT_FILE_NAMES_FOR} }; |
|
|
511 | print $fh "#\$pg{specialPGEnvironmentVars}->{PRINT_FILE_NAMES_FOR} = [ $value ];\n"; |
|
|
512 | } else { |
|
|
513 | print $fh "#\$pg{specialPGEnvironmentVars}->{PRINT_FILE_NAMES_FOR} = [ ];\n"; |
|
|
514 | } |
|
|
515 | |
|
|
516 | close $fh; |
|
|
517 | print "done.\n"; |
| 234 | |
518 | |
| 235 | =head1 AUTHOR |
519 | =head1 AUTHOR |
| 236 | |
520 | |
| 237 | Written by Sam Hathaway, hathaway at users.sourceforge.net. |
521 | Written by Sam Hathaway, hathaway at users.sourceforge.net. |
| 238 | |
522 | |