File:  [LON-CAPA] / loncom / interface / londependencies.pm
Revision 1.5: download - view: text, annotated - select for diffs
Sun Aug 13 20:52:59 2017 UTC (6 years, 8 months ago) by raeburn
Branches: MAIN
CVS tags: version_2_12_X, version_2_11_X, version_2_11_4_uiuc, version_2_11_4_msu, version_2_11_4, version_2_11_3_uiuc, version_2_11_3_msu, version_2_11_3, version_2_11_2_msu, HEAD
- Sanity checking.

    1: # The LearningOnline Network with CAPA
    2: # Handler to manage dependencies for HTML files uploaded directly
    3: # to a course. 
    4: #
    5: # $Id: londependencies.pm,v 1.5 2017/08/13 20:52:59 raeburn 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: # /home/httpd/html/adm/gpl.txt
   25: #
   26: # http://www.lon-capa.org/
   27: #
   28: #
   29: ###############################################################
   30: ##############################################################
   31: 
   32: =pod
   33: 
   34: =head1 NAME
   35: 
   36: londependencies- Handler to manage dependencies for HTML files
   37: uploaded directly to a course. 
   38: 
   39: =head1 SYNOPSIS
   40: 
   41: londependencies provides an interface for uploading, replacing 
   42: and deleting files which are dependencies for an HTML page
   43: uploaded directly to a course.
   44: 
   45: =head1 DESCRIPTION
   46: 
   47: This module is used when editing a web page uploaded to a course,
   48: in course context.
   49: 
   50: =head1 INTERNAL SUBROUTINES
   51: 
   52: =over
   53: 
   54: =item process_changes()
   55: 
   56: =item display_dependencies()
   57: 
   58: =back
   59: 
   60: =cut
   61: 
   62: package Apache::londependencies;
   63: 
   64: use strict;
   65: use Apache::Constants qw(:common :http);
   66: use Apache::lonnet;
   67: use Apache::loncommon();
   68: use Apache::lonhtmlcommon();
   69: use Apache::lonlocal;
   70: use LONCAPA qw(:DEFAULT :match);
   71: use File::MMagic;
   72: 
   73: sub handler {
   74:     my $r=shift;
   75:     if ($r->header_only) {
   76:         &Apache::loncommon::content_type($r,'text/html');
   77:         $r->send_http_header;
   78:         return OK;
   79:     }
   80:     my ($allowed,$cnum,$cdom,$chome);
   81:     if ($env{'request.course.id'}) {
   82:         $allowed = &Apache::lonnet::allowed('mdc',$env{'request.course.id'});
   83:     }
   84:     if (!$env{'request.course.fn'} || !$allowed) {
   85:         # Not in a course, or no mdc priv in course
   86:         $env{'user.error.msg'}="/adm/dependencies:mdc:0:0:Cannot display dependencies for page uploaded to course";
   87:         return HTTP_NOT_ACCEPTABLE;
   88:     } else {
   89:         $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
   90:         $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
   91:         $chome = $env{'course.'.$env{'request.course.id'}.'.home'};
   92:     }
   93:     &Apache::loncommon::content_type($r,'text/html');
   94:     $r->send_http_header;
   95: 
   96:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
   97:                                      ['action','symb','title','url','folderpath']);
   98:     my $action = $env{'form.action'};
   99:     my $symb = $env{'form.symb'};
  100:     my $docs_title = $env{'form.title'};
  101:     my $docs_url = $env{'form.url'};
  102:     my $folderpath = &unescape($env{'form.folderpath'});
  103:     my ($mimetype,$numpathchgs,$numrefchanges,%allfiles,%codebase,$url);
  104:     my $earlyout;
  105:     if ($symb) {
  106:         (undef,undef,$url) = &Apache::lonnet::decode_symb($symb);
  107:         unless (&Apache::lonnet::is_on_map($url)) {
  108:             $earlyout = 1;
  109:         }
  110:     } elsif (($docs_url) && (($env{'httpref.'.$docs_url} ne '') ||
  111:                              ($docs_url =~ m{^\Q/uploaded/$cdom/$cnum/\E(portfolio/syllabus)/}))) {
  112:         $url = $docs_url;
  113:         $url =~ s{^/}{};
  114:     }
  115:     my $title = &mt('Manage Dependencies');
  116:     my $state = '<input type="hidden" name="symb" value="'.$symb.'" />'."\n".
  117:                 '<input type="hidden" name="folderpath" value="'.$env{'form.folderpath'}.'" />'."\n".
  118:                 '<input type="hidden" name="title" value="'.$docs_title.'" />'."\n".
  119:                 '<input type="hidden" name="url" value="'.$docs_url.'" />'."\n";
  120:     my $dir_root = '/userfiles';
  121:     my ($destination,$context);
  122:     if ($url =~ m{^\Quploaded/$cdom/$cnum/\E(portfolio/syllabus)/}) {
  123:         $destination = $1;
  124:         $context = 'syllabus';
  125:     } else {
  126:         ($destination) =
  127:             ($url =~ m{^\Quploaded/$cdom/$cnum/\E((?:docs|supplemental)/(?:default|\d+)/\d+)/});
  128:         $context = 'coursedoc';
  129:         if ($destination eq '') {
  130:             $earlyout = 1;
  131:         } 
  132:     }
  133:     my $js = &Apache::loncommon::ask_embedded_js();
  134:     my $output = &Apache::loncommon::start_page($title,$js,
  135:                                                 {'only_body' => 1});
  136:     if ($earlyout) {
  137:         $r->print($output.&mt('Cannot display dependency information - invalid file: [_1].',$url).
  138:                   &Apache::loncommon::end_page());
  139:         return OK;
  140:     }
  141:     if ($action eq 'modifyhrefs') {
  142:         my ($result,$count,$codebasecount) =
  143:             &Apache::loncommon::modify_html_refs('manage_dependencies',$destination,
  144:                                                  $cnum,$cdom,$dir_root);
  145:         $output .= $result;
  146:         $numrefchanges = $count + $codebasecount;
  147:     } elsif ($action eq 'process_changes') {
  148:         (my $result,$numpathchgs) = 
  149:             &process_changes($cdom,$cnum,$chome,$url,$destination,$dir_root,$state,$context);
  150:         $output .= $result;
  151:     }
  152:     unless ((($action eq 'process_changes') && ($numpathchgs > 0)) ||
  153:             (($action eq 'modifyhrefs') && ($numrefchanges > 0))) {
  154:         if ($url =~ m{^\Quploaded/$cdom/$cnum/\E}) {
  155:             $output .= &display_dependencies($url,$state,$docs_title);
  156:         } else {
  157:             $output .= &mt('Cannot display dependency information - invalid file: [_1].',$url);
  158:         }
  159:         $output .= '<p><a href="javascript:window.close()">'.&mt('Close window').'</a>';
  160:     }
  161:     if (($action eq 'modifyhrefs') && ($numrefchanges > 0)) {
  162:         $output .= '<p><a href="javascript:window.opener.location.reload(true);javascript:window.close();">'.
  163:                    &mt('Close pop-up window and reload page').'</a>'; 
  164:     }
  165:     $output .= &Apache::loncommon::end_page();
  166:     $r->print($output);
  167:     return OK;
  168: }
  169: 
  170: sub process_changes {
  171:     my ($cdom,$cnum,$chome,$url,$destination,$dir_root,$state,$context) = @_;
  172:     my ($output,$numpathchgs);
  173:     my ($numnew,$numtodelete,$numtomod) = (0,0,0);
  174:     my $url_root = "/uploaded/$cdom/$cnum";
  175:     if ($destination ne '') {
  176:         my $actionurl = '/adm/dependencies';
  177:         my @deletions = &Apache::loncommon::get_env_multiple('form.del_upload_dep');
  178:         my @modifications = &Apache::loncommon::get_env_multiple('form.mod_upload_dep');
  179:         $numtodelete = scalar(@deletions);
  180:         $numtomod = scalar(@modifications);  
  181:         $numnew = $env{'form.number_newemb_items'};
  182:         if ($numtodelete > 0) {
  183:             my ($outcome,$error);
  184:             my @ids=&Apache::lonnet::current_machine_ids();
  185:             my $dir;
  186:             if (grep(/^\Q$chome\E$/,@ids)) {
  187:                 $dir = &LONCAPA::propath($cdom,$cnum)."$dir_root/$destination";
  188:             }
  189:             foreach my $todelete (@deletions) {
  190:                 my $item = &unescape($env{'form.embedded_orig_'.$todelete});
  191:                 if ($dir eq '') {
  192:                     my $result = 
  193:                         &Apache::lonnet::removeuploadedurl("$url_root/$destination/$item");
  194:                     if ($result eq 'ok') {
  195:                         $outcome .= '<li><span class="LC_filename">'.$item.'</li>';
  196:                     } else {
  197:                         $error .= &mt('Error: [_1] occurred when removing [_2]',$result,$item).'<br />';
  198:                     }
  199:                 } else {
  200:                     if (-e "$dir/$item") {
  201:                         if (unlink("$dir/$item")) {
  202:                             $outcome .= '<li><span class="LC_filename">'.$item.'</li>';
  203:                         } else {
  204:                             $error .= &mt('Removal failed for [_1].',$item).'<br />';
  205:                         }
  206:                     } else {
  207:                         $error .= &mt('File: [_1] not found when attempting removal.',$item).'<br />';
  208:                     }
  209:                 }
  210:             }
  211:             if ($outcome ne '') {
  212:                 $output .= '<h4>'.&mt('Deleted unused files').'</h4>'.
  213:                            '<ul>'.$outcome.'</ul>';
  214:             }
  215:             if ($error ne '') {
  216:                 $output .= '<h4>'.&mt('Error(s) deleting unused files').'</h4>'.
  217:                            '<p class="LC_warning">'.$error.'</p>';
  218:             }
  219:         }
  220:         if ((@modifications > 0) || ($numnew > 0)) {
  221:             (my $result,my $flag,$numpathchgs) =
  222:                 &Apache::loncommon::upload_embedded($context,$destination,$cnum,$cdom,
  223:                                                     $dir_root,$url_root,undef,undef,undef,
  224:                                                     $state,'/adm/dependencies');
  225:             $output .= '<h4>'.&mt('Uploaded files').'</h4>'. 
  226:                        $result;
  227:             unless ($numpathchgs) {
  228:                 if ($context eq 'syllabus') {
  229:                     my $modres =
  230:                         &Apache::loncommon::modify_html_refs($context,'portfolio/syllabus',
  231:                                                              $cnum,$cdom,
  232:                                                              '/userfiles',"/$url");
  233:                     $result .= $modres;
  234:                 }
  235:             }
  236:         }
  237:     } else {
  238:         $output .=  '<span class="LC_warning">'.
  239:                     &mt('Unable to process any requested dependency changes - invalid file: [_1].',$url).
  240:                     '</span>';
  241:     }
  242:     if (!$numtodelete && !$numtomod && !$numnew) { 
  243:         $output .= '<h4>'.&mt('No changes made.').'</h4>';    
  244:     }
  245:     unless ($numpathchgs) {
  246:         $output .= '<hr />';
  247:     }
  248:     return ($output,$numpathchgs);
  249: }
  250: 
  251: sub display_dependencies {
  252:     my ($url,$state,$docs_title) = @_;
  253:     my ($mimetype,%allfiles,%codebase);
  254:     my $output;
  255:     if (&Apache::lonnet::repcopy_userfile("/$url") eq 'ok') {
  256:         my $file=&Apache::lonnet::filelocation("","/$url");
  257:         my $mm = new File::MMagic;
  258:         $mimetype = $mm->checktype_filename($file);
  259:         if ($mimetype eq 'text/html') {
  260:             my $parse_result = &Apache::lonnet::extract_embedded_items($file,\%allfiles,\%codebase);
  261:             if ($parse_result eq 'ok') {
  262:                 my ($embedded,$num,$delnum) =
  263:                     &Apache::loncommon::ask_for_embedded_content(
  264:                         '/adm/dependencies',$state,\%allfiles,\%codebase,
  265:                         {'error_on_invalid_names'   => 1,
  266:                          'ignore_remote_references' => 1,
  267:                          'docs_url'                 => $url,
  268:                          'docs_title'               => $docs_title});
  269:                 if ($embedded) {
  270:                     $output .= $embedded;
  271:                 } else {
  272:                     $output .= &mt('This file has no dependencies.').'<br />';
  273:                 }
  274:             } else {
  275:                 $output .= '<span class="LC_warning">'.
  276:                            &mt('Could not parse HTML file: [_1] to identify existing dependencies.',"/$url").
  277:                            '</span>';
  278:             }
  279:         } else {
  280:             $output .= '<span class="LC_warning">'.
  281:                        &mt('File: [_1] does not appear to be an HTML file.',"/$url").
  282:                        '</span>';
  283:         }
  284:     } else {
  285:         $output .= '<span class="LC_warning">'.
  286:                    &mt('Failed to access HTML file: [_1] to identify existing dependencies.',
  287:                    "/$url");
  288:     }
  289:     return $output;
  290: }
  291: 
  292: 1;

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