[system] / branches / rel-2-2-dev / webwork-modperl / lib / WeBWorK / ContentGenerator / Hardcopy.pm Repository:
ViewVC logotype

Annotation of /branches/rel-2-2-dev/webwork-modperl/lib/WeBWorK/ContentGenerator/Hardcopy.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 738 - (view) (download) (as text)
Original Path: trunk/webwork-modperl/lib/WeBWorK/ContentGenerator/Hardcopy.pm

1 : sh002i 478 ################################################################################
2 : sh002i 494 # WeBWorK mod_perl (c) 2000-2002 WeBWorK Project
3 : sh002i 478 # $Id$
4 :     ################################################################################
5 :    
6 :     package WeBWorK::ContentGenerator::Hardcopy;
7 :    
8 :     =head1 NAME
9 :    
10 : sh002i 641 WeBWorK::ContentGenerator::Hardcopy - generate a PDF version of one or more
11 : sh002i 478 problem sets.
12 :    
13 :     =cut
14 :    
15 :     use strict;
16 :     use warnings;
17 :     use base qw(WeBWorK::ContentGenerator);
18 :     use CGI qw();
19 : sh002i 502 use File::Path qw(rmtree);
20 :     use File::Temp qw(tempdir);
21 :     use WeBWorK::DB::Classlist;
22 :     use WeBWorK::DB::WW;
23 : sh002i 478 use WeBWorK::Form;
24 :     use WeBWorK::Utils qw(readFile);
25 :    
26 : sh002i 737 sub go {
27 :     my ($self, $singleSet) = @_;
28 : sh002i 641
29 :     my $r = $self->{r};
30 : sh002i 502 my $ce = $self->{courseEnvironment};
31 : sh002i 737 my @sets = $r->param("hcSet");
32 :     my @users = $r->param("hcUser");
33 : sh002i 641
34 : sh002i 737 # add singleSet to the list of sets
35 : sh002i 641 if (length $singleSet > 0) {
36 :     $singleSet =~ s/^set//;
37 : sh002i 737 unshift @sets, $singleSet unless grep { $_ eq $singleSet } @sets;
38 : sh002i 641 }
39 :    
40 : sh002i 737 # default user is the effectiveUser
41 :     unless (@users) {
42 :     unshift @users, $r->param("effectiveUser");
43 :     }
44 :    
45 :     $self->{cldb} = WeBWorK::DB::Classlist->new($ce);
46 :     $self->{authdb} = WeBWorK::DB::Auth->new($ce);
47 :     $self->{wwdb} = WeBWorK::DB::WW->new($ce);
48 :     $self->{user} = $self->{cldb}->getUser($r->param("user"));
49 :     $self->{permissionLevel} = $self->{authdb}->getPermissions($r->param("user"));
50 :     $self->{effectiveUser} = $self->{cldb}->getUser($r->param("effectiveUser"));
51 :     $self->{sets} = \@sets;
52 :     $self->{users} = \@users;
53 :     $self->{errors} = [];
54 : sh002i 641 $self->{warnings} = [];
55 : sh002i 737
56 : sh002i 738 # security checks
57 : sh002i 737 my $multiSet = $self->{permissionLevel} > 0;
58 :     my $multiUser = $self->{permissionLevel} > 0;
59 :     if (@sets > 1 and not $multiSet) {
60 :     $self->{generationError} = ["SIMPLE", "You are not permitted to generate hardcopy for multiple sets. Please select a single set and try again."];
61 :     }
62 :     if (@users > 1 and not $multiUser) {
63 :     $self->{generationError} = ["SIMPLE", "You are not permitted to generate hardcopy for multiple users. Please select a single user and try again."];
64 :     }
65 :     if ($users[0] ne $self->{effectiveUser}->id and not $multiUser) {
66 :     $self->{generationError} = ["SIMPLE", "You are not permitted to generate hardcopy for other users."];
67 :     }
68 :    
69 :     unless ($self->{generationError}) {
70 :     if ($r->param("generateHardcopy")) {
71 :     my ($tempDir, $fileName) = eval { $self->generateHardcopy() };
72 :     if ($@) {
73 :     $self->{generationError} = $@;
74 :     } else {
75 :     my $filePath = "$tempDir/$fileName";
76 :    
77 :     $r->content_type("application/x-pdf");
78 :     # as per RFC2183:
79 :     $r->header_out("Content-Disposition", "attachment; filename=$fileName");
80 :     $r->send_http_header();
81 :    
82 :     local *INPUTFILE;
83 :     open INPUTFILE, "<", $filePath
84 :     or die "Failed to read $filePath: $!";
85 :     my $buf;
86 :     while (read INPUTFILE, $buf, 16384) {
87 :     print $buf;
88 :     }
89 :     close INPUTFILE;
90 :    
91 :     return;
92 :     }
93 :     }
94 :     }
95 :    
96 :     $r->content_type("text/html");
97 :     $r->send_http_header();
98 :     $self->template($ce->{templates}->{system}, $singleSet);
99 : sh002i 502 }
100 :    
101 : sh002i 737 # -----
102 :    
103 : sh002i 502 sub path {
104 :     my ($self, undef, $args) = @_;
105 :    
106 :     my $ce = $self->{courseEnvironment};
107 :     my $root = $ce->{webworkURLs}->{root};
108 :     my $courseName = $ce->{courseName};
109 :     return $self->pathMacro($args,
110 :     "Home" => "$root",
111 :     $courseName => "$root/$courseName",
112 :     "Hardcopy Generator" => "",
113 :     );
114 :     }
115 :    
116 :     sub title {
117 : sh002i 547 return "Hardcopy Generator";
118 : sh002i 502 }
119 :    
120 :     sub body {
121 : sh002i 641 my $self = shift;
122 : sh002i 478
123 : sh002i 737 if ($self->{generationError}) {
124 :     if (ref $self->{generationError} eq "ARRAY") {
125 :     my ($disposition, @rest) = @{$self->{generationError}};
126 :     if ($disposition eq "PGFAIL") {
127 :     print $self->multiErrorOutput(@{$self->{errors}});
128 :     return "";
129 :     } elsif ($disposition eq "FAIL") {
130 :     print $self->errorOutput(@rest);
131 :     return "";
132 :     } elsif ($disposition eq "RETRY") {
133 :     print $self->errorOutput(@rest);
134 :     } else { # a "simple" error
135 :     print CGI::p(CGI::font({-color=>"red"}, @rest));
136 : sh002i 669 }
137 :     } else {
138 : sh002i 737 # not something we were expecting...
139 :     die $self->{generationError};
140 : sh002i 669 }
141 : sh002i 737 }
142 :     $self->displayForm();
143 :     }
144 : sh002i 669
145 : sh002i 737 sub multiErrorOutput($@) {
146 :     my ($self, @errors) = @_;
147 :    
148 :     print CGI::h2("Software Errors");
149 :     print CGI::p(<<EOF);
150 : sh002i 641 WeBWorK has encountered one or more software errors while attempting to process these sets.
151 :     It is likely that there are error(s) in the problem itself.
152 :     If you are a student, contact your professor to have the error(s) corrected.
153 :     If you are a professor, please consut the error output below for more informaiton.
154 :     EOF
155 : sh002i 737 foreach my $error (@errors) {
156 :     print CGI::h3("Set: ", $error->{set}, ", Problem: ", $error->{problem});
157 :     print CGI::h4("Error messages"), CGI::blockquote(CGI::pre($error->{message}));
158 :     print CGI::h4("Error context"), CGI::blockquote(CGI::pre($error->{context}));
159 :     }
160 :     }
161 : sh002i 669
162 : sh002i 737 # -----
163 : sh002i 669
164 : sh002i 737 sub displayForm($) {
165 :     my $self = shift;
166 :     my $r = $self->{r};
167 :    
168 :     print CGI::start_p(), "Select the problem sets for which to generate hardcopy versions.";
169 :     if ($self->{permissionLevel} > 0) {
170 :     print "You may also select multiple users from the users list. You will receive hardcopy for each (set, user) pair.";
171 :     }
172 :     print CGI::end_p();
173 :    
174 :     print CGI::start_form(-method=>"POST", -action=>$r->uri);
175 :     print $self->hidden_authen_fields();
176 : sh002i 738 warn "showHints=", $r->param("showHints"), "\n";
177 :     print CGI::p(
178 :     CGI::checkbox(
179 :     -name => "showCorrectAnswers",
180 :     -checked => $r->param("showCorrectAnswers") || 0,
181 :     -label => "Correct answers",
182 :     ), CGI::br(),
183 :     CGI::checkbox(
184 :     -name => "showHints",
185 :     -checked => $r->param("showHints") || 0,
186 :     -label => "Hints",
187 :     ), CGI::br(),
188 :     CGI::checkbox(
189 :     -name => "showSolutions",
190 :     -checked => $r->param("showSolutions") || 0,
191 :     -label => "Solutions",
192 :     ),
193 :     );
194 : sh002i 737 print CGI::start_table({-width=>"100%"}), CGI::start_Tr({-valign=>"top"});
195 :    
196 :     my $multiSet = $self->{permissionLevel} > 0;
197 :     my $multiUser = $self->{permissionLevel} > 0;
198 :    
199 :     # set selection menu
200 :     {
201 :     print CGI::start_td();
202 :     print CGI::h3("Sets");
203 :     print CGI::start_table();
204 :     my @sets;
205 :     push @sets, $self->{wwdb}->getSet($self->{effectiveUser}->id, $_)
206 :     foreach ($self->{wwdb}->getSets($self->{effectiveUser}->id));
207 :     @sets = sort { $a->id cmp $b->id } @sets;
208 :     foreach my $set (@sets) {
209 :     my $checked = grep { $_ eq $set->id } @{$self->{sets}};
210 :     my $control;
211 :     if (time < $set->open_date) {
212 :     $control = "";
213 :     } else {
214 :     if ($multiSet) {
215 :     $control = CGI::checkbox(
216 :     -name=>"hcSet",
217 :     -value=>$set->id,
218 :     -label=>"",
219 :     -checked=>$checked
220 :     );
221 :     } else {
222 :     $control = CGI::radio_group(
223 :     -name=>"hcSet",
224 :     -values=>[$set->id],
225 :     -default=>($checked ? $set->id : "-"),
226 :     -labels=>{$set->id => ""}
227 :     );
228 :     }
229 : sh002i 669 }
230 : sh002i 737 print CGI::Tr(CGI::td([
231 :     $control,
232 :     $set->id,
233 :     ]));
234 : sh002i 641 }
235 : sh002i 737 print CGI::end_table();
236 :     print CGI::end_td();
237 : sh002i 641 }
238 :    
239 : sh002i 737 # user selection menu
240 :     if ($multiUser) {
241 :     print CGI::start_td();
242 :     print CGI::h3("Users");
243 :     print CGI::start_table();
244 :     #print CGI::Tr(
245 :     # CGI::td(CGI::checkbox(-name=>"hcAllUsers", -value=>"1", -label=>"")),
246 :     # CGI::td({-colspan=>"2"}, "All Users"),
247 :     #);
248 :     #print CGI::Tr(CGI::td({-colspan=>"3"}, "&nbsp;"));
249 :     my @users;
250 :     push @users, $self->{cldb}->getUser($_)
251 :     foreach ($self->{cldb}->getUsers());
252 :     @users = sort { $a->last_name cmp $b->last_name } @users;
253 :     foreach my $user (@users) {
254 :     my $checked = grep { $_ eq $user->id } @{$self->{users}};
255 :     print CGI::Tr(CGI::td([
256 :     CGI::checkbox(-name=>"hcUser", -value=>$user->id, -label=>"", -checked=>$checked),
257 :     $user->id,
258 :     $user->last_name.", ".$user->first_name,
259 :     ]));
260 :     }
261 :     print CGI::end_table();
262 :     print CGI::end_td();
263 :     }
264 : sh002i 669
265 : sh002i 737 print CGI::end_Tr(), CGI::end_table();
266 :     print CGI::p({-align=>"center"},
267 :     CGI::submit(-name=>"generateHardcopy", -label=>"Generate Hardcopy"));
268 :     print CGI::end_form();
269 :    
270 : sh002i 641 return "";
271 : sh002i 502 }
272 :    
273 : sh002i 737 sub generateHardcopy($) {
274 :     my $self = shift;
275 :     my @sets = @{$self->{sets}};
276 :     my @users = @{$self->{users}};
277 :     my $multiSet = $self->{permissionLevel} > 0;
278 :     my $multiUser = $self->{permissionLevel} > 0;
279 :     # sanity checks
280 :     unless (@sets) {
281 :     die ["RETRY", "No sets were specified."];
282 :     }
283 :     unless (@users) {
284 :     die ["RETRY", "No users were specified."];
285 :     }
286 :    
287 :     # determine where hardcopy is going to go
288 :     #my $tempDir = $self->{courseEnvironment}->{courseDirs}->{html_temp} . "/hardcopy";
289 :     my $tempDir = tempdir("webwork-hardcopy-XXXXXXXX", TMPDIR => 1);
290 :    
291 :     # make sure tempDir exists
292 :     #unless (-e $tempDir) {
293 :     # if (system "mkdir", "-p", $tempDir) {
294 :     # die ["FAIL", "Failed to mkdir $tempDir", $!];
295 :     # }
296 :     #}
297 :    
298 :     # determine name of PDF file
299 :     my $courseName = $self->{courseEnvironment}->{courseName};
300 :     my $fileNameSet = (@sets > 1 ? "multiset" : $sets[0]);
301 :     my $fileNameUser = (@users > 1 ? "multiuser" : $users[0]);
302 :     my $fileName = "$courseName.$fileNameUser.$fileNameSet.pdf";
303 :    
304 :     # for each user ... generate TeX for each set
305 :     my $tex;
306 :     foreach my $user (@users) {
307 :     $tex .= $self->getMultiSetTeX(@sets);
308 :     }
309 :    
310 :     # deal with PG errors
311 :     if (@{$self->{errors}}) {
312 :     die ["PGFAIL"];
313 :     }
314 :    
315 :     # "try" to generate pdf
316 :     eval { $self->latex2pdf($tex, $tempDir, $fileName) };
317 :     if ($@) {
318 :     die ["FAIL", "Failed to generate PDF from tex", $@];
319 :     }
320 :    
321 :     return $tempDir, $fileName;
322 :     }
323 :    
324 : sh002i 641 # -----
325 :    
326 : sh002i 502 sub latex2pdf {
327 :     # this is a little ad-hoc function which I will replace with a LaTeX
328 :     # module at some point (or put it in Utils).
329 :     my ($self, $tex, $fileBase, $fileName) = @_;
330 :     my $finalFile = "$fileBase/$fileName";
331 : sh002i 492 my $ce = $self->{courseEnvironment};
332 : sh002i 502
333 :     # create a temporary directory for tex to shit in
334 :     my $wd = tempdir("webwork-hardcopy-XXXXXXXX", TMPDIR => 1);
335 :     my $texFile = "$wd/hardcopy.tex";
336 :     my $pdfFile = "$wd/hardcopy.pdf";
337 : sh002i 562 my $logFile = "$wd/hardcopy.log";
338 : sh002i 502
339 :     # write the tex file
340 :     local *TEX;
341 : sh002i 641 open TEX, ">", $texFile or die "Failed to open $texFile: $!\n";
342 : sh002i 502 print TEX $tex;
343 :     close TEX;
344 :    
345 :     # call pdflatex - we don't want to chdir in the mod_perl process, as
346 :     # that might step on the feet of other things (esp. in Apache 2.0)
347 : sh002i 492 my $pdflatex = $ce->{externalPrograms}->{pdflatex};
348 : sh002i 641 system "cd $wd && $pdflatex $texFile" and die "Failed to call pdflatex: $!\n";
349 : sh002i 478
350 : sh002i 502 if (-e $pdfFile) {
351 :     # move resulting PDF file to appropriate location
352 : sh002i 641 system "/bin/mv", $pdfFile, $finalFile and die "Failed to mv: $!\n";
353 : sh002i 502 }
354 :    
355 :     # remove temporary directory
356 : sh002i 616 rmtree($wd, 0, 1);
357 : sh002i 502
358 : sh002i 641 -e $finalFile or die "Failed to create $finalFile for no apparent reason.\n";
359 : sh002i 478 }
360 :    
361 : sh002i 502 # -----
362 :    
363 : sh002i 737 sub texBlockComment(@) { return "\n".("%"x80)."\n%% ".join("", @_)."\n".("%"x80)."\n\n"; }
364 :    
365 : sh002i 502 sub getMultiSetTeX {
366 : sh002i 492 my ($self, @sets) = @_;
367 :     my $ce = $self->{courseEnvironment};
368 : sh002i 502 my $tex = "";
369 : sh002i 492
370 : sh002i 502 # the document preamble
371 :     $tex .= $self->texInclude($ce->{webworkFiles}->{hardcopySnippets}->{preamble});
372 : sh002i 492
373 : sh002i 641 while (defined (my $setName = shift @sets)) {
374 :     $tex .= $self->getSetTeX($setName);
375 : sh002i 492 if (@sets) {
376 :     # divide sets, but not after the last set
377 : sh002i 502 $tex .= $self->texInclude($ce->{webworkFiles}->{hardcopySnippets}->{setDivider});
378 : sh002i 492 }
379 :     }
380 :    
381 : sh002i 502 # the document postamble
382 :     $tex .= $self->texInclude($ce->{webworkFiles}->{hardcopySnippets}->{postamble});
383 :    
384 :     return $tex;
385 : sh002i 492 }
386 :    
387 : sh002i 478 sub getSetTeX {
388 :     my ($self, $setName) = @_;
389 :     my $ce = $self->{courseEnvironment};
390 :     my $wwdb = $self->{wwdb};
391 : sh002i 737 my $effectiveUserName = $self->{effectiveUser}->id;
392 : malsyned 722 my @problemNumbers = sort { $a <=> $b } $wwdb->getProblems($effectiveUserName, $setName);
393 : sh002i 478
394 : sh002i 492 # get header and footer
395 : malsyned 722 my $setHeader = $wwdb->getSet($effectiveUserName, $setName)->set_header
396 : sh002i 492 || $ce->{webworkFiles}->{hardcopySnippets}->{setHeader};
397 :     # database doesn't support the following yet :(
398 : malsyned 722 #my $setFooter = $wwdb->getSet($effectiveUserName, $setName)->set_footer
399 : sh002i 492 # || $ce->{webworkFiles}->{hardcopySnippets}->{setFooter};
400 : sh002i 502 # so we don't allow per-set customization, which is probably okay :)
401 :     my $setFooter = $ce->{webworkFiles}->{hardcopySnippets}->{setFooter};
402 : sh002i 478
403 : sh002i 502 my $tex = "";
404 :    
405 : sh002i 492 # render header
406 : sh002i 502 $tex .= texBlockComment("BEGIN $setName : $setHeader");
407 : sh002i 547 $tex .= $self->getProblemTeX($setName, 0, $setHeader);
408 : sh002i 478
409 :     # render each problem
410 : sh002i 492 while (my $problemNumber = shift @problemNumbers) {
411 : sh002i 502 $tex .= texBlockComment("BEGIN $setName : $problemNumber");
412 :     $tex .= $self->getProblemTeX($setName, $problemNumber);
413 : sh002i 492 if (@problemNumbers) {
414 :     # divide problems, but not after the last problem
415 : sh002i 502 $tex .= $self->texInclude($ce->{webworkFiles}->{hardcopySnippets}->{problemDivider});
416 : sh002i 492 }
417 : sh002i 478 }
418 :    
419 : sh002i 492 # render footer
420 : sh002i 502 $tex .= texBlockComment("BEGIN $setName : $setFooter");
421 :     $tex .= $self->getProblemTeX($setName, 0, $setFooter);
422 :    
423 :     return $tex;
424 : sh002i 478 }
425 :    
426 :     sub getProblemTeX {
427 : sh002i 502 my ($self, $setName, $problemNumber, $pgFile) = @_;
428 : sh002i 478 my $r = $self->{r};
429 :     my $ce = $self->{courseEnvironment};
430 :    
431 : sh002i 738 my $wwdb = $self->{wwdb};
432 :     my $cldb = $self->{cldb};
433 :     my $authdb = $self->{authdb};
434 : sh002i 737 my $effectiveUser = $self->{effectiveUser};
435 : sh002i 738 my $permissionLevel = $self->{permissionLevel};
436 : malsyned 722 my $set = $wwdb->getSet($effectiveUser->id, $setName);
437 :     my $psvn = $wwdb->getPSVN($effectiveUser->id, $setName);
438 : sh002i 502
439 :     # decide what to do about problem number
440 :     my $problem;
441 :     if ($problemNumber) {
442 : malsyned 722 $problem = $wwdb->getProblem($effectiveUser->id, $setName, $problemNumber);
443 : sh002i 502 } elsif ($pgFile) {
444 :     $problem = WeBWorK::Problem->new(
445 :     id => 0,
446 :     set_id => $set->id,
447 : malsyned 722 login_id => $effectiveUser->id,
448 : sh002i 502 source_file => $pgFile,
449 :     # the rest of Problem's fields are not needed, i think
450 :     );
451 :     }
452 :    
453 : sh002i 738 # *** right here, figure out if we're allowed to get solutions and call PG->new accordingly.
454 :     my $showCorrectAnswers = $r->param("showCorrectAnswers") || 0;
455 :     my $showHints = $r->param("showHints") || 0;
456 :     my $showSolutions = $r->param("showSolutions") || 0;
457 :     unless ($permissionLevel > 0 or time > $set->due_date) {
458 :     $showCorrectAnswers = 0;
459 :     $showSolutions = 0;
460 :     }
461 :    
462 : sh002i 478 my $pg = WeBWorK::PG->new(
463 :     $ce,
464 : malsyned 722 $effectiveUser,
465 : sh002i 478 $r->param('key'),
466 : sh002i 502 $set,
467 :     $problem,
468 :     $psvn,
469 :     {}, # no form fields!
470 : sh002i 478 { # translation options
471 :     displayMode => "tex",
472 :     showHints => 0,
473 :     showSolutions => 0,
474 :     processAnswers => 0,
475 :     },
476 :     );
477 :    
478 : sh002i 641 if ($pg->{warnings} ne "") {
479 :     push @{$self->{warnings}}, {
480 :     set => $setName,
481 :     problem => $problemNumber,
482 :     message => $pg->{warnings},
483 :     };
484 :     }
485 : sh002i 607
486 : sh002i 641 if ($pg->{flags}->{error_flag}) {
487 :     push @{$self->{errors}}, {
488 :     set => $setName,
489 :     problem => $problemNumber,
490 :     message => $pg->{errors},
491 :     context => $pg->{body_text},
492 :     };
493 :     # if there was an error, body_text contains
494 :     # the error context, not TeX code
495 :     $pg->{body_text} = undef;
496 :     }
497 :    
498 : sh002i 738 # *** right here, append list of correct answers to body text
499 :    
500 : sh002i 478 return $pg->{body_text};
501 :     }
502 :    
503 : sh002i 492 sub texInclude {
504 :     my ($self, $texFile) = @_;
505 : sh002i 502 my $tex = "";
506 : sh002i 492
507 : sh002i 502 $tex .= texBlockComment("BEGIN: $texFile");
508 : sh002i 492 eval {
509 : sh002i 502 $tex .= readFile($texFile)
510 : sh002i 492 };
511 :     if ($@) {
512 : sh002i 502 $tex .= texBlockComment($@);
513 : sh002i 492 }
514 : sh002i 502
515 :     return $tex;
516 : sh002i 478 }
517 :    
518 :     1;
519 : sh002i 737
520 :     __END__
521 :    
522 :     sub body {
523 :     my $self = shift;
524 :    
525 :     STUFF: {
526 :     my $courseName = $self->{courseEnvironment}->{courseName};
527 :     my $effectiveUserName = $self->{r}->param("effectiveUser");
528 :     my @sets = @{$self->{sets}};
529 :    
530 :     unless (@sets) {
531 :     print CGI::p("No problem sets were specified.");
532 :     last STUFF;
533 :     }
534 :    
535 :     # determine where hardcopy is going to go
536 :     my $tempDir = $self->{courseEnvironment}->{courseDirs}->{html_temp}
537 :     . "/hardcopy";
538 :     my $tempURL = $self->{courseEnvironment}->{courseURLs}->{html_temp}
539 :     . "/hardcopy";
540 :    
541 :     # make sure tempDir exists
542 :     unless (-e $tempDir) {
543 :     if (system "mkdir", "-p", $tempDir) {
544 :     print CGI::p("An error occured while trying to generate your PDF hardcopy:");
545 :     print CGI::blockquote(CGI::pre("Failed to mkdir $tempDir: $!\n"));
546 :     }
547 :     }
548 :    
549 :     # determine name of PDF file
550 :     my $fileName;
551 :     if (@sets > 1) {
552 :     # multiset output
553 :     $fileName = "$courseName.$effectiveUserName.multiset.pdf"
554 :     } elsif (@sets == 1) {
555 :     # only one set
556 :     my $setName = $sets[0];
557 :     $fileName = "$courseName.$effectiveUserName.$setName.pdf";
558 :     } else {
559 :     $fileName = "$courseName.$effectiveUserName.pdf";
560 :     }
561 :    
562 :     # determine full URL
563 :     my $fullURL = "$tempURL/$fileName";
564 :    
565 :     # generate TeX from sets
566 :     my $tex = $self->getMultiSetTeX(@sets);
567 :     #print CGI::pre($tex);
568 :    
569 :     # check for PG errors (fatal)
570 :     if (@{$self->{errors}}) {
571 :     my @errors = @{$self->{errors}};
572 :     print CGI::h2("Software Errors");
573 :     print CGI::p(<<EOF);
574 :     WeBWorK has encountered one or more software errors while attempting to process these sets.
575 :     It is likely that there are error(s) in the problem itself.
576 :     If you are a student, contact your professor to have the error(s) corrected.
577 :     If you are a professor, please consut the error output below for more informaiton.
578 :     EOF
579 :     foreach my $error (@errors) {
580 :     print CGI::h3("Set: ", $error->{set}, ", Problem: ", $error->{problem});
581 :     print CGI::h4("Error messages"), CGI::blockquote(CGI::pre($error->{message}));
582 :     print CGI::h4("Error context"), CGI::blockquote(CGI::pre($error->{context}));
583 :     }
584 :    
585 :     last STUFF;
586 :     }
587 :    
588 :     # "try" to generate hardcopy
589 :     eval { $self->latex2pdf($tex, $tempDir, $fileName) };
590 :     if ($@) {
591 :     print CGI::p("An error occured while trying to generate your PDF hardcopy:");
592 :     print CGI::blockquote(CGI::pre($@));
593 :     last STUFF;
594 :     } else {
595 :     print CGI::p({-align=>"center"},
596 :     CGI::big(CGI::a({-href=>$fullURL}, "Download PDF Hardcopy"))
597 :     );
598 :     }
599 :    
600 :     # check for PG warnings (non-fatal)
601 :     if (@{$self->{warnings}}) {
602 :     my @warnings = @{$self->{warnings}};
603 :     print CGI::h2("Software Warnings");
604 :     print CGI::p(<<EOF);
605 :     WeBWorK has encountered warnings while attempting to process these sets.
606 :     It is likely that this indicates an error or ambiguity in the problem(s) themselves.
607 :     If you are a student, contact your professor to have the problem(s) corrected.
608 :     If you are a professor, please consut the error output below for more informaiton.
609 :     EOF
610 :     foreach my $warning (@warnings) {
611 :     print CGI::h3("Set: ", $warning->{set}, ", Problem: ", $warning->{problem});
612 :     print CGI::h4("Warning messages"), CGI::blockquote(CGI::pre($warning->{message}));
613 :     }
614 :     }
615 :     }
616 :    
617 :     # feedback form
618 :     my $ce = $self->{courseEnvironment};
619 :     my $root = $ce->{webworkURLs}->{root};
620 :     my $courseName = $ce->{courseName};
621 :     my $feedbackURL = "$root/$courseName/feedback/";
622 :     print
623 :     CGI::startform("POST", $feedbackURL),
624 :     $self->hidden_authen_fields,
625 :     CGI::hidden("module", __PACKAGE__),
626 :     CGI::p({-align=>"right"},
627 :     CGI::submit(-name=>"feedbackForm", -label=>"Send Feedback")
628 :     ),
629 :     CGI::endform();
630 :    
631 :     return "";
632 :     }

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9