# The LearningOnline Network with CAPA # Handler to manage dependencies for HTML files uploaded directly # to a course. # # $Id: londependencies.pm,v 1.1 2012/04/16 19:59:12 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # # This file is part of the LearningOnline Network with CAPA (LON-CAPA). # # LON-CAPA is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # LON-CAPA is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with LON-CAPA; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA# # /home/httpd/html/adm/gpl.txt # # http://www.lon-capa.org/ # # ############################################################### ############################################################## =pod =head1 NAME londependencies- Handler to manage dependencies for HTML files uploaded directly to a course. =head1 SYNOPSIS londependencies provides an interface for uploading, replacing and deleting files which are dependencies for an HTML page uploaded directly to a course. =head1 DESCRIPTION This module is used when editing a web page uploaded to a course, in course context. =head1 INTERNAL SUBROUTINES =over =item process_changes() =item display_dependencies() =back =cut package Apache::londependencies; use strict; use Apache::Constants qw(:common :http); use Apache::lonnet; use Apache::loncommon(); use Apache::lonhtmlcommon(); use Apache::lonlocal; use LONCAPA qw(:DEFAULT :match); use File::MMagic; sub handler { my $r=shift; if ($r->header_only) { &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; return OK; } my ($allowed,$cnum,$cdom,$chome); if ($env{'request.course.id'}) { $allowed = &Apache::lonnet::allowed('mdc',$env{'request.course.id'}); } if (!$env{'request.course.fn'} || !$allowed) { # Not in a course, or no mdc priv in course $env{'user.error.msg'}="/adm/dependencies:mdc:0:0:Cannot display dependencies for page uploaded to course"; return HTTP_NOT_ACCEPTABLE; } else { $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; $chome = $env{'course.'.$env{'request.course.id'}.'.home'}; } &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['action','symb','title']); my $action = $env{'form.action'}; my $symb = $env{'form.symb'}; my $docs_title = $env{'form.title'}; my ($mimetype,$numpathchgs,$numrefchanges,%allfiles,%codebase); my ($map,$id,$url) = &Apache::lonnet::decode_symb($symb); my $title = &mt('Manage Dependencies'); my $state = ''."\n". ''."\n"; my $dir_root = '/userfiles'; my ($destination) = ($url =~ m{^\Quploaded/$cdom/$cnum/\E((?:docs|supplemental)/(?:default|\d+)/\d+)/}); my $js = &Apache::loncommon::ask_embedded_js(); my $output = &Apache::loncommon::start_page($title,$js, {'only_body' => 1}); if ($action eq 'modifyhrefs') { my ($result,$count,$codebasecount) = &Apache::loncommon::modify_html_refs('manage_dependencies',$destination, $cnum,$cdom,$dir_root); $output .= $result; $numrefchanges = $count + $codebasecount; } elsif ($action eq 'process_changes') { (my $result,$numpathchgs) = &process_changes($cdom,$cnum,$chome,$url,$destination,$dir_root,$state); $output .= $result; } unless ((($action eq 'process_changes') && ($numpathchgs > 0)) || (($action eq 'modifyhrefs') && ($numrefchanges > 0))) { if ($url =~ m{^\Quploaded/$cdom/$cnum/\E}) { $output .= &display_dependencies($url,$state,$docs_title); } else { $output .= &mt('Cannot display dependency information - invalid file: [_1].',$url); } $output .= '

'.&mt('Close window').''; } if (($action eq 'modifyhrefs') && ($numrefchanges > 0)) { $output .= '

'. &mt('Close pop-up window and reload page').''; } $output .= &Apache::loncommon::end_page(); $r->print($output); return OK; } sub process_changes { my ($cdom,$cnum,$chome,$url,$destination,$dir_root,$state) = @_; my ($output,$numpathchgs); my ($numnew,$numtodelete,$numtomod) = (0,0,0); my $url_root = "/uploaded/$cdom/$cnum"; if ($destination ne '') { my $actionurl = '/adm/dependencies'; my @deletions = &Apache::loncommon::get_env_multiple('form.del_upload_dep'); my @modifications = &Apache::loncommon::get_env_multiple('form.mod_upload_dep'); $numtodelete = scalar(@deletions); $numtomod = scalar(@modifications); $numnew = $env{'form.number_newemb_items'}; if ($numtodelete > 0) { my ($outcome,$error); my @ids=&Apache::lonnet::current_machine_ids(); my $dir; if (grep(/^\Q$chome\E$/,@ids)) { $dir = &LONCAPA::propath($cdom,$cnum)."$dir_root/$destination"; } foreach my $todelete (@deletions) { my $item = &unescape($env{'form.embedded_orig_'.$todelete}); if ($dir eq '') { my $result = &Apache::lonnet::removeuploadedurl("$url_root/$destination/$item"); if ($result eq 'ok') { $outcome .= '

  • '.$item.'
  • '; } else { $error .= &mt('Error: [_1] occurred when removing [_2]',$result,$item).'
    '; } } else { if (-e "$dir/$item") { if (unlink("$dir/$item")) { $outcome .= '
  • '.$item.'
  • '; } else { $error .= &mt('Removal failed for [_1].',$item).'
    '; } } else { $error .= &mt('File: [_1] not found when attempting removal.',$item).'
    '; } } } if ($outcome ne '') { $output .= '

    '.&mt('Deleted unused files').'

    '. ''; } if ($error ne '') { $output .= '

    '.&mt('Error(s) deleting unused files').'

    '. '

    '.$error.'

    '; } } if ((@modifications > 0) || ($numnew > 0)) { (my $result,my $flag,$numpathchgs) = &Apache::loncommon::upload_embedded('coursedoc',$destination,$cnum,$cdom, $dir_root,$url_root,undef,undef,undef, $state,'/adm/dependencies'); $output .= '

    '.&mt('Uploaded files').'

    '. $result; } } else { $output .= ''. &mt('Unable to process any requested dependency changes - invalid file: [_1].',$url). ''; } if (!$numtodelete && !$numtomod && !$numnew) { $output .= '

    '.&mt('No changes made.').'

    '; } unless ($numpathchgs) { $output .= '
    '; } return ($output,$numpathchgs); } sub display_dependencies { my ($url,$state,$docs_title) = @_; my ($mimetype,%allfiles,%codebase); my $output; if (&Apache::lonnet::repcopy_userfile("/$url") eq 'ok') { my $file=&Apache::lonnet::filelocation("","/$url"); my $mm = new File::MMagic; $mimetype = $mm->checktype_filename($file); if ($mimetype eq 'text/html') { my $parse_result = &Apache::lonnet::extract_embedded_items($file,\%allfiles,\%codebase); if ($parse_result eq 'ok') { my ($embedded,$num,$delnum) = &Apache::loncommon::ask_for_embedded_content( '/adm/dependencies',$state,\%allfiles,\%codebase, {'error_on_invalid_names' => 1, 'ignore_remote_references' => 1, 'docs_url' => $url, 'docs_title' => $docs_title}); if ($embedded) { $output .= $embedded; } else { $output .= &mt('This file has no dependencies.').'
    '; } } else { $output .= ''. &mt('Could not parse HTML file: [_1] to identify existing dependencies.',"/$url"). ''; } } else { $output .= ''. &mt('File: [_1] does not appear to be an HTML file.',"/$url"). ''; } } else { $output .= ''. &mt('Failed to access HTML file: [_1] to identify existing dependencies.', "/$url"); } return $output; } 1;