Annotation of loncom/interface/lonpdfupload.pm, revision 1.4

1.1       onken       1: # The LearningOnline Network with CAPA
                      2: # Publication Handler
                      3: #
1.4     ! onken       4: # $Id: lonpdfupload.pm,v 1.3 2009/04/04 21:47:41 bisitz 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
                     83:     $r->print("    <br />\n    <a href='/adm/navmaps'>\n      ".&mt("Navigate Contents")."\n    </a>\n    <br />");
1.1       onken      84: 
1.2       onken      85:     #&dumpenv($r); #debug -> prints the environment
                     86:     $r->print("  </body> \n</html>\n");
1.1       onken      87:     return OK;
1.2       onken      88: }
1.1       onken      89: 
                     90: 
                     91: sub checkpermission() {
                     92:     my $r = shift;
                     93:     if (! &LONCAPA::loncgi::check_cookie_and_load_env()) {
                     94:         my $result  = <<END
                     95: Content-type: text/html
                     96: 
                     97: <html>
1.2       onken      98:   <head>
                     99:     <title>
                    100:       Bad Cookie
                    101:     </title>
                    102:   </head>
                    103:   <body>
                    104:     Your cookie information is incorrect.
                    105:   </body>
1.1       onken     106: </html>
                    107: END
                    108: ;
                    109:         $r->print($result);
                    110:         return 0;
                    111:     } else {
                    112:         return 1;
                    113:     }
                    114: }
                    115: 
                    116: 
                    117: sub get_javascripts() {
1.2       onken     118:     
                    119:     my $message = &mt('Please choose a PDF-File');
1.1       onken     120: 
1.2       onken     121:     # simple test if the upload ends with ".pdf"
                    122:     # it's only for giving a message to the user
                    123:     my $result .= <<END
                    124:   <script type="text/javascript">
1.1       onken     125:     function checkFilename(form) {
                    126:         var fileExt = form.file.value;
                    127:         fileExt = fileExt.match(/[.]pdf\$/g);
                    128:         if(fileExt) {
                    129:             return true;
                    130:         }
1.2       onken     131:         alert("$message");
1.1       onken     132:         return false;
                    133:     }
1.2       onken     134:   </script>
1.1       onken     135: END
                    136: ;
                    137:     return $result; 
                    138: }
                    139: 
