Diff for /loncom/publisher/lonupload.pm between versions 1.49 and 1.68

version 1.49, 2010/02/16 10:26:17 version 1.68, 2017/11/12 23:01:00
Line 1 Line 1
   
 # The LearningOnline Network with CAPA  # The LearningOnline Network with CAPA
 # Handler to upload files into construction space  # Handler to upload files into construction space
 #  #
Line 70  Start page output Line 69  Start page output
   
 =item *  =item *
   
 output relevant interface phase (phaseone or phasetwo or phasethree)  output relevant interface phase (phaseone, phasetwo, phasethree or phasefour)
   
 =item *  =item *
   
Line 99  as overwriting an existing file). Line 98  as overwriting an existing file).
 Interface for handling secondary uploads of embedded objects  Interface for handling secondary uploads of embedded objects
 in an html file.  in an html file.
   
   =item phasefour()
   
   Interface for handling optional renaming of links to embedded
   objects. 
   
 =item upfile_store()  =item upfile_store()
   
 Store contents of uploaded file into temporary space.  Invoked  Store contents of uploaded file into temporary space.  Invoked
Line 121  use Apache::File; Line 125  use Apache::File;
 use File::Copy;  use File::Copy;
 use File::Basename;  use File::Basename;
 use Apache::Constants qw(:common :http :methods);  use Apache::Constants qw(:common :http :methods);
 use Apache::loncacc;  
 use Apache::loncommon();  use Apache::loncommon();
 use Apache::lonnet;  use Apache::lonnet;
 use HTML::Entities();  use HTML::Entities();
 use Apache::lonlocal;  use Apache::lonlocal;
 use Apache::lonnet;  use Apache::lonnet;
 use LONCAPA();  use LONCAPA qw(:DEFAULT :match);
   
 my $DEBUG=0;  my $DEBUG=0;
   
