File:
[LON-CAPA] /
loncom /
interface /
lonpdfupload.pm
Revision
1.6:
download - view:
text,
annotated -
select for diffs
Sat May 16 00:28:38 2009 UTC (15 years, 11 months ago) by
bisitz
Branches:
MAIN
CVS tags:
HEAD
Optimized screen layout, wording and localization:
- Wording
- Optimized mt usage
- Added new phrases to de.pm
- Always separate Navigate link from rest of screen by <hr>
- Make headlines headlines
- Added error style to error message
- Corrected grading table header and added table headline
# The LearningOnline Network with CAPA
# Publication Handler
#
# $Id: lonpdfupload.pm,v 1.6 2009/05/16 00:28:38 bisitz Exp $
#
# Copyright Michigan State University Board of Trustees
#
# This file is part of the LearningOnline Network with CAPA (LON-CAPA).
#
# LON-CAPA is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# LON-CAPA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LON-CAPA; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# /home/httpd/html/adm/gpl.txt
#
# http://www.lon-capa.org/
#
package Apache::lonpdfupload;
use lib '/home/httpd/lib/perl';
use Apache::Constants qw(:common :http);
use LONCAPA;
use LONCAPA::loncgi;
use File::Path;
use File::Basename;
use File::Copy;
use IO::File;
use Image::Magick;
use Apache::lonacc;
use Apache::lonxml;
use Apache::lonhtmlcommon();
use Apache::lonnet;
use Apache::loncommon();
use Apache::lonlocal;
use Apache::lonmsg();
use Apache::lonhomework;
use LONCAPA::Enrollment;
use LONCAPA::Configuration;
use CAM::PDF;
use strict;
sub handler() {
my $r = shift;
# check user permissions
if(!&checkpermission($r)) {
# stop processing
return OK;
}
$Apache::lonxml::request=$r;
$Apache::lonxml::debug=$env{'user.debug'};
$env{'request.uri'}=$r->uri;
$r->content_type('text/html');
$r->send_http_header();
$r->print(&Apache::loncommon::start_page('Upload PDF Form'));
#load post data into environment
&Apache::lonacc::get_posted_cgi($r);
# if a file was upload
if($env{'form.Uploaded'} && $env{'form.file'}) {
$r->print(&processPDF);
} else {
# print upload form
$r->print(&get_javascripts);
$r->print(&get_uploadform);
}
#link to course-content
$r->print('<hr />'
.'<p>'."\n"
.'<a href="/adm/navmaps">'."\n"
.&mt("Navigate Contents")."\n"
.'</a>'."\n"
.'</p>'."\n"
);
#&dumpenv($r); #debug -> prints the environment
$r->print(" </body> \n</html>\n");
return OK;
}
sub checkpermission() {
my $r = shift;
if (! &LONCAPA::loncgi::check_cookie_and_load_env()) {
my $result = <<END
Content-type: text/html
<html>
<head>
<title>
Bad Cookie
</title>
</head>
<body>
Your cookie information is incorrect.
</body>
</html>
END
;
$r->print($result);
return 0;
} else {
return 1;
}
}
sub get_javascripts() {
my $message = &mt('Please choose a PDF-File.');
# simple test if the upload ends with ".pdf"
# it's only for giving a message to the user
my $result .= <<END
<script type="text/javascript">
function checkFilename(form) {
var fileExt = form.file.value;
fileExt = fileExt.match(/[.]pdf\$/g);
if(fileExt) {
return true;
}
alert("$message");
return false;
}
</script>
END
;
return $result;
}
sub get_uploadform() {
my %lt = &Apache::lonlocal::texthash(
'title' => 'Upload a PDF Form with filled Form Fields',
'chFile' => 'File',
'submit' => 'Upload',
);
my $result =
'<br />'
.'<form method="post" enctype="multipart/form-data" onsubmit="return checkFilename(this);">'
.'<input type="hidden" name="type" value="upload" />'
.&Apache::lonhtmlcommon::start_pick_box()
.&Apache::lonhtmlcommon::row_headline()
.'<h2>'.$lt{'title'}.'</h2>'
.&Apache::lonhtmlcommon::row_closure()
.&Apache::lonhtmlcommon::row_title($lt{'chFile'})
.'<input type="file" name="file" id="filename" />'
.&Apache::lonhtmlcommon::row_closure(1)
.&Apache::lonhtmlcommon::end_pick_box()
.'<input type="submit" name="Uploaded" value="'.$lt{'submit'}.'" />'
.'</form>'
.'<br />';
return $result;
}
sub processPDF {
my $result = (); # message for Browser
my @pdfdata = (); # answers from PDF-Forms
@pdfdata = &get_pdf_data(); # get answers from PDF-Form
if (scalar @pdfdata) {
&grade_pdf(@pdfdata);
} else {
$result .= '<p class="LC_error">'
.&mt("Can't find any valid PDF formfields.")
.'</p>';
}
}
sub get_pdf_data() {
my @data = ();
my $pdf = CAM::PDF->new($env{'form.file'});
my @formFields = $pdf->getFormFieldList(); #get names of formfields
foreach my $field (@formFields) {
my $dict = $pdf->getFormFieldDict($pdf->getFormField($field)); # get formfield dictonary
#
# this is nessesary 'cause CAM::PDF has a problem with formfieldnames which include a
# dot in fieldnames. So a fieldname like "i.am.aFormfield" will offer three fieldnames "i", "i.am"
# and "i.am.aFormfield". The fragmentary names keep no values and will be ignored.
if($dict->{'V'}) {
push(@data, $field."?". $dict->{'V'}{'value'}); #binding fieldname with value
}
}
return @data;
}
sub grade_pdf {
my $result = ();
my @pdfdata = @_;
my $meta = ();
my %grades = ();
my %problems = ();
my $debug = ();
$debug .= "Found: ". scalar @pdfdata." Entries \n";
$result .= '<h2>'.&mt('Results of PDF Form problems').'</h2>';
$result .= &Apache::loncommon::start_data_table()
.&Apache::loncommon::start_data_table_header_row()
.'<th>'.&mt('Problem Name').'</th>'
.'<th>'.&mt('Grading').'</th>'
.&Apache::loncommon::start_data_table_header_row()
.&Apache::loncommon::end_data_table_header_row();
foreach my $entry (sort(@pdfdata)) {
if ($entry =~ /^meta.*/) {
$debug .= 'found: metadata -> '.$entry . "<br />";
my ($label, $value) = ($entry =~ /^([^?]*)\?(.*)/);
my ($domain, $user) = split('&', $value);
$user =~ s/(.*)\n/$1/; #TODO is that equals to chomp?
if($user ne $env{'user.name'} or $domain ne $env{'user.domain'}) {
return "<pre>".&mt('Wrong username in PDF-File').": $user $domain -> $env{'user.domain'} $env{'user.name'} </pre>";
}
} elsif($entry =~ /^upload.*/) {
$debug .= 'found: a problem -> '.$entry;
my ($label, $value) = ($entry =~ /^([^?]*)\?(.*)/);
my ($symb, $part, $type, $HWVAL) = split('&', $label);
my ($map,$id,$resource)=&Apache::lonnet::decode_symb($symb);
$value =~ s/(.*)\n/$1/;
#filter incorrect radiobuttons (Bug in CABAReT Stage)
if($type eq 'radiobuttonresponse' && $value eq 'Off' ) {
next;
}
my $submit = $part;
$submit =~ s/part_(.*)/submit_$1/;
if($problems{$symb.$part}) {
$problems{$symb.$part}{$HWVAL} = $value;
} else {
$problems{$symb.$part} = { 'resource' => $resource,
'symb' => &Apache::lonenc::encrypted($symb),
'submitted' => $part,
$submit => 'Answer',
$HWVAL => $value};
}
} else {
$debug .= 'found: -> '.$entry;
next;
}
}
#$result .= $debug;
foreach my $key (sort (keys %problems)) {
my %problem = %{$problems{$key}};
my ($problemname, $grade) = &grade_problem(%problem);
$problemname =~ s/(.*)\s*-\sPart\s0/$1/; #cut part when there is only one part in problem
$result .= &Apache::loncommon::start_data_table_row();
$result .= "<td>$problemname</td><td class='";
if($grade eq "EXACT_ANS") {
$result .= "LC_answer_correct";
} else {
$result .= "LC_answer_charged_try";
}
$result .= "'>$grade</span></td>";
$result .= &Apache::loncommon::end_data_table_row();
}
$result .= &Apache::loncommon::end_data_table();
return $result;
}
sub grade_problem {
my %problem = @_;
my ($content) = &Apache::loncommon::ssi_with_retries('/res/'.
$problem{'resource'}, 5, %problem);
#TODO ? filter html response can't be the answer
# ! find an other way to get a problemname and Part
$content =~ s/.*class="LC_current_location".*>(.*)<\/td>.*/$1/g;
$content = $1;
my $part = $problem{submitted};
$part =~ s/part_(.*)/$1/;
$content .= " - Part $part";
my %problemhash = &Apache::lonnet::restore($problem{'symb'});
my $grade = $problemhash{"resource.$part.award"};
return ($content, $grade);
}
sub dumpenv {
my $r = shift;
$r->print ("<br />-------------------<br />");
foreach my $key (sort (keys %env)) {
$r->print ("<br />$key -> $env{$key}");
}
$r->print ("<br />-------------------<br />");
$r->print ("<br />-------------------<br />");
foreach my $key (sort (keys %ENV)) {
$r->print ("<br />$key -> $ENV{$key}");
}
$r->print ("<br />-------------------<br />");
}
1;
__END__
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>