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 (7 years, 5 months ago) by
raeburn
Branches:
MAIN
CVS tags:
version_2_12_X,
version_2_11_X,
version_2_11_6,
version_2_11_5_msu,
version_2_11_5,
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.
# The LearningOnline Network with CAPA
# Handler to manage dependencies for HTML files uploaded directly
# to a course.
#
# $Id: londependencies.pm,v 1.5 2017/08/13 20:52:59 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','url','folderpath']);
my $action = $env{'form.action'};
my $symb = $env{'form.symb'};
my $docs_title = $env{'form.title'};
my $docs_url = $env{'form.url'};
my $folderpath = &unescape($env{'form.folderpath'});
my ($mimetype,$numpathchgs,$numrefchanges,%allfiles,%codebase,$url);
my $earlyout;
if ($symb) {
(undef,undef,$url) = &Apache::lonnet::decode_symb($symb);
unless (&Apache::lonnet::is_on_map($url)) {
$earlyout = 1;
}
} elsif (($docs_url) && (($env{'httpref.'.$docs_url} ne '') ||
($docs_url =~ m{^\Q/uploaded/$cdom/$cnum/\E(portfolio/syllabus)/}))) {
$url = $docs_url;
$url =~ s{^/}{};
}
my $title = &mt('Manage Dependencies');
my $state = '<input type="hidden" name="symb" value="'.$symb.'" />'."\n".
'<input type="hidden" name="folderpath" value="'.$env{'form.folderpath'}.'" />'."\n".
'<input type="hidden" name="title" value="'.$docs_title.'" />'."\n".
'<input type="hidden" name="url" value="'.$docs_url.'" />'."\n";
my $dir_root = '/userfiles';
my ($destination,$context);
if ($url =~ m{^\Quploaded/$cdom/$cnum/\E(portfolio/syllabus)/}) {
$destination = $1;
$context = 'syllabus';
} else {
($destination) =
($url =~ m{^\Quploaded/$cdom/$cnum/\E((?:docs|supplemental)/(?:default|\d+)/\d+)/});
$context = 'coursedoc';
if ($destination eq '') {
$earlyout = 1;
}
}
my $js = &Apache::loncommon::ask_embedded_js();
my $output = &Apache::loncommon::start_page($title,$js,
{'only_body' => 1});
if ($earlyout) {
$r->print($output.&mt('Cannot display dependency information - invalid file: [_1].',$url).
&Apache::loncommon::end_page());
return OK;
}
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,$context);
$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 .= '<p><a href="javascript:window.close()">'.&mt('Close window').'</a>';
}
if (($action eq 'modifyhrefs') && ($numrefchanges > 0)) {
$output .= '<p><a href="javascript:window.opener.location.reload(true);javascript:window.close();">'.
&mt('Close pop-up window and reload page').'</a>';
}
$output .= &Apache::loncommon::end_page();
$r->print($output);
return OK;
}
sub process_changes {
my ($cdom,$cnum,$chome,$url,$destination,$dir_root,$state,$context) = @_;
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 .= '<li><span class="LC_filename">'.$item.'</li>';
} else {
$error .= &mt('Error: [_1] occurred when removing [_2]',$result,$item).'<br />';
}
} else {
if (-e "$dir/$item") {
if (unlink("$dir/$item")) {
$outcome .= '<li><span class="LC_filename">'.$item.'</li>';
} else {
$error .= &mt('Removal failed for [_1].',$item).'<br />';
}
} else {
$error .= &mt('File: [_1] not found when attempting removal.',$item).'<br />';
}
}
}
if ($outcome ne '') {
$output .= '<h4>'.&mt('Deleted unused files').'</h4>'.
'<ul>'.$outcome.'</ul>';
}
if ($error ne '') {
$output .= '<h4>'.&mt('Error(s) deleting unused files').'</h4>'.
'<p class="LC_warning">'.$error.'</p>';
}
}
if ((@modifications > 0) || ($numnew > 0)) {
(my $result,my $flag,$numpathchgs) =
&Apache::loncommon::upload_embedded($context,$destination,$cnum,$cdom,
$dir_root,$url_root,undef,undef,undef,
$state,'/adm/dependencies');
$output .= '<h4>'.&mt('Uploaded files').'</h4>'.
$result;
unless ($numpathchgs) {
if ($context eq 'syllabus') {
my $modres =
&Apache::loncommon::modify_html_refs($context,'portfolio/syllabus',
$cnum,$cdom,
'/userfiles',"/$url");
$result .= $modres;
}
}
}
} else {
$output .= '<span class="LC_warning">'.
&mt('Unable to process any requested dependency changes - invalid file: [_1].',$url).
'</span>';
}
if (!$numtodelete && !$numtomod && !$numnew) {
$output .= '<h4>'.&mt('No changes made.').'</h4>';
}
unless ($numpathchgs) {
$output .= '<hr />';
}
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.').'<br />';
}
} else {
$output .= '<span class="LC_warning">'.
&mt('Could not parse HTML file: [_1] to identify existing dependencies.',"/$url").
'</span>';
}
} else {
$output .= '<span class="LC_warning">'.
&mt('File: [_1] does not appear to be an HTML file.',"/$url").
'</span>';
}
} else {
$output .= '<span class="LC_warning">'.
&mt('Failed to access HTML file: [_1] to identify existing dependencies.',
"/$url");
}
return $output;
}
1;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>