[system] / trunk / webwork / system / lib / Global.pm Repository:
ViewVC logotype

Diff of /trunk/webwork/system/lib/Global.pm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 82 Revision 83
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
14package 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
10use sigtrap; 75use sigtrap;
76use diagnostics;
77use webworkConfig;
78use PGtranslator;
79 # this is so that PGtranslator->evalute_macros is available when webworkCourse.ph is processed.
80
81require 5.000;
82require 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
424sub getWebworkScriptDirectory { convertPath($scriptDirectory ) };
425sub getCourseDatabaseDirectory { convertPath($databaseDirectory )};
426sub getCourseDatabaseTieFile { convertPath($DBtie_file )};
427sub getCourseLogsDirectory { convertPath($logsDirectory )};
428sub getCourseTemplateDirectory { convertPath($templateDirectory )};
429sub getCourseEmailDirectory { convertPath("${templateDirectory}email/")};
430sub getCourseScoringDirectory { convertPath($scoringDirectory ) };
431sub getCourseHtmlDirectory { convertPath($htmlDirectory )};
432sub getCourseTempDirectory {convertPath($courseTempDirectory)};
433sub getCoursel2hDirectory { convertPath( "${courseTempDirectory}l2h/" )};
434sub getCourseScriptsDirectory { convertPath($courseScriptsDirectory )};
435sub getCourseMacroDirectory { convertPath($macroDirectory )};
436sub getWebworkLogsDirectory { convertPath($webworkLogsDirectory)};
437
438sub getCourseClasslistFile { convertPath("${coursesDirectory}$_[0]/templates/${classlistFilename}") };
439
440sub getCourseKeyFile { convertPath("${coursesDirectory}$_[0]/DATA/${authDirectory}${keyFilename}") };
441sub getCoursePasswordFile { convertPath("${coursesDirectory}$_[0]/DATA/${authDirectory}${passwordFilename}") };
442sub getCoursePermissionsFile { convertPath("${coursesDirectory}$_[0]/DATA/${authDirectory}${permissionsFilename}") };
443sub getCourseDatabaseFile { convertPath("${coursesDirectory}$_[0]/DATA/${$database}") };
444
445sub getCourseMOTDFile { convertPath("${coursesDirectory}$_[0]/templates/${course_motd_filename}") };
446sub getSystemMOTDFile { convertPath("${mainDirectory}${system_motd_filename}") };
447
448sub getWebworkCgiURL { $cgiWebworkURL };
449sub getCourseHtmlURL { $htmlURL };
450sub getCoursel2hURL { "${courseTempURL}l2h/" }
451sub getCourseTempURL { $courseTempURL }; #defined in webworkCourse.ph
452sub getDirDelim { $dirDelim };
453sub getDelim { $delim };
454sub getScoreFilePrefix { $scoreFilePrefix };
455sub getScoring_log { $scoring_log };
456sub getDash { $dash };
457sub getDat { $dat };
458sub getBbext { @dbext };
459sub getStatusDrop { @statusDrop };
460
461sub getNumRelPercentTolDefault { $numRelPercentTolDefault };
462sub getNumZeroLevelDefault { $numZeroLevelDefault };
463sub getNumZeroLevelTolDefault { $numZeroLevelTolDefault };
464sub getNumAbsTolDefault { $numAbsTolDefault };
465sub getNumFormatDefault { $numFormatDefault };
466sub getFunctRelPercentTolDefault { $functRelPercentTolDefault };
467sub getFunctZeroLevelDefault { $functZeroLevelDefault };
468sub getFunctZeroLevelTolDefault { $functZeroLevelTolDefault };
469sub getFunctAbsTolDefault { $functAbsTolDefault };
470sub getFunctNumOfPoints { $functNumOfPoints };
471sub getFunctVarDefault { $functVarDefault };
472sub getFunctLLimitDefault { $functLLimitDefault };
473sub getFunctULimitDefault { $functULimitDefault };
474sub getFunctMaxConstantOfIntegration { $functMaxConstantOfIntegration };
475
476sub getLoginURL { $loginURL };
477
478sub getAllowDestroyRebuildProbSets { $allowDestroyRebuildProbSets };
479
480sub 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
508sub 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
534sub error {wwerror(@_);} ##alias for wwerror
535
536
537# return a (scalar) tip
538sub 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
559sub 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
581use Benchmark;
582sub 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
593sub 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
625sub 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
637sub 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 /
649sub 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
12BEGIN { 659BEGIN {
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
770BEGIN { #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###################################
119package Global;
120use webworkConfig;
121
122#use CGI::Carp ; #qw( fatalsToBrowser carp croak);
123use 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
188use 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
215require 5.000;
216require 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
561sub getWebworkScriptDirectory { convertPath($scriptDirectory ) };
562sub getCourseDatabaseDirectory { convertPath($databaseDirectory )};
563sub getCourseDatabaseTieFile { convertPath($DBtie_file )};
564sub getCourseLogsDirectory { convertPath($logsDirectory )};
565sub getCourseTemplateDirectory { convertPath($templateDirectory )};
566sub getCourseEmailDirectory { convertPath("${templateDirectory}email/")};
567sub getCourseScoringDirectory { convertPath($scoringDirectory ) };
568sub getCourseHtmlDirectory { convertPath($htmlDirectory )};
569sub getCourseTempDirectory {convertPath($courseTempDirectory)};
570sub getCoursel2hDirectory { convertPath( "${courseTempDirectory}l2h/" )};
571sub getCourseScriptsDirectory { convertPath($courseScriptsDirectory )};
572sub getCourseMacroDirectory { convertPath($macroDirectory )};
573sub getWebworkLogsDirectory { convertPath($webworkLogsDirectory)};
574
575sub getCourseClasslistFile { convertPath("${coursesDirectory}$_[0]/templates/${classlistFilename}") };
576
577sub getCourseKeyFile { convertPath("${coursesDirectory}$_[0]/DATA/${authDirectory}${keyFilename}") };
578sub getCoursePasswordFile { convertPath("${coursesDirectory}$_[0]/DATA/${authDirectory}${passwordFilename}") };
579sub getCoursePermissionsFile { convertPath("${coursesDirectory}$_[0]/DATA/${authDirectory}${permissionsFilename}") };
580sub getCourseDatabaseFile { convertPath("${coursesDirectory}$_[0]/DATA/${$database}") };
581
582sub getCourseMOTDFile { convertPath("${coursesDirectory}$_[0]/templates/${course_motd_filename}") };
583sub getSystemMOTDFile { convertPath("${mainDirectory}${system_motd_filename}") };
584
585sub getWebworkCgiURL { $cgiWebworkURL };
586sub getCourseHtmlURL { $htmlURL };
587sub getCoursel2hURL { "${courseTempURL}l2h/" }
588sub getCourseTempURL { $courseTempURL }; #defined in webworkCourse.ph
589sub getDirDelim { $dirDelim };
590sub getDelim { $delim };
591sub getScoreFilePrefix { $scoreFilePrefix };
592sub getScoring_log { $scoring_log };
593sub getDash { $dash };
594sub getDat { $dat };
595sub getBbext { @dbext };
596sub getStatusDrop { @statusDrop };
597
598sub getNumRelPercentTolDefault { $numRelPercentTolDefault };
599sub getNumZeroLevelDefault { $numZeroLevelDefault };
600sub getNumZeroLevelTolDefault { $numZeroLevelTolDefault };
601sub getNumAbsTolDefault { $numAbsTolDefault };
602sub getNumFormatDefault { $numFormatDefault };
603sub getFunctRelPercentTolDefault { $functRelPercentTolDefault };
604sub getFunctZeroLevelDefault { $functZeroLevelDefault };
605sub getFunctZeroLevelTolDefault { $functZeroLevelTolDefault };
606sub getFunctAbsTolDefault { $functAbsTolDefault };
607sub getFunctNumOfPoints { $functNumOfPoints };
608sub getFunctVarDefault { $functVarDefault };
609sub getFunctLLimitDefault { $functLLimitDefault };
610sub getFunctULimitDefault { $functULimitDefault };
611sub getFunctMaxConstantOfIntegration { $functMaxConstantOfIntegration };
612
613sub getLoginURL { $loginURL };
614
615sub getAllowDestroyRebuildProbSets { $allowDestroyRebuildProbSets };
616
617sub 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
645sub 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
671sub error {wwerror(@_);} ##alias for wwerror
672
673
674# return a (scalar) tip
675sub 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
696sub 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
718use Benchmark;
719sub 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
730sub 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
762sub 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
774sub 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 /
786sub 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
798BEGIN { #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

Legend:
Removed from v.82  
changed lines
  Added in v.83

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9