--- loncom/interface/londocs.pm 2006/03/17 00:06:54 1.224
+++ loncom/interface/londocs.pm 2025/01/07 21:01:37 1.722
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Documents
#
-# $Id: londocs.pm,v 1.224 2006/03/17 00:06:54 albertel Exp $
+# $Id: londocs.pm,v 1.722 2025/01/07 21:01:37 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -33,15 +33,29 @@ 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 Apache::lonhomework();
+use Apache::lonpublisher();
+use Apache::loncourserespicker();
use HTML::Entities;
+use HTML::TokeParser;
+use HTML::LCParser;
use GDBM_File;
+use File::MMagic;
+use File::Copy;
use Apache::lonlocal;
use Cwd;
+use UUID::Tiny ':std';
+use LONCAPA qw(:DEFAULT :match);
my $iconpath;
@@ -51,1214 +65,5126 @@ 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;
+ } elsif ($contentchg) {
+ $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)\.(.+)$/) {
+ my @ids=&Apache::lonnet::current_machine_ids();
+ 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'};
} 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;
+ 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 validate_supppath {
+ my ($coursenum,$coursedom) = @_;
+ my $backto;
+ if ($env{'form.supppath'} ne '') {
+ my @items = split(/\&/,$env{'form.supppath'});
+ my ($badpath,$got_supp,$supppath,%supphidden,%suppids);
+ for (my $i=0; $i<@items; $i++) {
+ my $odd = $i%2;
+ if ((!$odd) && ($items[$i] !~ /^supplemental(|_\d+)$/)) {
+ $badpath = 1;
+ last;
+ } elsif ($odd) {
+ my $suffix;
+ my $idx = $i-1;
+ if ($items[$i] =~ /^([^:]*)::(|1):::$/) {
+ $backto .= '&'.$1;
+ } elsif ($items[$idx] eq 'supplemental') {
+ $backto .= '&'.$items[$i];
+ } else {
+ $backto .= '&'.$items[$i];
+ my $is_hidden;
+ unless ($got_supp) {
+ my ($supplemental) = &Apache::loncommon::get_supplemental($coursenum,$coursedom);
+ if (ref($supplemental) eq 'HASH') {
+ if (ref($supplemental->{'hidden'}) eq 'HASH') {
+ %supphidden = %{$supplemental->{'hidden'}};
+ }
+ if (ref($supplemental->{'ids'}) eq 'HASH') {
+ %suppids = %{$supplemental->{'ids'}};
+ }
+ }
+ $got_supp = 1;
+ }
+ if (ref($suppids{"/uploaded/$coursedom/$coursenum/$items[$idx].sequence"}) eq 'ARRAY') {
+ my $mapid = $suppids{"/uploaded/$coursedom/$coursenum/$items[$idx].sequence"}->[0];
+ if ($supphidden{$mapid}) {
+ $is_hidden = 1;
+ }
+ }
+ $suffix = '::'.$is_hidden.':::';
+ }
+ $supppath .= '&'.$items[$i].$suffix;
+ } else {
+ $supppath .= '&'.$items[$i];
+ $backto .= '&'.$items[$i];
+ }
+ }
+ if ($badpath) {
+ delete($env{'form.supppath'});
+ } else {
+ $supppath =~ s/^\&//;
+ $backto =~ s/^\&//;
+ $env{'form.supppath'} = $supppath;
+ }
+ }
+ return $backto;
}
-# -------------------------------------------------------- Actually dump course
sub dumpcourse {
my ($r) = @_;
+ my $crstype = &Apache::loncommon::course_type();
+ my ($starthash,$js);
+ unless (($env{'form.authorspace'}) && ($env{'form.authorfolder'}=~/\w/)) {
+ $js = <<"ENDJS";
+
+ENDJS
+ $starthash = {
+ add_entries => {'onload' => "hide_searching();"},
+ };
+ }
+ $r->print(&Apache::loncommon::start_page('Copy uploaded content to Authoring Space',$js,$starthash)."\n".
+ &Apache::lonhtmlcommon::breadcrumbs('Copy uploaded content to Authoring Space')."\n");
+ $r->print(&startContentScreen('tools'));
my ($home,$other,%outhash)=&authorhosts();
- unless ($home) { return ''; }
+ unless ($home) {
+ $r->print(''.&mt('No author or co-author roles on this server.').'
');
+ $r->print(&endContentScreen());
+ return '';
+ }
my $origcrsid=$env{'request.course.id'};
my %origcrsdata=&Apache::lonnet::coursedescription($origcrsid);
if (($env{'form.authorspace'}) && ($env{'form.authorfolder'}=~/\w/)) {
# Do the dumping
- unless ($outhash{'home_'.$env{'form.authorspace'}}) { return ''; }
- my ($ca,$cd)=split(/\@/,$env{'form.authorspace'});
+ unless ($outhash{'home_'.$env{'form.authorspace'}}) {
+ $r->print(''.&mt('Selected Authoring Space is not on this server.').'
'.
+ &endContentScreen());
+ return '';
+ }
+ my ($ca,$cd)=split(/\:/,$env{'form.authorspace'});
$r->print(''.&mt('Copying Files').' ');
my $title=$env{'form.authorfolder'};
$title=&clean($title);
- my %replacehash=();
- foreach (keys %env) {
- if ($_=~/^form\.namefor\_(.+)/) {
- $replacehash{$1}=$env{$_};
- }
+ my ($navmap,$errormsg) =
+ &Apache::loncourserespicker::get_navmap_object($crstype,'dumpdocs');
+ my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+ my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+ my (%maps,%resources,%titles);
+ if (!ref($navmap)) {
+ $r->print($errormsg.
+ &endContentScreen());
+ return '';
+ } else {
+ &Apache::loncourserespicker::enumerate_course_contents($navmap,\%maps,\%resources,\%titles,
+ 'dumpdocs',$cdom,$cnum);
}
+ my @todump = &Apache::loncommon::get_env_multiple('form.archive');
+ my (%tocopy,%replacehash,%lookup,%deps,%display,%result,%depresult,%simpleproblems,%simplepages,
+ %newcontent,%has_simpleprobs);
+ foreach my $item (sort {$a <=> $b} (@todump)) {
+ my $name = $env{'form.namefor_'.$item};
+ if ($resources{$item}) {
+ my ($map,$id,$res) = &Apache::lonnet::decode_symb($resources{$item});
+ if ($res =~ m{^uploaded/$cdom/$cnum/\E((?:docs|supplemental)/.+)$}) {
+ $tocopy{$1} = $name;
+ $display{$item} = $1;
+ $lookup{$1} = $item;
+ } elsif ($res eq 'lib/templates/simpleproblem.problem') {
+ $simpleproblems{$item} = {
+ symb => $resources{$item},
+ name => $name,
+ };
+ $display{$item} = 'simpleproblem_'.$name;
+ if ($map =~ m{^\Quploaded/$cdom/$cnum/\E(.+)$}) {
+ $has_simpleprobs{$1}{$id} = $item;
+ }
+ } elsif ($res =~ m{^adm/$match_domain/$match_username/(\d+)/smppg}) {
+ my $marker = $1;
+ my $db_name = &Apache::lonsimplepage::get_db_name($res,$marker,$cdom,$cnum);
+ $simplepages{$item} = {
+ res => $res,
+ title => $titles{$item},
+ db => $db_name,
+ marker => $marker,
+ symb => $resources{$item},
+ name => $name,
+ };
+ $display{$item} = '/'.$res;
+ }
+ } elsif ($maps{$item}) {
+ if ($maps{$item} =~ m{^\Quploaded/$cdom/$cnum/\E((?:default|supplemental)_\d+\.(?:sequence|page))$}) {
+ $tocopy{$1} = $name;
+ $display{$item} = $1;
+ $lookup{$1} = $item;
+ }
+ } else {
+ next;
+ }
+ }
my $crs='/uploaded/'.$env{'request.course.id'}.'/';
$crs=~s/\_/\//g;
- foreach (keys %replacehash) {
- my $newfilename=$title.'/'.$replacehash{$_};
- $newfilename=~s/\.(\w+)$//;
- my $ext=$1;
- $newfilename=&clean($newfilename);
- $newfilename.='.'.$ext;
- my @dirs=split(/\//,$newfilename);
- my $path='/home/'.$ca.'/public_html';
- my $makepath=$path;
- my $fail=0;
- for (my $i=0;$i<$#dirs;$i++) {
- $makepath.='/'.$dirs[$i];
- unless (-e $makepath) {
- unless(mkdir($makepath,0777)) { $fail=1; }
- }
- }
- $r->print(''.$_.' => '.$newfilename.' : ');
- if (my $fh=Apache::File->new('>'.$path.'/'.$newfilename)) {
- if ($_=~/\.(sequence|page|html|htm|xml|xhtml)$/) {
- print $fh &Apache::loncreatecourse::rewritefile(
- &Apache::loncreatecourse::readfile($env{'request.course.id'},$_),
- (%replacehash,$crs => '')
- );
- } else {
- print $fh
- &Apache::loncreatecourse::readfile($env{'request.course.id'},$_);
- }
- $fh->close();
- } else {
- $fail=1;
- }
- if ($fail) {
- $r->print('fail ');
- } else {
- $r->print('ok ');
- }
- }
+ my $mm = new File::MMagic;
+ my $prefix = "/uploaded/$cdom/$cnum/";
+ %replacehash = %tocopy;
+ foreach my $item (sort(keys(%simpleproblems))) {
+ my $content = &Apache::imsexport::simpleproblem($simpleproblems{$item}{'symb'});
+ $newcontent{$display{$item}} = $content;
+ }
+ my $gateway = Apache::lonhtmlgateway->new('web');
+ foreach my $item (sort(keys(%simplepages))) {
+ if (ref($simplepages{$item}) eq 'HASH') {
+ my $pagetitle = $simplepages{$item}{'title'};
+ my %fields = &Apache::lonnet::dump($simplepages{$item}{'db'},$cdom,$cnum);
+ my %contents;
+ foreach my $field (keys(%fields)) {
+ if ($field =~ /^(?:aaa|bbb|ccc)_(\w+)$/) {
+ my $name = $1;
+ my $msg = $fields{$field};
+ if ($name eq 'webreferences') {
+ if ($msg =~ m{^https?://}) {
+ $contents{$name} = ''.$msg.' ';
+ }
+ } else {
+ $msg = &Encode::decode('utf8',$msg);
+ $msg = $gateway->process_outgoing_html($msg,1);
+ $contents{$name} = $msg;
+ }
+ } elsif ($field eq 'uploaded.photourl') {
+ my $marker = $simplepages{$item}{marker};
+ if ($fields{$field} =~ m{^\Q$prefix\E(simplepage/$marker/.+)$}) {
+ my $filepath = $1;
+ my ($relpath,$fname) = ($filepath =~ m{^(.+/)([^/]+)$});
+ if ($fname ne '') {
+ $fname=~s/\.(\w+)$//;
+ my $ext=$1;
+ $fname = &clean($fname);
+ $fname.='.'.$ext;
+ $contents{image} = ' ';
+ $replacehash{$filepath} = $relpath.$fname;
+ $deps{$item}{$filepath} = 1;
+ }
+ }
+ }
+ }
+ $replacehash{'/'.$simplepages{$item}{'res'}} = $simplepages{$item}{'name'};
+ $lookup{'/'.$simplepages{$item}{'res'}} = $item;
+ my $content = '
+
+
+'.$pagetitle.'
+
+';
+ if ($contents{title}) {
+ $content .= "\n".''.$contents{title}.' ';
+ }
+ if ($contents{image}) {
+ $content .= "\n".$contents{image};
+ }
+ if ($contents{content}) {
+ $content .= '
+
+
'.&mt('Content').' '.
+$contents{content}.'
+';
+ }
+ if ($contents{webreferences}) {
+ $content .= '
+
+
'.&mt('Web References').' '.
+$contents{webreferences}.'
+';
+ }
+ $content .= '
+
+
+';
+ $newcontent{'/'.$simplepages{$item}{res}} = $content;
+ }
+ }
+ foreach my $item (keys(%tocopy)) {
+ unless ($item=~/\.(sequence|page)$/) {
+ my $currurlpath = $prefix.$item;
+ my $currdirpath = &Apache::lonnet::filelocation('',$currurlpath);
+ &recurse_html($mm,$prefix,$currdirpath,$currurlpath,$item,$lookup{$item},\%replacehash,\%deps);
+ }
+ }
+ foreach my $num (sort {$a <=> $b} (@todump)) {
+ my $src = $display{$num};
+ next if ($src eq '');
+ my @needcopy = ();
+ if ($replacehash{$src}) {
+ push(@needcopy,$src);
+ if (ref($deps{$num}) eq 'HASH') {
+ foreach my $dep (sort(keys(%{$deps{$num}}))) {
+ if ($replacehash{$dep}) {
+ push(@needcopy,$dep);
+ }
+ }
+ }
+ } elsif ($src =~ /^simpleproblem_/) {
+ push(@needcopy,$src);
+ }
+ next if (@needcopy == 0);
+ my ($result,$depresult);
+ for (my $i=0; $i<@needcopy; $i++) {
+ my $item = $needcopy[$i];
+ my $newfilename;
+ if ($simpleproblems{$num}) {
+ $newfilename=$title.'/'.$simpleproblems{$num}{'name'};
+ } else {
+ $newfilename=$title.'/'.$replacehash{$item};
+ }
+ $newfilename=~s/\.(\w+)$//;
+ my $ext=$1;
+ $newfilename=&clean($newfilename);
+ $newfilename.='.'.$ext;
+ my ($newrelpath) = ($newfilename =~ m{^\Q$title/\E(.+)$});
+ if ($newrelpath ne $replacehash{$item}) {
+ $replacehash{$item} = $newrelpath;
+ }
+ my @dirs=split(/\//,$newfilename);
+ my $path=$r->dir_config('lonDocRoot')."/priv/$cd/$ca";
+ my $makepath=$path;
+ my $fail;
+ my $origin;
+ for (my $i=0;$i<$#dirs;$i++) {
+ $makepath.='/'.$dirs[$i];
+ unless (-e $makepath) {
+ unless(mkdir($makepath,0755)) {
+ $fail = &mt('Directory creation failed.');
+ }
+ }
+ }
+ if ($i == 0) {
+ $result = ''.$item.' => '.$newfilename.' : ';
+ } else {
+ $depresult .= ''.$item.' => '.$newfilename.' '.
+ ''.
+ &mt('(dependency)').' : ';
+ }
+ if (-e $path.'/'.$newfilename) {
+ $fail = &mt('Destination already exists -- not overwriting.');
+ } else {
+ if (my $fh=Apache::File->new('>'.$path.'/'.$newfilename)) {
+ if (($item =~ m{^/adm/$match_domain/$match_username/\d+/smppg}) ||
+ ($item =~ /^simpleproblem_/)) {
+ print $fh $newcontent{$item};
+ } else {
+ my $fileloc = &Apache::lonnet::filelocation('',$prefix.$item);
+ if (-e $fileloc) {
+ if ($item=~/\.(sequence|page|html|htm|xml|xhtml)$/) {
+ if ((($1 eq 'sequence') || ($1 eq 'page')) &&
+ (ref($has_simpleprobs{$item}) eq 'HASH')) {
+ my %changes = %{$has_simpleprobs{$item}};
+ my $content = &Apache::lonclonecourse::rewritefile(
+ &Apache::lonclonecourse::readfile($env{'request.course.id'},$item),
+ (%replacehash,$crs => '')
+ );
+ my $updatedcontent = '';
+ my $parser = HTML::TokeParser->new(\$content);
+ $parser->attr_encoded(1);
+ while (my $token = $parser->get_token) {
+ if ($token->[0] eq 'S') {
+ if (($token->[1] eq 'resource') &&
+ ($token->[2]->{'src'} eq '/res/lib/templates/simpleproblem.problem') &&
+ ($changes{$token->[2]->{'id'}})) {
+ my $id = $token->[2]->{'id'};
+ $updatedcontent .= '<'.$token->[1];
+ foreach my $attrib (@{$token->[3]}) {
+ next unless ($attrib =~ /^(src|type|title|id)$/);
+ if ($attrib eq 'src') {
+ my ($file) = ($display{$changes{$id}} =~ /^\Qsimpleproblem_\E(.+)$/);
+ if ($file) {
+ $updatedcontent .= ' '.$attrib.'="'.$file.'"';
+ } else {
+ $updatedcontent .= ' '.$attrib.'="'.$token->[2]->{$attrib}.'"';
+ }
+ } else {
+ $updatedcontent .= ' '.$attrib.'="'.$token->[2]->{$attrib}.'"';
+ }
+ }
+ $updatedcontent .= ' />'."\n";
+ } else {
+ $updatedcontent .= $token->[4]."\n";
+ }
+ } else {
+ $updatedcontent .= $token->[2];
+ }
+ }
+ print $fh $updatedcontent;
+ } else {
+ print $fh &Apache::lonclonecourse::rewritefile(
+ &Apache::lonclonecourse::readfile($env{'request.course.id'},$item),
+ (%replacehash,$crs => '')
+ );
+ }
+ } else {
+ print $fh
+ &Apache::lonclonecourse::readfile($env{'request.course.id'},$item);
+ }
+ } else {
+ $fail = &mt('Source does not exist.');
+ }
+ }
+ $fh->close();
+ } else {
+ $fail = &mt('Could not write to destination.');
+ }
+ }
+ my $text;
+ if ($fail) {
+ $text = ''.&mt('fail').(' 'x3).$fail.' ';
+ } else {
+ $text = ''.&mt('ok').' ';
+ }
+ if ($i == 0) {
+ $result .= $text;
+ } else {
+ $depresult .= $text.' ';
+ }
+ }
+ $r->print($result);
+ if ($depresult) {
+ $r->print('');
+ }
+ }
} else {
-# Input form
- unless ($home==1) {
- $r->print(
- ''.&mt('Select the Construction Space').' ');
- }
- foreach (sort keys %outhash) {
- if ($_=~/^home_(.+)$/) {
- if ($home==1) {
- $r->print(
- ' ');
- } else {
- $r->print(''.$1.' - '.
- &Apache::loncommon::plainname(split(/\@/,$1)).' ');
- }
- }
- }
- unless ($home==1) {
- $r->print(' ');
- }
- my $title=$origcrsdata{'description'};
- $title=~s/\s+/\_/gs;
- $title=&clean($title);
- $r->print(''.&mt('Folder in Construction Space').' ');
- &tiehash();
- $r->print(''.&mt('Filenames in Construction Space').' \n");
- &untiehash();
- $r->print(
- '
');
+ my $formname = 'dumpdoc';
+ my $preamble = &authorspace_selector($r,$formname,$home,$title,%outhash).
+ '
'."\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());
}
-# ------------------------------------------------------ Generate "export" button
+sub authorspace_selector {
+ my ($r,$formname,$home,$title,%outhash) = @_;
+ $r->print(''.&mt('Searching ...').'
'."\n");
+ $r->rflush();
+ my $preamble;
+ unless ($home==1) {
+ $preamble = ''.
+ '
'.
+ &mt('Select the Authoring Space').
+ ' ';
+ }
+ my @orderspaces = ();
+ foreach my $key (sort(keys(%outhash))) {
+ if ($key=~/^home_(.+)$/) {
+ if ($1 eq $env{'user.name'}.':'.$env{'user.domain'}) {
+ unshift(@orderspaces,$1);
+ } else {
+ push(@orderspaces,$1);
+ }
+ }
+ }
+ if ($home>1) {
+ $preamble .= ''.&mt('Select').' ';
+ }
+ foreach my $user (@orderspaces) {
+ if ($home==1) {
+ $preamble .= ' ';
+ } else {
+ $preamble .= ''.$user.' - '.
+ &Apache::loncommon::plainname(split(/\:/,$user)).' ';
+ }
+ }
+ unless ($home==1) {
+ $preamble .= ' '."\n";
+ }
+ $preamble .= ''.
+ '
'.&mt('Folder in Authoring Space').' '.
+ ' '."\n".
+ ' '."\n";
+ return $preamble;
+}
+
+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);
+ }
+ }
+ }
+ }
+ return;
+}
-sub exportbutton {
- return ''.
- ' '.
- &Apache::loncommon::help_open_topic('Docs_Export_Course_Docs');
+sub copycrsauthored {
+ my ($r,$coursenum,$coursedom,$coursehome,$readonly) = @_;
+ my ($starthash,$js,$title,$formname);
+ my %origcrsdata=&Apache::lonnet::coursedescription($env{'request.course.id'});
+ $title=$origcrsdata{'description'};
+ $title=~s/[\/\s]+/\_/gs;
+ $title=&clean($title);
+ my ($home,$other,%outhash)=&authorhosts();
+ unless (($env{'form.authorspace'}) && ($env{'form.authorfolder'}=~/\w/)) {
+ my %js_lt;
+ $formname = 'copycrsauthored';
+ if ($home) {
+ %js_lt =
+ &Apache::lonlocal::texthash(
+ yomu => 'You must select an Authoring Space',
+ whco => 'When Copyright set to "custom", URL of a published rights file is needed.',
+ );
+ &js_escape(\%js_lt);
+ }
+ if ($home > 1) {
+ $js = <<"ENDJS";
+
- &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
- ['finishexport']);
- if ($env{'form.finishexport'}) {
- &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
- ['archive','discussion']);
-
- my @exportitems = &Apache::loncommon::get_env_multiple('form.archive');
- my @discussions = &Apache::loncommon::get_env_multiple('form.discussion');
- if (@exportitems == 0 && @discussions == 0) {
- $outcome = ' As you did not select any content items or discussions for export, an IMS package has not been created. Please go back to select either content items or discussions for export';
- } else {
- my $now = time;
- my %symbs;
- my $manifestok = 0;
- my $imsresources;
- my $tempexport;
- my $copyresult;
- my $ims_manifest = &create_ims_store($now,\$manifestok,\$outcome,\$tempexport);
- if ($manifestok) {
- &build_package($now,$navmap,\@exportitems,\@discussions,\$outcome,$tempexport,\$copyresult,$ims_manifest);
- close($ims_manifest);
-
-#Create zip file in prtspool
- my $imszipfile = '/prtspool/'.
- $env{'user.name'}.'_'.$env{'user.domain'}.'_'.
- time.'_'.rand(1000000000).'.zip';
- my $cwd = &Cwd::getcwd();
- my $imszip = '/home/httpd/'.$imszipfile;
- chdir $tempexport;
- open(OUTPUT, "zip -r $imszip * 2> /dev/null |");
- close(OUTPUT);
- chdir $cwd;
- $outcome .= 'Download the zip file from IMS course archive ';
- if ($copyresult) {
- $outcome .= 'The following errors occurred during export - '.$copyresult;
- }
- } else {
- $outcome = ' Unfortunately you will not be able to retrieve an IMS archive of this posts at this time, because there was a problem creating a manifest file. ';
- }
- }
- $r->print(&Apache::loncommon::start_page('Export course to IMS content package'));
- $r->print($outcome);
- $r->print(&Apache::loncommon::end_page());
- } else {
- my $display;
- $display = ' ');
- }
-# ----------------------------------------------------- Supplemental documents
- if (!$forcestandard) {
- $r->print('');
-# ''.&mt('Supplemental Course Documents').
-# ($allowed?' '.$help{'Supplemental'}:'').' ');
+
+ my $newnavform=(<
+
+ $pathitem
+
+
+ $help{'Navigate_Content'}
+
+NNFORM
+ my $newsmppageform=(<
+
+ $pathitem
+
+
+ $help{'Simple Page'}
+
+NSPFORM
+
+ my $newsmpproblemform=(<
+
+ $pathitem
+
+
+ $help{'Simple_Problem'}
+
+
+NSPROBFORM
+
+ my $newdropboxform=(<
+
+ $pathitem
+
+
+ $help{'Dropbox'}
+
+NDBFORM
+
+ my $newexuploadform=(<
+
+ $pathitem
+
+
+ $help{'Score_Upload_Form'}
+
+NEXUFORM
+
+ my $newbulform=(<
+
+ $pathitem
+
+
+ $help{'Bulletin Board'}
+
+NBFORM
+
+ my $newaboutmeform=(<
+
+ $pathitem
+
+
+ $help{'My Personal Information Page'}
+
+NAMFORM
+
+ my $newaboutsomeoneform=(<
+
+ $pathitem
+
+
+
+NASOFORM
+
+ my $newrosterform=(<
+
+ $pathitem
+
+
+ $help{'Course_Roster'}
+
+NROSTFORM
+
+ my $newwebpage;
+ if ($folder =~ /^default_?(\d*)$/) {
+ $newwebpage = "/uploaded/$coursedom/$coursenum/docs/";
+ if ($1) {
+ $newwebpage .= $1;
+ } else {
+ $newwebpage .= 'default';
+ }
+ $newwebpage .= '/new.html';
+ }
+ my $newwebpageform =(<
+
+ $pathitem
+
+
+ $help{'Web_Page'}
+
+NWEBFORM
+ my $showpath = &HTML::Entities::encode($env{'form.folderpath'},'<>&"');
+ my @ids=&Apache::lonnet::current_machine_ids();
+ my $machines_str = "'".join("','",@ids)."'";
+ my (%is_home,%toppath,$rolehomes);
+ if ($env{'user.author'}) {
+ if (grep(/^\Q$env{'user.home'}\E$/,@ids)) {
+ $is_home{'author'} = 1;
+ }
+ $rolehomes = ' '."\n";
+ }
+ my %roleshash = &Apache::lonnet::get_my_roles($env{'user.name'},$env{'user.domain'},'userroles',
+ ['active'],['ca','aa']);
+ my %by_roletype;
+ if (keys(%roleshash)) {
+ foreach my $entry (keys(%roleshash)) {
+ my ($auname,$audom,$roletype) = split(/:/,$entry);
+ my $key = $entry;
+ $key =~ s/:/___/g;
+ my $author = $auname.'___'.$audom;
+ $by_roletype{$roletype}{$author} = 1;
+ my $rolehome = &Apache::lonnet::homeserver($auname,$audom);
+ $toppath{$author} = "/priv/$audom/$auname";
+ if (grep(/^\Q$rolehome\E$/,@ids)) {
+ $is_home{$author} = 1;
+ }
+ $rolehomes .= ' '."\n";
+ }
+ }
+ my $crshome = $env{'course.'.$env{'request.course.id'}.'.home'};
+ if (grep(/^\Q$crshome\E$/,@ids)) {
+ $is_home{'course'} = 1;
+ }
+ $rolehomes .= ' '."\n";
+ my $pickdir = $lt{'loca'}.
+ ''."\n".
+ ''.&mt('Select').' '."\n";
+ if ($env{'user.author'}) {
+ $pickdir .= ''.&Apache::lonnet::plaintext('au').' '."\n";
+ }
+ if (keys(%by_roletype)) {
+ foreach my $possrole ('ca','aa') {
+ if (ref($by_roletype{$possrole}) eq 'HASH') {
+ my $roletitle = &Apache::lonnet::plaintext($possrole);
+ foreach my $author (sort { lc($a) cmp lc($b) } (keys(%{$by_roletype{$possrole}}))) {
+ my ($none,$where,$auname,$audom) = split(/\//,$toppath{$author});
+ $pickdir .= ''.
+ $roletitle." ($audom/$auname) \n";
+ }
+ }
+ }
+ }
+ if ($checkcrsres) {
+ $pickdir .= ''.&mt('Course Resource').' '."\n";
+ }
+ $pickdir .= ' '."\n".
+ $lt{'dire'}.
+ ''.
+ ' '.
+ ' '."\n";
+ my %seltemplate_menus;
+ my @files = &Apache::lonhomework::get_template_list('problem');
+ my @noexamplelink = ('blank.problem','blank.library','script.library');
+ my $currentcategory = '';
+ my @ordered = ('');
+ my %templatehelp;
+ my $defcategory = '';
+ my @catorder = ($defcategory);
+ $seltemplate_menus{$defcategory}->{'order'} = [''];
+ $seltemplate_menus{$defcategory}->{'text'} = '';
+ foreach my $file (@files) {
+ if (ref($file) eq 'ARRAY') {
+ my ($path,$title,$category,$help) = @{$file};
+ next if ($title !~ /\S/);
+ if (&js_escape($category) ne $currentcategory) {
+ $currentcategory = &js_escape($category);
+ push(@catorder,&js_escape($currentcategory));
+ $seltemplate_menus{$currentcategory}->{'text'} = $category;
+ $seltemplate_menus{$currentcategory}->{'default'} = '';
+ $seltemplate_menus{$currentcategory}->{'select2'}->{''} = '';
+ push(@{$seltemplate_menus{$currentcategory}->{'order'}},'');
+ }
+ if ($path) {
+ $seltemplate_menus{$currentcategory}->{'select2'}->{&js_escape($path)} = $title;
+ push(@{$seltemplate_menus{$currentcategory}->{'order'}},&js_escape($path));
+ if ($help) {
+ $templatehelp{$path} = $help;
+ }
+ }
+ }
+ }
+
+ my $templates = $lt{'cate'}.' '.
+ &Apache::loncommon::linked_select_forms('courseresform',' '.$lt{'tmpl'}.' ',
+ $defcategory,'tempcategory','template',
+ \%seltemplate_menus,\@catorder,
+ "resize_scrollbox('contentscroll','1','0');",
+ "toggleExampleText();",'template').' ';
+ my $templatepreview = ''.
+ ''.&mt('Example').' ';
+ my $crsresform;
+ if (($env{'user.author'}) || ($checkcrsres)) {
+ $crsresform=(<
-ENDSUPFORM
- }
+ my $folderseq=
+ '/uploaded/'.$coursedom.'/'.$coursenum.'/supplemental_new.sequence';
+
+ my $supupdocform=(<