From: Mike G. v. a. <we...@ma...> - 2009-06-26 01:07:39
|
Log Message: ----------- syncing with HEAD Tags: ---- rel-2-4-patches Modified Files: -------------- webwork2: README webwork2/bin: remove_stale_images wwdb_upgrade webwork2/conf: global.conf.dist webwork2/conf/templates/math: system.template webwork2/conf/templates/ur: system.template webwork2/doc: Copying webwork2/lib: WebworkSOAP.pm webwork2/lib/WeBWorK: Constants.pm ContentGenerator.pm DB.pm URLPath.pm webwork2/lib/WeBWorK/ContentGenerator: CourseAdmin.pm GatewayQuiz.pm Login.pm Problem.pm ProblemSets.pm webwork2/lib/WeBWorK/ContentGenerator/Instructor: Index.pm PGProblemEditor.pm ProblemSetDetail.pm SetMaker.pm Stats.pm StudentProgress.pm UserDetail.pm webwork2/lib/WeBWorK/DB: Schema.pm webwork2/lib/WeBWorK/DB/Record: UserSetLocations.pm webwork2/lib/WeBWorK/DB/Schema/NewSQL: Std.pm webwork2/lib/WeBWorK/Utils: CourseManagement.pm DBUpgrade.pm Tasks.pm webwork2/lib/WebworkSOAP/Classes: GlobalProblem.pm GlobalSet.pm Key.pm Password.pm Permission.pm User.pm UserProblem.pm UserSet.pm Added Files: ----------- webwork2/conf/templates/math2: math2.css webwork2/lib/WeBWorK/Utils: CourseIntegrityCheck.pm Removed Files: ------------- webwork2/doc/docbook/install: Installing-WeBWorK.xml Revision Data ------------- Index: README =================================================================== RCS file: /webwork/cvs/system/webwork2/README,v retrieving revision 1.17.4.3.2.3 retrieving revision 1.17.4.3.2.4 diff -LREADME -LREADME -u -r1.17.4.3.2.3 -r1.17.4.3.2.4 --- README +++ README @@ -1,6 +1,6 @@ WeBWorK Online Homework Delivery System - Version 2.4.5 + Version 2.4.7 Branch: rel-2-4-patches http://webwork.maa.org/wiki/Release_notes_for_WeBWorK_2.4.5 Index: remove_stale_images =================================================================== RCS file: /webwork/cvs/system/webwork2/bin/remove_stale_images,v retrieving revision 1.4.4.1.2.1 retrieving revision 1.4.4.1.2.2 diff -Lbin/remove_stale_images -Lbin/remove_stale_images -u -r1.4.4.1.2.1 -r1.4.4.1.2.2 --- bin/remove_stale_images +++ bin/remove_stale_images @@ -197,12 +197,12 @@ sub count_report { my $j; print "Days\n"; - for $j (sort keys(%days)) { + for $j (sort {$a <=> $b} keys(%days)) { print "$j $days{$j}\n"; } print "\nWeeks\n"; - for $j (sort keys(%week)) { + for $j (sort {$a <=> $b} keys(%week)) { print " $j $week{$j}\n"; } @@ -281,7 +281,4 @@ chmod $perms, $cachePath; chown $uid, $groupID, $cachePath; - - - -1; \ No newline at end of file +1; Index: wwdb_upgrade =================================================================== RCS file: /webwork/cvs/system/webwork2/bin/wwdb_upgrade,v retrieving revision 1.13.2.1 retrieving revision 1.13.2.1.2.1 diff -Lbin/wwdb_upgrade -Lbin/wwdb_upgrade -u -r1.13.2.1 -r1.13.2.1.2.1 --- bin/wwdb_upgrade +++ bin/wwdb_upgrade @@ -18,7 +18,6 @@ use strict; use warnings; use Getopt::Std; -use DBI; use Data::Dumper; BEGIN { @@ -28,447 +27,23 @@ use lib "$ENV{WEBWORK_ROOT}/lib"; use WeBWorK::CourseEnvironment; -use WeBWorK::Utils qw/runtime_use/; -use WeBWorK::Utils::CourseManagement qw/listCourses/; +use WeBWorK::Utils::DBUpgrade; our ($opt_v); getopts("v"); if ($opt_v) { - $| = 1; - *verbose = sub { print STDERR @_ }; + $WeBWorK::Debug::Enabled = 1; } else { - *verbose = sub {}; + $WeBWorK::Debug::Enabled = 0; } -# global variables, hah hah. -my ($dbh, %sql_tables); +my $ce = new WeBWorK::CourseEnvironment({webwork_dir=>$ENV{WEBWORK_ROOT}}); -################################################################################ - -my $i = -1; -our @DB_VERSIONS; - -$DB_VERSIONS[++$i]{desc} = "is the initial version of database, identical to database structure in WeBWorK 2.2.x."; - -$DB_VERSIONS[++$i]{desc} = "adds dbupgrade table to facilitate automatic database upgrades."; -$DB_VERSIONS[ $i]{global_code} = sub { - $dbh->do("CREATE TABLE `dbupgrade` (`name` VARCHAR(255) NOT NULL PRIMARY KEY, `value` TEXT)"); - $dbh->do("INSERT INTO `dbupgrade` (`name`, `value`) VALUES (?, ?)", {}, "db_version", 1); - $sql_tables{dbupgrade} = (); -}; - -$DB_VERSIONS[++$i]{desc} = "adds problems_per_page field to set and set_user tables of each course."; -$DB_VERSIONS[ $i]{course_code} = sub { - my $course = shift; - $dbh->do("ALTER TABLE `${course}_set` ADD COLUMN `problems_per_page` INT") - if exists $sql_tables{"${course}_set"}; - $dbh->do("ALTER TABLE `${course}_set_user` ADD COLUMN `problems_per_page` INT") - if exists $sql_tables{"${course}_set_user"}; -}; - -$DB_VERSIONS[++$i]{desc} = "adds depths table to keep track of dvipng depth information."; -$DB_VERSIONS[ $i]{global_code} = sub { - $dbh->do("CREATE TABLE depths (md5 CHAR(33) NOT NULL, depth SMALLINT, PRIMARY KEY (md5))"); - $sql_tables{depths} = (); -}; - -$DB_VERSIONS[++$i]{desc} = "changes type of key timestamp field to BIGINT"; -$DB_VERSIONS[ $i]{course_code} = sub { - my $course = shift; - return unless exists $sql_tables{"${course}_key"}; - $dbh->do("ALTER TABLE `${course}_key` CHANGE COLUMN `timestamp` `timestamp` BIGINT"); -}; - -$DB_VERSIONS[++$i]{desc} = "changes type of problem_user status field to FLOAT"; -$DB_VERSIONS[ $i]{course_code} = sub { - my $course = shift; - return unless exists $sql_tables{"${course}_problem_user"}; - $dbh->do("UPDATE `${course}_problem_user` SET `status`=NULL WHERE `status`=''"); - $dbh->do("ALTER TABLE `${course}_problem_user` CHANGE COLUMN `status` `status` FLOAT"); -}; - -$DB_VERSIONS[++$i]{desc} = "changes types of alphanumeric keyfields to TINYBLOB NOT NULL"; -$DB_VERSIONS[ $i]{course_code} = sub { - my $course = shift; - $dbh->do("ALTER TABLE `${course}_user` CHANGE COLUMN `user_id` `user_id` TINYBLOB NOT NULL") - if exists $sql_tables{"${course}_user"}; - $dbh->do("ALTER TABLE `${course}_password` CHANGE COLUMN `user_id` `user_id` TINYBLOB NOT NULL") - if exists $sql_tables{"${course}_password"}; - $dbh->do("ALTER TABLE `${course}_permission` CHANGE COLUMN `user_id` `user_id` TINYBLOB NOT NULL") - if exists $sql_tables{"${course}_permission"}; - $dbh->do("ALTER TABLE `${course}_key` CHANGE COLUMN `user_id` `user_id` TINYBLOB NOT NULL") - if exists $sql_tables{"${course}_key"}; - $dbh->do("ALTER TABLE `${course}_set` CHANGE COLUMN `set_id` `set_id` TINYBLOB NOT NULL") - if exists $sql_tables{"${course}_set"}; - $dbh->do("ALTER TABLE `${course}_problem` CHANGE COLUMN `set_id` `set_id` TINYBLOB NOT NULL") - if exists $sql_tables{"${course}_problem"}; - $dbh->do("ALTER TABLE `${course}_set_user` CHANGE COLUMN `user_id` `user_id` TINYBLOB NOT NULL") - if exists $sql_tables{"${course}_set_user"}; - $dbh->do("ALTER TABLE `${course}_set_user` CHANGE COLUMN `set_id` `set_id` TINYBLOB NOT NULL") - if exists $sql_tables{"${course}_set_user"}; - $dbh->do("ALTER TABLE `${course}_problem_user` CHANGE COLUMN `user_id` `user_id` TINYBLOB NOT NULL") - if exists $sql_tables{"${course}_problem_user"}; - $dbh->do("ALTER TABLE `${course}_problem_user` CHANGE COLUMN `set_id` `set_id` TINYBLOB NOT NULL") - if exists $sql_tables{"${course}_problem_user"}; -}; - -$DB_VERSIONS[++$i]{desc} = "fixes KEY length, adds UNIQUE KEY for user table"; -$DB_VERSIONS[ $i]{course_code} = sub { - my $course = shift; - return unless exists $sql_tables{"${course}_user"}; - $dbh->do("ALTER TABLE `${course}_user` DROP KEY `user_id`"); - $dbh->do("ALTER TABLE `${course}_user` ADD UNIQUE KEY (`user_id`(255))"); -}; - -$DB_VERSIONS[++$i]{desc} = "fixes KEY length, adds UNIQUE KEY for password table"; -$DB_VERSIONS[ $i]{course_code} = sub { - my $course = shift; - return unless exists $sql_tables{"${course}_password"}; - $dbh->do("ALTER TABLE `${course}_password` DROP KEY `user_id`"); - $dbh->do("ALTER TABLE `${course}_password` ADD UNIQUE KEY (`user_id`(255))"); -}; - -$DB_VERSIONS[++$i]{desc} = "fixes KEY length, adds UNIQUE KEY for permission table"; -$DB_VERSIONS[ $i]{course_code} = sub { - my $course = shift; - return unless exists $sql_tables{"${course}_permission"}; - $dbh->do("ALTER TABLE `${course}_permission` DROP KEY `user_id`"); - $dbh->do("ALTER TABLE `${course}_permission` ADD UNIQUE KEY (`user_id`(255))"); -}; - -$DB_VERSIONS[++$i]{desc} = "fixes KEY length, adds UNIQUE KEY for key table"; -$DB_VERSIONS[ $i]{course_code} = sub { - my $course = shift; - return unless exists $sql_tables{"${course}_key"}; - $dbh->do("ALTER TABLE `${course}_key` DROP KEY `user_id`"); - $dbh->do("ALTER TABLE `${course}_key` ADD UNIQUE KEY (`user_id`(255))"); -}; - -$DB_VERSIONS[++$i]{desc} = "fixes KEY length, adds UNIQUE KEY for set table"; -$DB_VERSIONS[ $i]{course_code} = sub { - my $course = shift; - return unless exists $sql_tables{"${course}_set"}; - $dbh->do("ALTER TABLE `${course}_set` DROP KEY `set_id`"); - $dbh->do("ALTER TABLE `${course}_set` ADD UNIQUE KEY (`set_id`(255))"); -}; - -$DB_VERSIONS[++$i]{desc} = "fixes KEY length, adds UNIQUE KEY for problem table"; -$DB_VERSIONS[ $i]{course_code} = sub { - my $course = shift; - return unless exists $sql_tables{"${course}_problem"}; - $dbh->do("ALTER TABLE `${course}_problem` DROP KEY `set_id`"); - $dbh->do("ALTER TABLE `${course}_problem` ADD UNIQUE KEY (`set_id`(255), `problem_id`)"); - $dbh->do("ALTER TABLE `${course}_problem` DROP KEY `problem_id`"); - $dbh->do("ALTER TABLE `${course}_problem` ADD KEY (`problem_id`)"); -}; - -$DB_VERSIONS[++$i]{desc} = "fixes KEY length, adds UNIQUE KEY for set_user table"; -$DB_VERSIONS[ $i]{course_code} = sub { - my $course = shift; - return unless exists $sql_tables{"${course}_set_user"}; - $dbh->do("ALTER TABLE `${course}_set_user` DROP KEY `user_id`"); - $dbh->do("ALTER TABLE `${course}_set_user` ADD UNIQUE KEY (`user_id`(255), `set_id`(255))"); - $dbh->do("ALTER TABLE `${course}_set_user` DROP KEY `set_id`"); - $dbh->do("ALTER TABLE `${course}_set_user` ADD KEY (`set_id`(255))"); -}; - -$DB_VERSIONS[++$i]{desc} = "fixes KEY length, adds UNIQUE KEY for problem_user table"; -$DB_VERSIONS[ $i]{course_code} = sub { - my $course = shift; - return unless exists $sql_tables{"${course}_problem_user"}; - $dbh->do("ALTER TABLE `${course}_problem_user` DROP KEY `user_id`"); - $dbh->do("ALTER TABLE `${course}_problem_user` ADD UNIQUE KEY (`user_id`(255), `set_id`(255), `problem_id`)"); - $dbh->do("ALTER TABLE `${course}_problem_user` DROP KEY `set_id`"); - $dbh->do("ALTER TABLE `${course}_problem_user` ADD KEY (`set_id`(255), `problem_id`)"); - $dbh->do("ALTER TABLE `${course}_problem_user` DROP KEY `problem_id`"); - $dbh->do("ALTER TABLE `${course}_problem_user` ADD KEY (`problem_id`)"); -}; - -$DB_VERSIONS[++$i]{desc} = "changes psvn index from PRIMARY KEY to UNIQUE KEY"; -$DB_VERSIONS[ $i]{course_code} = sub { - my $course = shift; - return unless exists $sql_tables{"${course}_set_user"}; - $dbh->do("ALTER TABLE `${course}_set_user` ADD UNIQUE KEY (`psvn`)"); - $dbh->do("ALTER TABLE `${course}_set_user` DROP PRIMARY KEY"); -}; - -$DB_VERSIONS[++$i]{desc} = "adds hide_score and hide_work fields to set and set_user"; -$DB_VERSIONS[ $i]{course_code} = sub { - my $course = shift; - if ( exists $sql_tables{"${course}_set"} ) { - $dbh->do("ALTER TABLE `${course}_set` ADD COLUMN `hide_score` ENUM('0','1')"); - $dbh->do("ALTER TABLE `${course}_set` ADD COLUMN `hide_work` ENUM('0','1')"); - } - if ( exists $sql_tables{"${course}_set_user"} ) { - $dbh->do("ALTER TABLE `${course}_set_user` ADD COLUMN `hide_score` ENUM('0','1')"); - $dbh->do("ALTER TABLE `${course}_set_user` ADD COLUMN `hide_work` ENUM('0','1')"); - } -}; - -$DB_VERSIONS[++$i]{desc} = "updates hide_score and hide_work in set and set_user tables to allow more (and more descriptive) possible values"; -$DB_VERSIONS[ $i]{course_code} = sub { - my $course = shift; - if ( exists $sql_tables{"${course}_set"} ) { - $dbh->do("ALTER TABLE `${course}_set` MODIFY COLUMN `hide_score` ENUM('0','1','2')"); - $dbh->do("ALTER TABLE `${course}_set` MODIFY COLUMN `hide_work` ENUM('0','1','2')"); - } - if ( exists $sql_tables{"${course}_set_user"} ) { - $dbh->do("ALTER TABLE `${course}_set_user` MODIFY COLUMN `hide_score` ENUM('0','1','2')"); - $dbh->do("ALTER TABLE `${course}_set_user` MODIFY COLUMN `hide_work` ENUM('0','1','2')"); - } -}; - -$DB_VERSIONS[++$i]{desc} = "adds time_limit_cap field to set and set_user tables"; -$DB_VERSIONS[ $i]{course_code} = sub { - my $course = shift; - if ( exists $sql_tables{"${course}_set"} ) { - $dbh->do("ALTER TABLE `${course}_set` ADD COLUMN `time_limit_cap` ENUM('0','1')"); - } - if ( exists $sql_tables{"${course}_set_user"} ) { - $dbh->do("ALTER TABLE `${course}_set_user` ADD COLUMN `time_limit_cap` ENUM('0','1')"); - } -}; - -$DB_VERSIONS[++$i]{desc} = "updates hide_score and hide_work in set and set_user tables to have more descriptive values, set default values"; -$DB_VERSIONS[ $i]{course_code} = sub { - my $course = shift; - if ( exists $sql_tables{"${course}_set"} ) { - $dbh->do("ALTER TABLE `${course}_set` MODIFY COLUMN `hide_score` ENUM('N','Y','BeforeAnswerDate') DEFAULT 'N'"); - $dbh->do("ALTER TABLE `${course}_set` MODIFY COLUMN `hide_work` ENUM('N','Y','BeforeAnswerDate') DEFAULT 'N'"); - } - if ( exists $sql_tables{"${course}_set_user"} ) { - $dbh->do("ALTER TABLE `${course}_set_user` MODIFY COLUMN `hide_score` ENUM('N','Y','BeforeAnswerDate') DEFAULT 'N'"); - $dbh->do("ALTER TABLE `${course}_set_user` MODIFY COLUMN `hide_work` ENUM('N','Y','BeforeAnswerDate') DEFAULT 'N'"); - } -}; - -$DB_VERSIONS[++$i]{desc} = "adds locations, location_addresses, set_locations and set_locations_user tables to database, and add restrict_ip to set and set_user."; -$DB_VERSIONS[ $i]{global_code} = sub { - $dbh->do("CREATE TABLE locations (location_id TINYBLOB NOT NULL, description TEXT, PRIMARY KEY (location_id(1000)))"); - $dbh->do("CREATE TABLE location_addresses (location_id TINYBLOB NOT NULL, ip_mask TINYBLOB NOT NULL, PRIMARY KEY (location_id(500),ip_mask(500)))"); -}; -$DB_VERSIONS[ $i]{course_code} = sub { - my $course = shift; - - $dbh->do("CREATE TABLE `${course}_set_locations` (set_id TINYBLOB NOT NULL, location_id TINYBLOB NOT NULL, PRIMARY KEY (set_id(500),location_id(500)))"); - $dbh->do("CREATE TABLE `${course}_set_locations_user` (set_id TINYBLOB NOT NULL, user_id TINYBLOB NOT NULL, location_id TINYBLOB NOT NULL, PRIMARY KEY (set_id(300),user_id(300),location_id(300)))"); - - if ( exists $sql_tables{"${course}_set"} ) { - $dbh->do("ALTER TABLE `${course}_set` ADD COLUMN `restrict_ip` enum('No','RestrictTo','DenyFrom') DEFAULT 'No'"); - } - if ( exists $sql_tables{"${course}_set_user"} ) { - $dbh->do("ALTER TABLE `${course}_set_user` ADD COLUMN `restrict_ip` enum('No','RestrictTo','DenyFrom')"); - } -}; - -$DB_VERSIONS[++$i]{desc} = "updates defaults for hide_work and hide_score in set_user tables."; -$DB_VERSIONS[ $i]{course_code} = sub { - my $course = shift; - - if ( exists $sql_tables{"${course}_set_user"} ) { - $dbh->do("ALTER TABLE `${course}_set_user` MODIFY COLUMN `hide_score` ENUM('N','Y','BeforeAnswerDate')"); - $dbh->do("ALTER TABLE `${course}_set_user` MODIFY COLUMN `hide_work` ENUM('N','Y','BeforeAnswerDate')"); - } -}; - -$DB_VERSIONS[++$i]{desc} = "adds relax_restrict_ip, hide_problem_score columns to set and set_user tables."; -$DB_VERSIONS[ $i]{course_code} = sub { - my $course = shift; - - if ( exists $sql_tables{"${course}_set"} ) { - $dbh->do("ALTER TABLE `${course}_set` ADD COLUMN `relax_restrict_ip` ENUM('No','AfterAnswerDate','AfterVersionAnswerDate') DEFAULT 'No'"); - $dbh->do("ALTER TABLE `${course}_set` ADD COLUMN `hide_score_by_problem` ENUM('N','Y') DEFAULT 'N'"); - } - if ( exists $sql_tables{"${course}_set_user"} ) { - $dbh->do("ALTER TABLE `${course}_set_user` ADD COLUMN `relax_restrict_ip` ENUM('No','AfterAnswerDate','AfterVersionAnswerDate')"); - $dbh->do("ALTER TABLE `${course}_set_user` ADD COLUMN `hide_score_by_problem` ENUM('N','Y')"); - } -}; - -$DB_VERSIONS[++$i]{desc} = "adds set and set_user fields to allow set-level proctor, updates permissions to allow finer-grained regulation of proctoring."; -$DB_VERSIONS[ $i]{course_code} = sub { - my $course = shift; - if ( exists $sql_tables{"${course}_permission"} ) { - $dbh->do("UPDATE `${course}_permission` SET `permission`=3 where `permission`=2"); - } - if ( exists $sql_tables{"${course}_set"} ) { - $dbh->do("ALTER TABLE `${course}_set` ADD COLUMN `restricted_login_proctor` ENUM('No','Yes') DEFAULT 'No'"); - } - if ( exists $sql_tables{"${course}_set_user"} ) { - $dbh->do("ALTER TABLE `${course}_set_user` ADD COLUMN `restricted_login_proctor` ENUM('No','Yes')"); - } -}; - -our $THIS_DB_VERSION = $i; - -################################################################################ - -my $ce = WeBWorK::CourseEnvironment->new({ - webwork_dir => $ENV{WEBWORK_ROOT}, -}); - -my @ww_courses = listCourses($ce); - -$dbh = DBI->connect( - $ce->{database_dsn}, - $ce->{database_username}, - $ce->{database_password}, - { - PrintError => 0, - RaiseError => 1, - }, +my $upgrader = new WeBWorK::Utils::DBUpgrade( + ce => $ce, + verbose_sub => sub { print STDERR @_ }, ); -{ - verbose("Obtaining dbupgrade lock...\n"); - my ($lock_status) = $dbh->selectrow_array("SELECT GET_LOCK('dbupgrade', 10)"); - if (not defined $lock_status) { - print "Couldn't obtain lock because an error occurred.\n"; - exit 2; - } - if ($lock_status) { - verbose("Got lock.\n"); - } else { - print "Timed out while waiting for lock.\n"; - exit 2; - } -} - -%sql_tables = get_sql_tables(); - -my $db_version = exists $sql_tables{dbupgrade} ? get_db_version() : 0; - -if (not defined $db_version) { - print "Failed to get db_version -- can't continue.\n"; - exit 1; -} - -verbose("Initial db_version is $db_version\n"); - -if ($db_version > $THIS_DB_VERSION) { - print "db_version is $db_version, but the current database version is only $THIS_DB_VERSION. This database was probably used with a newer version of WeBWorK.\n"; - exit; -} - -while ($db_version < $THIS_DB_VERSION) { - $db_version++; - unless (upgrade_to_version($db_version)) { - print "\nUpgrading from version ".($db_version-1)." to $db_version failed.\n\n"; - unless (ask_permission("Ignore this error and go on to the next version?", 0)) { - exit 3; - } - } - set_db_version($db_version); -} - -print "\nDatabase is up-to-date at version $db_version.\n"; - -END { - verbose("Releasing dbupgrade lock...\n"); - my ($lock_status) = $dbh->selectrow_array("SELECT RELEASE_LOCK('dbupgrade')"); - if (not defined $lock_status) { - print "Couldn't release lock because the lock does not exist.\n"; - exit 2; - } - if ($lock_status) { - verbose("Released lock.\n"); - } else { - print "Couldn't release lock because the lock is not held by this thread.\n"; - exit 2; - } -} - -################################################################################ - -sub get_sql_tables { - my $sql_tables_ref = $dbh->selectcol_arrayref("SHOW TABLES"); - my %sql_tables; @sql_tables{@$sql_tables_ref} = (); - - return %sql_tables; -} - -sub get_db_version { - my $vers_value_should_be = "This value should always be a positive integer."; - my $vers_stop_now = "You should stop now and take a closer look."; - - my @record = $dbh->selectrow_array("SELECT `value` FROM `dbupgrade` WHERE `name`='db_version'"); - if (@record) { - my $db_version = $record[0]; - if (not defined $db_version) { - print "'db_version' exists, but it has a NULL value. $vers_value_should_be $vers_stop_now\n"; - return; - } elsif ($db_version !~ /^-?\d+$/) { - print "'db_version' is set to the non-numeric value '$db_version'. $vers_value_should_be $vers_stop_now\n"; - return; - } elsif ($db_version < 0) { - print "'db_version' is set to the negative value '$db_version'. $vers_value_should_be $vers_stop_now\n"; - return; - } elsif ($db_version == 0) { - print "'db_version' is set 0, which is reserved to indicate a pre-automatic-upgrade version. $vers_value_should_be $vers_stop_now\n"; - return; - } else { - # db_version is positive! yay! - return $db_version; - } - } else { - print "The 'dbupgrade' table exists, but doesn't contain a 'db_version' setting. $vers_stop_now\n"; - return; - } -} - -sub set_db_version { - my $vers = shift; - $dbh->do("UPDATE `dbupgrade` SET `value`=? WHERE `name`='db_version'", {}, $vers); -} +$upgrader->do_upgrade; -sub upgrade_to_version { - my $vers = shift; - my %info = %{$DB_VERSIONS[$vers]}; - - print "\nUpgrading database from version " . ($vers-1) . " to $vers...\n"; - my $desc = $info{desc} || "has no description."; - print "(Version $vers $desc)\n"; - - if (exists $info{global_code}) { - eval { $info{global_code}->() }; - if ($@) { - print "\nAn error occured while running the system upgrade code for version $vers:\n"; - print "$@"; - return 0 unless ask_permission("Ignore this error and keep going?", 0); - } - } - - if (@ww_courses and exists $info{course_code}) { - foreach my $curr_course (@ww_courses) { - eval { $info{course_code}->($curr_course) }; - if ($@) { - print "\nAn error occured while running the course upgrade code for version $vers on course $curr_course:\n"; - print "$@"; - next if ask_permission("Ignore this error and go on to the next course?", 0); - } - } - } - - print "Done.\n"; - return 1; -} - -################################################################################ - -sub ask_permission { - my ($prompt, $default) = @_; - - $default = 1 if not defined $default; - my $options = $default ? "[Y/n]" : "[y/N]"; - - while (1) { - print "$prompt $options "; - my $resp = <STDIN>; - chomp $resp; - return $default if $resp eq ""; - return 1 if lc $resp eq "y"; - return 0 if lc $resp eq "n"; - $prompt = 'Please enter "y" or "n".'; - } -} Index: global.conf.dist =================================================================== RCS file: /webwork/cvs/system/webwork2/conf/global.conf.dist,v retrieving revision 1.189.2.7.2.10 retrieving revision 1.189.2.7.2.11 diff -Lconf/global.conf.dist -Lconf/global.conf.dist -u -r1.189.2.7.2.10 -r1.189.2.7.2.11 --- conf/global.conf.dist +++ conf/global.conf.dist @@ -375,6 +375,32 @@ # the templates directory. $courseFiles{login_info} = "login_info.txt"; +# Additional library buttons can be added to the Library Browser (SetMaker.pm) +# by adding the libraries you want to the following line. For each key=>value +# in the list, if a directory (or link to a directory) with name 'key' appears +# in the templates directory, then a button with name 'value' will be placed at +# the top of the problem browser. (No button will appear if there is no +# directory or link with the given name in the templates directory.) For +# example, +# +# $courseFiles{problibs} = {rochester => "Rochester", asu => "ASU"}; +# +# would add two buttons, one for the Rochester library and one for the ASU +# library, provided templates/rochester and templates/asu exists either as +# subdirectories or links to other directories. The "NPL Directory" button +# activated below gives access to all the directories in the National +# Problem Library. +# +$courseFiles{problibs} = { + Library => "NPL Directory", +# rochesterLibrary => "Rochester", +# asuLibrary => "Arizona State", +# dcdsLibrary => "Detroit CDS", +# dartmouthLibrary => "Dartmouth", +# indianaLibrary => "Indiana", +# osuLibrary => "Ohio State", +# capaLibrary => "CAPA", +}; ################################################################################ # Status system @@ -472,35 +498,6 @@ passwd => $database_password, }; - -# Additional library buttons can be added to the Library Browser (SetMaker.pm) -# by adding the libraries you want to the following line. For each key=>value -# in the list, if a directory (or link to a directory) with name 'key' appears -# in the templates directory, then a button with name 'value' will be placed at -# the top of the problem browser. (No button will appear if there is no -# directory or link with the given name in the templates directory.) For -# example, -# -# $courseFiles{problibs} = {rochester => "Rochester", asu => "ASU"}; -# -# would add two buttons, one for the Rochester library and one for the ASU -# library, provided templates/rochester and templates/asu exists either as -# subdirectories or links to other directories. The "NPL Directory" button -# activated below gives access to all the directories in the National -# Problem Library. -# -$courseFiles{problibs} = { - Library => "NPL Directory", -# rochesterLibrary => "Rochester", -# asuLibrary => "Arizona State", -# dcdsLibrary => "Detroit CDS", -# dartmouthLibrary => "Dartmouth", -# indianaLibrary => "Indiana", -# osuLibrary => "Ohio State", - capaLibrary => "CAPA", - ucsbLibrary => "UCSB" -}; - ################################################################################ # Logs ################################################################################ @@ -551,7 +548,7 @@ # your school. If just a few courses are in a different timezone, set this in # course.conf for the affected courses instead. # -$siteDefaults{timezone} ="US/Eastern"; +$siteDefaults{timezone} = ""; # The default_templates_course is used by default to create a new course. # The contents of the templates directory are copied from this course Index: system.template =================================================================== RCS file: /webwork/cvs/system/webwork2/conf/templates/math/system.template,v retrieving revision 1.6.2.1.2.2 retrieving revision 1.6.2.1.2.3 diff -Lconf/templates/math/system.template -Lconf/templates/math/system.template -u -r1.6.2.1.2.2 -r1.6.2.1.2.3 --- conf/templates/math/system.template +++ conf/templates/math/system.template @@ -28,7 +28,8 @@ <title><!--#path style="text" text=" : " textonly="1"--></title> <!--#head--> </head> -<body bgcolor="white" onload="if (typeof(initializeAction) == 'function') {initializeAction()}"> + +<body bgcolor="white" onload="if (typeof(initializeWWquestion) == 'function') {initializeWWquestion()}"> <div id="masthead"> <div id="loginstatus"> Index: system.template =================================================================== RCS file: /webwork/cvs/system/webwork2/conf/templates/ur/system.template,v retrieving revision 1.3.4.1.2.2 retrieving revision 1.3.4.1.2.3 diff -Lconf/templates/ur/system.template -Lconf/templates/ur/system.template -u -r1.3.4.1.2.2 -r1.3.4.1.2.3 --- conf/templates/ur/system.template +++ conf/templates/ur/system.template @@ -5,7 +5,7 @@ <!-- ################################################################################ # WeBWorK Online Homework Delivery System -# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# Copyright � 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ # $CVSHeader$ # # This program is free software; you can redistribute it and/or modify it under @@ -27,6 +27,9 @@ <link rel="stylesheet" type="text/css" href="<!--#url type="webwork" name="htdocs"-->/css/ur.css"/> <title><!--#path style="text" text=" : " textonly="1"--></title> <!--#head--> + +<link rel="stylesheet" type="text/css" href="<!--#url type="webwork" name="htdocs"-->/css/ur.css"/> + </head> <body bgcolor="white" onload="if (typeof(initializeAction) == 'function') {initializeAction()}"> Index: Copying =================================================================== RCS file: /webwork/cvs/system/webwork2/doc/Copying,v retrieving revision 1.1.26.1 retrieving revision 1.1.26.2 diff -Ldoc/Copying -Ldoc/Copying -u -r1.1.26.1 -r1.1.26.2 --- doc/Copying +++ doc/Copying @@ -136,12 +136,12 @@ under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: - a) accompany it with the complete corresponding machine-readable + a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, - b) accompany it with a written offer, valid for at least three + b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be --- doc/docbook/install/Installing-WeBWorK.xml +++ /dev/null @@ -1,155 +0,0 @@ -<?xml version="1.0" standalone="no"?> -<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" -"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [ -<!ENTITY WW "WeBWorK"> -]> -<article> - <articleinfo> - <title>Installing WeBWorK</title> - <author><firstname>Sam</firstname><surname>Hathaway</surname></author> - <copyright><year>2005</year><holder>The WeBWorK Project</holder></copyright> - </articleinfo> - <section id="intro"> - <title>Introduction</title> - <para>FiXME: purpose of this article, assumptions, etc.</para> - </section> - <section id="sysreq"> - <title>System Requirements</title> - <para>&WW; requires several software packages to run. The installation procedure varies depending on your operating system.</para> - <section id="os"> - <title>Operating System</title> - <para>&WW; runs on most POSIX-compliant operating systems. It has been tested on FreeBSD, Linux, Solaris, Mac OS X.</para> - </section> - <section id="perl"> - <title>Perl</title> - <para>&WW; requires Perl 5.6 or higher and several of the core modules included in the Perl distribution.</para> - <itemizedlist> - <listitem><simpara><ulink type="http" url="http://perl.org/">Perl web site</ulink></simpara></listitem> - <listitem><simpara><ulink type="http" url="http://packages.debian.org/perl">Debian package perl</ulink></simpara></listitem> - </itemizedlist> - <para>The following non-core Perl modules are also required. All are available from <ulink type="http" url="http://cpan.org/">CPAN</ulink>, and many OS vendors provide packages of these modules. To see if <replaceable>Module</replaceable> is installed on your system, run <command>perl -M<replaceable>Module</replaceable> -e 'print "installed!\n"'</command>. To install <replaceable>Module</replaceable> from CPAN, run <command>perl -MCPAN -e "install <replaceable>Module</replaceable>"</command>.</para> - <segmentedlist> - <title>Required Perl Modules</title> - <?dbhtml list-presentation="table"?> - <segtitle>Module</segtitle> - <segtitle>Debian package</segtitle> - <seglistitem> - <seg>Apache::Request</seg> - <seg><ulink type="http" url="http://packages.debian.org/libapache-request-perl">libapache-request-perl</ulink></seg> - </seglistitem> - <seglistitem> - <seg>Data::UUID</seg> - <seg>not available<footnote><para>The package <ulink type="http" url="http://packages.debian.org/libossp-uuid-perl">libossp-uuid-perl</ulink> provides a clone of Data::UUID that alledgedly has the same interface. It has not been tested with &WW;</para></footnote></seg> - </seglistitem> - <seglistitem> - <seg>String::ShellQuote</seg> - <seg><ulink type="http" url="http://packages.debian.org/libstring-shellquote-perl">libstring-shellquote-perl</ulink></seg> - </seglistitem> - <seglistitem> - <seg>DateTime</seg> - <seg><ulink type="http" url="http://packages.debian.org/libdatetime-perl">libdatetime-perl</ulink></seg> - </seglistitem> - <seglistitem> - <seg>Date::Format</seg> - <seg><ulink type="http" url="http://packages.debian.org/libtimedate-perl">libtimedate-perl</ulink></seg> - </seglistitem> - <seglistitem> - <seg>Date::Parse</seg> - <seg><ulink type="http" url="http://packages.debian.org/libtimedate-perl">libtimedate-perl</ulink></seg> - </seglistitem> - <seglistitem> - <seg>GD</seg> - <seg><ulink type="http" url="http://packages.debian.org/libgd-gd2-perl">libgd-gd2-perl</ulink></seg> - </seglistitem> - <seglistitem> - <seg>Mail::Sender</seg> - <seg><ulink type="http" url="http://packages.debian.org/libmail-sender-perl">libmail-sender-perl</ulink></seg> - </seglistitem> - <seglistitem> - <seg>SOAP::Lite</seg> - <seg><ulink type="http" url="http://packages.debian.org/libsoap-lite-perl">libsoap-lite-perl</ulink></seg> - </seglistitem> - <seglistitem> - <seg>Time::HiRes</seg> - <seg><ulink type="http" url="http://packages.debian.org/libtime-hires-perl">libtime-hires-perl</ulink></seg> - </seglistitem> - <seglistitem> - <seg>XML::Parser</seg> - <seg><ulink type="http" url="http://packages.debian.org/libxml-parser-perl">libxml-parser-perl</ulink></seg> - </seglistitem> - <seglistitem> - <seg>XML::Parser::EasyTree</seg> - <seg>not available</seg> - </seglistitem> - <seglistitem> - <seg>XML::Writer</seg> - <seg><ulink type="http" url="http://packages.debian.org/libxml-writer-perl">libxml-writer-perl</ulink></seg> - </seglistitem> - <seglistitem> - <seg>DBI</seg> - <seg><ulink type="http" url="http://packages.debian.org/libdbi-perl">libdbi-perl</ulink></seg> - </seglistitem> - <seglistitem> - <seg>DBD::mysql</seg> - <seg><ulink type="http" url="http://packages.debian.org/libdbd-mysql-perl">libdbd-mysql-perl</ulink></seg> - </seglistitem> - </segmentedlist> - </section> - <section id="apache"> - <title>Apache 1.3</title> - <para>&WW; requires Apache 1.3.x and the <literal>mod_alias</literal> module.</para> - <itemizedlist> - <listitem><simpara><ulink type="http" url="http://httpd.apache.org/">Apache web site</ulink></simpara></listitem> - <listitem><simpara><ulink type="http" url="http://packages.debian.org/apache">Debian package apache</ulink></simpara></listitem> - </itemizedlist> - </section> - <section id="modperl"> - <title>mod_perl</title> - <para>&WW; is a mod_perl application and requires mod_perl 1.x. If compiling mod_perl from source, use the <envar>EVERYTHING=1</envar> flag to enable all mod_perl features. Most vendors compile their mod_perl packages with this setting enabled.</para> - <itemizedlist> - <listitem><simpara><ulink type="http" url="http://perl.apache.org/">mod_perl web site</ulink></simpara></listitem> - <listitem><simpara><ulink type="http" url="http://packages.debian.org/libapache-mod-perl">Debian package libapache-mod-perl</ulink></simpara></listitem> - </itemizedlist> - </section> - <section id="mysql"> - <title>MySQL</title> - <para>&WW; stores its data in a MySQL database. &WW; has been tested with MySQL 3 and 4. It should work with MySQL 5 as well. The MySQL server can be on the same machine as &WW; or on a remote machine. You will need the <command>mysql</command> client to create the &WW; database.</para> - <itemizedlist> - <listitem><simpara><ulink type="http" url="http://mysql.com/">MySQL web site</ulink></simpara></listitem> - <listitem><simpara><ulink type="http" url="http://packages.debian.org/mysql-server">Debian package mysql-server</ulink></simpara></listitem> - </itemizedlist> - </section> - <section id="latex"> - <title>LaTeX</title> - <para>&WW; uses LaTeX for generating hardcopy output and displaying mathematics graphically. Any standard LaTeX distribution that provides the commands <command>latex</command> and <command>pdflatex</command> should work. &WW; has been tested with teTeX.</para> - <itemizedlist> - <listitem><simpara><ulink type="http" url="http://tug.org/tetex/">teTeX web site</ulink></simpara></listitem> - <listitem><simpara>Debian packages <ulink type="http" url="http://packages.debian.org/tetex-bin">tetex-bin</ulink> and <ulink type="http" url="http://packages.debian.org/tetex-extra">tetex-extra</ulink></simpara></listitem> - </itemizedlist> - </section> - <section id="netpbm"> - <title>Netpbm</title> - <para>&WW; requires Netpbm, an image manipulation library, to convert images among the GIF, PNG, and EPS formats.</para> - <itemizedlist> - <listitem><simpara><ulink type="http" url="http://netpbm.sf.net/">Netpbm web site</ulink></simpara></listitem> - <listitem><simpara>Debian package <ulink type="http" url="http://packages.debian.org/netpbm">netpbm</ulink></simpara></listitem> - </itemizedlist> - </section> - <section id="dvipng"> - <title>dvipng</title> - <para>&WW; uses dvipng to display mathematics graphically. It is only required if you wish to use the <literal>images</literal> display mode. &WW; is initially configured to work with dvipng 1.0 or greater, but can be reconfigured to work with dvipng 0.8 or 0.9. dvipng requires the <filename>preview.sty</filename> file from the preview-latex package.</para> - <itemizedlist> - <listitem><simpara><ulink type="http" url="http://dvipng.sf.net/">dvipng web site</ulink></simpara></listitem> - <listitem><simpara>Debian packages <ulink type="http" url="http://packages.debian.org/dvipng">dvipng</ulink> and <ulink type="http" url="http://packages.debian.org/preview-latex-style">preview-latex-style</ulink></simpara></listitem> - </itemizedlist> - </section> - <section id="tth"> - <title>tth</title> - <para>&WW; uses TtH to display mathematics as formatted HTML. It is only required if you wish to use the <literal>formatted-text</literal> display mode.</para> - <itemizedlist> - <listitem><simpara><ulink type="http" url="http://hutchinson.belmont.ma.us/tth/">TtH web site</ulink></simpara></listitem> - <listitem><simpara>Debian package <ulink type="http" url="http://packages.debian.org/tth">tth</ulink></simpara></listitem> - </itemizedlist> - </section> - </section> -</article> \ No newline at end of file Index: WebworkSOAP.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WebworkSOAP.pm,v retrieving revision 1.12.2.1 retrieving revision 1.12.2.2 diff -Llib/WebworkSOAP.pm -Llib/WebworkSOAP.pm -u -r1.12.2.1 -r1.12.2.2 --- lib/WebworkSOAP.pm +++ lib/WebworkSOAP.pm @@ -57,6 +57,12 @@ return $self; } +sub array_to_soap_string { + my @array = @_; + @array = map { SOAP::Data->type( 'string', $_ ) } @array; + return \@array; +} + sub soap_fault_authen { die SOAP::Fault->faultcode(SOAPERROR_AUTHEN_FAILED) ->faultstring("SOAP Webservice Authentication Failed!"); @@ -103,7 +109,7 @@ } $@ and soap_fault_major("Course Environment cannot be constructed."); my @test = listCourses($ce); - return \@test; + return array_to_soap_string( @test ); } =pod @@ -127,7 +133,7 @@ eval { $soapEnv->{db}->deleteKey($userID) }; eval { $soapEnv->{db}->addKey($Key) }; $@ and soap_fault(SOAPERROR_USER_NOT_FOUND,"User not found."); - return $newKey; + return SOAP::Data->type( 'string', $newKey ); } =pod @@ -171,7 +177,7 @@ initializeUserProblem($UserProblem, $seed); eval { $db->addUserProblem($UserProblem) }; } - return @results; + return array_to_soap_string( @results ); #FIXME WSDL says $string, not @string? } =pod @@ -196,7 +202,7 @@ } push(@grades,$grade); } - return \@grades; + return array_to_soap_string( @grades ); } =pod @@ -204,7 +210,7 @@ _IN authenKey $string _IN courseName $string _IN setID $string -_RETURN @string +_RETURN $WebworkSOAP::Classes::GlobalSet =end WSDL =cut sub get_set_data { @@ -216,8 +222,6 @@ } my $set = new WebworkSOAP::Classes::GlobalSet($setData); return $set; - - } #################################################################### @@ -240,7 +244,7 @@ my $soapEnv = new WebworkSOAP($authenKey,$courseName); my $newPassword = $soapEnv->{db}->newPassword; %$newPassword = %$record; - return $soapEnv->{db}->addPassword($newPassword); + return SOAP::Data->type( 'string', $soapEnv->{db}->addPassword($newPassword) ); } =pod @@ -254,7 +258,7 @@ sub put_password { my ($self,$authenKey,$courseName,$record) = @_; my $soapEnv = new WebworkSOAP($authenKey,$courseName); - return $soapEnv->{db}->putPassword($record); + return SOAP::Data->type( 'string', $soapEnv->{db}->putPassword($record) ); } =pod @@ -268,7 +272,7 @@ my ($self,$authenKey,$courseName) = @_; my $soapEnv = new WebworkSOAP($authenKey,$courseName); my @tempArray = $soapEnv->{db}->listPasswords; - return \@tempArray; + return array_to_soap_string( @tempArray ); } =pod @@ -326,7 +330,7 @@ my $soapEnv = new WebworkSOAP($authenKey,$courseName); my $newPermissionLevel = $soapEnv->{db}->newPermissionLevel; %$newPermissionLevel = %$record; - return $soapEnv->{db}->addPermissionLevel($newPermissionLevel); + return SOAP::Data->type( 'string', $soapEnv->{db}->addPermissionLevel($newPermissionLevel) ); } =pod @@ -340,7 +344,7 @@ sub put_permission { my ($self,$authenKey,$courseName,$record) = @_; my $soapEnv = new WebworkSOAP($authenKey,$courseName); - return $soapEnv->{db}->putPermissionLevel($record); + return SOAP::Data->type( 'string', $soapEnv->{db}->putPermissionLevel($record) ); } =pod @@ -354,7 +358,7 @@ my ($self,$authenKey,$courseName) = @_; my $soapEnv = new WebworkSOAP($authenKey,$courseName); my @tempArray = $soapEnv->{db}->listPermissionLevels; - return \@tempArray; + return array_to_soap_string( @tempArray ); } =pod @@ -412,7 +416,7 @@ my $soapEnv = new WebworkSOAP($authenKey,$courseName); my $newKey = $soapEnv->{db}->newKey; %$newKey = %$record; - return $soapEnv->{db}->addKey($newKey); + return SOAP::Data->type( 'string', $soapEnv->{db}->addKey($newKey) ); } =pod @@ -426,7 +430,7 @@ sub put_key { my ($self,$authenKey,$courseName,$record) = @_; my $soapEnv = new WebworkSOAP($authenKey,$courseName); - return $soapEnv->{db}->putKey($record); + return SOAP::Data->type( 'string', $soapEnv->{db}->putKey($record) ); } =pod @@ -440,7 +444,7 @@ my ($self,$authenKey,$courseName) = @_; my $soapEnv = new WebworkSOAP($authenKey,$courseName); my @tempArray = $soapEnv->{db}->listKeys; - return \@tempArray; + return array_to_soap_string( @tempArray ); } =pod @@ -498,7 +502,7 @@ my $soapEnv = new WebworkSOAP($authenKey,$courseName); my $newUser = $soapEnv->{db}->newUser; %$newUser = %$record; - return $soapEnv->{db}->addUser($newUser); + return SOAP::Data->type( 'string', $soapEnv->{db}->addUser($newUser) ); } =pod @@ -512,7 +516,7 @@ sub put_user { my ($self,$authenKey,$courseName,$record) = @_; my $soapEnv = new WebworkSOAP($authenKey,$courseName); - return $soapEnv->{db}->putUser($record); + return SOAP::Data->type( 'string', $soapEnv->{db}->putUser($record) ); } =pod @@ -526,7 +530,7 @@ my ($self,$authenKey,$courseName) = @_; my $soapEnv = new WebworkSOAP($authenKey,$courseName); my @tempArray = $soapEnv->{db}->listUsers; - return \@tempArray; + return array_to_soap_string( @tempArray ); } =pod @@ -578,7 +582,7 @@ sub delete_user { my ($self,$authenKey,$courseName,$userID) = @_; my $soapEnv = new WebworkSOAP($authenKey,$courseName); - return $soapEnv->{db}->deleteUser($userID); + return SOAP::Data->type( 'string', $soapEnv->{db}->deleteUser($userID) ); } ################################################## @@ -598,7 +602,7 @@ my $soapEnv = new WebworkSOAP($authenKey,$courseName); my $newGlobalSet = $soapEnv->{db}->newGlobalSet; %$newGlobalSet = %$record; - return $soapEnv->{db}->addGlobalSet($newGlobalSet); + return SOAP::Data->type( 'string', $soapEnv->{db}->addGlobalSet($newGlobalSet) ); } =pod @@ -612,7 +616,7 @@ sub put_global_set { my ($self,$authenKey,$courseName,$record) = @_; my $soapEnv = new WebworkSOAP($authenKey,$courseName); - return $soapEnv->{db}->putGlobalSet($record); + return SOAP::Data->type( 'string', $soapEnv->{db}->putGlobalSet($record) ); } =pod @@ -626,10 +630,9 @@ my ($self,$authenKey,$courseName) = @_; my $soapEnv = new WebworkSOAP($authenKey,$courseName); my @tempArray = $soapEnv->{db}->listGlobalSets; - return \@tempArray; + return array_to_soap_string( @tempArray ); } - =pod =begin WSDL _IN authenKey $string @@ -698,7 +701,7 @@ sub delete_global_set { my ($self,$authenKey,$courseName,$setID) = @_; my $soapEnv = new WebworkSOAP($authenKey,$courseName); - return $soapEnv->{db}->deleteGlobalSet($setID); + return SOAP::Data->type( 'string', $soapEnv->{db}->deleteGlobalSet($setID) ); } ################################################## @@ -718,7 +721,7 @@ my $soapEnv = new WebworkSOAP($authenKey,$courseName); my $newGlobalProblem = $soapEnv->{db}->newGlobalProblem; %$newGlobalProblem = %$record; - return $soapEnv->{db}->addGlobalProblem($newGlobalProblem); + return SOAP::Data->type( 'string', $soapEnv->{db}->addGlobalProblem($newGlobalProblem) ); } =pod @@ -732,7 +735,7 @@ sub put_global_problem { my ($self,$authenKey,$courseName,$record) = @_; my $soapEnv = new WebworkSOAP($authenKey,$courseName); - return $soapEnv->{db}->putGlobalProblem($record); + return SOAP::Data->type( 'string', $soapEnv->{db}->putGlobalProblem($record) ); } =pod @@ -747,7 +750,7 @@ my ($self,$authenKey,$courseName,$setID) = @_; my $soapEnv = new WebworkSOAP($authenKey,$courseName); my @tempArray = $soapEnv->{db}->listGlobalProblems($setID); - return \@tempArray; + return array_to_soap_string( @tempArray ); } =pod @@ -773,7 +776,7 @@ =begin _IN authenKey $string _IN courseName $string -_IN problemIDs @string +_IN problemIDs @string An array reference: [userID setID problemID] _RETURN @WebworkSOAP::Classes::GlobalProblem Array of user objects =end WSDL =cut @@ -783,7 +786,7 @@ my @problemData = $soapEnv->{db}->getGlobalProblems(@$problemIDs); my @problems; for(my $i=0;$i<@problemData;$i++) { - push(@problems,new WebworkSOAP::Classes::GlobalProblem(@problemData[$i])); + push(@problems,new WebworkSOAP::Classes::GlobalProblem(@problemData[$i])); #FIXME $problemData[$i]? } return \@problems; } @@ -820,7 +823,7 @@ sub delete_global_problem { my ($self,$authenKey,$courseName,$setID,$problemID) = @_; my $soapEnv = new WebworkSOAP($authenKey,$courseName); - return $soapEnv->{db}->deleteGlobalProblem($setID,$problemID); + return SOAP::Data->type( 'string', $soapEnv->{db}->deleteGlobalProblem($setID,$problemID) ); } ################################################## @@ -840,7 +843,7 @@ my $soapEnv = new WebworkSOAP($authenKey,$courseName); my $newUserProblem = $soapEnv->{db}->newUserProblem; %$newUserProblem = %$record; - return $soapEnv->{db}->addUserProblem($newUserProblem); + return SOAP::Data->type( 'string', $soapEnv->{db}->addUserProblem($newUserProblem) ); } =pod @@ -854,7 +857,7 @@ sub put_user_problem { my ($self,$authenKey,$courseName,$record) = @_; my $soapEnv = new WebworkSOAP($authenKey,$courseName); - return $soapEnv->{db}->putUserProblem($record); + return SOAP::Data->type( 'string', $soapEnv->{db}->putUserProblem($record) ); } =pod @@ -862,14 +865,15 @@ _IN authenKey $string _IN courseName $string _IN userID $string +_IN setID $string _RETURN @string of names objects. =end WSDL =cut sub list_user_problems { - my ($self,$authenKey,$courseName,$userID) = @_; + my ($self,$authenKey,$courseName,$userID,$setID) = @_; my $soapEnv = new WebworkSOAP($authenKey,$courseName); - my @tempArray = $soapEnv->{db}->listUserProblems($userID); - return \@tempArray; + my @tempArray = $soapEnv->{db}->listUserProblems($userID,$setID); + return array_to_soap_string( @tempArray ); } =pod @@ -896,7 +900,7 @@ =begin WSDL _IN authenKey $string _IN courseName $string -_IN userProblemIDs @string +_IN userProblemIDs @string A 3 element array: { user_ID, setID, problemID } _RETURN @WebworkSOAP::Classes::UserProblem of names objects. =end WSDL =cut @@ -945,7 +949,7 @@ sub delete_user_problem { my ($self,$authenKey,$courseName,$userID,$setID,$problemID) = @_; my $soapEnv = new WebworkSOAP($authenKey,$courseName); - return $soapEnv->{db}->deleteUserProblem($userID,$setID,$problemID); + return SOAP::Data->type( 'string', $soapEnv->{db}->deleteUserProblem($userID,$setID,$problemID) ); } ################################################## @@ -965,7 +969,7 @@ my $soapEnv = new WebworkSOAP($authenKey,$courseName); my $newUserSet = $soapEnv->{db}->newUserSet; %$newUserSet = %$record; - return $soapEnv->{db}->addUserSet($newUserSet); + return SOAP::Data->type( 'string', $soapEnv->{db}->addUserSet($newUserSet) ); } =pod @@ -979,7 +983,7 @@ sub put_user_set { my ($self,$authenKey,$courseName,$record) = @_; my $soapEnv = new WebworkSOAP($authenKey,$courseName); - return $soapEnv->{db}->addUserSet($record); + return SOAP::Data->type( 'string', $soapEnv->{db}->addUserSet($record) ); } =pod @@ -994,7 +998,7 @@ my ($self,$authenKey,$courseName,$userID) = @_; my $soapEnv = new WebworkSOAP($authenKey,$courseName); my @tempArray = $soapEnv->{db}->listUserSets($userID); - return \@tempArray; + return array_to_soap_string( @tempArray ); } =pod @@ -1066,7 +1070,7 @@ sub delete_user_set { my ($self,$authenKey,$courseName,$userID,$setID) = @_; my $soapEnv = new WebworkSOAP($authenKey,$courseName); - return $soapEnv->{db}->deleteUserSet($userID,$setID); + return SOAP::Data->type( 'string', $soapEnv->{db}->deleteUserSet($userID,$setID) ); } Index: DB.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/DB.pm,v retrieving revision 1.104.2.2.2.1 retrieving revision 1.104.2.2.2.2 diff -Llib/WeBWorK/DB.pm -Llib/WeBWorK/DB.pm -u -r1.104.2.2.2.1 -r1.104.2.2.2.2 --- lib/WeBWorK/DB.pm +++ lib/WeBWorK/DB.pm @@ -151,6 +151,10 @@ 'WeBWorK::DB::Ex::DependencyNotFound' => { isa => 'WeBWorK::DB::Ex::RecordNotFound', }, + 'WeBWorK::DB::Ex::TableMissing' => { + isa => 'WeBWorK::DB::Ex', + description =>"missing table", + }, ); ################################################################################ @@ -496,7 +500,7 @@ eval { return $self->{user}->add($User); }; - if (my $ex = caught WeBWorK::DB::Schema::Ex::RecordExists) { + if (my $ex = caught WeBWorK::DB::Ex::RecordExists) { croak "addUser: user exists (perhaps you meant to use putUser?)"; } elsif ($@) { die $@; @@ -601,7 +605,7 @@ eval { return $self->{password}->add($Password); }; - if (my $ex = caught WeBWorK::DB::Schema::Ex::RecordExists) { + if (my $ex = caught WeBWorK::DB::Ex::RecordExists) { croak "addPassword: password exists (perhaps you meant to use putPassword?)"; } elsif ($@) { die $@; @@ -694,7 +698,7 @@ eval { return $self->{permission}->add($PermissionLevel); }; - if (my $ex = caught WeBWorK::DB::Schema::Ex::RecordExists) { + if (my $ex = caught WeBWorK::DB::Ex::RecordExists) { croak "addPermissionLevel: permission level exists (perhaps you meant to use putPermissionLevel?)"; } elsif ($@) { die $@; @@ -780,7 +784,7 @@ eval { return $self->{key}->add($Key); }; - if (my $ex = caught WeBWorK::DB::Schema::Ex::RecordExists) { + if (my $ex = caught WeBWorK::DB::Ex::RecordExists) { croak "addKey: key exists (perhaps you meant to use putKey?)"; } elsif ($@) { die $@; @@ -913,7 +917,7 @@ eval { return $self->{locations}->add($Location); }; - if ( my $ex = caught WeBWorK::DB::Schema::Ex::RecordExists ) { + if ( my $ex = caught WeBWorK::DB::Ex::RecordExists ) { croak "addLocation: location exists (perhaps you meant to use putLocation?)"; } elsif ($@) { die $@; @@ -1014,7 +1018,7 @@ eval { return $self->{location_addresses}->add($LocationAddress); }; - if (my $ex = caught WeBWorK::DB::Schema::Ex::RecordExists) { + if (my $ex = caught WeBWorK::DB::Ex::RecordExists) { croak "addLocationAddress: location address exists (perhaps you meant to use putLocationAddress?)"; } elsif ($@) { die $@; @@ -1085,7 +1089,7 @@ return $self->{set}->add($GlobalSet); }; - if (my $ex = caught WeBWorK::DB::Schema::Ex::RecordExists) { + if (my $ex = caught WeBWorK::DB::Ex::RecordExists) { croak "addGlobalSet: global set exists (perhaps you meant to use putGlobalSet?)"; } elsif ($@) { die $@; @@ -1177,7 +1181,7 @@ eval { return $self->{set_user}->add($UserSet); }; - if (my $ex = caught WeBWorK::DB::Schema::Ex::RecordExists) { + if (my $ex = caught WeBWorK::DB::Ex::RecordExists) { croak "addUserSet: user set exists (perhaps you meant to use putUserSet?)"; } elsif ($@) { die $@; @@ -1289,7 +1293,7 @@ eval { return $self->{set_version}->add($SetVersion); }; - if (my $ex = caught WeBWorK::DB::Schema::Ex::RecordExists) { + if (my $ex = caught WeBWorK::DB::Ex::RecordExists) { croak "addSetVersion: set version exists (perhaps you meant to use putSetVersion?)"; } elsif ($@) { die $@; @@ -1403,7 +1407,7 @@ eval { return $self->{set_locations}->add($GlobalSetLocation); }; - if (my $ex = caught WeBWorK::DB::Schema::Ex::RecordExists) { + if (my $ex = caught WeBWorK::DB::Ex::RecordExists) { croak "addGlobalSetLocation: global set_location exists (perhaps you meant to use putGlobalSetLocation?)"; } elsif ($@) { die $@; @@ -1502,7 +1506,7 @@ eval { return $self->{set_locations_user}->add($UserSetLocation); }; - if (my $ex = caught WeBWorK::DB::Schema::Ex::RecordExists) { + if (my $ex = caught WeBWorK::DB::Ex::RecordExists) { croak "addUserSetLocation: user set_location exists (perhaps you meant to use putUserSetLocation?)"; } elsif ($@) { die $@; @@ -1604,7 +1608,7 @@ eval { return $self->{problem}->add($GlobalProblem); }; - if (my $ex = caught WeBWorK::DB::Schema::Ex::RecordExists) { + if (my $ex = caught WeBWorK::DB::Ex::RecordExists) { croak "addGlobalProblem: global problem exists (perhaps you meant to use putGlobalProblem?)"; } elsif ($@) { die $@; @@ -1702,7 +1706,7 @@ eval { return $self->{problem_user}->add($UserProblem); }; - if (my $ex = caught WeBWorK::DB::Schema::Ex::RecordExists) { + if (my $ex = caught WeBWorK::DB::Ex::RecordExists) { croak "addUserProblem: user problem exists (perhaps you meant to use putUserProblem?)"; } elsif ($@) { die $@; @@ -1846,7 +1850,7 @@ eval { return $self->{problem_version}->add($ProblemVersion); }; - if (my $ex = caught WeBWorK::DB::Schema::Ex::RecordExists) { + if (my $ex = caught WeBWorK::DB::Ex::RecordExists) { croak "addProblemVersion: problem version exists (perhaps you meant to use putProblemVersion?)"; } elsif ($@) { die $@; Index: ContentGenerator.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator.pm,v retrieving revision 1.191.2.1.2.2 retrieving revision 1.191.2.1.2.3 diff -Llib/WeBWorK/ContentGenerator.pm -Llib/WeBWorK/ContentGenerator.pm -u -r1.191.2.1.2.2 -r1.191.2.1.2.3 --- lib/WeBWorK/ContentGenerator.pm +++ lib/WeBWorK/ContentGenerator.pm @@ -51,6 +51,7 @@ use URI::Escape; use WeBWorK::Debug; use WeBWorK::PG; +use MIME::Base64; use WeBWorK::Template qw(template); use mod_perl; @@ -661,8 +662,17 @@ if (defined $setID) { print CGI::start_ul(); print CGI::start_li(); # $setID - print &$makelink("${pfx}ProblemSet", text=>"$prettySetID", urlpath_args=>{%args,setID=>$setID}, systemlink_args=>\%systemlink_args); - # FIXME i think we only want this if the problem set is not a gateway quiz + # show a link if we're displaying a homework set, or a version + # of a gateway assignment; to know if it's a gateway + # assignment, we have to get the set record. + my ($globalSetID) = ( $setID =~ /(.+?)(,v\d+)?$/ ); + my $setRecord = $db->getGlobalSet( $globalSetID ); + if ( $setRecord->assignment_type !~ /gateway/ ) { + print &$makelink("${pfx}ProblemSet", text=>"$prettySetID", urlpath_args=>{%args,setID=>$setID}, systemlink_args=>\%systemlink_args); + } elsif ($setID =~ /,v(\d)+$/) { + print &$makelink("${pfx}GatewayQuiz", text=>"$prettySetID", urlpath_args=>{%args,setID=>$setID}, systemlink_args=>\%systemlink_args); + } + if (defined $problemID) { print CGI::start_ul(); print CGI::start_li(); # $problemID @@ -693,7 +703,8 @@ print CGI::start_li(); # Homework Set Editor print &$makelink("${pfx}ProblemSetList", urlpath_args=>{%args}, systemlink_args=>\%systemlink_args); - if (defined $setID) { + ## only show editor link for non-versioned sets + if (defined $setID && $setID !~ /,v\d+$/ ) { print CGI::start_ul(); print CGI::start_li(); # $setID print &$makelink("${pfx}ProblemSetDetail", text=>"$prettySetID", urlpath_args=>{%args,setID=>$setID}, systemlink_args=>\%systemlink_args); @@ -719,7 +730,11 @@ print CGI::li(&$makelink("${pfx}Stats", text=>"$eUserID", urlpath_args=>{%args,statType=>"student",userID=>$eUserID}, systemlink_args=>\%systemlink_args)); } if (defined $setID) { - print CGI::li(&$makelink("${pfx}Stats", text=>"$prettySetID", urlpath_args=>{%args,statType=>"set",setID=>$setID}, systemlink_args=>\%systemlink_args)); + # make sure we don't try to send a versioned + # set id in to the stats link + my ( $nvSetID ) = ( $setID =~ /(.+?)(,v\d+)?$/ ); + my ( $nvPretty ) = ( $prettySetID =~ /(.+?)(,v\d+)?$/ ); + print CGI::li(&$makelink("${pfx}Stats", text=>"$nvPretty", urlpath_args=>{%args,statType=>"set",setID=>$nvSetID}, systemlink_args=>\%systemlink_args)); } print CGI::end_ul(); } @@ -733,7 +748,11 @@ print CGI::li(&$makelink("${pfx}StudentProgress", text=>"$eUserID", urlpath_args=>{%args,statType=>"student",userID=>$eUserID}, systemlink_args=>\%systemlink_args)); } if (defined $setID) { - print CGI::li(&$makelink("${pfx}StudentProgress", text=>"$prettySetID", urlpath_args=>{%args,statType=>"set",setID=>$setID}, systemlink_args=>\%systemlink_args)); + # make sure we don't try to send a versioned + # set id in to the stats link + my ( $nvSetID ) = ( $setID =~ /(.+?)(,v\d+)?$/ ); + my ( $nvPretty ) = ( $prettySetID =~ /(.+?)(,v\d+)?$/ ); + print CGI::li(&$makelink("${pfx}StudentProgress", text=>"$nvPretty", urlpath_args=>{%args,statType=>"set",setID=>$nvSetID}, systemlink_args=>\%systemlink_args)); } print CGI::end_ul(); } @@ -1439,8 +1458,11 @@ return "" unless $authz->hasPermissions($userID, "submit_feedback"); my $feedbackURL = $r->ce->{courseURLs}{feedbackURL}; + my $feedbackFormURL = $r->ce->{courseURLs}{feedbackFormURL}; if (defined $feedbackURL and $feedbackURL ne "") { return $self->feedbackMacro_url($feedbackURL); + } elsif (defined $feedbackFormURL and $feedbackFormURL ne "") { + return $self->feedbackMacro_form($feedbackFormURL,%params); } else { return $self->feedbackMacro_email(%params); } @@ -1462,6 +1484,7 @@ $result .= $self->hidden_authen_fields . "\n"; while (my ($key, $value) = each %params) { + next if $key eq 'pg_object'; # not used in internal feedback mechanism $result .= CGI::hidden($key, $value) . "\n"; } $result .= CGI::p({-align=>"left"}, CGI::submit(-name=>"feedbackForm", -label=>$feedbackName)); @@ -1470,6 +1493,34 @@ return $result; } +sub feedbackMacro_form { + my ($self, $feedbackFormURL, %params) = @_; + my $r = $self->r; + my $ce = $r->ce; + my $urlpath = $r->urlpath; + my $courseID = $urlpath->arg("courseID"); + + # feedback form url + my $feedbackName = $ce->{feedback_button_name} || "Email instructor"; + + my $result = CGI::start_form(-method=>"POST", -action=>$feedbackFormURL,-target=>"WW_info") . "\n"; + $result .= $self->hidden_authen_fields . "\n"; + + while (my ($key,... [truncated message content] |