--- loncom/interface/londocs.pm 2012/04/05 15:22:39 1.480
+++ loncom/interface/londocs.pm 2017/05/07 13:57:58 1.625
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Documents
#
-# $Id: londocs.pm,v 1.480 2012/04/05 15:22:39 raeburn Exp $
+# $Id: londocs.pm,v 1.625 2017/05/07 13:57:58 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -40,8 +40,16 @@ use Apache::lonxml;
use Apache::lonclonecourse;
use Apache::lonnavmaps;
use Apache::lonnavdisplay();
+use Apache::lonextresedit();
+use Apache::lontemplate();
+use Apache::lonsimplepage();
+use Apache::lonhomework();
+use Apache::lonpublisher();
use HTML::Entities;
+use HTML::TokeParser;
use GDBM_File;
+use File::MMagic;
+use File::Copy;
use Apache::lonlocal;
use Cwd;
use LONCAPA qw(:DEFAULT :match);
@@ -54,6 +62,7 @@ my $hashtied;
my %alreadyseen=();
my $hadchanges;
+my $suppchanges;
my %help=();
@@ -67,13 +76,21 @@ sub mapread {
}
sub storemap {
- my ($coursenum,$coursedom,$map)=@_;
+ my ($coursenum,$coursedom,$map,$contentchg)=@_;
+ my $report;
+ if (($contentchg) && ($map =~ /^default/)) {
+ $report = 1;
+ }
my ($outtext,$errtext)=
&LONCAPA::map::storemap('/uploaded/'.$coursedom.'/'.$coursenum.'/'.
- $map,1);
+ $map,1,$report);
if ($errtext) { return ($errtext,2); }
- $hadchanges=1;
+ if ($map =~ /^default/) {
+ $hadchanges=1;
+ } else {
+ $suppchanges=1;
+ }
return ($errtext,0);
}
@@ -100,12 +117,17 @@ sub authorhosts {
my $allowed=0;
my $myhome=&Apache::lonnet::homeserver($ca,$cd);
my @ids=&Apache::lonnet::current_machine_ids();
- foreach my $id (@ids) { if ($id eq $myhome) { $allowed=1; } }
+ foreach my $id (@ids) {
+ if ($id eq $myhome) {
+ $allowed=1;
+ last;
+ }
+ }
if ($allowed) {
$home++;
- $outhash{'home_'.$ca.'@'.$cd}=1;
+ $outhash{'home_'.$ca.':'.$cd}=1;
} else {
- $outhash{'otherhome_'.$ca.'@'.$cd}=$myhome;
+ $outhash{'otherhome_'.$ca.':'.$cd}=$myhome;
$other++;
}
}
@@ -114,164 +136,499 @@ sub authorhosts {
}
-sub dumpbutton {
- my ($home,$other,%outhash)=&authorhosts();
- my $crstype = &Apache::loncommon::course_type();
- if ($home+$other==0) { return ''; }
- if ($home) {
- my $link =
- "';
- return
- $link.' '
- .&Apache::loncommon::help_open_topic('Docs_Dump_Course_Docs')
- .'
';
- } else {
- return
- &mt('Dump '.$crstype.' Documents to Construction Space: available on other servers');
- }
-}
-
sub clean {
my ($title)=@_;
$title=~s/[^\w\/\!\$\%\^\*\-\_\=\+\;\:\,\\\|\`\~]+/\_/gs;
return $title;
}
-
+sub default_folderpath {
+ my ($coursenum,$coursedom,$navmapref) = @_;
+ return unless ($coursenum && $coursedom && ref($navmapref));
+# Check if entire course is hidden and/or encrypted
+ my ($hiddenmap,$encryptmap,$folderpath,$hiddentop);
+ my $toplevel = "uploaded/$coursedom/$coursenum/default.sequence";
+ unless (ref($$navmapref)) {
+ $$navmapref = Apache::lonnavmaps::navmap->new();
+ }
+ if (ref($$navmapref)) {
+ if (lc($$navmapref->get_mapparam(undef,$toplevel,"0.hiddenresource")) eq 'yes') {
+ my $filterFunc = sub { my $res = shift; return (!$res->randomout() && !$res->is_map()) };
+ my @resources = $$navmapref->retrieveResources($toplevel,$filterFunc,1,1);
+ unless (@resources) {
+ $hiddenmap = 1;
+ unless ($env{'request.role.adv'}) {
+ $hiddentop = 1;
+ if ($env{'form.folder'}) {
+ undef($env{'form.folder'});
+ }
+ }
+ }
+ }
+ if (lc($$navmapref->get_mapparam(undef,$toplevel,"0.encrypturl")) eq 'yes') {
+ $encryptmap = 1;
+ }
+ }
+ unless ($hiddentop) {
+ $folderpath='default&'.&escape(&mt('Main Content')).
+ '::'.$hiddenmap.':'.$encryptmap.'::';
+ }
+ if (wantarray) {
+ return ($folderpath,$hiddentop);
+ } else {
+ return $folderpath;
+ }
+}
sub dumpcourse {
my ($r) = @_;
my $crstype = &Apache::loncommon::course_type();
- $r->print(&Apache::loncommon::start_page('Dump '.$crstype.' Documents to Construction Space').
- '
');
+ $preamble .= ''.
+ '
'."\n";
+ my %uploadedfiles;
+ &tiehash();
+ foreach my $file (&Apache::lonclonecourse::crsdirlist($origcrsid,'userfiles')) {
+ my ($ext)=($file=~/\.(\w+)$/);
+# FIXME Check supplemental here
+ my $title=$hash{'title_'.$hash{
+ 'ids_/uploaded/'.$origcrsdata{'domain'}.'/'.$origcrsdata{'num'}.'/'.$file}};
+ if (!$title) {
+ $title=$file;
+ } else {
+ $title=~s|/|_|g;
+ }
+ $title=~s/\.(\w+)$//;
+ $title=&clean($title);
+ $title.='.'.$ext;
+# $r->print("\n | "
+ $uploadedfiles{$file} = $title;
+ }
+ &untiehash();
+ $r->print(&Apache::loncourserespicker::create_picker($navmap,'dumpdocs',$formname,$crstype,undef,
+ undef,undef,$preamble,$home,\%uploadedfiles));
+ }
+ }
+ $r->print(&endContentScreen());
+}
+
+sub recurse_html {
+ my ($mm,$prefix,$currdirpath,$currurlpath,$container,$item,$replacehash,$deps) = @_;
+ return unless ((ref($replacehash) eq 'HASH') && (ref($deps) eq 'HASH'));
+ my (%allfiles,%codebase);
+ if (&Apache::lonnet::extract_embedded_items($currdirpath,\%allfiles,\%codebase) eq 'ok') {
+ if (keys(%allfiles)) {
+ foreach my $dependency (keys(%allfiles)) {
+ next if (($dependency =~ m{^/(res|adm)/}) || ($dependency =~ m{^https?://}));
+ my ($depurl,$relfile,$newcontainer);
+ if ($dependency =~ m{^/}) {
+ if ($dependency =~ m{^\Q$currurlpath/\E(.+)$}) {
+ $relfile = $1;
+ if ($dependency =~ m{^\Q$prefix\E(.+)$}) {
+ $newcontainer = $1;
+ next if ($replacehash->{$newcontainer});
+ }
+ $depurl = $dependency;
+ } else {
+ next;
+ }
+ } else {
+ $relfile = $dependency;
+ $depurl = $currurlpath;
+ $depurl =~ s{[^/]+$}{};
+ $depurl .= $dependency;
+ ($newcontainer) = ($depurl =~ m{^\Q$prefix\E(.+)$});
+ }
+ next if ($relfile eq '');
+ my $newname = $replacehash->{$container};
+ $newname =~ s{[^/]+$}{};
+ $replacehash->{$newcontainer} = $newname.$relfile;
+ $deps->{$item}{$newcontainer} = 1;
+ my ($newurlpath) = ($depurl =~ m{^(.*)/[^/]+$});
+ my $depfile = &Apache::lonnet::filelocation('',$depurl);
+ my $type = $mm->checktype_filename($depfile);
+ if ($type eq 'text/html') {
+ &recurse_html($mm,$prefix,$depfile,$newurlpath,$newcontainer,$item,$replacehash,$deps);
+ }
+ }
+ }
}
-}
-
-sub exportbutton {
- my $crstype = &Apache::loncommon::course_type();
- return "".
- &Apache::loncommon::help_open_topic('Docs_Export_Course_Docs').'
';
+ return;
}
sub group_import {
- my ($coursenum, $coursedom, $folder, $container, $caller, @files) = @_;
-
+ my ($coursenum, $coursedom, $folder, $container, $caller, $ltitoolsref, @files) = @_;
+ my ($donechk,$allmaps,%hierarchy,%titles,%addedmaps,%removefrommap,
+ %removeparam,$importuploaded,$fixuperrors);
+ $allmaps = {};
while (@files) {
my ($name, $url, $residx) = @{ shift(@files) };
if (($url =~ m{^/uploaded/\Q$coursedom\E/\Q$coursenum\E/(default_\d+\.)(page|sequence)$})
@@ -288,7 +645,7 @@ sub group_import {
$env{'form.output'}=$newmapstr;
my $result=&Apache::lonnet::finishuserfileupload($coursenum,$coursedom,
'output',$1.$2);
- if ($result != m|^/uploaded/|) {
+ if ($result !~ m{^/uploaded/}) {
$errtext.='Map not saved: A network error occurred when trying to save the new map. ';
$fatal = 2;
}
@@ -297,6 +654,120 @@ sub group_import {
}
}
if ($url) {
+ if ($url =~ m{^(/adm/$coursedom/$coursenum/(\d+)/exttool)\:?(.*)$}) {
+ $url = $1;
+ my $marker = $2;
+ my $info = $3;
+ my ($toolid,%toolhash,%toolsettings);
+ my @extras = ('linktext','explanation','crslabel','crstitle');
+ my @toolinfo = split(/:/,$info);
+ if ($residx) {
+ %toolsettings=&Apache::lonnet::dump('exttool_'.$marker,$coursedom,$coursenum);
+ $toolid = $toolsettings{'id'};
+ } else {
+ $toolid = shift(@toolinfo);
+ }
+ $toolid =~ s/\D//g;
+ ($toolhash{'target'},$toolhash{'width'},$toolhash{'height'},
+ $toolhash{'linktext'},$toolhash{'explanation'},
+ $toolhash{'crslabel'},$toolhash{'crstitle'}) = @toolinfo;
+ foreach my $item (@extras) {
+ $toolhash{$item} = &unescape($toolhash{$item});
+ }
+ if (ref($ltitoolsref) eq 'HASH') {
+ my @deleted;
+ if (ref($ltitoolsref->{$toolid}) eq 'HASH') {
+ $toolhash{'id'} = $toolid;
+ if (($toolhash{'target'} eq 'iframe') || ($toolhash{'target'} eq 'window')) {
+ if ($toolhash{'target'} eq 'window') {
+ foreach my $item ('width','height') {
+ $toolhash{$item} =~ s/^\s+//;
+ $toolhash{$item} =~ s/\s+$//;
+ if ($toolhash{$item} =~ /\D/) {
+ delete($toolhash{$item});
+ if ($residx) {
+ if ($toolsettings{$item}) {
+ push(@deleted,$item);
+ }
+ }
+ }
+ }
+ }
+ } elsif ($residx) {
+ $toolhash{'target'} = $toolsettings{'target'};
+ if ($toolhash{'target'} eq 'window') {
+ foreach my $item ('width','height') {
+ $toolhash{$item} = $toolsettings{$item};
+ }
+ }
+ } elsif (ref($ltitoolsref->{$toolid}->{'display'}) eq 'HASH') {
+ $toolhash{'target'} = $ltitoolsref->{$toolid}->{'display'}->{'target'};
+ if ($toolhash{'target'} eq 'window') {
+ $toolhash{'width'} = $ltitoolsref->{$toolid}->{'display'}->{'width'};
+ $toolhash{'height'} = $ltitoolsref->{$toolid}->{'display'}->{'height'};
+ }
+ }
+ if ($toolhash{'target'} eq 'iframe') {
+ foreach my $item ('width','height','linktext','explanation') {
+ delete($toolhash{$item});
+ if ($residx) {
+ if ($toolsettings{$item}) {
+ push(@deleted,$item);
+ }
+ }
+ }
+ }
+ if (ref($ltitoolsref->{$toolid}->{'crsconf'}) eq 'HASH') {
+ foreach my $item ('label','title','linktext','explanation') {
+ my $crsitem;
+ if (($item eq 'label') || ($item eq 'title')) {
+ $crsitem = 'crs'.$item;
+ } else {
+ $crsitem = $item;
+ }
+ if ($ltitoolsref->{$toolid}->{'crsconf'}->{$item}) {
+ $toolhash{$crsitem} =~ s/^\s+//;
+ $toolhash{$crsitem} =~ s/\s+$//;
+ if ($toolhash{$crsitem} eq '') {
+ delete($toolhash{$crsitem});
+ }
+ } else {
+ delete($toolhash{$crsitem});
+ }
+ if (($residx) && (exists($toolsettings{$crsitem}))) {
+ unless (exists($toolhash{$crsitem})) {
+ push(@deleted,$crsitem);
+ }
+ }
+ }
+ }
+ my $putres = &Apache::lonnet::put('exttool_'.$marker,\%toolhash,$coursedom,$coursenum);
+ if ($putres eq 'ok') {
+ if (@deleted) {
+ &Apache::lonnet::del('exttool_'.$marker,\@deleted,$coursedom,$coursenum);
+ }
+ }
+ }
+ }
+ }
+ if (($caller eq 'londocs') &&
+ ($folder =~ /^default/)) {
+ if (($url =~ /\.(page|sequence)$/) && (!$donechk)) {
+ my $chome = &Apache::lonnet::homeserver($coursenum,$coursedom);
+ my $cid = $coursedom.'_'.$coursenum;
+ $allmaps =
+ &Apache::loncommon::allmaps_incourse($coursedom,$coursenum,
+ $chome,$cid);
+ $donechk = 1;
+ }
+ if ($url =~ m{^/uploaded/\Q$coursedom\E/\Q$coursenum\E/(default_\d+\.)(page|sequence)$}) {
+ &contained_map_check($url,$folder,\%removefrommap,\%removeparam,
+ \%addedmaps,\%hierarchy,\%titles,$allmaps);
+ $importuploaded = 1;
+ } elsif ($url =~ m{^/res/.+\.(page|sequence)$}) {
+ next if ($allmaps->{$url});
+ }
+ }
if (!$residx
|| defined($LONCAPA::map::zombies[$residx])) {
$residx = &LONCAPA::map::getresidx($url,$residx);
@@ -304,73 +775,97 @@ sub group_import {
}
my $ext = 'false';
if ($url=~m{^http://} || $url=~m{^https://}) { $ext = 'true'; }
- $url = &LONCAPA::map::qtunescape($url);
$name = &LONCAPA::map::qtunescape($name);
+ if ($name eq '') {
+ $name = &LONCAPA::map::qtunescape(&mt('Web Page'));
+ }
+ if ($url =~ m{^/uploaded/$coursedom/$coursenum/((?:docs|supplemental)/(?:default|\d+))/new\.html$}) {
+ my $filepath = $1;
+ my $fname = $name;
+ if ($fname =~ /^\W+$/) {
+ $fname = 'web';
+ } else {
+ $fname =~ s/\W/_/g;
+ }
+ if (length($fname) > 15) {
+ $fname = substr($fname,0,14);
+ }
+ my $initialtext = &mt('Replace with your own content.');
+ my $newhtml = <
+
+$name
+
+
+$initialtext
+
+