--- loncom/interface/londocs.pm 2003/09/17 23:40:25 1.81 +++ loncom/interface/londocs.pm 2005/06/13 20:23:53 1.189 @@ -1,7 +1,7 @@ # The LearningOnline Network # Documents # -# $Id: londocs.pm,v 1.81 2003/09/17 23:40:25 www Exp $ +# $Id: londocs.pm,v 1.189 2005/06/13 20:23:53 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -30,15 +30,18 @@ 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::lonxml; use Apache::loncreatecourse; +use Apache::lonnavmaps; use HTML::Entities; use GDBM_File; use Apache::lonlocal; +use Cwd; my $iconpath; @@ -68,10 +71,13 @@ sub mapread { sub storemap { my ($coursenum,$coursedom,$map)=@_; - $hadchanges=1; - return + my ($outtext,$errtext)= &Apache::lonratedt::storemap('/uploaded/'.$coursedom.'/'.$coursenum.'/'. $map,1); + if ($errtext) { return ($errtext,2); } + + $hadchanges=1; + return ($errtext,0); } # ----------------------------------------- Return hash with valid author names @@ -80,27 +86,29 @@ sub authorhosts { my %outhash=(); my $home=0; my $other=0; - foreach (keys %ENV) { + foreach (keys %env) { if ($_=~/^user\.role\.(au|ca)\.(.+)$/) { my $role=$1; my $realm=$2; - my ($start,$end)=split(/\./,$ENV{$_}); + my ($start,$end)=split(/\./,$env{$_}); if (($start) && ($start>time)) { next; } if (($end) && (time>$end)) { next; } my $ca; my $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+)$/); } - if (&Apache::lonnet::homeserver($ca,$cd) eq - $Apache::lonnet::perlvar{'lonHostID'}) { + 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; } } + if ($allowed) { $home++; $outhash{'home_'.$ca.'@'.$cd}=1; } else { - $outhash{'otherhome_'.$ca.'@'.$cd}= - &Apache::lonnet::homeserver($ca,$cd); + $outhash{'otherhome_'.$ca.'@'.$cd}=$myhome; $other++; } } @@ -116,42 +124,49 @@ sub dumpbutton { if ($home) { return ''. ''; + &mt('Dump Course DOCS to Construction Space').'" />'. + &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'. + my $html=&Apache::lonxml::xmlbegin(); + $r->print($html.'Dump DOCS'. &Apache::loncommon::bodytag('Dump Course DOCS to Construction Space'). '
'); my ($home,$other,%outhash)=&authorhosts(); unless ($home) { return ''; } - my $origcrsid=$ENV{'request.course.id'}; + my $origcrsid=$env{'request.course.id'}; my %origcrsdata=&Apache::lonnet::coursedescription($origcrsid); - if (($ENV{'form.authorspace'}) && ($ENV{'form.authorfolder'}=~/\w/)) { + 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'}); - $r->print('

Copying Files

'); - my $title=$ENV{'form.authorfolder'}; - $title=~s/[^\w\/]+/\_/g; + unless ($outhash{'home_'.$env{'form.authorspace'}}) { 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) { + foreach (keys %env) { if ($_=~/^form\.namefor\_(.+)/) { - $replacehash{$1}=$ENV{$_}; + $replacehash{$1}=$env{$_}; } } - my $crs='/uploaded/'.$ENV{'request.course.id'}.'/'; + my $crs='/uploaded/'.$env{'request.course.id'}.'/'; $crs=~s/\_/\//g; foreach (keys %replacehash) { my $newfilename=$title.'/'.$replacehash{$_}; - $newfilename=~s/[^\w\/\.]+/\_/g; + $newfilename=&clean($newfilename); my @dirs=split(/\//,$newfilename); my $path='/home/'.$ca.'/public_html'; my $makepath=$path; @@ -166,12 +181,12 @@ sub dumpcourse { 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'},$_), + &Apache::loncreatecourse::readfile($env{'request.course.id'},$_), (%replacehash,$crs => '') ); } else { print $fh - &Apache::loncreatecourse::readfile($ENV{'request.course.id'},$_); + &Apache::loncreatecourse::readfile($env{'request.course.id'},$_); } $fh->close(); } else { @@ -195,7 +210,8 @@ sub dumpcourse { $r->print( ''); } else { - $r->print(''); + $r->print(''); } } } @@ -204,7 +220,7 @@ sub dumpcourse { } my $title=$origcrsdata{'description'}; $title=~s/\s+/\_/gs; - $title=~s/\W//gs; + $title=&clean($title); $r->print('

'.&mt('Folder in Construction Space').'


'); &tiehash(); $r->print('

'.&mt('Filenames in Construction Space').'

'); @@ -213,12 +229,13 @@ sub dumpcourse { my ($ext)=($_=~/\.(\w+)$/); my $title=$hash{'title_'.$hash{ 'ids_/uploaded/'.$origcrsdata{'domain'}.'/'.$origcrsdata{'num'}.'/'.$_}}; + $title=~s/:/:/g; $r->print(''); unless ($title) { $title=$_; } $title=~s/\.(\w+)$//; - $title=~s/\W+/\_/gs; + $title=&clean($title); $title.='.'.$ext; $r->print("\n\n"); } @@ -229,6 +246,579 @@ sub dumpcourse { } } +# ------------------------------------------------------ Generate "export" button + +sub exportbutton { + return ''; + return ''); + } + $r->print("\n
'.&mt('Internal Filename').''.&mt('Title').''.&mt('Save as ...').'
'.($title?$title:' ').'
'. + ''. + &Apache::loncommon::help_open_topic('Docs_Export_Course_Docs'); +} + +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; + my $outcome; + + &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.
'; + } + } + my $html=&Apache::lonxml::xmlbegin(); + $r->print($html.'Export Course'. + &Apache::loncommon::bodytag('Export course to IMS content package')); + $r->print($outcome); + $r->print(''); + } else { + my $display; + $display = ''."\n"; + $display .= 'Choose which items you wish to export from your course.

'; + $display .= ''. + ''. + ''. + ''. + '
 Content items'. + ''. + '  
  
 Discussion posts'. + ''. + '  
'; + my $curRes; + my $depth = 0; + my $count = 0; + my $boards = 0; + my $startcount = 5; + my %parent = (); + my %children = (); + my $lastcontainer = $startcount; + my @bgcolors = ('#F6F6F6','#FFFFFF'); + $display .= ''. + ''; + while ($curRes = $it->next()) { + if (ref($curRes)) { + $count ++; + } + if ($curRes == $it->BEGIN_MAP()) { + $depth++; + $parent{$depth} = $lastcontainer; + } + if ($curRes == $it->END_MAP()) { + $depth--; + $lastcontainer = $parent{$depth}; + } + if (ref($curRes)) { + my $symb = $curRes->symb(); + my $ressymb = $symb; + if ($ressymb =~ m|adm/(\w+)/(\w+)/(\d+)/bulletinboard$|) { + unless ($ressymb =~ m|adm/wrapper/adm|) { + $ressymb = 'bulletin___'.$3.'___adm/wrapper/adm/'.$1.'/'.$2.'/'.$3.'/bulletinboard'; + } + } + my $color = $count%2; + $display .=''; + if ($discussiontime{$ressymb} > 0) { + $boards ++; + $currelem = $count+$boards+$startcount; + $display .= ''."\n"; + } else { + $display .= ''."\n"; + } + } + } + my $scripttag = qq| + + |; + my $html=&Apache::lonxml::xmlbegin(); + $r->print($html.'Export Course'.$scripttag.''. + &Apache::loncommon::bodytag('Export course to IMS content package' +)); + + $r->print($display.'
Export content item?
 '."\n"; + if ($numdisc > 0) { + $display.='Export discussion posts?'."\n"; + } + $display.=' 
'."\n". + 'is_sequence()) || ($curRes->is_page())) { + my $checkitem = $count + $boards + $startcount; + $display .= 'onClick="javascript:propagateCheck('."'$checkitem'".')"'; + } + $display .= ' />'."\n"; + for (my $i=0; $i<$depth; $i++) { + $display .= ''."\n"; + } + if ($curRes->is_sequence()) { + $display .= ' '."\n"; + $lastcontainer = $count + $startcount + $boards; + } elsif ($curRes->is_page()) { + $display .= ' '."\n"; + $lastcontainer = $count + $startcount + $boards; + } + my $currelem = $count+$boards+$startcount; + $children{$parent{$depth}} .= $currelem.':'; + $display .= ' '.$curRes->title().'   
'. + '

'. + '

