From 09f6c5029826ba8f993af29fb92e2706f65bf1df Mon Sep 17 00:00:00 2001 From: Michael Gage Date: Sat, 25 Feb 2012 20:39:25 -0500 Subject: [PATCH 1/9] Break global.conf into prelocal.conf, global.conf postlocal.conf The entries in global.conf.dist will seldom be modified -- and in fact if global.conf is not present global.conf.dist will be used instead. The files prelocal.conf.dist and postlocal.conf.dist need to be copied to prelocal.conf and postlocal.conf files and the local modifications applied. database.conf.dist is seldom modified but needs to be copied to database.conf in this version. --- conf/global.conf.dist | 125 +++++--------- conf/postlocal.conf.dist | 274 +++++++++++++++++++++++++++++++ conf/prelocal.conf.dist | 155 +++++++++++++++++ lib/WeBWorK/CourseEnvironment.pm | 9 +- 4 files changed, 476 insertions(+), 87 deletions(-) create mode 100755 conf/postlocal.conf.dist create mode 100755 conf/prelocal.conf.dist diff --git a/conf/global.conf.dist b/conf/global.conf.dist index f9af763b4b..3f724eb2a0 100644 --- a/conf/global.conf.dist +++ b/conf/global.conf.dist @@ -24,26 +24,13 @@ # addition, the $courseName variable holds the name of the current course. ################################################################################ -# Seed variables -################################################################################ - -# Set these variables to correspond to your configuration and preferences. You -# will need to restart the webserver to reset the variables in this section. - -# URL of WeBWorK handler. If WeBWorK is to be on the web server root, use "". Note -# that using "" may not work so we suggest sticking with "/webwork2". -$webwork_url = "/webwork2"; - - -$server_root_url = ""; # e.g. http://webwork.yourschool.edu -$server_userID = ""; # e.g. www-data -$server_groupID = ""; # e.g. wwdata - -# In the apache configuration file (often called httpd.conf) you will find -# User wwadmin --- this is the $server_userID -- of course it may be wwhttpd or some other name -# Group wwdata --- this is the $server_groupID -- this will have different names also +include("conf/prelocal.conf"); +################################################################################ +# prelocal.conf should contain basic information about +# certain directories on your server +################################################################################ # Root directory of PG. $pg_dir = "/opt/webwork/pg"; @@ -56,47 +43,6 @@ $webwork_htdocs_dir = "$webwork_dir/htdocs"; $webwork_courses_url = "/webwork2_course_files"; $webwork_courses_dir = "/opt/webwork/courses"; #(a typical place to put the course directory -################################################################################ -# Paths to external programs -################################################################################ - -# system utilities -$externalPrograms{mv} = "/bin/mv"; -$externalPrograms{cp} = "/bin/cp"; -$externalPrograms{rm} = "/bin/rm"; -$externalPrograms{mkdir} = "/bin/mkdir"; -$externalPrograms{tar} = "/bin/tar"; -$externalPrograms{gzip} = "/bin/gzip"; - -# equation rendering/hardcopy utiltiies -$externalPrograms{latex} = "/usr/bin/latex"; -$externalPrograms{pdflatex} = "/usr/bin/pdflatex --shell-escape"; -$externalPrograms{dvipng} = "/usr/bin/dvipng"; -$externalPrograms{tth} = "/usr/bin/tth"; - -#################################################### -# NetPBM - basic image manipulation utilities -# Most sites only need to configure $netpbm_prefix. -#################################################### -my $netpbm_prefix = "/usr/bin"; -$externalPrograms{giftopnm} = "$netpbm_prefix/giftopnm"; -$externalPrograms{ppmtopgm} = "$netpbm_prefix/ppmtopgm"; -$externalPrograms{pnmtops} = "$netpbm_prefix/pnmtops"; -$externalPrograms{pnmtopng} = "$netpbm_prefix/pnmtopng"; -$externalPrograms{pngtopnm} = "$netpbm_prefix/pngtopnm"; - -# url checker -$externalPrograms{checkurl} = "/usr/bin/lwp-request -d -mHEAD "; # or "/usr/local/bin/w3c -head " - -# image conversions utiltiies -# the source file is given on stdin, and the output expected on stdout. -$externalPrograms{gif2eps} = "$externalPrograms{giftopnm} | $externalPrograms{ppmtopgm} | $externalPrograms{pnmtops} -noturn 2>/dev/null"; -$externalPrograms{png2eps} = "$externalPrograms{pngtopnm} | $externalPrograms{ppmtopgm} | $externalPrograms{pnmtops} -noturn 2>/dev/null"; -$externalPrograms{gif2png} = "$externalPrograms{giftopnm} | $externalPrograms{pnmtopng}"; - -# mysql clients -$externalPrograms{mysql} = "/usr/bin/mysql"; -$externalPrograms{mysqldump} = "/usr/bin/mysqldump"; ################################################################################ # Mail settings @@ -178,6 +124,11 @@ $mail{editor_window_columns} = 100; # Customizing the action of the "Email your instructor" button ################################################### +# This is best done by copying the lines below, entering them +# in the postlocal.conf file and making the desired modifications. +# Then you will not need to update these modifications +# when you download a new version of WeBWorK. + # Use this to customize the text of the feedback button. $feedback_button_name = "Email instructor"; @@ -263,8 +214,11 @@ $webworkDirs{htdocs} = "$webwork_htdocs_dir" || "$webworkDirs{root}/htdoc $webworkURLs{htdocs} = "$webwork_htdocs_url"; # Location of web-accessible temporary files, such as equation images. -$webworkDirs{htdocs_temp} = "$webworkDirs{htdocs}/tmp"; -$webworkURLs{htdocs_temp} = "$webworkURLs{htdocs}/tmp"; +# These two should be set in prelocal.conf -- not here since this can be overwritten by new versions. +$webworkDirs{htdocs_temp} = (defined $webworkDirs{htdocs_temp} ) ? $webworkDirs{htdocs_temp} :"$webworkDirs{htdocs}/tmp"; +$webworkURLs{htdocs_temp} = (defined $webworkURLs{htdocs_temp} ) ? $webworkURLs{htdocs_temp} :"$webworkURLs{htdocs}/tmp"; + +#$webworkURLs{htdocs_temp} = "$webworkURLs{htdocs}/tmp"; # Location of cached equation images. $webworkDirs{equationCache} = "$webworkDirs{htdocs_temp}/equations"; @@ -498,20 +452,18 @@ $default_status = "Enrolled"; # GRANT SELECT ON webwork.* TO webworkRead@localhost IDENTIFIED BY 'passwordRO'; # GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, DROP, INDEX, LOCK TABLES ON webwork.* TO webworkWrite@localhost IDENTIFIED BY 'passwordRW'; -$database_dsn = "dbi:mysql:webwork"; -$database_username = "webworkWrite"; -$database_password = ""; -$database_debug = 0; +################################################################################ +# set these variables in prelocal.conf +# +# $database_dsn = "dbi:mysql:webwork"; +# $database_username = "webworkWrite"; +# #$database_password = ""; #set this in prelocal.conf +################################################################################ -# Variables for sql_moodle database layout. -$moodle_dsn = "dbi:mysql:moodle"; -$moodle_username = $database_username; -$moodle_password = $database_password; -$moodle_table_prefix = "mdl_"; -$moodle17 = 0; +# $database_debug = 0; -# Several database are defined in the file conf/database.conf and stored in the -# hash %dbLayouts. +# Database schemas are defined in the file conf/database.conf and stored in the +# hash %dbLayouts. The standard schema is called "sql_single"; include "conf/database.conf"; # Select the default database layout. This can be overridden in the course.conf @@ -547,8 +499,6 @@ $problemLibrary_db = { # Logs ################################################################################ -# FIXME: take logs out of %webworkFiles/%courseFiles and give them their own -# top-level hash. # Logs data about how long it takes to process problems. (Do not confuse this # with the /other/ timing log which can be set by WeBWorK::Timing and is used @@ -576,7 +526,7 @@ $courseFiles{logs}{login_log} = "$courseDirs{logs}/login.log"; $courseFiles{logs}{activity_log} = ''; ################################################################################ -# Site defaults (FIXME: what other things could be "site defaults"?) +# Site defaults (Usually overridden in postlocal.conf) ################################################################################ # Set the default timezone of courses on this server. To get a list of valid @@ -616,7 +566,7 @@ $siteDefaults{default_templates_course} ="modelCourse"; # current database layout is found. # $authen{user_module} = { - sql_moodle => "WeBWorK::Authen::Moodle", + # sql_moodle => "WeBWorK::Authen::Moodle", # sql_ldap => "WeBWorK::Authen::LDAP", "*" => "WeBWorK::Authen", }; @@ -627,15 +577,12 @@ $authen{user_module} = { # $authen{proctor_module} = "WeBWorK::Authen::Proctor"; +################################################################################ # Options for particular authentication modules +################################################################################ -# $authen{moodle_options} = { -# dsn => $moodle_dsn, -# username => $moodle_username, -# password => $moodle_password, -# table_prefix => $moodle_table_prefix, -# moodle17 => $moodle17, -# }; +# If you are using ldap this next snippet should be copied and entered into postlocal.conf. +# Make modifications there so that it works with your local LDAP protocol $authen{ldap_options} = { # hosts to attempt to connect to, in order. For example: @@ -686,7 +633,7 @@ $authen{ldap_options} = { }; ################################################################################ -# Authorization system +# Authorization system (Make local overrides in postlocal.conf ) ################################################################################ # this section lets you define which groups of users can perform which actions. @@ -703,6 +650,7 @@ $authen{ldap_options} = { grade_proctor => 3, ta => 5, professor => 10, + admin => 20, ); # this hash maps operations to the roles that are allowed to perform those @@ -1082,3 +1030,10 @@ $webworkRoot = $webworkDirs{root}; $webworkURLRoot = $webworkURLs{root}; $pgRoot = $pg{directories}{root}; +################################################################################ +# Site wide overrides are entered into the file postlocal.conf +################################################################################ + +include("conf/postlocal.conf"); + +1; #final line of the file to reassure perl that it was read properly. diff --git a/conf/postlocal.conf.dist b/conf/postlocal.conf.dist new file mode 100755 index 0000000000..b1aa8fc9fc --- /dev/null +++ b/conf/postlocal.conf.dist @@ -0,0 +1,274 @@ +#!perl +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader: webwork2/conf/global.conf.dist,v 1.225 2010/05/18 18:03:31 apizer Exp $ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + +# This file is used to set up the default WeBWorK course environment for all +# requests. Values may be overwritten by the course.conf for a specific course. +# All package variables set in this file are added to the course environment. +# If you wish to set a variable here but omit it from the course environment, +# use the "my" keyword. The $webwork_dir variable is set in the WeBWorK Apache +# configuration file (webwork.apache-config) and is available for use here. In +# addition, the $courseName variable holds the name of the current course. + +################################################################################ +# postlocal.conf -- this file +################################################################################ + +# prelocal.conf and postlocal.conf contain the local modifications commonly made +# when installing WeBWorK on a new site. The configurations in global.conf.dist +# and in database.conf can usually remain untouched. +# +# postlocal.conf is the appropriate place to override permission settings, +# paths to macros and other customizations that are specific to your +# WeBWorK site + + +################################################################################ +# Mail settings +################################################################################ + +################################################################################ +# These configurations must be defined in order for the mailing capabilities +# of webwork to work +################################################################################ + +# Mail sent by the PG system and the mail merge and feedback modules will be +# sent via this SMTP server. +$mail{smtpServer} ="mail.yourschool.edu"; + +# When connecting to the above server, WeBWorK will send this address in the +# MAIL FROM command. This has nothing to do with the "From" address on the mail +# message. It can really be anything, but some mail servers require it contain +# a valid mail domain, or at least be well-formed. +$mail{smtpSender} = 'webwork@yourserver.yourschool.edu'; + + +################################################################################ +# Additional mail settings in global.conf can be overridden here +################################################################################ +$mail{feedbackRecipients} = [ + #'prof1@yourserver.yourdomain.edu', + #'prof2@yourserver.yourdomain.edu', +]; + + + + + +################################################################################ +# Theme +################################################################################ + +$defaultTheme = "math3"; +$defaultThemeTemplate = "system"; + +################################################################################ +# Language +################################################################################ + +$language = "en"; # tr = turkish en=english + +################################################################################ +# Directory overrides +################################################################################ +# Location of web-accessible temporary files, such as equation images. Standard: +#$webworkDirs{htdocs_temp} = "$webworkDirs{htdocs}/tmp"; +#$webworkURLs{htdocs_temp} = "$webworkURLs{htdocs}/tmp"; + +# Alternate locations -- this allows you to place temporary files +# in a location that is not backed up. +#For example. +#$webworkDirs{htdocs_temp} = "/opt/htdocs/wwtmp"; +#$webworkURLs{htdocs_temp} = "$server_root_url/wwtmp"; + +################################################################################ +# Default screen header files +################################################################################ + +# The setHeader preceeds each set in hardcopy output. It is a PG file. +# This is the default file which is used if a specific files is not selected + +$webworkFiles{hardcopySnippets}{setHeader} = "$webworkDirs{conf}/snippets/ASimpleCombinedHeaderFile.pg"; + +#$webworkFiles{hardcopySnippets}{setHeader} = "$courseDirs{templates}/ASimpleHardCopyHeaderFile.pg"; # An alternate default hardcopy only header file +#$webworkFiles{hardcopySnippets}{setHeader} = "$courseDirs{templates}/ASimpleCombinedHeaderFile.pg"; + +# The set header is displayed on the problem set page. It is a PG file. +# One of these default files which is used if a specific files is not selected + +$webworkFiles{screenSnippets}{setHeader} = "$webworkDirs{conf}/snippets/ASimpleCombinedHeaderFile.pg"; + +# $webworkFiles{screenSnippets}{setHeader} = "$courseDirs{templates}/ASimpleScreenHeaderFile.pg"; # An alternate default screen HTML only header file +# $webworkFiles{screenSnippets}{setHeader} = "$courseDirs{templates}/ASimpleCombinedHeaderFile.pg"; + + +################################################################################ +# National Problem Library +################################################################################ + + +# For configuration instructions, see: +# http://webwork.maa.org/wiki/National_Problem_Library +# The directory containing the natinal problem library files. Set to "" if no problem +# library is installed. +$problemLibrary{root} ="/opt/webwork/libraries/NationalProblemLibrary"; + +# 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", +# unionLibrary =>"Union", +# asuLibrary => "Arizona State", +# dcdsLibrary => "Detroit CDS", +# dartmouthLibrary => "Dartmouth", +# indianaLibrary => "Indiana", +# osuLibrary => "Ohio State", +# capaLibrary => "CAPA", +}; + + +################################################################################ +# Site defaults +################################################################################ + +# Set the default timezone of courses on this server. To get a list of valid +# timezones, run: +# +# perl -MDateTime::TimeZone -e 'print join "\n", DateTime::TimeZone::all_names' +# +# To get a list of valid timezone "links" (deprecated names), run: +# +# perl -MDateTime::TimeZone -e 'print join "\n", DateTime::TimeZone::links' +# +# If left blank, the system timezone will be used. This is usually what you +# want. You might want to set this if your server is NOT in the same timezone as +# your school. If just a few courses are in a different timezone, set this in +# course.conf for the affected courses instead. +# +$siteDefaults{timezone} = "America/New_York"; + + +################################################################################ +# Permission levels (see global.conf for list of items to give permissions on ) +################################################################################ +# User roles in order of increasing permissions. Each level has all of the privileges of +# the lower levels. +# guest +# student +# login_proctor +# grade_proctor +# ta +# professor +# admin + +# To modify permission levels use this syntax: +# $permissionLevels{login} = "guest"; + + +################################################################################ +# PG subsystem options +################################################################################ + +# List of enabled display modes. Comment out any modes you don't wish to make +# available for use. +$pg{displayModes} = [ +# "plainText", # display raw TeX for math expressions +# "formattedText", # format math expressions using TtH + "images", # display math expressions as images generated by dvipng + "jsMath", # render TeX math expressions on the client side using jsMath + "MathJax", # render TeX math expressions on the client side using MathJax --- we strongly recommend people install and use MathJax +# "asciimath", # render TeX math expressions on the client side using ASCIIMathML + "LaTeXMathML", # render TeX math expressions on the client side using LaTeXMathML +]; + +################################################################################ +# The macro file search path. (Check with entries in global.conf before overriding) +################################################################################ +# Each directory in this list is seached +# (in this order) by loadMacros() when it looks for a .pl file. +# +# $pg{directories}{macrosPath} = [ +# ".", # search the problem file's directory +# $courseDirs{macros}, +# $pg{directories}{macros}, +# "$courseDirs{templates}/Library/macros/Union", +# "$courseDirs{templates}/Library/macros/Michigan", +# "$courseDirs{templates}/Library/macros/CollegeOfIdaho", +# "$courseDirs{templates}/Library/macros/FortLewis", +# "$courseDirs{templates}/Library/macros/TCNJ", +# "$courseDirs{templates}/Library/macros/NAU", +# "$courseDirs{templates}/Library/macros/Dartmouth", +# "$courseDirs{templates}/Library/macros/WHFreeman", +# ]; + +################################################################################ +# The applet search path. (Check with entries in global.conf before overriding) +################################################################################ + +# If a full URL is given, it is used unmodified. If an +# absolute path is given, the URL of the local server is prepended to it. +# +# For example, if an item is "/math/applets", +# and the local server is "https://math.yourschool.edu", +# then the URL "https://math.yourschool.edu/math/applets" will be used. +# + +# $pg{directories}{appletPath} = [ # paths to search for applets (requires full url) +# "$webworkURLs{htdocs}/applets", +# "$webworkURLs{htdocs}/applets/geogebra_stable", +# "$courseURLs{html}/applets", +# "$webworkURLs{htdocs}/applets/Xgraph", +# "$webworkURLs{htdocs}/applets/PointGraph", +# "$webworkURLs{htdocs}/applets/Xgraph", +# "$webworkURLs{htdocs}/applets/liveJar", +# "$webworkURLs{htdocs}/applets/Image_and_Cursor_All", +# +# ]; + +################################################################################ +# Problem creation defaults +################################################################################ + +# The default weight (also called value) of a problem to use when using the +# Library Browser, Problem Editor or Hmwk Sets Editor to add problems to a set +# or when this value is left blank in an imported set definition file. + +$problemDefaults{value} = 1; + +# The default max_attempts for a problem to use when using the +# Library Browser, Problem Editor or Hmwk Sets Editor to add problems to a set +# or when this value is left blank in an imported set definition file. Note that +# setting this to -1 gives students unlimited attempts. + +$problemDefaults{max_attempts} = -1; + + +1; #final line of the file to reassure perl that it was read properly. diff --git a/conf/prelocal.conf.dist b/conf/prelocal.conf.dist new file mode 100755 index 0000000000..2e8035e249 --- /dev/null +++ b/conf/prelocal.conf.dist @@ -0,0 +1,155 @@ +#!perl +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader: webwork2/conf/global.conf.dist,v 1.225 2010/05/18 18:03:31 apizer Exp $ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + +# This file is used to set up the default WeBWorK course environment for all +# requests. Values may be overwritten by the course.conf for a specific course. +# All package variables set in this file are added to the course environment. +# If you wish to set a variable here but omit it from the course environment, +# use the "my" keyword. The $webwork_dir variable is set in the WeBWorK Apache +# configuration file (webwork.apache-config) and is available for use here. In +# addition, the $courseName variable holds the name of the current course. + +################################################################################ +# prelocal.conf -- this file +################################################################################ + +# prelocal.conf and postlocal.conf contain the local modifications commonly made +# when installing WeBWorK on a new site. The configurations in global.conf.dist +# and in database.conf can usually remain untouched. + +################################################################################ +# Seed variables +################################################################################ + +# Set these variables to correspond to your configuration and preferences. You +# will need to restart the webserver to reset the variables in this section. + +# URL of WeBWorK handler. If WeBWorK is to be on the web server root, use "". Note +# that using "" may not work so we suggest sticking with "/webwork2". +$webwork_url = "/webwork2"; +$server_root_url = ""; +$server_userID = "wwadmin"; +$server_groupID = "wwdata"; + +# In the apache configuration file (often called httpd.conf) you will find +# User wwadmin --- this is the $server_userID -- of course it may be wwhttpd or some other name +# Group wwdata --- this is the $server_groupID -- this will have different names also + + +################################################################################ +# Paths to external programs +################################################################################ + +# These applications are often found in /bin, but sometimes in /usr/bin +# or even in /opt/local/bin. +# You can use "which tar" for example to find out where the "tar" program is located + +#################################################### +# system utilities +#################################################### +$externalPrograms{mv} = "/bin/mv"; +$externalPrograms{cp} = "/bin/cp"; +$externalPrograms{rm} = "/bin/rm"; +$externalPrograms{mkdir} = "/bin/mkdir"; +$externalPrograms{tar} = "/bin/tar"; +$externalPrograms{gzip} = "/bin/gzip"; + +#################################################### +# equation rendering/hardcopy utiltiies +#################################################### +$externalPrograms{latex} ="/usr/bin/latex"; +$externalPrograms{pdflatex} ="/usr/bin/pdflatex --shell-escape"; +$externalPrograms{dvipng} ="/usr/bin//dvipng"; +$externalPrograms{tth} ="/usr/bin/tth"; + +#################################################### +# NetPBM - basic image manipulation utilities +# Most sites only need to configure $netpbm_prefix. +#################################################### +my $netpbm_prefix = "/usr/bin"; +$externalPrograms{giftopnm} = "$netpbm_prefix/giftopnm"; +$externalPrograms{ppmtopgm} = "$netpbm_prefix/ppmtopgm"; +$externalPrograms{pnmtops} = "$netpbm_prefix/pnmtops"; +$externalPrograms{pnmtopng} = "$netpbm_prefix/pnmtopng"; +$externalPrograms{pngtopnm} = "$netpbm_prefix/pngtopnm"; + +#################################################### +# url checker +#################################################### + +$externalPrograms{checkurl} = "/usr/bin/lwp-request -d -mHEAD "; # or "/usr/local/bin/w3c -head " + +#################################################### +# image conversions utiltiies +# the source file is given on stdin, and the output expected on stdout. +#################################################### + +$externalPrograms{gif2eps} = "$externalPrograms{giftopnm} | $externalPrograms{ppmtopgm} | $externalPrograms{pnmtops} -noturn 2>/dev/null"; +$externalPrograms{png2eps} = "$externalPrograms{pngtopnm} | $externalPrograms{ppmtopgm} | $externalPrograms{pnmtops} -noturn 2>/dev/null"; +$externalPrograms{gif2png} = "$externalPrograms{giftopnm} | $externalPrograms{pnmtopng}"; + +#################################################### +# mysql clients +#################################################### + +$externalPrograms{mysql} ="/usr/bin/mysql"; +$externalPrograms{mysqldump} ="/usr/bin/mysqldump"; + + +#################################################### +# End paths to external utilities. +#################################################### + +################################################################################ +# Database options +################################################################################ + + +# Standard permissions command used to initialize the webwork database +# GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, DROP, INDEX, LOCK TABLES ON webwork.* TO webworkWrite@localhost IDENTIFIED BY 'passwordRW'; + +################################################################################ +# these variables are used by database.conf. we define them here so that editing +# database.conf isn't necessary. + +# You must initialize the database and set the password for webworkWrite +# The other parameters are set as defaults in global.conf but you can modify them +# here if for example you want to use a mysql database on a remote machine. +################################################################################ +$database_dsn ="dbi:mysql:webwork"; +$database_username ="webworkWrite"; +#$database_password ="passwordRW"; +$database_password ="dajchovo"; + +################################################################################ +# Directory for temporary files +################################################################################ +# Location of web-accessible temporary files, such as equation images. +Default: +#$webworkDirs{htdocs_temp} = "$webworkDirs{htdocs}/tmp"; +#$webworkURLs{htdocs_temp} = "$webworkURLs{htdocs}/tmp"; + +# Alternate locations -- this allows you to place temporary files +# in a location that is not backed up. +#For example. +#$webworkDirs{htdocs_temp} = "/opt/local/apache2/htdocs/wwtmp"; +#$webworkURLs{htdocs_temp} = "$server_root_url/wwtmp"; + +################################################################################ + +1; #final line of the file to reassure perl that it was read properly. + diff --git a/lib/WeBWorK/CourseEnvironment.pm b/lib/WeBWorK/CourseEnvironment.pm index c87c7a7612..eb4865a376 100644 --- a/lib/WeBWorK/CourseEnvironment.pm +++ b/lib/WeBWorK/CourseEnvironment.pm @@ -149,7 +149,12 @@ sub new { $safe->mask($maskBackup); # determine location of globalEnvironmentFile - my $globalEnvironmentFile = "$seedVars{webwork_dir}/conf/global.conf"; + my $globalEnvironmentFile; + if (-r "$seedVars{webwork_dir}/conf/global.conf") { + $globalEnvironmentFile = "$seedVars{webwork_dir}/conf/global.conf"; + } elsif (-r "$seedVars{webwork_dir}/conf/global.conf.dist") { # default version + $globalEnvironmentFile = "$seedVars{webwork_dir}/conf/global.conf.dist"; + } # read and evaluate the global environment file my $globalFileContents = readFile($globalEnvironmentFile); @@ -157,7 +162,7 @@ sub new { # if that evaluation failed, we can't really go on... # we need a global environment! - $@ and die "Could not evaluate global environment file $globalEnvironmentFile: $@"; + $@ and croak "Could not evaluate global environment file $globalEnvironmentFile: $@"; # determine location of courseEnvironmentFile and simple configuration file # pull it out of $safe's symbol table ad hoc From 6ca4f60ee7d31f1a54c50b1d41c3dc83c068cc80 Mon Sep 17 00:00:00 2001 From: Michael Gage Date: Sun, 26 Feb 2012 10:29:25 -0500 Subject: [PATCH 2/9] Make configurable which editors are shown in the left side bar. This is a temporary? hack while we have code that has several alternative editors. It allows site managers to turn on or off one or more of the editors on a site wide or on a course by course basis. The basic configuration is in global.conf.dist and there are stubs for overrides in postlocal.conf.dist. One can add similar stubs to course.config. --- conf/global.conf.dist | 19 +++++++++++++++++++ conf/postlocal.conf.dist | 32 ++++++++++++++++++++------------ lib/WeBWorK/ContentGenerator.pm | 27 ++++++++++++++++++--------- 3 files changed, 57 insertions(+), 21 deletions(-) diff --git a/conf/global.conf.dist b/conf/global.conf.dist index 3f724eb2a0..6f6d4dfdf3 100644 --- a/conf/global.conf.dist +++ b/conf/global.conf.dist @@ -1030,6 +1030,25 @@ $webworkRoot = $webworkDirs{root}; $webworkURLRoot = $webworkURLs{root}; $pgRoot = $pg{directories}{root}; +################################################################################ +# Temporary hack for displaying the different versions of the editors +################################################################################ +# These behaviors can be overridden in postlocal.conf +# These configurations can be placed in CourseConfig to tune the behavior for individual courses +%showeditors = ( + classlisteditor1 => 1, + classlisteditor2 => 0, + + homeworkseteditor1 => 1, + homeworkseteditor2 => 0, + + librarybrowser1 => 1, + librarybrowser2 => 0, + librarybrowser3 => 1, + + pgproblemeditor1 => 1, + pgproblemeditor2 => 0, +); ################################################################################ # Site wide overrides are entered into the file postlocal.conf ################################################################################ diff --git a/conf/postlocal.conf.dist b/conf/postlocal.conf.dist index b1aa8fc9fc..86819694ca 100755 --- a/conf/postlocal.conf.dist +++ b/conf/postlocal.conf.dist @@ -81,18 +81,6 @@ $defaultThemeTemplate = "system"; $language = "en"; # tr = turkish en=english -################################################################################ -# Directory overrides -################################################################################ -# Location of web-accessible temporary files, such as equation images. Standard: -#$webworkDirs{htdocs_temp} = "$webworkDirs{htdocs}/tmp"; -#$webworkURLs{htdocs_temp} = "$webworkURLs{htdocs}/tmp"; - -# Alternate locations -- this allows you to place temporary files -# in a location that is not backed up. -#For example. -#$webworkDirs{htdocs_temp} = "/opt/htdocs/wwtmp"; -#$webworkURLs{htdocs_temp} = "$server_root_url/wwtmp"; ################################################################################ # Default screen header files @@ -270,5 +258,25 @@ $problemDefaults{value} = 1; $problemDefaults{max_attempts} = -1; +################################################################################ +# Temporary hack for displaying the different versions of the editors +################################################################################ +# These configurations can be placed in CourseConfig to tune the behavior for individual courses +# The items below can be used to override the settings in global.conf.dist +# One can also use $showeditors{classlisteditor1}=0; to override +# %showeditors = ( +# classlisteditor1 => 1, +# classlisteditor2 => 1, +# +# homeworkseteditor1 => 1, +# homeworkseteditor2 => 1, +# +# librarybrowser1 => 1, +# librarybrowser2 => 1, +# librarybrowser3 => 1, +# +# pgproblemeditor1 => 1, +# pgproblemeditor2 => 1, +# ); 1; #final line of the file to reassure perl that it was read properly. diff --git a/lib/WeBWorK/ContentGenerator.pm b/lib/WeBWorK/ContentGenerator.pm index 310c6efc0c..1d23ca45c1 100644 --- a/lib/WeBWorK/ContentGenerator.pm +++ b/lib/WeBWorK/ContentGenerator.pm @@ -706,13 +706,17 @@ sub links { print &$makelink("${pfx}Index", urlpath_args=>{%args}, systemlink_args=>\%systemlink_args); print CGI::start_ul(); - print CGI::li(&$makelink("${pfx}UserList", urlpath_args=>{%args}, systemlink_args=>\%systemlink_args)); - print CGI::li(&$makelink("${pfx}UserList2", urlpath_args=>{%args}, systemlink_args=>\%systemlink_args)); + print CGI::li(&$makelink("${pfx}UserList", urlpath_args=>{%args}, systemlink_args=>\%systemlink_args)) + if $ce->{showeditors}->{classlisteditor1}; + print CGI::li(&$makelink("${pfx}UserList2", urlpath_args=>{%args}, systemlink_args=>\%systemlink_args)) + if $ce->{showeditors}->{classlisteditor2};; print CGI::start_li(); # Homework Set Editor - print &$makelink("${pfx}ProblemSetList", urlpath_args=>{%args}, systemlink_args=>\%systemlink_args); + print &$makelink("${pfx}ProblemSetList", urlpath_args=>{%args}, systemlink_args=>\%systemlink_args) + if $ce->{showeditors}->{homeworkseteditor1}; print "
"; - print &$makelink("${pfx}ProblemSetList2", urlpath_args=>{%args}, systemlink_args=>\%systemlink_args); + print &$makelink("${pfx}ProblemSetList2", urlpath_args=>{%args}, systemlink_args=>\%systemlink_args) + if $ce->{showeditors}->{homeworkseteditor2};; ## only show editor link for non-versioned sets if (defined $setID && $setID !~ /,v\d+$/ ) { @@ -722,12 +726,14 @@ sub links { if (defined $problemID) { print CGI::start_ul(); - print CGI::li(&$makelink("${pfx}PGProblemEditor", text=>"$problemID", urlpath_args=>{%args,setID=>$setID,problemID=>$problemID}, systemlink_args=>\%systemlink_args, target=>"WW_Editor")); + print CGI::li(&$makelink("${pfx}PGProblemEditor", text=>"$problemID", urlpath_args=>{%args,setID=>$setID,problemID=>$problemID}, systemlink_args=>\%systemlink_args, target=>"WW_Editor")) + if $ce->{showeditors}->{pgproblemeditor1}; print CGI::end_ul(); } if (defined $problemID) { print CGI::start_ul(); - print CGI::li(&$makelink("${pfx}PGProblemEditor2", text=>"--$problemID", urlpath_args=>{%args,setID=>$setID,problemID=>$problemID}, systemlink_args=>\%systemlink_args, target=>"WW_Editor2")); + print CGI::li(&$makelink("${pfx}PGProblemEditor2", text=>"--$problemID", urlpath_args=>{%args,setID=>$setID,problemID=>$problemID}, systemlink_args=>\%systemlink_args, target=>"WW_Editor2")) + if $ce->{showeditors}->{pgproblemeditor2};; print CGI::end_ul(); } @@ -736,9 +742,12 @@ sub links { } print CGI::end_li(); # end Homework Set Editor - print CGI::li(&$makelink("${pfx}SetMaker", text=>$r->maketext("Library Browser"), urlpath_args=>{%args}, systemlink_args=>\%systemlink_args)); - print CGI::li(&$makelink("${pfx}SetMaker2", text=>$r->maketext("Library Browser 2"), urlpath_args=>{%args}, systemlink_args=>\%systemlink_args)); - print CGI::li(&$makelink("${pfx}SetMaker3", text=>$r->maketext("Library Browser 3"), urlpath_args=>{%args}, systemlink_args=>\%systemlink_args)); + print CGI::li(&$makelink("${pfx}SetMaker", text=>$r->maketext("Library Browser"), urlpath_args=>{%args}, systemlink_args=>\%systemlink_args)) + if $ce->{showeditors}->{librarybrowser1}; + print CGI::li(&$makelink("${pfx}SetMaker2", text=>$r->maketext("Library Browser 2"), urlpath_args=>{%args}, systemlink_args=>\%systemlink_args)) + if $ce->{showeditors}->{librarybrowser2}; + print CGI::li(&$makelink("${pfx}SetMaker3", text=>$r->maketext("Library Browser 3"), urlpath_args=>{%args}, systemlink_args=>\%systemlink_args)) + if $ce->{showeditors}->{librarybrowser3}; print CGI::start_li(); # Stats print &$makelink("${pfx}Stats", urlpath_args=>{%args}, systemlink_args=>\%systemlink_args); if ($userID ne $eUserID or defined $setID) { From 7290ce0a654417ee6cb0c53055d2f8dd77d67fa4 Mon Sep 17 00:00:00 2001 From: Michael Gage Date: Sun, 26 Feb 2012 10:52:50 -0500 Subject: [PATCH 3/9] Add README file explaining the function of prelocal.conf and postlocal.conf --- conf/README | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 conf/README diff --git a/conf/README b/conf/README new file mode 100644 index 0000000000..c2c2fa64a8 --- /dev/null +++ b/conf/README @@ -0,0 +1,16 @@ +Use the prelocal.conf and postlocal.conf files to make modifications. + +The prelocal.conf file is read before the global.conf.dist file is processed. Non-local variables in this file +are then available for use in global.conf.dist. + +The postlocal.conf file is read after the global.conf.dist file is processed and will overright configurations in global.conf.dist + +In order to make sure that the global.conf.dist is read you should remove +(or make unreadable) the global.conf file. Other wise the global.conf file +will be read instead of global.conf.dist. + +This system should greatly simplify the process of updating webwork2 since it is less likely +that one will need to modify the config files when upgrading. Default configurations or permissions for +new features will be defined in global.conf.dist and will allow automatic upgrades. +Overrides for these new features can be added later to postlocal.conf + From b93bdb0537ba4cdb80e70b5972bda66ff93ce101 Mon Sep 17 00:00:00 2001 From: Michael Gage Date: Sun, 26 Feb 2012 11:19:50 -0500 Subject: [PATCH 4/9] Correct default paths --- conf/prelocal.conf.dist | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/conf/prelocal.conf.dist b/conf/prelocal.conf.dist index 2e8035e249..018503f97b 100755 --- a/conf/prelocal.conf.dist +++ b/conf/prelocal.conf.dist @@ -133,7 +133,6 @@ $externalPrograms{mysqldump} ="/usr/bin/mysqldump"; $database_dsn ="dbi:mysql:webwork"; $database_username ="webworkWrite"; #$database_password ="passwordRW"; -$database_password ="dajchovo"; ################################################################################ # Directory for temporary files @@ -146,8 +145,8 @@ Default: # Alternate locations -- this allows you to place temporary files # in a location that is not backed up. #For example. -#$webworkDirs{htdocs_temp} = "/opt/local/apache2/htdocs/wwtmp"; -#$webworkURLs{htdocs_temp} = "$server_root_url/wwtmp"; +#$webworkDirs{htdocs_temp} = "/opt/htdocs/wwtmp"; +#$webworkURLs{htdocs_temp} = "/wwtmp"; ################################################################################ From fb5638221645a003230be90fed49ceb59f083fdc Mon Sep 17 00:00:00 2001 From: Michael Gage Date: Sun, 26 Feb 2012 11:28:25 -0500 Subject: [PATCH 5/9] Expand on the instructions in README --- conf/README | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/conf/README b/conf/README index c2c2fa64a8..eb23902b1d 100644 --- a/conf/README +++ b/conf/README @@ -5,12 +5,30 @@ are then available for use in global.conf.dist. The postlocal.conf file is read after the global.conf.dist file is processed and will overright configurations in global.conf.dist -In order to make sure that the global.conf.dist is read you should remove -(or make unreadable) the global.conf file. Other wise the global.conf file -will be read instead of global.conf.dist. - -This system should greatly simplify the process of updating webwork2 since it is less likely +This new configuration system should greatly simplify the process of +updating webwork2 since it is less likely that one will need to modify the config files when upgrading. Default configurations or permissions for new features will be defined in global.conf.dist and will allow automatic upgrades. + Overrides for these new features can be added later to postlocal.conf +FIRST TIME RECONFIGURATION + +COPY prelocal.conf.dist to prelocal.conf. +COPY postlocal.conf.dist to postlocal.conf. + +MODIFY prelocal.conf using the data from your global.conf file. +In particular you will need to fill in the server name, the +password for the database and any modifications you have made as to the +location of the temporary files directory. Notice that the location of the temporary files directory +is used to define several other related subdirectories, so this modification needs to be made +in prelocal.conf BEFORE the standard global.conf.dist file is read. + +RENAME global.conf to global.save in order to make sure that the global.conf.dist is read. +Otherwise the global.conf file will be read instead of global.conf.dist and the behavior will be +as with the old system. + +INSPECT and possibly modify postlocal.conf to add any further local modifications that you had +made to your global.conf file. + + From f9b49b4a056d461c25e22c4466c1bdeced485c52 Mon Sep 17 00:00:00 2001 From: Michael Gage Date: Sun, 26 Feb 2012 14:25:16 -0500 Subject: [PATCH 6/9] Add snippets/ASimpleCombinedHeaderFile.pg to snippets This will be the new default header file. --- conf/snippets/ASimpleCombinedHeaderFile.pg | 88 ++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 conf/snippets/ASimpleCombinedHeaderFile.pg diff --git a/conf/snippets/ASimpleCombinedHeaderFile.pg b/conf/snippets/ASimpleCombinedHeaderFile.pg new file mode 100644 index 0000000000..14cc26995c --- /dev/null +++ b/conf/snippets/ASimpleCombinedHeaderFile.pg @@ -0,0 +1,88 @@ +# ASimpleCombinedHeaderFile.pg +# This header file can be used for both the screen and hardcopy output + + +DOCUMENT(); + +loadMacros( + "PG.pl", + "PGbasicmacros.pl", + "PGcourse.pl", +); + +TEXT($BEGIN_ONE_COLUMN); + +#################################################### +# +# The item below printed out only when a hardcopy is made. +# +#################################################### + + + +TEXT(MODES(TeX =>EV3(<<'EOT'),HTML=>"")); + +\noindent {\large \bf $studentName} +\hfill +{\large \bf {\{protect_underbar($courseName)\}}} +% Uncomment the line below if this course has sections. Note that this is a comment in TeX mode since this is only processed by LaTeX +% {\large \bf { Section: \{protect_underbar($sectionName)\} } } +\par +\noindent{\large \bf {Assignment \{protect_underbar($setNumber)\} due $formatedDueDate}} +\par\noindent \bigskip +% Uncomment and edit the line below if this course has a web page. Note that this is a comment in TeX mode. +%See the course web page for information http://yoururl/yourcourse + +EOT + +#################################################### +# +# End of hardcopy only output. +# +#################################################### + + +#################################################### +# +# The items below are printed out only when set is displayed on screen +# +#################################################### +TEXT(MODES(TeX =>"",HTML=>EV3(<<'EOT'))); + +$BBOLD WeBWorK Assignment \{ protect_underbar($setNumber) \} is due : $formattedDueDate. $EBOLD +$PAR +Here's the list of +\{ htmlLink(qq!http://webwork.maa.org/wiki/Available_Functions!,"functions and symbols") \} + which WeBWorK understands. +$BR +EOT + +#################################################### +# Uncomment and edit the lines below if this course has a web page. Note that this is comment in Perl mode. +# IMPORTANT: Make sure the EOT at the bottom is at the beginning of a line with no spaces preceeding it. +#TEXT(MODES(TeX =>"",HTML=>EV3(<<'EOT'))); +#See the course web page for information \{ htmlLink(qq!http://yoururl/yourcourse!,"your course name") \} +#EOT +#################################################### + +#################################################### +# +# End of screen only output. +# +#################################################### + +#################################################### +# +# Anything between the BEGIN_TEXT AND END_TEXT lines +# will be printed in both screen and hardcopy output +# +#################################################### + +BEGIN_TEXT + +END_TEXT + + +TEXT($END_ONE_COLUMN); + +ENDDOCUMENT(); # This should be the last executable line in the problem. From 739bafb061a2f8c51c01624948b39bd00b2fa1b7 Mon Sep 17 00:00:00 2001 From: Michael Gage Date: Sun, 26 Feb 2012 14:26:22 -0500 Subject: [PATCH 7/9] update .gitignore to ignore *.save files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 831eaae24c..f4cef05b70 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .svn .DS_Store .* +*.save htdocs/tmp/* tmp/* logs/* From 23dca36ca62e7495d9b7850d3ef015da862d0ef3 Mon Sep 17 00:00:00 2001 From: Michael Gage Date: Sun, 26 Feb 2012 15:55:59 -0500 Subject: [PATCH 8/9] Add .js files from Grant He's repository There might be some extraneous .js files but this should help insure that things work as Grant intended them to. --- htdocs/js/ajax_reload.js | 40 +++ htdocs/js/classlist_handlers.js | 32 ++ htdocs/js/form_checker_hmwksets.js | 18 ++ htdocs/js/getInputTable.js | 23 ++ htdocs/js/hmwksets_handlers.js | 18 ++ htdocs/js/java_init.js | 9 + htdocs/js/mimic.js | 490 +++++++++++++++++++++++++++++ htdocs/js/removeDuplicates.js | 20 ++ htdocs/js/show_hide.js | 13 + htdocs/js/warn_handler.js | 38 +++ 10 files changed, 701 insertions(+) create mode 100644 htdocs/js/ajax_reload.js create mode 100644 htdocs/js/classlist_handlers.js create mode 100644 htdocs/js/form_checker_hmwksets.js create mode 100644 htdocs/js/getInputTable.js create mode 100644 htdocs/js/hmwksets_handlers.js create mode 100644 htdocs/js/java_init.js create mode 100644 htdocs/js/mimic.js create mode 100644 htdocs/js/removeDuplicates.js create mode 100644 htdocs/js/show_hide.js create mode 100644 htdocs/js/warn_handler.js diff --git a/htdocs/js/ajax_reload.js b/htdocs/js/ajax_reload.js new file mode 100644 index 0000000000..dba3924a23 --- /dev/null +++ b/htdocs/js/ajax_reload.js @@ -0,0 +1,40 @@ +/* This is the javascript that creates the AJAX object and attaches it to the reload button*/ +/* Reference: w3schools.com, http://www.w3schools.com/ajax/ajax_examples.asp*/ + +function ajax_Reload() { + var xmlhttp; + + if(window.XMLHttpRequest){ + xmlhttp = new XMLHttpRequest(); + } + else{ + xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); + } + + xmlhttp.onreadystatechange=function() { + if (xmlhttp.readyState==4 && xmlhttp.status==200){ + document.getElementById("problem_viewer_content").innerHTML=xmlhttp.responseText; + } + }; + + var tempEditFileDirectory = document.getElementById("temp_url_id").getAttribute("value"); + alert(location.protocol+"//"+location.host+tempEditFileDirectory+"/temp_body.txt"); + xmlhttp.open("GET", location.protocol+"//"+location.host+tempEditFileDirectory+"/temp_body.txt", true); + xmlhttp.send(); +} + +/*This method of adding to the onload event listener is taken from tabber.js, which in turn takes from http://simon.incutio.com/archive/2004/05/26/addLoadEvent*/ + +// var oldonload; + +// oldonload = window.onload; + +// if(typeof window.onload != "function"){ + // window.onload = function() { document.getElementById("reload_button").onclick = ajax_Reload; }; +// } +// else{ + // window.onload = function() { + // oldonload(); + // document.getElementById("reload_button").onclick = ajax_Reload; + // }; +// } \ No newline at end of file diff --git a/htdocs/js/classlist_handlers.js b/htdocs/js/classlist_handlers.js new file mode 100644 index 0000000000..0f901c2662 --- /dev/null +++ b/htdocs/js/classlist_handlers.js @@ -0,0 +1,32 @@ +/*This is the Javascript which applies some handlers to various input elements*/ + +function classlist_add_filter_elements() { + var filter_select = document.getElementById("filter_select"); + var filter_elements = document.getElementById("filter_elements"); + + if(filter_select.selectedIndex == 3){ + filter_elements.style.display = "block"; + } + else{ + filter_elements.style.display = "none"; + } +} + +function classlist_add_export_elements() { + var export_select_target = document.getElementById("export_select_target"); + var export_elements = document.getElementById("export_elements"); + + if(export_select_target.selectedIndex == 0){ + export_elements.style.display = "block"; + } + else{ + export_elements.style.display = "none"; + } +} + +addOnLoadEvent(function() { + document.getElementById("filter_select").onchange = classlist_add_filter_elements; + classlist_add_filter_elements(); + document.getElementById("export_select_target").onchange = classlist_add_export_elements; + classlist_add_export_elements(); + }); \ No newline at end of file diff --git a/htdocs/js/form_checker_hmwksets.js b/htdocs/js/form_checker_hmwksets.js new file mode 100644 index 0000000000..6f0bcab1d9 --- /dev/null +++ b/htdocs/js/form_checker_hmwksets.js @@ -0,0 +1,18 @@ +/*This is the javascript which checks the forms for errors on the Hmwksets editor page.*/ + +function check_form_hmwk_sets() { + var filter_text = document.getElementById("filter_text"); + var filter_select = document.getElementById("filter_select"); + var filter_err_msg = document.getElementById("filter_err_msg"); + var filter_radio = document.getElementById("filter_id"); + + if(filter_radio.checked && filter_select.selectedIndex == 3 && filter_text.value == ""){ + filter_err_msg.style.display = "inline"; + return false; + } +} + + +addOnLoadEvent(function (){ + document.getElementById("take_action").onclick = check_form_hmwk_sets; +}); \ No newline at end of file diff --git a/htdocs/js/getInputTable.js b/htdocs/js/getInputTable.js new file mode 100644 index 0000000000..51efca3c48 --- /dev/null +++ b/htdocs/js/getInputTable.js @@ -0,0 +1,23 @@ +/*This gets the input table for the XMLRPC call*/ + +function getInputTable(){ + var problem_viewer = document.getElementById("problem_viewer_form"); + var inputElems = problem_viewer.getElementsByTagName("input"); + + var inputTable = new Array(); + + var type,name,value; + for(i in inputElems){ + type = inputElems[i].getAttribute("type"); + name = inputElems[i].getAttribute("name"); + value = inputElems[i].getAttribute("value"); + if(type == "submit" || type == "button" || type == "reset"){ + continue; + } + else{ + inputTable[name] = value; + } + } + + return inputTable; +} \ No newline at end of file diff --git a/htdocs/js/hmwksets_handlers.js b/htdocs/js/hmwksets_handlers.js new file mode 100644 index 0000000000..2b9b6b0a6d --- /dev/null +++ b/htdocs/js/hmwksets_handlers.js @@ -0,0 +1,18 @@ +/*This contains the Javascripts for the handlers on the hmwk sets page.*/ + +function hmwksets_add_filter_elements() { + var filter_select = document.getElementById("filter_select"); + var filter_elements = document.getElementById("filter_elements"); + + if(filter_select.selectedIndex == 3){ + filter_elements.style.display = "block"; + } + else{ + filter_elements.style.display = "none"; + } +} + +addOnLoadEvent(function() { + document.getElementById("filter_select").onchange = hmwksets_add_filter_elements; + hmwksets_add_filter_elements(); +}); \ No newline at end of file diff --git a/htdocs/js/java_init.js b/htdocs/js/java_init.js new file mode 100644 index 0000000000..ea4ed5d320 --- /dev/null +++ b/htdocs/js/java_init.js @@ -0,0 +1,9 @@ +/*This is the file where the proper functions are initialized for the problem applets which use them.*/ + +function initWW(){ + if (typeof(initializeWWquestion) == 'function') { + initializeWWquestion(); + } +} + +addOnLoadEvent(initWW); \ No newline at end of file diff --git a/htdocs/js/mimic.js b/htdocs/js/mimic.js new file mode 100644 index 0000000000..61872487a4 --- /dev/null +++ b/htdocs/js/mimic.js @@ -0,0 +1,490 @@ +/* +* Mimic (XML-RPC Client for JavaScript) v2.0.1 +* Copyright (C) 2005-2009 Carlos Eduardo Goncalves (cadu.goncalves@gmail.com) +* +* Mimic is dual licensed under the MIT (http://opensource.org/licenses/mit-license.php) +* and GPLv3 (http://opensource.org/licenses/gpl-3.0.html) licenses. +*/ + + +/** + * XmlRpc + */ + function XmlRpc(){ + + }; + +/**

