| 1 | ################################################################################ |
1 | ################################################################################ |
| 2 | # WeBWorK |
2 | # WeBWorK |
| 3 | # |
3 | # |
| 4 | # Copyright (c) 1995-2001 University of Rochester |
4 | # Copyright (c) 1995-2001 WeBWorK Team, University of Rochester |
| 5 | # All rights reserved |
5 | # All rights reserved |
| 6 | # |
6 | # |
| 7 | # $Id$ |
7 | # $Id$ |
| 8 | ################################################################################ |
8 | ################################################################################ |
| 9 | |
9 | |
|
|
10 | ################################### |
|
|
11 | ## Begin Global |
|
|
12 | ################################### |
|
|
13 | |
|
|
14 | package Global; |
|
|
15 | |
|
|
16 | # The variables defined in this package set defaults and parameters for |
|
|
17 | # the whole weBWorK system. Defaults can be over ridden for individual |
|
|
18 | # courses by redefining variables in the individual course |
|
|
19 | # webworkCourse.ph file. For example the default SYSTEM feedback address |
|
|
20 | # set below as: $feedbackAddress = 'webwork@math.rochester.edu'; can (and |
|
|
21 | # should) be over ridden for an individual course by entering e.g. |
|
|
22 | # $Global::feedbackAdress = 'apizer@math.rochester.edu, |
|
|
23 | # gage@math.rochester.edu'; in the individual course webworkCourse.ph |
|
|
24 | # file. Of course you should really enter the email address(es) of the |
|
|
25 | # professors teaching the course. |
|
|
26 | |
|
|
27 | ################################ |
|
|
28 | # Local configuration settings # |
|
|
29 | ################################ |
|
|
30 | |
|
|
31 | # $legalAddress defines addresses which are accepted for use in scripts that send mail. |
|
|
32 | # it is a perl regular expression. |
|
|
33 | $legalAddress = '^[\w\-\.]+(\@([\w\-\.]+\.)*rochester\.edu)?$'; # destinations must match |
|
|
34 | |
|
|
35 | # these define the default addresses to which will be used by the system. |
|
|
36 | $feedbackAddress = 'webwork@math.rochester.edu'; |
|
|
37 | $webmaster = $feedbackAddress; |
|
|
38 | $defaultfrom = $feedbackAddress; |
|
|
39 | $defaultreply = $feedbackAddress; |
|
|
40 | |
|
|
41 | # $smtpServer is the address of the sendmail server. if you are running sendmail on the |
|
|
42 | # same machine as webwork, use "localhost" |
|
|
43 | $smtpServer = 'mail.math.rochester.edu'; |
|
|
44 | |
|
|
45 | # $dirDelim is the delimiter used in pathnames on your system. |
|
|
46 | $dirDelim = '/'; |
|
|
47 | |
|
|
48 | # $cgiDebugMode, if enabled, will call the debug wrapper scripts instead of the |
|
|
49 | # cgi scripts themselves, allowing for header output, etc. |
|
|
50 | $cgiDebugMode = 0; |
|
|
51 | |
|
|
52 | ## Change DBtie_file only if you want to change the default database. The script |
|
|
53 | ## db_tie.pl uses DB_File (the Berkeley DB) and gdbm_tie.pl uses GDBM_File. This |
|
|
54 | ## setting can be changed for an individual course in the webworkCourse.ph file. For |
|
|
55 | ## some other database, you will have to write your own database tie-file. Such |
|
|
56 | ## files reside in the scripts directory. |
|
|
57 | #$DBtie_file = 'db_tie.pl'; |
|
|
58 | $DBtie_file = 'gdbm_tie.pl'; |
|
|
59 | |
|
|
60 | ## Set to 1 to enable the access log; set to 0 to disable. |
|
|
61 | ## |
|
|
62 | ## The access log is stored in the logs/ directory under the system directory |
|
|
63 | ## in a file called "access_log". It contains information about virtually |
|
|
64 | ## every action committed by users, including all answers submitted. |
|
|
65 | ## Usually this information is unneccessary, and the file becomes |
|
|
66 | ## large very quickly, so this log is ordinarily turned off. However, the |
|
|
67 | ## information it contains might be useful if, for example, a student wants an |
|
|
68 | ## extension and claims not to have viewed the correct answers. |
|
|
69 | $logAccessData = 1; |
|
|
70 | |
|
|
71 | #################################################################################### |
|
|
72 | ########### There should be no need to customize after this point ################# |
|
|
73 | #################################################################################### |
|
|
74 | |
| 10 | use sigtrap; |
75 | use sigtrap; |
|
|
76 | use diagnostics; |
|
|
77 | use webworkConfig; |
|
|
78 | use PGtranslator; |
|
|
79 | # this is so that PGtranslator->evalute_macros is available when webworkCourse.ph is processed. |
|
|
80 | |
|
|
81 | require 5.000; |
|
|
82 | require Exporter; |
|
|
83 | @ISA = qw(Exporter); |
|
|
84 | @EXPORT = qw( |
|
|
85 | getWebworkScriptDirectory |
|
|
86 | getWebworkCgiURL |
|
|
87 | getCourseMOTDFile |
|
|
88 | getSystemMOTDFile |
|
|
89 | getCourseDatabaseDirectory |
|
|
90 | getCourseDatabaseTieFile |
|
|
91 | getCourseLogsDirectory |
|
|
92 | getCourseTemplateDirectory |
|
|
93 | getCourseURL |
|
|
94 | getCourseScoringDirectory |
|
|
95 | getCourseScriptsDirectory |
|
|
96 | getCourseMacroDirectory |
|
|
97 | getCourseHtmlDirectory |
|
|
98 | getCourseEmailDirectory |
|
|
99 | getCourseTempDirectory |
|
|
100 | getCourseTempURL |
|
|
101 | getCourseClasslistFile |
|
|
102 | getCourseEnvironment |
|
|
103 | getCourseKeyFile |
|
|
104 | getCoursePasswordFile |
|
|
105 | getCoursePermissionsFile |
|
|
106 | getCourseDatabaseFile |
|
|
107 | getCourseHtmlURL |
|
|
108 | getCoursel2hDirectory |
|
|
109 | getCoursel2hURL |
|
|
110 | getDirDelim |
|
|
111 | getDelim |
|
|
112 | getScoreFilePrefix |
|
|
113 | getScoring_log |
|
|
114 | getDash |
|
|
115 | getDat |
|
|
116 | getBbext |
|
|
117 | getStatusDrop |
|
|
118 | convertPath |
|
|
119 | getNumRelPercentTolDefault |
|
|
120 | getNumZeroLevelDefault |
|
|
121 | getNumZeroLevelTolDefault |
|
|
122 | getNumAbsTolDefault |
|
|
123 | getNumFormatDefault |
|
|
124 | getFunctRelPercentTolDefault |
|
|
125 | getFunctZeroLevelDefault |
|
|
126 | getFunctZeroLevelTolDefault |
|
|
127 | getFunctAbsTolDefault |
|
|
128 | getFunctNumOfPoints |
|
|
129 | getFunctVarDefault |
|
|
130 | getFunctLLimitDefault |
|
|
131 | getFunctULimitDefault |
|
|
132 | getFunctMaxConstantOfIntegration |
|
|
133 | getLoginURL |
|
|
134 | getWebworkLogsDirectory |
|
|
135 | wwerror |
|
|
136 | getAllowDestroyRebuildProbSets |
|
|
137 | ); |
|
|
138 | |
|
|
139 | ## URL's derived from webworkConfig.pm |
|
|
140 | $loginURL = "${cgiWebworkURL}login.pl"; |
|
|
141 | $imagesURL = "${htmlWebworkURL}images/"; |
|
|
142 | $helpURL = "${htmlWebworkURL}helpFiles/"; |
|
|
143 | $webworkDocsURL = 'http://webwork.math.rochester.edu/docs/docs/'; |
|
|
144 | $appletsURL = "${htmlWebworkURL}applets/"; |
|
|
145 | |
|
|
146 | ## practice users |
|
|
147 | $practiceUser = 'practice'; # name of password-less "practice" user |
|
|
148 | $practiceKey = 'practice'; # a dummy key for this user, can be anything |
|
|
149 | |
|
|
150 | |
|
|
151 | ## The database handle for using mSQL: |
|
|
152 | $dbh = 0; |
|
|
153 | |
|
|
154 | ## various gifs |
|
|
155 | $helpGifUrl = "${imagesURL}ww_help.gif"; |
|
|
156 | $logoutGifUrl = "${imagesURL}ww_logout.gif"; |
|
|
157 | $feedbackGifUrl = "${imagesURL}ww_feedback.gif"; |
|
|
158 | $currentImgUrl = "${imagesURL}ww_curr.gif"; |
|
|
159 | $previousImgUrl = "${imagesURL}ww_prev.gif"; |
|
|
160 | $nextImgUrl = "${imagesURL}ww_next.gif"; |
|
|
161 | $problistImgUrl = "${imagesURL}ww_problist.gif"; |
|
|
162 | $upImgUrl = "${imagesURL}ww_up.gif"; |
|
|
163 | $bluesquareImgUrl = "${imagesURL}ww_bluesq.gif"; |
|
|
164 | $headerImgUrl = "${imagesURL}webwork.gif"; # image to include at top of pages |
|
|
165 | $squareWebworkGif = "${imagesURL}square_webwork.gif"; # image to include at top of pages |
|
|
166 | |
|
|
167 | ## backgrounds gifs for HTML documents |
|
|
168 | $background_plain_url = "${imagesURL}white.gif"; |
|
|
169 | $background_okay_url = "${imagesURL}green.gif"; |
|
|
170 | $background_warn_url = "${imagesURL}red.gif"; |
|
|
171 | $bg_color = '#EFEFEF'; #background color for processProblem |
|
|
172 | |
|
|
173 | ## Directories |
|
|
174 | $coursesDirectory = convertPath("${mainDirectory}courses/"); |
|
|
175 | $scriptDirectory = convertPath("${mainDirectory}scripts/"); |
|
|
176 | $cgiDirectory = convertPath("${mainDirectory}cgi/"); |
|
|
177 | #$tempDirectory = convertPath("/tmp/"); |
|
|
178 | $authDirectory = convertPath(".auth/"); |
|
|
179 | $courseScriptsDirectory = convertPath("${mainDirectory}courseScripts/"); |
|
|
180 | $macroDirectory = convertPath("${mainDirectory}courseScripts/"); |
|
|
181 | $classDirectory = ''; #This must be defined in webworkCourse.ph |
|
|
182 | $webworkLogsDirectory = "${mainDirectory}/logs/"; |
|
|
183 | |
|
|
184 | ## File names |
|
|
185 | $coursesFilename = 'courses-list'; |
|
|
186 | $coursesFile = "${coursesDirectory}$coursesFilename"; |
|
|
187 | $classlistFilename = 'classlist.lst'; |
|
|
188 | $keyFilename = 'keys'; |
|
|
189 | $passwordFilename = 'password'; |
|
|
190 | $permissionsFilename = 'permissions'; |
|
|
191 | $database = 'webwork-database'; |
|
|
192 | $CL_Database = 'classlist-database'; |
|
|
193 | $tipsFilename = 'tips.txt'; |
|
|
194 | $system_motd_filename = 'motd.txt'; |
|
|
195 | $course_motd_filename = 'motd.txt'; |
|
|
196 | $tipsFile = "${mainDirectory}$tipsFilename"; |
|
|
197 | |
|
|
198 | # CGI script calls |
|
|
199 | |
|
|
200 | $login_CGI = "${cgiWebworkURL}login.pl"; |
|
|
201 | $logout_CGI = "${cgiWebworkURL}logout.pl"; |
|
|
202 | $welcome_CGI = "${cgiWebworkURL}welcome.pl"; |
|
|
203 | $welcomeAction_CGI = "${cgiWebworkURL}welcomeAction.pl"; |
|
|
204 | $processProblem_CGI = "${cgiWebworkURL}processProblem8.pl"; |
|
|
205 | $feedback_CGI = "${cgiWebworkURL}feedback.pl"; |
|
|
206 | $problemEditor_CGI = "${cgiWebworkURL}problemEditor.pl"; |
|
|
207 | |
|
|
208 | ## The following items control how the whole problem set is typeset by downloadPS.pl. |
|
|
209 | ## The files (e.g. "tex_set_ptramble.tex") are found in the .../templates directory |
|
|
210 | ## Note that the system dependent latex and dvips programs are defined in the file |
|
|
211 | ## makePS which is in the .../scripts directory. makePS must be edited to call |
|
|
212 | ## the correct programs. |
|
|
213 | ## |
|
|
214 | |
|
|
215 | ## This is the tex preamble file used by downloadPS.pl in typeseting the whole problem set. |
|
|
216 | ## E.g. loads AMS latex and graphics packages, some macro definitions. |
|
|
217 | $TEX_SET_PREAMBLE = 'texSetPreamble.tex'; |
|
|
218 | |
|
|
219 | ## This is the tex header file used by downloadPS.pl in typeseting the whole problem set |
|
|
220 | ## E.g. loads two column format, macro definitions. |
|
|
221 | $TEX_SET_HEADER = ''; |
|
|
222 | |
|
|
223 | ## This is the header file used by downloadPS.pl to enter preliminary verbiage for the |
|
|
224 | ## whole problem set. E.g. Course name, student name, problem set number,instructions, due date. |
|
|
225 | $SET_HEADER = 'paperSetHeader.pg'; |
|
|
226 | |
|
|
227 | ## This is the tex footer file used by downloadPS.pl in typeseting the whole problem set |
|
|
228 | $TEX_SET_FOOTER = 'texSetFooter.tex'; |
|
|
229 | |
|
|
230 | |
|
|
231 | ## The following items control how an individual problem is typeset by processProblem.pl |
|
|
232 | ## and l2h. Note that the system dependent latex2html program is defined in processProblem.pl. It |
|
|
233 | ## should really be in a seperate file like makeps. |
|
|
234 | |
|
|
235 | ## This is the tex preamble file used by processProblem.pl typeseting an individual problem |
|
|
236 | ## Usually very similar to $TEX_SET_PREAMBLE |
|
|
237 | $TEX_PROB_PREAMBLE = 'texProbPreamble.tex'; |
|
|
238 | |
|
|
239 | ## This is the tex header file used by processProblem.pl typeseting an individual problem |
|
|
240 | $TEX_PROB_HEADER = ''; |
|
|
241 | |
|
|
242 | |
|
|
243 | ## This is the header file used by probSet.pl to enter preliminary verbiage on the prob set |
|
|
244 | ## page. E.g. Instructions, due date. |
|
|
245 | $PROB_HEADER = 'screenSetHeader.pg'; |
|
|
246 | |
|
|
247 | ## This is the tex footer file processProblem.pl typeseting an individual problem |
|
|
248 | $TEX_PROB_FOOTER = 'texProbFooter.tex'; |
|
|
249 | |
|
|
250 | |
|
|
251 | |
|
|
252 | $courseEnvironmentFile = 'webworkCourse.ph'; |
|
|
253 | #$webworkCourse_ph = 'webworkCourse.ph'; |
|
|
254 | $DBglue_pl = 'DBglue8.pl'; |
|
|
255 | $HTMLglue_pl = 'HTMLglue.pl'; |
|
|
256 | $classlist_DBglue_pl = 'classlist_DBglue.pl'; |
|
|
257 | $FILE_pl = 'FILE.pl'; |
|
|
258 | $displayMacros_pl = 'displayMacros.pl'; |
|
|
259 | $scoring_log = 'scoring.log'; |
|
|
260 | #####$probSetHeader = 'probSetHeader'; |
|
|
261 | $SCRtools_pl = 'pScSet6.pl'; |
|
|
262 | $buildProbSetTools = 'proceduresForBuildProbSetDB.pl'; |
|
|
263 | |
|
|
264 | |
|
|
265 | ## File and Directory permissions |
|
|
266 | |
|
|
267 | ## e.g. S1-1521.sco in (base course directory)/DATA |
|
|
268 | $sco_files_permission = 0660; |
|
|
269 | |
|
|
270 | ## tie permissions (used in tie commands) |
|
|
271 | ## The database, password, and permissions files |
|
|
272 | ## always take their permissions from the Global |
|
|
273 | ## vaiables below. The important keys file |
|
|
274 | ## takes its permission from $restricted_tie_permission. |
|
|
275 | $restricted_tie_permission = 0600; |
|
|
276 | $standard_tie_permission = 0660; |
|
|
277 | |
|
|
278 | ## webwork-database in (base course directory)/DATA |
|
|
279 | $webwork_database_permission = 0660; |
|
|
280 | |
|
|
281 | ## password in (base course directory)/DATA/.auth |
|
|
282 | $password_permission = 0660; |
|
|
283 | |
|
|
284 | ## permissions in (base course directory)/DATA/.auth |
|
|
285 | $permissions_permission = 0660; |
|
|
286 | |
|
|
287 | ## e.g. s1ful.csv in (base course directory)/scoring |
|
|
288 | $scoring_files_permission = 0660; |
|
|
289 | |
|
|
290 | ## e.g. s1bak1.csv in (base course directory)/scoring |
|
|
291 | $scoring_bak_files_permission = 0440; |
|
|
292 | |
|
|
293 | ## e.g. 8587l2h.log in (base course directory)/html/tmp/l2h |
|
|
294 | $l2h_logs_permission = 0660; |
|
|
295 | |
|
|
296 | ## e.g. set1/ in (base course directory)/html/tmp/l2h |
|
|
297 | $l2h_set_directory_permission = 0770; |
|
|
298 | |
|
|
299 | ## e.g. 1-1082/ in (base course directory)/html/tmp/l2h/set1 |
|
|
300 | $l2h_prob_directory_permission = 0770; |
|
|
301 | |
|
|
302 | ## e.g. 1082output.html in (base course directory)/html/tmp/l2h/set1/1-1082 |
|
|
303 | $l2h_data_permission = 0770; |
|
|
304 | |
|
|
305 | ## e.g. file.gif in (base course directory)/html/tmp/gif |
|
|
306 | $tmp_file_permission = 0660; |
|
|
307 | |
|
|
308 | ## e.g. gif/ in (base course directory)/html/tmp/ |
|
|
309 | $tmp_directory_permission = 0770; |
|
|
310 | |
|
|
311 | ##e.g. classlist files (e.g. MTH140A.lst) in (base course directory)/templates/ |
|
|
312 | $classlist_file_permission = 0660; |
|
|
313 | |
|
|
314 | ## Prefixes, extensions, defaults, etc |
|
|
315 | |
|
|
316 | $scoreFilePrefix = 'S'; |
|
|
317 | $dash = '-'; # Can not be the underscore character or an upper or |
|
|
318 | # lowercase letter or a digit. Used in .sco file names |
|
|
319 | $delim = ','; # used in scoring, classlist |
|
|
320 | $dat = 'csv'; |
|
|
321 | @statusDrop = qw(drop d withdraw); |
|
|
322 | $courselist_delim = '::'; # used by login.pl to get course names / dirs |
|
|
323 | $instructor_permissions = 10; |
|
|
324 | $TA_permissions = 5; |
|
|
325 | $psvn_digits = 5; # Number of digits in psvn numbers. E.g. if 4, psvn's |
|
|
326 | # will be between 1000 and 9999. The number of available |
|
|
327 | # psvn's must be greater than (#students)*(#problem sets) |
|
|
328 | $score_decimal_digits = 1; # Number of decimal digits in recorded scores. For example |
|
|
329 | # if this is 1 then on a 1 point problem that allows partial |
|
|
330 | # credit, possible scores are 0, .1, .2, ..., 1. |
|
|
331 | |
|
|
332 | $maxAttemptsWarningLevel = 5; |
|
|
333 | # If the set definition file puts a limit on the number of |
|
|
334 | # times a problem may be attempted, processProblem.pl will |
|
|
335 | # give a warning message when <= $maxAttemptsWarningLevel |
|
|
336 | # attempts remain. |
|
|
337 | |
|
|
338 | $noOfFieldsInClasslist = 9; |
|
|
339 | # The number of fields in the classlist file. This is used as |
|
|
340 | # a check to make sure each record in the classlist file has |
|
|
341 | # this number of fields |
|
|
342 | |
|
|
343 | $htmlModeDefault = 'HTML_tth'; # The default mode for displayed problems (either 'HTML', |
|
|
344 | # 'Latex2HTML', or 'HTML_tth' |
|
|
345 | |
|
|
346 | $allowStudentToChangeEMAddress = 1; # setting to 1 allows students to change their |
|
|
347 | # own email address. Setting to 0 disallows this |
|
|
348 | |
|
|
349 | $Global::PG_environment{showPartialCorrectAnswers} = 1; ## Set to 0 or 1. If set to 1 in multipart |
|
|
350 | # questions the student will be told which parts are |
|
|
351 | # correct and which are incorrect. Usually, this is |
|
|
352 | # set explicitly in each individual problem. |
|
|
353 | |
|
|
354 | $allowDestroyRebuildProbSets = 0; # Set to 0 or 1. If set to 1 a professor can destroy and |
|
|
355 | # rebuild problems sets in one operation. This is very |
|
|
356 | # convenient and powerful, but also very dangerous. Usually |
|
|
357 | # this is not allowed in courses students are using. It is |
|
|
358 | # often set to 1 in a private course being used only for |
|
|
359 | # developing problem sets. To do this, reset this in the |
|
|
360 | # private course's webworkCourse.ph file. |
|
|
361 | |
|
|
362 | $Global::PG_environment{recordSubmittedAnswers} = 1; # Set to 0 or 1. If set to 1, submitted answers will be |
|
|
363 | # stored. For example in a multipart question, a student can |
|
|
364 | # do several parts, then logout or go onto another question. |
|
|
365 | # When they view the problem again, the answer blanks will be |
|
|
366 | # filled in with their most recent answers. This also allows |
|
|
367 | # professors to see exactly what a student entered. This default |
|
|
368 | # can be over ridden for an individual problem by setting |
|
|
369 | # recordSubmittedAnswers in the .pg file for the problem. |
|
|
370 | |
|
|
371 | $maxSizeRecordedAns = 256; # Student answers longer than this length in bytes will not |
|
|
372 | # stored in the database. |
|
|
373 | |
|
|
374 | $hide_studentID_from_TAs = 0; # Set to 0 or 1. If set to 1, studentID's will be hidden |
|
|
375 | # from TA's. For example some Universities may use SS#'s for |
|
|
376 | # student ID's and you may not want TA's to view these. |
|
|
377 | |
|
|
378 | ## arguments for flock() |
|
|
379 | |
|
|
380 | $shared_lock = 1; |
|
|
381 | $exclusive_lock = 2; |
|
|
382 | $nonblocking_lock = 4; |
|
|
383 | $unlock_lock = 8; |
|
|
384 | |
|
|
385 | # These values provide defaults for the various answer comparison macros found |
|
|
386 | # in PGanswermacros.pl. They can be over ridden for individual courses by |
|
|
387 | # redefining the variables in the individual course webworkCourse.ph file. |
|
|
388 | # They can be over ridden for individual problems by explicitly passing the |
|
|
389 | # desired values to the answer comparison macro |
|
|
390 | |
|
|
391 | # The following effect numerical answer comparison |
|
|
392 | $numRelPercentTolDefault = .1; |
|
|
393 | $numZeroLevelDefault = 1E-14; |
|
|
394 | $numZeroLevelTolDefault = 1E-12; |
|
|
395 | $numAbsTolDefault = .001; |
|
|
396 | $numFormatDefault = ''; ## use perl's format in prfmt() |
|
|
397 | # The following effect function comparison |
|
|
398 | $functRelPercentTolDefault = .1; |
|
|
399 | $functZeroLevelDefault = 1E-14; |
|
|
400 | $functZeroLevelTolDefault = 1E-12; |
|
|
401 | $functAbsTolDefault = .001; |
|
|
402 | $functNumOfPoints = 3; |
|
|
403 | $functVarDefault = 'x'; |
|
|
404 | $functLLimitDefault = .0000001; |
|
|
405 | $functULimitDefault = .9999999; |
|
|
406 | # The following effects function comparison upto constant for antidifferentiation |
|
|
407 | $functMaxConstantOfIntegration = 1E8; |
|
|
408 | |
|
|
409 | ## These values provide defaults for the window size in the problemEditor.pl script |
|
|
410 | $editor_window_rows = 25; |
|
|
411 | $editor_window_columns = 90; |
|
|
412 | |
|
|
413 | ## This is the maximum number problems sets that can be downloaded at one time |
|
|
414 | ## by a professor. Set this higher or lower depending on the speed of your server |
|
|
415 | |
|
|
416 | $max_num_of_ps_downloads_allowed = 20; |
|
|
417 | |
|
|
418 | |
|
|
419 | # Subroutines for defining the directories and URLs |
|
|
420 | ###### Public vars/routines - these are imported into your namespace, ####### |
|
|
421 | ###### so they can be called as they are. |
|
|
422 | ####### |
|
|
423 | |
|
|
424 | sub getWebworkScriptDirectory { convertPath($scriptDirectory ) }; |
|
|
425 | sub getCourseDatabaseDirectory { convertPath($databaseDirectory )}; |
|
|
426 | sub getCourseDatabaseTieFile { convertPath($DBtie_file )}; |
|
|
427 | sub getCourseLogsDirectory { convertPath($logsDirectory )}; |
|
|
428 | sub getCourseTemplateDirectory { convertPath($templateDirectory )}; |
|
|
429 | sub getCourseEmailDirectory { convertPath("${templateDirectory}email/")}; |
|
|
430 | sub getCourseScoringDirectory { convertPath($scoringDirectory ) }; |
|
|
431 | sub getCourseHtmlDirectory { convertPath($htmlDirectory )}; |
|
|
432 | sub getCourseTempDirectory {convertPath($courseTempDirectory)}; |
|
|
433 | sub getCoursel2hDirectory { convertPath( "${courseTempDirectory}l2h/" )}; |
|
|
434 | sub getCourseScriptsDirectory { convertPath($courseScriptsDirectory )}; |
|
|
435 | sub getCourseMacroDirectory { convertPath($macroDirectory )}; |
|
|
436 | sub getWebworkLogsDirectory { convertPath($webworkLogsDirectory)}; |
|
|
437 | |
|
|
438 | sub getCourseClasslistFile { convertPath("${coursesDirectory}$_[0]/templates/${classlistFilename}") }; |
|
|
439 | |
|
|
440 | sub getCourseKeyFile { convertPath("${coursesDirectory}$_[0]/DATA/${authDirectory}${keyFilename}") }; |
|
|
441 | sub getCoursePasswordFile { convertPath("${coursesDirectory}$_[0]/DATA/${authDirectory}${passwordFilename}") }; |
|
|
442 | sub getCoursePermissionsFile { convertPath("${coursesDirectory}$_[0]/DATA/${authDirectory}${permissionsFilename}") }; |
|
|
443 | sub getCourseDatabaseFile { convertPath("${coursesDirectory}$_[0]/DATA/${$database}") }; |
|
|
444 | |
|
|
445 | sub getCourseMOTDFile { convertPath("${coursesDirectory}$_[0]/templates/${course_motd_filename}") }; |
|
|
446 | sub getSystemMOTDFile { convertPath("${mainDirectory}${system_motd_filename}") }; |
|
|
447 | |
|
|
448 | sub getWebworkCgiURL { $cgiWebworkURL }; |
|
|
449 | sub getCourseHtmlURL { $htmlURL }; |
|
|
450 | sub getCoursel2hURL { "${courseTempURL}l2h/" } |
|
|
451 | sub getCourseTempURL { $courseTempURL }; #defined in webworkCourse.ph |
|
|
452 | sub getDirDelim { $dirDelim }; |
|
|
453 | sub getDelim { $delim }; |
|
|
454 | sub getScoreFilePrefix { $scoreFilePrefix }; |
|
|
455 | sub getScoring_log { $scoring_log }; |
|
|
456 | sub getDash { $dash }; |
|
|
457 | sub getDat { $dat }; |
|
|
458 | sub getBbext { @dbext }; |
|
|
459 | sub getStatusDrop { @statusDrop }; |
|
|
460 | |
|
|
461 | sub getNumRelPercentTolDefault { $numRelPercentTolDefault }; |
|
|
462 | sub getNumZeroLevelDefault { $numZeroLevelDefault }; |
|
|
463 | sub getNumZeroLevelTolDefault { $numZeroLevelTolDefault }; |
|
|
464 | sub getNumAbsTolDefault { $numAbsTolDefault }; |
|
|
465 | sub getNumFormatDefault { $numFormatDefault }; |
|
|
466 | sub getFunctRelPercentTolDefault { $functRelPercentTolDefault }; |
|
|
467 | sub getFunctZeroLevelDefault { $functZeroLevelDefault }; |
|
|
468 | sub getFunctZeroLevelTolDefault { $functZeroLevelTolDefault }; |
|
|
469 | sub getFunctAbsTolDefault { $functAbsTolDefault }; |
|
|
470 | sub getFunctNumOfPoints { $functNumOfPoints }; |
|
|
471 | sub getFunctVarDefault { $functVarDefault }; |
|
|
472 | sub getFunctLLimitDefault { $functLLimitDefault }; |
|
|
473 | sub getFunctULimitDefault { $functULimitDefault }; |
|
|
474 | sub getFunctMaxConstantOfIntegration { $functMaxConstantOfIntegration }; |
|
|
475 | |
|
|
476 | sub getLoginURL { $loginURL }; |
|
|
477 | |
|
|
478 | sub getAllowDestroyRebuildProbSets { $allowDestroyRebuildProbSets }; |
|
|
479 | |
|
|
480 | sub getCourseEnvironment { |
|
|
481 | die "getCourseEnvironment was called without specifying a course" unless $_[0]; |
|
|
482 | my $fullPath = convertPath("${coursesDirectory}$_[0]/$courseEnvironmentFile"); |
|
|
483 | require "$fullPath" |
|
|
484 | || die "Can't find local environment file for |
|
|
485 | $fullPath\n"; |
|
|
486 | } |
|
|
487 | |
|
|
488 | |
|
|
489 | |
|
|
490 | ### dump a (hopefully) descriptive error to the browser and quit |
|
|
491 | #sub wwerror { |
|
|
492 | # my($title, $msg, $url, $label, $query_string) = @_; |
|
|
493 | # |
|
|
494 | # print "content-type: text/html\n\n |
|
|
495 | # <HTML><HEAD><TITLE>Error: $title</TITLE></HEAD> |
|
|
496 | # <BODY BACKGROUND=\"$background_warn_url\"> |
|
|
497 | # <H1>Error: $title</H1>\n $msg \n"; |
|
|
498 | # if ($url) { |
|
|
499 | # print "<FORM ACTION=\"$url\"> |
|
|
500 | # <INPUT TYPE=SUBMIT VALUE=\"$label\"> |
|
|
501 | # </FORM>\n"; |
|
|
502 | # } |
|
|
503 | # print "</BODY></HTML>"; |
|
|
504 | # &log_error($title, $query_string); |
|
|
505 | # exit 1; |
|
|
506 | #} |
|
|
507 | |
|
|
508 | sub wwerror { |
|
|
509 | my($title, $msg, $url, $label, $query_string) = @_; |
|
|
510 | # <BODY BACKGROUND=\"$background_warn_url\"> |
|
|
511 | |
|
|
512 | $msg = '' unless defined $msg; |
|
|
513 | $url = '' unless defined $url; |
|
|
514 | $label = '' unless defined $label; |
|
|
515 | $query_string = '' unless defined $query_string; |
|
|
516 | |
|
|
517 | print "content-type: text/html\n\n |
|
|
518 | <HTML><HEAD><TITLE>Error: $title</TITLE></HEAD> |
|
|
519 | <BODY BGCOLOR = 'CCCCCC'> |
|
|
520 | |
|
|
521 | <H2>Error: $title</H2> |
|
|
522 | <PRE>$msg\n |
|
|
523 | </PRE>"; |
|
|
524 | if ($url) { |
|
|
525 | print "<FORM ACTION=\"$url\"> |
|
|
526 | <INPUT TYPE=SUBMIT VALUE=\"$label\"> |
|
|
527 | </FORM>\n"; |
|
|
528 | } |
|
|
529 | print "</BODY></HTML>"; |
|
|
530 | &log_error($title, $query_string); |
|
|
531 | exit 1; |
|
|
532 | } |
|
|
533 | |
|
|
534 | sub error {wwerror(@_);} ##alias for wwerror |
|
|
535 | |
|
|
536 | |
|
|
537 | # return a (scalar) tip |
|
|
538 | sub tip { |
|
|
539 | my ($tips, @tiplist); |
|
|
540 | local($/) = undef; |
|
|
541 | #undef $/; # slurp it all in |
|
|
542 | open(TIPS, "$tipsFile") || &error("Can't open $tipsFile"); |
|
|
543 | $tips = <TIPS>; |
|
|
544 | close(TIPS); |
|
|
545 | |
|
|
546 | # add any local tips to the list before we pick a random one |
|
|
547 | if (-r "${templateDirectory}$tipsFilename") { |
|
|
548 | open(TIPS, "${templateDirectory}$tipsFilename"); |
|
|
549 | $tips .= '%%' . <TIPS>; |
|
|
550 | close(TIPS); |
|
|
551 | } |
|
|
552 | $/ = "\n"; # <> now reads until newline |
|
|
553 | $tips =~ s/#.*?\n//mg; # remove comments |
|
|
554 | @tiplist = split(/%%/, $tips); |
|
|
555 | return $tiplist[rand(@tiplist)]; # choose one at random |
|
|
556 | } |
|
|
557 | |
|
|
558 | # return an array of tips |
|
|
559 | sub all_tips { |
|
|
560 | my ($tip, $tips, @tiplist); |
|
|
561 | |
|
|
562 | local($/) = undef; # slurp it all in |
|
|
563 | open(TIPS, "$tipsFile") || &error("Can't open $tipsFile"); |
|
|
564 | $tips = <TIPS>; |
|
|
565 | close(TIPS); |
|
|
566 | |
|
|
567 | # add any local tips to the list before we pick a random one |
|
|
568 | if (-r "${templateDirectory}$tipsFilename") { |
|
|
569 | open(TIPS, "${templateDirectory}$tipsFilename"); |
|
|
570 | $tips .= '%%' . <TIPS>; |
|
|
571 | close(TIPS); |
|
|
572 | } |
|
|
573 | $/ = "\n"; # <> now reads until newline |
|
|
574 | $tips =~ s/#.*?\n//mg; # remove comments |
|
|
575 | @tiplist = split(/%%/, $tips); |
|
|
576 | return @tiplist; |
|
|
577 | } |
|
|
578 | |
|
|
579 | |
|
|
580 | # begin Timing code |
|
|
581 | use Benchmark; |
|
|
582 | sub dateTime { |
|
|
583 | my @timeArray = localtime(time); |
|
|
584 | my $out = sprintf("%2.2d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d", |
|
|
585 | $timeArray[5],$timeArray[4]+1,@timeArray[3,2,1,0]); |
|
|
586 | $out; |
|
|
587 | } |
|
|
588 | |
|
|
589 | #the ps system calls do not work on all systems, and are usually not |
|
|
590 | #necessary anyway. If you wish that information to be logged, simply |
|
|
591 | #uncomment the relevant lines, but be warned that they might need to |
|
|
592 | #be modified for your system |
|
|
593 | sub logTimingInfo { |
|
|
594 | my ($beginTime,$endTime,$script,$course,$user,$remoteHost,$userAgent) = @_; |
|
|
595 | $remoteHost = ""unless defined($remoteHost); |
|
|
596 | $userAgent = "" unless defined($userAgent); |
|
|
597 | open(TIMELOG, ">>${webworkLogsDirectory}timing_log") || |
|
|
598 | warn "*Unable to open timing log for writing:\n ${webworkLogsDirectory}timing_log. "; |
|
|
599 | |
|
|
600 | my $mem_string = ''; |
|
|
601 | # my $process_string = `ps -o vsz -p $$`; |
|
|
602 | # $process_string =~ s/^\s*//; |
|
|
603 | # $process_string =~ s/\s*$//; |
|
|
604 | # my @process_string = split(/\s+/,$process_string); # gets memory size |
|
|
605 | # my $mem_string = " mem: ${process_string[1]}K"; |
|
|
606 | |
|
|
607 | my $load_string = ''; |
|
|
608 | # my @load = split(/\n/,`ps -U wwhttpd -o state`); |
|
|
609 | # my $load_string = " load: " . grep(/R/,@load); |
|
|
610 | |
|
|
611 | print TIMELOG $script,"\t",$course,"\t",&dateTime,"\t", |
|
|
612 | timestr( timediff($endTime,$beginTime), 'all' ),"\t", |
|
|
613 | "pid: $$ DBtie_tries: $Global::DBtie_tries" . $mem_string . $load_string,"\t",$user,"\t", |
|
|
614 | $remoteHost,"\t",$userAgent,"\n"; |
|
|
615 | close(TIMELOG); |
|
|
616 | } |
|
|
617 | # end Timing code |
|
|
618 | |
|
|
619 | |
|
|
620 | # handy routines for modules that wish to throw exceptions outside of the |
|
|
621 | # current package. (taken from Carp.pm) |
|
|
622 | # |
|
|
623 | # We'll want to remove this in final versions of WeBWorK. |
|
|
624 | |
|
|
625 | sub log_error { |
|
|
626 | my ($comment, $data) = @_; |
|
|
627 | my $accessLog = convertPath("${webworkLogsDirectory}access_log"); |
|
|
628 | my $errorLog = convertPath("${webworkLogsDirectory}error_log"); |
|
|
629 | open(ACCESS, ">>$accessLog"); |
|
|
630 | open(ERROR, ">>$errorLog"); |
|
|
631 | print ACCESS "ERROR ($comment) ", scalar(localtime), ': ', &shortmess($data); |
|
|
632 | print ERROR "ERROR ($comment) ", scalar(localtime), ': ', &shortmess($data); |
|
|
633 | close(ACCESS); |
|
|
634 | close(ERROR); |
|
|
635 | } |
|
|
636 | |
|
|
637 | sub log_info { |
|
|
638 | if( $Global::logAccessData == 1 ) { |
|
|
639 | my ($comment, $data) = @_; |
|
|
640 | my $accessLog = convertPath("${webworkLogsDirectory}access_log"); |
|
|
641 | open(LOG, ">>$accessLog") or warn "Can't open accessLog $accessLog"; |
|
|
642 | print LOG "INFO ($comment) ", scalar(localtime), ': ', &shortmess($data); |
|
|
643 | close(LOG); |
|
|
644 | } |
|
|
645 | } |
|
|
646 | |
|
|
647 | |
|
|
648 | ## converts full path names to to use the $dirDelim instead of / |
|
|
649 | sub convertPath { |
|
|
650 | my ($path) = @_; |
|
|
651 | warn "convertPath has been asked to convert an empty path<BR> |$path| at ", caller(),"<BR>" unless $path; |
|
|
652 | $path =~ s|/|$dirDelim|g; |
|
|
653 | |
|
|
654 | $path; |
|
|
655 | } |
|
|
656 | |
|
|
657 | # ----- |
| 11 | |
658 | |
| 12 | BEGIN { |
659 | BEGIN { |
| 13 | |
|
|
| 14 | sub PG_floating_point_exception_handler { # 1st argument is signal name |
660 | sub PG_floating_point_exception_handler { # 1st argument is signal name |
| 15 | my($sig) = @_; |
661 | my($sig) = @_; |
| 16 | print "Content-type: text/html\n\n<H4>There was a floating point arithmetic error (exception SIG$sig )</H4>--perhaps |
662 | print "Content-type: text/html\n\n<H4>There was a floating point arithmetic error (exception SIG$sig )</H4>--perhaps |
| 17 | you divided by zero or took the square root of a negative number? |
663 | you divided by zero or took the square root of a negative number? |
| 18 | <BR>\n Use the back button to return to the previous page and recheck your entries.<BR>\n"; |
664 | <BR>\n Use the back button to return to the previous page and recheck your entries.<BR>\n"; |
| 19 | exit(0); |
665 | exit(0); |
| 20 | } |
666 | } |
| 21 | |
667 | |
| 22 | $SIG{'FPE'} = \&PG_floating_point_exception_handler; |
668 | $SIG{'FPE'} = \&PG_floating_point_exception_handler; |
| 23 | |
669 | |
| 24 | sub PG_warnings_handler { |
670 | sub PG_warnings_handler { |
| 25 | my @input = @_; |
671 | my @input = @_; |
| 26 | my $msg_string = longmess(@_); |
672 | my $msg_string = longmess(@_); |
| 27 | my @msg_array = split("\n",$msg_string); |
673 | my @msg_array = split("\n",$msg_string); |
| 28 | my $out_string = "##More details:<BR>\n----"; |
674 | my $out_string = "##More details:<BR>\n----"; |
| 29 | foreach my $line (@msg_array) { |
675 | foreach my $line (@msg_array) { |
| 30 | chomp($line); |
676 | chomp($line); |
| 31 | next unless $line =~/\w+\:\:/; |
677 | next unless $line =~/\w+\:\:/; |
| 32 | $out_string .= "----" .$line . "<BR>\n"; |
678 | $out_string .= "----" .$line . "<BR>\n"; |
| 33 | } |
679 | } |
| 34 | |
680 | |
| 35 | $Global::WARNINGS .="* " . join("<BR>",@input) . "<BR>\n" . $out_string . |
681 | $Global::WARNINGS .="* " . join("<BR>",@input) . "<BR>\n" . $out_string . |
| 36 | "<BR>\n--------------------------------------<BR>\n<BR>\n"; |
682 | "<BR>\n--------------------------------------<BR>\n<BR>\n"; |
| 37 | $Global::background_plain_url = $Global::background_warn_url; |
683 | $Global::background_plain_url = $Global::background_warn_url; |
| 38 | $Global::bg_color = '#FF99CC'; #for warnings -- this change may come too late |
684 | $Global::bg_color = '#FF99CC'; #for warnings -- this change may come too late |
| 39 | } |
685 | } |
| 40 | |
686 | |
| 41 | $SIG{__WARN__}=\&PG_warnings_handler; |
687 | $SIG{__WARN__}=\&PG_warnings_handler; |
|
|
688 | |
| 42 | $SIG{__DIE__} = sub { |
689 | $SIG{__DIE__} = sub { |
| 43 | print "Content-type: text/html\r\n\r\n <h4>Software error</h4> @_<br> |
690 | print "Content-type: text/html\r\n\r\n <h4>Software error</h4> @_<br> |
| 44 | Please inform the webwork meister.<p> |
691 | Please inform the webwork meister.<p> |
| 45 | In addition to the error message above the following warnings were detected: |
692 | In addition to the error message above the following warnings were detected: |
| 46 | <HR> |
693 | <HR> |
| 47 | $Global::WARNINGS; |
694 | $Global::WARNINGS; |
| 48 | <HR> |
695 | <HR> |
| 49 | It's sometimes hard to tell exactly what has gone wrong since the |
696 | It's sometimes hard to tell exactly what has gone wrong since the |
| 50 | full error message may have been sent to |
697 | full error message may have been sent to |
| 51 | standard error instead of to standard out. |
698 | standard error instead of to standard out. |
| 52 | <p> To debug you can |
699 | <p> To debug you can |
| 53 | <ul> |
700 | <ul> |
| 54 | <li> guess what went wrong and try to fix it. |
701 | <li> guess what went wrong and try to fix it. |
| 55 | <li> call the offending script directly from the command line |
702 | <li> call the offending script directly from the command line |
| 56 | of unix |
703 | of unix |
| 57 | <li> enable the debugging features by redefining |
704 | <li> enable the debugging features by redefining |
| 58 | \$cgiURL in Global.pm and checking the redirection scripts in |
705 | \$cgiURL in Global.pm and checking the redirection scripts in |
| 59 | system/cgi. This will force the standard error to be placed |
706 | system/cgi. This will force the standard error to be placed |
| 60 | in the standard out pipe as well. |
707 | in the standard out pipe as well. |
| 61 | <li> Run tail -f error_log <br> |
708 | <li> Run tail -f error_log <br> |
| 62 | from the unix command line to see error messages from the webserver. |
709 | from the unix command line to see error messages from the webserver. |
| 63 | The standard error output is being placed in the error_log file for the apache |
710 | The standard error output is being placed in the error_log file for the apache |
| 64 | web server. To run this command you have to be in the directory containing the |
711 | web server. To run this command you have to be in the directory containing the |
| 65 | error_log or enter the full path name of the error_log. <p> |
712 | error_log or enter the full path name of the error_log. <p> |
| 66 | In a standard apache installation, this file is at /usr/local/apache/logs/error_log<p> |
713 | In a standard apache installation, this file is at /usr/local/apache/logs/error_log<p> |
| 67 | In a RedHat Linux installation, this file is at /var/log/httpd/error_log<p> |
714 | In a RedHat Linux installation, this file is at /var/log/httpd/error_log<p> |
| 68 | At Rochester this file is at /ww/logs/error_log. |
715 | At Rochester this file is at /ww/logs/error_log. |
| 69 | </ul> |
716 | </ul> |
| 70 | Good luck./n" ; exit(0); }; #exit(0); |
717 | Good luck./n" ; exit(0); |
| 71 | # CGI::Carp::croak(@_); }; |
718 | }; |
|
|
719 | |
|
|
720 | #exit(0); |
|
|
721 | #CGI::Carp::croak(@_); }; |
| 72 | #use CGI::Carp qw( fatalsToBrowser carp croak); |
722 | #use CGI::Carp qw( fatalsToBrowser carp croak); |
| 73 | |
723 | |
| 74 | my $CarpLevel = 0; # How many extra package levels to skip on carp. |
724 | my $CarpLevel = 0; # How many extra package levels to skip on carp. |
| 75 | my $MaxEvalLen = 0; # How much eval '...text...' to show. 0 = all. |
725 | my $MaxEvalLen = 0; # How much eval '...text...' to show. 0 = all. |
| 76 | |
726 | |
|
|
727 | # sub longmess { |
|
|
728 | # my $error = shift; |
|
|
729 | # my $mess = ""; |
|
|
730 | # my $i = 1 + $CarpLevel; |
|
|
731 | # my ($pack,$file,$line,$sub,$eval,$require); |
|
|
732 | # |
|
|
733 | # while (($pack,$file,$line,$sub,undef,undef,$eval,$require) = caller($i++)) { |
|
|
734 | # if ($error =~ m/\n$/) { |
|
|
735 | # $mess .= $error; |
|
|
736 | # } |
|
|
737 | # else { |
|
|
738 | # if (defined $eval) { |
|
|
739 | # if ($require) { |
|
|
740 | # $sub = "require $eval"; |
|
|
741 | # } |
|
|
742 | # else { |
|
|
743 | # $eval =~ s/[\\\']/\\$&/g; |
|
|
744 | # if ($MaxEvalLen && length($eval) > $MaxEvalLen) { |
|
|
745 | # substr($eval,$MaxEvalLen) = '...'; |
|
|
746 | # } |
|
|
747 | # $sub = "eval '$eval'"; |
|
|
748 | # } |
|
|
749 | # } |
|
|
750 | # elsif ($sub eq '(eval)') { |
|
|
751 | # $sub = 'eval {...}'; |
|
|
752 | # } |
|
|
753 | # |
|
|
754 | # $mess .= "\t$sub " if $error eq "called"; |
|
|
755 | # $mess .= "$error at $file line $line\n"; |
|
|
756 | # } |
|
|
757 | # |
|
|
758 | # $error = "called"; |
|
|
759 | # } |
|
|
760 | # |
|
|
761 | # $mess || $error; |
|
|
762 | # } |
|
|
763 | |
|
|
764 | } |
|
|
765 | |
|
|
766 | ############### |
|
|
767 | ## Error message routines |
|
|
768 | ############### |
|
|
769 | |
|
|
770 | BEGIN { #error message routines |
|
|
771 | |
|
|
772 | my $CarpLevel = 0; # How many extra package levels to skip on carp. |
|
|
773 | my $MaxEvalLen = 0; # How much eval '...text...' to show. 0 = all. |
|
|
774 | |
| 77 | sub longmess { |
775 | sub longmess { |
| 78 | my $error = shift; |
776 | my $error = shift; |
| 79 | my $mess = ""; |
777 | my $mess = ""; |
| 80 | my $i = 1 + $CarpLevel; |
778 | my $i = 1 + $CarpLevel; |
| 81 | my ($pack,$file,$line,$sub,$eval,$require); |
779 | my ($pack,$file,$line,$sub,$eval,$require); |
| … | |
… | |
| 109 | } |
807 | } |
| 110 | |
808 | |
| 111 | $mess || $error; |
809 | $mess || $error; |
| 112 | } |
810 | } |
| 113 | |
811 | |
| 114 | } |
|
|
| 115 | |
|
|
| 116 | ################################### |
|
|
| 117 | ## Begin Global |
|
|
| 118 | ################################### |
|
|
| 119 | package Global; |
|
|
| 120 | use webworkConfig; |
|
|
| 121 | |
|
|
| 122 | #use CGI::Carp ; #qw( fatalsToBrowser carp croak); |
|
|
| 123 | use PGtranslator; # this is so that PGtranslator->evalute_macros is available when webworkCourse.ph is processed. |
|
|
| 124 | |
|
|
| 125 | ## $Id$ |
|
|
| 126 | |
|
|
| 127 | # ############################################################# |
|
|
| 128 | # Copyright © 1995-2000 University of Rochester |
|
|
| 129 | # All Rights Reserved |
|
|
| 130 | # ############################################################# |
|
|
| 131 | |
|
|
| 132 | |
|
|
| 133 | |
|
|
| 134 | ## IMPORTANT: The items in the section below: |
|
|
| 135 | ## "##These will most likely need to be customized for your site" |
|
|
| 136 | ## should be customized for your own site. |
|
|
| 137 | |
|
|
| 138 | |
|
|
| 139 | ## The variables defined in this package set defaults and |
|
|
| 140 | ## parameters for the whole weBWorK system. Defaults can |
|
|
| 141 | ## be over ridden for individual courses by redefining |
|
|
| 142 | ## variables in the individual course webworkCourse.ph file. |
|
|
| 143 | ## For example the default SYSTEM feedback address set below as: |
|
|
| 144 | ## $feedbackAddress = 'webwork@math.rochester.edu'; |
|
|
| 145 | ## can (and should) be over ridden for an individual course by entering e.g. |
|
|
| 146 | ## $Global::feedbackAdress = 'apizer@math.rochester.edu, gage@math.rochester.edu'; |
|
|
| 147 | ## in the individual course webworkCourse.ph file. Of course you should really |
|
|
| 148 | ## enter the email address(es) of the professors teaching the course. |
|
|
| 149 | |
|
|
| 150 | ### Private vars - refer to these as $Global::var ### |
|
|
| 151 | |
|
|
| 152 | ## These will most likely need to be customized for your site |
|
|
| 153 | |
|
|
| 154 | $feedbackAddress = 'webwork@math.rochester.edu'; |
|
|
| 155 | $legalAddress = '^[\w\-\.]+(\@([\w\-\.]+\.)*rochester\.edu)?$'; # destinations must match |
|
|
| 156 | #$webmaster = 'webmaster@math.rochester.edu'; |
|
|
| 157 | $webmaster = $feedbackAddress; |
|
|
| 158 | $defaultfrom = $feedbackAddress; # this is the default name (only one) that would be in the profSendMail SEND field |
|
|
| 159 | $defaultreply = $feedbackAddress; # this is the default names that would be in the profSendMail REPLY-TO field |
|
|
| 160 | #$SENDMAIL = '/usr/sbin/sendmail -t -oi -n'; # this should no longer be needed |
|
|
| 161 | $smtpServer = 'mail.math.rochester.edu'; |
|
|
| 162 | $dirDelim = '/'; |
|
|
| 163 | |
|
|
| 164 | ## Change DBtie_file only if you want to change the default database. The script |
|
|
| 165 | ## db_tie.pl uses DB_File (the Berkeley DB) and gdbm_tie.pl uses GDBM_File. This |
|
|
| 166 | ## setting can be changed for an individual course in the webworkCourse.ph file. For |
|
|
| 167 | ## some other database, you will have to write your own database tie-file. Such |
|
|
| 168 | ## files reside in the scripts directory. |
|
|
| 169 | |
|
|
| 170 | #$DBtie_file = 'db_tie.pl'; |
|
|
| 171 | $DBtie_file = 'gdbm_tie.pl'; |
|
|
| 172 | |
|
|
| 173 | ## Set to 1 to enable the access log; set to 0 to disable. |
|
|
| 174 | ## |
|
|
| 175 | ## The access log is stored in the logs/ directory under the system directory |
|
|
| 176 | ## in a file called "access_log". It contains information about virtually |
|
|
| 177 | ## every action committed by users, including all answers submitted. |
|
|
| 178 | ## Usually this information is unneccessary, and the file becomes |
|
|
| 179 | ## large very quickly, so this log is ordinarily turned off. However, the |
|
|
| 180 | ## information it contains might be useful if, for example, a student wants an |
|
|
| 181 | ## extension and claims not to have viewed the correct answers. |
|
|
| 182 | $logAccessData = 1; |
|
|
| 183 | |
|
|
| 184 | #################################################################################### |
|
|
| 185 | ########### There should be no need to customize after this point ################# |
|
|
| 186 | #################################################################################### |
|
|
| 187 | |
|
|
| 188 | use diagnostics; ## Usually this is commented out for a system students are using. |
|
|
| 189 | ## If you or students experience problems, uncomment this statement |
|
|
| 190 | ## and you will see hopefully helpful error messages. |
|
|
| 191 | |
|
|
| 192 | ### URL's and directory defined by the setup script system_webwork_setup.pl |
|
|
| 193 | |
|
|
| 194 | # for debugging uncomment the "WeBWorKCGIDebugURL" line, |
|
|
| 195 | # comment out the "WeBWorKCGINoDebugURL" line, and edit |
|
|
| 196 | # the wrapper scripts in the directory $cgiWebworkURL. |
|
|
| 197 | #$cgiWebworkURL = '/cgi-bin/gage_system/cgi-scripts/'; #WeBWorKCGINoDebugURL |
|
|
| 198 | #$cgiWebworkURL = '/cgi-bin/gage_system/'; #WeBWorKCGIDebugURL |
|
|
| 199 | # in order for system_webwork_setup.pl to set the above URLs |
|
|
| 200 | # correctly, the comment tags must remain at the ends of |
|
|
| 201 | # these lines. |
|
|
| 202 | # |
|
|
| 203 | #$htmlWebworkURL = '/webwork_system_html/'; |
|
|
| 204 | #$mainDirectory = '/u/gage/webwork/system/'; |
|
|
| 205 | |
|
|
| 206 | |
|
|
| 207 | ## URL's derived from above |
|
|
| 208 | $loginURL = "${cgiWebworkURL}login.pl"; |
|
|
| 209 | $imagesURL = "${htmlWebworkURL}images/"; |
|
|
| 210 | $helpURL = "${htmlWebworkURL}helpFiles/"; |
|
|
| 211 | $webworkDocsURL = 'http://webwork.math.rochester.edu/docs/docs/'; |
|
|
| 212 | $appletsURL = "${htmlWebworkURL}applets/"; |
|
|
| 213 | |
|
|
| 214 | |
|
|
| 215 | require 5.000; |
|
|
| 216 | require Exporter; |
|
|
| 217 | @ISA = qw(Exporter); |
|
|
| 218 | @EXPORT = qw( |
|
|
| 219 | getWebworkScriptDirectory |
|
|
| 220 | getWebworkCgiURL |
|
|
| 221 | getCourseMOTDFile |
|
|
| 222 | getSystemMOTDFile |
|
|
| 223 | getCourseDatabaseDirectory |
|
|
| 224 | getCourseDatabaseTieFile |
|
|
| 225 | getCourseLogsDirectory |
|
|
| 226 | getCourseTemplateDirectory |
|
|
| 227 | getCourseURL |
|
|
| 228 | getCourseScoringDirectory |
|
|
| 229 | getCourseScriptsDirectory |
|
|
| 230 | getCourseMacroDirectory |
|
|
| 231 | getCourseHtmlDirectory |
|
|
| 232 | getCourseEmailDirectory |
|
|
| 233 | getCourseTempDirectory |
|
|
| 234 | getCourseTempURL |
|
|
| 235 | getCourseClasslistFile |
|
|
| 236 | getCourseEnvironment |
|
|
| 237 | getCourseKeyFile |
|
|
| 238 | getCoursePasswordFile |
|
|
| 239 | getCoursePermissionsFile |
|
|
| 240 | getCourseDatabaseFile |
|
|
| 241 | getCourseHtmlURL |
|
|
| 242 | getCoursel2hDirectory |
|
|
| 243 | getCoursel2hURL |
|
|
| 244 | getDirDelim |
|
|
| 245 | getDelim |
|
|
| 246 | getScoreFilePrefix |
|
|
| 247 | getScoring_log |
|
|
| 248 | getDash |
|
|
| 249 | getDat |
|
|
| 250 | getBbext |
|
|
| 251 | getStatusDrop |
|
|
| 252 | convertPath |
|
|
| 253 | getNumRelPercentTolDefault |
|
|
| 254 | getNumZeroLevelDefault |
|
|
| 255 | getNumZeroLevelTolDefault |
|
|
| 256 | getNumAbsTolDefault |
|
|
| 257 | getNumFormatDefault |
|
|
| 258 | getFunctRelPercentTolDefault |
|
|
| 259 | getFunctZeroLevelDefault |
|
|
| 260 | getFunctZeroLevelTolDefault |
|
|
| 261 | getFunctAbsTolDefault |
|
|
| 262 | getFunctNumOfPoints |
|
|
| 263 | getFunctVarDefault |
|
|
| 264 | getFunctLLimitDefault |
|
|
| 265 | getFunctULimitDefault |
|
|
| 266 | getFunctMaxConstantOfIntegration |
|
|
| 267 | getLoginURL |
|
|
| 268 | getWebworkLogsDirectory |
|
|
| 269 | wwerror |
|
|
| 270 | getAllowDestroyRebuildProbSets |
|
|
| 271 | ); |
|
|
| 272 | |
|
|
| 273 | |
|
|
| 274 | ## practice users |
|
|
| 275 | $practiceUser = 'practice'; # name of password-less "practice" user |
|
|
| 276 | $practiceKey = 'practice'; # a dummy key for this user, can be anything |
|
|
| 277 | |
|
|
| 278 | |
|
|
| 279 | ## The database handle for using mSQL: |
|
|
| 280 | $dbh = 0; |
|
|
| 281 | |
|
|
| 282 | ## various gifs |
|
|
| 283 | $helpGifUrl = "${imagesURL}ww_help.gif"; |
|
|
| 284 | $logoutGifUrl = "${imagesURL}ww_logout.gif"; |
|
|
| 285 | $feedbackGifUrl = "${imagesURL}ww_feedback.gif"; |
|
|
| 286 | $currentImgUrl = "${imagesURL}ww_curr.gif"; |
|
|
| 287 | $previousImgUrl = "${imagesURL}ww_prev.gif"; |
|
|
| 288 | $nextImgUrl = "${imagesURL}ww_next.gif"; |
|
|
| 289 | $problistImgUrl = "${imagesURL}ww_problist.gif"; |
|
|
| 290 | $upImgUrl = "${imagesURL}ww_up.gif"; |
|
|
| 291 | $bluesquareImgUrl = "${imagesURL}ww_bluesq.gif"; |
|
|
| 292 | $headerImgUrl = "${imagesURL}webwork.gif"; # image to include at top of pages |
|
|
| 293 | $squareWebworkGif = "${imagesURL}square_webwork.gif"; # image to include at top of pages |
|
|
| 294 | |
|
|
| 295 | ## backgrounds gifs for HTML documents |
|
|
| 296 | $background_plain_url = "${imagesURL}white.gif"; |
|
|
| 297 | $background_okay_url = "${imagesURL}green.gif"; |
|
|
| 298 | $background_warn_url = "${imagesURL}red.gif"; |
|
|
| 299 | $bg_color = '#EFEFEF'; #background color for processProblem |
|
|
| 300 | |
|
|
| 301 | ## Directories |
|
|
| 302 | $coursesDirectory = convertPath("${mainDirectory}courses/"); |
|
|
| 303 | $scriptDirectory = convertPath("${mainDirectory}scripts/"); |
|
|
| 304 | $cgiDirectory = convertPath("${mainDirectory}cgi/"); |
|
|
| 305 | #$tempDirectory = convertPath("/tmp/"); |
|
|
| 306 | $authDirectory = convertPath(".auth/"); |
|
|
| 307 | $courseScriptsDirectory = convertPath("${mainDirectory}courseScripts/"); |
|
|
| 308 | $macroDirectory = convertPath("${mainDirectory}courseScripts/"); |
|
|
| 309 | $classDirectory = ''; #This must be defined in webworkCourse.ph |
|
|
| 310 | $webworkLogsDirectory = "${mainDirectory}/logs/"; |
|
|
| 311 | |
|
|
| 312 | ## File names |
|
|
| 313 | $coursesFilename = 'courses-list'; |
|
|
| 314 | $coursesFile = "${coursesDirectory}$coursesFilename"; |
|
|
| 315 | $classlistFilename = 'classlist.lst'; |
|
|
| 316 | $keyFilename = 'keys'; |
|
|
| 317 | $passwordFilename = 'password'; |
|
|
| 318 | $permissionsFilename = 'permissions'; |
|
|
| 319 | $database = 'webwork-database'; |
|
|
| 320 | $CL_Database = 'classlist-database'; |
|
|
| 321 | $tipsFilename = 'tips.txt'; |
|
|
| 322 | $system_motd_filename = 'motd.txt'; |
|
|
| 323 | $course_motd_filename = 'motd.txt'; |
|
|
| 324 | $tipsFile = "${mainDirectory}$tipsFilename"; |
|
|
| 325 | |
|
|
| 326 | # CGI script calls |
|
|
| 327 | |
|
|
| 328 | $login_CGI = "${cgiWebworkURL}login.pl"; |
|
|
| 329 | $logout_CGI = "${cgiWebworkURL}logout.pl"; |
|
|
| 330 | $welcome_CGI = "${cgiWebworkURL}welcome.pl"; |
|
|
| 331 | $welcomeAction_CGI = "${cgiWebworkURL}welcomeAction.pl"; |
|
|
| 332 | $processProblem_CGI = "${cgiWebworkURL}processProblem8.pl"; |
|
|
| 333 | $feedback_CGI = "${cgiWebworkURL}feedback.pl"; |
|
|
| 334 | $problemEditor_CGI = "${cgiWebworkURL}problemEditor.pl"; |
|
|
| 335 | |
|
|
| 336 | |
|
|
| 337 | |
|
|
| 338 | |
|
|
| 339 | |
|
|
| 340 | |
|
|
| 341 | ## The following items control how the whole problem set is typeset by downloadPS.pl. |
|
|
| 342 | ## The files (e.g. "tex_set_ptramble.tex") are found in the .../templates directory |
|
|
| 343 | ## Note that the system dependent latex and dvips programs are defined in the file |
|
|
| 344 | ## makePS which is in the .../scripts directory. makePS must be edited to call |
|
|
| 345 | ## the correct programs. |
|
|
| 346 | ## |
|
|
| 347 | |
|
|
| 348 | ## This is the tex preamble file used by downloadPS.pl in typeseting the whole problem set. |
|
|
| 349 | ## E.g. loads AMS latex and graphics packages, some macro definitions. |
|
|
| 350 | $TEX_SET_PREAMBLE = 'texSetPreamble.tex'; |
|
|
| 351 | |
|
|
| 352 | ## This is the tex header file used by downloadPS.pl in typeseting the whole problem set |
|
|
| 353 | ## E.g. loads two column format, macro definitions. |
|
|
| 354 | $TEX_SET_HEADER = ''; |
|
|
| 355 | |
|
|
| 356 | ## This is the header file used by downloadPS.pl to enter preliminary verbiage for the |
|
|
| 357 | ## whole problem set. E.g. Course name, student name, problem set number,instructions, due date. |
|
|
| 358 | $SET_HEADER = 'paperSetHeader.pg'; |
|
|
| 359 | |
|
|
| 360 | ## This is the tex footer file used by downloadPS.pl in typeseting the whole problem set |
|
|
| 361 | $TEX_SET_FOOTER = 'texSetFooter.tex'; |
|
|
| 362 | |
|
|
| 363 | |
|
|
| 364 | ## The following items control how an individual problem is typeset by processProblem.pl |
|
|
| 365 | ## and l2h. Note that the system dependent latex2html program is defined in processProblem.pl. It |
|
|
| 366 | ## should really be in a seperate file like makeps. |
|
|
| 367 | |
|
|
| 368 | ## This is the tex preamble file used by processProblem.pl typeseting an individual problem |
|
|
| 369 | ## Usually very similar to $TEX_SET_PREAMBLE |
|
|
| 370 | $TEX_PROB_PREAMBLE = 'texProbPreamble.tex'; |
|
|
| 371 | |
|
|
| 372 | ## This is the tex header file used by processProblem.pl typeseting an individual problem |
|
|
| 373 | $TEX_PROB_HEADER = ''; |
|
|
| 374 | |
|
|
| 375 | |
|
|
| 376 | ## This is the header file used by probSet.pl to enter preliminary verbiage on the prob set |
|
|
| 377 | ## page. E.g. Instructions, due date. |
|
|
| 378 | $PROB_HEADER = 'screenSetHeader.pg'; |
|
|
| 379 | |
|
|
| 380 | ## This is the tex footer file processProblem.pl typeseting an individual problem |
|
|
| 381 | $TEX_PROB_FOOTER = 'texProbFooter.tex'; |
|
|
| 382 | |
|
|
| 383 | |
|
|
| 384 | |
|
|
| 385 | $courseEnvironmentFile = 'webworkCourse.ph'; |
|
|
| 386 | #$webworkCourse_ph = 'webworkCourse.ph'; |
|
|
| 387 | $DBglue_pl = 'DBglue8.pl'; |
|
|
| 388 | $HTMLglue_pl = 'HTMLglue.pl'; |
|
|
| 389 | $classlist_DBglue_pl = 'classlist_DBglue.pl'; |
|
|
| 390 | $FILE_pl = 'FILE.pl'; |
|
|
| 391 | $displayMacros_pl = 'displayMacros.pl'; |
|
|
| 392 | $scoring_log = 'scoring.log'; |
|
|
| 393 | #####$probSetHeader = 'probSetHeader'; |
|
|
| 394 | $SCRtools_pl = 'pScSet6.pl'; |
|
|
| 395 | $buildProbSetTools = 'proceduresForBuildProbSetDB.pl'; |
|
|
| 396 | |
|
|
| 397 | |
|
|
| 398 | ## File and Directory permissions |
|
|
| 399 | |
|
|
| 400 | ## e.g. S1-1521.sco in (base course directory)/DATA |
|
|
| 401 | $sco_files_permission = 0660; |
|
|
| 402 | |
|
|
| 403 | ## tie permissions (used in tie commands) |
|
|
| 404 | ## The database, password, and permissions files |
|
|
| 405 | ## always take their permissions from the Global |
|
|
| 406 | ## vaiables below. The important keys file |
|
|
| 407 | ## takes its permission from $restricted_tie_permission. |
|
|
| 408 | $restricted_tie_permission = 0600; |
|
|
| 409 | $standard_tie_permission = 0660; |
|
|
| 410 | |
|
|
| 411 | ## webwork-database in (base course directory)/DATA |
|
|
| 412 | $webwork_database_permission = 0660; |
|
|
| 413 | |
|
|
| 414 | ## password in (base course directory)/DATA/.auth |
|
|
| 415 | $password_permission = 0660; |
|
|
| 416 | |
|
|
| 417 | ## permissions in (base course directory)/DATA/.auth |
|
|
| 418 | $permissions_permission = 0660; |
|
|
| 419 | |
|
|
| 420 | ## e.g. s1ful.csv in (base course directory)/scoring |
|
|
| 421 | $scoring_files_permission = 0660; |
|
|
| 422 | |
|
|
| 423 | ## e.g. s1bak1.csv in (base course directory)/scoring |
|
|
| 424 | $scoring_bak_files_permission = 0440; |
|
|
| 425 | |
|
|
| 426 | ## e.g. 8587l2h.log in (base course directory)/html/tmp/l2h |
|
|
| 427 | $l2h_logs_permission = 0660; |
|
|
| 428 | |
|
|
| 429 | ## e.g. set1/ in (base course directory)/html/tmp/l2h |
|
|
| 430 | $l2h_set_directory_permission = 0770; |
|
|
| 431 | |
|
|
| 432 | ## e.g. 1-1082/ in (base course directory)/html/tmp/l2h/set1 |
|
|
| 433 | $l2h_prob_directory_permission = 0770; |
|
|
| 434 | |
|
|
| 435 | ## e.g. 1082output.html in (base course directory)/html/tmp/l2h/set1/1-1082 |
|
|
| 436 | $l2h_data_permission = 0770; |
|
|
| 437 | |
|
|
| 438 | ## e.g. file.gif in (base course directory)/html/tmp/gif |
|
|
| 439 | $tmp_file_permission = 0660; |
|
|
| 440 | |
|
|
| 441 | ## e.g. gif/ in (base course directory)/html/tmp/ |
|
|
| 442 | $tmp_directory_permission = 0770; |
|
|
| 443 | |
|
|
| 444 | ##e.g. classlist files (e.g. MTH140A.lst) in (base course directory)/templates/ |
|
|
| 445 | $classlist_file_permission = 0660; |
|
|
| 446 | |
|
|
| 447 | |
|
|
| 448 | |
|
|
| 449 | ## Prefixes, extensions, defaults, etc |
|
|
| 450 | |
|
|
| 451 | |
|
|
| 452 | |
|
|
| 453 | $scoreFilePrefix = 'S'; |
|
|
| 454 | $dash = '-'; # Can not be the underscore character or an upper or |
|
|
| 455 | # lowercase letter or a digit. Used in .sco file names |
|
|
| 456 | $delim = ','; # used in scoring, classlist |
|
|
| 457 | $dat = 'csv'; |
|
|
| 458 | @statusDrop = qw(drop d withdraw); |
|
|
| 459 | $courselist_delim = '::'; # used by login.pl to get course names / dirs |
|
|
| 460 | $instructor_permissions = 10; |
|
|
| 461 | $TA_permissions = 5; |
|
|
| 462 | $psvn_digits = 5; # Number of digits in psvn numbers. E.g. if 4, psvn's |
|
|
| 463 | # will be between 1000 and 9999. The number of available |
|
|
| 464 | # psvn's must be greater than (#students)*(#problem sets) |
|
|
| 465 | $score_decimal_digits = 1; # Number of decimal digits in recorded scores. For example |
|
|
| 466 | # if this is 1 then on a 1 point problem that allows partial |
|
|
| 467 | # credit, possible scores are 0, .1, .2, ..., 1. |
|
|
| 468 | |
|
|
| 469 | $maxAttemptsWarningLevel = 5; |
|
|
| 470 | # If the set definition file puts a limit on the number of |
|
|
| 471 | # times a problem may be attempted, processProblem.pl will |
|
|
| 472 | # give a warning message when <= $maxAttemptsWarningLevel |
|
|
| 473 | # attempts remain. |
|
|
| 474 | |
|
|
| 475 | $noOfFieldsInClasslist = 9; |
|
|
| 476 | # The number of fields in the classlist file. This is used as |
|
|
| 477 | # a check to make sure each record in the classlist file has |
|
|
| 478 | # this number of fields |
|
|
| 479 | |
|
|
| 480 | $htmlModeDefault = 'HTML_tth'; # The default mode for displayed problems (either 'HTML', |
|
|
| 481 | # 'Latex2HTML', or 'HTML_tth' |
|
|
| 482 | |
|
|
| 483 | $allowStudentToChangeEMAddress = 1; # setting to 1 allows students to change their |
|
|
| 484 | # own email address. Setting to 0 disallows this |
|
|
| 485 | |
|
|
| 486 | $Global::PG_environment{showPartialCorrectAnswers} = 1; ## Set to 0 or 1. If set to 1 in multipart |
|
|
| 487 | # questions the student will be told which parts are |
|
|
| 488 | # correct and which are incorrect. Usually, this is |
|
|
| 489 | # set explicitly in each individual problem. |
|
|
| 490 | |
|
|
| 491 | $allowDestroyRebuildProbSets = 0; # Set to 0 or 1. If set to 1 a professor can destroy and |
|
|
| 492 | # rebuild problems sets in one operation. This is very |
|
|
| 493 | # convenient and powerful, but also very dangerous. Usually |
|
|
| 494 | # this is not allowed in courses students are using. It is |
|
|
| 495 | # often set to 1 in a private course being used only for |
|
|
| 496 | # developing problem sets. To do this, reset this in the |
|
|
| 497 | # private course's webworkCourse.ph file. |
|
|
| 498 | |
|
|
| 499 | $Global::PG_environment{recordSubmittedAnswers} = 1; # Set to 0 or 1. If set to 1, submitted answers will be |
|
|
| 500 | # stored. For example in a multipart question, a student can |
|
|
| 501 | # do several parts, then logout or go onto another question. |
|
|
| 502 | # When they view the problem again, the answer blanks will be |
|
|
| 503 | # filled in with their most recent answers. This also allows |
|
|
| 504 | # professors to see exactly what a student entered. This default |
|
|
| 505 | # can be over ridden for an individual problem by setting |
|
|
| 506 | # recordSubmittedAnswers in the .pg file for the problem. |
|
|
| 507 | |
|
|
| 508 | $maxSizeRecordedAns = 256; # Student answers longer than this length in bytes will not |
|
|
| 509 | # stored in the database. |
|
|
| 510 | |
|
|
| 511 | $hide_studentID_from_TAs = 0; # Set to 0 or 1. If set to 1, studentID's will be hidden |
|
|
| 512 | # from TA's. For example some Universities may use SS#'s for |
|
|
| 513 | # student ID's and you may not want TA's to view these. |
|
|
| 514 | |
|
|
| 515 | ## arguments for flock() |
|
|
| 516 | |
|
|
| 517 | $shared_lock = 1; |
|
|
| 518 | $exclusive_lock = 2; |
|
|
| 519 | $nonblocking_lock = 4; |
|
|
| 520 | $unlock_lock = 8; |
|
|
| 521 | |
|
|
| 522 | # These values provide defaults for the various answer comparison macros found |
|
|
| 523 | # in PGanswermacros.pl. They can be over ridden for individual courses by |
|
|
| 524 | # redefining the variables in the individual course webworkCourse.ph file. |
|
|
| 525 | # They can be over ridden for individual problems by explicitly passing the |
|
|
| 526 | # desired values to the answer comparison macro |
|
|
| 527 | |
|
|
| 528 | # The following effect numerical answer comparison |
|
|
| 529 | $numRelPercentTolDefault = .1; |
|
|
| 530 | $numZeroLevelDefault = 1E-14; |
|
|
| 531 | $numZeroLevelTolDefault = 1E-12; |
|
|
| 532 | $numAbsTolDefault = .001; |
|
|
| 533 | $numFormatDefault = ''; ## use perl's format in prfmt() |
|
|
| 534 | # The following effect function comparison |
|
|
| 535 | $functRelPercentTolDefault = .1; |
|
|
| 536 | $functZeroLevelDefault = 1E-14; |
|
|
| 537 | $functZeroLevelTolDefault = 1E-12; |
|
|
| 538 | $functAbsTolDefault = .001; |
|
|
| 539 | $functNumOfPoints = 3; |
|
|
| 540 | $functVarDefault = 'x'; |
|
|
| 541 | $functLLimitDefault = .0000001; |
|
|
| 542 | $functULimitDefault = .9999999; |
|
|
| 543 | # The following effects function comparison upto constant for antidifferentiation |
|
|
| 544 | $functMaxConstantOfIntegration = 1E8; |
|
|
| 545 | |
|
|
| 546 | ## These values provide defaults for the window size in the problemEditor.pl script |
|
|
| 547 | $editor_window_rows = 25; |
|
|
| 548 | $editor_window_columns = 90; |
|
|
| 549 | |
|
|
| 550 | ## This is the maximum number problems sets that can be downloaded at one time |
|
|
| 551 | ## by a professor. Set this higher or lower depending on the speed of your server |
|
|
| 552 | |
|
|
| 553 | $max_num_of_ps_downloads_allowed = 20; |
|
|
| 554 | |
|
|
| 555 | |
|
|
| 556 | # Subroutines for defining the directories and URLs |
|
|
| 557 | ###### Public vars/routines - these are imported into your namespace, ####### |
|
|
| 558 | ###### so they can be called as they are. |
|
|
| 559 | ####### |
|
|
| 560 | |
|
|
| 561 | sub getWebworkScriptDirectory { convertPath($scriptDirectory ) }; |
|
|
| 562 | sub getCourseDatabaseDirectory { convertPath($databaseDirectory )}; |
|
|
| 563 | sub getCourseDatabaseTieFile { convertPath($DBtie_file )}; |
|
|
| 564 | sub getCourseLogsDirectory { convertPath($logsDirectory )}; |
|
|
| 565 | sub getCourseTemplateDirectory { convertPath($templateDirectory )}; |
|
|
| 566 | sub getCourseEmailDirectory { convertPath("${templateDirectory}email/")}; |
|
|
| 567 | sub getCourseScoringDirectory { convertPath($scoringDirectory ) }; |
|
|
| 568 | sub getCourseHtmlDirectory { convertPath($htmlDirectory )}; |
|
|
| 569 | sub getCourseTempDirectory {convertPath($courseTempDirectory)}; |
|
|
| 570 | sub getCoursel2hDirectory { convertPath( "${courseTempDirectory}l2h/" )}; |
|
|
| 571 | sub getCourseScriptsDirectory { convertPath($courseScriptsDirectory )}; |
|
|
| 572 | sub getCourseMacroDirectory { convertPath($macroDirectory )}; |
|
|
| 573 | sub getWebworkLogsDirectory { convertPath($webworkLogsDirectory)}; |
|
|
| 574 | |
|
|
| 575 | sub getCourseClasslistFile { convertPath("${coursesDirectory}$_[0]/templates/${classlistFilename}") }; |
|
|
| 576 | |
|
|
| 577 | sub getCourseKeyFile { convertPath("${coursesDirectory}$_[0]/DATA/${authDirectory}${keyFilename}") }; |
|
|
| 578 | sub getCoursePasswordFile { convertPath("${coursesDirectory}$_[0]/DATA/${authDirectory}${passwordFilename}") }; |
|
|
| 579 | sub getCoursePermissionsFile { convertPath("${coursesDirectory}$_[0]/DATA/${authDirectory}${permissionsFilename}") }; |
|
|
| 580 | sub getCourseDatabaseFile { convertPath("${coursesDirectory}$_[0]/DATA/${$database}") }; |
|
|
| 581 | |
|
|
| 582 | sub getCourseMOTDFile { convertPath("${coursesDirectory}$_[0]/templates/${course_motd_filename}") }; |
|
|
| 583 | sub getSystemMOTDFile { convertPath("${mainDirectory}${system_motd_filename}") }; |
|
|
| 584 | |
|
|
| 585 | sub getWebworkCgiURL { $cgiWebworkURL }; |
|
|
| 586 | sub getCourseHtmlURL { $htmlURL }; |
|
|
| 587 | sub getCoursel2hURL { "${courseTempURL}l2h/" } |
|
|
| 588 | sub getCourseTempURL { $courseTempURL }; #defined in webworkCourse.ph |
|
|
| 589 | sub getDirDelim { $dirDelim }; |
|
|
| 590 | sub getDelim { $delim }; |
|
|
| 591 | sub getScoreFilePrefix { $scoreFilePrefix }; |
|
|
| 592 | sub getScoring_log { $scoring_log }; |
|
|
| 593 | sub getDash { $dash }; |
|
|
| 594 | sub getDat { $dat }; |
|
|
| 595 | sub getBbext { @dbext }; |
|
|
| 596 | sub getStatusDrop { @statusDrop }; |
|
|
| 597 | |
|
|
| 598 | sub getNumRelPercentTolDefault { $numRelPercentTolDefault }; |
|
|
| 599 | sub getNumZeroLevelDefault { $numZeroLevelDefault }; |
|
|
| 600 | sub getNumZeroLevelTolDefault { $numZeroLevelTolDefault }; |
|
|
| 601 | sub getNumAbsTolDefault { $numAbsTolDefault }; |
|
|
| 602 | sub getNumFormatDefault { $numFormatDefault }; |
|
|
| 603 | sub getFunctRelPercentTolDefault { $functRelPercentTolDefault }; |
|
|
| 604 | sub getFunctZeroLevelDefault { $functZeroLevelDefault }; |
|
|
| 605 | sub getFunctZeroLevelTolDefault { $functZeroLevelTolDefault }; |
|
|
| 606 | sub getFunctAbsTolDefault { $functAbsTolDefault }; |
|
|
| 607 | sub getFunctNumOfPoints { $functNumOfPoints }; |
|
|
| 608 | sub getFunctVarDefault { $functVarDefault }; |
|
|
| 609 | sub getFunctLLimitDefault { $functLLimitDefault }; |
|
|
| 610 | sub getFunctULimitDefault { $functULimitDefault }; |
|
|
| 611 | sub getFunctMaxConstantOfIntegration { $functMaxConstantOfIntegration }; |
|
|
| 612 | |
|
|
| 613 | sub getLoginURL { $loginURL }; |
|
|
| 614 | |
|
|
| 615 | sub getAllowDestroyRebuildProbSets { $allowDestroyRebuildProbSets }; |
|
|
| 616 | |
|
|
| 617 | sub getCourseEnvironment { |
|
|
| 618 | die "getCourseEnvironment was called without specifying a course" unless $_[0]; |
|
|
| 619 | my $fullPath = convertPath("${coursesDirectory}$_[0]/$courseEnvironmentFile"); |
|
|
| 620 | require "$fullPath" |
|
|
| 621 | || die "Can't find local environment file for |
|
|
| 622 | $fullPath\n"; |
|
|
| 623 | } |
|
|
| 624 | |
|
|
| 625 | |
|
|
| 626 | |
|
|
| 627 | ### dump a (hopefully) descriptive error to the browser and quit |
|
|
| 628 | #sub wwerror { |
|
|
| 629 | # my($title, $msg, $url, $label, $query_string) = @_; |
|
|
| 630 | # |
|
|
| 631 | # print "content-type: text/html\n\n |
|
|
| 632 | # <HTML><HEAD><TITLE>Error: $title</TITLE></HEAD> |
|
|
| 633 | # <BODY BACKGROUND=\"$background_warn_url\"> |
|
|
| 634 | # <H1>Error: $title</H1>\n $msg \n"; |
|
|
| 635 | # if ($url) { |
|
|
| 636 | # print "<FORM ACTION=\"$url\"> |
|
|
| 637 | # <INPUT TYPE=SUBMIT VALUE=\"$label\"> |
|
|
| 638 | # </FORM>\n"; |
|
|
| 639 | # } |
|
|
| 640 | # print "</BODY></HTML>"; |
|
|
| 641 | # &log_error($title, $query_string); |
|
|
| 642 | # exit 1; |
|
|
| 643 | #} |
|
|
| 644 | |
|
|
| 645 | sub wwerror { |
|
|
| 646 | my($title, $msg, $url, $label, $query_string) = @_; |
|
|
| 647 | # <BODY BACKGROUND=\"$background_warn_url\"> |
|
|
| 648 | |
|
|
| 649 | $msg = '' unless defined $msg; |
|
|
| 650 | $url = '' unless defined $url; |
|
|
| 651 | $label = '' unless defined $label; |
|
|
| 652 | $query_string = '' unless defined $query_string; |
|
|
| 653 | |
|
|
| 654 | print "content-type: text/html\n\n |
|
|
| 655 | <HTML><HEAD><TITLE>Error: $title</TITLE></HEAD> |
|
|
| 656 | <BODY BGCOLOR = 'CCCCCC'> |
|
|
| 657 | |
|
|
| 658 | <H2>Error: $title</H2> |
|
|
| 659 | <PRE>$msg\n |
|
|
| 660 | </PRE>"; |
|
|
| 661 | if ($url) { |
|
|
| 662 | print "<FORM ACTION=\"$url\"> |
|
|
| 663 | <INPUT TYPE=SUBMIT VALUE=\"$label\"> |
|
|
| 664 | </FORM>\n"; |
|
|
| 665 | } |
|
|
| 666 | print "</BODY></HTML>"; |
|
|
| 667 | &log_error($title, $query_string); |
|
|
| 668 | exit 1; |
|
|
| 669 | } |
|
|
| 670 | |
|
|
| 671 | sub error {wwerror(@_);} ##alias for wwerror |
|
|
| 672 | |
|
|
| 673 | |
|
|
| 674 | # return a (scalar) tip |
|
|
| 675 | sub tip { |
|
|
| 676 | my ($tips, @tiplist); |
|
|
| 677 | local($/) = undef; |
|
|
| 678 | #undef $/; # slurp it all in |
|
|
| 679 | open(TIPS, "$tipsFile") || &error("Can't open $tipsFile"); |
|
|
| 680 | $tips = <TIPS>; |
|
|
| 681 | close(TIPS); |
|
|
| 682 | |
|
|
| 683 | # add any local tips to the list before we pick a random one |
|
|
| 684 | if (-r "${templateDirectory}$tipsFilename") { |
|
|
| 685 | open(TIPS, "${templateDirectory}$tipsFilename"); |
|
|
| 686 | $tips .= '%%' . <TIPS>; |
|
|
| 687 | close(TIPS); |
|
|
| 688 | } |
|
|
| 689 | $/ = "\n"; # <> now reads until newline |
|
|
| 690 | $tips =~ s/#.*?\n//mg; # remove comments |
|
|
| 691 | @tiplist = split(/%%/, $tips); |
|
|
| 692 | return $tiplist[rand(@tiplist)]; # choose one at random |
|
|
| 693 | } |
|
|
| 694 | |
|
|
| 695 | # return an array of tips |
|
|
| 696 | sub all_tips { |
|
|
| 697 | my ($tip, $tips, @tiplist); |
|
|
| 698 | |
|
|
| 699 | local($/) = undef; # slurp it all in |
|
|
| 700 | open(TIPS, "$tipsFile") || &error("Can't open $tipsFile"); |
|
|
| 701 | $tips = <TIPS>; |
|
|
| 702 | close(TIPS); |
|
|
| 703 | |
|
|
| 704 | # add any local tips to the list before we pick a random one |
|
|
| 705 | if (-r "${templateDirectory}$tipsFilename") { |
|
|
| 706 | open(TIPS, "${templateDirectory}$tipsFilename"); |
|
|
| 707 | $tips .= '%%' . <TIPS>; |
|
|
| 708 | close(TIPS); |
|
|
| 709 | } |
|
|
| 710 | $/ = "\n"; # <> now reads until newline |
|
|
| 711 | $tips =~ s/#.*?\n//mg; # remove comments |
|
|
| 712 | @tiplist = split(/%%/, $tips); |
|
|
| 713 | return @tiplist; |
|
|
| 714 | } |
|
|
| 715 | |
|
|
| 716 | |
|
|
| 717 | # begin Timing code |
|
|
| 718 | use Benchmark; |
|
|
| 719 | sub dateTime { |
|
|
| 720 | my @timeArray = localtime(time); |
|
|
| 721 | my $out = sprintf("%2.2d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d", |
|
|
| 722 | $timeArray[5],$timeArray[4]+1,@timeArray[3,2,1,0]); |
|
|
| 723 | $out; |
|
|
| 724 | } |
|
|
| 725 | |
|
|
| 726 | #the ps system calls do not work on all systems, and are usually not |
|
|
| 727 | #necessary anyway. If you wish that information to be logged, simply |
|
|
| 728 | #uncomment the relevant lines, but be warned that they might need to |
|
|
| 729 | #be modified for your system |
|
|
| 730 | sub logTimingInfo { |
|
|
| 731 | my ($beginTime,$endTime,$script,$course,$user,$remoteHost,$userAgent) = @_; |
|
|
| 732 | $remoteHost = ""unless defined($remoteHost); |
|
|
| 733 | $userAgent = "" unless defined($userAgent); |
|
|
| 734 | open(TIMELOG, ">>${webworkLogsDirectory}timing_log") || |
|
|
| 735 | warn "*Unable to open timing log for writing:\n ${webworkLogsDirectory}timing_log. "; |
|
|
| 736 | |
|
|
| 737 | my $mem_string = ''; |
|
|
| 738 | # my $process_string = `ps -o vsz -p $$`; |
|
|
| 739 | # $process_string =~ s/^\s*//; |
|
|
| 740 | # $process_string =~ s/\s*$//; |
|
|
| 741 | # my @process_string = split(/\s+/,$process_string); # gets memory size |
|
|
| 742 | # my $mem_string = " mem: ${process_string[1]}K"; |
|
|
| 743 | |
|
|
| 744 | my $load_string = ''; |
|
|
| 745 | # my @load = split(/\n/,`ps -U wwhttpd -o state`); |
|
|
| 746 | # my $load_string = " load: " . grep(/R/,@load); |
|
|
| 747 | |
|
|
| 748 | print TIMELOG $script,"\t",$course,"\t",&dateTime,"\t", |
|
|
| 749 | timestr( timediff($endTime,$beginTime), 'all' ),"\t", |
|
|
| 750 | "pid: $$ DBtie_tries: $Global::DBtie_tries" . $mem_string . $load_string,"\t",$user,"\t", |
|
|
| 751 | $remoteHost,"\t",$userAgent,"\n"; |
|
|
| 752 | close(TIMELOG); |
|
|
| 753 | } |
|
|
| 754 | # end Timing code |
|
|
| 755 | |
|
|
| 756 | |
|
|
| 757 | # handy routines for modules that wish to throw exceptions outside of the |
|
|
| 758 | # current package. (taken from Carp.pm) |
|
|
| 759 | # |
|
|
| 760 | # We'll want to remove this in final versions of WeBWorK. |
|
|
| 761 | |
|
|
| 762 | sub log_error { |
|
|
| 763 | my ($comment, $data) = @_; |
|
|
| 764 | my $accessLog = convertPath("${webworkLogsDirectory}access_log"); |
|
|
| 765 | my $errorLog = convertPath("${webworkLogsDirectory}error_log"); |
|
|
| 766 | open(ACCESS, ">>$accessLog"); |
|
|
| 767 | open(ERROR, ">>$errorLog"); |
|
|
| 768 | print ACCESS "ERROR ($comment) ", scalar(localtime), ': ', &shortmess($data); |
|
|
| 769 | print ERROR "ERROR ($comment) ", scalar(localtime), ': ', &shortmess($data); |
|
|
| 770 | close(ACCESS); |
|
|
| 771 | close(ERROR); |
|
|
| 772 | } |
|
|
| 773 | |
|
|
| 774 | sub log_info { |
|
|
| 775 | if( $Global::logAccessData == 1 ) { |
|
|
| 776 | my ($comment, $data) = @_; |
|
|
| 777 | my $accessLog = convertPath("${webworkLogsDirectory}access_log"); |
|
|
| 778 | open(LOG, ">>$accessLog") or warn "Can't open accessLog $accessLog"; |
|
|
| 779 | print LOG "INFO ($comment) ", scalar(localtime), ': ', &shortmess($data); |
|
|
| 780 | close(LOG); |
|
|
| 781 | } |
|
|
| 782 | } |
|
|
| 783 | |
|
|
| 784 | |
|
|
| 785 | ## converts full path names to to use the $dirDelim instead of / |
|
|
| 786 | sub convertPath { |
|
|
| 787 | my ($path) = @_; |
|
|
| 788 | warn "convertPath has been asked to convert an empty path<BR> |$path| at ", caller(),"<BR>" unless $path; |
|
|
| 789 | $path =~ s|/|$dirDelim|g; |
|
|
| 790 | |
|
|
| 791 | $path; |
|
|
| 792 | } |
|
|
| 793 | |
|
|
| 794 | ############### |
|
|
| 795 | ## Error message routines |
|
|
| 796 | ############### |
|
|
| 797 | |
|
|
| 798 | BEGIN { #error message routines |
|
|
| 799 | |
|
|
| 800 | my $CarpLevel = 0; # How many extra package levels to skip on carp. |
|
|
| 801 | my $MaxEvalLen = 0; # How much eval '...text...' to show. 0 = all. |
|
|
| 802 | |
|
|
| 803 | sub longmess { |
|
|
| 804 | my $error = shift; |
|
|
| 805 | my $mess = ""; |
|
|
| 806 | my $i = 1 + $CarpLevel; |
|
|
| 807 | my ($pack,$file,$line,$sub,$eval,$require); |
|
|
| 808 | |
|
|
| 809 | while (($pack,$file,$line,$sub,undef,undef,$eval,$require) = caller($i++)) { |
|
|
| 810 | if ($error =~ m/\n$/) { |
|
|
| 811 | $mess .= $error; |
|
|
| 812 | } |
|
|
| 813 | else { |
|
|
| 814 | if (defined $eval) { |
|
|
| 815 | if ($require) { |
|
|
| 816 | $sub = "require $eval"; |
|
|
| 817 | } |
|
|
| 818 | else { |
|
|
| 819 | $eval =~ s/[\\\']/\\$&/g; |
|
|
| 820 | if ($MaxEvalLen && length($eval) > $MaxEvalLen) { |
|
|
| 821 | substr($eval,$MaxEvalLen) = '...'; |
|
|
| 822 | } |
|
|
| 823 | $sub = "eval '$eval'"; |
|
|
| 824 | } |
|
|
| 825 | } |
|
|
| 826 | elsif ($sub eq '(eval)') { |
|
|
| 827 | $sub = 'eval {...}'; |
|
|
| 828 | } |
|
|
| 829 | |
|
|
| 830 | $mess .= "\t$sub " if $error eq "called"; |
|
|
| 831 | $mess .= "$error at $file line $line\n"; |
|
|
| 832 | } |
|
|
| 833 | |
|
|
| 834 | $error = "called"; |
|
|
| 835 | } |
|
|
| 836 | |
|
|
| 837 | $mess || $error; |
|
|
| 838 | } |
|
|
| 839 | |
|
|
| 840 | sub shortmess { # Short-circuit &longmess if called via multiple packages |
812 | sub shortmess { # Short-circuit &longmess if called via multiple packages |
| 841 | my $error = $_[0]; # Instead of "shift" |
813 | my $error = $_[0]; # Instead of "shift" |
| 842 | my ($curpack) = caller(1); |
814 | my ($curpack) = caller(1); |
| 843 | my $extra = $CarpLevel; |
815 | my $extra = $CarpLevel; |
| 844 | my $i = 2; |
816 | my $i = 2; |
| … | |
… | |
| 859 | } |
831 | } |
| 860 | |
832 | |
| 861 | |
833 | |
| 862 | } |
834 | } |
| 863 | |
835 | |
| 864 | |
|
|
| 865 | |
|
|
| 866 | |
|
|
| 867 | ############### |
836 | ############### |
| 868 | ## End Error message routines |
837 | ## End Error message routines |
| 869 | ############### |
838 | ############### |
| 870 | |
839 | |
| 871 | |
840 | |