[LON-CAPA-cvs] cvs: loncom /interface lonpdfupload.pm
onken
onken@source.lon-capa.org
Fri, 03 Apr 2009 15:40:17 -0000
onken Fri Apr 3 15:40:17 2009 EDT
Modified files:
/loncom/interface lonpdfupload.pm
Log:
Upgrade for PDF-Forms.
Now only perl is used to read out PDF-Formdata. Before you copy lonpdfupload.pm in to your Apache-folder check the needed Steps below.
----------
Enable PDF-Forms in LON-CAPA
First you need to install the AcroTeX-education bundle from ctan.
Get the package and unzip it:
[root@loncapa ]# wget http://tug.ctan.org/get/macros/latex/contrib/acrotex.zip
[root@loncapa ]# unzip acrotex.zip
go into the acrotex-folder and install
[root@loncapa ]# cd acrotex
[root@loncapa acrotex]# latex acrotex.ins
Now move the folder acrotex file into the latex path. You can easy find it by searching for "cite.sty" or some other tex-packages.
[root@loncapa /]# locate cite.sty
/usr/share/texmf/tex/latex/cite/cite.sty
/usr/share/texmf/tex/latex/cite/drftcite.sty
/usr/share/texmf/tex/latex/cite/overcite.sty
On CentOS the latex path is: /usr/share/texmf/tex/latex/ (perhaps there is different to
[root@loncapa acrotex]# cd ..
[root@loncapa ]# mv acrotex /usr/share/texmf/tex/latex/
Remove the acrotex.zip
[root@loncapa]# rm acrotex.zip
After that you must rehash tex:
[root@loncapa ]# texhash
Now you are able to print PDF with Forms (Radiobutton-, Comboboxes-, Textfield based problems).
The second thing to do is to enable the Upload-script lonpdfupload.pm. Before you can use it you have to install CAM::PDF for perl. It is available on CPAN so you can use the perl –MCPAN -eshell.
[root@loncapa ~]# perl -MCPAN -eshell
cpan shell -- CPAN exploration and modules installation (v1.7602)
ReadLine support enabled
cpan>install CAM::PDF
(…follow installation and also install the dependencies)
cpan>exit
Next you need to copy the upload-script from CVS to the LON-CAPA Apache folder.
[root@loncapa ~]# cp [your-cvs-folder]/loncom/interface/lonpdfupload.pm /home/httpd/lib/perl/Apache/
Now restart httpd:
[root@loncapa ~]# /etc/init.d/httpd restart
Index: loncom/interface/lonpdfupload.pm
diff -u loncom/interface/lonpdfupload.pm:1.1 loncom/interface/lonpdfupload.pm:1.2
--- loncom/interface/lonpdfupload.pm:1.1 Tue Sep 9 13:56:44 2008
+++ loncom/interface/lonpdfupload.pm Fri Apr 3 15:40:17 2009
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Publication Handler
#
-# $Id: lonpdfupload.pm,v 1.1 2008/09/09 13:56:44 onken Exp $
+# $Id: lonpdfupload.pm,v 1.2 2009/04/03 15:40:17 onken Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -46,45 +46,48 @@
use Apache::lonhomework;
use LONCAPA::Enrollment;
use LONCAPA::Configuration;
+use CAM::PDF;
use strict;
sub handler() {
- my $r = shift;
+ my $r = shift;
- #Testen ob der Benutzer ein gültiges Cookie besitzt
- if(!&checkpermission($r)) {
- return OK;
- }
+ # 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'));
-
- #lade die per POST gesendenten daten in env
- &Apache::lonacc::get_posted_cgi($r);
-
- if($env{'form.Uploaded'} && $env{'form.file'}) {
- #Upload-Formular wurde gesendet
- $r->print(&processPDF);
-
- } else {
- #erster Aufruf Upload-Formular wird ausgeben
- $r->print(&get_javascripts);
- $r->print(&get_uploadform);
-
- }
-
- #&dumpenv($r); #debug -> prints the environment
- $r->print("<br /><a href='/adm/navmaps'>".&mt("Navigate Contents")."</a><br />");
- $r->print(" </body>\n</html>\n");
- 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(" <br />\n <a href='/adm/navmaps'>\n ".&mt("Navigate Contents")."\n </a>\n <br />");
+
+ #&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()) {
@@ -92,10 +95,14 @@
Content-type: text/html
<html>
-<head><title>Bad Cookie</title></head>
-<body>
-Your cookie information is incorrect.
-</body>
+ <head>
+ <title>
+ Bad Cookie
+ </title>
+ </head>
+ <body>
+ Your cookie information is incorrect.
+ </body>
</html>
END
;
@@ -108,25 +115,29 @@
sub get_javascripts() {
- my $result = ' <script type="text/javascript">';
+
+ my $message = &mt('Please choose a PDF-File');
- # JavaScript prüft die Datei Endung der hochzuladenden Datei
- $result .= <<END
+ # 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("Bitte geben Sie nur ein PDF an.")
+ alert("$message");
return false;
}
+ </script>
END
;
- $result .= " </script>";
return $result;
}
+
sub get_uploadform() {
my $result = <<END
<p height='25'>
@@ -168,53 +179,35 @@
}
sub processPDF {
- my $result = ();
- my @pdfdata = ();
+ my $result = (); # message for Browser
+ my @pdfdata = (); # answers from PDF-Forms
- @pdfdata = &get_pdf_data;
+ @pdfdata = &get_pdf_data(); # get answers from PDF-Form
if (scalar @pdfdata) {
- $result .= &grade_pdf(@pdfdata);
+ &grade_pdf(@pdfdata);
} else {
- $result .= "<h2>".&mt("reading PDF-formfields: failed")."</h2>";
+ $result .= "<h2>".&mt("Can't find any valid PDF-formfields")."</h2>";
}
}
sub get_pdf_data() {
my @data = ();
- my $file_path = "/home/httpd/pdfspool/".time."_".
- int(rand(100000)).".pdf";
- my $file_data = $file_path;
- $file_data =~ s/(.*)\..*/$1.data/;
-
- # zwischenspeichern der hochgeladenen PDF
- my $temp_file = Apache::File->new('>'.$file_path);
- binmode($temp_file);
- print $temp_file $env{'form.file'};
- $temp_file->close;
-
- #Java PDF-Auslese-Programm starten
- my @command = ("java", "-jar",
- "/home/httpd/pdfspool/dumpPDF.jar",
- $file_path, $file_data);
- system(@command);
-
+ my $pdf = CAM::PDF->new($env{'form.file'});
- #Einlesen der extrahierten Daten
- $temp_file = new IO::File->new('<'.$file_data);
- while (defined (my $line = $temp_file->getline())) {
- push(@data, $line);
- }
- $temp_file->close;
- undef($temp_file);
+ my @formFields = $pdf->getFormFieldList(); #get names of formfields
+
+ foreach my $field (@formFields) {
+ my $dict = $pdf->getFormFieldDict($pdf->getFormField($field)); # get formfield dictonary
- #zwischengespeicherte Dateien loeschen
- if( -e $file_path) {
-# unlink($file_path);
- }
- if( -e $file_data) {
-# unlink($file_data);
- }
+ #
+ # 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;
}
@@ -232,10 +225,10 @@
$result .= "<table width='80%'>\n";
foreach my $entry (sort(@pdfdata)) {
if ($entry =~ /^meta.*/) {
- $debug .= 'found: metadata -> '.$entry;
- my ($label, $value) = split('\?', $entry);
+ $debug .= 'found: metadata -> '.$entry . "<br />";
+ my ($label, $value) = ($entry =~ /^([^?]*)\?(.*)/);
my ($domain, $user) = split('&', $value);
- $user =~ s/(.*)\n/$1/;
+ $user =~ s/(.*)\n/$1/; #TODO find an other way
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>";
@@ -243,7 +236,7 @@
} elsif($entry =~ /^upload.*/) {
$debug .= 'found: a problem -> '.$entry;
- my ($label, $value) = split('\?', $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/;
@@ -268,8 +261,8 @@
$debug .= 'found: -> '.$entry;
next;
}
- #$result = $debug;
}
+ $result .= $debug;
foreach my $key (sort (keys %problems)) {
my %problem = %{$problems{$key}};