--- loncom/interface/londocs.pm 2004/09/14 01:21:49 1.142
+++ loncom/interface/londocs.pm 2014/10/24 00:25:12 1.484.2.56
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Documents
#
-# $Id: londocs.pm,v 1.142 2004/09/14 01:21:49 raeburn Exp $
+# $Id: londocs.pm,v 1.484.2.56 2014/10/24 00:25:12 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -30,16 +30,26 @@ package Apache::londocs;
use strict;
use Apache::Constants qw(:common :http);
+use Apache::imsexport;
use Apache::lonnet;
use Apache::loncommon;
-use Apache::lonratedt;
-use Apache::lonratsrv;
+use Apache::lonhtmlcommon;
+use LONCAPA::map();
+use Apache::lonratedt();
use Apache::lonxml;
-use Apache::loncreatecourse;
+use Apache::lonclonecourse;
use Apache::lonnavmaps;
+use Apache::lonnavdisplay();
+use Apache::lonextresedit();
+use Apache::lontemplate();
+use Apache::lonsimplepage();
use HTML::Entities;
+use HTML::TokeParser;
use GDBM_File;
+use File::MMagic;
use Apache::lonlocal;
+use Cwd;
+use LONCAPA qw(:DEFAULT :match);
my $iconpath;
@@ -49,917 +59,3871 @@ my $hashtied;
my %alreadyseen=();
my $hadchanges;
+my $suppchanges;
-# Available help topics
my %help=();
-# Mapread read maps into lonratedt::global arrays
-# @order and @resources, determines status
-# sets @order - pointer to resources in right order
-# sets @resources - array with the resources with correct idx
-#
sub mapread {
my ($coursenum,$coursedom,$map)=@_;
return
- &Apache::lonratedt::mapread('/uploaded/'.$coursedom.'/'.$coursenum.'/'.
- $map);
+ &LONCAPA::map::mapread('/uploaded/'.$coursedom.'/'.$coursenum.'/'.
+ $map);
}
sub storemap {
- my ($coursenum,$coursedom,$map)=@_;
+ my ($coursenum,$coursedom,$map,$contentchg)=@_;
+ my $report;
+ if (($contentchg) && ($map =~ /^default/)) {
+ $report = 1;
+ }
my ($outtext,$errtext)=
- &Apache::lonratedt::storemap('/uploaded/'.$coursedom.'/'.$coursenum.'/'.
- $map,1);
+ &LONCAPA::map::storemap('/uploaded/'.$coursedom.'/'.$coursenum.'/'.
+ $map,1,$report);
if ($errtext) { return ($errtext,2); }
-
- $hadchanges=1;
+
+ if ($map =~ /^default/) {
+ $hadchanges=1;
+ } else {
+ $suppchanges=1;
+ }
return ($errtext,0);
}
-# ----------------------------------------- Return hash with valid author names
+
sub authorhosts {
my %outhash=();
my $home=0;
my $other=0;
- foreach (keys %ENV) {
- if ($_=~/^user\.role\.(au|ca)\.(.+)$/) {
+ foreach my $key (keys(%env)) {
+ if ($key=~/^user\.role\.(au|ca)\.(.+)$/) {
my $role=$1;
my $realm=$2;
- my ($start,$end)=split(/\./,$ENV{$_});
+ my ($start,$end)=split(/\./,$env{$key});
if (($start) && ($start>time)) { next; }
if (($end) && (time>$end)) { next; }
- my $ca; my $cd;
+ my ($ca,$cd);
if ($1 eq 'au') {
- $ca=$ENV{'user.name'};
- $cd=$ENV{'user.domain'};
+ $ca=$env{'user.name'};
+ $cd=$env{'user.domain'};
} else {
- ($cd,$ca)=($realm=~/^\/(\w+)\/(\w+)$/);
+ ($cd,$ca)=($realm=~/^\/($match_domain)\/($match_username)$/);
}
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++;
}
}
}
return ($home,$other,%outhash);
}
-# ------------------------------------------------------ Generate "dump" button
-sub dumpbutton {
- my ($home,$other,%outhash)=&authorhosts();
- if ($home+$other==0) { return ''; }
- my $output='
';
- if ($home) {
- return ' | '.
- ''.
- &Apache::loncommon::help_open_topic('Docs_Dump_Course_Docs');
- } else {
- return' | '.
- &mt('Dump Course DOCS to Construction Space: available on other servers');
- }
+
+sub clean {
+ my ($title)=@_;
+ $title=~s/[^\w\/\!\$\%\^\*\-\_\=\+\;\:\,\\\|\`\~]+/\_/gs;
+ return $title;
}
-# -------------------------------------------------------- Actually dump course
+
sub dumpcourse {
- my $r=shift;
- $r->print('Dump DOCS'.
- &Apache::loncommon::bodytag('Dump Course DOCS to Construction Space').
- ' | '.
- ''.
- &Apache::loncommon::help_open_topic('Docs_Export_Course_Docs');
+ $addtoenv{'docs.markedcopy_title_'.$suffix} = $title,
+ $addtoenv{'docs.markedcopy_url_'.$suffix} = $url,
+ $addtoenv{'docs.markedcopy_cmd_'.$suffix} = $cmd,
+ $addtoenv{'docs.markedcopy_crs_'.$suffix} = $env{'request.course.id'};
+
+ if ($url =~ m{^/uploaded/$match_domain/$match_courseid/(default|supplemental)_?(\d*)\.(page|sequence)$}) {
+ my $prefix = $1;
+ my $subdir =$2;
+ if ($subdir eq '') {
+ $subdir = $prefix;
+ }
+ my (%addedmaps,%removefrommap,%removeparam,%hierarchy,%titles,%allmaps);
+ &contained_map_check($url,$folder,\%removefrommap,\%removeparam,\%addedmaps,
+ \%hierarchy,\%titles,\%allmaps);
+ if (ref($hierarchy{$url}) eq 'HASH') {
+ my ($nested,$nestednames);
+ &recurse_uploaded_maps($url,$subdir,\%hierarchy,\%titles,\$nested,\$nestednames);
+ $nested =~ s/\&$//;
+ $nestednames =~ s/\Q___&&&___\E$//;
+ if ($nested ne '') {
+ $addtoenv{'docs.markedcopy_nested_'.$suffix} = $nested;
+ }
+ if ($nestednames ne '') {
+ $addtoenv{'docs.markedcopy_nestednames_'.$suffix} = $nestednames;
+ }
+ }
+ }
+ }
+ if (@newpaste) {
+ $addtoenv{'docs.markedcopies'} = join(',',(@currpaste,@newpaste));
+ }
+ &Apache::lonnet::appenv(\%addtoenv);
+ delete($env{'form.markcopy'});
+ return;
}
-sub exportcourse {
- my $r=shift;
- my %discussiontime = &Apache::lonnet::dump('discussiontimes',
- $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
- my $numdisc = keys %discussiontime;
- my $navmap = Apache::lonnavmaps::navmap->new();
- my $it=$navmap->getIterator(undef,undef,undef,1,undef,undef);
- my $curRes;
+sub recurse_uploaded_maps {
+ my ($url,$dir,$hierarchy,$titlesref,$nestref,$namesref) = @_;
+ if (ref($hierarchy->{$url}) eq 'HASH') {
+ my @maps = map { $hierarchy->{$url}{$_}; } sort { $a <=> $b } (keys(%{$hierarchy->{$url}}));
+ my @titles = map { $titlesref->{$url}{$_}; } sort { $a <=> $b } (keys(%{$titlesref->{$url}}));
+ my (@uploaded,@names,%shorter);
+ for (my $i=0; $i<@maps; $i++) {
+ my ($inner) = ($maps[$i] =~ m{^/uploaded/$match_domain/$match_courseid/(?:default|supplemental)_(\d+)\.(?:page|sequence)$});
+ if ($inner ne '') {
+ push(@uploaded,$inner);
+ push(@names,&escape($titles[$i]));
+ $shorter{$maps[$i]} = $inner;
+ }
+ }
+ $$nestref .= "$dir:".join(',',@uploaded).'&';
+ $$namesref .= "$dir:".(join(',',@names)).'___&&&___';
+ foreach my $map (@maps) {
+ if ($shorter{$map} ne '') {
+ &recurse_uploaded_maps($map,$shorter{$map},$hierarchy,$titlesref,$nestref,$namesref);
+ }
+ }
+ }
+ return;
+}
- &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
- ['finishexport']);
- if ($ENV{'form.finishexport'}) {
- &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
- ['archive','discussion']);
+sub print_paste_buffer {
+ my ($r,$container,$folder,$coursedom,$coursenum) = @_;
+ return if (!defined($env{'docs.markedcopies'}));
+
+ unless (($env{'form.pastemarked'}) || ($env{'form.clearmarked'})) {
+ return if ($env{'docs.markedcopies'} eq '');
+ }
- my @exportitems = ();
- if (defined($ENV{'form.archive'})) {
- if (ref($ENV{'form.archive'}) eq 'ARRAY') {
- @exportitems = @{$ENV{'form.archive'}};
+ my @currpaste = split(/,/,$env{'docs.markedcopies'});
+ my ($pasteitems,@pasteable);
+ my $clipboardcount = 0;
+
+# Construct identifiers for current contents of user's paste buffer
+ foreach my $suffix (@currpaste) {
+ next if ($suffix =~ /\D/);
+ my $cid = $env{'docs.markedcopy_crs_'.$suffix};
+ my $url = $env{'docs.markedcopy_url_'.$suffix};
+ if (($cid =~ /^$match_domain\_$match_courseid$/) &&
+ ($url ne '')) {
+ $clipboardcount ++;
+ my ($is_external,$othercourse,$fromsupp,$is_uploaded_map,$parent,
+ $canpaste,$nopaste,$othercrs,$areachange);
+ my $extension = (split(/\./,$env{'docs.markedcopy_url_'.$suffix}))[-1];
+ if ($url =~ m{^(?:/adm/wrapper/ext|(?:http|https)(?::|:))//} ) {
+ $is_external = 1;
+ }
+ if ($folder =~ /^supplemental/) {
+ $canpaste = &supp_pasteable($env{'docs.markedcopy_url_'.$suffix});
+ unless ($canpaste) {
+ $nopaste = &mt('Paste into Supplemental Content unavailable.');
+ }
} else {
- $exportitems[0] = $ENV{'form.archive'};
+ $canpaste = 1;
}
- }
- my @discussions = ();
- if (defined($ENV{'form.discussion'})) {
- if (ref($ENV{'form.discussion'}) eq 'ARRAY') {
- @discussions = $ENV{'form.discussion'};
+ if ($canpaste) {
+ if ($url =~ m{^/uploaded/($match_domain)/($match_courseid)/(.+)$}) {
+ my $srcdom = $1;
+ my $srcnum = $2;
+ my $rem = $3;
+ if (($srcdom ne $coursedom) || ($srcnum ne $coursenum)) {
+ $othercourse = 1;
+ if ($env{"user.priv.cm./$srcdom/$srcnum"} =~ /\Q:mdc&F\E/) {
+ if ($canpaste) {
+ $othercrs = ' '.&mt('(from another course)');
+ }
+ } else {
+ $canpaste = 0;
+ $nopaste = &mt('Paste from another course unavailable.');
+ }
+ }
+ if ($rem =~ m{^(default|supplemental)_?(\d*)\.(?:page|sequence)$}) {
+ my $prefix = $1;
+ $parent = $2;
+ if ($folder !~ /^\Q$prefix\E/) {
+ $areachange = 1;
+ }
+ $is_uploaded_map = 1;
+ }
+ }
+ }
+ if ($canpaste) {
+ push(@pasteable,$suffix);
+ }
+ my $buffer;
+ if ($is_external) {
+ $buffer = &mt('External Resource').': '.
+ &LONCAPA::map::qtescape($env{'docs.markedcopy_title_'.$suffix}).' ('.
+ &LONCAPA::map::qtescape($url).')';
} else {
- $discussions[0] = $ENV{'form.discussion'};
+ my $icon = &Apache::loncommon::icon($extension);
+ if ($extension eq 'sequence' &&
+ $url =~ m{/default_\d+\.sequence$}x) {
+ $icon = &Apache::loncommon::lonhttpdurl($r->dir_config('lonIconsURL'));
+ $icon .= '/navmap.folder.closed.gif';
+ }
+ $buffer = ''.
+ ': '.
+ &Apache::loncommon::parse_supplemental_title(
+ &LONCAPA::map::qtescape($env{'docs.markedcopy_title_'.$suffix}));
}
+ $pasteitems .= '';
+ my ($options,$onclick);
+ if (($canpaste) && (!$areachange) && (!$othercourse) &&
+ ($env{'docs.markedcopy_cmd_'.$suffix} eq 'cut')) {
+ if (($is_uploaded_map) ||
+ ($url =~ /(bulletinboard|smppg)$/) ||
+ ($url =~ m{^/uploaded/$coursedom/$coursenum/(?:docs|supplemental)/(.+)$})) {
+ $options = &paste_options($suffix,$is_uploaded_map,$parent);
+ $onclick= 'onclick="showOptions(this,'."'$suffix'".');" ';
+ }
+ }
+ $pasteitems .= '';
+ if ($nopaste) {
+ $pasteitems .= $nopaste;
+ } else {
+ if ($othercrs) {
+ $pasteitems .= $othercrs;
+ }
+ if ($options) {
+ $pasteitems .= $options;
+ }
+ }
+ $pasteitems .= ' ';
}
- my $curRes;
- my $count;
- my %symbs;
- my $display;
- while ($curRes = $it->next()) {
- if (ref($curRes)) {
- $count ++;
- $symbs{$count} = $curRes->symb();
- if (grep/^$count$/,@exportitems) {
- $display.= 'Export content item '.$curRes->title()." \n";
- }
- if (grep/^$count$/,@discussions) {
- $display.= 'Export discussion posts '.$curRes->title()." \n";
- }
+ }
+ if ($pasteitems eq '') {
+ &Apache::lonnet::delenv('docs.markedcopies');
+ }
+ my ($pasteform,$form_start,$buttons,$form_end);
+ if ($pasteitems) {
+ $pasteitems .= '';
+ $form_start = '';
+ } else {
+ $pasteitems = &mt('Clipboard is empty');
+ }
+ $r->print($form_start
+ .''
+ .$form_end);
+}
- $r->print('Export Course'.
- &Apache::loncommon::bodytag('Export course to IMS or SCORM content package'
-));
-
- my $exportfile;
- $r->print($display);
- $r->print(' |