'); + } +} + +sub create_ims_store { + my ($now,$manifestok,$outcome,$tempexport) = @_; + $$tempexport = $Apache::lonnet::perlvar{'lonDaemons'}.'/tmp/ims_exports'; + my $ims_manifest; + if (!-e $$tempexport) { + mkdir($$tempexport,0700); + } + $$tempexport .= '/'.$now; + if (!-e $$tempexport) { + mkdir($$tempexport,0700); + } + $$tempexport .= '/'.$env{'user.domain'}.'_'.$env{'user.name'}; + if (!-e $$tempexport) { + mkdir($$tempexport,0700); + } + if (!-e "$$tempexport/resources") { + mkdir("$$tempexport/resources",0700); + } +# open manifest file + my $manifest = '/imsmanifest.xml'; + my $manifestfilename = $$tempexport.$manifest; + if ($ims_manifest = Apache::File->new('>'.$manifestfilename)) { + $$manifestok=1; + print $ims_manifest +''."\n". +''."\n". +' '."\n". +' '."\n". +' '.$env{'request.'.$env{'request.course.id'}.'.description'}.'' + } else { + $$outcome .= 'An error occurred opening the IMS manifest file.
' +; + } + return $ims_manifest; +} + +sub build_package { + my ($now,$navmap,$exportitems,$discussions,$outcome,$tempexport,$copyresult,$ims_manifest) = @_; +# first iterator to look for dependencies + my $it = $navmap->getIterator(undef,undef,undef,1,undef,undef); + my $curRes; + my $count = 0; + my $depth = 0; + my $lastcontainer = 0; + my %parent = (); + my @dependencies = (); + my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + while ($curRes = $it->next()) { + if (ref($curRes)) { + $count ++; + } + if ($curRes == $it->BEGIN_MAP()) { + $depth++; + $parent{$depth} = $lastcontainer; + } + if ($curRes == $it->END_MAP()) { + $depth--; + $lastcontainer = $parent{$depth}; + } + if (ref($curRes)) { + if ($curRes->is_sequence() || $curRes->is_page()) { + $lastcontainer = $count; + } + if (grep/^$count$/,@$exportitems) { + &get_dependencies($exportitems,\%parent,$depth,\@dependencies); + } + } + } +# second iterator to build manifest and store resources + $it = $navmap->getIterator(undef,undef,undef,1,undef,undef); + $depth = 0; + my $prevdepth; + $count = 0; + my $imsresources; + my $pkgdepth; + my $included = 0; + while ($curRes = $it->next()) { + if ($curRes == $it->BEGIN_MAP()) { + $prevdepth = $depth; + $depth++; + } + if ($curRes == $it->END_MAP()) { + $prevdepth = $depth; + $depth--; + } + + if (ref($curRes)) { + $count ++; + if ((grep/^$count$/,@$exportitems) || (grep/^$count$/,@dependencies)) { + my $symb = $curRes->symb(); + my $isvisible = 'true'; + my $resourceref; + if ($curRes->randomout()) { + $isvisible = 'false'; + } + unless ($curRes->is_sequence()) { + $resourceref = 'identifierref="RES-'.$env{'request.course.id'}.'-'.$count.'"'; + } + if (($depth <= $prevdepth) && ($count > 1) && ($included)) { + print $ims_manifest "\n".' '."\n"; + } + $included = 1; + $prevdepth = $depth; + + my $itementry = + ''. + ''.$curRes->title().''; + print $ims_manifest "\n".$itementry; + + unless ($curRes->is_sequence()) { + my $content_file; + my @hrefs = (); + &process_content($count,$curRes,$cdom,$cnum,$symb,\$content_file,\@hrefs,$copyresult,$tempexport); + if ($content_file) { + $imsresources .= "\n". + ' '."\n". + ' '."\n"; + foreach (@hrefs) { + $imsresources .= + ' '."\n"; + } + if (grep/^$count$/,@$discussions) { + my $ressymb = $symb; + my $mode; + if ($ressymb =~ m|adm/(\w+)/(\w+)/(\d+)/bulletinboard$|) { + unless ($ressymb =~ m|adm/wrapper/adm|) { + $ressymb = 'bulletin___'.$3.'___adm/wrapper/adm/'.$1.'/'.$2.'/'.$3.'/bulletinboard'; + } + $mode = 'board'; + } + my %extras = ( + caller => 'imsexport', + tempexport => $tempexport.'/resources', + count => $count + ); + my $discresult = &Apache::lonfeedback::list_discussion($mode,undef,$ressymb,\%extras); + } + $imsresources .= ' '."\n"; + } + } + $pkgdepth = $depth; + } else { + $included = 0; + } + } + } + while ($pkgdepth > 0) { + print $ims_manifest " \n"; + $pkgdepth --; + } + my $resource_text = qq| +
+
+ + $imsresources + +
+ |; + print $ims_manifest $resource_text; +} + +sub get_dependencies { + my ($exportitems,$parent,$depth,$dependencies) = @_; + if ($depth > 1) { + if ((!grep/^$$parent{$depth}$/,@$exportitems) && (!grep/^$$parent{$depth}$/,@$dependencies)) { + push @$dependencies, $$parent{$depth}; + if ($depth > 2) { + &get_dependencies($exportitems,$parent,$depth-1,$dependencies); + } + } + } +} + +sub process_content { + my ($count,$curRes,$cdom,$cnum,$symb,$content_file,$href,$copyresult,$tempexport) = @_; + my $content_type; + my $message; +# find where user is author or co-author + my @uploads = (); + if ($curRes->is_sequence()) { + $content_type = 'sequence'; + } elsif ($curRes->is_page()) { + $content_type = 'page'; # need to handle individual items in pages. + } elsif ($symb =~ m-public/$cdom/$cnum/syllabus$-) { + $content_type = 'syllabus'; + my $contents = &Apache::imsexport::templatedpage($content_type); + if ($contents) { + $$content_file = &store_template($contents,$tempexport,$count,$content_type); + } + } elsif ($symb =~ m-\.sequence___\d+___ext-) { + $content_type = 'external'; + my $title = $curRes->title; + my $contents = &Apache::imsexport::external($symb,$title); + if ($contents) { + $$content_file = &store_template($contents,$tempexport,$count,$content_type); + } + } elsif ($symb =~ m-adm/navmaps$-) { + $content_type = 'navmap'; + } elsif ($symb =~ m-adm/[^/]+/[^/]+/(\d+)/smppg$-) { + $content_type = 'simplepage'; + my $contents = &Apache::imsexport::templatedpage($content_type,$1,$count,\@uploads); + if ($contents) { + $$content_file = &store_template($contents,$tempexport,$count,$content_type); + } + } elsif ($symb =~ m-lib/templates/simpleproblem\.problem$-) { + $content_type = 'simpleproblem'; + my $contents = &Apache::imsexport::simpleproblem($symb); + if ($contents) { + $$content_file = &store_template($contents,$tempexport,$count,$content_type); + } + } elsif ($symb =~ m-lib/templates/examupload\.problem$-) { + $content_type = 'examupload'; + } elsif ($symb =~ m-adm/(\w+)/(\w+)/(\d+)/bulletinboard$-) { + $content_type = 'bulletinboard'; + my $contents = &Apache::imsexport::templatedpage($content_type,$3,$count,\@uploads,$1,$2); + if ($contents) { + $$content_file = &store_template($contents,$tempexport,$count,$content_type); + } + } elsif ($symb =~ m-adm/([^/]+)/([^/]+)/aboutme$-) { + $content_type = 'aboutme'; + my $contents = &Apache::imsexport::templatedpage($content_type,undef,$count,\@uploads,$1,$2); + if ($contents) { + $$content_file = &store_template($contents,$tempexport,$count,$content_type); + } + } elsif ($symb =~ m-\.(sequence|page)___\d+___uploaded/$cdom/$cnum/-) { + $$content_file = &replicate_content($cdom,$cnum,$tempexport,$symb,$count,\$message,$href,'uploaded'); + } elsif ($symb =~ m-\.(sequence|page)___\d+___([^/]+)/([^/]+)-) { + my $canedit = 0; + if ($2 eq $env{'user.domain'} && $3 eq $env{'user.name'}) { + $canedit= 1; + } + if ($canedit) { + $$content_file = &replicate_content($cdom,$cnum,$tempexport,$symb,$count,\$message,$href,'resource'); + } else { + $$content_file = &replicate_content($cdom,$cnum,$tempexport,$symb,$count,\$message,$href,'noedit'); + } + } elsif ($symb =~ m-uploaded/$cdom/$cnum-) { + $$content_file = &replicate_content($cdom,$cnum,$tempexport,$symb,$count,\$message,$href,'uploaded'); + } + if (@uploads > 0) { + foreach my $item (@uploads) { + my $uploadmsg = ''; + &replicate_content($cdom,$cnum,$tempexport,$item,$count,\$uploadmsg,$href,'templateupload'); + if ($uploadmsg) { + $$copyresult .= $uploadmsg."\n"; + } + } + } + if ($message) { + $$copyresult .= $message."\n"; + } +} + +sub replicate_content { + my ($cdom,$cnum,$tempexport,$symb,$count,$message,$href,$caller) = @_; + my ($map,$ind,$url); + if ($caller eq 'templateupload') { + $url = $symb; + $url =~ s#//#/#g; + } else { + ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb); + } + my $content; + my $filename; + my $repstatus; + my $content_name; + if ($url =~ m-/([^/]+)$-) { + $filename = $1; + if (!-e $tempexport.'/resources') { + mkdir($tempexport.'/resources',0700); + } + if (!-e $tempexport.'/resources/'.$count) { + mkdir($tempexport.'/resources/'.$count,0700); + } + my $destination = $tempexport.'/resources/'.$count.'/'.$filename; + my $copiedfile; + if ($copiedfile = Apache::File->new('>'.$destination)) { + my $content; + if ($caller eq 'resource') { + $content = &Apache::lonnet::getfile('/home/httpd/html/res/'.$url); + if ($content eq -1) { + $$message = 'Could not copy file '.$filename; + } else { + &extract_media($content,$count,$tempexport,$href,'resource'); + $repstatus = 'ok'; + } + } elsif ($caller eq 'uploaded' || $caller eq 'templateupload') { + my $rtncode; + $repstatus = &Apache::lonnet::getuploaded('GET',$url,$cdom,$cnum,\$content,$rtncode); + if ($repstatus eq 'ok') { + if ($url =~ /\.html?$/i) { + &extract_media(\$content,$count,$tempexport,$href,'uploaded'); + } + } else { + $$message = 'Could not render '.$url.' server message - '.$rtncode; + } + } elsif ($caller eq 'noedit') { +# Need to render the resource without the LON-CAPA Internal header and the Post discussion footer, and then set $content equal to this. + $repstatus = 'ok'; + $content = 'Not the owner of this resource'; + } + if ($repstatus eq 'ok') { + print $copiedfile $content; + } + close($copiedfile); + } else { + $$message = 'Could not open destination file for '.$filename."\n"; + } + } else { + $$message = 'Could not determine name of file for '.$symb."\n"; + } + if ($repstatus eq 'ok') { + $content_name = $count.'/'.$filename; + } + return $content_name; +} + +sub extract_media { + my ($content,$count,$tempexport,$href,$caller) = @_; +# @$href will contain path to any embedded resources in the content. +# For LON-CAPA problems this would be images. applets etc. +# For uploaded HTML files this would be images etc. +# paths will be in the form $count/res/$file, and urls in the $content will be rewritten with the new paths. + return; +} + +sub store_template { + my ($contents,$tempexport,$count,$content_type) = @_; + if ($contents) { + if ($tempexport) { + if (!-e $tempexport.'/resources') { + mkdir($tempexport.'/resources',0700); + } + if (!-e $tempexport.'/resources/'.$count) { + mkdir($tempexport.'/resources/'.$count,0700); + } + my $destination = $tempexport.'/resources/'.$count.'/'.$content_type.'.xml'; + my $storetemplate; + if ($storetemplate = Apache::File->new('>'.$destination)) { + print $storetemplate $contents; + close($storetemplate); + } + if ($content_type eq 'external') { + return $count.'/'.$content_type.'.html'; + } else { + return $count.'/'.$content_type.'.xml'; + } + } + } +} # Imports the given (name, url) resources into the course # coursenum, coursedom, and folder must precede the list @@ -236,11 +826,32 @@ sub group_import { my $coursenum = shift; my $coursedom = shift; my $folder = shift; + my $container = shift; + my $caller = shift; while (@_) { my $name = shift; my $url = shift; + if (($url =~ m#^/uploaded/$coursedom/$coursenum/(default_\d+\.)(page|sequence)$#) && ($caller eq 'londocs')) { + my $errtext = ''; + my $fatal = 0; + my $newmapstr = ''."\n". + ''."\n". + ''."\n". + ''."\n". + ''; + $env{'form.output'}=$newmapstr; + my $result=&Apache::lonnet::finishuserfileupload($coursenum,$coursedom, + 'output',$1.$2); + if ($result != m|^/uploaded/|) { + $errtext.='Map not saved: A network error occured when trying to save the new map. '; + $fatal = 2; + } + if ($fatal) { + return ($errtext,$fatal); + } + } if ($url) { - my $idx = $#Apache::lonratedt::resources + 1; + my $idx = &Apache::lonratedt::getresidx($url); $Apache::lonratedt::order[$#Apache::lonratedt::order+1]=$idx; my $ext = 'false'; if ($url=~/^http:\/\//) { $ext = 'true'; } @@ -250,57 +861,195 @@ sub group_import { join ':', ($name, $url, $ext, 'normal', 'res'); } } - &storemap($coursenum, $coursedom, $folder.'.sequence'); + return &storemap($coursenum, $coursedom, $folder.'.'.$container); } -sub editor { - my ($r,$coursenum,$coursedom,$folder,$allowed)=@_; - if ($ENV{'form.foldername'}) { - $r->print('

Folder: '.$ENV{'form.foldername'}.'

'); +sub breadcrumbs { + my ($where)=@_; + &Apache::lonhtmlcommon::clear_breadcrumbs(); + my (@folders); + if ($env{'form.pagepath'}) { + @folders = split('&',$env{'form.pagepath'}); + } else { + @folders=split('&',$env{'form.folderpath'}); + } + my $folderpath; + my $cpinfo=''; + if ($env{'form.markedcopy_url'}) { + &Apache::lonnet::logthis('Found '.$env{'form.markedcopy_url'}); + $cpinfo='&markedcopy_url='. + &Apache::lonnet::escape($env{'form.markedcopy_url'}). + '&markedcopy_title='. + &Apache::lonnet::escape($env{'form.markedcopy_title'}); } + while (@folders) { + my $folder=shift(@folders); + my $foldername=shift(@folders); + if ($folderpath) {$folderpath.='&';} + $folderpath.=$folder.'&'.$foldername; + my $url='/adm/coursedocs?folderpath='. + &Apache::lonnet::escape($folderpath); + &Apache::lonhtmlcommon::add_breadcrumb( + {'href'=>$url.$cpinfo, + 'title'=>&Apache::lonnet::unescape($foldername), + 'text'=>''. + &Apache::lonnet::unescape($foldername).'' + }); + + + } + return &Apache::lonhtmlcommon::breadcrumbs(undef,undef,undef,undef,undef, + 0,'nohelp'); +} + +sub editor { + my ($r,$coursenum,$coursedom,$folder,$allowed,$upload_output)=@_; my $errtext=''; my $fatal=0; + my $container='sequence'; + if ($env{'form.pagepath'}) { + $container='page'; + } ($errtext,$fatal)= - &mapread($coursenum,$coursedom,$folder.'.sequence'); + &mapread($coursenum,$coursedom,$folder.'.'.$container); if ($#Apache::lonratedt::order<1) { - $Apache::lonratedt::order[0]=1; - $Apache::lonratedt::resources[1]=''; + my $idx=&Apache::lonratedt::getresidx(); + if ($idx<=0) { $idx=1; } + $Apache::lonratedt::order[0]=$idx; + $Apache::lonratedt::resources[$idx]=''; } + if (defined($env{'form.markcopy'})) { +# Mark for copying + my ($title,$url)=split(':',$Apache::lonratedt::resources[$Apache::lonratedt::order[$env{'form.markcopy'}]]); + $env{'form.markedcopy_title'}=$title; + $env{'form.markedcopy_url'}=$url; + } + $r->print(&breadcrumbs($folder)); if ($fatal) { $r->print('

'.$errtext.'

'); } else { # ------------------------------------------------------------ Process commands + # ---------------- if they are for this folder and user allowed to make changes - if (($allowed) && ($ENV{'form.folder'} eq $folder)) { -# upload a file, if present - if (($ENV{'form.uploaddoc.filename'}) && - ($ENV{'form.cmd'}=~/^upload_(\w+)/)) { - if ($folder=~/^$1/) { -# this is for a course, not a user, so set coursedoc flag -# probably the only place in the system where this should be "1" - my $url=&Apache::lonnet::userfileupload('uploaddoc',1); - my $ext='false'; - if ($url=~/^http\:\/\//) { $ext='true'; } - $url=~s/\:/\:/g; - my $comment=$ENV{'form.comment'}; - $comment=~s/\/\>\;/g; - $comment=~s/\:/\:/g; - if ($folder=~/^supplemental/) { - $comment=time.'___&&&___'.$ENV{'user.name'}.'___&&&___'. - $ENV{'user.domain'}.'___&&&___'.$comment; - } - my $newidx=$#Apache::lonratedt::resources+1; - $Apache::lonratedt::resources[$newidx]= - $comment.':'.$url.':'.$ext.':normal:res'; - $Apache::lonratedt::order[$#Apache::lonratedt::order+1]= - $newidx; - &storemap($coursenum,$coursedom,$folder.'.sequence'); - } - } - if ($ENV{'form.cmd'}) { - my ($cmd,$idx)=split(/\_/,$ENV{'form.cmd'}); + if (($allowed) && ($env{'form.folder'} eq $folder)) { +# set parameters and change order + if (defined($env{'form.setparms'})) { + my $idx=$env{'form.setparms'}; +# set parameters + if ($env{'form.randpick_'.$idx}) { + &Apache::lonratedt::storeparameter($idx,'parameter_randompick',$env{'form.randpick_'.$idx},'int_pos'); + } else { + &Apache::lonratedt::delparameter($idx,'parameter_randompick'); + } + if ($env{'form.hidprs_'.$idx}) { + &Apache::lonratedt::storeparameter($idx,'parameter_hiddenresource','yes','string_yesno'); + } else { + &Apache::lonratedt::delparameter($idx,'parameter_hiddenresource'); + } + if ($env{'form.encprs_'.$idx}) { + &Apache::lonratedt::storeparameter($idx,'parameter_encrypturl','yes','string_yesno'); + } else { + &Apache::lonratedt::delparameter($idx,'parameter_encrypturl'); + } + + if ($env{'form.newpos'}) { +# change order + + my $newpos=$env{'form.newpos'}-1; + my $currentpos=$env{'form.currentpos'}-1; + my $i; + my @neworder=(); + if ($newpos>$currentpos) { +# moving stuff up + for ($i=0;$i<$currentpos;$i++) { + $neworder[$i]=$Apache::lonratedt::order[$i]; + } + for ($i=$currentpos;$i<$newpos;$i++) { + $neworder[$i]=$Apache::lonratedt::order[$i+1]; + } + $neworder[$newpos]=$Apache::lonratedt::order[$currentpos]; + for ($i=$newpos+1;$i<=$#Apache::lonratedt::order;$i++) { + $neworder[$i]=$Apache::lonratedt::order[$i]; + } + } else { +# moving stuff down + for ($i=0;$i<$newpos;$i++) { + $neworder[$i]=$Apache::lonratedt::order[$i]; + } + $neworder[$newpos]=$Apache::lonratedt::order[$currentpos]; + for ($i=$newpos+1;$i<$currentpos+1;$i++) { + $neworder[$i]=$Apache::lonratedt::order[$i-1]; + } + for ($i=$currentpos+1;$i<=$#Apache::lonratedt::order;$i++) { + $neworder[$i]=$Apache::lonratedt::order[$i]; + } + } + @Apache::lonratedt::order=@neworder; + } +# store the changed version + + ($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.'.$container); + if ($fatal) { + $r->print('

'.$errtext.'

'); + return; + } + + } + if ($env{'form.pastemarked'}) { +# paste resource to end of list + my $url=$env{'form.markedcopy_url'}; + my $title=$env{'form.markedcopy_title'}; +# Maps need to be copied first + if (($url=~/\.(page|sequence)$/) || ($url=~/^\/uploaded\//)) { + $title=&mt('Copy of').' '.$title; + my $newid=$$.time; + $url=~/^(.+)\.(\w+)$/; + my $newurl=$1.$newid.'.'.$2; + my $storefn=$newurl; + $storefn=~s/^\/\w+\/\w+\/\w+\///; + &Apache::loncreatecourse::writefile + ($env{'request.course.id'},$storefn, + &Apache::lonnet::getfile($url)); + $url=$newurl; + } + $title=~s/\/\>\;/g; + $title=~s/\:/\:/g; + my $ext='false'; + if ($url=~/^http\:\/\//) { $ext='true'; } + $url=~s/\:/\:/g; +# Now insert the URL at the bottom + my $newidx=&Apache::lonratedt::getresidx($url); + $Apache::lonratedt::resources[$newidx]= + $title.':'.$url.':'.$ext.':normal:res'; + $Apache::lonratedt::order[1+$#Apache::lonratedt::order]=$newidx; +# Store the result + ($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.'.$container); + if ($fatal) { + $r->print('

'.$errtext.'

'); + return; + } + + } + $r->print($upload_output); + if ($env{'form.cmd'}) { + my ($cmd,$idx)=split(/\_/,$env{'form.cmd'}); if ($cmd eq 'del') { + my (undef,$url)=split(':',$Apache::lonratedt::resources[$Apache::lonratedt::order[$idx]]); + if (($url=~m|/+uploaded/\Q$coursedom\E/\Q$coursenum\E/|) && + ($url!~/\.(page|sequence|problem|exam|quiz|assess|survey|form|library)$/)) { + &Apache::lonnet::removeuploadedurl($url); + } else { + &Apache::lonratedt::makezombie($Apache::lonratedt::order[$idx]); + } + for (my $i=$idx;$i<$#Apache::lonratedt::order;$i++) { + $Apache::lonratedt::order[$i]= + $Apache::lonratedt::order[$i+1]; + } + $#Apache::lonratedt::order--; + } elsif ($cmd eq 'cut') { + my (undef,$url)=split(':',$Apache::lonratedt::resources[$Apache::lonratedt::order[$idx]]); + &Apache::lonratedt::makezombie($Apache::lonratedt::order[$idx]); for (my $i=$idx;$i<$#Apache::lonratedt::order;$i++) { $Apache::lonratedt::order[$i]= $Apache::lonratedt::order[$i+1]; @@ -321,26 +1070,33 @@ sub editor { $Apache::lonratedt::order[$idx]=$i; } } elsif ($cmd eq 'rename') { + my $ratstr = $Apache::lonratedt::resources[$Apache::lonratedt::order[$idx]]; my ($rtitle,@rrest)=split(/\:/, $Apache::lonratedt::resources[ $Apache::lonratedt::order[$idx]]); my $comment= - &HTML::Entities::decode($ENV{'form.title'}); + &HTML::Entities::decode($env{'form.title'}); $comment=~s/\/\>\;/g; $comment=~s/\:/\:/g; - $Apache::lonratedt::resources[ + if ($comment=~/\S/) { + $Apache::lonratedt::resources[ $Apache::lonratedt::order[$idx]]= - $comment.':'.join(':',@rrest); - + $comment.':'.join(':',@rrest); + } } # Store the changed version - &storemap($coursenum,$coursedom,$folder.'.sequence'); + ($errtext,$fatal)=&storemap($coursenum,$coursedom, + $folder.'.'.$container); + if ($fatal) { + $r->print('

'.$errtext.'

'); + return; + } } # Group import/search - if ($ENV{'form.importdetail'}) { + if ($env{'form.importdetail'}) { my @imports; - foreach (split(/\&/,$ENV{'form.importdetail'})) { + foreach (split(/\&/,$env{'form.importdetail'})) { if (defined($_)) { my ($name,$url)=split(/\=/,$_); $name=&Apache::lonnet::unescape($name); @@ -349,122 +1105,453 @@ sub editor { } } # Store the changed version - group_import($coursenum, $coursedom, $folder, @imports); + ($errtext,$fatal)=group_import($coursenum, $coursedom, $folder, + $container,'londocs',@imports); + if ($fatal) { + $r->print('

'.$errtext.'

'); + return; + } } # Loading a complete map - if (($ENV{'form.importmap'}) && ($ENV{'form.loadmap'})) { - foreach -(&Apache::lonsequence::attemptread(&Apache::lonnet::filelocation('',$ENV{'form.importmap'}))) { - my $idx=$#Apache::lonratedt::resources; - $idx++; + if (($env{'form.importmap'}) && ($env{'form.loadmap'})) { + foreach (&Apache::lonsequence::attemptread(&Apache::lonnet::filelocation('',$env{'form.importmap'}))) { + my ($title,$url,$ext,$type)=split(/\:/,$_); + my $idx=&Apache::lonratedt::getresidx($url); $Apache::lonratedt::resources[$idx]=$_; $Apache::lonratedt::order - [$#Apache::lonratedt::order+1]=$idx; - } + [$#Apache::lonratedt::order+1]=$idx; + } # Store the changed version - &storemap($coursenum,$coursedom,$folder.'.sequence'); + ($errtext,$fatal)=&storemap($coursenum,$coursedom, + $folder.'.'.$container); + if ($fatal) { + $r->print('

'.$errtext.'

'); + return; + } } } # ---------------------------------------------------------------- End commands # ---------------------------------------------------------------- Print screen my $idx=0; + my $shown=0; $r->print(''); foreach (@Apache::lonratedt::order) { my ($name,$url)=split(/\:/,$Apache::lonratedt::resources[$_]); unless ($name) { $name=(split(/\//,$url))[-1]; } - unless ($name) { $name='NO RESOURCE'; $url='/adm/notfound.html'; } - $r->print(&entryline($idx,$name,$url,$folder,$allowed,$_)); + unless ($name) { $idx++; next; } + $r->print(&entryline($idx,$name,$url,$folder,$allowed,$_,$coursenum)); $idx++; + $shown++; } - $r->print('
'); + unless ($shown) { + $r->print('
'.&mt('Currently no documents.').'
\n"); + if ($env{'form.markedcopy_url'}) { + $r->print(<
+ + +ENDPASTE + $r->print( + ' '.&Apache::loncommon::filedescription( + (split(/\./,$env{'form.markedcopy_url'}))[-1]).': '. + $env{'form.markedcopy_title'}); + if ($container eq 'page') { + $r->print(< + +PAGEINFO + } else { + $r->print(< +FOLDERINFO + } + $r->print('

'); + } } } +sub process_file_upload { + my ($upload_output,$coursenum,$coursedom,$allfiles,$codebase) = @_; +# upload a file, if present + my $parseaction; + if ($env{'form.parserflag'}) { + $parseaction = 'parse'; + } + my $phase_status; + my $folder=$env{'form.folder'}; + if ($folder eq '' || $folder eq 'supplemental') { + $folder='default'; + } + if ( ($folder=~/^$1/) || ($1 eq 'default') ) { + my $errtext=''; + my $fatal=0; + my $container='sequence'; + if ($env{'form.pagepath'}) { + $container='page'; + } + ($errtext,$fatal)= + &mapread($coursenum,$coursedom,$folder.'.'.$container); + if ($#Apache::lonratedt::order<1) { + $Apache::lonratedt::order[0]=1; + $Apache::lonratedt::resources[1]=''; + } + if ($fatal) { + return 'failed'; + } + my $destination = 'docs/'; + if ($folder eq 'default') { + $destination .= 'default/'; + } elsif ($folder =~ /^default_(\d+)$/) { + $destination .= $1.'/'; + } +# this is for a course, not a user, so set coursedoc flag +# probably the only place in the system where this should be "1" + my $newidx=&Apache::lonratedt::getresidx(); + $destination .= $newidx; + my $url=&Apache::lonnet::userfileupload('uploaddoc',1,$destination,$parseaction,$allfiles,$codebase); + my $ext='false'; + if ($url=~/^http\:\/\//) { $ext='true'; } + $url=~s/\:/\:/g; + my $comment=$env{'form.comment'}; + $comment=~s/\/\>\;/g; + $comment=~s/\:/\:/g; + if ($folder=~/^supplemental/) { + $comment=time.'___&&&___'.$env{'user.name'}.'___&&&___'. + $env{'user.domain'}.'___&&&___'.$comment; + } + + $Apache::lonratedt::resources[$newidx]= + $comment.':'.$url.':'.$ext.':normal:res'; + $Apache::lonratedt::order[$#Apache::lonratedt::order+1]= + $newidx; + ($errtext,$fatal)=&storemap($coursenum,$coursedom,$folder.'.'.$container); + if ($fatal) { + $$upload_output .= '

'.$errtext.'

'; + return 'failed'; + } else { + if ($parseaction eq 'parse') { + my $total_embedded = keys %{$allfiles}; + if ($total_embedded > 0) { + my $num = 0; + $$upload_output .= 'This file contains embedded multimedia objects, which need to be uploaded to LON-CAPA.
+
+ + + + '; + $$upload_output .= 'Upload embedded files:
+ '; + foreach my $embed_file (keys %{$allfiles}) { + $$upload_output .= ''; + $num ++; + } + $phase_status = 'phasetwo'; + $$upload_output .= '
'.$embed_file. + ' + '; + my $attrib; + if (@{$$allfiles{$embed_file}} > 1) { + $attrib = join(':',@{$$allfiles{$embed_file}}); + } else { + $attrib = $$allfiles{$embed_file}[0]; + } + $$upload_output .= + ''; + if (exists($$codebase{$embed_file})) { + $$upload_output .= + ''; + } + $$upload_output .= '

+ +
'; + } else { + $$upload_output .= 'No embedded items identified
'; + } + } + } + } + return $phase_status; +} + +sub process_secondary_uploads { + my ($upload_output,$coursedom,$coursenum,$formname,$num,$newidx) = @_; + my $folder=$env{'form.folder'}; + my $destination = 'docs/'; + if ($folder eq 'default') { + $destination .= 'default/'; + } elsif ($folder =~ /^default_(\d+)$/) { + $destination .= $1.'/'; + } + $destination .= $newidx; + my ($url,$filename); + $url=&Apache::lonnet::userfileupload($formname.$num,1,$destination); + ($filename) = ($url =~ m-^/uploaded/$coursedom/$coursenum/$destination/(.+)$-); + return $filename; +} + # --------------------------------------------------------------- An entry line sub entryline { - my ($index,$title,$url,$folder,$allowed,$residx)=@_; + my ($index,$title,$url,$folder,$allowed,$residx,$coursenum)=@_; $title=~s/\&colon\;/\:/g; $title=&HTML::Entities::encode(&HTML::Entities::decode( - &Apache::lonnet::unescape($title)),'\"\<\>\&\''); + &Apache::lonnet::unescape($title)),'"<>&\''); my $renametitle=$title; my $foldertitle=$title; - if ($title=~ - /^(\d+)\_\_\_\&\;\&\;\&\;\_\_\_(\w+)\_\_\_\&\;\&\;\&\;\_\_\_(\w+)\_\_\_\&\;\&\;\&\;\_\_\_(.*)$/ - ) { - $foldertitle=&Apache::lontexconvert::msgtexconverted($4); - $renametitle=$4; - $title=''.localtime($1).' '. - &Apache::loncommon::plainname($2,$3).':
'. - $foldertitle; - } + my $pagetitle=$title; + my $orderidx=$Apache::lonratedt::order[$index]; + if ($title=~ /^(\d+)___&&&___(\w+)___&&&___(\w+)___&&&___(.*)$/ ) { + $foldertitle=&Apache::lontexconvert::msgtexconverted($4); + $renametitle=$4; + $title=''.&Apache::lonlocal::locallocaltime($1).' '. + &Apache::loncommon::plainname($2,$3).':
'. + $foldertitle; + } $renametitle=~s/\"\;/\\\"/g; my $line=''; # Edit commands + my $container; + my $folderpath; + if ($env{'form.folderpath'}) { + $container = 'sequence'; + $folderpath=&Apache::lonnet::escape($env{'form.folderpath'}); + # $htmlfoldername=&HTML::Entities::encode($env{'form.foldername'},'<>&"'); + } + my ($pagepath,$pagesymb); + if ($env{'form.pagepath'}) { + $container = 'page'; + $pagepath=&Apache::lonnet::escape($env{'form.pagepath'}); + $pagesymb=&Apache::lonnet::escape($env{'form.pagesymb'}); + } + my $cpinfo=''; + if ($env{'form.markedcopy_url'}) { + $cpinfo='&markedcopy_url='. + &Apache::lonnet::escape($env{'form.markedcopy_url'}). + '&markedcopy_title='. + &Apache::lonnet::escape($env{'form.markedcopy_title'}); + } if ($allowed) { - $line.=(<0) && + ((split(/\:/, + $Apache::lonratedt::resources[$Apache::lonratedt::order[0]]))[1] + ne '') && + ((split(/\:/, + $Apache::lonratedt::resources[$Apache::lonratedt::order[1]]))[1] + ne '')) { + $selectbox= + ''. + ''; + } + my %lt=&Apache::lonlocal::texthash( + 'up' => 'Move Up', + 'dw' => 'Move Down', + 'rm' => 'Remove', + 'ct' => 'Cut', + 'rn' => 'Rename', + 'cp' => 'Copy'); + if ($env{'form.pagepath'}) { + $line.=(< + + + + + + +$lt{ -
- -UP
- -DOWN
- -Remove - -Rename + +$lt{ + +$selectbox + + +$lt{'rm'} + +$lt{'ct'} + +$lt{'rn'} + +$lt{'cp'} END + } else { + $line.=(< + + + + + + + +
+ +$lt{
+ +$lt{
+$selectbox + + +$lt{'rm'} + +$lt{'ct'} + +$lt{'rn'} + +$lt{'cp'} +END + } } # Figure out what kind of a resource this is my ($extension)=($url=~/\.(\w+)$/); my $uploaded=($url=~/^\/*uploaded\//); - my $icon='unknown'; - if (-e "/home/httpd/html/adm/lonIcons/$extension.gif") { - $icon=$extension; - } + my $icon=&Apache::loncommon::icon($url); my $isfolder=0; + my $ispage=0; + my $folderarg; + my $pagearg; + my $pagefile; if ($uploaded) { - if ($extension eq 'sequence') { - $icon='folder_closed'; - $url=~/\/(\w+)\.sequence/; - $url='/adm/coursedocs?folder='.$1; - $isfolder=1; - } else { - $url=&Apache::lonnet::tokenwrapper($url); - } + if ($extension eq 'sequence') { + $icon=$iconpath.'/folder_closed.gif'; + $url=~/$coursenum\/([\/\w]+)\.sequence$/; + $url='/adm/coursedocs?'; + $folderarg=$1; + $isfolder=1; + } elsif ($extension eq 'page') { + $icon=$iconpath.'/page.gif'; + $url=~/$coursenum\/([\/\w]+)\.page$/; + $pagearg=$1; + $url='/adm/coursedocs?'; + $ispage=1; + } else { + &Apache::lonnet::allowuploaded('/adm/coursedoc',$url); + } } $url=~s/^http\&colon\;\/\//\/adm\/wrapper\/ext\//; - if (($residx) && ($folder!~/supplemental/)) { - $url.=(($url=~/\?/)?'&':'?').'symb='. - &Apache::lonnet::escape(&Apache::lonnet::symbclean( + if ((!$isfolder) && ($residx) && ($folder!~/supplemental/) && (!$ispage)) { + my $symb=&Apache::lonnet::symbclean( &Apache::lonnet::declutter('uploaded/'. - $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}.'/'. - $ENV{'course.'.$ENV{'request.course.id'}.'.num'}.'/'.$folder. + $env{'course.'.$env{'request.course.id'}.'.domain'}.'/'. + $env{'course.'.$env{'request.course.id'}.'.num'}.'/'.$folder. '.sequence'). '___'.$residx.'___'. - &Apache::lonnet::declutter($url))); + &Apache::lonnet::declutter($url)); + (undef,undef,$url)=&Apache::lonnet::decode_symb($symb); + $url=&Apache::lonnet::clutter($url); + if ($url=~/^\/*uploaded\//) { + $url=~/\.(\w+)$/; + my $embstyle=&Apache::loncommon::fileembstyle($1); + if (($embstyle eq 'img') || ($embstyle eq 'emb')) { + $url='/adm/wrapper'.$url; + } elsif ($embstyle eq 'ssi') { + #do nothing with these + } elsif ($url!~/\.(sequence|page)$/) { + $url='/adm/coursedocs/showdoc'.$url; + } + } elsif ($url=~m|^/ext/|) { + $url='/adm/wrapper'.$url; + } + $url.=(($url=~/\?/)?'&':'?').'symb='.&Apache::lonnet::escape($symb); + if ($container eq 'page') { + my $symb=$env{'form.pagesymb'}; + + $url=&Apache::lonnet::clutter((&Apache::lonnet::decode_symb($symb))[2]); + $url.=(($url=~/\?/)?'&':'?').'symb='.&Apache::lonnet::escape($symb); + } + } + my $parameterset=' '; + if ($isfolder) { + my $foldername=&Apache::lonnet::escape($foldertitle); + my $folderpath=$env{'form.folderpath'}; + if ($folderpath) { $folderpath.='&' }; + $folderpath.=$folderarg.'&'.$foldername; + $url.='folderpath='.&Apache::lonnet::escape($folderpath).$cpinfo; + $parameterset=''; + + } + if ($ispage) { + my $pagename=&Apache::lonnet::escape($pagetitle); + my $pagepath; + my $folderpath=$env{'form.folderpath'}; + if ($folderpath) { $pagepath = $folderpath.'&' }; + $pagepath.=$pagearg.'&'.$pagename; + my $symb=$env{'form.pagesymb'}; + if (!$symb) { + my $path='uploaded/'. + $env{'course.'.$env{'request.course.id'}.'.domain'}.'/'. + $env{'course.'.$env{'request.course.id'}.'.num'}.'/'; + $symb=&Apache::lonnet::encode_symb($path.$folder.'.sequence', + $residx, + $path.$pagearg.'.page'); + } + $url.='pagepath='.&Apache::lonnet::escape($pagepath). + '&pagesymb='.&Apache::lonnet::escape($symb).$cpinfo; } - if ($isfolder) { $url.='&foldername='. - &Apache::lonnet::escape($foldertitle); } - $line.=''. - "$title"; + $line.=''. + "$title"; + if (($allowed) && ($folder!~/^supplemental/)) { + my %lt=&Apache::lonlocal::texthash( + 'hd' => 'Hidden', + 'ec' => 'URL hidden'); + my $enctext= + ((&Apache::lonratedt::getparameter($orderidx,'parameter_encrypturl'))[0]=~/^yes$/i?' checked="1"':''); + my $hidtext= + ((&Apache::lonratedt::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i?' checked="1"':''); + $line.=(< + + + +$parameterset +ENDPARMS + } + $line.=""; return $line; } # ---------------------------------------------------------------- tie the hash sub tiehash { + my ($mode)=@_; $hashtied=0; - if ($ENV{'request.course.fn'}) { - if (tie(%hash,'GDBM_File',$ENV{'request.course.fn'}.".db", - &GDBM_READER(),0640)) { + if ($env{'request.course.fn'}) { + if ($mode eq 'write') { + if (tie(%hash,'GDBM_File',$env{'request.course.fn'}.".db", + &GDBM_WRCREAT(),0640)) { + $hashtied=2; + } + } else { + if (tie(%hash,'GDBM_File',$env{'request.course.fn'}.".db", + &GDBM_READER(),0640)) { $hashtied=1; - } + } + } } } @@ -477,10 +1564,11 @@ sub untiehash { sub checkonthis { my ($r,$url,$level,$title)=@_; + $url=&Apache::lonnet::unescape($url); $alreadyseen{$url}=1; $r->rflush(); if (($url) && ($url!~/^\/uploaded\//) && ($url!~/\*$/)) { - $r->print('
'); + $r->print("\n
"); for (my $i=0;$i<=$level*5;$i++) { $r->print(' '); } @@ -489,8 +1577,8 @@ sub checkonthis { if ($url=~/^\/res\//) { my $result=&Apache::lonnet::repcopy( &Apache::lonnet::filelocation('',$url)); - if ($result==OK) { - $r->print('ok'); + if ($result eq 'ok') { + $r->print(''.&mt('ok').''); $r->rflush(); &Apache::lonnet::countacc($url); $url=~/\.(\w+)$/; @@ -500,25 +1588,25 @@ sub checkonthis { for (my $i=0;$i<=$level*5;$i++) { $r->print(' '); } - $r->print('- Rendering: '); - my $oldpath=$ENV{'request.filename'}; - $ENV{'request.filename'}=&Apache::lonnet::filelocation('',$url); - &Apache::lonxml::xmlparse($r,'web', - &Apache::lonnet::getfile( - &Apache::lonnet::filelocation('',$url))); - $ENV{'request.filename'}=$oldpath; - if (($Apache::lonxml::errorcount) || - ($Apache::lonxml::warningcount)) { - if ($Apache::lonxml::errorcount) { - $r->print(''. - $Apache::lonxml::errorcount.' error(s) '); + $r->print('- '.&mt('Rendering').': '); + my ($errorcount,$warningcount)=split(/:/, + &Apache::lonnet::ssi_body($url, + ('grade_target'=>'web', + 'return_only_error_and_warning_counts' => 1))); + if (($errorcount) || + ($warningcount)) { + if ($errorcount) { + $r->print(''. + $errorcount.' '. + &mt('error(s)').' '); } - if ($Apache::lonxml::warningcount) { + if ($warningcount) { $r->print(''. - $Apache::lonxml::warningcount.' warning(s)'); + $warningcount.' '. + &mt('warning(s)').'
'); } } else { - $r->print('ok'); + $r->print(''.&mt('ok').''); } $r->rflush(); } @@ -529,12 +1617,16 @@ sub checkonthis { &checkonthis($r,$_,$level+1); } } - } elsif ($result==HTTP_SERVICE_UNAVAILABLE) { - $r->print('connection down'); - } elsif ($result==HTTP_NOT_FOUND) { - $r->print('not found'); + } elsif ($result eq 'unavailable') { + $r->print(''.&mt('connection down').''); + } elsif ($result eq 'not_found') { + unless ($url=~/\$/) { + $r->print(''.&mt('not found').''); + } else { + $r->print(''.&mt('unable to verify variable URL').''); + } } else { - $r->print('access denied'); + $r->print(''.&mt('access denied').''); } } } @@ -548,133 +1640,339 @@ sub verifycontent { my $r=shift; my $loaderror=&Apache::lonnet::overloaderror($r); if ($loaderror) { return $loaderror; } - - $r->print('Verify Content'. + my $html=&Apache::lonxml::xmlbegin(); + $r->print($html.'Verify Content'. &Apache::loncommon::bodytag('Verify Course Documents')); $hashtied=0; undef %alreadyseen; %alreadyseen=(); &tiehash(); foreach (keys %hash) { - if (($_=~/^src\_(.+)$/) && (!$alreadyseen{$hash{$_}})) { + if ($hash{$_}=~/\.(page|sequence)$/) { + if (($_=~/^src_/) && ($alreadyseen{&Apache::lonnet::unescape($hash{$_})})) { + $r->print('
'. + &mt('The following sequence or page is included more than once in your course: '). + &Apache::lonnet::unescape($hash{$_}).'
'. + &mt('Note that grading records for problems included in this sequence or folder will overlap.
')); + } + } + if (($_=~/^src\_(.+)$/) && (!$alreadyseen{&Apache::lonnet::unescape($hash{$_})})) { &checkonthis($r,$hash{$_},0,$hash{'title_'.$1}); } } &untiehash(); - $r->print('

'.&mt('Done').'.

'); + $r->print('

'.&mt('Done').'.

'.''. + &mt('Return to DOCS').''); } # -------------------------------------------------------------- Check Versions sub checkversions { my $r=shift; - $r->print('Check Versions'. + my $html=&Apache::lonxml::xmlbegin(); + $r->print($html.'Check Versions'. &Apache::loncommon::bodytag('Check Course Document Versions')); - $hashtied=0; - &tiehash(); - my %changes=&Apache::lonnet::dump - ('versionupdate',$ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, - $ENV{'course.'.$ENV{'request.course.id'}.'.num'}); - my $firstkey=(keys %changes)[0]; - unless ($firstkey=~/^error\:/) { - unless ($ENV{'form.timerange'}) { - $ENV{'form.timerange'}=604800; - } - my $seltext='during the last '.$ENV{'form.timerange'}.' seconds'; - my $startsel=''; - my $monthsel=''; - my $weeksel=''; - my $daysel=''; - if ($ENV{'form.timerange'}==-1) { - $seltext='since start of course'; - $startsel='selected'; - $ENV{'form.timerange'}=time; - } - my $starttime=time-$ENV{'form.timerange'}; - if ($ENV{'form.timerange'}==2592000) { - $seltext='during the last month ('.localtime($starttime).')'; - $monthsel='selected'; - } elsif ($ENV{'form.timerange'}==604800) { - $seltext='during the last week ('.localtime($starttime).')'; - $weeksel='selected'; - } elsif ($ENV{'form.timerange'}==86400) { - $seltext='since yesterday ('.localtime($starttime).')'; - $daysel='selected'; - } + my $header=''; + my $startsel=''; + my $monthsel=''; + my $weeksel=''; + my $daysel=''; + my $allsel=''; + my %changes=(); + my $starttime=0; + my $haschanged=0; + my %setversions=&Apache::lonnet::dump('resourceversions', + $env{'course.'.$env{'request.course.id'}.'.domain'}, + $env{'course.'.$env{'request.course.id'}.'.num'}); - $r->print(<0) { + $newsetversions{$1}=$getvers; + } + } + } + } elsif ($env{'form.setversions'}) { + $haschanged=1; + foreach (keys %env) { + if ($_=~/^form\.set_version_(.+)$/) { + my $src=$1; + if (($env{$_}) && ($env{$_} ne $setversions{$src})) { + $newsetversions{$src}=$env{$_}; + } + } + } + } + if ($haschanged) { + if (&Apache::lonnet::put('resourceversions',\%newsetversions, + $env{'course.'.$env{'request.course.id'}.'.domain'}, + $env{'course.'.$env{'request.course.id'}.'.num'}) eq 'ok') { + $r->print('

'.&mt('Your Version Settings have been Stored').'

'); + } else { + $r->print('

'.&mt('An Error Occured while Attempting to Store your Version Settings').'

'); + } + &mark_hash_old(); + } + &changewarning($r,''); + if ($env{'form.timerange'} eq 'all') { +# show all documents + $header=&mt('All Documents in Course'); + $allsel=1; + foreach (keys %hash) { + if ($_=~/^ids\_(\/res\/.+)$/) { + my $src=$1; + $changes{$src}=1; + } + } + } else { +# show documents which changed + %changes=&Apache::lonnet::dump + ('versionupdate',$env{'course.'.$env{'request.course.id'}.'.domain'}, + $env{'course.'.$env{'request.course.id'}.'.num'}); + my $firstkey=(keys %changes)[0]; + unless ($firstkey=~/^error\:/) { + unless ($env{'form.timerange'}) { + $env{'form.timerange'}=604800; + } + my $seltext=&mt('during the last').' '.$env{'form.timerange'}.' ' + .&mt('seconds'); + if ($env{'form.timerange'}==-1) { + $seltext='since start of course'; + $startsel='selected'; + $env{'form.timerange'}=time; + } + $starttime=time-$env{'form.timerange'}; + if ($env{'form.timerange'}==2592000) { + $seltext=&mt('during the last month').' ('.&Apache::lonlocal::locallocaltime($starttime).')'; + $monthsel='selected'; + } elsif ($env{'form.timerange'}==604800) { + $seltext=&mt('during the last week').' ('.&Apache::lonlocal::locallocaltime($starttime).')'; + $weeksel='selected'; + } elsif ($env{'form.timerange'}==86400) { + $seltext=&mt('since yesterday').' ('.&Apache::lonlocal::locallocaltime($starttime).')'; + $daysel='selected'; + } + $header=&mt('Content changed').' '.$seltext; + } else { + $header=&mt('No content modifications yet.'); + } + } + %setversions=&Apache::lonnet::dump('resourceversions', + $env{'course.'.$env{'request.course.id'}.'.domain'}, + $env{'course.'.$env{'request.course.id'}.'.num'}); + my %lt=&Apache::lonlocal::texthash + ('st' => 'Version changes since start of Course', + 'lm' => 'Version changes since last Month', + 'lw' => 'Version changes since last Week', + 'sy' => 'Version changes since Yesterday', + 'al' => 'All Resources (possibly large output)', + 'sd' => 'Display', + 'fi' => 'File', + 'md' => 'Modification Date', + 'mr' => 'Most recently published Version', + 've' => 'Version used in Course', + 'vu' => 'Set Version to be used in Course', +'sv' => 'Set Versions to be used in Course according to Selections below', +'sm' => 'Keep all Resources up-to-date with most recent Versions (default)', +'sc' => 'Set all Resource Versions to current Version (Fix Versions)', + 'di' => 'Differences'); + $r->print(< + + +
- - -

Content changed $seltext

- - - - + +

$header

+ +
FileModification DateVersionDifferences
ENDHEADERS - foreach (keys %changes) { - if ($changes{$_}>$starttime) { - my ($root,$extension)=($_=~/^(.*)\.(\w+)$/); - my $currentversion=&Apache::lonnet::getversion($_); - my $linkurl=&Apache::lonnet::clutter($_); - $r->print( - ''. - ''. + ''. + ''. + ''. + ''. + ''. + ''); + my $lastold=1; + for (my $prevvers=1;$prevvers<$currentversion;$prevvers++) { + my $url=$root.'.'.$prevvers.'.'.$extension; + if (&Apache::lonnet::metadata($url,'lastrevisiondate')< + $starttime) { + $lastold=$prevvers; + } + } + # + # Code to figure out how many version entries should go in + # each of the four columns + my $entries_per_col = 0; + my $num_entries = ($currentversion-$lastold); + if ($num_entries % 4 == 0) { + $entries_per_col = $num_entries/4; + } else { + $entries_per_col = $num_entries/4 + 1; + } + my $entries_count = 0; + $r->print(''); - } - } - $r->print('
'.$linkurl. - ''. - localtime($changes{$_}).''.$currentversion.''); - my $lastold=1; - for (my $prevvers=1;$prevvers<$currentversion;$prevvers++) { - my $url=$root.'.'.$prevvers.'.'.$extension; - if (&Apache::lonnet::metadata($url,'lastrevisiondate')< - $starttime) { - $lastold=$prevvers; - } - } + foreach (sort keys %changes) { + if ($changes{$_}>$starttime) { + my ($root,$extension)=($_=~/^(.*)\.(\w+)$/); + my $currentversion=&Apache::lonnet::getversion($_); + if ($currentversion<0) { + $currentversion=&mt('Could not be determined.'); + } + my $linkurl=&Apache::lonnet::clutter($_); + $r->print( + '


'. + &Apache::lonnet::gettitle($linkurl). + '
   '. + ''.$linkurl. + '
'. + &Apache::lonlocal::locallocaltime( + &Apache::lonnet::metadata($root.'.'.$extension, + 'lastrevisiondate') + ). + 'Most Recent: '. + ''.$currentversion.''. + 'In Course: '. + ''); +# Used in course + my $usedversion=$hash{'version_'.$linkurl}; + if (($usedversion) && ($usedversion ne 'mostrecent')) { + $r->print($usedversion); + } else { + $r->print($currentversion); + } + $r->print(''. + 'Use: '); +# Set version + $r->print(&Apache::loncommon::select_form($setversions{$linkurl}, + 'set_version_'.$linkurl, + ('select_form_order' => + ['',1..$currentversion,'mostrecent'], + '' => '', + 'mostrecent' => 'most recent', + map {$_,$_} (1..$currentversion)))); + $r->print('
'); + my $cols_output = 1; for (my $prevvers=$lastold;$prevvers<$currentversion;$prevvers++) { - my $url=$root.'.'.$prevvers.'.'.$extension; - $r->print('Version '.$prevvers.' ('. - localtime(&Apache::lonnet::metadata($url,'lastrevisiondate')). - ')'); - if (&Apache::loncommon::fileembstyle($extension) eq 'ssi') { + my $url=$root.'.'.$prevvers.'.'.$extension; + $r->print(''.&mt('Version').' '.$prevvers.' ('. + &Apache::lonlocal::locallocaltime( + &Apache::lonnet::metadata($url, + 'lastrevisiondate') + ). + ')'); + if (&Apache::loncommon::fileembstyle($extension) eq 'ssi') { $r->print(' Diffs'); - } - $r->print('
'); - } - $r->print('
'); - $r->print('

'.&mt('Done').'.

'); - } else { - $r->print('

'.&mt('No content modifications yet.').'

'); - } - &untiehash(); + &Apache::lonnet::clutter($root.'.'.$extension). + '&versionone='.$prevvers. + '">'.&mt('Diffs').''); + } + $r->print('
'); + if (++$entries_count % $entries_per_col == 0) { + $r->print('
'); + if ($cols_output != 4) { + $r->print(''); + $cols_output++; + } + } + } + while($cols_output++ < 4) { + $r->print('') + } + $r->print(''."\n"); + } + } + $r->print(''); + $r->print('

'.&mt('Done').'.

'); + + &untiehash(); +} + +sub mark_hash_old { + my $retie_hash=0; + if ($hashtied) { + $retie_hash=1; + &untiehash(); + } + &tiehash('write'); + $hash{'old'}=1; + &untiehash(); + if ($retie_hash) { &tiehash(); } +} + +sub is_hash_old { + my $untie_hash=0; + if (!$hashtied) { + $untie_hash=1; + &tiehash(); + } + my $return=$hash{'old'}; + if ($untie_hash) { &untiehash(); } + return $return; +} + +sub changewarning { + my ($r,$postexec,$message,$url)=@_; + if (!&is_hash_old()) { return; } + my $pathvar='folderpath'; + my $path=&Apache::lonnet::escape($env{'form.folderpath'}); + if (!defined($url)) { + if (defined($env{'form.pagepath'})) { + $pathvar='pagepath'; + $path=&Apache::lonnet::escape($env{'form.pagepath'}); + $path.='&symb='.&Apache::lonnet::escape($env{'form.pagesymb'}); + } + $url='/adm/coursedocs?'.$pathvar.'='.$path; + } + if (!defined($message)) { + $message='Changes will become active for your current session after [_1], or the next time you log in.'; + } + $r->print("\n\n". +''."\n". +'
'. +'

'. +&mt($message,' '). +$help{'Caching'}.'

'."\n\n"); } # ================================================================ Main Handler sub handler { my $r = shift; - $r->content_type('text/html'); + &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; return OK if $r->header_only; - &Apache::lonlocal::clearreroutetrans(); # --------------------------------------------- Initialize help topics for this foreach ('Adding_Course_Doc','Main_Course_Documents', 'Adding_External_Resource','Navigate_Content', 'Adding_Folders','Docs_Overview', 'Load_Map', - 'Supplemental', 'Score_Upload_Form', - 'Importing_LON-CAPA_Resource','Uploading_From_Harddrive') { + 'Supplemental','Score_Upload_Form','Adding_Pages', + 'Importing_LON-CAPA_Resource','Uploading_From_Harddrive', + 'Check_Resource_Versions','Verify_Content') { $help{$_}=&Apache::loncommon::help_open_topic('Docs_'.$_); } # Composite help files @@ -682,39 +1980,62 @@ sub handler { 'Docs_About_Syllabus,Docs_Editing_Templated_Pages'); $help{'Simple Page'} = &Apache::loncommon::help_open_topic( 'Docs_About_Simple_Page,Docs_Editing_Templated_Pages'); + $help{'Simple Problem'} = &Apache::loncommon::help_open_topic( + 'Option_Response_Simple'); $help{'Bulletin Board'} = &Apache::loncommon::help_open_topic( 'Docs_About_Bulletin_Board,Docs_Editing_Templated_Pages'); $help{'My Personal Info'} = &Apache::loncommon::help_open_topic( 'Docs_About_My_Personal_Info,Docs_Editing_Templated_Pages'); $help{'Caching'} = &Apache::loncommon::help_open_topic('Caching'); - - if ($ENV{'form.verify'}) { + + if ($env{'form.verify'}) { &verifycontent($r); - } elsif ($ENV{'form.versions'}) { + } elsif ($env{'form.versions'}) { &checkversions($r); - } elsif ($ENV{'form.dumpcourse'}) { + } elsif ($env{'form.dumpcourse'}) { &dumpcourse($r); + } elsif ($env{'form.exportcourse'}) { + &exportcourse($r); } else { # is this a standard course? - my $standard=($ENV{'request.course.uri'}=~/^\/uploaded\//); - my $forcestandard; + my $standard=($env{'request.course.uri'}=~/^\/uploaded\//); + my $forcestandard = 0; my $forcesupplement; my $script=''; my $allowed; my $events=''; my $showdoc=0; + my $containertag; + my $uploadtag; &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, - ['folder','foldername']); + ['folderpath','pagepath','pagesymb','markedcopy_url','markedcopy_title']); + if ($env{'form.folderpath'}) { + my (@folderpath)=split('&',$env{'form.folderpath'}); + $env{'form.foldername'}=&Apache::lonnet::unescape(pop(@folderpath)); + $env{'form.folder'}=pop(@folderpath); + } + if ($env{'form.pagepath'}) { + my (@pagepath)=split('&',$env{'form.pagepath'}); + $env{'form.pagename'}=&Apache::lonnet::unescape(pop(@pagepath)); + $env{'form.folder'}=pop(@pagepath); + $containertag = ''. + ''; + $uploadtag = ''. + ''; + } if ($r->uri=~/^\/adm\/coursedocs\/showdoc\/(.*)$/) { - $showdoc=$1; + $showdoc='/'.$1; } unless ($showdoc) { # got called from remote - $forcestandard=($ENV{'form.folder'}=~/^default_/); - $forcesupplement=($ENV{'form.folder'}=~/^supplemental_/); + if (($env{'form.folder'}=~/^default_/) || + ($env{'form.folder'} =~ m#^\d+/(pages|sequences)/#)) { + $forcestandard = 1; + } + $forcesupplement=($env{'form.folder'}=~/^supplemental_/); # does this user have privileges to post, etc? - $allowed=&Apache::lonnet::allowed('mdc',$ENV{'request.course.id'}); + $allowed=&Apache::lonnet::allowed('mdc',$env{'request.course.id'}); if ($allowed) { &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['cmd']); $script=&Apache::lonratedt::editscript('simple'); @@ -727,25 +2048,26 @@ sub handler { } # get course data - my $coursenum=$ENV{'course.'.$ENV{'request.course.id'}.'.num'}; - my $coursedom=$ENV{'course.'.$ENV{'request.course.id'}.'.domain'}; + my $coursenum=$env{'course.'.$env{'request.course.id'}.'.num'}; + my $coursedom=$env{'course.'.$env{'request.course.id'}.'.domain'}; # get personal data - my $uname=$ENV{'user.name'}; - my $udom=$ENV{'user.domain'}; + my $uname=$env{'user.name'}; + my $udom=$env{'user.domain'}; my $plainname=&Apache::lonnet::escape( &Apache::loncommon::plainname($uname,$udom)); # graphics settings - $iconpath = $r->dir_config('lonIconsURL') . "/"; + $iconpath = &Apache::loncommon::lonhttpdurl($r->dir_config('lonIconsURL') . "/"); my $now=time; # print screen + my $html=&Apache::lonxml::xmlbegin(); $r->print(< +$html The LearningOnline Network with CAPA ENDNEWSCRIPT @@ -837,20 +2234,106 @@ ENDNEWSCRIPT # -------------------------------------------------------------------- Body tag $r->print(''. &Apache::loncommon::bodytag('Course Documents','',$events, - '','',$showdoc)); - unless ($showdoc) { + '','',$showdoc). + &Apache::loncommon::help_open_menu('','','','',273,'RAT')); + my %allfiles = (); + my %codebase = (); + my ($upload_result,$upload_output); + if ($allowed) { + if (($env{'form.uploaddoc.filename'}) && ($env{'form.cmd'}=~/^upload_(\w+)/)) { +# Process file upload - phase one - upload and parse primary file. + $upload_result = &process_file_upload(\$upload_output,$coursenum,$coursedom,\%allfiles,\%codebase); + if ($upload_result eq 'phasetwo') { + $r->print($upload_output); + } + } elsif ($env{'form.phasetwo'}) { + my %newname = (); + my %origname = (); + my %attribs = (); + my $updateflag = 0; + my $residx = $env{'form.newidx'}; + my $primary_url = &Apache::lonnet::unescape($env{'form.primaryurl'}); +# Process file upload - phase two - gather secondary files. + for (my $i=0; $i<$env{'form.phasetwo'}; $i++) { + if ($env{'form.embedded_item_'.$i.'.filename'}) { + my $javacodebase; + $newname{$i} = &process_secondary_uploads(\$upload_output,$coursedom,$coursenum,'embedded_item_',$i,$residx); + $origname{$i} = &Apache::lonnet::unescape($env{'form.embedded_orig_'.$i}); + if (exists($env{'form.embedded_codebase_'.$i})) { + $javacodebase = &Apache::lonnet::unescape($env{'form.embedded_codebase_'.$i}); + $origname{$i} =~ s#^\Q$javacodebase\E/##; + } + my @attributes = (); + if ($env{'form.embedded_attrib_'.$i} =~ /:/) { + @attributes = split/:/,$env{'form.embedded_attrib_'.$i}; + } else { + @attributes = ($env{'form.embedded_attrib_'.$i}); + } + foreach (@attributes) { + push(@{$attribs{$i}},&Apache::lonnet::unescape($_)); + } + if ($javacodebase) { + $codebase{$i} = $javacodebase; + $codebase{$i} =~ s#/$##; + $updateflag = 1; + } + } + unless ($newname{$i} eq $origname{$i}) { + $updateflag = 1; + } + } +# Process file upload - phase three - modify primary file + if ($updateflag) { + my ($content,$rtncode); + my $updateflag = 0; + my $getstatus = &Apache::lonnet::getuploaded('GET',$primary_url,$coursedom,$coursenum,\$content,\$rtncode); + if ($getstatus eq 'ok') { + foreach my $item (keys %newname) { + if ($newname{$item} ne $origname{$item}) { + my $attrib_regexp = ''; + if (@{$attribs{$item}} > 1) { + $attrib_regexp = join('|',@{$attribs{$item}}); + } else { + $attrib_regexp = $attribs{$item}[0]; + } + if ($content =~ m#($attrib_regexp\s*=\s*['"]?)\Q$origname{$item}\E(['"]?)#) { + } + $content =~ s#($attrib_regexp\s*=\s*['"]?)\Q$origname{$item}\E(['"]?)#$1$newname{$item}$2#gi; + } + if (exists($codebase{$item})) { + $content =~ s/(codebase\s*=\s*["']?)\Q$codebase{$item}\E(["']?)/$1.$2/i; + } + } +# Save edited file. + my $saveresult; + my $docuname=$env{'course.'.$env{'request.course.id'}.'.num'}; + my $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'}; + my $docuhome=$env{'course.'.$env{'request.course.id'}.'.home'}; + my $url = &Apache::lonnet::store_edited_file($primary_url,$content,$docudom,$docuname,$docuhome,\$saveresult); + } else { + &Apache::lonnet::logthis('retrieval of uploaded file - '.$primary_url.' - for editing, failed: '.$getstatus); + } + } + } + } + + unless ($showdoc || $upload_result eq 'phasetwo') { # ----------------------------------------------------------------------------- my %lt=&Apache::lonlocal::texthash( 'uplm' => 'Upload a new main course document', 'upls' => 'Upload a new supplemental course document', - 'impp' => 'Import a published document', + 'impp' => 'Import a document', + 'pubd' => 'Published documents', + 'copm' => 'All documents out of a published map into this folder', 'spec' => 'Special documents', 'upld' => 'Upload Document', 'srch' => 'Search', 'impo' => 'Import', 'selm' => 'Select Map', 'load' => 'Load Map', + 'reco' => 'Recover Deleted Resources', 'newf' => 'New Folder', + 'newp' => 'New Composite Page', 'extr' => 'External Resource', 'syll' => 'Syllabus', 'navc' => 'Navigate Contents', @@ -858,62 +2341,93 @@ ENDNEWSCRIPT 'sipr' => 'Simple Problem', 'scuf' => 'Score Upload Form', 'bull' => 'Bulletin Board', - 'mypi' => 'My Personal Info' + 'mypi' => 'My Personal Info', + 'abou' => 'About User', + 'imsf' => 'Import IMS package', + 'file' => 'File', + 'title' => 'Title', + 'comment' => 'Comment', + 'parse' => 'If HTML file, upload embedded images/multimedia files' ); # ----------------------------------------------------------------------------- if ($allowed) { my $dumpbut=&dumpbutton(); + my $exportbut=&exportbutton(); + my %lt=&Apache::lonlocal::texthash( + 'vc' => 'Verify Content', + 'cv' => 'Check/Set Resource Versions', + ); + + my $folderpath=$env{'form.folderpath'}; + if (!$folderpath) { + if ($env{'form.folder'} eq '' || + $env{'form.folder'} eq 'supplemental') { + $folderpath='default&'. + &Apache::lonnet::escape(&mt('Main Course Documents')); + } + } + unless ($env{'form.pagepath'}) { + $containertag = ''; + $uploadtag = ''; + } + $r->print(< - + +$containertag
- +$uploadtag
- +$help{'Verify_Content'} - + $help{'Check_Resource_Versions'} $dumpbut +$exportbut
ENDCOURSEVERIFY $r->print(&Apache::loncommon::help_open_topic('Docs_Adding_Course_Doc', - 'Editing the Table of Contents for your Course')); + &mt('Editing the Table of Contents for your Course'))); } # --------------------------------------------------------- Standard documents $r->print(''); if (($standard) && ($allowed) && (!$forcesupplement)) { - $r->print(' @@ -921,45 +2435,74 @@ $help{'Caching'}.''); -

'.&mt('Main Course Documents'). - ($allowed?' '.$help{'Main_Course_Documents'}:'').'

'); - my $folder=$ENV{'form.folder'}; - unless ($folder=~/^default/) { $folder='default'; } + $r->print('
'); +# '

'.&mt('Main Course Documents'). +# ($allowed?' '.$help{'Main_Course_Documents'}:'').'

'); + my $folder=$env{'form.folder'}; + if ($folder eq '' || $folder eq 'supplemental') { + $folder='default'; + $env{'form.folderpath'}='default&'.&Apache::lonnet::escape(&mt('Main Course Documents')); + } my $postexec=''; if ($folder eq 'default') { $r->print(''); } else { - $postexec='self.close();'; + #$postexec='self.close();'; } $hadchanges=0; - &editor($r,$coursenum,$coursedom,$folder,$allowed); + &editor($r,$coursenum,$coursedom,$folder,$allowed,$upload_output); if ($hadchanges) { - $r->print( -''. -'
'. -'

'. -&mt('Changes will become active for your current session after'). -' '.&mt(', or the next time you log in.'). -$help{'Caching'}.'

'); + &mark_hash_old() } + &changewarning($r,$postexec); my $folderseq='/uploaded/'.$coursedom.'/'.$coursenum.'/default_'.time. '.sequence'; + my $pageseq = '/uploaded/'.$coursedom.'/'.$coursenum.'/default_'.time. + '.page'; + my $container='sequence'; + if ($env{'form.pagepath'}) { + $container='page'; + } + my $readfile='/uploaded/'.$coursedom.'/'.$coursenum.'/'.$folder.'.'.$container; $r->print(<
$lt{'uplm'}$lt{'spec'}
-File:
-
+$lt{'file'}:
+
-Title:
+$lt{'title'}:
- - +$uploadtag - +
+ +$lt{'parse'}? + + +
+
+ $help{'Uploading_From_Harddrive'}
- - - +$lt{'pubd'}
+$uploadtag + - + $help{'Importing_LON-CAPA_Resource'}


-
+$lt{'copm'}
+
$help{'Load_Map'}

-
+
+
+ +
+ENDFORM + unless ($env{'form.pagepath'}) { + $r->print(< +
+$uploadtag + + + $help{'Adding_External_Resource'} + +
+
+ + + +
+ENDFORM + } + $r->print('
'); + unless ($env{'form.pagepath'}) { + $r->print(< - - + $help{'Adding_Folders'} -
- - + + - $help{'Adding_External_Resource'} +$help{'Adding_Pages'}
- - +$uploadtag @@ -987,8 +2529,7 @@ value="Syllabus=/public/$coursedom/$cour
- - +$uploadtag @@ -997,8 +2538,7 @@ $help{'Navigate_Content'}
- - +$uploadtag $
- - +$uploadtag
- - +$uploadtag
- - +$uploadtag
- - +$uploadtag @@ -1044,18 +2580,55 @@ value="$plainname=/adm/$udom/$uname/abou $help{'My Personal Info'}
-
+
+$uploadtag + + + + +
ENDFORM + } + if ($env{'form.pagepath'}) { + $r->print(< +$uploadtag + + +$help{'Simple Problem'} + + +
+$uploadtag + + + +$help{'Score_Upload_Form'} + +
+ENDBLOCK + } + $r->print(''."\n". +''); $r->print(''); } # ----------------------------------------------------- Supplemental documents if (!$forcestandard) { - $r->print( - '

'.&mt('Supplemental Course Documents'). - ($allowed?' '.$help{'Supplemental'}:'').'

'); - my $folder=$ENV{'form.folder'}; - unless ($folder=~/supplemental/) { $folder='supplemental'; } + $r->print(''); +# '

'.&mt('Supplemental Course Documents'). +# ($allowed?' '.$help{'Supplemental'}:'').'

'); + my $folder=$env{'form.folder'}; + unless ($folder=~/^supplemental/) { + $folder='supplemental'; + } + if ($folder =~ /^supplemental$/ && + $env{'form.folderpath'} =~ /^default\&/) { + $env{'form.folderpath'}='supplemental&'. + &Apache::lonnet::escape(&mt('Supplemental Course Documents')); + } &editor($r,$coursenum,$coursedom,$folder,$allowed); if ($allowed) { my $folderseq= @@ -1065,17 +2638,16 @@ ENDFORM $r->print(< $lt{'upls'} -$lt{'impp'} $lt{'spec'}
-
Comment:
+
$lt{'comment'}:
- - +
+ @@ -1084,26 +2656,8 @@ ENDFORM -
- - - - -$help{'Importing_LON-CAPA_Resource'} -

-


- - -

-
-
- - + $help{'Adding_Fol
- - + $help{'Adding_Ext
- - + @@ -1132,8 +2684,7 @@ $help{'Syllabus'}
- - + @@ -1147,17 +2698,20 @@ ENDSUPFORM } } if ($allowed) { - $r->print(''); + $r->print('
'); } $r->print(''); } else { + unless ($upload_result eq 'phasetwo') { # -------------------------------------------------------- This is showdoc mode - $r->print("

".&mt('Uploaded Document').'

'. + $r->print("

".&mt('Uploaded Document').' - '. + &Apache::lonnet::gettitle($r->uri).'

'. &mt('It is recommended that you use an up-to-date virus scanner before handling this file.')."

". - &entryline(0,&mt("Click to download or use your browser's Save Link function"),$showdoc).'

'); + &entryline(0,&mt("Click to download or use your browser's Save Link function"),$showdoc).'

'); + } } } - $r->print(&Apache::lonlocal::endreroutetrans().''); + $r->print(''); return OK; } 500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.