[system] / trunk / webwork / system / cgi / cgi-scripts / welcomeAction.pl Repository:
ViewVC logotype

View of /trunk/webwork/system/cgi/cgi-scripts/welcomeAction.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2406 - (download) (as text) (annotate)
Fri Jun 25 15:18:18 2004 UTC (8 years, 10 months ago) by apizer
File size: 46286 byte(s)
Loas IO.pl in 3 places

Arnie

    1 #!/usr/local/bin/webwork-perl
    2 
    3 ################################################################
    4 #  Copyright @1995-1999 by Michael E. Gage, Arnold K. Pizer and
    5 #  WeBWorK at the University of Rochester. All rights reserved.
    6 ################################################################
    7 
    8 use lib '.'; use webworkInit; # WeBWorKInitLine
    9 
   10 require 5.001;
   11 use strict;
   12 use Global;
   13 use Auth;
   14 use CGI qw(:standard);
   15 use Net::SMTP;
   16 use Safe;
   17 
   18 use WeBWorK::PG::ImageGenerator;
   19 use WeBWorK::PG::Translator;
   20 use PGtranslator; # this is now a stub
   21 use WeBWorK::Timing;
   22 use vars qw($modules_to_evaluate $extra_packages_to_be_loaded);
   23 $main::timingON=0;  ## If you set this to 1, you should also edit the file
   24               ## .../webwork/system/lib/WeBWorK/Timing.pm setting
   25               ## \$TIMING_LOG to a specific log file.  Otherwise the
   26               ## timing data will be sent to apache's error_log.
   27 
   28 $/ ="\n";
   29 
   30 BEGIN {
   31   # set to 1 to enable timing_log
   32   # (contains information about time taken by scripts to run)
   33   $main::logTimingData = 0;
   34 
   35   # begin Timing code
   36   if( $main::logTimingData == 1 ) {
   37     use Benchmark;
   38     $main::beginTime = new Benchmark;
   39   }
   40   # end Timing code
   41 
   42   # Setting these time out comstants to zeros removes the time constraint completely. (zero = infinity :=)  )
   43   $main::TIME_OUT_CONSTANT = 60;                   # one minute wait for on screen problems
   44   $main::CLASS_DOWNLOAD_TIME_OUT_CONSTANT = 1200;  #twenty minutes
   45   $main::CLASS_DOWNLOAD_NICE = 5;   # higher numbers indicated lower priorities
   46   # $main::DOWNLOAD_TIME_OUT_CONSTANT = 300;         # give it five minutes
   47   # $main::DOWNLOAD_NICE = 2;
   48 
   49   # ATTENTION:  The handlers PG_floating_point_exception_handler and PG_warnings_handler
   50   # have to be installed after CGI::Carp is called since it also
   51   # modifes the die and warn labels. Finding the right warning mechanism using these two
   52   # methods bears further investigation
   53   # They are defined in Global.pm
   54   $SIG{'FPE'}  = \&Global::PG_floating_point_exception_handler;
   55   $SIG{__WARN__}=\&Global::PG_warnings_handler;
   56   $SIG{'TERM'} = sub {die '[',scalar(localtime),"] Caught a SIGTERM, Error: $!   stopped at $0\n"; };
   57   $SIG{'PIPE'} = sub {$main::SIGPIPE = 1, die '[',scalar(localtime),"] Caught a SIGPIPE, Error: $!   stopped at $0\n"; };
   58   $SIG{ALRM} = sub { $main::SIG_TIME_OUT = 1; exit(0) };
   59 
   60   alarm($main::TIME_OUT_CONSTANT);
   61   # By explicitly catching the signals and dieing one forces the execution of the END statements which clean up the files.
   62 };
   63 
   64 ################################################################################
   65 # main #########################################################################
   66 ################################################################################
   67 my $debugON = 0;
   68 $debugON = 1 if $Global::imageDebugMode;
   69 
   70 &CGI::ReadParse;
   71 my %inputs=%main::in;
   72 my $query = $main::in{CGI};
   73 
   74 $main::timer1  = WeBWorK::Timing->new("Begin welcomeAction create TeX source") if $main::timingON;
   75 $main::timer1->start if $main::timingON;
   76 # verify that the rest of the information has been received
   77 my $Course = $inputs{'course'};
   78 my $Course_display = $Course;
   79 $Course_display =~ s/_/ /g;
   80 
   81 my $User = $inputs{'user'};
   82 
   83 my @local_psvns = $query -> param('local_psvns');
   84 my $psvn = $local_psvns[0]; # get the first one for doing problem sets
   85 $inputs{'probSetKey'} = $psvn; # only used by htmlBOTTOM
   86 my $Session_key = $inputs{'key'};
   87 
   88 &Global::getCourseEnvironment($Course);
   89 
   90 my $scriptDirectory        = getWebworkScriptDirectory();
   91 my $databaseDirectory      = getCourseDatabaseDirectory();
   92 my $courseScriptsDirectory = getCourseScriptsDirectory();
   93 my $templateDirectory      = getCourseTemplateDirectory();
   94 my $tempDirectory          = getCourseTempDirectory();
   95 
   96 eval{require "${courseScriptsDirectory}$Global::displayMacros_pl";};
   97 eval{require "${scriptDirectory}$Global::DBglue_pl";};
   98 eval{require "${scriptDirectory}$Global::classlist_DBglue_pl";};
   99 eval{require "${scriptDirectory}$Global::HTMLglue_pl";};
  100 eval{require "${scriptDirectory}$Global::FILE_pl";};
  101 
  102 # load the modules to be used in PGtranslator
  103 #
  104 # we need to support the above file, but we've changed how
  105 # evaluate_modules and load_extra_packages work so that they use an
  106 # instance variable. so what we do is use a stub PGtranslator class to
  107 # store the list of included modules in a package variable for later
  108 # retrieveal.
  109 require "${courseScriptsDirectory}PG_module_list.pl"
  110   or wwerror($0, "Can't read ${courseScriptsDirectory}PG_module_list.pl");
  111 
  112 my $keyFile = &Global::getCourseKeyFile($Course);
  113 my $permissionsFile = &getCoursePermissionsFile($Course);
  114 
  115 # check to see if prob set has been selected
  116 if(not defined($psvn) or $psvn eq "") {
  117   selectionError();
  118   exit;
  119 }
  120 
  121 # log access
  122 &Global::log_info('', query_string);
  123 
  124 &verify_key($inputs{'user'}, $Session_key, $keyFile, $Course);
  125 my $permissions = &get_permissions($User,$permissionsFile);
  126 
  127 &attachProbSetRecord($psvn);
  128 my $login_name_for_psvn = &getStudentLogin($psvn);
  129 attachCLRecord($login_name_for_psvn);
  130 
  131 my $setNumber=&getSetNumber($psvn);
  132 $setNumber = $inputs{'setNo'} if defined $inputs{'setNo'};  ## script called from profChangeDates.pl
  133 
  134 my $setNumber_display = $setNumber;
  135 $setNumber_display =~ s/_/ /g;
  136 
  137 # keep strict happy -sh
  138 my $tempTexFileBaseName;
  139 
  140 # check to see that it is after the open date
  141 my ($currentTime,$odts,$ddts,$adts,$remainingTime, $TimeString);
  142 $currentTime = time;
  143 $odts=&getOpenDate($psvn);
  144 $ddts=&getDueDate($psvn);
  145 $adts=&getAnswerDate($psvn);
  146 $remainingTime=$ddts-$currentTime;
  147 
  148 if($currentTime<$odts && $permissions !=$Global::instructor_permissions) {
  149   print &htmlTOP("Before open date error");
  150   print "<CENTER><h2>Sorry, cannot download or do problem set $setNumber yet.
  151   <BR>It is before the open date.</h2></CENTER>";
  152   print &htmlBOTTOM("downloadPS.pl",\%inputs);
  153     exit(0);
  154 }
  155 
  156 my %PSVNHashForSet = %{getPSVNHashForSet($setNumber)};
  157 my $action = $inputs{'action'};
  158 my $downloadType= $inputs{'downloadType'}; # either pdf, ps, tex, or dvi
  159 
  160 # Verify that the problem set has been created if a psvn number has been passed
  161 unless ($action eq 'Get_all_copies') {
  162     unless (defined $PSVNHashForSet{$psvn} ) {
  163       print   &htmlTOP("Problem set version number $psvn not created");
  164         print ( "Pin number $psvn was not created for set $setNumber");
  165         print   &htmlBOTTOM("downloadPS.pl", \%inputs);
  166         exit(0);
  167     }
  168 }
  169 
  170 my $save_errors = '';
  171 
  172 # check if solutions should be displayed
  173 
  174 my $solutionsRequestedQ= 0;
  175 $solutionsRequestedQ= $inputs{'ShowSol'} if defined($inputs{'ShowSol'});
  176 
  177 my $displaySolutionsQ = 0;   #initialize
  178 $displaySolutionsQ =1 if $solutionsRequestedQ && ($currentTime > $adts);
  179 $displaySolutionsQ =1 if $solutionsRequestedQ && ($permissions == $Global::instructor_permissions);
  180 
  181 if ($action eq 'Do problem set' or $action eq 'Do_problem_set') { displayProbSet(); }
  182 elsif ($action eq 'Get hard copy' or $action eq 'Get_hard_copy') { downloadAllSets(); }
  183 elsif ($action eq 'Get_all_copies') { downloadAllSets(); }
  184 else { wwerror($0, "Unknown action: $action"); }
  185 
  186 # begin Timing code
  187 #my $endTime = new Benchmark;
  188 #&Global::logTimingInfo($main::beginTime,$endTime,$0,$Course,$User);
  189 # end Timing code
  190 $main::timer1->stop if $main::timingON;
  191 $main::timer1->save if $main::timingON;
  192 exit;
  193 
  194 ################################################################################
  195 # displayProbSet ###############################################################
  196 ################################################################################
  197 
  198 sub displayProbSet
  199 {
  200     my $studentName=&CL_getStudentName($login_name_for_psvn);
  201     my $probHeaderFileName = &getProbHeaderFileName($psvn);
  202 
  203   sub numerical { $a <=> $b};
  204   my @problems=sort numerical &getAllProblemsForProbSetRecord($psvn);
  205   my $numberOfProblems = @problems;
  206 
  207   print &probSet_htmlTOP("Problem Set $setNumber_display from  $Course_display for $studentName");
  208             #see subroutines at the bottom of this file
  209                     #this allows the use of a small gif for the webwork logo
  210                     #and takes up less screen real estate.
  211 
  212   print &probSet_titleBar("Problem Set $setNumber_display from  $Course_display for $studentName");
  213 
  214     #
  215     #  DPVC -- added ROWSPAN below to accommodate the "time-remaining" section
  216     #
  217     print <<"ENDOFHTML";
  218 <TABLE BORDER=1 CELLPADDING=5>
  219   <TR>
  220     <!-- Row 1 Column 1 -->
  221     <TD WIDTH="15%" ROWSPAN="2">
  222 Select one of the $numberOfProblems problems to try:
  223 <FORM METHOD=POST ACTION="$Global::processProblem_CGI">
  224 <INPUT TYPE=HIDDEN NAME=probSetKey VALUE=$psvn>
  225 <P>
  226 <SELECT NAME=probNum SIZE=11>
  227 ENDOFHTML
  228     #
  229     #  DPVC -- for display of total score
  230     #
  231     my ($problemValue,$score); my $totalScore = 0;
  232     #
  233     #  End DPVC
  234     #
  235     my ($problemAttempted, $problemStatus, $longProblemStatus);
  236     foreach my $problem (@problems) {
  237       $problemStatus = getProblemStatus($problem,$psvn);
  238       $problemAttempted = getProblemAttempted($problem,$psvn);
  239       #
  240       #  DPVC -- so we can add up the total score
  241       #
  242       $problemValue = &getProblemValue($problem,$psvn);
  243       $score += round_score($problemStatus*$problemValue);
  244       $totalScore += $problemValue;
  245        #
  246        #  End DPVC
  247      #
  248 
  249       if (!$problemAttempted) {
  250         $longProblemStatus  = '';
  251       } elsif ($problemStatus  >= 0 and $problemStatus <=1 ) {
  252           my $percentCorr = int(100*$problemStatus+.5);
  253         $longProblemStatus = "${percentCorr}\% correct"
  254       } else {
  255         $longProblemStatus = 'unknown status'; # default value
  256       }
  257       print "<OPTION VALUE=\"$problem\">Problem $problem -- $longProblemStatus</OPTION>\n";
  258   }
  259 
  260   # nice note to warn if there's less than one day left to complete problem set
  261     if ($remainingTime < 86400 and $remainingTime > 0)  {
  262       $TimeString = "<P><EM>Note: you have less than one day left to complete this problem set</EM>";
  263     } else {
  264       $TimeString = "";
  265     }
  266 
  267     print "</SELECT><BR>";
  268 
  269     print "<NOBR>\n";      #  DPVC -- don't wrap this text
  270 
  271     #
  272     #  DPVC -- show total score
  273     #
  274     my $totalPercent = "";
  275     $totalPercent = " (".int($score/$totalScore*100+.5)."%)" if ($totalScore > 0);
  276     print "Total score: $score out of $totalScore$totalPercent<P>\n";
  277     #
  278     #  End DPVC
  279     #
  280 
  281   my $practiceUser = $Global::practiceUser;
  282   if (($currentTime > $ddts) or ($User =~ /^$practiceUser/)) {
  283     print '<INPUT type="checkbox" name="show_old_answers" value="1"> Show my old answers<BR><BR>';
  284   }
  285   else {
  286     print '<INPUT type="checkbox" name="show_old_answers" value="1" checked> Show my old answers<BR><BR>';
  287   }
  288 
  289     print &sessionKeyInputs(\%inputs);
  290 
  291     my $button_style = 'STYLE = "width: 10em"';
  292     my $mode = $inputs{'Mode'};
  293     $mode = $Global::htmlModeDefault unless ($mode);
  294     &displaySelectModeLine($mode); ## displays mode select buttons
  295     ## displaySelectModeLine() is in "${courseScriptsDirectory}$Global::displayMacros_pl"
  296     print "</NOBR>\n";     #  DPVC -- end of unwrapped text
  297     print <<"ENDOFHTML";
  298 <BR>
  299 <INPUT TYPE=SUBMIT VALUE="Get Problem" $button_style>
  300 $TimeString
  301 </FORM>
  302 ENDOFHTML
  303 
  304     print "<FORM METHOD=POST ACTION=\"${Global::cgiWebworkURL}welcome.pl\"><P>";
  305     print &sessionKeyInputs(\%inputs);
  306 
  307     print <<"ENDOFHTML";
  308 <INPUT TYPE=HIDDEN NAME="probSetKey" VALUE=$psvn>
  309 <INPUT TYPE=SUBMIT VALUE="Problem Sets" $button_style>
  310 </FORM>
  311     </TD>
  312     <!-- Row 1 Column 2 -->
  313     <TD>
  314 ENDOFHTML
  315 
  316 
  317   # process problem and save @printlines
  318   my $probHeader = $Global::PROB_HEADER;  # default value
  319   if ((defined($probHeaderFileName)) and ($probHeaderFileName =~ /\S/)) {
  320     $probHeader = $probHeaderFileName;
  321     }
  322 
  323   # use $probHeader as default unless $probHeaderFileName is defined in the set definition file
  324     my $source;
  325     if (-e "${templateDirectory}$probHeader") {
  326         unless (-r "${templateDirectory}$probHeader") {
  327           wwerror($0, "Can't read ${templateDirectory}$probHeader");
  328         }
  329         open(PROB,"<${templateDirectory}$probHeader");
  330         $source = join("",<PROB>);
  331         close(PROB);
  332     }
  333 
  334     # translate the problem header file
  335   my %envir=defineProblemEnvir($mode,0,$psvn,$Course);
  336   $envir{fileName} = $probHeader;
  337 
  338   my $imgen="";
  339   if($mode eq 'HTML_dpng') {
  340     # for John Jones' WW1 ImageGenerator:
  341     #$imgen = new ImageGenerator;
  342     #$imgen->initialize(\%envir);
  343     # for Sam's WW2 ImageGenerator:
  344     $imgen = WeBWorK::PG::ImageGenerator->new(
  345       tempDir  => $Global::tempDirectory,
  346       latex    => $Global::externalLatexPath,
  347       dvipng   => $Global::externalDvipngPath,
  348       useCache => 1,
  349       cacheDir => $Global::equationCacheDirectory,
  350       cacheURL => $Global::equationURL,
  351       cacheDB  => $Global::equationCacheDB,
  352     );
  353   }
  354   $envir{imagegen} = $imgen;
  355 
  356   my $pt = new WeBWorK::PG::Translator; # pt stands for problem translator;
  357   $pt->{ra_included_modules} = [ @PGtranslator::class_modules ]; # copy from PGtranslator stub
  358   $pt->environment(\%envir);
  359   $pt->initialize();
  360   $pt->set_mask();
  361   $pt->source_string($source);
  362   $pt->unrestricted_load("${courseScriptsDirectory}PG.pl");
  363   $pt->unrestricted_load("${courseScriptsDirectory}dangerousMacros.pl");
  364   $pt->unrestricted_load("${courseScriptsDirectory}IO.pl");
  365   $pt->translate();
  366 
  367   my $PG_PROBLEM_TEXT_REF = $pt->ra_text();
  368   my $PG_HEADER_TEXT_REF  = $pt->r_header; #\$PG_HEADER_TEXT;
  369   my $PG_ANSWER_HASH_REF  = $pt->rh_correct_answers;
  370   my $PG_FLAGS_REF        = $pt->rh_flags;
  371 
  372   my @printlines;
  373 
  374   if($mode eq 'HTML_dpng') {
  375                 my $forceRefresh=0;
  376 #                if($inputs{'refreshCachedImages'} || $main::refreshCachedImages) {
  377 #                        $forceRefresh=1;
  378 #               }
  379     # for both John Jones' WW1 ImageGenerator and Sam's WW2 ImageGenerator:
  380     $imgen->render('refresh'=>$forceRefresh); # Can force new images
  381         }
  382 
  383   if($mode eq "HTML" || $mode eq 'HTML_tth' || $mode eq 'HTML_dpng' || $mode eq 'HTML_jsMath' || $mode eq 'HTML_asciimath') {
  384     @printlines = @{$PG_PROBLEM_TEXT_REF};
  385     #@printlines = @{$pt->ra_text()};
  386   }
  387   elsif ($mode eq 'Latex2HTML') {
  388     @printlines =
  389       &createDisplayedInsert($setNumber,$probHeader,$psvn,$Course,$PG_PROBLEM_TEXT_REF);
  390   }
  391   else {
  392       @printlines="$0: Error:  Mode |$mode| is not HTML, HTML_tth, HTML_dpng, HTML_jsMath,HTML_asciimath or Latex2HTML.";
  393     }
  394   print @printlines;
  395   print "</TD></TR>\n";
  396         #
  397         # DPVC -- for showing time remaining
  398         #
  399         showTimeRemaining() if (($Global::showRemainingTime) and ($remainingTime < $Global::startShowingRemainingTime));
  400         #
  401         # End DPVC
  402         #
  403         print "</TABLE>";
  404 
  405   print &htmlBOTTOM('welcomeAction.pl', \%inputs,'probSetHelp.html');
  406 }
  407 
  408 
  409 #
  410 #  DPVC  -- for showing the remaining time
  411 #
  412 
  413 sub showTimeRemaining {
  414   print "<TR><TD ALIGN=\"CENTER\" VALIGN=\"MIDDLE\"><SMALL><NOBR>";
  415   print "This is <B>Problem Set $setNumber</B> due on <B>".
  416     formatDateAndTime($ddts)."</B><BR>\n";
  417   print "This page was last generated on ".formatDateAndTime($currentTime)."<BR>\n";
  418   print "(You have ".formatTimeRemaining($remainingTime)." remaining)\n";
  419   print "</NOBR></SMALL></TD></TR>";
  420 }
  421 
  422 sub formatTimeRemaining {
  423     my ($seconds) = @_;
  424     return("no time") if ($seconds <= 0);
  425     my ($minutes) = int($seconds/60);
  426     my ($hours) = int($minutes/60);
  427     my ($days) = int($hours/24);
  428 
  429     return("about $days days") if ($days > 1);
  430     return("about a day") if ($days == 1);
  431     return("about $hours hours") if ($hours > 1);
  432     return("more than an hour") if ($hours == 1);
  433     return("less than an hour");
  434 }
  435 
  436 #
  437 #  End DPVC
  438 #
  439 
  440 ################################################################################
  441 # downloadAllSets (and related subroutines) ####################################
  442 ################################################################################
  443 
  444 ###################
  445 # downloadAllSets #
  446 ###################
  447 
  448 sub downloadAllSets {
  449   system("/usr/bin/renice +$main::CLASS_DOWNLOAD_NICE -p $$ 1>/dev/null") && warn "Could not renice process. pid $$";
  450   alarm( $main::CLASS_DOWNLOAD_TIME_OUT_CONSTANT);
  451 
  452   my $downloadMulti = "unknown";
  453   $downloadMulti = "multistudent" if $action eq "Get_all_copies";
  454   $downloadMulti = "multiset" if $action eq "Get_hard_copy";
  455 
  456   my @psvns_to_download = $query->param('local_psvns');
  457   my $num_psvns_to_download = @psvns_to_download;
  458   my $max_psvns_to_download = $Global::max_num_of_ps_downloads_allowed;
  459 
  460   if($num_psvns_to_download > 1 and $permissions != $Global::instructor_permissions) {
  461     wwerror("Non-professors are not permitted to download more than one problem set at a time.");
  462   }
  463 
  464   if(@psvns_to_download > $Global::max_num_of_ps_downloads_allowed) {
  465     my $tooManyWhat = $downloadMulti eq "multiset" ? "problem sets" : "students";
  466     wwerror("Too many $tooManyWhat are selected for download.",
  467       "The maximum number of $tooManyWhat which can be downloaded at one time is $Global::max_num_of_ps_downloads_allowed."
  468       ." You selected $num_psvns_to_download. Go back and select fewer $tooManyWhat."
  469       ." (This maximun is set by the variable \$max_num_of_ps_downloads_allowed in Global.pm.)");
  470   }
  471 
  472   my ($cumulativeTexSource, $currentTexSourceRef, $currentTexSource, $currentTexErrorRef);
  473 
  474   # this could be used when eliminating pre-foreach createTexSourceHandleErrors call
  475   # s/\\end\{document\}.*?\\begin\{document\}/\n\\newpage\n/s;
  476 
  477   $tempTexFileBaseName = "${tempDirectory}Temp_downloadAllSets_$User";
  478   my $first_psvn = $psvns_to_download[0];
  479 
  480   my $current_psvn = shift @psvns_to_download;
  481   ($currentTexSourceRef, $currentTexErrorRef) = createTexSource($current_psvn);
  482   @psvns_to_download = () if(@$currentTexErrorRef);
  483   $currentTexSource = $$currentTexSourceRef;
  484   $currentTexSource =~ s|\\end\{document\}\s$|\n|s;
  485   $cumulativeTexSource .= $currentTexSource;
  486 
  487   foreach $current_psvn (@psvns_to_download) {
  488     ($currentTexSourceRef, $currentTexErrorRef) = createTexSource($current_psvn);
  489     @psvns_to_download = () if(@$currentTexErrorRef);
  490     $currentTexSource = $$currentTexSourceRef;
  491     $currentTexSource =~ s|^.*?\\begin\{document\}|\n\\newpage\n|s;
  492     $currentTexSource =~ s|\\end\{document\}\s$|\n|s;
  493     $cumulativeTexSource .= $currentTexSource;
  494   }
  495 
  496   $cumulativeTexSource .= "\n\\end{document}\n";
  497 
  498   open TEXOUTPUT, ">$tempTexFileBaseName.tex"
  499     or wwerror("Can't open $tempTexFileBaseName.tex for output.");
  500   print TEXOUTPUT $cumulativeTexSource;
  501   close TEXOUTPUT;
  502 
  503   if(@$currentTexErrorRef) {
  504     PG_error_print($tempTexFileBaseName, $current_psvn, @$currentTexErrorRef);
  505   } else {
  506     $downloadType = lc $downloadType;
  507     my $mimeType = prepareHardcopy($tempTexFileBaseName, $downloadType);
  508 
  509     my ($setName, $userName);
  510     &attachProbSetRecord($first_psvn);
  511     if($downloadMulti eq "multistudent") {
  512       if($num_psvns_to_download == 1) {
  513         $setName = getSetNumber($first_psvn);
  514         $userName = getStudentLogin($first_psvn);
  515       } else {
  516         $setName = getSetNumber($first_psvn);
  517         $userName = "multistudent";
  518       }
  519     } elsif($downloadMulti eq "multiset") {
  520       if($num_psvns_to_download == 1) {
  521         $setName = getSetNumber($first_psvn);
  522         $userName = getStudentLogin($first_psvn);
  523       } else {
  524         $setName = "multiset";
  525         $userName = getStudentLogin($first_psvn);
  526       }
  527     }
  528     my $hardCopyName = "$Course.$userName.$setName.$downloadType";
  529 
  530     open(TEXINPUT, "$tempTexFileBaseName.$downloadType")
  531       or wwerror($0, "Can't open $tempTexFileBaseName.$downloadType: $!\n");
  532     print "Content-type: $mimeType\n";
  533     print "Content-disposition: attachment; filename=\"$hardCopyName\"\n\n";
  534     print while (<TEXINPUT>);
  535     close TEXINPUT;
  536   }
  537 }
  538 
  539 ###################
  540 # createTexSource #
  541 ###################
  542 
  543 sub createTexSource {
  544   my $psvn = shift;
  545 
  546   # Check that the psvn corresponds to the user and that it is after the open date.
  547   # This should only fail if someone is trying to break into WeBWorK.
  548   &attachProbSetRecord($psvn);
  549   $login_name_for_psvn = &getStudentLogin($psvn);
  550   attachCLRecord($login_name_for_psvn);
  551 
  552   if ((($User ne &getStudentLogin($psvn)) ||($currentTime < $odts))
  553       and ($permissions != $Global::instructor_permissions)
  554       and ($permissions != $Global::TA_permissions))
  555   {
  556     &hackerError;
  557     exit;
  558   }
  559 
  560   my $probSetHeader = $Global::SET_HEADER;
  561   my $setHeaderFileName = &getSetHeaderFileName($psvn);
  562 
  563   my $answersRequestedQ = 0;
  564   $answersRequestedQ=  $inputs{'ShowAns'} if defined($inputs{'ShowAns'});
  565 
  566   my $adts=&getAnswerDate($psvn);
  567 
  568   my $displayCorrectAnswersQ = 0;  #initialize
  569   $displayCorrectAnswersQ =1 if $answersRequestedQ && ($currentTime > $adts);
  570   $displayCorrectAnswersQ =1 if $answersRequestedQ && ($permissions == $Global::instructor_permissions);
  571 
  572 
  573 
  574   $main::timer1->continue("create TeX source for $login_name_for_psvn")if $main::timingON;
  575   my $texSource ='';
  576 
  577   print STDERR "%%Creating a tex version of set $setNumber<BR>\n" if $debugON;
  578   print STDERR "%%For", &CL_getStudentName($login_name_for_psvn), "psvn=$psvn<BR>\n" if $debugON;
  579 
  580   # print TeX preamble and header
  581   $texSource .= &texInput($Global::TEX_SET_PREAMBLE);
  582   $texSource .= &texInput($Global::TEX_SET_HEADER);
  583 
  584   # print set header
  585   my $mode = "TeX";
  586   my @PG_COMPILE_ERRORS = ();
  587   if ((defined($setHeaderFileName)) and $setHeaderFileName =~ /\S/) {
  588     $probSetHeader = $setHeaderFileName;
  589   }
  590   if (open(INPUT,"${templateDirectory}$probSetHeader")) {
  591     $probSetHeader =~ /\.([^\.]*)$/;
  592     my $displayMode = $1;
  593 
  594     if ($displayMode eq 'pg') {
  595       my %envir=defineProblemEnvir($mode, 0, $psvn, $Course, undef());
  596       my $input_string=  join("",<INPUT>);
  597       my ($PG_PROBLEM_TEXT_REF, $PG_HEADER_TEXT_REF, $PG_ANSWER_HASH_REF, $PG_FLAGS_REF);
  598 
  599 # BEGIN fork
  600       if (open TEX_PIPE, "-|") {
  601         # parent:
  602         local $/ = "\n";
  603         my $curr_pg_compile_error = <TEX_PIPE>;
  604         chomp $curr_pg_compile_error;
  605         push @PG_COMPILE_ERRORS, $curr_pg_compile_error if $curr_pg_compile_error;
  606 
  607         undef $/;
  608         $texSource .= <TEX_PIPE>;
  609       } else {
  610         # child:
  611         $texSource = ''; # clear this at beginning of fork
  612         @PG_COMPILE_ERRORS = (); # clear this as well
  613 # -----
  614         my $pt = new WeBWorK::PG::Translator;
  615         $pt->{ra_included_modules} = [ @PGtranslator::class_modules ]; # copy from PGtranslator stub
  616         $pt -> evaluate_modules( @{main::modules_to_evaluate}) ;
  617         $pt -> load_extra_packages(@{main::extra_packages_to_be_loaded});
  618         # The variables in the two preceding lines are  defined in PG_module_list.pl
  619         # require "${courseScriptsDirectory}PG_module_list.pl";
  620         # (Modules are defined by require statement above found near the top of this file)
  621         $pt->environment(\%envir);
  622         $pt->initialize();
  623         $pt->set_mask();
  624         $pt->source_string($input_string);
  625         $pt->unrestricted_load("${courseScriptsDirectory}PG.pl");
  626         $pt->unrestricted_load("${courseScriptsDirectory}dangerousMacros.pl");
  627         $pt->unrestricted_load("${courseScriptsDirectory}IO.pl");
  628         $pt->translate();
  629 
  630         $PG_PROBLEM_TEXT_REF = $pt->ra_text();
  631         $PG_HEADER_TEXT_REF = $pt->r_header;#\$PG_HEADER_TEXT;
  632         $PG_ANSWER_HASH_REF = $pt->rh_correct_answers;
  633         $PG_FLAGS_REF = $pt->rh_flags;
  634 
  635         $texSource .= join '', @{$PG_PROBLEM_TEXT_REF};
  636 
  637 # begin non-FORK code
  638 #       if (defined($PG_FLAGS_REF->{'error_flag'}) and $PG_FLAGS_REF->{'error_flag'} == 1) {
  639 #         push(@PG_COMPILE_ERRORS, qq{<A HREF="#problem0">$probSetHeader</A>} );
  640 #       }
  641 # end non-FORK code
  642 
  643 # begin FORK-only code
  644       my $stupid_forked_error_string;
  645       if (defined($PG_FLAGS_REF->{'error_flag'}) and  $PG_FLAGS_REF->{'error_flag'} ==1) {
  646         $texSource = qq{<A HREF="#problem0">$probSetHeader</A>} . "\n" . $texSource;
  647       } else {
  648         $texSource = "\n" . $texSource;
  649       }
  650 # end FORK code
  651 
  652         if (defined($Global::WARNINGS) and $Global::WARNINGS) {
  653           my $warnings = '{\\bf WARNINGS:\par{\\tiny ' . $Global::WARNINGS . ' }}';
  654           $warnings =~ s|/|\\\-/|g;  # allow linebreaks in the middle of URLs
  655           $warnings =~ s/<br>/\\par\n/ig; # introduce breaks at linebreaks and paragraphs
  656           $warnings =~ s/<p>/\\par\n/ig;
  657           $warnings =~ s/\#/\\\#/g; # protect against some of the symbols which are reserved in tex
  658           $warnings =~ s/\_/\\\_/g;
  659           $warnings =~ s/\>/\\\>/g;
  660           $warnings =~ s/\</\\\</g;
  661           $texSource .= $warnings;
  662         }
  663         $Global::WARNINGS = ''; # reset the Global::WARNINGS parameter
  664 # -----
  665         print $texSource;
  666         exit;
  667       }
  668 # END fork
  669     } else {
  670       $texSource .= "Don't understand languages with extension $displayMode.<BR>\n";
  671     }
  672     close INPUT;
  673   } else {
  674     print STDERR ( "Can't open ${templateDirectory}${probSetHeader}\n") if $debugON;
  675     wwerror("$0", "\n######## Could not open the set header file: ${templateDirectory}${probSetHeader}","","");
  676   }
  677 
  678   # Print problems
  679   my @problems = sort { $a <=> $b } &getAllProblemsForProbSetRecord($psvn);
  680   my @refSubmittedAnswers = ();
  681 
  682   my $probNum;
  683   foreach $probNum (@problems) {
  684     my $source;
  685     my $probFileName = &getProblemFileName($probNum,$psvn);
  686     $main::timer1->continue("processing $probFileName") if $main::timingON;
  687     if (-e "${templateDirectory}$probFileName") {
  688       unless (-r "${templateDirectory}$probFileName") {
  689         wwerror($0, "Can't read ${templateDirectory}$probFileName");
  690       }
  691       open(PROB,"<${templateDirectory}$probFileName");
  692       $source = join("",<PROB>);
  693       close(PROB);
  694     }
  695     local($^W) =0; ##########CHANGE THIS BACK!!!! # what do you mean by that?
  696     my %envir=defineProblemEnvir('TeX',$probNum,$psvn,$Course,undef());
  697     my ($PG_PROBLEM_TEXT_REF, $PG_HEADER_TEXT_REF, $PG_ANSWER_HASH_REF, $PG_FLAGS_REF,$PG_EVALUATED_ANSWERS_REF);
  698 
  699 # BEGIN fork
  700     if (open TEX_PIPE, "-|") {
  701       # parent:
  702       local $/ = "\n";
  703       my $curr_pg_compile_error = <TEX_PIPE>;
  704       chomp $curr_pg_compile_error;
  705       push @PG_COMPILE_ERRORS, $curr_pg_compile_error if $curr_pg_compile_error;
  706 
  707       undef $/;
  708       $texSource .= <TEX_PIPE>;
  709     } else {
  710       # child:
  711       $texSource = ''; # clear this at beginning of fork
  712       @PG_COMPILE_ERRORS = (); # clear this as well
  713 # -----
  714       my $pt = new WeBWorK::PG::Translator;  #pt stands for problem translator;
  715       $pt->{ra_included_modules} = [ @PGtranslator::class_modules ]; # copy from PGtranslator stub
  716       $pt->environment(\%envir) ;
  717       $pt->initialize();
  718       $pt-> set_mask();
  719       $pt->source_string($source);
  720       $pt->unrestricted_load("${courseScriptsDirectory}PG.pl");
  721       $pt->unrestricted_load("${courseScriptsDirectory}dangerousMacros.pl");
  722       $pt->unrestricted_load("${courseScriptsDirectory}IO.pl");
  723       $pt->translate();
  724 
  725       $PG_PROBLEM_TEXT_REF      = $pt->ra_text();
  726       $PG_HEADER_TEXT_REF       = $pt->r_header;#\$PG_HEADER_TEXT;
  727       #$PG_ANSWER_HASH_REF       = $pt->rh_correct_answers;
  728       $PG_EVALUATED_ANSWERS_REF = $pt->process_answers;
  729       $PG_FLAGS_REF             = $pt ->rh_flags;
  730 
  731       $texSource .= join '', @{$PG_PROBLEM_TEXT_REF};
  732 
  733 # begin non-FORK code
  734 #     if (defined($PG_FLAGS_REF->{'error_flag'}) and  $PG_FLAGS_REF->{'error_flag'} ==1) {
  735 #       push(@PG_COMPILE_ERRORS, qq{<A HREF="#problem$probNum">$probNum</A>} );
  736 #     }
  737 # end non-FORK code
  738 
  739 # begin FORK-only code
  740       if (defined($PG_FLAGS_REF->{'error_flag'}) and  $PG_FLAGS_REF->{'error_flag'} ==1) {
  741         $texSource = qq{<A HREF="#problem$probNum">$probNum</A>} . "\n" . $texSource;
  742       } else {
  743         $texSource = "\n" . $texSource;
  744       }
  745 # end FORK code
  746 
  747       if ($displayCorrectAnswersQ) {
  748         my %correctAnswerHash = ();
  749         my @correctAnswerList = ();
  750         my %submittedAnswerHash = ();
  751 
  752         if (ref($PG_EVALUATED_ANSWERS_REF) eq 'HASH') {
  753           %correctAnswerHash = %$PG_EVALUATED_ANSWERS_REF;
  754         } else {
  755           warn "ERROR: Please pass the PG answer list as a hash not a list.";
  756         }
  757 
  758         if (%correctAnswerHash) {
  759           my ($correctFlag,$normalizedCorrectAnswer,
  760             $normalizedSubmittedAnswer,
  761             $answerMessage) = ();
  762 
  763           # determine the correct order for the answers
  764           my @answer_entry_order =
  765             (defined($pt->{PG_FLAGS_REF}->{ANSWER_ENTRY_ORDER}))
  766               ? @{$pt->{PG_FLAGS_REF}->{ANSWER_ENTRY_ORDER}}
  767               : keys %{$pt->rh_evaluated_answers};
  768           $texSource .= "\\par Correct Answers:\\vspace{-\\parskip}\\begin{itemize}\n";
  769 #         $texSource .= "Correct Answers:\\par\\begin{itemize}\n";
  770           foreach my $ky (@answer_entry_order) {
  771             $normalizedCorrectAnswer = $correctAnswerHash{$ky}->{correct_ans};
  772             #
  773             #  DPVC -- 2003/07/14
  774             #    Changed this to use verbatim mode so that
  775             #    all answers are displayed as typed by the
  776             #    instructor (perhaps the answer checker
  777             #    should format them, so that they can be
  778             #    put in math mode when appropriate.)
  779             #
  780             #$normalizedCorrectAnswer =~ s/\^/\\\^\{\}/g;
  781             #$normalizedCorrectAnswer =~ s/\_/\\\_/g;
  782             $texSource .= "\\item\\begin{verbatim}$normalizedCorrectAnswer\\end{verbatim}\n";
  783             # End DPVC
  784           }
  785           $texSource .= "\\end{itemize} \\par\n";
  786         }
  787       }
  788 
  789       if (defined($Global::WARNINGS) and $Global::WARNINGS) {
  790         my $warnings = '{\\bf WARNINGS:\par{\\tiny ' . $Global::WARNINGS . ' }}';
  791         unless (@PG_COMPILE_ERRORS) { # prepare warnings for TeX output in this case
  792           $warnings =~ s|/|\\\-/|g; # allow linebreaks in the middle of URLs
  793           $warnings =~ s/<br>/\\par\n/ig; # introduce breaks at linebreaks and paragraphs
  794           $warnings =~ s/<p>/\\par\n/ig;
  795           $warnings =~ s/\#/\\\#/g; # protect against some of the symbols which are reserved in tex
  796           $warnings =~ s/\_/\\\_/g;
  797           $warnings =~ s/\>/\\\>/g;
  798           $warnings =~ s/\</\\\</g;
  799           $texSource .= $warnings;
  800         }
  801       }
  802       $Global::WARNINGS = '';   #reset the Global::WARNINGS parameter
  803 # -----
  804       print $texSource;
  805       exit;
  806     }
  807 # END fork
  808   } # this is the end of the foreach problem loop
  809 
  810   # print Tex postamble
  811   $texSource .= &texInput($Global::TEX_SET_FOOTER);
  812 
  813   return \$texSource, \@PG_COMPILE_ERRORS;
  814 }
  815 
  816 ###################
  817 # prepareHardcopy #
  818 ###################
  819 
  820 sub prepareHardcopy
  821 {
  822   my ($texFileBaseName, $targetFormat) = @_;
  823   my $mimeType;
  824     $main::timer2 = WeBWorK::Timing->new("Begin tex to pdf process") if $main::timingON;
  825     $main::timer2->start if $main::timingON;
  826   chdir $tempDirectory;
  827   $ENV{PATH} .= "$Global::extendedPath";
  828   my $error_log = '/dev/null';    ## by default do not log error messages
  829   $error_log = &Global::getErrorLog if $Global::imageDebugMode;
  830 
  831   my $dviCommandLine = "$Global::externalLatexPath $texFileBaseName.tex >>$error_log 2>>$error_log";
  832   my $psCommandLine = "$Global::externalDvipsPath -o $texFileBaseName.ps $texFileBaseName.dvi >>$error_log 2>>$error_log";
  833   my $pdfCommandLine = "$Global::externalGsPath -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=$texFileBaseName.pdf -c save pop -f $texFileBaseName.ps";
  834 # my $pdfCommandLine = "$Global::externalPs2pdfPath $texFileBaseName.ps $texFileBaseName.pdf";
  835 
  836   # make sure that you are not using old copies of the following files:
  837   unlink("$texFileBaseName.dvi","$texFileBaseName.ps", "$texFileBaseName.pdf");
  838 
  839   # we use logPrint() for TeX->DVI errors as they are usually caused
  840   if($targetFormat eq "pdf") {
  841     system($dviCommandLine); -e "$texFileBaseName.dvi" or &logPrint($texFileBaseName);
  842     system($psCommandLine);  -e "$texFileBaseName.ps" or die "ps generation failed.";
  843     system($pdfCommandLine); -e "$texFileBaseName.pdf" or die "pdf generation failed.";
  844     $mimeType = "application/pdf";
  845   } elsif($targetFormat eq "ps") {
  846     system($dviCommandLine); -e "$texFileBaseName.dvi" or &logPrint($texFileBaseName);
  847     system($psCommandLine);  -e "$texFileBaseName.ps" or die "ps generation failed.";
  848     $mimeType = "application/postscript";
  849   } elsif($targetFormat eq "dvi") {
  850     system($dviCommandLine); -e "$texFileBaseName.dvi" or &logPrint($texFileBaseName);
  851     $mimeType = "application/x-dvi";
  852   } elsif($targetFormat eq "tex") {
  853     $mimeType = "application/tex";
  854   } else {
  855     die "unrecognized format: $targetFormat";
  856   }
  857     $main::timer2->stop if $main::timingON;
  858     $main::timer2->save if $main::timingON;
  859   return $mimeType;
  860 }
  861 
  862 ##################
  863 # PG_error_print #
  864 ##################
  865 
  866 sub PG_error_print
  867 {
  868   my ($tempTexFileBaseName, $current_psvn, @errors) = @_;
  869 
  870   # get set name and student name from psvn
  871   &attachProbSetRecord($current_psvn);
  872   my $userName = &getStudentLogin($current_psvn);
  873   my $setName = &getSetNumber($current_psvn);
  874 
  875   # print error page header
  876   print &htmlTOP("PG compile error");
  877   print "<H3>PG error while compiling problem number", (@errors>1) ? 's ' : ' ',
  878     join(', ', @errors), " in problem set $setName for $userName.</H3>";
  879   print "<h3>TeX source file:</h3>";
  880 
  881   # open temp tex file
  882   if(open TEXINPUT, "$tempTexFileBaseName.tex") {
  883     print "<pre>\n";
  884     my $lineNumber = 1;
  885     while(<TEXINPUT>) {
  886       if(/<A NAME/) { print $_; }
  887       else { print protect_HTML("$lineNumber $_"), "\n"; }
  888       $lineNumber++;
  889     }
  890     print "</pre>\n";
  891     close TEXINPUT;
  892   } else {
  893     print "<p>Unable to open TeX source file:<br><tt>$tempTexFileBaseName.tex</tt></p>";
  894   }
  895 
  896   # print page footer
  897   print &htmlBOTTOM("welcomeAction.pl", \%inputs);
  898   exit;
  899 }
  900 
  901 sub logPrint {
  902   my $texFileBaseName=shift;
  903     print &htmlTOP("TeX Error or error in creating PostScript file");
  904     open (LOGFILE, " $texFileBaseName.log")
  905   || print  "<H3>Can't open log file:</H3> path= $texFileBaseName.log<BR>$!<BR><BR>"  ;
  906 
  907 
  908     print "<H3>TeX Error Log:</H3>";
  909     my $print_error_switch = ($debugON) ? 1: 0;
  910     my $out='';
  911     #warn ord $/, ord  "\n", ord "\r";
  912     #warn "length of separator = ", length($/);
  913     $/ = "\n";
  914     #warn ord $/, ord  "\n", ord "\r";
  915     while (<LOGFILE>) {
  916       $out = $_;
  917       $print_error_switch = 1 if $out =~ /^!/;  # after a fatal error start printing messages
  918     print protect_HTML($out)."<BR>\n" if $print_error_switch;
  919     }
  920     close(LOGFILE);
  921 
  922     open (TEXFILE, "$texFileBaseName.tex")
  923   || print "<H3>Can't open tex source file:</H3> path= $texFileBaseName.tex:<BR> $!<BR><BR>\n";
  924     print "<BR>\n<H3>TeX Source File:</H3><BR>\n";
  925     print "<PRE>";
  926 
  927     my $lineNumber = 1;
  928     while (<TEXFILE>) {
  929     print protect_HTML("$lineNumber $_")."\n";
  930         $lineNumber++;
  931     }
  932     close(TEXFILE);
  933     print "</PRE>";
  934     print &htmlBOTTOM("welcomeAction.pl", \%inputs);
  935 }
  936 sub protect_HTML {
  937   my $line = shift;
  938   chomp($line);
  939   $line =~s/\&/&amp;/g;
  940   $line =~s/</&lt;/g;
  941   $line =~s/>/&gt;/g;
  942   $line;
  943 }
  944 sub selectionError {
  945     print &htmlTOP("Selection error");
  946 #
  947 #  DPVC -- 2002/1/4
  948 #    Modified the error message to it makes sense for Do Problem Set as well,
  949 #    and added a more complete explanation of what they should have done.
  950 #
  951     print "<H2>Error: No problem set selected!</H2>\n\n";
  952     print "<BLOCKQUOTE>\n";
  953     print "You must first <I>select</I> a problem set in order to work on it or download it.\n";
  954     print "<p>To select a problem set, click (once) on its name in the list so that it\n";
  955     print "becomes highlighted.  Once you have done that, you can choose to work on or download\n";
  956     print "the set.\n";
  957     print "</BLOCKQUOTE>\n<p>\n";
  958     print "<FORM METHOD=POST ACTION=\"${Global::cgiWebworkURL}welcome.pl\"><P>";
  959     print &sessionKeyInputs(\%inputs);
  960     print '<INPUT TYPE=SUBMIT VALUE="Return to Welcome Page">';
  961     print "\n</FORM>\n";
  962     print &htmlBOTTOM("welcomeAction.pl", \%inputs);
  963 }
  964 
  965 sub probSet_htmlTOP {
  966     my ($title, $bg_url) = @_;
  967     my $background_url = $bg_url || $Global::background_plain_url;
  968 
  969 
  970     my $out = <<ENDhtmlTOP;
  971 Content-type: text/html
  972 Expires: 0
  973 
  974 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
  975 <HTML>
  976 <HEAD>
  977 <TITLE>$title</TITLE>
  978 </HEAD>
  979 <BODY BACKGROUND="$background_url"><p>
  980 <P>
  981 
  982 ENDhtmlTOP
  983     $out;
  984 }
  985 
  986 sub probSet_titleBar {
  987   my ($title) = @_;
  988   my $title_bar = "";
  989   $title_bar .= qq{
  990     <TABLE BORDER="0" WIDTH="100%">
  991     <TR ALIGN=CENTER  >
  992     <TD ALIGN=LEFT >
  993     <A HREF="$Global::webworkDocsURL">
  994     <IMG SRC="$Global::squareWebworkGif" BORDER=1 ALT="WeBWorK"></A>
  995     </TD>
  996     <TD VALIGN=MIDDLE>
  997     <H2 ALIGN=CENTER>
  998     $title
  999     </H2>
 1000     </TD>
 1001     <TD ALIGN=RIGHT >
 1002     <FORM METHOD=POST ACTION=\"${Global::cgiWebworkURL}welcome.pl\"><P>
 1003   };
 1004   my $inputkeys = &sessionKeyInputs(\%inputs);
 1005 
 1006   $title_bar .= qq{
 1007     $inputkeys
 1008     <INPUT TYPE=HIDDEN NAME=\"probSetKey\" VALUE=$psvn>
 1009     <INPUT TYPE=SUBMIT VALUE=\"Problem Sets\">
 1010     </FORM>
 1011     </TD>
 1012       </TABLE>
 1013   };
 1014   $title_bar;
 1015 }
 1016 
 1017 sub hackerError  { ## prints hacker error message
 1018 
 1019     my $msg = "Attempt to hack into WeBWorK \n Remote Host is: ". remote_host()."\n";
 1020     $msg .= query_string;
 1021     &Global::log_error('hacker error', $msg);   ## log attempt
 1022 
 1023     ## notify by email
 1024 
 1025    my $toAdd = $Global::feedbackAddress;
 1026 
 1027     my $emailMsg = "To: $toAdd
 1028 Subject: Attempt to hack into WeBWorK
 1029 
 1030 Here are the details on the attempt to hack into weBWorK:\n
 1031 $msg
 1032 \n";
 1033 
 1034   my $smtp = Net::SMTP->new($Global::smtpServer, Timeout=>20);
 1035   $smtp->mail($Global::webmaster);
 1036   $smtp->recipient($Global::feedbackAddress);
 1037   $smtp->data($msg);
 1038   $smtp->quit;
 1039 
 1040 
 1041 #    my $SENDMAIL = $Global::SENDMAIL;
 1042 #    open (MAIL,"|$SENDMAIL");
 1043 #    print MAIL "$emailMsg";
 1044 #    close (MAIL);
 1045 
 1046     print   &htmlTOP("Hacker Error"),
 1047                         "<H2>Error:Please do not try to hack into WeBWorK!</H2>",
 1048                         startform(-action=>"${Global::cgiWebworkURL}${Global::welcomeAction_CGI}"),
 1049                         "<p>",
 1050                         &sessionKeyInputs(\%inputs),
 1051                         hidden(-name=>'local_psvns', -value=>$psvn),
 1052                         hidden(-name=>'action', -value=>'Do_problem_set'),
 1053                         submit(-value=>"Return to Problem Set"),
 1054                         endform(),
 1055                         &htmlBOTTOM($0, \%inputs);
 1056 }
 1057 
 1058 sub defineProblemEnvir {
 1059     my ($mode,$probNum,$psvn,$courseName,$refSubmittedAnswers)      =   @_;
 1060     my %envir=();
 1061     my $loginName = &getStudentLogin($psvn);
 1062   ##how to put an array submittedAnswers in a hash??
 1063     $envir{'refSubmittedAnswers'}   =   $refSubmittedAnswers if defined($refSubmittedAnswers);
 1064     $envir{'psvnNumber'}        =   $psvn;
 1065     $envir{'psvn'}            =   $psvn;
 1066     $envir{'studentName'}       =   &CL_getStudentName($loginName);
 1067   $envir{'studentLogin'}        = $loginName;
 1068   $envir{'studentID'}         = &CL_getStudentID($loginName);
 1069   $envir{'sectionName'}       = &CL_getClassSection($loginName);
 1070   $envir{'sectionNumber'}       = &CL_getClassSection($loginName);
 1071   $envir{'recitationName'}      = &CL_getClassRecitation($loginName);
 1072   $envir{'recitationNumber'}      = &CL_getClassRecitation($loginName);
 1073   $envir{'setNumber'}         = &getSetNumber($psvn);
 1074   $envir{'questionNumber'}        = $probNum;
 1075   $envir{'probNum'}           = $probNum;
 1076   $envir{'openDate'}          = &getOpenDate($psvn);
 1077   $envir{'formatedOpenDate'}      = &formatDateAndTime(&getOpenDate($psvn));
 1078   $envir{'formattedOpenDate'}     = &formatDateAndTime(&getOpenDate($psvn));
 1079   $envir{'dueDate'}           = &getDueDate($psvn);
 1080   $envir{'formatedDueDate'}       = &formatDateAndTime(&getDueDate($psvn));
 1081   $envir{'formattedDueDate'}      = &formatDateAndTime(&getDueDate($psvn));
 1082   $envir{'answerDate'}        = &getAnswerDate($psvn);
 1083   $envir{'formatedAnswerDate'}    = &formatDateAndTime(&getAnswerDate($psvn));
 1084   $envir{'formattedAnswerDate'}   = &formatDateAndTime(&getAnswerDate($psvn));
 1085    #  DavideCervone's new parameters
 1086    $envir{'showRemainingTime'} = $Global::showRemainingTime;
 1087   $envir{'startShowingRemainingTime'} = $Global::startShowingRemainingTime;
 1088    $envir{'dueDateLeeway'} = $Global::dueDateLeeway;
 1089    #  end DPVC
 1090   $envir{'problemValue'}        = &getProblemValue($probNum,$psvn);
 1091   $envir{'fileName'}          = &getProblemFileName($probNum,$psvn);
 1092   $envir{'probFileName'}        = &getProblemFileName($probNum,$psvn);
 1093   $envir{'languageMode'}        = $mode;
 1094   $envir{'displayMode'}       = $mode;
 1095   $envir{'outputMode'}        = $mode;
 1096   $envir{'courseName'}        = $courseName;
 1097   $envir{'sessionKey'}        = ( defined($inputs{'key'}) ) ?$inputs{'key'} : " ";
 1098 
 1099   # initialize constants for PGanswermacros.pl
 1100   $envir{'numRelPercentTolDefault'}   =     getNumRelPercentTolDefault();
 1101   $envir{'numZeroLevelDefault'}   =     getNumZeroLevelDefault();
 1102   $envir{'numZeroLevelTolDefault'}  =     getNumZeroLevelTolDefault();
 1103   $envir{'numAbsTolDefault'}      =     getNumAbsTolDefault();
 1104   $envir{'numFormatDefault'}      =     getNumFormatDefault();
 1105   $envir{'functRelPercentTolDefault'} =     getFunctRelPercentTolDefault();
 1106   $envir{'functZeroLevelDefault'}   =     getFunctZeroLevelDefault();
 1107   $envir{'functZeroLevelTolDefault'}  =     getFunctZeroLevelTolDefault();
 1108   $envir{'functAbsTolDefault'}    =     getFunctAbsTolDefault();
 1109   $envir{'functNumOfPoints'}      =     getFunctNumOfPoints();
 1110   $envir{'functVarDefault'}       =     getFunctVarDefault();
 1111   $envir{'functLLimitDefault'}    =     getFunctLLimitDefault();
 1112   $envir{'functULimitDefault'}    =     getFunctULimitDefault();
 1113   $envir{'functMaxConstantOfIntegration'} = getFunctMaxConstantOfIntegration();
 1114   $envir{'defaultDisplayMatrixStyle'} =     $Global::defaultDisplayMatrixStyle;
 1115   $envir{'numOfAttempts'}             =     undef(); # this is defined only for problems
 1116 
 1117   # defining directorys and URLs
 1118   $envir{'templateDirectory'}       = &getCourseTemplateDirectory();
 1119   $envir{'classDirectory'}        = $Global::classDirectory;
 1120   $envir{'cgiDirectory'}        = $Global::cgiDirectory;
 1121   $envir{'macroDirectory'}        = getCourseMacroDirectory();
 1122   $envir{'courseScriptsDirectory'}    = getCourseScriptsDirectory();
 1123   $envir{'htmlDirectory'}             =   getCourseHtmlDirectory();
 1124   $envir{'htmlURL'}           = getCourseHtmlURL();
 1125   $envir{'tempDirectory'}             =   getCourseTempDirectory();
 1126   $envir{'tempURL'}                   =   getCourseTempURL();
 1127   $envir{'scriptDirectory'}       = $Global::scriptDirectory;
 1128   $envir{'webworkDocsURL'}        = $Global::webworkDocsURL;
 1129   $envir{'externalTTHPath'}       = $Global::externalTTHPath;
 1130   $envir{'externalGif2EpsPath'}     = $scriptDirectory.'gif2eps';  #compatible with previous standard of storing this script in the scripts directory
 1131   $envir{'externalPng2EpsPath'}     = $scriptDirectory.'png2eps';
 1132 
 1133 
 1134   $envir{'inputs_ref'}                =  \%inputs;
 1135 
 1136 
 1137   my $seed    = &getProblemSeed($probNum, $psvn);
 1138   $seed     = 1111 unless defined($seed);
 1139   $envir{'problemSeed'}     =   $seed if defined($seed);
 1140   $envir{'displaySolutionsQ'}     =   $displaySolutionsQ;
 1141 
 1142   # here is a way to pass environment variables defined in webworkCourse.ph
 1143   my $k;
 1144   foreach $k (keys %Global::PG_environment ) {
 1145     $envir{$k} = $Global::PG_environment{$k};
 1146   }
 1147   %envir;
 1148 }
 1149 
 1150 ################################################################################
 1151 # cleanup routines #############################################################
 1152 ################################################################################
 1153 
 1154 BEGIN {
 1155   # This subroutine cleans up temporary files after the postscript copy has been created.
 1156   sub cleanup_downloadPS {
 1157       unless (defined($action) and ($action eq 'Do problem set' or $action eq 'Do_problem_set')) {
 1158           my $ERRORS = $save_errors;
 1159           unless ($debugON) {
 1160           eval {
 1161                   chdir $tempDirectory;
 1162                   unlink(
 1163                     "$tempTexFileBaseName.dvi",
 1164                     "$tempTexFileBaseName.ps",
 1165                     "$tempTexFileBaseName.pdf",
 1166                   "$tempTexFileBaseName.log",
 1167                   "$tempTexFileBaseName.aux",
 1168                   "$tempTexFileBaseName.tex"
 1169                 );
 1170                   unlink("${tempDirectory}eps/${login_name_for_psvn}*.eps");
 1171               };
 1172           $ERRORS .= $ERRORS . $@;
 1173         }
 1174         my $query = query_string();
 1175         $query = "" unless defined($query);
 1176         wwerror("$0", "ERROR: in downloadPS subroutine of welcomeAction.pl $ERRORS","","",$query) if $ERRORS;
 1177       }
 1178   }
 1179 }
 1180 
 1181 END {
 1182    if (defined($main::SIG_TIME_OUT) && $main::SIG_TIME_OUT == 1) {
 1183       alarm(0);  # turn off the alarm
 1184   my $hard_copy_message = qq{Content-type: text/html\n\n
 1185       <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
 1186       <HTML><BODY BGCOLOR = "FF99CC">
 1187       <BLOCKQUOTE><H3>WeBWorK hard copy download time out.</H3>\n
 1188     <H4>This download was cancelled because it took more than $main::TIME_OUT_CONSTANT seconds.</H4>  This may be because the
 1189     WeBWorK server is extraordinarily busy, or because there was an error in the problem,
 1190     or because you tried to download a set with too many  problems (more than 50).<P>\n
 1191         Use the back button to return to the previous page and try again.<BR>\n
 1192         If the problem is repeated you can report this to your instructor using the feedback button.
 1193         <P>
 1194         Because the WeBWorK server at the Unversity of Rochester is experiencing heavy use we have made downloading
 1195         hard copies a low priority during the times of very heavy useage.  It will be helpful if you
 1196         download hard copies during times when the load is not too heavy.
 1197         <P>
 1198         The load is usually heaviest in the evenings , particularly a few hours before assignments
 1199         are due.  The best times to download hard copies are in the morning and afternoon
 1200          -- or an hour after the due date and time of the previous assignment -- nobody is using the system then :-)
 1201          </BLOCKQUOTE></BODY></HTML>
 1202         };
 1203      my $do_problem_message = qq{Content-type: text/html\n\n
 1204         <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
 1205         <HTML><BODY BGCOLOR = "FF99CC">
 1206       <BLOCKQUOTE><H3>WeBWorK heavy useage time out.</H3>\n
 1207     <H4>Your request (action = $action) was cancelled because it took more than $main::TIME_OUT_CONSTANT seconds.</H4>
 1208     This is probably because the
 1209     WeBWorK server is extraordinarily busy.<P>\n
 1210     You should be warned that WeBWorK response will be unusually slow.  If possible you should try
 1211     to use WeBWorK at another time when the load is not as high.  The highest useage periods are in the
 1212     evening, particularly in the two hours before assignments are due.<P>\n
 1213         Use the back button to return to the previous page and try again.<P>\n
 1214         If the high useage problem continues you can report this to your instructor using the feedback button.
 1215         <P>
 1216 
 1217          </BLOCKQUOTE></BODY></HTML>
 1218         };
 1219      if ($action eq 'Get hard copy' or $action eq 'Get_hard_copy')  {
 1220       print $hard_copy_message;
 1221      } else{
 1222       print $do_problem_message;
 1223      }
 1224 
 1225 
 1226    }
 1227 
 1228   # begin Timing code
 1229   if( $main::logTimingData == 1 ) {
 1230     my $endTime = new Benchmark;
 1231     my $error_str='';
 1232 
 1233     if ($main::SIGPIPE) {
 1234       $error_str = 'broken PIPE--';
 1235     } elsif ($main::SIG_TIME_OUT) {
 1236       $error_str = "TIME_OUT after $main::TIME_OUT_CONSTANT secs --";
 1237     } elsif ($action eq 'Get hard copy' or $action eq 'Get_hard_copy') {
 1238       $error_str = 'successful download --  ';
 1239     }
 1240 
 1241     &Global::logTimingInfo($main::beginTime,$endTime,$error_str.'welcomeAction.pl',$Course,$User);
 1242   }
 1243   # end Timing code
 1244 
 1245   cleanup_downloadPS();
 1246 }
 1247 
 1248 1;

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9