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, 7 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.

# 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>