Line 147  sub upfile_store { Line 150  sub upfile_store {
           
     chomp($env{'form.upfile'});      chomp($env{'form.upfile'});
       
     my $datatoken=$env{'user.name'}.'_'.$env{'user.domain'}.      my $datatoken;
   '_upload_'.$fname.'_'.time.'_'.$$;      if (($env{'user.name'} =~ /^$match_username$/) && ($env{'user.domain'} =~ /^$match_domain$/)) {
           $datatoken=$env{'user.name'}.'_'.$env{'user.domain'}.
                      '_upload_'.$fname.'_'.time.'_'.$$;
       }
       return if ($datatoken eq '');
     {      {
        my $fh=Apache::File->new('>'.$r->dir_config('lonDaemons').         my $fh=Apache::File->new('>'.$r->dir_config('lonDaemons').
                                    '/tmp/'.$datatoken.'.tmp');                                     '/tmp/'.$datatoken.'.tmp');
Line 158  sub upfile_store { Line 165  sub upfile_store {
 }  }
   
 sub phaseone {  sub phaseone {
     my ($r,$fn,$uname,$udom,$mode)=@_;      my ($r,$fn,$mode,$uname,$udom)=@_;
     my $action = '/adm/upload';      my $action = '/adm/upload';
     if ($mode eq 'testbank') {      if ($mode eq 'testbank') {
         $action = '/adm/testbank';          $action = '/adm/testbank';
Line 170  sub phaseone { Line 177  sub phaseone {
     $env{'form.upfile.filename'}=~s/\\/\//g;      $env{'form.upfile.filename'}=~s/\\/\//g;
     $env{'form.upfile.filename'}=~s/^.*\/([^\/]+)$/$1/;      $env{'form.upfile.filename'}=~s/^.*\/([^\/]+)$/$1/;
     if (!$env{'form.upfile.filename'}) {      if (!$env{'form.upfile.filename'}) {
         $r->print('<p class="LC_warning">'.&mt('No upload file specified.').'</p>');          $r->print('<p class="LC_warning">'.&mt('No upload file specified.').'</p>'.
                     &earlyout($fn,$uname,$udom));
         return;          return;
     }      }
   
     $fn=~s/\/[^\/]+$//;      # Append the name of the uploaded file
     $fn=~s/([^\/])$/$1\//;  
     $fn.=$env{'form.upfile.filename'};      $fn.=$env{'form.upfile.filename'};
     $fn=~s/^\///;  
     $fn=~s/(\/)+/\//g;      $fn=~s/(\/)+/\//g;
     #    Fn is the full path to the destination filename.  
   
     # Check for illegal filename      # Check for illegal filename
     &Debug($r, "Filename for upload: $fn");      &Debug($r, "Filename for upload: $fn");
Line 187  sub phaseone { Line 192  sub phaseone {
         $r->print('<p class="LC_warning">'.&mt('Illegal filename.').'</p>');          $r->print('<p class="LC_warning">'.&mt('Illegal filename.').'</p>');
         return;          return;
     }      }
       # Check if quota exceeded
       my $filesize = length($env{'form.upfile'});
       if (!$filesize) {
           $r->print('<p class="LC_warning">'.
                     &mt('Unable to upload [_1]. (size = [_2] bytes)',
                         '<span class="LC_filename">'.$env{'form.upfile.filename'}.'</span>',
                         $filesize).'<br />'.
                     &mt('Either the file you attempted to upload was empty, or your web browser was unable to read its contents.').'<br />'.
                     '</p>'.
                     &earlyout($fn,$uname,$udom));
           return;
       }
       $filesize = int($filesize/1000); #expressed in kb
       my $output = &Apache::loncommon::excess_filesize_warning($uname,$udom,'author',
                                                                $env{'form.upfile.filename'},$filesize,'upload');
       if ($output) {
           $r->print($output.&earlyout($fn,$uname,$udom));
           return;
       }
   
   # Split part that I can change from the part that I cannot change
       my ($fn1,$fn2)=($fn=~/^(\/priv\/[^\/]+\/[^\/]+\/)(.*)$/);
     # Display additional options for upload      # Display additional options for upload
     # and upload button      # and upload button
     $r->print(      $r->print(
         '<form action="'.$action.'" method="post" name="fileupload">'          '<form action="'.$action.'" method="post" name="fileupload">'
        .'<input type="hidden" name="phase" value="two" />'         .'<input type="hidden" name="phase" value="two" />'
        .'<input type="hidden" name="datatoken" value="'.&upfile_store.'" />'         .'<input type="hidden" name="datatoken" value="'.&upfile_store.'" />'
        .'<input type="hidden" name="uploaduname" value="'.$uname.'" />'  
     );      );
     $r->print(      $r->print(
         &Apache::lonhtmlcommon::start_pick_box()          &Apache::lonhtmlcommon::start_pick_box()
        .&Apache::lonhtmlcommon::row_title(&mt('Save uploaded file as'))         .&Apache::lonhtmlcommon::row_title(&mt('Save uploaded file as'))
        .'<span class="LC_filename">/priv/'.$uname.'/</span>'         .'<span class="LC_filename">'.$fn1.'</span>'
        .'<input type="text" size="50" name="filename" value="'.$fn.'" />'         .'<input type="hidden" name="filename1" value="'.$fn1.'" />'
          .'<input type="text" size="50" name="filename2" value="'.$fn2.'" />'
        .&Apache::lonhtmlcommon::row_closure()         .&Apache::lonhtmlcommon::row_closure()
        .&Apache::lonhtmlcommon::row_title(&mt('File Type'))         .&Apache::lonhtmlcommon::row_title(&mt('File Type'))
        .'<select name="filetype">'         .'<select name="filetype">'
Line 237  sub phaseone { Line 263  sub phaseone {
 }  }
   
 sub phasetwo {  sub phasetwo {
     my ($r,$tfn,$uname,$udom,$mode)=@_;      my ($r,$fn,$mode)=@_;
   
     my $output;      my $output;
     my $action = '/adm/upload';      my $action = '/adm/upload';
     my $returnflag = '';      my $returnflag = '';
Line 246  sub phasetwo { Line 273  sub phasetwo {
     } elsif ($mode eq 'imsimport') {      } elsif ($mode eq 'imsimport') {
         $action = '/adm/imsimport';          $action = '/adm/imsimport';
     }      }
     my $fn='/priv/'.$uname.'/'.$tfn;  
     $fn=~s/\/+/\//g;      $fn=~s/\/+/\//g;
     &Debug($r, "Filename is ".$tfn);      if ($fn) {
     if ($tfn) {   my $target= $r->dir_config('lonDocRoot').'/'.$fn;
  &Debug($r, "Filename for tfn = ".$tfn);  
  my $target='/home/'.$uname.'/public_html'.$tfn;  
  &Debug($r, "target -> ".$target);   &Debug($r, "target -> ".$target);
 #     target is the full filesystem path of the destination file.  #     target is the full filesystem path of the destination file.
  my $base = &File::Basename::basename($fn);   my $base = &File::Basename::basename($fn);
Line 259  sub phasetwo { Line 283  sub phasetwo {
  $base    = &HTML::Entities::encode($base,'<>&"');   $base    = &HTML::Entities::encode($base,'<>&"');
  my $url  = $path."/".$base;    my $url  = $path."/".$base; 
  &Debug($r, "URL is now ".$url);   &Debug($r, "URL is now ".$url);
  my $datatoken=$env{'form.datatoken'};   my $datatoken;
           if ($env{'form.datatoken'} =~ /^$match_username\_$match_domain\_upload_\w*_\d+_\d+$/) {
               $datatoken = $env{'form.datatoken'};
           }
  if (($fn) && ($datatoken)) {   if (($fn) && ($datatoken)) {
             if ($env{'form.cancel'}) {              if ($env{'form.cancel'}) {
                 my $source=$r->dir_config('lonDaemons').'/tmp/'.$datatoken.'.tmp';                  my $source=$r->dir_config('lonDaemons').'/tmp/'.$datatoken.'.tmp';
Line 350  sub check_extension { Line 377  sub check_extension {
             my (%allfiles,%codebase);              my (%allfiles,%codebase);
             &Apache::lonnet::extract_embedded_items($target,\%allfiles,\%codebase);              &Apache::lonnet::extract_embedded_items($target,\%allfiles,\%codebase);
             if (keys(%allfiles) > 0) {              if (keys(%allfiles) > 0) {
                 my $state = <<STATE;                  my ($currentpath) = ($url =~ m{^(.+)/[^/]+$});
     <input type="hidden" name="action"      value="upload_embedded" />                  my $state = &embedded_form_elems('upload_embedded',$url,$mode);
     <input type="hidden" name="currentpath" value="$env{'form.currentpath'}" />                  my ($embedded,$num,$pathchg) = 
     <input type="hidden" name="mode"        value="$mode" />                      &Apache::loncommon::ask_for_embedded_content($action,$state,\%allfiles,
     <input type="hidden" name="phase"       value="three" />                                                                   \%codebase,
     <input type="hidden" name="filename" value="$url" />                                                                   {'error_on_invalid_names'   => 1,
 STATE                                                                    'ignore_remote_references' => 1,
                 $result .= "<h3>".&mt("Reference Warning")."</h3>".                                                                    'current_path'             => $currentpath});
                            "<p>".&mt("Completed upload of the file. This file contained references to other files.")."</p>".                  if ($embedded) {
                           "<p>".&mt("Please select the locations from which the referenced files are to be uploaded.")."</p>".                      $result .= '<h3>'.&mt('Reference Warning').'</h3>';
                           &Apache::loncommon::ask_for_embedded_content($action,$state,\%allfiles,\%codebase,                      if ($num) {
                                       {'error_on_invalid_names'   => 1,                          $result .= '<p>'.&mt('Completed upload of the file.').' '.&mt('This file contained references to other files.').'</p>'.
                                        'ignore_remote_references' => 1,});                                     '<p>'.&mt('Please select the locations from which the referenced files are to be uploaded.').'</p>'.
                 if ($mode eq 'testbank') {                                     $embedded;
                     $returnflag = 'embedded';                          if ($mode eq 'testbank') {
                     $result .=  '<p>'.&mt('Or [_1]continue[_2] the testbank import without these files','<a href="javascript:document.testbankForm.submit();">','</a>').'</p>';                              $returnflag = 'embedded';
                               $result .=  '<p>'.&mt('Or [_1]continue[_2] the testbank import without these files.','<a href="javascript:document.testbankForm.submit();">','</a>').'</p>';
                           }
                       } else {
                           $result .= '<p>'.&mt('Completed upload of the file.').'</p>'.$embedded;
                           if ($pathchg) {
                               if ($mode eq 'testbank') {
                                   $returnflag = 'embedded';
                                   $result .=  '<p>'.&mt('Or [_1]continue[_2] the testbank import without modifying the reference(s).','<a href="javascript:document.testbankForm.submit();">','</a>').'</p>';
                               }
                           }
                       }
                 }                  }
             }              }
         }          }
Line 385  STATE Line 423  STATE
   
 sub phasethree {  sub phasethree {
     my ($r,$fn,$uname,$udom,$mode) = @_;      my ($r,$fn,$uname,$udom,$mode) = @_;
   
       my $action = '/adm/upload'; 
       if ($mode eq 'testbank') {
           $action = '/adm/testbank';
       } elsif ($mode eq 'imsimport') {
           $action = '/adm/imsimport';
       }
       my $url_root = "/priv/$udom/$uname";
       my $dir_root = $r->dir_config('lonDocRoot').$url_root;
       my $path = &File::Basename::dirname($fn);
       $path =~ s{^\Q$url_root\E}{};
       my $dirpath = $url_root.$path.'/';
       $dirpath=~s{/+}{/}g;
       my $filename = &HTML::Entities::encode($env{'form.filename'},'<>&"');
       my $state = &embedded_form_elems('modify_orightml',$filename,$mode).
                   '<input type="hidden" name="phase" value="four" />';
       my ($result,$returnflag) = 
           &Apache::loncommon::upload_embedded($mode,$path,$uname,$udom,
                                               $dir_root,$url_root,undef,
                                               undef,undef,$state,$action);
       if ($mode ne 'imsimport' && $mode ne 'testbank') {
           $result .= '<br /><h3><a href="'.$fn.'">'.
                     &mt('View main file').'</a></h3>'.
                     '<h3><a href="'.$dirpath.'">'.
                     &mt('Back to Directory').'</a></h3><br />';
       }
       return ($result,$returnflag);
   }
   
   sub embedded_form_elems {
       my ($action,$filename,$mode) = @_;
       return <<STATE;
       <input type="hidden" name="action" value="$action" />
       <input type="hidden" name="mode" value="$mode" />
       <input type="hidden" name="filename" value="$filename" />
   STATE
   }
   
   sub phasefour {
       my ($r,$fn,$uname,$udom,$mode) = @_;
   
       my $action = '/adm/upload';
       if ($mode eq 'testbank') {
           $action = '/adm/testbank';
       } elsif ($mode eq 'imsimport') {
           $action = '/adm/imsimport';
       }
     my $result;      my $result;
     my $dir_root = '/home/'.$uname.'/public_html';      my $url_root = "/priv/$udom/$uname";
     my $url_root = '/priv/'.$uname;      my $dir_root = $r->dir_config('lonDocRoot').$url_root;
     my $base = &File::Basename::basename($fn);  
     my $path = &File::Basename::dirname($fn);      my $path = &File::Basename::dirname($fn);
     $result = &Apache::loncommon::upload_embedded($mode,$path,$uname,$udom,      $path =~ s{^\Q$url_root\E}{};
                                                   $dir_root,$url_root);      my $dirpath = $url_root.$path.'/';
       $dirpath=~s{/+}{/}g;
       my $outcome = 
           &Apache::loncommon::modify_html_refs($mode,$path,$uname,$udom,$dir_root);
       $result .= $outcome;
     if ($mode ne 'imsimport' && $mode ne 'testbank') {      if ($mode ne 'imsimport' && $mode ne 'testbank') {
         $result = '<br /><font size="+2"><a href="'.$url_root.$fn.'">'.          $result .= '<br /><h3><a href="'.$fn.'">'.
                   &mt('View main file').'</a></font>'.                    &mt('View main file').'</a></h3>'.
                   '<br /><font size="+2"><a href="'.$url_root.$path.'">'.                    '<h3><a href="'.$dirpath.'">'.
                   &mt('Back to Directory').'</a></font><br />';                    &mt('Back to Directory').'</a></h3><br />';
     }      }
     return $result;      return $result;
 }  }
   
   sub earlyout {
       my ($fn,$uname,$udom) = @_;
       if ($fn =~ m{^(/priv/$udom/$uname(?:.*)/)[^/]*}) {
           return &Apache::lonhtmlcommon::actionbox(
                  ['<a href="'.$1.'">'.&mt('Return to Directory').'</a>']);
       }
       return;
   }
   
 # ---------------------------------------------------------------- Main Handler  # ---------------------------------------------------------------- Main Handler
 sub handler {  sub handler {
   
     my $r=shift;      my $r=shift;
   
     my $uname;  
     my $udom;  
     my $javascript = '';      my $javascript = '';
 #      my $fn=$env{'form.filename'};
 # phase two: re-attach user  
 #      if ($env{'form.filename1'}) {
     if ($env{'form.uploaduname'}) {         $fn=$env{'form.filename1'}.$env{'form.filename2'};
  $env{'form.filename'}='/priv/'.$env{'form.uploaduname'}.'/'.  
     $env{'form.filename'};  
     }      }
       $fn=~s/\/+/\//g;
   
       unless ($fn) {
           $r->log_reason($env{'user.name'}.' at '.$env{'user.domain'}.
                          ' unspecified filename for upload', $r->filename);
           return HTTP_NOT_FOUND;
       }
   
       my ($uname,$udom)=&Apache::lonnet::constructaccess($fn);
   
       unless (($uname) && ($udom)) {
           $r->log_reason($uname.' at '.$udom.
                          ' trying to publish file '.$env{'form.filename'}.
                          ' - not authorized',
                          $r->filename);
           return HTTP_NOT_ACCEPTABLE;
       }
   
   # ----------------------------------------------------------- Start page output
   
       &Apache::loncommon::content_type($r,'text/html');
       $r->send_http_header;
   
     unless ($env{'form.phase'} eq 'two') {      unless ($env{'form.phase'} eq 'two') {
         $javascript = qq|          $javascript = <<"ENDJS";
   <script type="text/javascript">
   // <![CDATA[
 function verifyForm() {  function verifyForm() {
     var mode = document.fileupload.filetype.options[document.fileupload.filetype.selectedIndex].value      var mode = document.fileupload.filetype.options[document.fileupload.filetype.selectedIndex].value
     if (mode == "testbank") {      if (mode == "testbank") {
Line 432  function verifyForm() { Line 548  function verifyForm() {
     }      }
     document.fileupload.submit();      document.fileupload.submit();
 }  }
  |;  // ]]>
     }  </script>
     ($uname,$udom)=  ENDJS
  &Apache::loncacc::constructaccess($env{'form.filename'},  
   $r->dir_config('lonDefDomain'));  
   
     unless (($uname) && ($udom)) {  
  $r->log_reason($uname.' at '.$udom.  
        ' trying to publish file '.$env{'form.filename'}.  
        ' - not authorized',   
        $r->filename);   
  return HTTP_NOT_ACCEPTABLE;  
     }  
       
     my $fn;  
     if ($env{'form.filename'}) {  
  $fn=$env{'form.filename'};  
  $fn=~s/^https?\:\/\/[^\/]+\///;  
  $fn=~s/^\///;  
  $fn=~s{(~|priv/)($LONCAPA::username_re)}{};  
  $fn=~s/\/+/\//g;  
     } else {  
  $r->log_reason($env{'user.name'}.' at '.$env{'user.domain'}.  
        ' unspecified filename for upload', $r->filename);   
  return HTTP_NOT_FOUND;  
     }      }
   
 # ----------------------------------------------------------- Start page output      my $londocroot = $r->dir_config('lonDocRoot');
       my $trailfile = $fn;
       $trailfile =~ s{^/(priv/)}{$londocroot/$1};
     &Apache::loncommon::content_type($r,'text/html');  
     $r->send_http_header;  
   
    $javascript = "<script type=\"text/javascript\">\n//<!--\n".  
  $javascript."\n// --></script>\n";  
   
     # Breadcrumbs      # Breadcrumbs
     my $brcrum = [{'href' => &Apache::loncommon::authorspace(),      my $brcrum = [{'href' => &Apache::loncommon::authorspace($fn),
                    'text' => 'Construction Space'},                     'text' => 'Authoring Space'},
                   {'href' => '/adm/upload',                    {'href' => '/adm/upload',
                    'text' => 'Upload file to Construction Space'}];                     'text' => 'Upload file to Authoring Space'}];
     $r->print(&Apache::loncommon::start_page('Upload file to Construction Space',      $r->print(&Apache::loncommon::start_page('Upload file to Authoring Space',
                                              $javascript,                                               $javascript,
                                              {'bread_crumbs' => $brcrum,})                                               {'bread_crumbs' => $brcrum,})
              .&Apache::loncommon::head_subbox(               .&Apache::loncommon::head_subbox(
                 &Apache::loncommon::CSTR_pageheader())                  &Apache::loncommon::CSTR_pageheader($trailfile))
     );      );
       
     if (($uname ne $env{'user.name'}) || ($udom ne $env{'user.domain'})) {      if (($uname ne $env{'user.name'}) || ($udom ne $env{'user.domain'})) {
         $r->print('<p class="LC_warning">'          $r->print('<p class="LC_info">'
                  .&mt('Co-Author [_1]',$uname.':'.$udom)                   .&mt('Co-Author [_1]',$uname.':'.$udom)
                  .'</p>'                   .'</p>'
         );          );
     }      }
       if ($env{'form.phase'} eq 'four') {
     if ($env{'form.phase'} eq 'three') {          my $output = &phasefour($r,$fn,$uname,$udom,'author');
         my $output = &phasethree($r,$fn,$uname,$udom,'author');          $r->print($output);
       } elsif ($env{'form.phase'} eq 'three') {
           my ($output,$rtnflag) = &phasethree($r,$fn,$uname,$udom,'author');
         $r->print($output);          $r->print($output);
     } elsif ($env{'form.phase'} eq 'two') {      } elsif ($env{'form.phase'} eq 'two') {
  my ($output,$returnflag) = &phasetwo($r,$fn,$uname,$udom);   my ($output,$returnflag) = &phasetwo($r,$fn);
         $r->print($output);          $r->print($output);
     } else {      } else {
  &phaseone($r,$fn,$uname,$udom);   &phaseone($r,$fn,undef,$uname,$udom);
     }      }
   
     $r->print(&Apache::loncommon::end_page());      $r->print(&Apache::loncommon::end_page());

Removed from v.1.49  
changed lines
  Added in v.1.68


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