[system] / trunk / webwork-modperl / bin / addcourse Repository:
ViewVC logotype

View of /trunk/webwork-modperl/bin/addcourse

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1906 - (download) (annotate)
Fri Mar 19 21:54:45 2004 UTC (9 years, 3 months ago) by sh002i
File size: 12219 byte(s)
fixed stupid errors in generated course.conf file.

    1 #!/usr/bin/env perl
    2 ################################################################################
    3 # WeBWorK Online Homework Delivery System
    4 # Copyright © 2000-2003 The WeBWorK Project, http://openwebwork.sf.net/
    5 # $CVSHeader: webwork-modperl/bin/addcourse,v 1.9 2004/03/10 16:00:16 sh002i Exp $
    6 # 
    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
    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.
   11 # 
   12 # This program is distributed in the hope that it will be useful, but WITHOUT
   13 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   14 # FOR A PARTICULAR PURPOSE.  See either the GNU General Public License or the
   15 # Artistic License for more details.
   16 ################################################################################
   17 
   18 =head1 NAME
   19 
   20 addcourse - add a course
   21 
   22 =head1 SYNOPSIS
   23 
   24  addcourse [options] COURSEID
   25 
   26 =head1 DESCRIPTION
   27 
   28 Add a course to the courses directory. The required directories will be
   29 created. Optionally, a database can be populated with users and the
   30 F<templates> directory can be populated with the contents of another directory.
   31 Also, one or more users can be granted professor privileges.
   32 
   33 =head1 OPTIONS
   34 
   35 =over
   36 
   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>
   43 
   44 The specified database layout will be used in place of the default specified in
   45 F<global.conf>.
   46 
   47 =item B<--global-user>=I<USERID>
   48 
   49 Specifies that the user ID of the global user will be I<USERID>, overriding the
   50 value set in F<database.conf>. Applicable only to courses using the C<gdbm>
   51 database layout.
   52 
   53 =item B<--users>=I<FILE>
   54 
   55 The users listed in the comma-separated text file I<FILE> will be added to the
   56 user list of the new course. The format of this file is the same as user lists
   57 exported from WeBWorK.
   58 
   59 =item B<--professors>=I<USERID>[,I<USERID>]...
   60 
   61 Each I<USERID>, if it is present in the new course's user list, will be granted
   62 professor privileges (i.e. a permission level of 10). Requires B<--users>.
   63 
   64 =item I<COURSEID>
   65 
   66 The name of the course to create.
   67 
   68 =back
   69 
   70 =cut
   71 
   72 use strict;
   73 use warnings;
   74 use Getopt::Long;
   75 
   76 BEGIN {
   77 	die "WEBWORK_ROOT not found in environment.\n"
   78 		unless exists $ENV{WEBWORK_ROOT};
   79 }
   80 
   81 use lib "$ENV{WEBWORK_ROOT}/lib";
   82 use WeBWorK::CourseEnvironment;
   83 use WeBWorK::DB;
   84 use WeBWorK::Utils qw(readFile cryptPassword);
   85 
   86 sub usage {
   87 	print STDERR "usage: $0 [options] COURSEID\n";
   88 	print STDERR "Options:\n";
   89 	print STDERR "  [--templates=DIR]\n";
   90 	print STDERR "  [--db-layout=LAYOUT]\n";
   91 	print STDERR "  [--global-user=USERID]\n";
   92 	print STDERR "  [--users=FILE [--professors=USERID[,USERID]...] ]\n";
   93 	exit;
   94 }
   95 
   96 my $templates = "";
   97 my $dbLayout = "";
   98 my $users = "";
   99 my $globalUserID = "";
  100 my @professors = ();
  101 
  102 GetOptions(
  103 	"templates=s" => \$templates,
  104 	"db-layout=s" => \$dbLayout,
  105 	"users=s" => \$users,
  106 	"global-user=s" => \$globalUserID,
  107 	"professors=s" => \@professors,
  108 );
  109 my %professors = map { $_ => 1 } map { split /,/ } @professors;
  110 my $courseID = shift;
  111 
  112 unless ($courseID) {
  113 	print STDERR "$0: must specify COURSEID.\n";
  114 	usage();
  115 };
  116 
  117 if (@professors and not $users) {
  118 	print STDERR "$0: can't specify --professors without also specifying --users.\n";
  119 	usage();
  120 }
  121 
  122 # bring up a minimal course environment
  123 my $ce = WeBWorK::CourseEnvironment->new($ENV{WEBWORK_ROOT}, "FAKE_URL_ROOT",
  124 	"FAKE_PG_ROOT", $courseID);
  125 
  126 if ($dbLayout) {
  127 	die "Database layout $dbLayout does not exist in the course environment.",
  128 			" (It must be defined in global.conf.)\n"
  129 		unless exists $ce->{dbLayouts}->{$dbLayout};
  130 }
  131 
  132 # collect some data
  133 my $coursesDir = $ce->{webworkDirs}->{courses};
  134 my $courseDir = "$coursesDir/$courseID";
  135 
  136 # make sure the course doesn't already exist
  137 if (-e $courseDir) {
  138 	die "$courseID: course exists\n";
  139 }
  140 
  141 umask 0002;
  142 
  143 # create required directories
  144 my @subDirs = sort values %{ $ce->{courseDirs} };
  145 foreach my $subDir (@subDirs) {
  146 	print "mkdir $subDir\n";
  147 	mkdir "$subDir"
  148 		or die "Failed to create course directory $subDir: $!\n";
  149 }
  150 
  151 if ($templates) {
  152 	unless (-d "$courseDir/templates") {
  153 		warn "$courseDir/templates: not found, creating:\n";
  154 		print "mkdir $courseDir/templates\n";
  155 		mkdir "$courseDir/templates"
  156 			or die "Failed to mkdir $courseDir/templates: $!\n";
  157 	}
  158 	print "copy $templates/* -> $courseDir/templates\n";
  159 	system "/bin/cp -r $templates/* $courseDir/templates/"
  160 		and die "Failed to copy $templates/* to $courseDir/templates: $!\n";
  161 }
  162 
  163 if ($users) {
  164 	# import users - much of this code is burgled from UserList.pm
  165 	
  166 	my $db;
  167 	if ($dbLayout) {
  168 		# use the specified layout
  169 		$db = WeBWorK::DB->new($ce->{dbLayouts}->{$dbLayout});
  170 	} else {
  171 		# use the default layout
  172 		$db = WeBWorK::DB->new($ce->{dbLayout});
  173 	}
  174 	
  175 	my @contents = split /\n/, readFile($users);
  176 	
  177 	my $globalUserPresent = 0;
  178 	
  179 	foreach my $string (@contents) {
  180 		$string =~ s/^\s+//;
  181 		$string =~ s/\s+$//;
  182 		my (
  183 			$student_id, $last_name, $first_name, $status, $comment,
  184 			$section, $recitation, $email_address, $user_id
  185 		) = split /\s*,\s*/, $string;
  186 		
  187 		my $User = $db->newUser;
  188 		$User->user_id($user_id);
  189 		$User->first_name($first_name);
  190 		$User->last_name($last_name);
  191 		$User->email_address($email_address);
  192 		$User->student_id($student_id);
  193 		$User->status($status);
  194 		$User->section($section);
  195 		$User->recitation($recitation);
  196 		$User->comment($comment);
  197 		
  198 		my $PermissionLevel = $db->newPermissionLevel;
  199 		$PermissionLevel->user_id($user_id);
  200 		if (exists $professors{$user_id}) {
  201 			$PermissionLevel->permission(10);
  202 		} else {
  203 			$PermissionLevel->permission(0);
  204 		}
  205 		
  206 		my $Password = $db->newPassword;
  207 		$Password->user_id($user_id);
  208 		$Password->password(cryptPassword($student_id));
  209 		
  210 		$db->addUser($User);
  211 		$db->addPermissionLevel($PermissionLevel);
  212 		$db->addPassword($Password);
  213 		
  214 		if ($user_id eq $globalUserID) {
  215 			$globalUserPresent = 1;
  216 		}
  217 		
  218 		if (exists $professors{$user_id}) {
  219 			print "add professor $user_id\n";
  220 			delete $professors{$user_id};
  221 		} else {
  222 			print "add user $user_id\n";
  223 		}
  224 	}
  225 	
  226 	if (my @ids = keys %professors) {
  227 		print STDERR "warning: @ids not in imported user list.\n";
  228 	}
  229 	
  230 	unless ($globalUserPresent) {
  231 		warn "warning: global user $globalUserID not in imported user list.\n",
  232 		     "         please add a user with this user ID manually.\n";
  233 	}
  234 }
  235 
  236 my $courseEnvFile = $ce->{courseFiles}->{environment};
  237 print "writing $courseEnvFile... ";
  238 open my $fh, ">", $courseEnvFile
  239 	or die "failed to open $courseEnvFile for writing.\n";
  240 
  241 print $fh <<EOF;
  242 #!perl
  243 ################################################################################
  244 # WeBWorK Online Homework Delivery System
  245 # Copyright © 2000-2003 The WeBWorK Project, http://openwebwork.sf.net/
  246 # 
  247 # This program is free software; you can redistribute it and/or modify it under
  248 # the terms of either: (a) the GNU General Public License as published by the
  249 # Free Software Foundation; either version 2, or (at your option) any later
  250 # version, or (b) the "Artistic License" which comes with this package.
  251 # 
  252 # This program is distributed in the hope that it will be useful, but WITHOUT
  253 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  254 # FOR A PARTICULAR PURPOSE.  See either the GNU General Public License or the
  255 # Artistic License for more details.
  256 ################################################################################
  257 
  258 # This file is used to override the global WeBWorK course environment for
  259 # requests to this course. All package variables set in this file are added to
  260 # the course environment. If you wish to set a variable here but omit it from
  261 # the course environment,  use the "my" keyword. Commonly changed configuration
  262 # options are noted below. The commented-out values are the values which were
  263 # set in the global configuration file at the time this course was created.
  264 
  265 EOF
  266 
  267 print $fh <<EOF;
  268 # Database layout -- if this course uses a different database layout than the
  269 # one defined in the global configuration file, set it here.
  270 # 
  271 # Example: \$dbLayoutName = "sql";
  272 #          \*dbLayout = \$dbLayouts{sql};
  273 # 
  274 EOF
  275 
  276 if ($dbLayout) {
  277 	print $fh "\$dbLayoutName = '$dbLayout';\n";
  278 	print $fh "\*dbLayout = \$dbLayouts{$dbLayout};\n";
  279 } else {
  280 	my $defaultLayoutName = $ce->{dbLayoutName};
  281 	if ($defaultLayoutName) {
  282 		print $fh "#\$dbLayoutName = '$defaultLayoutName';\n";
  283 		print $fh "#\*dbLayout = \$dbLayouts{\$dbLayoutName};\n";
  284 	} else {
  285 		print $fh "#\$dbLayoutName = '#NOT#FOUND#';\n";
  286 		print $fh "#\*dbLayout = \$dbLayouts#NOT#FOUND#;\n";
  287 		warn "default database layout name (\$dbLayoutName) not found in course environment.\n";
  288 	}
  289 }
  290 
  291 print $fh <<EOF;
  292 
  293 # Global user ID - denotes the ID of the user that the GlobalTableEmulator will
  294 # use to store data for the set and problem tables. only applicable when using
  295 # the GDBM database layout.
  296 # 
  297 # Example: \$dbLayouts{gdbm}->{set}->{params}->{globalUserID} = 'some_user';
  298 #          \$dbLayouts{gdbm}->{problem}->{params}->{globalUserID} = 'some_user';
  299 # 
  300 EOF
  301 
  302 if ($globalUserID) {
  303 	print $fh "\$dbLayouts{gdbm}->{set}->{params}->{globalUserID} = '$globalUserID';\n";
  304 	print $fh "\$dbLayouts{gdbm}->{problem}->{params}->{globalUserID} = '$globalUserID';\n";
  305 } else {
  306 	my $defaultGlobalUserID = $ce->{dbLayouts}->{gdbm}->{set}->{params}->{globalUserID};
  307 	if (defined $defaultGlobalUserID) {
  308 		print $fh "#\$dbLayouts{gdbm}->{set}->{params}->{globalUserID} = '$defaultGlobalUserID';\n";
  309 		print $fh "#\$dbLayouts{gdbm}->{problem}->{params}->{globalUserID} = '$defaultGlobalUserID';\n";
  310 	} else {
  311 		print $fh "#\$dbLayouts{gdbm}->{set}->{params}->{globalUserID} = '#NOT#FOUND#';\n";
  312 		print $fh "#\$dbLayouts{gdbm}->{problem}->{params}->{globalUserID} = '#NOT#FOUND#';\n";
  313 		warn "default GDBM global user ID not found in course environment.\n";
  314 	}
  315 }
  316 
  317 print $fh <<EOF;
  318 
  319 # Allowed mail recipients - list of email addresses that the PG system is
  320 # allowed to send mail to. (This prevents subtle PG exploits.) If this is not
  321 # set somewhere, mail from the PG system (i.e. questionaires, essay questions)
  322 # will fail.
  323 # 
  324 # Example: \$mail{allowedRecipients} = [ 'gage\@math.rochester.edu', 'apizer\@math.rochester.edu' ];
  325 # 
  326 EOF
  327 
  328 if (defined $ce->{mail}->{allowedRecipients}) {
  329 	my $value = join ", ", map { "'$_'" } @{ $ce->{mail}->{allowedRecipients} };
  330 	print $fh "#\$mail{allowedRecipients} = [ $value ];\n";
  331 } else {
  332 	print $fh "#\$mail{allowedRecipients} = [  ];\n";
  333 }
  334 
  335 print $fh <<EOF;
  336 
  337 # Feedback recipients - list of email addresses to send feedback to. If not
  338 # defined, mail is sent to all professors and TAs.
  339 # 
  340 # Example: \$mail{feedbackRecipients} = [ 'gage\@math.rochester.edu', 'apizer\@math.rochester.edu', 'feedback-list\@lists.webwork.rochester.edu' ];
  341 # 
  342 EOF
  343 
  344 if (defined $ce->{mail}->{feedbackRecipients}) {
  345 	my $value = join ", ", map { "'$_'" } @{ $ce->{mail}->{feedbackRecipients} };
  346 	print $fh "#\$mail{feedbackRecipients} = [ $value ];\n";
  347 } else {
  348 	print $fh "#\$mail{feedbackRecipients} = [  ];\n";
  349 }
  350 
  351 print $fh <<EOF;
  352 
  353 # Special PG environment variable: PRINT_FILE_NAMES_FOR -  List the user IDs of
  354 # users who should get PG source file names in their rendered problems. This is
  355 # usually set to the list of professors and TAs in the course.
  356 # 
  357 # Example: \$pg{specialPGEnvironmentVars}->{PRINT_FILE_NAMES_FOR}  = [ 'gage', 'apizer', 'voloshin' ];
  358 # 
  359 EOF
  360 
  361 if (defined $ce->{pg}->{specialPGEnvironmentVars}->{PRINT_FILE_NAMES_FOR}) {
  362 	my $value = join ", ", map { "'$_'" }
  363 		@{ $ce->{pg}->{specialPGEnvironmentVars}->{PRINT_FILE_NAMES_FOR} };
  364 	print $fh "#\$pg{specialPGEnvironmentVars}->{PRINT_FILE_NAMES_FOR}  = [ $value ];\n";
  365 } else {
  366 	print $fh "#\$pg{specialPGEnvironmentVars}->{PRINT_FILE_NAMES_FOR}  = [  ];\n";
  367 }
  368 
  369 close $fh;
  370 print "done.\n";
  371 
  372 =head1 BUGS
  373 
  374 Some database drivers are unable to create storage for their data. The GDBM
  375 backend can do this, but the SQL backend cannot (currently). If you wish to
  376 create a course using the SQL database layout, you must create a
  377 
  378 =head1 AUTHOR
  379 
  380 Written by Sam Hathaway, hathaway at users.sourceforge.net.
  381 
  382 =cut

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9