XML-RPC document prolog.

*/ +XmlRpc.PROLOG = "\n"; + +/**

XML-RPC methodCall node template.

*/ +XmlRpc.REQUEST = "\n${METHOD}\n\n${DATA}\n"; + +/**

XML-RPC param node template.

*/ +XmlRpc.PARAM = "\n\n${DATA}\n\n"; + +/**

XML-RPC array node template.

*/ +XmlRpc.ARRAY = "\n\n${DATA}\n\n"; + +/**

XML-RPC struct node template.

*/ +XmlRpc.STRUCT = "\n${DATA}\n"; + +/**

XML-RPC member node template.

*/ +XmlRpc.MEMBER = "\n${DATA}\n"; + +/**

XML-RPC name node template.

*/ +XmlRpc.NAME = "${DATA}\n"; + +/**

XML-RPC value node template.

*/ +XmlRpc.VALUE = "\n${DATA}\n"; + +/**

XML-RPC scalar node template (int, i4, double, string, boolean, base64, dateTime.iso8601).

*/ +XmlRpc.SCALAR = "<${TYPE}>${DATA}\n"; + +/** +*

Get the tag name used to represent a JavaScript +* object in the XMLRPC protocol.

+* @param data +* A JavaScript object. +* @return +* String with XMLRPC object type. +*/ +XmlRpc.getDataTag = function(data) { + try { + var tag = typeof data; + switch(tag.toLowerCase()) { + case "number": + tag = (Math.round(data) == data) ? "int" : "double"; + break; + case "object": + if(data.constructor == Base64) + tag = "base64"; + else + if(data.constructor == String) + tag = "string"; + else + if(data.constructor == Boolean) + tag = "boolean"; + else + if(data.constructor == Array) + tag = "array"; + else + if(data.constructor == Date) + tag = "dateTime.iso8601"; + else + if(data.constructor == Number) + tag = (Math.round(data) == data) ? "int" : "double"; + else + tag = "struct"; + break; + } + return tag; + } + catch(e) { + Engine.reportException(null, e); + } +}; + +/** +*

Get JavaScript object type represented by +* XMLRPC protocol tag.

+* @param tag +* A XMLRPC tag name. +* @return +* A JavaScript object. +*/ +XmlRpc.getTagData = function(tag) { + var data = null; + switch(tag) { + case "struct": + data = new Object(); + break; + case "array": + data = new Array(); + break; + case "datetime.iso8601": + data = new Date(); + break; + case "boolean": + data = new Boolean(); + break; + case "int": + case "i4": + case "double": + data = new Number(); + break; + case "string": + data = new String(); + break; + case "base64": + data = new Base64(); + break; + } + return data; +}; + +/** + * XmlRpcRequest + * @param url + * Server url. + * @param method + * Server side method do call. + */ +function XmlRpcRequest(url, method) { + this.serviceUrl = url; + this.methodName = method; + this.params = []; +}; + +/** + *

Add a new request parameter.

+ * @param data + * New parameter value. + */ +XmlRpcRequest.prototype.addParam = function(data) { + var type = typeof data; + switch(type.toLowerCase()) { + case "function": + return; + case "object": + if(!data.constructor.name) return; + } + this.params.push(data); +}; + +/** + *

Clear all request parameters.

+ * @param data + * New parameter value. + */ +XmlRpcRequest.prototype.clearParams = function() { + this.params.splice(0, this.params.length); +}; + +/** + *

Execute a synchronous XML-RPC request.

+ * @return + * XmlRpcResponse object. + */ +XmlRpcRequest.prototype.send = function() { + var xml_params = ""; + for(var i = 0; i < this.params.length; i++) + xml_params += XmlRpc.PARAM.replace("${DATA}", this.marshal(this.params[i])); + var xml_call = XmlRpc.REQUEST.replace("${METHOD}", this.methodName); + xml_call = XmlRpc.PROLOG + xml_call.replace("${DATA}", xml_params); + var xhr = Builder.buildXHR(); + xhr.open("POST", this.serviceUrl, false); + xhr.send(Builder.buildDOM(xml_call)); + return new XmlRpcResponse(xhr.responseXML); +}; + +/** + *

Marshal request parameters.

+ * @param data + * A request parameter. + * @return + * String with XML-RPC element notation. + */ +XmlRpcRequest.prototype.marshal = function(data) { + var type = XmlRpc.getDataTag(data); + var scalar_type = XmlRpc.SCALAR.replace(/\$\{TYPE\}/g, type); + var xml = ""; + switch(type) { + case "struct": + var member = ""; + for(var i in data) { + var value = ""; + value += XmlRpc.NAME.replace("${DATA}", i); + value += XmlRpc.VALUE.replace("${DATA}", this.marshal(data[i])); + member += XmlRpc.MEMBER.replace("${DATA}", value); + } + xml = XmlRpc.STRUCT.replace("${DATA}", member); + break; + case "array": + var value = ""; + for(var i = 0; i < data.length; i++) { + value += XmlRpc.VALUE.replace("${DATA}", this.marshal(data[i])); + } + xml = XmlRpc.ARRAY.replace("${DATA}", value); + break; + case "dateTime.iso8601": + xml = scalar_type.replace("${DATA}", data.toIso8601()); + break; + case "boolean": + xml = scalar_type.replace("${DATA}", (data == true) ? 1 : 0); + break; + case "base64": + xml = scalar_type.replace("${DATA}", data.encode()); + break; + default : + xml = scalar_type.replace("${DATA}", data); + break; + } + return xml; +}; + +/** + * XmlRpcResponse + * @param xml + * Response XML document. + */ +function XmlRpcResponse(xml) { + this.xmlData = xml; +}; + +/** + *

Indicate if response is a fault.

+ * @return + * Boolean flag indicating fault status. + */ +XmlRpcResponse.prototype.isFault = function() { + return this.faultValue; +}; + +/** + *

Parse XML response to JavaScript.

+ * @return + * JavaScript object parsed from XML-RPC document. + */ +XmlRpcResponse.prototype.parseXML = function() { + this.faultValue = undefined; + this.currentIsName = false; + this.propertyName = ""; + this.params = []; + for(var i = 0; i < this.xmlData.childNodes.length; i++) + this.unmarshal(this.xmlData.childNodes[i], 0); + return this.params[0]; +}; + +/** + *

Unmarshal response parameters.

+ * @param node + * Current document node under processing. + * @param parent + * Current node' parent node. + */ +XmlRpcResponse.prototype.unmarshal = function(node, parent) { + if(node.nodeType == 1) { + var obj = null; + var tag = node.tagName.toLowerCase(); + switch(tag) { + case "fault": + this.faultValue = true; + break; + case "name": + this.currentIsName = true; + break; + default: + obj = XmlRpc.getTagData(tag); + break; + } + if(obj != null) { + this.params.push(obj); + if(tag == "struct" || tag == "array") { + if(this.params.length > 1) { + switch(XmlRpc.getDataTag(this.params[parent])) { + case "struct": + this.params[parent][this.propertyName] = this.params[this.params.length - 1]; + break; + case "array": + this.params[parent].push(this.params[this.params.length - 1]); + break; + } + } + var parent = this.params.length - 1; + } + } + for(var i = 0; i < node.childNodes.length; i++) { + this.unmarshal(node.childNodes[i], parent); + } + } + if( (node.nodeType == 3) && (/[^\t\n\r ]/.test(node.nodeValue)) ) { + if(this.currentIsName == true) { + this.propertyName = node.nodeValue; + this.currentIsName = false; + } + else { + switch(XmlRpc.getDataTag(this.params[this.params.length - 1])) { + case "dateTime.iso8601": + this.params[this.params.length - 1] = Date.fromIso8601(node.nodeValue); + break; + case "boolean": + this.params[this.params.length - 1] = (node.nodeValue == "1") ? true : false; + break; + case "int": + case "double": + this.params[this.params.length - 1] = new Number(node.nodeValue); + break; + case "string": + this.params[this.params.length - 1] = new String(node.nodeValue); + break; + case "base64": + this.params[this.params.length - 1] = new Base64(node.nodeValue); + break; + } + if(this.params.length > 1) { + switch(XmlRpc.getDataTag(this.params[parent])) { + case "struct": + this.params[parent][this.propertyName] = this.params[this.params.length - 1]; + break; + case "array": + this.params[parent].push(this.params[this.params.length - 1]); + break; + } + } + } + } +}; + +/** + * Builder + */ +function Builder(){ + +}; + +/** + *

Build a valid XMLHttpRequest object

+ * @return + * XMLHttpRequest object. + */ +Builder.buildXHR = function() { + return (typeof XMLHttpRequest != "undefined") ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"); +}; + +/** + *

Build a valid XML document from string markup.

+ * @param xml + * Document markup. + * @return + * XMLDocument object. + */ +Builder.buildDOM = function(xml) { + if(typeof DOMParser != "undefined") { + var w3c_parser = new DOMParser(); + return w3c_parser.parseFromString(xml, "text/xml"); + } + else { + var names = ["Microsoft.XMLDOM", "MSXML2.DOMDocument", "MSXML.DOMDocument"]; + for(var i = 0; i < names.length; i++) { + try{ + var atx_parser = new ActiveXObject(names[i]); + atx_parser.loadXML(xml); + return atx_parser; + } + catch (e) {/* ignore */ } + } + } + return null; +}; + +/** + * Date + */ + + /** +*

Convert a GMT date to ISO8601.

+* @return +* String with an ISO8601 date. +*/ +Date.prototype.toIso8601 = function() { + year = this.getYear(); + if (year < 1900) year += 1900; + month = this.getMonth() + 1; + if (month < 10) month = "0" + month; + day = this.getDate(); + if (day < 10) day = "0" + day; + time = this.toTimeString().substr(0,8); + return year + month + day + "T" + time; +}; + +/** +*

Convert ISO8601 date to GMT.

+* @param value +* ISO8601 date. +* @return +* GMT date. +*/ +Date.fromIso8601 = function(value) { + year = value.substr(0,4); + month = value.substr(4,2); + day = value.substr(6,2); + hour = value.substr(9,2); + minute = value.substr(12,2); + sec = value.substr(15,2); + return new Date(year, month - 1, day, hour, minute, sec, 0); +}; + +/** + * Base64 + */ +function Base64(value) { + Base64.prototype.bytes = value; +}; + +/**

Base64 characters map.

*/ +Base64.CHAR_MAP = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + +/** +*

Encode the object bytes using base64 algorithm.

+* @return +* Encoded string. +*/ +Base64.prototype.encode = function() { + if(typeof btoa == "function") + this.bytes = btoa(this.bytes); + else { + var _byte = new Array(), _char = new Array(), _result = new Array(); + var j = 0; + for (var i = 0; i < this.bytes.length; i += 3) { + _byte[0] = this.bytes.charCodeAt(i); + _byte[1] = this.bytes.charCodeAt(i + 1); + _byte[2] = this.bytes.charCodeAt(i + 2); + _char[0] = _byte[0] >> 2; + _char[1] = ((_byte[0] & 3) << 4) | (_byte[1] >> 4); + _char[2] = ((_byte[1] & 15) << 2) | (_byte[2] >> 6); + _char[3] = _byte[2] & 63; + if(isNaN(_byte[1])) + _char[2] = _char[3] = 64; + else + if(isNaN(_byte[2])) + _char[3] = 64; + _result[j++] = Base64.CHAR_MAP.charAt(_char[0]) + Base64.CHAR_MAP.charAt(_char[1]) + + Base64.CHAR_MAP.charAt(_char[2]) + Base64.CHAR_MAP.charAt(_char[3]); + } + this.bytes = _result.join(""); + } + return this.bytes; +}; + +/** +*

Decode the object bytes using base64 algorithm.

+* @return +* Decoded string. +*/ +Base64.prototype.decode = function() { + if(typeof atob == "function") + this.bytes = atob(this.bytes); + else { + var _byte = new Array(), _char = new Array(), _result = new Array(); + var j = 0; + while ((this.bytes.length % 4) != 0) + this.bytes += "="; + for (var i = 0; i < this.bytes.length; i += 4) { + _char[0] = Base64.CHAR_MAP.indexOf(this.bytes.charAt(i)); + _char[1] = Base64.CHAR_MAP.indexOf(this.bytes.charAt(i + 1)); + _char[2] = Base64.CHAR_MAP.indexOf(this.bytes.charAt(i + 2)); + _char[3] = Base64.CHAR_MAP.indexOf(this.bytes.charAt(i + 3)); + _byte[0] = (_char[0] << 2) | (_char[1] >> 4); + _byte[1] = ((_char[1] & 15) << 4) | (_char[2] >> 2); + _byte[2] = ((_char[2] & 3) << 6) | _char[3]; + _result[j++] = String.fromCharCode(_byte[0]); + if(_char[2] != 64) + _result[j++] = String.fromCharCode(_byte[1]); + if(_char[3] != 64) + _result[j++] = String.fromCharCode(_byte[2]); + } + this.bytes = _result.join(""); + } + return this.bytes; +}; \ No newline at end of file diff --git a/htdocs/js/removeDuplicates.js b/htdocs/js/removeDuplicates.js new file mode 100644 index 0000000000..5989c620e7 --- /dev/null +++ b/htdocs/js/removeDuplicates.js @@ -0,0 +1,20 @@ +/*This defines a function which removes duplicate javascript files from the page*/ + +function removeDuplicates(){ + var scripts = document.getElementsByTagName("script"); + + var src; + var i,j,x + for(i=0; i Date: Sun, 26 Feb 2012 21:02:13 -0500 Subject: [PATCH 9/9] Trouble shoot warning message passing. Restore "edit problem" line when warnings occur. Using the opportunity provided by having the level_curves subroutine fail to make sure that the appropriate warning messages are passed and that one can get back to the PGeditor to make corrections. --- lib/WeBWorK/ContentGenerator.pm | 6 ++-- lib/WeBWorK/ContentGenerator/Problem.pm | 48 +++++++++++++++---------- 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/lib/WeBWorK/ContentGenerator.pm b/lib/WeBWorK/ContentGenerator.pm index 1d23ca45c1..d425e7c91b 100644 --- a/lib/WeBWorK/ContentGenerator.pm +++ b/lib/WeBWorK/ContentGenerator.pm @@ -1067,7 +1067,7 @@ The implementation in this package checks for a note in the request named sub warnings { my ($self) = @_; my $r = $self->r; - + print CGI::p("Entering ContentGenerator::warnings"); print "\n\n"; my $warnings = MP2 ? $r->notes->get("warnings") : $r->notes("warnings"); print $self->warningOutput($warnings) if $warnings; @@ -1949,7 +1949,7 @@ problem rendering. sub errorOutput($$$) { my ($self, $error, $details) = @_; my $r = $self->{r}; - + print "Entering ContentGenerator::errorOutput subroutine
"; my $time = time2str("%a %b %d %H:%M:%S %Y", time); my $method = $r->method; my $uri = $r->uri; @@ -2007,7 +2007,7 @@ and content generation. sub warningOutput($$) { my ($self, $warnings) = @_; my $r = $self->{r}; - + print "Entering ContentGenerator::warningOutput subroutine
"; my @warnings = split m/\n+/, $warnings; foreach my $warning (@warnings) { #$warning = escapeHTML($warning); # this would prevent using tables in output from answer evaluators diff --git a/lib/WeBWorK/ContentGenerator/Problem.pm b/lib/WeBWorK/ContentGenerator/Problem.pm index a82756f04e..ec8046e579 100644 --- a/lib/WeBWorK/ContentGenerator/Problem.pm +++ b/lib/WeBWorK/ContentGenerator/Problem.pm @@ -726,12 +726,14 @@ sub pre_header_initialize { # because the PG file is never run # if (defined ($pg->{pgcore}) ) { - my @debug_msgs = @{ $pg->{pgcore}->get_debug_messages}; - $self->addmessage(join(CGI::br(),@debug_msgs) ) if @debug_msgs; + my $debug_msg = CGI::br().join( CGI::br(), @{ $pg->{pgcore}->get_debug_messages}); + $self->addmessage($debug_msg ) if $debug_msg; $self->{pgdebug} = $pg->{pgcore}->get_debug_messages; $self->{pgwarning} = $pg->{pgcore}->get_warning_messages; $self->{pginternalerrors} = $pg->{pgcore}->get_internal_debug_messages ; - $self->{pgerrors} = @{$self->{pgdebug}} || @{$self->{pgwarning}} || @{$self->{pginternalerrors}}; + $self->{pgerrors} = @{$self->{pgdebug}} || @{$self->{pgwarning}} || @{$self->{pginternalerrors}}||0; + } else { + $self->{pgerrors}=undef; # unable to obtain errors } debug("end pg processing"); @@ -752,23 +754,30 @@ sub pre_header_initialize { } sub warnings { my $self = shift; - $self->SUPER::warnings(); - my $r = $self->r; - my $pg = $self->{pg}; - - my @pgdebug = @{ $self->{pgdebug} }; - my @pgwarning = @{ $self->{pgwarning} }; - my @pginternalerrors = @{ $self->{pginternalerrors} }; -# my $pgerrordiv = $pgdebug||$pgwarning||$pginternalerrors; # is 1 if any of these are non-empty + # print "entering warnings() subroutine internal messages = ", $self->{pgerrors},CGI::br(); + my $r = $self->r; +# my $pg = $self->{pg}; +# warn "type of pg is ",ref($pg); +# my $pgerrordiv = $pgdebug||$pgwarning||$pginternalerrors; # is 1 if any of these are non-empty # print warning messages - if ( $self->{pgerrors} ) { + if (not defined $self->{pgerrors} ) { + print CGI::start_div(); + print CGI::h3({style=>"color:red;"}, $r->maketext("PG question failed to render")); + print CGI::p($r->maketext("Unable to obtain error messages from within the PG question." )); + print CGI::end_div(); + } elsif ( $self->{pgerrors} > 0 ) { + my @pgdebug = @{ $self->{pgdebug} }; + my @pgwarning = @{ $self->{pgwarning} }; + my @pginternalerrors = @{ $self->{pginternalerrors} }; print CGI::start_div(); - print CGI::h3({style=>"color:red;"}, $r->maketext("Additional Error Messages")); - print CGI::p(CGI::h3("PG debug messages"), CGI::br(), @pgdebug ) if @pgdebug ; - print CGI::p(CGI::h3("PG warning messages"), CGI::br(), @pgwarning ) if @pgwarning ; - print CGI::p(CGI::h3("PG internal errors"), CGI::br(), @pginternalerrors ) if @pginternalerrors; + print CGI::h3({style=>"color:red;"}, $r->maketext("PG question processing error messages")); + print CGI::p(CGI::h3($r->maketext("PG debug messages" ) ), CGI::br(), join(CGI::br(), @pgdebug ) ) if @pgdebug ; + print CGI::p(CGI::h3($r->maketext("PG warning messages" ) ), CGI::br(), join(CGI::br(), @pgwarning) ) if @pgwarning ; + print CGI::p(CGI::h3($r->maketext("PG internal errors" ) ), CGI::br(), join(CGI::br(), @pginternalerrors )) if @pginternalerrors; print CGI::end_div(); - } + } + # print "proceeding to SUPER::warnings"; + $self->SUPER::warnings(); ""; } @@ -924,7 +933,7 @@ sub body { my $set = $self->{set}; my $problem = $self->{problem}; my $pg = $self->{pg}; - + print CGI::p("Entering Problem::body subroutine. This indicates an older style system.template file -- consider upgrading. "); my $valid = WeBWorK::ContentGenerator::ProblemUtil::ProblemUtil::check_invalid($self); unless($valid eq "valid"){ return $valid; @@ -1048,10 +1057,13 @@ sub output_editorLink{ if ($pg->{flags}->{error_flag}) { if ($authz->hasPermissions($user, "view_problem_debugging_info")) { + print "Call errorOutput
"; print $self->errorOutput($pg->{errors}, $pg->{body_text}); + print $editorLink; } else { print $self->errorOutput($pg->{errors}, $r->maketext("You do not have permission to view the details of this error.")); } + print ""; } else{