1.2       onken     140: 
1.1       onken     141: sub get_uploadform() {
1.4     ! onken     142:     
        !           143:     #TODO use LON-CAPA routines like pick_box or like that  
        !           144:     my %lt = &Apache::lonlocal::texthash(
        !           145:                  'title'=>'Submit a PDF-Form with problems', 
        !           146:                  'chFile' => 'Choose file:',
        !           147:                  'submit'=>'Submit'
        !           148:              );
        !           149: 
1.1       onken     150:     my $result = <<END
                    151:     <form method="post" enctype="multipart/form-data" onsubmit="return checkFilename(this);">
1.3       bisitz    152:       <input type="hidden" name="type" value="upload" />
1.4     ! onken     153:       <br />
        !           154:       <b>$lt{'title'}</b>
        !           155:       <table class="LC_pick_box"> 
        !           156:         <tbody>
        !           157:           <tr class="LC_pick_box_row">
        !           158:             <td class="LC_pick_box_title">
        !           159:               $lt{'chFile'}
        !           160:             </td>
        !           161:             <td class="LC_pick_box_value LC_odd_row">
        !           162:               <input type="file" name="file" id="filename" />
        !           163:             </td>
        !           164:           </tr>
        !           165:         </tbody>
        !           166:       </table>
        !           167:       <br />
        !           168:       <input type="submit" name="Uploaded" value="$lt{'submit'}" />
        !           169:     </form>
        !           170:     <br />
        !           171:     <hr />    
1.1       onken     172: END
                    173: ;
                    174:   return $result;
                    175: }
                    176: 
                    177: sub processPDF {
1.2       onken     178:     my $result = ();  # message for Browser
                    179:     my @pdfdata = (); # answers from PDF-Forms
1.1       onken     180:     
1.2       onken     181:     @pdfdata = &get_pdf_data(); # get answers from PDF-Form
1.1       onken     182:     
                    183:     if (scalar @pdfdata) {    
1.2       onken     184:         &grade_pdf(@pdfdata);
1.1       onken     185:     } else {
1.2       onken     186:         $result .= "<h2>".&mt("Can't find any valid PDF-formfields")."</h2>";
1.1       onken     187:     }
                    188: }
                    189: 
                    190: sub get_pdf_data() {
                    191:     my @data = ();
1.2       onken     192:     my $pdf = CAM::PDF->new($env{'form.file'});
                    193: 
                    194:     my @formFields = $pdf->getFormFieldList(); #get names of formfields
1.1       onken     195:     
1.2       onken     196:     foreach my $field (@formFields) {
                    197: 	my $dict = $pdf->getFormFieldDict($pdf->getFormField($field)); # get formfield dictonary
1.1       onken     198: 
1.2       onken     199:         #
                    200:         # this is nessesary 'cause CAM::PDF has a problem with formfieldnames which include a
                    201:         # dot in fieldnames. So a fieldname like "i.am.aFormfield" will offer three fieldnames "i", "i.am" 
                    202:         # and "i.am.aFormfield". The fragmentary names keep no values and will be ignored.
                    203:         if($dict->{'V'}) {
                    204:             push(@data, $field."?". $dict->{'V'}{'value'}); #binding fieldname with value
                    205:         }
                    206:     } 
1.1       onken     207:     return @data;
                    208: }
                    209: 
                    210: sub grade_pdf {
                    211:     my $result = ();
                    212:     my @pdfdata = @_;
                    213:    
                    214:     my $meta = ();
                    215:     my %grades = ();
                    216:     my %problems = ();
                    217:         
                    218:     my $debug = ();
                    219: 
                    220:     $debug  .= "Found: ". scalar @pdfdata." Entries \n";
1.4     ! onken     221:     $result .= '<br />';
        !           222:     $result .= &Apache::loncommon::start_data_table();
        !           223:     $result .= &Apache::loncommon::start_data_table_header_row();
        !           224:     $result .= &mt('<b>Results of PDF-Form problems</b>');
        !           225:     $result .= &Apache::loncommon::end_data_table_header_row();
        !           226: 
1.1       onken     227:     foreach my $entry (sort(@pdfdata)) {
                    228:         if ($entry =~ /^meta.*/) {
1.2       onken     229:             $debug .= 'found: metadata -> '.$entry . "<br />";
                    230:             my ($label, $value) = ($entry =~ /^([^?]*)\?(.*)/);
1.1       onken     231:             my ($domain, $user) = split('&', $value);
1.4     ! onken     232:             $user =~ s/(.*)\n/$1/; #TODO is that equals to chomp?
1.1       onken     233:             
                    234:             if($user ne $env{'user.name'} or  $domain ne $env{'user.domain'}) {
                    235:                 return "<pre>".&mt('Wrong username in PDF-File').": $user $domain -> $env{'user.domain'} $env{'user.name'} </pre>";    
                    236:             }
                    237: 
                    238:         } elsif($entry =~ /^upload.*/)  {
                    239:             $debug .= 'found: a problem -> '.$entry;
1.2       onken     240:             my ($label, $value) = ($entry =~ /^([^?]*)\?(.*)/);
1.1       onken     241:             my ($symb, $part, $type, $HWVAL) = split('&', $label);
                    242:             my ($map,$id,$resource)=&Apache::lonnet::decode_symb($symb);  
                    243:             $value =~ s/(.*)\n/$1/; 
                    244: 
                    245:             #fehlerhafte Radiobuttons rausfiltern (Bug in CABAReT Stage)
                    246:             if($type eq 'radiobuttonresponse' && $value eq 'Off' ) {
                    247:                 next;
                    248:             }
                    249:  
                    250:             my $submit = $part;
                    251:             $submit =~ s/part_(.*)/submit_$1/;
                    252:             if($problems{$symb.$part}) {
                    253:                  $problems{$symb.$part}{$HWVAL} = $value;
                    254:             } else {
                    255:                  $problems{$symb.$part} =  { 'resource' => $resource,
1.4     ! onken     256:                                         'symb' => &Apache::lonenc::encrypted($symb),
1.1       onken     257:                                         'submitted' => $part,
                    258:                                         $submit => 'Answer',
                    259:                                         $HWVAL => $value};
                    260:             }
                    261:         } else {
                    262:             $debug .= 'found: -> '.$entry;
                    263:             next;
                    264:         }
                    265:     }
1.4     ! onken     266:     #$result .= $debug;
1.1       onken     267: 
                    268:     foreach my $key (sort (keys %problems)) {
                    269:         my %problem = %{$problems{$key}};
                    270:         my ($problemname, $grade) = &grade_problem(%problem);
1.4     ! onken     271: 
        !           272:         $problemname =~ s/(.*)\s*-\sPart\s0/$1/; #cut part when there is only one part in problem
        !           273: 
        !           274:         $result .= &Apache::loncommon::start_data_table_row();
        !           275:         $result .= "<td>$problemname</td><td class='";
1.1       onken     276:         if($grade eq "EXACT_ANS") {
1.4     ! onken     277:             $result .= "LC_answer_correct";
1.1       onken     278:         } else { 
1.4     ! onken     279:             $result .= "LC_answer_charged_try";
1.1       onken     280:         }
1.4     ! onken     281:         $result .= "'>$grade</span></td>";
        !           282:         $result .= &Apache::loncommon::end_data_table_row();
        !           283:     }
        !           284:     #$result .= "\n</table>";
        !           285:     $result .= &Apache::loncommon::end_data_table();
1.1       onken     286: 
                    287: 
                    288:     return $result;        
                    289: }
                    290: 
                    291: sub grade_problem {
                    292:     my %problem = @_;
                    293: 
                    294:     my ($content) =  &Apache::loncommon::ssi_with_retries('/res/'.
                    295:             $problem{'resource'}, 5, %problem);
1.4     ! onken     296:     
        !           297:     #TODO ? filter html response can't be the answer 
        !           298:     #     ! find an other way to get a problemname and Part
1.1       onken     299:     $content =~ s/.*class="LC_current_location".*>(.*)<\/td>.*/$1/g;
                    300:     $content = $1;
                    301: 
                    302:     my $part = $problem{submitted};
                    303:     $part =~ s/part_(.*)/$1/;
                    304:     $content .= " - Part $part";
                    305:  
                    306:     my %problemhash = &Apache::lonnet::restore($problem{'symb'});
                    307:     my $grade = $problemhash{"resource.$part.award"};
                    308: 
                    309:     return ($content, $grade);    
                    310: }
                    311: 
                    312: sub dumpenv  {
                    313:     my $r = shift;
                    314: 
                    315:     $r->print ("<br />-------------------<br />");
                    316:     foreach my $key (sort (keys %env)) {
                    317:         $r->print ("<br />$key -> $env{$key}");
                    318:     }
                    319:     $r->print ("<br />-------------------<br />");
                    320:     $r->print ("<br />-------------------<br />");
                    321:     foreach my $key (sort (keys %ENV)) {
                    322:         $r->print ("<br />$key -> $ENV{$key}");
                    323:     }
                    324:     $r->print ("<br />-------------------<br />");
                    325:     
                    326: }	
                    327: 
                    328: 1;
                    329: __END__
                    330: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>