File:  [LON-CAPA] / loncom / publisher / lonupload.pm
Revision 1.33: download - view: text, annotated - select for diffs
Wed Jul 5 22:23:09 2006 UTC (17 years, 10 months ago) by albertel
Branches: MAIN
CVS tags: version_2_2_X, version_2_2_2, version_2_2_1, version_2_2_0, version_2_1_99_3, version_2_1_99_2, version_2_1_99_1, HEAD
- move inline text into help files
- CSS erro messages and file names

    1: 
    2: # The LearningOnline Network with CAPA
    3: # Handler to upload files into construction space
    4: #
    5: # $Id: lonupload.pm,v 1.33 2006/07/05 22:23:09 albertel Exp $
    6: #
    7: # Copyright Michigan State University Board of Trustees
    8: #
    9: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
   10: #
   11: # LON-CAPA is free software; you can redistribute it and/or modify
   12: # it under the terms of the GNU General Public License as published by
   13: # the Free Software Foundation; either version 2 of the License, or
   14: # (at your option) any later version.
   15: #
   16: # LON-CAPA is distributed in the hope that it will be useful,
   17: # but WITHOUT ANY WARRANTY; without even the implied warranty of
   18: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   19: # GNU General Public License for more details.
   20: #
   21: # You should have received a copy of the GNU General Public License
   22: # along with LON-CAPA; if not, write to the Free Software
   23: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   24: #
   25: # /home/httpd/html/adm/gpl.txt
   26: #
   27: # http://www.lon-capa.org/
   28: #
   29: ###
   30: 
   31: package Apache::lonupload;
   32: 
   33: use strict;
   34: use Apache::File;
   35: use File::Copy;
   36: use File::Basename;
   37: use Apache::Constants qw(:common :http :methods);
   38: use Apache::loncacc;
   39: use Apache::loncommon();
   40: use Apache::lonnet;
   41: use HTML::Entities();
   42: use Apache::lonlocal;
   43: use Apache::lonnet;
   44: 
   45: my $DEBUG=0;
   46: 
   47: sub Debug {
   48:     # Put out the indicated message but only if DEBUG is true.
   49:     if ($DEBUG) {
   50: 	my ($r,$message) = @_;
   51: 	$r->log_reason($message);
   52:     }
   53: }
   54: 
   55: sub upfile_store {
   56:     my $r=shift;
   57: 	
   58:     my $fname=$env{'form.upfile.filename'};
   59:     $fname=~s/\W//g;
   60:     
   61:     chomp($env{'form.upfile'});
   62:   
   63:     my $datatoken=$env{'user.name'}.'_'.$env{'user.domain'}.
   64: 		  '_upload_'.$fname.'_'.time.'_'.$$;
   65:     {
   66:        my $fh=Apache::File->new('>'.$r->dir_config('lonDaemons').
   67:                                    '/tmp/'.$datatoken.'.tmp');
   68:        print $fh $env{'form.upfile'};
   69:     }
   70:     return $datatoken;
   71: }
   72: 
   73: 
   74: sub phaseone {
   75:     my ($r,$fn,$uname,$udom,$mode)=@_;
   76:     my $action = '/adm/upload';
   77:     if ($mode eq 'testbank') {
   78:         $action = '/adm/testbank';
   79:     } elsif ($mode eq 'imsimport') {
   80:         $action = '/adm/imsimport';
   81:     }
   82:     $env{'form.upfile.filename'}=~s/\\/\//g;
   83:     $env{'form.upfile.filename'}=~s/^.*\/([^\/]+)$/$1/;
   84:     if ($env{'form.upfile.filename'}) {
   85: 	$fn=~s/\/[^\/]+$//;
   86: 	$fn=~s/([^\/])$/$1\//;
   87: 	$fn.=$env{'form.upfile.filename'};
   88: 	$fn=~s/^\///;
   89: 	$fn=~s/(\/)+/\//g;
   90: 
   91: #    Fn is the full path to the destination filename.
   92: #    
   93: 
   94: 	&Debug($r, "Filename for upload: $fn");
   95: 	if (($fn) && ($fn!~/\/$/)) {
   96: 	    $r->print('<form action="'.$action.'" method="post" name="fileupload">'.
   97: 		      '<input type="hidden" name="phase" value="two" />'.
   98: 		      '<input type="hidden" name="datatoken" value="'.
   99: 		      &upfile_store.'" />'.
  100: 		      '<input type="hidden" name="uploaduname" value="'.$uname.
  101: 		      '" />'.&mt('Store uploaded file as ').
  102:                       "<span class='LC_filename'>/priv/$uname/</span>".
  103:                       '<input type="text" size="50" name="filename" value="'.$fn.
  104:                       '" /><br />'.
  105: 		      '<br />'.&mt('Choose file type:').'
  106: <select name="filetype">
  107:  <option value="standard" selected>'.&mt('Regular file').'
  108:  <option value="testbank">'.&mt('Testbank file').'
  109:  <option value="imsimport">'.&mt('IMS package').'
  110: </select>'.&Apache::loncommon::help_open_topic("Uploading_File_Options").'
  111: <br />
  112: <br />
  113: ');
  114:             $r->print('<input type="button" value="'.&mt('Store').'" onClick="javascript:verifyForm()"/></form>');
  115: 	    # Check for bad extension and warn user
  116: 	    if ($fn=~/\.(\w+)$/ && 
  117: 		(&Apache::loncommon::fileembstyle($1) eq 'hdn')) {
  118: 		$r->print('<span class="LC_error">'.&mt('The extension on this file,').
  119: 			  ' "'.$1.'"'.&mt(', is reserved internally by LON-CAPA.').
  120: 			  ' <br />'.&mt('Please change the extension.').'</span>');
  121: 	    } elsif($fn=~/\.(\w+)$/ && 
  122: 		    !defined(&Apache::loncommon::fileembstyle($1))) {
  123: 		$r->print('<span class="LC_error">'.&mt('The extension on this file,').
  124: 			  ' "'.$1.'"'.&mt(', is not recognized by LON-CAPA.').
  125: 			  ' <br />'.&mt('Please change the extension.').
  126: 			  '</span>');
  127: 	    }
  128: 	} else {
  129: 	    $r->print('<span class="LC_error">'.&mt('Illegal filename.').'</span>');
  130: 	}
  131:     } else {
  132: 	$r->print('<span class="LC_error">'.&mt('No upload file specified.').'</span>');
  133:     }
  134: }
  135: 
  136: sub phasetwo {
  137:     my ($r,$tfn,$uname,$udom,$mode)=@_;
  138:     my $action = '/adm/upload';
  139:     my $returnflag = '';
  140:     if ($mode eq 'testbank') {
  141:         $action = '/adm/testbank';
  142:     } elsif ($mode eq 'imsimport') {
  143:         $action = '/adm/imsimport';
  144:     }
  145:     my $fn='/priv/'.$uname.'/'.$tfn;
  146:     $fn=~s/\/+/\//g;
  147:     &Debug($r, "Filename is ".$tfn);
  148:     if ($tfn) {
  149: 	&Debug($r, "Filename for tfn = ".$tfn);
  150: 	my $target='/home/'.$uname.'/public_html'.$tfn;
  151: 	&Debug($r, "target -> ".$target);
  152: #     target is the full filesystem path of the destination file.
  153: 	my $base = &File::Basename::basename($fn);
  154: 	my $path = &File::Basename::dirname($fn);
  155: 	$base    = &HTML::Entities::encode($base,'<>&"');
  156: 	my $url  = $path."/".$base; 
  157: 	&Debug($r, "URL is now ".$url);
  158: 	my $datatoken=$env{'form.datatoken'};
  159: 	if (($fn) && ($datatoken)) {
  160: 	    if ((-e $target) && ($env{'form.override'} ne 'Yes')) {
  161: 		$r->print('<form action="'.$action.'" method="post">'.
  162: 			  &mt('File').' <span class="LC_filename">'.$fn.'</span> '.
  163: 			  &mt('exists. Overwrite?').' '.
  164: 			  '<input type="hidden" name="phase" value="two" />'.
  165: 			  '<input type="hidden" name="filename" value="'."$url".'" />'.
  166: 			  '<input type="hidden" name="datatoken" value="'.$datatoken.'" />'.
  167: 			  '<input type="submit" name="override" value="'.&mt('Yes').'" /></form>');
  168: 	    } else {
  169: 		my $source=$r->dir_config('lonDaemons').'/tmp/'.$datatoken.'.tmp';
  170: 		my $dirpath=$path.'/';
  171: 		$dirpath=~s/\/+/\//g;
  172: 		# Check for bad extension and disallow upload
  173: 		if ($fn=~/\.(\w+)$/ && 
  174: 		    (&Apache::loncommon::fileembstyle($1) eq 'hdn')) {
  175: 		    $r->print(&mt('File').' <span class="LC_filename">'.$fn.'</span> '.
  176: 			      &mt('could not be copied.').'<br />'.
  177: 			      '<span class="LC_error">'.
  178: 			      &mt('The extension on this file is reserved internally by LON-CAPA.').
  179: 			      '</span>');
  180: 		    $r->print('<br /><font size=+2><a href="'.$dirpath.'">'.
  181: 			      &mt('Back to Directory').'</a></font>');
  182: 		} elsif ($fn=~/\.(\w+)$/ && 
  183: 			 !defined(&Apache::loncommon::fileembstyle($1))) {
  184: 		    $r->print(&mt('File').' <span class="LC_filename">'.$fn.'</span> '.
  185: 			      &mt('could not be copied.').'<br />'.
  186: 			      '<span class="LC_error">'.
  187: 			      &mt('The extension on this file is not recognized by LON-CAPA.').
  188: 			      '</span>');
  189: 		    $r->print('<br /><font size="+2"><a href="'.$dirpath.'">'.
  190: 			      &mt('Back to Directory').'</a></font>');
  191: 		} elsif (-d $target) {
  192: 		    $r->print('File <span class="LC_filename">'.$fn.'</span> could not be copied.<br />'.
  193: 			      '<span class="LC_error">'.
  194: 			      &mt('The target is an existing directory.').
  195: 			      '</span><br />');
  196: 		    $r->print('<font size="+2"><a href="'.$dirpath.'">'.
  197: 			      &mt('Back to Directory').'</a></font>');
  198: 		} elsif (copy($source,$target)) {
  199: 		    chmod(0660, $target); # Set permissions to rw-rw---.
  200:                     if ($mode eq 'testbank' || $mode eq 'imsimport') {
  201:                         $r->print(&mt("Your file - $fn - was uploaded successfully")."<br /><br />");
  202:                         $returnflag = 'ok';
  203:                     } else {
  204:                         $r->print(&mt('File copied.'));
  205: 		        $r->print('<br /><font size="+2"><a href="'.$url.'">'.
  206: 			      &mt('View file').'</a></font>');
  207: 		        $r->print('<br /><font size="+2"><a href="'.$dirpath.'">'.
  208: 			      &mt('Back to Directory').'</a></font><br />');
  209:                     }
  210: 		} else {
  211: 		    $r->print('Failed to copy: '.$!);
  212: 		    $r->print('<br /><font size="+2"><a href="'.$path.'">'.
  213: 			      &mt('Back to Directory').'</a></font>');
  214: 		}
  215: 	    }
  216: 	} else {
  217: 	    $r->print('<span class="LC_error">'.
  218: 		      &mt('Please use browser "Back" button and pick a filename').
  219: 		      '</span><br />');
  220: 	}
  221:     } else {
  222: 	$r->print('<span class="LC_error">'.
  223: 		  &mt('Please use browser "Back" button and pick a filename').
  224: 		  '</span><br />>');
  225:     }
  226:     return $returnflag;
  227: }
  228: 
  229: # ---------------------------------------------------------------- Main Handler
  230: sub handler {
  231: 
  232:     my $r=shift;
  233: 
  234:     my $uname;
  235:     my $udom;
  236:     my $javascript = '';
  237: #
  238: # phase two: re-attach user
  239: #
  240:     if ($env{'form.uploaduname'}) {
  241: 	$env{'form.filename'}='/priv/'.$env{'form.uploaduname'}.'/'.
  242: 	    $env{'form.filename'};
  243:     }
  244: 
  245:     unless ($env{'form.phase'} eq 'two') {
  246: 	my %body_layout = ('rightmargin'  => "0",
  247: 			   'leftmargin'   => "0",
  248: 			   'marginwidth'  => "0",
  249: 			   'topmargin'    => "0",
  250: 			   'marginheight' => "0");
  251: 	my $start_page = 
  252: 	    &Apache::loncommon::start_page('Importing a Testbank file into LON-CAPA',
  253: 					   undef,
  254: 					   {'only_body'   => 1,
  255: 					    'add_entries' => \%body_layout,
  256: 					    'js_ready'    => 1,});
  257: 	my $end_page = 
  258: 	    &Apache::loncommon::end_page({'js_ready' => 1,});
  259: 
  260:         $javascript = qq|
  261: function verifyForm() {
  262:     var mode = document.fileupload.filetype.options[document.fileupload.filetype.selectedIndex].value
  263:     if (mode == "testbank") {
  264:         document.fileupload.action = "/adm/testbank";
  265:     }
  266:     if (mode == "imsimport") {
  267:         document.fileupload.action = "/adm/imsimport";
  268:     }
  269:     if (mode == "standard") {
  270:         document.fileupload.action = "/adm/upload";
  271:     }
  272:     document.fileupload.submit();
  273: }
  274: 	|;
  275:     }
  276:     ($uname,$udom)=
  277: 	&Apache::loncacc::constructaccess($env{'form.filename'},
  278: 					  $r->dir_config('lonDefDomain'));
  279:     unless (($uname) && ($udom)) {
  280: 	$r->log_reason($uname.' at '.$udom.
  281: 		       ' trying to publish file '.$env{'form.filename'}.
  282: 		       ' - not authorized', 
  283: 		       $r->filename); 
  284: 	return HTTP_NOT_ACCEPTABLE;
  285:     }
  286:     
  287:     my $fn;
  288:     if ($env{'form.filename'}) {
  289: 	$fn=$env{'form.filename'};
  290: 	$fn=~s/^http\:\/\/[^\/]+\///;
  291: 	$fn=~s/^\///;
  292: 	$fn=~s/(\~|priv\/)(\w+)//;
  293: 	$fn=~s/\/+/\//g;
  294:     } else {
  295: 	$r->log_reason($env{'user.name'}.' at '.$env{'user.domain'}.
  296: 		       ' unspecified filename for upload', $r->filename); 
  297: 	return HTTP_NOT_FOUND;
  298:     }
  299: 
  300: # ----------------------------------------------------------- Start page output
  301: 
  302: 
  303:     &Apache::loncommon::content_type($r,'text/html');
  304:     $r->send_http_header;
  305: 
  306:    $javascript = "<script type=\"text/javascript\">\n//<!--\n".
  307: 	$javascript."\n// --></script>\n";
  308: 
  309:     $r->print(&Apache::loncommon::start_page('Upload file to Construction Space',
  310: 					     $javascript));
  311:   
  312:     if (($uname ne $env{'user.name'}) || ($udom ne $env{'user.domain'})) {
  313: 	$r->print('<h3><font color=red>'.&mt('Co-Author').': '.$uname.
  314: 		  &mt(' at ').$udom.'</font></h3>');
  315:     }
  316: 
  317:     if ($env{'form.phase'} eq 'two') {
  318: 	&phasetwo($r,$fn,$uname,$udom);
  319:     } else {
  320: 	&phaseone($r,$fn,$uname,$udom);
  321:     }
  322: 
  323:     $r->print(&Apache::loncommon::end_page());
  324:     return OK;  
  325: }
  326: 
  327: 1;
  328: __END__
  329: 
  330: =head1 NAME
  331: 
  332: Apache::lonupload - upload files into construction space
  333: 
  334: =head1 SYNOPSIS
  335: 
  336: Invoked by /etc/httpd/conf/srm.conf:
  337: 
  338:  <Location /adm/upload>
  339:  PerlAccessHandler       Apache::lonacc
  340:  SetHandler perl-script
  341:  PerlHandler Apache::lonupload
  342:  ErrorDocument     403 /adm/login
  343:  ErrorDocument     404 /adm/notfound.html
  344:  ErrorDocument     406 /adm/unauthorized.html
  345:  ErrorDocument	  500 /adm/errorhandler
  346:  </Location>
  347: 
  348: =head1 INTRODUCTION
  349: 
  350: This module uploads a file sitting on a client computer into 
  351: library server construction space.
  352: 
  353: This is part of the LearningOnline Network with CAPA project
  354: described at http://www.lon-capa.org.
  355: 
  356: =head1 HANDLER SUBROUTINE
  357: 
  358: This routine is called by Apache and mod_perl.
  359: 
  360: =over 4
  361: 
  362: =item *
  363: 
  364: Initialize variables
  365: 
  366: =item *
  367: 
  368: Start page output
  369: 
  370: =item *
  371: 
  372: output relevant interface phase (phaseone or phasetwo)
  373: 
  374: =item *
  375: 
  376: (phase one is to specify upload file; phase two is to handle conditions
  377: subsequent to specification--like overwriting an existing file)
  378: 
  379: =back
  380: 
  381: =head1 OTHER SUBROUTINES
  382: 
  383: =over 4
  384: 
  385: =item *
  386: 
  387: phaseone() : Interface for specifying file to upload.
  388: 
  389: =item *
  390: 
  391: phasetwo() : Interface for handling post-conditions about uploading (such
  392: as overwriting an existing file).
  393: 
  394: =item *
  395: 
  396: upfile_store() : Store contents of uploaded file into temporary space.  Invoked
  397: by phaseone subroutine.
  398: 
  399: =back
  400: 
  401: =cut

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