| … | |
… | |
| 35 | } |
35 | } |
| 36 | # end Timing code |
36 | # end Timing code |
| 37 | |
37 | |
| 38 | # ## Setting these time out comstants to zeros removes the time constraint completely. (zero = infinity :=) ) |
38 | # ## Setting these time out comstants to zeros removes the time constraint completely. (zero = infinity :=) ) |
| 39 | $main::TIME_OUT_CONSTANT = 60; # one minute wait for on screen problems |
39 | $main::TIME_OUT_CONSTANT = 60; # one minute wait for on screen problems |
| 40 | $main::DOWNLOAD_TIME_OUT_CONSTANT = 300; # give it five minutes |
40 | # $main::DOWNLOAD_TIME_OUT_CONSTANT = 300; # give it five minutes |
| 41 | $main::CLASS_DOWNLOAD_TIME_OUT_CONSTANT = 1200; #twenty minutes |
41 | $main::CLASS_DOWNLOAD_TIME_OUT_CONSTANT = 1200; #twenty minutes |
| 42 | $main::DOWNLOAD_NICE = 2; |
42 | # $main::DOWNLOAD_NICE = 2; |
| 43 | $main::CLASS_DOWNLOAD_NICE = 5; # higher numbers indicated lower priorities |
43 | $main::CLASS_DOWNLOAD_NICE = 5; # higher numbers indicated lower priorities |
| 44 | |
44 | |
| 45 | # ## ATTENTION: The handlers PG_floating_point_exception_handler and PG_warnings_handler |
45 | # ## ATTENTION: The handlers PG_floating_point_exception_handler and PG_warnings_handler |
| 46 | # ## have to be installed after CGI::Carp is called since it also |
46 | # ## have to be installed after CGI::Carp is called since it also |
| 47 | # ## modifes the die and warn labels. Finding the right warning mechanism using these two |
47 | # ## modifes the die and warn labels. Finding the right warning mechanism using these two |
| 48 | # ## methods bears further investigation |
48 | # ## methods bears further investigation |
| 49 | # ## They are defined in Global.pm |
49 | # ## They are defined in Global.pm |
| 50 | $SIG{'FPE'} = \&PG_floating_point_exception_handler; |
50 | $SIG{'FPE'} = \&Global::PG_floating_point_exception_handler; |
| 51 | $SIG{__WARN__}=\&PG_warnings_handler; |
51 | $SIG{__WARN__}=\&Global::PG_warnings_handler; |
| 52 | $SIG{'TERM'} = sub {die '[',scalar(localtime),"] Caught a SIGTERM, Error: $! stopped at $0\n"; }; |
52 | $SIG{'TERM'} = sub {die '[',scalar(localtime),"] Caught a SIGTERM, Error: $! stopped at $0\n"; }; |
| 53 | $SIG{'PIPE'} = sub {$main::SIGPIPE = 1, die '[',scalar(localtime),"] Caught a SIGPIPE, Error: $! stopped at $0\n"; }; |
53 | $SIG{'PIPE'} = sub {$main::SIGPIPE = 1, die '[',scalar(localtime),"] Caught a SIGPIPE, Error: $! stopped at $0\n"; }; |
| 54 | $SIG{ALRM} = sub { $main::SIG_TIME_OUT = 1; exit(0) }; |
54 | $SIG{ALRM} = sub { $main::SIG_TIME_OUT = 1; exit(0) }; |
| 55 | |
55 | |
| 56 | alarm($main::TIME_OUT_CONSTANT); |
56 | alarm($main::TIME_OUT_CONSTANT); |
| … | |
… | |
| 132 | attachCLRecord($login_name_for_psvn); |
132 | attachCLRecord($login_name_for_psvn); |
| 133 | |
133 | |
| 134 | my $setNumber=&getSetNumber($psvn); |
134 | my $setNumber=&getSetNumber($psvn); |
| 135 | $setNumber = $inputs{'setNo'} if defined $inputs{'setNo'}; ## script called from profChangeDates.pl |
135 | $setNumber = $inputs{'setNo'} if defined $inputs{'setNo'}; ## script called from profChangeDates.pl |
| 136 | |
136 | |
| 137 | |
137 | # keep strict happy |
|
|
138 | my $tempTexFileBaseName; |
| 138 | |
139 | |
| 139 | ###### check to see that it is after the open date |
140 | ###### check to see that it is after the open date |
| 140 | my ($currentTime,$odts,$ddts,$remainingTime, $TimeString); |
141 | my ($currentTime,$odts,$ddts,$remainingTime, $TimeString); |
| 141 | $currentTime = time; |
142 | $currentTime = time; |
| 142 | $odts=&getOpenDate($psvn); |
143 | $odts=&getOpenDate($psvn); |
| … | |
… | |
| 244 | </SELECT> |
245 | </SELECT> |
| 245 | <BR> |
246 | <BR> |
| 246 | ENDOFHTML |
247 | ENDOFHTML |
| 247 | |
248 | |
| 248 | |
249 | |
|
|
250 | my $practiceUser = $Global::practiceUser; |
|
|
251 | if (($currentTime > $ddts) or ($User =~ /^$practiceUser/)) { |
|
|
252 | print q!<INPUT type="checkbox" name="show_old_answers" value=1> Show my old answers<BR>!; |
|
|
253 | } |
|
|
254 | else { |
|
|
255 | print q!<INPUT type="checkbox" name="show_old_answers" checked value=1> Show my old answers<BR>!; |
|
|
256 | } |
|
|
257 | |
| 249 | print &sessionKeyInputs(\%inputs); |
258 | print &sessionKeyInputs(\%inputs); |
| 250 | my $mode = $inputs{'Mode'}; |
259 | my $mode = $inputs{'Mode'}; |
| 251 | $mode = $Global::htmlModeDefault unless ($mode); |
260 | $mode = $Global::htmlModeDefault unless ($mode); |
| 252 | &displaySelectModeLine($mode); ## displays mode select buttons |
261 | &displaySelectModeLine($mode); ## displays mode select buttons |
| 253 | ## the sub displaySelectModeLine is in |
262 | ## the sub displaySelectModeLine is in |
| … | |
… | |
| 472 | # $PG_ANSWER_HASH_REF = $pt->rh_correct_answers; |
481 | # $PG_ANSWER_HASH_REF = $pt->rh_correct_answers; |
| 473 | $PG_EVALUATED_ANSWERS_REF = $pt->process_answers; |
482 | $PG_EVALUATED_ANSWERS_REF = $pt->process_answers; |
| 474 | $PG_FLAGS_REF = $pt ->rh_flags; |
483 | $PG_FLAGS_REF = $pt ->rh_flags; |
| 475 | |
484 | |
| 476 | |
485 | |
| 477 | print OUTPUT @{$PG_PROBLEM_TEXT_REF}; |
486 | # print OUTPUT @{$PG_PROBLEM_TEXT_REF}; |
| 478 | $texSource .= join '', @{$PG_PROBLEM_TEXT_REF}; |
487 | $texSource .= join '', @{$PG_PROBLEM_TEXT_REF}; |
| 479 | |
488 | |
| 480 | if (defined($PG_FLAGS_REF->{'error_flag'}) and $PG_FLAGS_REF->{'error_flag'} ==1) { |
489 | if (defined($PG_FLAGS_REF->{'error_flag'}) and $PG_FLAGS_REF->{'error_flag'} ==1) { |
| 481 | push(@PG_COMPILE_ERRORS, qq{<A HREF="#problem$probNum">$probNum</A>} ); |
490 | push(@PG_COMPILE_ERRORS, qq{<A HREF="#problem$probNum">$probNum</A>} ); |
| 482 | } |
491 | } |
| … | |
… | |
| 513 | |
522 | |
| 514 | } |
523 | } |
| 515 | |
524 | |
| 516 | $texSource .= "\\end{itemize} \\par\n"; |
525 | $texSource .= "\\end{itemize} \\par\n"; |
| 517 | } |
526 | } |
|
|
527 | if (defined($Global::WARNINGS) and $Global::WARNINGS) { |
|
|
528 | my $warnings = '{\\bf WARNINGS:\par{\\tiny ' . $Global::WARNINGS . ' }}'; |
|
|
529 | $warnings =~ s|/|\\\-/|g; #allow linebreaks in the middle of URLs |
|
|
530 | $warnings =~ s/<br>/\\par\n/ig; #introduce breaks at linebreaks and paragraphs |
|
|
531 | $warnings =~ s/<p>/\\par\n/ig; |
|
|
532 | $warnings =~ s/\#/\\\#/g; #protect against some of the symbols which are reserved in tex |
|
|
533 | $warnings =~ s/\_/\\\_/g; |
|
|
534 | $warnings =~ s/\>/\\\>/g; |
|
|
535 | $warnings =~ s/\</\\\</g; |
|
|
536 | $texSource .= $warnings; |
|
|
537 | } |
|
|
538 | $Global::WARNINGS = ''; #reset the Global::WARNINGS parameter |
| 518 | } |
539 | } |
| 519 | |
540 | |
| 520 | |
541 | |
| 521 | } |
542 | } |
| 522 | |
543 | |
| … | |
… | |
| 527 | return \$texSource, \@PG_COMPILE_ERRORS; |
548 | return \$texSource, \@PG_COMPILE_ERRORS; |
| 528 | } |
549 | } |
| 529 | |
550 | |
| 530 | ################### END main routine ################################## |
551 | ################### END main routine ################################## |
| 531 | |
552 | |
| 532 | sub downloadPS { |
553 | sub downloadAllSets { |
| 533 | my $psvn = shift; |
554 | system("/usr/bin/renice +$main::CLASS_DOWNLOAD_NICE -p $$ 1>/dev/null") && warn "Could not renice process. pid $$"; |
| 534 | my $texFile = shift; |
555 | alarm( $main::CLASS_DOWNLOAD_TIME_OUT_CONSTANT); |
| 535 | |
556 | |
|
|
557 | my $downloadMulti = "unknown"; |
|
|
558 | $downloadMulti = "multistudent" if $action eq "Get_all_copies"; |
|
|
559 | $downloadMulti = "multiset" if $action eq "Get_hard_copy"; |
|
|
560 | |
|
|
561 | my @psvns_to_download = $query->param('local_psvns'); |
|
|
562 | my $num_psvns_to_download = @psvns_to_download; |
|
|
563 | my $max_psvns_to_download = $Global::max_num_of_ps_downloads_allowed; |
|
|
564 | |
|
|
565 | if($num_psvns_to_download > 1 and $permissions != $Global::instructor_permissions) { |
|
|
566 | wwerror("Non-professors are not permitted to download more than one problem set at a time."); |
|
|
567 | } |
|
|
568 | |
|
|
569 | if(@psvns_to_download > $Global::max_num_of_ps_downloads_allowed) { |
|
|
570 | my $tooManyWhat = $downloadMulti eq "multiset" ? "problem sets" : "students"; |
|
|
571 | wwerror("Too many $tooManyWhat are selected for download.", |
|
|
572 | "The maximum number of $tooManyWhat which can be downloaded at one time is $Global::max_num_of_ps_downloads_allowed." |
|
|
573 | ." You selected $num_psvns_to_download. Go back and select fewer $tooManyWhat." |
|
|
574 | ." (This maximun is set by the variable \$max_num_of_ps_downloads_allowed in Global.pm.)"); |
|
|
575 | } |
|
|
576 | |
|
|
577 | my ($cumulativeTexSource, $currentTexSourceRef, $currentTexSource, $currentTexErrorRef); |
|
|
578 | |
|
|
579 | # this could be used when eliminating pre-foreach createTexSourceHandleErrors call |
|
|
580 | # s/\\end\{document\}.*?\\begin\{document\}/\n\\newpage\n/s; |
|
|
581 | |
|
|
582 | $tempTexFileBaseName = "${tempDirectory}Temp_downloadAllSets_$User"; |
|
|
583 | my $first_psvn = $psvns_to_download[0]; |
|
|
584 | |
|
|
585 | my $current_psvn = shift @psvns_to_download; |
| 536 | my ($texSourceRef, $errorRef) = &createTexSource($psvn); |
586 | ($currentTexSourceRef, $currentTexErrorRef) = createTexSource($current_psvn); |
| 537 | |
587 | @psvns_to_download = () if(@$currentTexErrorRef); |
| 538 | |
588 | $currentTexSource = $$currentTexSourceRef; |
| 539 | open(OUTPUT, ">${tempDirectory}${texFile}${psvn}.tex") |
589 | $currentTexSource =~ s|\\end\{document\}\s$|\n|s; |
| 540 | || wwerror("Can't create $tempDirectory${texFile}$psvn.tex\n"); |
590 | $cumulativeTexSource .= $currentTexSource; |
| 541 | print OUTPUT $$texSourceRef; |
591 | |
|
|
592 | foreach $current_psvn (@psvns_to_download) { |
|
|
593 | ($currentTexSourceRef, $currentTexErrorRef) = createTexSource($current_psvn); |
|
|
594 | @psvns_to_download = () if(@$currentTexErrorRef); |
|
|
595 | $currentTexSource = $$currentTexSourceRef; |
|
|
596 | $currentTexSource =~ s|^.*?\\begin\{document\}|\n\\newpage\n|s; |
|
|
597 | $currentTexSource =~ s|\\end\{document\}\s$|\n|s; |
|
|
598 | $cumulativeTexSource .= $currentTexSource; |
|
|
599 | } |
|
|
600 | |
|
|
601 | $cumulativeTexSource .= "\n\\end{document}\n"; |
|
|
602 | |
|
|
603 | open TEXOUTPUT, ">$tempTexFileBaseName.tex" |
|
|
604 | or wwerror("Can't open $tempTexFileBaseName.tex for output."); |
|
|
605 | print TEXOUTPUT $cumulativeTexSource; |
| 542 | close OUTPUT; |
606 | close TEXOUTPUT; |
|
|
607 | |
|
|
608 | if(@$currentTexErrorRef) { |
|
|
609 | PG_error_print($tempTexFileBaseName, $current_psvn, @$currentTexErrorRef); |
|
|
610 | } else { |
|
|
611 | $downloadType = lc $downloadType; |
|
|
612 | my $mimeType = prepareHardcopy($tempTexFileBaseName, $downloadType); |
|
|
613 | |
|
|
614 | my ($setName, $userName); |
|
|
615 | &attachProbSetRecord($first_psvn); |
|
|
616 | if($downloadMulti eq "multistudent") { |
|
|
617 | if($num_psvns_to_download == 1) { |
|
|
618 | $setName = getSetNumber($first_psvn); |
|
|
619 | $userName = getStudentLogin($first_psvn); |
|
|
620 | } else { |
|
|
621 | $setName = getSetNumber($first_psvn); |
|
|
622 | $userName = "multistudent"; |
|
|
623 | } |
|
|
624 | } elsif($downloadMulti eq "multiset") { |
|
|
625 | if($num_psvns_to_download == 1) { |
|
|
626 | $setName = getSetNumber($first_psvn); |
|
|
627 | $userName = getStudentLogin($first_psvn); |
|
|
628 | } else { |
|
|
629 | $setName = "multiset"; |
|
|
630 | $userName = getStudentLogin($first_psvn); |
|
|
631 | } |
|
|
632 | } |
|
|
633 | my $hardCopyName = "$Course.$userName.$setName.$downloadType"; |
|
|
634 | |
|
|
635 | open(TEXINPUT, "$tempTexFileBaseName.$downloadType") |
|
|
636 | or wwerror($0, "Can't open $tempTexFileBaseName.$downloadType: $!\n"); |
|
|
637 | print "Content-type: $mimeType\n"; |
|
|
638 | print "Content-disposition: attachment; filename=\"$hardCopyName\"\n\n"; |
|
|
639 | print while (<TEXINPUT>); |
|
|
640 | close TEXINPUT; |
|
|
641 | } |
|
|
642 | } |
| 543 | |
643 | |
| 544 | |
644 | sub prepareHardcopy |
| 545 | print STDERR "Finished making tex file $tempDirectory${texFile}$psvn.tex <br>\n\n" if $debugON; |
645 | { |
|
|
646 | my ($texFileBaseName, $targetFormat) = @_; |
|
|
647 | my $mimeType; |
|
|
648 | |
| 546 | # chdir "$tempDirectory"; |
649 | chdir $tempDirectory; |
| 547 | # umask(022); |
650 | |
| 548 | |
651 | my $dviCommandLine = "$Global::externalLatexPath $texFileBaseName.tex >/dev/null 2>/dev/null"; |
| 549 | # Now that the complete TeX version of the problem set has been |
652 | my $psCommandLine = "$Global::externalDvipsPath -o $texFileBaseName.ps $texFileBaseName.dvi >/dev/null 2>/dev/null"; |
| 550 | # constructed in the $tempDirectory We first attempt to convert it to |
653 | my $pdfCommandLine = "$Global::externalPs2pdfPath $texFileBaseName.ps $texFileBaseName.pdf"; |
| 551 | # postscript, first running TeX and then running dvips The system commands |
654 | |
| 552 | # for this are located in the file makePS which is in the script directory. |
655 | # make sure that you are not using old copies of the following files: |
| 553 | # If this command fails then an error is reported, otherwise &psPrint |
656 | unlink("$texFileBaseName.dvi","$texFileBaseName.ps", "$texFileBaseName.pdf"); |
| 554 | # ships the postscript file off to the client which requested the download. |
657 | |
| 555 | my @PG_COMPILE_ERRORS = @$errorRef; |
658 | if($targetFormat eq "pdf") { |
| 556 | if ( @PG_COMPILE_ERRORS ) { |
659 | #system($dviCommandLine); -e "$texFileBaseName.dvi" or die "dvi generation failed."; |
| 557 | &PG_error_print(@PG_COMPILE_ERRORS); |
660 | system($dviCommandLine); -e "$texFileBaseName.dvi" or &logPrint($texFileBaseName); |
| 558 | # $PG_COMPILE_ERRORS contains the number of the first problem with an error. |
661 | # this gives more information about pure TeX errors |
| 559 | return 'errors'; |
662 | # (i.e. the .pg file has compiled but the resulting TeX is not well formed.) |
| 560 | } |
663 | |
| 561 | else {return 'no_errors';} |
664 | # The following commands don't usually give very useful error messages anyway so just report failure. |
|
|
665 | system($psCommandLine); -e "$texFileBaseName.ps" or die "ps generation failed."; |
|
|
666 | system($pdfCommandLine); -e "$texFileBaseName.pdf" or die "pdf generation failed."; |
|
|
667 | $mimeType = "application/pdf"; |
|
|
668 | } elsif($targetFormat eq "ps") { |
|
|
669 | #system($dviCommandLine); -e "$texFileBaseName.dvi" or die "dvi generation failed."; |
|
|
670 | system($dviCommandLine); -e "$texFileBaseName.dvi" or &logPrint($texFileBaseName); |
|
|
671 | # this gives more information about pure TeX errors |
|
|
672 | # (i.e. the .pg file has compiled but the resulting TeX is not well formed.) |
|
|
673 | system($psCommandLine); -e "$texFileBaseName.ps" or die "ps generation failed."; |
|
|
674 | $mimeType = "application/postscript"; |
|
|
675 | } elsif($targetFormat eq "dvi") { |
|
|
676 | #system($dviCommandLine); -e "$texFileBaseName.dvi" or die "dvi generation failed."; |
|
|
677 | system($dviCommandLine); -e "$texFileBaseName.dvi" or &logPrint($texFileBaseName); |
|
|
678 | # this gives more information about pure TeX errors |
|
|
679 | # (i.e. the .pg file has compiled but the resulting TeX is not well formed.) |
|
|
680 | $mimeType = "application/x-dvi"; |
|
|
681 | } elsif($targetFormat eq "tex") { |
|
|
682 | $mimeType = "application/tex"; |
|
|
683 | } else { |
|
|
684 | die "unrecognized format: $targetFormat"; |
|
|
685 | } |
|
|
686 | |
|
|
687 | return $mimeType; |
| 562 | } |
688 | } |
| 563 | |
689 | |
| 564 | |
690 | sub PG_error_print |
| 565 | sub psPrint { |
691 | { |
| 566 | open(INPUT, "$tempDirectory${texFile}$psvn.ps") |
692 | my ($tempTexFileBaseName, $current_psvn, @errors) = @_; |
| 567 | or wwerror( $0, "Can't open $tempDirectory${texFile}$psvn.ps: $!\n", "", ""); |
693 | |
| 568 | |
694 | # get set name and student name from psvn |
| 569 | print "Content-disposition: attachment; filename= \"${login_name_for_psvn}_Set${setNumber}.ps\"\n"; |
695 | &attachProbSetRecord($current_psvn); |
| 570 | print "Content-type: application/postscript\n\n"; |
696 | my $userName = &getStudentLogin($current_psvn); |
|
|
697 | my $setName = &getSetNumber($current_psvn); |
|
|
698 | |
|
|
699 | # print error page header |
|
|
700 | print &htmlTOP("PG compile error"); |
|
|
701 | print "<H3>PG error while compiling problem number", (@errors>1) ? 's ' : ' ', |
|
|
702 | join(', ', @errors), " in problem set $setName for $userName.</H3>"; |
|
|
703 | print "<h3>TeX source file:</h3>"; |
|
|
704 | |
|
|
705 | # open temp tex file |
|
|
706 | if(open TEXINPUT, "$tempTexFileBaseName.tex") { |
|
|
707 | print "<pre>\n"; |
|
|
708 | my $lineNumber = 1; |
| 571 | while (<INPUT>) { |
709 | while(<TEXINPUT>) { |
| 572 | print; |
710 | if(/<A NAME/) { print $_; } |
| 573 | } |
711 | else { print protect_HTML("$lineNumber $_"), "\n"; } |
| 574 | close INPUT; |
712 | $lineNumber++; |
| 575 | print STDERR "Finished TeX $texFile for $login_name_for_psvn in $Course\n" if $debugON; |
713 | } |
| 576 | |
714 | print "</pre>\n"; |
|
|
715 | close TEXINPUT; |
|
|
716 | } else { |
|
|
717 | print "<p>Unable to open TeX source file:<br><tt>$tempTexFileBaseName.tex</tt></p>"; |
|
|
718 | } |
|
|
719 | |
|
|
720 | # print page footer |
|
|
721 | print &htmlBOTTOM("welcomeAction.pl", \%inputs); |
|
|
722 | exit; |
| 577 | } |
723 | } |
| 578 | |
724 | |
| 579 | sub pdfPrint { |
725 | # ----- |
| 580 | |
|
|
| 581 | system( "${scriptDirectory}makePDF $tempDirectory ${texFile}$psvn 1>&2" ) == 0 |
|
|
| 582 | or wwerror("$0", "Unable to create PDF output using makePDF file:<BR> ${scriptDirectory}makePDF $tempDirectory ${texFile}$psvn 1>&2<BR>Error is: $!", "", ""); |
|
|
| 583 | open(INPUT, "$tempDirectory${texFile}$psvn.pdf") |
|
|
| 584 | || wwerror("$0", "Can't open $tempDirectory${texFile}$psvn.pdf: $!\n","",""); |
|
|
| 585 | |
|
|
| 586 | print "Content-type: application/pdf\n\n" ; |
|
|
| 587 | print "Content-disposition: attachment; filename= \"${login_name_for_psvn}_Set${setNumber}.pdf\"\n"; |
|
|
| 588 | #print "Content-type: application/pdf\n\n" ; |
|
|
| 589 | while (<INPUT>) { |
|
|
| 590 | print; |
|
|
| 591 | } |
|
|
| 592 | close INPUT; |
|
|
| 593 | print STDERR "Finished TeX $texFile for $login_name_for_psvn in $Course\n" if $debugON; |
|
|
| 594 | |
|
|
| 595 | } |
|
|
| 596 | |
|
|
| 597 | sub texPrint { |
|
|
| 598 | open(INPUT, "$tempDirectory${texFile}$psvn.tex") || |
|
|
| 599 | wwerror("$0", "Can't open $tempDirectory${texFile}$psvn.tex:<BR> $!\n", "", ""); |
|
|
| 600 | |
|
|
| 601 | print "Content-disposition: attachment; filename= \"${login_name_for_psvn}_Set${setNumber}.tex\"\n"; |
|
|
| 602 | print "Content-type: application/tex\n\n"; |
|
|
| 603 | |
|
|
| 604 | while (<INPUT>) { |
|
|
| 605 | print; |
|
|
| 606 | } |
|
|
| 607 | close INPUT; |
|
|
| 608 | } |
|
|
| 609 | |
|
|
| 610 | sub dviPrint { |
|
|
| 611 | open(INPUT, "$tempDirectory${texFile}$psvn.dvi") || |
|
|
| 612 | wwerror("$0", "Can't open $tempDirectory${texFile}$psvn.dvi:<BR> $!\n", "", ""); |
|
|
| 613 | |
|
|
| 614 | print "Content-disposition: attachment; filename= \"${login_name_for_psvn}_Set${setNumber}.dvi\"\n"; |
|
|
| 615 | print "Content-type: application/x-dvi\n\n" ; |
|
|
| 616 | while (<INPUT>) { |
|
|
| 617 | print; |
|
|
| 618 | } |
|
|
| 619 | close INPUT; |
|
|
| 620 | } |
|
|
| 621 | |
726 | |
| 622 | sub logPrint { |
727 | sub logPrint { |
|
|
728 | my $texFileBaseName=shift; |
| 623 | print &htmlTOP("TeX Error or error in creating PostScript file"); |
729 | print &htmlTOP("TeX Error or error in creating PostScript file"); |
| 624 | open (LOGFILE, " $tempDirectory$texFile$psvn.log") |
730 | open (LOGFILE, " $texFileBaseName.log") |
| 625 | || print "<H3>Can't open log file:</H3> path= $tempDirectory$texFile$psvn.log<BR>$!<BR><BR>" ; |
731 | || print "<H3>Can't open log file:</H3> path= $texFileBaseName.log<BR>$!<BR><BR>" ; |
| 626 | |
732 | |
| 627 | |
733 | |
| 628 | print "<H3>TeX Error Log:</H3>"; |
734 | print "<H3>TeX Error Log:</H3>"; |
| 629 | my $print_error_switch = ($debugON) ? 1: 0; |
735 | my $print_error_switch = ($debugON) ? 1: 0; |
| 630 | my $out=''; |
736 | my $out=''; |
| … | |
… | |
| 637 | $print_error_switch = 1 if $out =~ /^!/; # after a fatal error start printing messages |
743 | $print_error_switch = 1 if $out =~ /^!/; # after a fatal error start printing messages |
| 638 | print protect_HTML($out)."<BR>\n" if $print_error_switch; |
744 | print protect_HTML($out)."<BR>\n" if $print_error_switch; |
| 639 | } |
745 | } |
| 640 | close(LOGFILE); |
746 | close(LOGFILE); |
| 641 | |
747 | |
| 642 | open (TEXFILE, "${tempDirectory}${texFile}${psvn}.tex") |
748 | open (TEXFILE, "$texFileBaseName.tex") |
| 643 | || print "<H3>Can't open tex source file:</H3> path= ${tempDirectory}${texFile}${psvn}.tex:<BR> $!<BR><BR>\n"; |
749 | || print "<H3>Can't open tex source file:</H3> path= $texFileBaseName.tex:<BR> $!<BR><BR>\n"; |
| 644 | print "<BR>\n<H3>TeX Source File:</H3><BR>\n"; |
750 | print "<BR>\n<H3>TeX Source File:</H3><BR>\n"; |
| 645 | print "<PRE>"; |
751 | print "<PRE>"; |
| 646 | |
752 | |
| 647 | my $lineNumber = 1; |
753 | my $lineNumber = 1; |
| 648 | while (<TEXFILE>) { |
754 | while (<TEXFILE>) { |
| 649 | print protect_HTML("$lineNumber $_")."\n"; |
755 | print protect_HTML("$lineNumber $_")."\n"; |
| 650 | $lineNumber++; |
756 | $lineNumber++; |
| 651 | } |
757 | } |
| 652 | close(TEXFILE); |
758 | close(TEXFILE); |
| 653 | print "</PRE>"; |
759 | print "</PRE>"; |
| 654 | print &htmlBOTTOM("downloadPS.pl", \%inputs); |
760 | print &htmlBOTTOM("welcomeAction.pl", \%inputs); |
| 655 | } |
761 | } |
| 656 | sub protect_HTML { |
762 | sub protect_HTML { |
| 657 | my $line = shift; |
763 | my $line = shift; |
| 658 | chomp($line); |
764 | chomp($line); |
| 659 | $line =~s/\&/&/g; |
765 | $line =~s/\&/&/g; |
| 660 | $line =~s/</</g; |
766 | $line =~s/</</g; |
| 661 | $line =~s/>/>/g; |
767 | $line =~s/>/>/g; |
| 662 | $line; |
768 | $line; |
| 663 | } |
769 | } |
| 664 | sub PG_error_print { |
|
|
| 665 | my @probNums = @_; |
|
|
| 666 | open (TEXFILE, "${tempDirectory}${texFile}${psvn}.tex") |
|
|
| 667 | || ! $debugON || print STDERR "Can't open $tempDirectory$texFile$psvn.tex" ; |
|
|
| 668 | print &htmlTOP("PG compile error"); |
|
|
| 669 | print "<H3>PG error while compiling problem number", |
|
|
| 670 | (@probNums>1) ? 's ' : ' ', |
|
|
| 671 | join(',', @probNums), |
|
|
| 672 | "</H3>"; |
|
|
| 673 | print "(Search for "ERROR" to find the line where the error occurs.)"; |
|
|
| 674 | print "<H3>TeX Source File:</H3>"; |
|
|
| 675 | print "<PRE>"; |
|
|
| 676 | my $lineNumber = 1; |
|
|
| 677 | local($/) = "\n"; |
|
|
| 678 | while (<TEXFILE>) { |
|
|
| 679 | if ( $_ =~/^<A NAME/ ) { # skip lines starting with a destination anchor |
|
|
| 680 | print $_; |
|
|
| 681 | } else { |
|
|
| 682 | print protect_HTML("$lineNumber $_")."\n"; |
|
|
| 683 | } |
|
|
| 684 | $lineNumber++; |
|
|
| 685 | } |
|
|
| 686 | close(TEXFILE); |
|
|
| 687 | print &htmlBOTTOM("downloadPS.pl", \%inputs); |
|
|
| 688 | } |
|
|
| 689 | |
|
|
| 690 | sub selectionError { |
770 | sub selectionError { |
| 691 | print &htmlTOP("Selection error"); |
771 | print &htmlTOP("Selection error"); |
| 692 | print"<H2>Error:</H2> You must first select a problem set in order to download a hard copy!\n"; |
772 | print"<H2>Error:</H2> You must first select a problem set in order to download a hard copy!\n"; |
| 693 | print "<FORM METHOD=POST ACTION=\"${Global::cgiWebworkURL}welcome.pl\"><P>"; |
773 | print "<FORM METHOD=POST ACTION=\"${Global::cgiWebworkURL}welcome.pl\"><P>"; |
| 694 | print &sessionKeyInputs(\%inputs); |
774 | print &sessionKeyInputs(\%inputs); |
| … | |
… | |
| 748 | </TD> |
828 | </TD> |
| 749 | </TABLE> |
829 | </TABLE> |
| 750 | }; |
830 | }; |
| 751 | $title_bar; |
831 | $title_bar; |
| 752 | } |
832 | } |
| 753 | |
|
|
| 754 | sub downloadIndividualSet { |
|
|
| 755 | system("/usr/bin/renice +$main::DOWNLOAD_NICE -p $$ 1>/dev/null") && warn "Could not renice process. pid $$"; |
|
|
| 756 | alarm( $main::DOWNLOAD_TIME_OUT_CONSTANT); |
|
|
| 757 | my $return_status=''; |
|
|
| 758 | eval {$return_status = downloadPS($psvn,$texFile)}; ## trap any errors |
|
|
| 759 | $save_errors=$@; ## errors will be printed out by END |
|
|
| 760 | if ($return_status eq 'errors') {exit;} |
|
|
| 761 | elsif ($return_status eq 'no_errors') { |
|
|
| 762 | if ($downloadType eq "TeX" ) { |
|
|
| 763 | &texPrint; |
|
|
| 764 | } |
|
|
| 765 | elsif (system( "${scriptDirectory}makePS $tempDirectory $texFile$psvn 1>&2" )) { |
|
|
| 766 | &logPrint; |
|
|
| 767 | # wwerror("$0", "downloadPS: Error in creating postscript file. <BR> |
|
|
| 768 | # System command ${scriptDirectory}makePS $tempDirectory $texFile$psvn 1>&2", "", ""); |
|
|
| 769 | } |
|
|
| 770 | else { # tex file has been processed successfully |
|
|
| 771 | if ($downloadType eq 'pdf') {&pdfPrint;} |
|
|
| 772 | elsif ($downloadType eq 'dvi') {&dviPrint;} |
|
|
| 773 | else {&psPrint;} |
|
|
| 774 | } |
|
|
| 775 | } |
|
|
| 776 | else {wwerror($0, "The subroutine downloadPS returned an unknown status");} |
|
|
| 777 | } |
|
|
| 778 | |
|
|
| 779 | sub downloadAllSets { |
|
|
| 780 | system("/usr/bin/renice +$main::CLASS_DOWNLOAD_NICE -p $$ 1>/dev/null") && warn "Could not renice process. pid $$"; |
|
|
| 781 | alarm( $main::CLASS_DOWNLOAD_TIME_OUT_CONSTANT); |
|
|
| 782 | my $localpsvn; ## psvn numbers for individual students |
|
|
| 783 | my $return_status=''; |
|
|
| 784 | my $texSource =''; |
|
|
| 785 | my $individualTexSource =''; |
|
|
| 786 | my ($texSourceRef, $errorRef); |
|
|
| 787 | |
|
|
| 788 | my @local_psvns = $query -> param('local_psvns'); |
|
|
| 789 | |
|
|
| 790 | my $max = $Global::max_num_of_ps_downloads_allowed; |
|
|
| 791 | |
|
|
| 792 | ## make sure non professors can not download more than one set by submitting an altered form |
|
|
| 793 | @local_psvns = ($local_psvns[0]) unless $permissions == $Global::instructor_permissions; |
|
|
| 794 | |
|
|
| 795 | my $length = @local_psvns; |
|
|
| 796 | |
|
|
| 797 | if ($length > $max) { |
|
|
| 798 | wwerror ("Too many students selected", "The maximun number of sets which can be downloaded at one time is $max. You selected $length. |
|
|
| 799 | Go back and select fewer students. This maximun is set by the variable |
|
|
| 800 | \$max_num_of_ps_downloads_allowed in Global.pm."); |
|
|
| 801 | } |
|
|
| 802 | $localpsvn = shift @local_psvns; ## get first set which will contain TeX header info |
|
|
| 803 | # attachProbSetRecord($localpsvn); |
|
|
| 804 | ($texSourceRef, $errorRef) = &createTexSource($localpsvn); |
|
|
| 805 | ## don't do anything with $errorRef at this time |
|
|
| 806 | ## only contains prob numbers of bad problems |
|
|
| 807 | $texSource = $$texSourceRef; ## contains initial header info |
|
|
| 808 | $texSource =~ s|\\end\{document\}\s$|\n|s; ## remove end{document} statement |
|
|
| 809 | |
|
|
| 810 | foreach $localpsvn (@local_psvns) { ## get the rest of the sets and strip TeX header info |
|
|
| 811 | # attachProbSetRecord($localpsvn); |
|
|
| 812 | ($texSourceRef, $errorRef) = &createTexSource($localpsvn); |
|
|
| 813 | ## don't do anything with $errorRef at this time |
|
|
| 814 | ## only contains prob numbers of bad problems |
|
|
| 815 | $individualTexSource = $$texSourceRef; |
|
|
| 816 | $individualTexSource =~ s|^.*?\\begin\{document\}|\n\\newpage\n|s; ## remove header material and start new page |
|
|
| 817 | $individualTexSource =~ s|\\end\{document\}\s$|\n|s; ## remove end{document} statement |
|
|
| 818 | $texSource .= $individualTexSource; |
|
|
| 819 | } |
|
|
| 820 | $texSource .= "\n\\end{document}\n"; ## append end{document} statement |
|
|
| 821 | |
|
|
| 822 | $psvn = -1; |
|
|
| 823 | $texFile = "set${setNumber}.tempTex-CGIscript"; |
|
|
| 824 | $login_name_for_psvn = 'all_students'; |
|
|
| 825 | |
|
|
| 826 | open(OUTPUT, ">${tempDirectory}${texFile}${psvn}.tex") |
|
|
| 827 | || wwerror("Can't create $tempDirectory${texFile}$psvn.tex\n"); |
|
|
| 828 | print OUTPUT $texSource; |
|
|
| 829 | close OUTPUT; |
|
|
| 830 | |
|
|
| 831 | if ($downloadType eq "TeX" ) { |
|
|
| 832 | &texPrint; |
|
|
| 833 | } |
|
|
| 834 | elsif (system( "${scriptDirectory}makePS $tempDirectory $texFile$psvn 1>&2" )) { |
|
|
| 835 | &logPrint; |
|
|
| 836 | } |
|
|
| 837 | else { # tex file has been processed successfully |
|
|
| 838 | if ($downloadType eq 'pdf') {&pdfPrint;} |
|
|
| 839 | elsif ($downloadType eq 'dvi') {&dviPrint;} |
|
|
| 840 | else {&psPrint;} |
|
|
| 841 | } |
|
|
| 842 | } |
|
|
| 843 | |
|
|
| 844 | |
|
|
| 845 | |
|
|
| 846 | |
833 | |
| 847 | sub hackerError { ## prints hacker error message |
834 | sub hackerError { ## prints hacker error message |
| 848 | |
835 | |
| 849 | my $msg = "Attempt to hack into WeBWorK \n Remote Host is: ". remote_host()."\n"; |
836 | my $msg = "Attempt to hack into WeBWorK \n Remote Host is: ". remote_host()."\n"; |
| 850 | $msg .= query_string; |
837 | $msg .= query_string; |
| … | |
… | |
| 947 | $envir{'htmlURL'} = getCourseHtmlURL(); |
934 | $envir{'htmlURL'} = getCourseHtmlURL(); |
| 948 | $envir{'tempDirectory'} = getCourseTempDirectory(); |
935 | $envir{'tempDirectory'} = getCourseTempDirectory(); |
| 949 | $envir{'tempURL'} = getCourseTempURL(); |
936 | $envir{'tempURL'} = getCourseTempURL(); |
| 950 | $envir{'scriptDirectory'} = $Global::scriptDirectory; |
937 | $envir{'scriptDirectory'} = $Global::scriptDirectory; |
| 951 | $envir{'webworkDocsURL'} = $Global::webworkDocsURL; |
938 | $envir{'webworkDocsURL'} = $Global::webworkDocsURL; |
|
|
939 | $envir{'externalTTHPath'} = $Global::externalTTHPath; |
| 952 | |
940 | |
| 953 | |
941 | |
| 954 | $envir{'inputs_ref'} = \%inputs; |
942 | $envir{'inputs_ref'} = \%inputs; |
| 955 | |
943 | |
| 956 | |
944 | |
| … | |
… | |
| 976 | unless (defined($action ) and ($action eq 'Do problem set' or $action eq 'Do_problem_set')) { |
964 | unless (defined($action ) and ($action eq 'Do problem set' or $action eq 'Do_problem_set')) { |
| 977 | my $ERRORS = $save_errors; |
965 | my $ERRORS = $save_errors; |
| 978 | unless ($debugON) { #clean up the directory |
966 | unless ($debugON) { #clean up the directory |
| 979 | eval { |
967 | eval { |
| 980 | chdir $tempDirectory; |
968 | chdir $tempDirectory; |
| 981 | unlink("$texFile$psvn.dvi", "$texFile$psvn.ps","$texFile$psvn.pdf", |
969 | unlink( |
| 982 | "$texFile$psvn.log", "$texFile$psvn.aux", |
970 | "#tempTexFileBaseName.dvi", |
|
|
971 | "$tempTexFileBaseName.ps", |
|
|
972 | "$tempTexFileBaseName.pdf", |
|
|
973 | "$tempTexFileBaseName.log", |
|
|
974 | "$tempTexFileBaseName.aux", |
| 983 | "$texFile$psvn.tex",); |
975 | "$tempTexFileBaseName.tex" |
|
|
976 | ); |
| 984 | unlink("${tempDirectory}eps/${login_name_for_psvn}*.eps"); |
977 | unlink("${tempDirectory}eps/${login_name_for_psvn}*.eps"); |
| 985 | }; # clean up |
978 | }; # clean up |
| 986 | $ERRORS .= $ERRORS . $@; |
979 | $ERRORS .= $ERRORS . $@; |
| 987 | } |
980 | } |
| 988 | my $query = query_string(); |
981 | my $query = query_string(); |
| … | |
… | |
| 1058 | } |
1051 | } |
| 1059 | # end Timing code |
1052 | # end Timing code |
| 1060 | cleanup_downloadPS(); |
1053 | cleanup_downloadPS(); |
| 1061 | } |
1054 | } |
| 1062 | |
1055 | |
| 1063 | |
|
|
| 1064 | ######## DEBUGGING TOOLS |
|
|
| 1065 | |
|
|
| 1066 | # sub downloadPS_dumpvar { |
|
|
| 1067 | # my ($packageName) = @_; |
|
|
| 1068 | # |
|
|
| 1069 | # local(*alias); |
|
|
| 1070 | # |
|
|
| 1071 | # |
|
|
| 1072 | # *stash = *{"${packageName}::"}; |
|
|
| 1073 | # $, = " "; |
|
|
| 1074 | # |
|
|
| 1075 | # print OUTPUT "Content-type: text/html\n\n<PRE>\n"; |
|
|
| 1076 | # |
|
|
| 1077 | # |
|
|
| 1078 | # while ( ($varName, $globValue) = each %stash) { |
|
|
| 1079 | # print OUTPUT "$varName =================================\n"; |
|
|
| 1080 | # |
|
|
| 1081 | # *alias = $globValue; |
|
|
| 1082 | # next if $varName=~/main/; |
|
|
| 1083 | # next unless $varName =~/::/; |
|
|
| 1084 | # |
|
|
| 1085 | # if (defined($alias) ) { |
|
|
| 1086 | # print OUTPUT "\t \$$varName $alias \n"; |
|
|
| 1087 | # } |
|
|
| 1088 | # |
|
|
| 1089 | # if ( defined(@alias) ) { |
|
|
| 1090 | # print OUTPUT "\t \@$varName @alias \n"; |
|
|
| 1091 | # } |
|
|
| 1092 | # if (defined(%alias) ) { |
|
|
| 1093 | # print OUTPUT "\t \%$varName \n"; |
|
|
| 1094 | # foreach $key (keys %alias) { |
|
|
| 1095 | # print OUTPUT "\t\t $key => $alias{$key}\n"; |
|
|
| 1096 | # } |
|
|
| 1097 | # |
|
|
| 1098 | # |
|
|
| 1099 | # } |
|
|
| 1100 | # } |
|
|
| 1101 | # |
|
|
| 1102 | # |
|
|
| 1103 | # |
|
|
| 1104 | # } |
|
|
| 1105 | |
|
|
| 1106 | |
|
|
| 1107 | 1; |
1056 | 1; |