| 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: webwork2/bin/addcourse,v 1.13 2004/05/22 01:08:08 sh002i Exp $ |
5 | # $CVSHeader: webwork2/bin/addcourse,v 1.14 2004/09/23 16:53:25 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. |
| … | |
… | |
| 127 | } |
127 | } |
| 128 | |
128 | |
| 129 | use lib "$ENV{WEBWORK_ROOT}/lib"; |
129 | use lib "$ENV{WEBWORK_ROOT}/lib"; |
| 130 | use WeBWorK::CourseEnvironment; |
130 | use WeBWorK::CourseEnvironment; |
| 131 | use WeBWorK::DB; |
131 | use WeBWorK::DB; |
|
|
132 | use WeBWorK::File::Classlist; |
| 132 | use WeBWorK::Utils qw(runtime_use readFile cryptPassword); |
133 | use WeBWorK::Utils qw(runtime_use readFile cryptPassword); |
| 133 | use WeBWorK::Utils::CourseManagement qw(addCourse deleteCourse listCourses); |
134 | use WeBWorK::Utils::CourseManagement qw(addCourse deleteCourse listCourses); |
| 134 | |
135 | |
| 135 | sub usage { |
136 | sub usage { |
| 136 | print STDERR "usage: $0 [options] COURSEID\n"; |
137 | print STDERR "usage: $0 [options] COURSEID\n"; |
| … | |
… | |
| 239 | |
240 | |
| 240 | runtime_use($userClass); |
241 | runtime_use($userClass); |
| 241 | runtime_use($passwordClass); |
242 | runtime_use($passwordClass); |
| 242 | runtime_use($permissionClass); |
243 | runtime_use($permissionClass); |
| 243 | |
244 | |
| 244 | my @contents = split /\n/, readFile($users); |
245 | my @classlist = parse_classlist($users); |
| 245 | |
246 | foreach my $record (@classlist) { |
| 246 | # much of this code is burgled from UserList.pm |
247 | my %record = %$record; |
| 247 | foreach my $string (@contents) { |
248 | my $user_id = $record{user_id}; |
| 248 | $string =~ s/^\s+//; |
|
|
| 249 | $string =~ s/\s+$//; |
|
|
| 250 | my ( |
|
|
| 251 | $student_id, $last_name, $first_name, $status, $comment, |
|
|
| 252 | $section, $recitation, $email_address, $user_id |
|
|
| 253 | ) = split /\s*,\s*/, $string; |
|
|
| 254 | |
249 | |
| 255 | my $User = $userClass->new(); |
250 | my $User = new $userClass(%record); |
| 256 | $User->user_id($user_id); |
251 | my $PermissionLevel = new $permissionClass(user_id => $user_id, permission => 0); |
| 257 | $User->first_name($first_name); |
252 | my $Password = new $passwordClass(user_id => $user_id, password => cryptPassword($record{student_id})); |
| 258 | $User->last_name($last_name); |
|
|
| 259 | $User->email_address($email_address); |
|
|
| 260 | $User->student_id($student_id); |
|
|
| 261 | $User->status($status); |
|
|
| 262 | $User->section($section); |
|
|
| 263 | $User->recitation($recitation); |
|
|
| 264 | $User->comment($comment); |
|
|
| 265 | |
253 | |
| 266 | my $Password = $passwordClass->new; |
|
|
| 267 | $Password->user_id($user_id); |
|
|
| 268 | $Password->password(cryptPassword($student_id)); |
|
|
| 269 | |
|
|
| 270 | my $PermissionLevel = $permissionClass->new; |
|
|
| 271 | $PermissionLevel->user_id($user_id); |
|
|
| 272 | if (exists $professors{$user_id}) { |
254 | if (exists $professors{$user_id}) { |
| 273 | $PermissionLevel->permission(10); |
255 | $PermissionLevel->permission(10); |
| 274 | delete $professors{$user_id}; |
256 | delete $professors{$user_id}; |
| 275 | } else { |
|
|
| 276 | $PermissionLevel->permission(0); |
|
|
| 277 | } |
257 | } |
| 278 | |
258 | |
| 279 | push @users, [ $User, $Password, $PermissionLevel ]; |
259 | push @users, [ $User, $Password, $PermissionLevel ]; |
| 280 | } |
260 | } |
| 281 | |
261 | |
| … | |
… | |
| 306 | my $error = $@; |
286 | my $error = $@; |
| 307 | print STDERR "$error\n"; |
287 | print STDERR "$error\n"; |
| 308 | exit; |
288 | exit; |
| 309 | } |
289 | } |
| 310 | |
290 | |
| 311 | __END__ |
|
|
| 312 | |
|
|
| 313 | if ($templates) { |
|
|
| 314 | unless (-d "$courseDir/templates") { |
|
|
| 315 | warn "$courseDir/templates: not found, creating:\n"; |
|
|
| 316 | print "mkdir $courseDir/templates\n"; |
|
|
| 317 | mkdir "$courseDir/templates" |
|
|
| 318 | or die "Failed to mkdir $courseDir/templates: $!\n"; |
|
|
| 319 | } |
|
|
| 320 | print "copy $templates/* -> $courseDir/templates\n"; |
|
|
| 321 | system "/bin/cp -r $templates/* $courseDir/templates/" |
|
|
| 322 | and die "Failed to copy $templates/* to $courseDir/templates: $!\n"; |
|
|
| 323 | } |
|
|
| 324 | |
|
|
| 325 | if ($users) { |
|
|
| 326 | # import users - much of this code is burgled from UserList.pm |
|
|
| 327 | |
|
|
| 328 | my $db; |
|
|
| 329 | if ($dbLayout) { |
|
|
| 330 | # use the specified layout |
|
|
| 331 | $db = WeBWorK::DB->new($ce->{dbLayouts}->{$dbLayout}); |
|
|
| 332 | } else { |
|
|
| 333 | # use the default layout |
|
|
| 334 | $db = WeBWorK::DB->new($ce->{dbLayout}); |
|
|
| 335 | } |
|
|
| 336 | |
|
|
| 337 | my @contents = split /\n/, readFile($users); |
|
|
| 338 | |
|
|
| 339 | my $globalUserPresent = 0; |
|
|
| 340 | |
|
|
| 341 | foreach my $string (@contents) { |
|
|
| 342 | $string =~ s/^\s+//; |
|
|
| 343 | $string =~ s/\s+$//; |
|
|
| 344 | my ( |
|
|
| 345 | $student_id, $last_name, $first_name, $status, $comment, |
|
|
| 346 | $section, $recitation, $email_address, $user_id |
|
|
| 347 | ) = split /\s*,\s*/, $string; |
|
|
| 348 | |
|
|
| 349 | my $User = $db->newUser; |
|
|
| 350 | $User->user_id($user_id); |
|
|
| 351 | $User->first_name($first_name); |
|
|
| 352 | $User->last_name($last_name); |
|
|
| 353 | $User->email_address($email_address); |
|
|
| 354 | $User->student_id($student_id); |
|
|
| 355 | $User->status($status); |
|
|
| 356 | $User->section($section); |
|
|
| 357 | $User->recitation($recitation); |
|
|
| 358 | $User->comment($comment); |
|
|
| 359 | |
|
|
| 360 | my $PermissionLevel = $db->newPermissionLevel; |
|
|
| 361 | $PermissionLevel->user_id($user_id); |
|
|
| 362 | if (exists $professors{$user_id}) { |
|
|
| 363 | $PermissionLevel->permission(10); |
|
|
| 364 | } else { |
|
|
| 365 | $PermissionLevel->permission(0); |
|
|
| 366 | } |
|
|
| 367 | |
|
|
| 368 | my $Password = $db->newPassword; |
|
|
| 369 | $Password->user_id($user_id); |
|
|
| 370 | $Password->password(cryptPassword($student_id)); |
|
|
| 371 | |
|
|
| 372 | $db->addUser($User); |
|
|
| 373 | $db->addPermissionLevel($PermissionLevel); |
|
|
| 374 | $db->addPassword($Password); |
|
|
| 375 | |
|
|
| 376 | if ($user_id eq $globalUserID) { |
|
|
| 377 | $globalUserPresent = 1; |
|
|
| 378 | } |
|
|
| 379 | |
|
|
| 380 | if (exists $professors{$user_id}) { |
|
|
| 381 | print "add professor $user_id\n"; |
|
|
| 382 | delete $professors{$user_id}; |
|
|
| 383 | } else { |
|
|
| 384 | print "add user $user_id\n"; |
|
|
| 385 | } |
|
|
| 386 | } |
|
|
| 387 | |
|
|
| 388 | if (my @ids = keys %professors) { |
|
|
| 389 | print STDERR "warning: @ids not in imported user list.\n"; |
|
|
| 390 | } |
|
|
| 391 | |
|
|
| 392 | unless ($globalUserPresent) { |
|
|
| 393 | warn "warning: global user $globalUserID not in imported user list.\n", |
|
|
| 394 | " please add a user with this user ID manually.\n"; |
|
|
| 395 | } |
|
|
| 396 | } |
|
|
| 397 | |
|
|
| 398 | my $courseEnvFile = $ce->{courseFiles}->{environment}; |
|
|
| 399 | print "writing $courseEnvFile... "; |
|
|
| 400 | open my $fh, ">", $courseEnvFile |
|
|
| 401 | or die "failed to open $courseEnvFile for writing.\n"; |
|
|
| 402 | |
|
|
| 403 | print $fh <<EOF; |
|
|
| 404 | #!perl |
|
|
| 405 | ################################################################################ |
|
|
| 406 | # WeBWorK Online Homework Delivery System |
|
|
| 407 | # Copyright © 2000-2003 The WeBWorK Project, http://openwebwork.sf.net/ |
|
|
| 408 | # |
|
|
| 409 | # This program is free software; you can redistribute it and/or modify it under |
|
|
| 410 | # the terms of either: (a) the GNU General Public License as published by the |
|
|
| 411 | # Free Software Foundation; either version 2, or (at your option) any later |
|
|
| 412 | # version, or (b) the "Artistic License" which comes with this package. |
|
|
| 413 | # |
|
|
| 414 | # This program is distributed in the hope that it will be useful, but WITHOUT |
|
|
| 415 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
|
|
| 416 | # FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the |
|
|
| 417 | # Artistic License for more details. |
|
|
| 418 | ################################################################################ |
|
|
| 419 | |
|
|
| 420 | # This file is used to override the global WeBWorK course environment for |
|
|
| 421 | # requests to this course. All package variables set in this file are added to |
|
|
| 422 | # the course environment. If you wish to set a variable here but omit it from |
|
|
| 423 | # the course environment, use the "my" keyword. Commonly changed configuration |
|
|
| 424 | # options are noted below. The commented-out values are the values which were |
|
|
| 425 | # set in the global configuration file at the time this course was created. |
|
|
| 426 | |
|
|
| 427 | EOF |
|
|
| 428 | |
|
|
| 429 | print $fh <<EOF; |
|
|
| 430 | # Database layout -- if this course uses a different database layout than the |
|
|
| 431 | # one defined in the global configuration file, set it here. |
|
|
| 432 | # |
|
|
| 433 | # Example: \$dbLayoutName = "sql"; |
|
|
| 434 | # \*dbLayout = \$dbLayouts{sql}; |
|
|
| 435 | # |
|
|
| 436 | EOF |
|
|
| 437 | |
|
|
| 438 | if ($dbLayout) { |
|
|
| 439 | print $fh "\$dbLayoutName = '$dbLayout';\n"; |
|
|
| 440 | print $fh "\*dbLayout = \$dbLayouts{$dbLayout};\n"; |
|
|
| 441 | } else { |
|
|
| 442 | my $defaultLayoutName = $ce->{dbLayoutName}; |
|
|
| 443 | if ($defaultLayoutName) { |
|
|
| 444 | print $fh "#\$dbLayoutName = '$defaultLayoutName';\n"; |
|
|
| 445 | print $fh "#\*dbLayout = \$dbLayouts{\$dbLayoutName};\n"; |
|
|
| 446 | } else { |
|
|
| 447 | print $fh "#\$dbLayoutName = '#NOT#FOUND#';\n"; |
|
|
| 448 | print $fh "#\*dbLayout = \$dbLayouts#NOT#FOUND#;\n"; |
|
|
| 449 | warn "default database layout name (\$dbLayoutName) not found in course environment.\n"; |
|
|
| 450 | } |
|
|
| 451 | } |
|
|
| 452 | |
|
|
| 453 | print $fh <<EOF; |
|
|
| 454 | |
|
|
| 455 | # Global user ID - denotes the ID of the user that the GlobalTableEmulator will |
|
|
| 456 | # use to store data for the set and problem tables. only applicable when using |
|
|
| 457 | # the GDBM database layout. |
|
|
| 458 | # |
|
|
| 459 | # Example: \$dbLayouts{gdbm}->{set}->{params}->{globalUserID} = 'some_user'; |
|
|
| 460 | # \$dbLayouts{gdbm}->{problem}->{params}->{globalUserID} = 'some_user'; |
|
|
| 461 | # |
|
|
| 462 | EOF |
|
|
| 463 | |
|
|
| 464 | if ($globalUserID) { |
|
|
| 465 | print $fh "\$dbLayouts{gdbm}->{set}->{params}->{globalUserID} = '$globalUserID';\n"; |
|
|
| 466 | print $fh "\$dbLayouts{gdbm}->{problem}->{params}->{globalUserID} = '$globalUserID';\n"; |
|
|
| 467 | } else { |
|
|
| 468 | my $defaultGlobalUserID = $ce->{dbLayouts}->{gdbm}->{set}->{params}->{globalUserID}; |
|
|
| 469 | if (defined $defaultGlobalUserID) { |
|
|
| 470 | print $fh "#\$dbLayouts{gdbm}->{set}->{params}->{globalUserID} = '$defaultGlobalUserID';\n"; |
|
|
| 471 | print $fh "#\$dbLayouts{gdbm}->{problem}->{params}->{globalUserID} = '$defaultGlobalUserID';\n"; |
|
|
| 472 | } else { |
|
|
| 473 | print $fh "#\$dbLayouts{gdbm}->{set}->{params}->{globalUserID} = '#NOT#FOUND#';\n"; |
|
|
| 474 | print $fh "#\$dbLayouts{gdbm}->{problem}->{params}->{globalUserID} = '#NOT#FOUND#';\n"; |
|
|
| 475 | warn "default GDBM global user ID not found in course environment.\n"; |
|
|
| 476 | } |
|
|
| 477 | } |
|
|
| 478 | |
|
|
| 479 | print $fh <<EOF; |
|
|
| 480 | |
|
|
| 481 | # Allowed mail recipients - list of email addresses that the PG system is |
|
|
| 482 | # allowed to send mail to. (This prevents subtle PG exploits.) If this is not |
|
|
| 483 | # set somewhere, mail from the PG system (i.e. questionaires, essay questions) |
|
|
| 484 | # will fail. |
|
|
| 485 | # |
|
|
| 486 | # Example: \$mail{allowedRecipients} = [ 'gage\@math.rochester.edu', 'apizer\@math.rochester.edu' ]; |
|
|
| 487 | # |
|
|
| 488 | EOF |
|
|
| 489 | |
|
|
| 490 | if (defined $ce->{mail}->{allowedRecipients}) { |
|
|
| 491 | my $value = join ", ", map { "'$_'" } @{ $ce->{mail}->{allowedRecipients} }; |
|
|
| 492 | print $fh "#\$mail{allowedRecipients} = [ $value ];\n"; |
|
|
| 493 | } else { |
|
|
| 494 | print $fh "#\$mail{allowedRecipients} = [ ];\n"; |
|
|
| 495 | } |
|
|
| 496 | |
|
|
| 497 | print $fh <<EOF; |
|
|
| 498 | |
|
|
| 499 | # Feedback recipients - list of email addresses to send feedback to. If not |
|
|
| 500 | # defined, mail is sent to all professors and TAs. |
|
|
| 501 | # |
|
|
| 502 | # Example: \$mail{feedbackRecipients} = [ 'gage\@math.rochester.edu', 'apizer\@math.rochester.edu', 'feedback-list\@lists.webwork.rochester.edu' ]; |
|
|
| 503 | # |
|
|
| 504 | EOF |
|
|
| 505 | |
|
|
| 506 | if (defined $ce->{mail}->{feedbackRecipients}) { |
|
|
| 507 | my $value = join ", ", map { "'$_'" } @{ $ce->{mail}->{feedbackRecipients} }; |
|
|
| 508 | print $fh "#\$mail{feedbackRecipients} = [ $value ];\n"; |
|
|
| 509 | } else { |
|
|
| 510 | print $fh "#\$mail{feedbackRecipients} = [ ];\n"; |
|
|
| 511 | } |
|
|
| 512 | |
|
|
| 513 | print $fh <<EOF; |
|
|
| 514 | |
|
|
| 515 | # Special PG environment variable: PRINT_FILE_NAMES_FOR - List the user IDs of |
|
|
| 516 | # users who should get PG source file names in their rendered problems. This is |
|
|
| 517 | # usually set to the list of professors and TAs in the course. |
|
|
| 518 | # |
|
|
| 519 | # Example: \$pg{specialPGEnvironmentVars}->{PRINT_FILE_NAMES_FOR} = [ 'gage', 'apizer', 'voloshin' ]; |
|
|
| 520 | # |
|
|
| 521 | EOF |
|
|
| 522 | |
|
|
| 523 | if (defined $ce->{pg}->{specialPGEnvironmentVars}->{PRINT_FILE_NAMES_FOR}) { |
|
|
| 524 | my $value = join ", ", map { "'$_'" } |
|
|
| 525 | @{ $ce->{pg}->{specialPGEnvironmentVars}->{PRINT_FILE_NAMES_FOR} }; |
|
|
| 526 | print $fh "#\$pg{specialPGEnvironmentVars}->{PRINT_FILE_NAMES_FOR} = [ $value ];\n"; |
|
|
| 527 | } else { |
|
|
| 528 | print $fh "#\$pg{specialPGEnvironmentVars}->{PRINT_FILE_NAMES_FOR} = [ ];\n"; |
|
|
| 529 | } |
|
|
| 530 | |
|
|
| 531 | close $fh; |
|
|
| 532 | print "done.\n"; |
|
|
| 533 | |
|
|
| 534 | =head1 AUTHOR |
291 | =head1 AUTHOR |
| 535 | |
292 | |
| 536 | Written by Sam Hathaway, hathaway at users.sourceforge.net. |
293 | Written by Sam Hathaway, hathaway at users.sourceforge.net. |
| 537 | |
294 | |
| 538 | =cut |
295 | =cut |