Annotation of loncom/interface/lonpdfupload.pm, revision 1.5
1.1 onken 1: # The LearningOnline Network with CAPA
2: # Publication Handler
3: #
1.5 ! bisitz 4: # $Id: lonpdfupload.pm,v 1.4 2009/05/15 17:53:06 onken Exp $
1.1 onken 5: #
6: # Copyright Michigan State University Board of Trustees
7: #
8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
9: #
10: # LON-CAPA is free software; you can redistribute it and/or modify
11: # it under the terms of the GNU General Public License as published by
12: # the Free Software Foundation; either version 2 of the License, or
13: # (at your option) any later version.
14: #
15: # LON-CAPA is distributed in the hope that it will be useful,
16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18: # GNU General Public License for more details.
19: #
20: # You should have received a copy of the GNU General Public License
21: # along with LON-CAPA; if not, write to the Free Software
22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23: #
24: # /home/httpd/html/adm/gpl.txt
25: #
26: # http://www.lon-capa.org/
27: #
28: package Apache::lonpdfupload;
29:
30: use lib '/home/httpd/lib/perl';
31: use Apache::Constants qw(:common :http);
32: use LONCAPA;
33: use LONCAPA::loncgi;
34: use File::Path;
35: use File::Basename;
36: use File::Copy;
37: use IO::File;
38: use Image::Magick;
39: use Apache::lonacc;
40: use Apache::lonxml;
41: use Apache::lonhtmlcommon();
42: use Apache::lonnet;
43: use Apache::loncommon();
44: use Apache::lonlocal;
45: use Apache::lonmsg();
46: use Apache::lonhomework;
47: use LONCAPA::Enrollment;
48: use LONCAPA::Configuration;
1.2 onken 49: use CAM::PDF;
1.1 onken 50:
51: use strict;
52:
53: sub handler() {
1.2 onken 54: my $r = shift;
55:
56: # check user permissions
57: if(!&checkpermission($r)) {
58: # stop processing
59: return OK;
60: }
61:
62: $Apache::lonxml::request=$r;
63: $Apache::lonxml::debug=$env{'user.debug'};
64:
65: $env{'request.uri'}=$r->uri;
66: $r->content_type('text/html');
67: $r->send_http_header();
68: $r->print(&Apache::loncommon::start_page('Upload-PDF-Form'));
69:
70: #load post data into environment
71: &Apache::lonacc::get_posted_cgi($r);
72:
73: # if a file was upload
74: if($env{'form.Uploaded'} && $env{'form.file'}) {
75: $r->print(&processPDF);
76: } else {
77: # print upload form
78: $r->print(&get_javascripts);
79: $r->print(&get_uploadform);
80: }
81:
82: #link to course-content
1.5 ! bisitz 83: $r->print('<p>'."\n"
! 84: .'<a href="/adm/navmaps">'."\n"
! 85: .&mt("Navigate Contents")."\n"
! 86: .'</a>'."\n"
! 87: .'</p>'."\n"
! 88: );
1.1 onken 89:
1.2 onken 90: #&dumpenv($r); #debug -> prints the environment
91: $r->print(" </body> \n</html>\n");
1.1 onken 92: return OK;
1.2 onken 93: }
1.1 onken 94:
95:
96: sub checkpermission() {
97: my $r = shift;
98: if (! &LONCAPA::loncgi::check_cookie_and_load_env()) {
99: my $result = <<END
100: Content-type: text/html
101:
102: <html>
1.2 onken 103: <head>
104: <title>
105: Bad Cookie
106: </title>
107: </head>
108: <body>
109: Your cookie information is incorrect.
110: </body>
1.1 onken 111: </html>
112: END
113: ;
114: $r->print($result);
115: return 0;
116: } else {
117: return 1;
118: }
119: }
120:
121:
122: sub get_javascripts() {
1.2 onken 123:
124: my $message = &mt('Please choose a PDF-File');
1.1 onken 125:
1.2 onken 126: # simple test if the upload ends with ".pdf"
127: # it's only for giving a message to the user
128: my $result .= <<END
129: <script type="text/javascript">
1.1 onken 130: function checkFilename(form) {
131: var fileExt = form.file.value;
132: fileExt = fileExt.match(/[.]pdf\$/g);
133: if(fileExt) {
134: return true;
135: }
1.2 onken 136: alert("$message");
1.1 onken 137: return false;
138: }
1.2 onken 139: </script>
1.1 onken 140: END
141: ;
142: return $result;
143: }
144:
1.2 onken 145:
1.1 onken 146: sub get_uploadform() {
1.4 onken 147:
148: my %lt = &Apache::lonlocal::texthash(
149: 'title'=>'Submit a PDF-Form with problems',
1.5 ! bisitz 150: 'chFile' => 'Choose file',
1.4 onken 151: 'submit'=>'Submit'
152: );
153:
1.5 ! bisitz 154: my $result =
! 155: '<br />'
! 156: .'<form method="post" enctype="multipart/form-data" onsubmit="return checkFilename(this);">'
! 157: .'<input type="hidden" name="type" value="upload" />'
! 158: .&Apache::lonhtmlcommon::start_pick_box()
! 159: .&Apache::lonhtmlcommon::row_headline()
! 160: .'<h2>'.$lt{'title'}.'</h2>'
! 161: .&Apache::lonhtmlcommon::row_closure()
! 162: .&Apache::lonhtmlcommon::row_title($lt{'chFile'})
! 163: .'<input type="file" name="file" id="filename" />'
! 164: .&Apache::lonhtmlcommon::row_closure(1)
! 165: .&Apache::lonhtmlcommon::end_pick_box()
! 166: .'<input type="submit" name="Uploaded" value="'.$lt{'submit'}.'" />'
! 167: .'</form>'
! 168: .'<br />'
! 169: .'<hr />';
! 170:
1.1 onken 171: return $result;
172: }
173:
174: sub processPDF {
1.2 onken 175: my $result = (); # message for Browser
176: my @pdfdata = (); # answers from PDF-Forms
1.1 onken 177:
1.2 onken 178: @pdfdata = &get_pdf_data(); # get answers from PDF-Form
1.1 onken 179:
180: if (scalar @pdfdata) {
1.2 onken 181: &grade_pdf(@pdfdata);
1.1 onken 182: } else {
1.2 onken 183: $result .= "<h2>".&mt("Can't find any valid PDF-formfields")."</h2>";
1.1 onken 184: }
185: }
186:
187: sub get_pdf_data() {
188: my @data = ();
1.2 onken 189: my $pdf = CAM::PDF->new($env{'form.file'});
190:
191: my @formFields = $pdf->getFormFieldList(); #get names of formfields
1.1 onken 192:
1.2 onken 193: foreach my $field (@formFields) {
194: my $dict = $pdf->getFormFieldDict($pdf->getFormField($field)); # get formfield dictonary
1.1 onken 195:
1.2 onken 196: #
197: # this is nessesary 'cause CAM::PDF has a problem with formfieldnames which include a
198: # dot in fieldnames. So a fieldname like "i.am.aFormfield" will offer three fieldnames "i", "i.am"
199: # and "i.am.aFormfield". The fragmentary names keep no values and will be ignored.
200: if($dict->{'V'}) {
201: push(@data, $field."?". $dict->{'V'}{'value'}); #binding fieldname with value
202: }
203: }
1.1 onken 204: return @data;
205: }
206:
207: sub grade_pdf {
208: my $result = ();
209: my @pdfdata = @_;
210:
211: my $meta = ();
212: my %grades = ();
213: my %problems = ();
214:
215: my $debug = ();
216:
217: $debug .= "Found: ". scalar @pdfdata." Entries \n";
1.4 onken 218: $result .= '<br />';
219: $result .= &Apache::loncommon::start_data_table();
220: $result .= &Apache::loncommon::start_data_table_header_row();
221: $result .= &mt('<b>Results of PDF-Form problems</b>');
222: $result .= &Apache::loncommon::end_data_table_header_row();
223:
1.1 onken 224: foreach my $entry (sort(@pdfdata)) {
225: if ($entry =~ /^meta.*/) {
1.2 onken 226: $debug .= 'found: metadata -> '.$entry . "<br />";
227: my ($label, $value) = ($entry =~ /^([^?]*)\?(.*)/);
1.1 onken 228: my ($domain, $user) = split('&', $value);
1.4 onken 229: $user =~ s/(.*)\n/$1/; #TODO is that equals to chomp?
1.1 onken 230:
231: if($user ne $env{'user.name'} or $domain ne $env{'user.domain'}) {
232: return "<pre>".&mt('Wrong username in PDF-File').": $user $domain -> $env{'user.domain'} $env{'user.name'} </pre>";
233: }
234:
235: } elsif($entry =~ /^upload.*/) {
236: $debug .= 'found: a problem -> '.$entry;
1.2 onken 237: my ($label, $value) = ($entry =~ /^([^?]*)\?(.*)/);
1.1 onken 238: my ($symb, $part, $type, $HWVAL) = split('&', $label);
239: my ($map,$id,$resource)=&Apache::lonnet::decode_symb($symb);
240: $value =~ s/(.*)\n/$1/;
241:
242: #fehlerhafte Radiobuttons rausfiltern (Bug in CABAReT Stage)
243: if($type eq 'radiobuttonresponse' && $value eq 'Off' ) {
244: next;
245: }
246:
247: my $submit = $part;
248: $submit =~ s/part_(.*)/submit_$1/;
249: if($problems{$symb.$part}) {
250: $problems{$symb.$part}{$HWVAL} = $value;
251: } else {
252: $problems{$symb.$part} = { 'resource' => $resource,
1.4 onken 253: 'symb' => &Apache::lonenc::encrypted($symb),
1.1 onken 254: 'submitted' => $part,
255: $submit => 'Answer',
256: $HWVAL => $value};
257: }
258: } else {
259: $debug .= 'found: -> '.$entry;
260: next;
261: }
262: }
1.4 onken 263: #$result .= $debug;
1.1 onken 264:
265: foreach my $key (sort (keys %problems)) {
266: my %problem = %{$problems{$key}};
267: my ($problemname, $grade) = &grade_problem(%problem);
1.4 onken 268:
269: $problemname =~ s/(.*)\s*-\sPart\s0/$1/; #cut part when there is only one part in problem
270:
271: $result .= &Apache::loncommon::start_data_table_row();
272: $result .= "<td>$problemname</td><td class='";
1.1 onken 273: if($grade eq "EXACT_ANS") {
1.4 onken 274: $result .= "LC_answer_correct";
1.1 onken 275: } else {
1.4 onken 276: $result .= "LC_answer_charged_try";
1.1 onken 277: }
1.4 onken 278: $result .= "'>$grade</span></td>";
279: $result .= &Apache::loncommon::end_data_table_row();
280: }
281: #$result .= "\n</table>";
282: $result .= &Apache::loncommon::end_data_table();
1.1 onken 283:
284:
285: return $result;
286: }
287:
288: sub grade_problem {
289: my %problem = @_;
290:
291: my ($content) = &Apache::loncommon::ssi_with_retries('/res/'.
292: $problem{'resource'}, 5, %problem);
1.4 onken 293:
294: #TODO ? filter html response can't be the answer
295: # ! find an other way to get a problemname and Part
1.1 onken 296: $content =~ s/.*class="LC_current_location".*>(.*)<\/td>.*/$1/g;
297: $content = $1;
298:
299: my $part = $problem{submitted};
300: $part =~ s/part_(.*)/$1/;
301: $content .= " - Part $part";
302:
303: my %problemhash = &Apache::lonnet::restore($problem{'symb'});
304: my $grade = $problemhash{"resource.$part.award"};
305:
306: return ($content, $grade);
307: }
308:
309: sub dumpenv {
310: my $r = shift;
311:
312: $r->print ("<br />-------------------<br />");
313: foreach my $key (sort (keys %env)) {
314: $r->print ("<br />$key -> $env{$key}");
315: }
316: $r->print ("<br />-------------------<br />");
317: $r->print ("<br />-------------------<br />");
318: foreach my $key (sort (keys %ENV)) {
319: $r->print ("<br />$key -> $ENV{$key}");
320: }
321: $r->print ("<br />-------------------<br />");
322:
323: }
324:
325: 1;
326: __END__
327:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>