--- loncom/interface/londocs.pm 2012/01/03 01:54:39 1.474
+++ loncom/interface/londocs.pm 2012/04/05 15:22:39 1.480
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Documents
#
-# $Id: londocs.pm,v 1.474 2012/01/03 01:54:39 raeburn Exp $
+# $Id: londocs.pm,v 1.480 2012/04/05 15:22:39 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -26,8 +26,6 @@
# http://www.lon-capa.org/
#
-
-
package Apache::londocs;
use strict;
@@ -265,809 +263,12 @@ sub dumpcourse {
}
}
-
-
sub exportbutton {
my $crstype = &Apache::loncommon::course_type();
return "".
&Apache::loncommon::help_open_topic('Docs_Export_Course_Docs').' ';
}
-
-
-sub exportcourse {
- my $r=shift;
- my $crstype = &Apache::loncommon::course_type();
- 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 $numprobs = 0;
- my $navmap = Apache::lonnavmaps::navmap->new();
- if (!defined($navmap)) {
- $r->print(&Apache::loncommon::start_page('Export '.$crstype.' to IMS Package').
- '
'.&mt('IMS Export Failed').' '.
- '');
- if ($crstype eq 'Community') {
- $r->print(&mt('Unable to retrieve information about community contents'));
- } else {
- $r->print(&mt('Unable to retrieve information about course contents'));
- }
- $r->print('
');
- if ($crstype eq 'Community') {
- $r->print(&mt('Return to Community Editor'));
- } else {
- $r->print(&mt('Return to Course Editor'));
- }
- $r->print(' ');
- &Apache::lonnet::logthis('IMS export failed - could not create navmap object in '.lc($crstype).':'.$env{'request.course.id'});
- return;
- }
- 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 $format = $env{'form.format'};
- my @exportitems = &Apache::loncommon::get_env_multiple('form.archive');
- my @discussions = &Apache::loncommon::get_env_multiple('form.discussion');
- if (@exportitems == 0 && @discussions == 0) {
- $outcome =
- ''
- .&mt('As you did not select any content items or discussions'
- .' for export, an IMS package has not been created.')
- .'
'
- .''
- .&mt('Please [_1]go back[_2] 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 $testbank;
- my $ims_manifest = &create_ims_store($now,\$manifestok,\$outcome,\$tempexport,$format,\$testbank);
- if ($manifestok) {
- &build_package($now,$navmap,\@exportitems,\@discussions,\$outcome,$tempexport,\$copyresult,$ims_manifest,$format,$testbank);
- 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 .= ''
- .&mt('[_1]Your IMS package[_2] is ready for download.'
- ,'',' ')
- .'
';
- if ($copyresult) {
- $outcome .= ''
- .&mt('The following errors occurred during export - [_1]'
- ,$copyresult)
- .'
';
- }
- } else {
- $outcome = ''
- .&mt('Unfortunately you will not be able to retrieve'
- .' an IMS archive of your course at this time,'
- .' because there was a problem creating a'
- .' manifest file.')
- .'
'
- .''
- .&mt('Go Back')
- .'
';
- }
- }
- $r->print(&Apache::loncommon::start_page('Export '.$crstype.' to IMS Package'));
- $r->print(&Apache::lonhtmlcommon::breadcrumbs('IMS Export'));
- $r->print($outcome);
- $r->print(&Apache::loncommon::end_page());
- } else {
- my $display='');
- }
-}
-
-sub create_ims_store {
- my ($now,$manifestok,$outcome,$tempexport,$format,$testbank) = @_;
- $$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".
-'
-
-
-
- '.$env{'request.course.id'}.'
-
- '.$env{'course.'.$env{'request.course.id'}.'.description'}.'
-
-
-
- '."\n".
-' '."\n".
-' '."\n".
-' '.$env{'course.'.$env{'request.course.id'}.'.description'}.' ';
- if ($format eq 'plaintext') {
- my $testbankfilename = $$tempexport.'/testbank.txt';
- $$testbank = Apache::File->new('>'.$testbankfilename);
- }
- } 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,$format,$testbank) = @_;
-# 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 $currdirpath = 'Top';
- 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.'"';
- }
- my $step = $prevdepth - $depth;
- if (($step >= 0) && ($count > 1)) {
- while ($step >= 0) {
- print $ims_manifest "\n".' '."\n";
- $step --;
- }
- }
- $prevdepth = $depth;
-
- my $itementry =
- '- '.
- '
'.$curRes->title().' ';
- print $ims_manifest "\n".$itementry;
-
- if ($curRes->is_sequence()) {
- $currdirpath = 'Top';
- my $pcslist = $curRes->map_hierarchy();
- if ($pcslist ne '') {
- foreach my $pc (split(/,/,$pcslist),$curRes->map_pc()) {
- next if ($pc <= 1);
- my $res = $navmap->getByMapPc($pc);
- if (ref($res)) {
- my $encloser = $res->title();
- if ($encloser) {
- if ($currdirpath) {
- $currdirpath .= ' -> ';
- }
- $currdirpath .= $encloser;
- }
- }
- }
- }
- } else {
- my $content_file;
- my @hrefs = ();
- &process_content($count,$curRes,$cdom,$cnum,$symb,\$content_file,\@hrefs,$copyresult,$tempexport,$format,$currdirpath,$testbank);
- if ($content_file) {
- $imsresources .= "\n".
- ' '."\n".
- ' '."\n";
- foreach my $item (@hrefs) {
- $imsresources .=
- ' '."\n";
- }
- if (grep(/^$count$/,@$discussions)) {
- my $ressymb = $symb;
- my $mode;
- if ($ressymb =~ m|adm/($match_domain)/($match_username)/(\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;
- }
- }
- }
- 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,$format,$currdirpath,$testbank) = @_;
- my $content_type;
- my $message;
- 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/($match_domain)/($match_username)/(\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;
- }
-# only include problem code where current user is author
- if (($format eq 'html') || ($format eq 'plaintext')) {
- my $title = $curRes->title;
- $$content_file = &replicate_content($cdom,$cnum,$tempexport,$symb,$count,\$message,$href,$format,$currdirpath,$title,$testbank);
- } elsif ($format eq 'xml') {
- 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,$currdirpath,
- $title,$testbank) = @_;
- 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') {
- my $respath = $Apache::lonnet::perlvar{'lonDocRoot'}.'/res';
- my $filepath = &Apache::lonnet::filelocation($respath,$url);
- $content = &Apache::lonnet::getfile($filepath);
- if ($content eq -1) {
- $$message = 'Could not copy file '.$filename;
- } else {
- &extract_media($url,$cdom,$cnum,\$content,$count,$tempexport,$href,$message,'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($url,$cdom,$cnum,\$content,$count,$tempexport,$href,$message,'uploaded');
- }
- } else {
- $$message = 'Could not render '.$url.' server message - '.$rtncode." \n";
- }
- } elsif (($caller eq 'noedit') || ($caller eq 'html') ||
- ($caller eq 'plaintext')) {
-# Need to render the resource without the LON-CAPA Internal header and the Post discussion footer, and then set $content equal to this.
- my %form = (
- grade_symb => $symb,
- grade_courseid => $cdom.'_'.$cnum,
- grade_domain => $env{'user.domain'},
- grade_username => $env{'user.name'},
- grade_imsexport => 1,
- instructor_comments => 'hide',
- );
- my $feedurl=&Apache::lonnet::clutter($url);
- my ($userview,$response)=&Apache::lonnet::ssi_body($feedurl,%form);
- if (ref($response)) {
- if ($response->is_success) {
- $content = $userview;
- $content =~ s/\Qonchange="javascript:setSubmittedPart('\E[^\']+\Q');"\E//g;
- $content =~ s/^\s*[\n\r]+$//;
- if ($caller eq 'plaintext') {
- my @lines = split(/[\n\r]+/,$content);
- my @tosave;
- my $foilcounter = 0;
- my @alphabet = ('a'..'z');
- my $mc_answer;
- foreach my $line (@lines) {
- next if ($line =~ /^\s*$/);
- if ($line =~ m{(|\Q<\label>\E)\Q Incorrect:\E}) {
- $foilcounter ++;
- } elsif ($line =~ m{(|\Q \E)\Q Correct:\E}) {
- $foilcounter ++;
- $mc_answer = $alphabet[$foilcounter-1];
- } elsif ($line !~ m{\Q \E(|\Q \E)\Q \E}) {
- $line =~ s/^(\s+|\s+)$//g;
- $line =~ s{^\Q\E([^<]+)\Q \E$}{1};
- $tosave[$foilcounter] .= $line.' ';
- }
- $content = join("\t",@tosave);
- if ($mc_answer) {
- $content .= "\t".$mc_answer."\n";
- }
- }
- if (@tosave) {
- my $qtype;
- if ($mc_answer) {
- $qtype = 'MC';
- }
- $content = $currdirpath."\t".$title."\t$qtype\t".join("\t",@tosave);
- if ($mc_answer) {
- $content .= "\t".$mc_answer;
- }
- $content .= "\n";
- }
- } else {
- $content = ''.$content.'';
- }
- if (($caller eq 'plaintext') && ($testbank)) {
- print $testbank $content;
- }
- } else {
- $content = 'Not the owner of this resource';
- }
- } else {
- $content = 'Not the owner of this resource';
- }
- $repstatus = 'ok';
- }
- 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 = 'resources/'.$count.'/'.$filename;
- }
- return $content_name;
-}
-
-sub extract_media {
- my ($url,$cdom,$cnum,$content,$count,$tempexport,$href,$message,$caller) = @_;
- my ($dirpath,$container);
- my %allfiles = ();
- my %codebase = ();
- if ($url =~ m-(.*/)([^/]+)$-) {
- $dirpath = $1;
- $container = $2;
- } else {
- $dirpath = $url;
- $container = '';
- }
- &Apache::lonnet::extract_embedded_items(undef,\%allfiles,\%codebase,$content);
- foreach my $embed_file (keys(%allfiles)) {
- my $filename;
- if ($embed_file =~ m#([^/]+)$#) {
- $filename = $1;
- } else {
- $filename = $embed_file;
- }
- my $newname = 'res/'.$filename;
- my ($rtncode,$embed_content,$repstatus);
- my $embed_url;
- if ($embed_file =~ m-^/-) {
- $embed_url = $embed_file; # points to absolute path
- } else {
- if ($embed_file =~ m-https?://-) {
- next; # points to url
- } else {
- $embed_url = $dirpath.$embed_file; # points to relative path
- }
- }
- if ($caller eq 'resource') {
- my $respath = $Apache::lonnet::perlvar{'lonDocRoot'}.'/res';
- my $embed_path = &Apache::lonnet::filelocation($respath,$embed_url);
- $embed_content = &Apache::lonnet::getfile($embed_path);
- unless ($embed_content eq -1) {
- $repstatus = 'ok';
- }
- } elsif ($caller eq 'uploaded') {
- $repstatus = &Apache::lonnet::getuploaded('GET',$embed_url,$cdom,$cnum,\$embed_content,$rtncode);
- }
- if ($repstatus eq 'ok') {
- my $destination = $tempexport.'/resources/'.$count.'/res';
- if (!-e "$destination") {
- mkdir($destination,0755);
- }
- $destination .= '/'.$filename;
- my $copiedfile;
- if ($copiedfile = Apache::File->new('>'.$destination)) {
- print $copiedfile $embed_content;
- push(@{$href},'resources/'.$count.'/res/'.$filename);
- my $attrib_regexp = '';
- if (@{$allfiles{$embed_file}} > 1) {
- $attrib_regexp = join('|',@{$allfiles{$embed_file}});
- } else {
- $attrib_regexp = $allfiles{$embed_file}[0];
- }
- $$content =~ s#($attrib_regexp\s*=\s*['"]?)\Q$embed_file\E(['"]?)#$1$newname$2#gi;
- if ($caller eq 'resource' && $container =~ /\.(problem|library)$/) {
- $$content =~ s#\Q$embed_file\E#$newname#gi;
- }
- }
- } else {
- $$message .= 'replication of embedded file - '.$embed_file.' in '.$url.' failed, reason -'.$rtncode." \n";
- }
- }
- 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 'resources/'.$count.'/'.$content_type.'.html';
- } else {
- return 'resources/'.$count.'/'.$content_type.'.xml';
- }
- }
- }
-}
-
-
sub group_import {
my ($coursenum, $coursedom, $folder, $container, $caller, @files) = @_;
@@ -1567,7 +768,6 @@ sub update_parameter {
sub handle_edit_cmd {
my ($coursenum,$coursedom) =@_;
-
my ($cmd,$idx)=split('_',$env{'form.cmd'});
my $ratstr = $LONCAPA::map::resources[$LONCAPA::map::order[$idx]];
@@ -1907,12 +1107,59 @@ sub process_file_upload {
$$upload_output .= &mt('No embedded items identified').' ';
}
$$upload_output = ''.$$upload_output.'
';
+ } elsif (&Apache::loncommon::is_archive_file($mimetype)) {
+ $nextphase = 'decompress_uploaded';
+ my $position = scalar(@LONCAPA::map::order)-1;
+ my $noextract = &return_to_editor();
+ my $archiveurl = &HTML::Entities::encode($url,'<>&"');
+ my %archiveitems = (
+ folderpath => $env{'form.folderpath'},
+ pagepath => $env{'form.pagepath'},
+ cmd => $nextphase,
+ newidx => $newidx,
+ position => $position,
+ phase => $nextphase,
+ comment => $comment,
+ );
+ my ($destination,$dir_root) = &embedded_destination($coursenum,$coursedom);
+ my @current = &get_dir_list($url,$coursenum,$coursedom,$newidx);
+ $$upload_output = $showupload.
+ &Apache::loncommon::decompress_form($mimetype,
+ $archiveurl,'/adm/coursedocs',$noextract,
+ \%archiveitems,\@current);
}
}
}
return $nextphase;
}
+sub get_dir_list {
+ my ($url,$coursenum,$coursedom,$newidx) = @_;
+ my ($destination,$dir_root) = &embedded_destination();
+ my ($dirlistref,$listerror) =
+ &Apache::lonnet::dirlist("$dir_root/$destination/$newidx",$coursedom,$coursenum,1);
+ my @dir_lines;
+ my $dirptr=16384;
+ if (ref($dirlistref) eq 'ARRAY') {
+ foreach my $dir_line (sort
+ {
+ my ($afile)=split('&',$a,2);
+ my ($bfile)=split('&',$b,2);
+ return (lc($afile) cmp lc($bfile));
+ } (@{$dirlistref})) {
+ my ($filename,$dom,undef,$testdir,undef,undef,undef,undef,$size,undef,$mtime,undef,undef,undef,$obs,undef)=split(/\&/,$dir_line,16);
+ $filename =~ s/\s+$//;
+ next if ($filename =~ /^\.\.?$/);
+ my $isdir = 0;
+ if ($dirptr&$testdir) {
+ $isdir = 1;
+ }
+ push(@dir_lines, [$filename,$dom,$isdir,$size,$mtime,$obs]);
+ }
+ }
+ return @dir_lines;
+}
+
sub is_supplemental_title {
my ($title) = @_;
return scalar($title =~ m/^(\d+)___&&&___($match_username)___&&&___($match_domain)___&&&___(.*)$/);
@@ -1963,7 +1210,7 @@ sub entryline {
$renametitle=~s/\"\;/\\\"/g;
$renametitle=~s/ /%20/g;
my $line=&Apache::loncommon::start_data_table_row();
- my ($form_start,$form_end);
+ my ($form_start,$form_end,$form_common);
# Edit commands
my ($container, $type, $esc_path, $path, $symb);
if ($env{'form.folderpath'}) {
@@ -2054,8 +1301,10 @@ ENDCOPY
$lt{'ct'}
ENDCUT
}
- $form_start = (<
+ $form_start = '
+ ';
my $ro_set=
((&LONCAPA::map::getparameter($orderidx,'parameter_randomorder'))[0]=~/^yes$/i?' checked="checked"':'');
- $rand_order_text ='
- '.&mt('Random Order').' ';
+ $rand_order_text =
+$form_start.
+$form_common.'
+ '.&mt('Random Order').' ';
}
if ($ispage) {
my $pagename=&escape($pagetitle);
@@ -2236,6 +1497,8 @@ END
$line.=$title.' '.$reinit.' ';
}
$line.=$external."";
+ $rand_pick_text = ' ' if ($rand_pick_text eq '');
+ $rand_order_text = ' ' if ($rand_order_text eq '');
if (($allowed) && ($folder!~/^supplemental/)) {
my %lt=&Apache::lonlocal::texthash(
'hd' => 'Hidden',
@@ -2247,15 +1510,17 @@ END
$line.=(<
$form_start
+ $form_common
$lt{'hd'}
$form_end
$form_start
+ $form_common
$lt{'ec'}
$form_end
- $form_start $parameterset $form_end
- $form_start $rand_order_text $form_end
+ $rand_pick_text
+ $rand_order_text
ENDPARMS
}
$line.=&Apache::loncommon::end_data_table_row();
@@ -2494,9 +1759,11 @@ sub checkversions {
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 Saved').' ');
+ $r->print(&Apache::loncommon::confirmwrapper(
+ &Apache::lonhtmlcommon::confirm_success(&mt('Your Version Settings have been Saved'))));
} else {
- $r->print(''.&mt('An Error Occured while Attempting to Save your Version Settings').' ');
+ $r->print(&Apache::loncommon::confirmwrapper(
+ &Apache::lonhtmlcommon::confirm_success(&mt('An Error Occured while Attempting to Save your Version Settings'),1)));
}
&mark_hash_old();
}
@@ -2562,12 +1829,19 @@ sub checkversions {
'sv' => 'Set Versions to be used in '.$crstype.' 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');
+ 'di' => 'Differences',
+ 'save' => 'Save',
+ 'act' => 'Actions');
$r->print(<
-
-
+
+
+$lt{'act'}
+$lt{'sm'}:
+$lt{'sc'}:
+
+
$lt{'al'}
$lt{'st'}
@@ -2576,47 +1850,49 @@ sub checkversions {
$lt{'sy'}
-$header
-
+$header
+
ENDHEADERS
+ #number of columns for version history
+ my $num_ver_col = 1;
+ $r->print(
+ &Apache::loncommon::start_data_table().
+ &Apache::loncommon::start_data_table_header_row().
+ ''.&mt('Resources').' '.
+ "$lt{'mr'} ".
+ "$lt{'ve'} ".
+ "$lt{'vu'} ".
+ ''.&mt('History').' '.
+ '');
foreach my $key (sort(keys(%changes))) {
if ($changes{$key}>$starttime) {
my ($root,$extension)=($key=~/^(.*)\.(\w+)$/);
my $currentversion=&Apache::lonnet::getversion($key);
if ($currentversion<0) {
- $currentversion=&mt('Could not be determined.');
+ $currentversion=''.&mt('Could not be determined.').' ';
}
my $linkurl=&Apache::lonnet::clutter($key);
- $r->print(
- ''.
- &Apache::lonnet::gettitle($linkurl).
- ' '.
- ' '.
- ''.
- ''.$linkurl.
- ' '.
- ' '.
- ''.
- &Apache::lonlocal::locallocaltime(
- &Apache::lonnet::metadata($root.'.'.$extension,
- 'lastrevisiondate')
- ).
- ' '.
- 'Most Recent: '.
- ''.$currentversion.' '.
- ' '.
- 'In '.$crstype.': '.
- '');
+ $r->print(
+ &Apache::loncommon::end_data_table_header_row().
+ &Apache::loncommon::start_data_table_row().
+ ' '.&Apache::lonnet::gettitle($linkurl).' '.
+ ''.$linkurl.' '.
+ ''.$currentversion.' ('.
+ &Apache::lonlocal::locallocaltime(&Apache::lonnet::metadata($root.'.'.$extension,'lastrevisiondate')).') '.
+ '');
# Used in course
my $usedversion=$hash{'version_'.$linkurl};
if (($usedversion) && ($usedversion ne 'mostrecent')) {
- $r->print($usedversion);
+ if($usedversion != $currentversion){
+ $r->print(''.$usedversion.' ');
+ }else{
+ $r->print($usedversion);
+ }
} else {
$r->print($currentversion);
}
- $r->print(' '.
- 'Use: ');
+ $r->print(' ');
# Set version
$r->print(&Apache::loncommon::select_form($setversions{$linkurl},
'set_version_'.$linkurl,
@@ -2625,7 +1901,6 @@ ENDHEADERS
'' => '',
'mostrecent' => &mt('most recent'),
map {$_,$_} (1..$currentversion)}));
- $r->print(' ');
my $lastold=1;
for (my $prevvers=1;$prevvers<$currentversion;$prevvers++) {
my $url=$root.'.'.$prevvers.'.'.$extension;
@@ -2639,13 +1914,13 @@ ENDHEADERS
# 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;
+ if ($num_entries % $num_ver_col == 0) {
+ $entries_per_col = $num_entries/$num_ver_col;
} else {
- $entries_per_col = $num_entries/4 + 1;
+ $entries_per_col = $num_entries/$num_ver_col + 1;
}
my $entries_count = 0;
- $r->print('');
+ $r->print(' ');
my $cols_output = 1;
for (my $prevvers=$lastold;$prevvers<$currentversion;$prevvers++) {
my $url=$root.'.'.$prevvers.'.'.$extension;
@@ -2664,21 +1939,21 @@ ENDHEADERS
}
$r->print(' ');
if (++$entries_count % $entries_per_col == 0) {
- $r->print(' ');
- if ($cols_output != 4) {
- $r->print('');
+ $r->print(' ');
+ if ($cols_output != $num_ver_col) {
+ $r->print('');
$cols_output++;
}
}
}
- while($cols_output++ < 4) {
- $r->print(' ')
+ while($cols_output++ < $num_ver_col) {
+ $r->print(' ');
}
- $r->print(' '."\n");
}
}
- $r->print('
');
- $r->print(''.&mt('Done').'
');
+ $r->print(''.&Apache::loncommon::end_data_table_row().
+ &Apache::loncommon::end_data_table().
+ ' ');
&untiehash();
}
@@ -2865,7 +2140,7 @@ sub handler {
&dumpcourse($r);
} elsif ($allowed && $env{'form.exportcourse'}) {
&init_breadcrumbs('exportcourse','IMS Export');
- &exportcourse($r);
+ &Apache::imsexport::exportcourse($r);
} else {
#
# Done catching special calls
@@ -2899,6 +2174,7 @@ sub handler {
my $script='';
my $showdoc=0;
my $addentries = {};
+ my $container;
my $containertag;
my $uploadtag;
@@ -3024,11 +2300,13 @@ sub handler {
my (@folderpath)=split('&',$env{'form.folderpath'});
$env{'form.foldername'}=&unescape(pop(@folderpath));
$env{'form.folder'}=pop(@folderpath);
+ $container='sequence';
}
if ($env{'form.pagepath'}) {
my (@pagepath)=split('&',$env{'form.pagepath'});
$env{'form.pagename'}=&unescape(pop(@pagepath));
$env{'form.folder'}=pop(@pagepath);
+ $container='page';
$containertag = ' '.
' ';
$uploadtag =
@@ -3158,6 +2436,14 @@ sub handler {
$docuname,$docudom,undef,
$dir_root).
&return_to_editor());
+ } elsif ($env{'form.phase'} eq 'decompress_uploaded') {
+ $uploadphase = 'decompress_phase_one';
+ $r->print(&decompression_phase_one().
+ &return_to_editor());
+ } elsif ($env{'form.phase'} eq 'decompress_cleanup') {
+ $uploadphase = 'decompress_phase_two';
+ $r->print(&decompression_phase_two().
+ &return_to_editor());
}
}
@@ -3728,6 +3014,112 @@ sub return_to_editor {
'';
}
+sub decompression_info {
+ my ($destination,$dir_root) = &embedded_destination();
+ my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'};
+ my $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'};
+ my $docuname=$env{'course.'.$env{'request.course.id'}.'.num'};
+ my $container='sequence';
+ my ($pathitem,$hiddenelem);
+ my @hiddens = ('newidx','comment','position');
+ if ($env{'form.pagepath'}) {
+ $container='page';
+ $pathitem = 'pagepath';
+ } else {
+ $pathitem = 'folderpath';
+ }
+ unshift(@hiddens,$pathitem);
+ foreach my $item (@hiddens) {
+ if ($env{'form.'.$item}) {
+ $hiddenelem .= ' '."\n";
+ }
+ }
+ return ($destination,$dir_root,$londocroot,$docudom,$docuname,$container,
+ $hiddenelem);
+}
+
+sub decompression_phase_one {
+ my ($dir,$file,$warning,$error,$output);
+ my ($destination,$dir_root,$londocroot,$docudom,$docuname,$container,$hiddenelem)=
+ &decompression_info();
+ if ($env{'form.archiveurl'} !~ m{^/uploaded/\Q$docudom/$docuname/docs/\E(?:default|supplemental|\d+).*/([^/]+)$}) {
+ $error = &mt('Archive file "[_1]" not in the expected location.',$env{'form.archiveurl'});
+ } else {
+ my $file = $1;
+ $output = &Apache::loncommon::process_decompression($docudom,$docuname,$file,$destination,$dir_root,$hiddenelem);
+ }
+ if ($error) {
+ $output .= ''.&mt('Not extracted.').' '.
+ $error.'
'."\n";
+ }
+ if ($warning) {
+ $output .= ''.$warning.'
'."\n";
+ }
+ return $output;
+}
+
+sub decompression_phase_two {
+ my ($destination,$dir_root,$londocroot,$docudom,$docuname,$container,$hiddenelem)=
+ &decompression_info();
+ my ($output,$url);
+ if ($env{'form.archivedelete'}) {
+ ($output,$url) = &remove_archive($docudom,$docuname,$container);
+ }
+ $output .=
+ &Apache::loncommon::process_extracted_files('coursedocs',$docudom,$docuname,$url,
+ $destination,$dir_root,$hiddenelem);
+ return $output;
+}
+
+sub remove_archive {
+ my ($docudom,$docuname,$container) = @_;
+ my $map = $env{'form.folder'}.'.'.$container;
+ my ($output,$delwarning,$delresult,$url,$outcome);
+ my ($errtext,$fatal) = &mapread($docuname,$docudom,$map);
+ if ($fatal) {
+ if ($container eq 'page') {
+ $delwarning = &mt('An error occurred retrieving the contents of the current page.');
+ } else {
+ $delwarning = &mt('An error occurred retrieving the contents of the current folder.');
+ }
+ $delwarning .= &mt('As a result the archive file has not been removed.');
+ } else {
+ my $currcmd = $env{'form.cmd'};
+ my $position = $env{'form.position'};
+ if ($position > 0) {
+ $env{'form.cmd'} = 'del_'.$position;
+ my ($title,$url,@rrest) =
+ split(/:/,$LONCAPA::map::resources[$LONCAPA::map::order[$position]]);
+ if (&handle_edit_cmd($docuname,$docudom)) {
+ ($errtext,$fatal) = &storemap($docuname,$docudom,$map);
+ if ($fatal) {
+ if ($container eq 'page') {
+ $delwarning = &mt('An error occurred updating the contents of the current page.');
+ } else {
+ $delwarning = &mt('An error occurred updating the contents of the current folder.');
+ }
+ } else {
+ $outcome = 'ok';
+ }
+ $delresult = &mt('Archive file removed.');
+ }
+ }
+ $env{'form.cmd'} = $currcmd;
+ }
+ if ($delwarning) {
+ $output = ''.
+ $delwarning.
+ '
';
+ }
+ if ($delresult) {
+ $output .= ''.
+ $delresult.
+ '
';
+ }
+ return ($output,$url,$outcome);
+}
+
sub generate_admin_options {
my ($help_ref,$env_ref) = @_;
my %lt=&Apache::lonlocal::texthash(
@@ -3843,7 +3235,8 @@ sub editing_js {
p_ctr1a => 'WARNING: Cutting a resource makes associated grades and scores inaccessible!',
p_ctr1b => 'Grades remain inaccessible if resource is pasted into another folder.',
p_ctr2a => 'Cut[_98]',
- p_ctr2b => '?[_98]'
+ p_ctr2b => '?[_98]',
+ rpck => 'Enter number to pick (e.g., 3)',
);
my $crstype = &Apache::loncommon::course_type();
@@ -3967,7 +3360,6 @@ newWindow = window.open("","IMSimport","
newWindow.location.href = newlocation;
}
-
function finishpick() {
var title=this.document.forms.extimport.title.value;
var url=this.document.forms.extimport.url.value;
@@ -4037,6 +3429,37 @@ this.document.forms.renameform.pagesymb.
this.document.forms.renameform.submit();
}
+function updatePick(targetform,index,caller) {
+ var pickitem = document.getElementById('rpick_'+index);
+ var picknumitem = document.getElementById('rpicknum_'+index);
+ if (pickitem.checked) {
+ var picknum=prompt('$lt{"rpck"}',picknumitem.value);
+ if (picknum == '' || picknum == null) {
+ if (caller == 'check') {
+ pickitem.checked=false;
+ return;
+ }
+ } else {
+ picknum.toString();
+ var regexdigit=/^\\d+\$/;
+ if (regexdigit.test(picknum)) {
+ picknumitem.value = picknum;
+ targetform.changeparms.value='randompick';
+ targetform.submit();
+ } else {
+ if (caller == 'check') {
+ pickitem.checked=false;
+ }
+ return;
+ }
+ }
+ } else {
+ picknumitem.value = 0;
+ targetform.changeparms.value='randompick';
+ targetform.submit();
+ }
+}
+
function unselectInactive(nav) {
currentNav = document.getElementById(nav);
currentLis = currentNav.getElementsByTagName('LI');
@@ -4390,22 +3813,6 @@ Generate "dump" button
Generate "export" button
-=item exportcourse()
-
-=item create_ims_store()
-
-=item build_package()
-
-=item get_dependencies()
-
-=item process_content()
-
-=item replicate_content()
-
-=item extract_media()
-
-=item store_template()
-
=item group_import()
Imports the given (name, url) resources into the course