--- loncom/interface/londocs.pm 2004/09/18 17:06:57 1.146 +++ loncom/interface/londocs.pm 2004/12/23 14:00:58 1.158 @@ -1,7 +1,7 @@ # The LearningOnline Network # Documents # -# $Id: londocs.pm,v 1.146 2004/09/18 17:06:57 albertel Exp $ +# $Id: londocs.pm,v 1.158 2004/12/23 14:00:58 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -30,6 +30,7 @@ package Apache::londocs; use strict; use Apache::Constants qw(:common :http); +use Apache::imsexport; use Apache::lonnet; use Apache::loncommon; use Apache::lonratedt; @@ -283,7 +284,6 @@ sub exportcourse { $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 $count = 0; my %symbs; my $manifestok = 0; my $imsresources; @@ -291,7 +291,7 @@ sub exportcourse { 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); + &build_package($now,$navmap,\@exportitems,\@discussions,\$outcome,$tempexport,\$copyresult,$ims_manifest); close($ims_manifest); #Create zip file in prtspool @@ -320,7 +320,7 @@ sub exportcourse { } $r->print('Export Course'. - &Apache::loncommon::bodytag('Export course to IMS or SCORM content package')); + &Apache::loncommon::bodytag('Export course to IMS content package')); $r->print($outcome); $r->print(''); } else { @@ -369,6 +369,12 @@ sub exportcourse { } 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 .=''."\n". 'title().''; - if ($discussiontime{$symb} > 0) { + if ($discussiontime{$ressymb} > 0) { $boards ++; $currelem = $count+$boards+$startcount; $display .= '  '."\n"; @@ -403,13 +409,23 @@ sub exportcourse { |; $r->print('Export Course'.$scripttag.''. - &Apache::loncommon::bodytag('Export course to IMS or SCORM content package' + &Apache::loncommon::bodytag('Export course to IMS content package' )); $r->print($display.''. @@ -483,7 +499,7 @@ sub create_ims_store { ' identifier="MANIFEST-'.$ENV{'request.course.id'}.'-'.$now.'"'. ' xsi:schemaLocation="http://www.imsglobal.org/xsd/imscp_v1p1imscp_v1p1.xsd'. ' http://www.imsglobal.org/xsd/imsmd_v1p2 imsmd_v1p2p2.xsd">'."\n". -' '."\n". +' '."\n". ' '."\n". ' '.$ENV{'request.'.$ENV{'request.course.id'}.'.description'}.'' @@ -504,8 +520,8 @@ sub build_package { my $lastcontainer = 0; my %parent = (); my @dependencies = (); - my $cnum = $ENV{'request.'.$ENV{'request.course.id'}.'.num'}; - my $cdom = $ENV{'request.'.$ENV{'request.course.id'}.'.domain'}; + 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 ++; @@ -534,57 +550,80 @@ sub build_package { $count = 0; my $imsresources; my $pkgdepth; - if ($curRes == $it->BEGIN_MAP()) { - $prevdepth = $depth; - $depth++; - } - if ($curRes == $it->END_MAP()) { - $prevdepth = $depth; - $depth--; - } - - if (ref($curRes)) { - 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)) { - print $ims_manifest ' '."\n"; - } + 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 = + my $itementry = ''. ''.$curRes->title().''; - print $ims_manifest "\n".$itementry; + 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". + 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 .= + 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, + count => $count + ); + my $discresult = &Apache::lonfeedback::list_discussion($mode,undef,$ressymb,\%extras); + } + $imsresources .= ' '."\n"; } - $imsresources .= ' '."\n"; } + $pkgdepth = $depth; + } else { + $included = 0; } - $pkgdepth = $depth; } } - while ($pkgdepth > -1) { + while ($pkgdepth > 0) { print $ims_manifest " \n"; $pkgdepth --; } @@ -602,7 +641,7 @@ sub build_package { sub get_dependencies { my ($exportitems,$parent,$depth,$dependencies) = @_; if ($depth > 1) { - unless (grep/^$$parent{$depth}$/,@$exportitems || grep/^$$parent{$depth}$/,@$dependencies) { + if ((!grep/^$$parent{$depth}$/,@$exportitems) && (!grep/^$$parent{$depth}$/,@$dependencies)) { push @$dependencies, $$parent{$depth}; if ($depth > 2) { &get_dependencies($exportitems,$parent,$depth-1,$dependencies); @@ -616,29 +655,61 @@ sub process_content { my $content_type; my $message; # find where user is author or co-author - my %roleshash = &Appache::lonnet::get_my_roles(); - if ($curRes->is_page()) { - $content_type = 'page'; + my %roleshash = &Apache::lonnet::get_my_roles(); + 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'; - } elsif ($symb =~ m-\.sequence____\d+____ext-) { + 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/$cdom/$cnum/\d+/smppg$-) { + } elsif ($symb =~ m-adm/[^/]+/[^/]+/(\d+)/smppg$-) { $content_type = 'simplepage'; - } elsif ($symb =~ m-$-) { + 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'; - } elsif ($symb =~ m-adm/$cdom/$cnum/\d+/bulletinboard$-) { + my $contents = &Apache::imsexport::simpleproblem($symb); + if ($contents) { + $$content_file = &store_template($contents,$tempexport,$count,$content_type); + } + } elsif ($symb =~ m-lib/templates/examupload\.problem-m) { + $content_type = 'examupload'; + } elsif ($symb =~ m-adm/(\w+)/(\w+)/(\d+)/bulletinboard$-) { $content_type = 'bulletinboard'; - } elsif ($symb =~ m-adm/$cdom/$cnum/\d+/aboutme$-) { + 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-uploaded/$cdom/$cnum-) { - &replicate_content($cdom,$cnum,$tempexport,$symb,$count,\$message,'uploaded'); - } elsif ($symb =~ m-\.sequence____\d+____([^/])/([^/])-) { - my $coauth = $2.':'.$1.':ca'; + $$content_file = &replicate_content($cdom,$cnum,$tempexport,$symb,$count,\$message,$href,'uploaded'); + } 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 $coauth = $3.':'.$2.':ca'; my $canedit = 0; - if ($1 eq $ENV{'user.domain'} && $2 eq $ENV{'user.name'}) { + if ($2 eq $ENV{'user.domain'} && $3 eq $ENV{'user.name'}) { $canedit= 1; } elsif (defined($roleshash{$coauth})) { if ($roleshash{$coauth} =~ /(\d+):(\d+)/) { @@ -650,45 +721,62 @@ sub process_content { } } if ($canedit) { - &replicate_content($cdom,$cnum,$tempexport,$symb,$count,\$message,'resource'); + $$content_file = &replicate_content($cdom,$cnum,$tempexport,$symb,$count,\$message,$href,'resource'); } else { - &replicate_content($cdom,$cnum,$tempexport,$symb,$count,\$message,'noedit'); + $$content_file = &replicate_content($cdom,$cnum,$tempexport,$symb,$count,\$message,$href,'noedit'); } } - $$copyresult .= $message."\n"; + if (@uploads > 0) { + foreach my $item (@uploads) { + my $uploadmsg = ''; + &replicate_content($cdom,$cnum,$tempexport,$item,$count,\$uploadmsg,$href,'uploaded'); + if ($uploadmsg) { + $$copyresult .= $uploadmsg."\n"; + } + } + } + if ($message) { + $$copyresult .= $message."\n"; + } } sub replicate_content { - my ($cdom,$cnum,$tempexport,$symb,$count,$message,$caller) = @_; + my ($cdom,$cnum,$tempexport,$symb,$count,$message,$href,$caller) = @_; my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb); my $feedurl = &Apache::lonnet::clutter($url); my $content; my $filename; my $repstatus; - if ($url =~ m-[^/]/(.+)$-) { + my $content_name; + if ($url =~ m-/([^/]+)$-) { $filename = $1; if (!-e $tempexport.'/resources') { mkdir($tempexport.'/resources',0700); } - if (!-e $tempexport.'/resources') { + if (!-e $tempexport.'/resources/'.$count) { mkdir($tempexport.'/resources/'.$count,0700); } - my $destination = $$tempexport.'/resources/'.$count.'/'.$filename; + my $destination = $tempexport.'/resources/'.$count.'/'.$filename; my $copiedfile; if ($copiedfile = Apache::File->new('>'.$destination)) { my $content; - if ($caller eq 'uploaded' || $caller eq 'resource') { + if ($caller eq 'resource') { $content = &Apache::lonnet::getfile($url); if ($content eq -1) { $$message = 'Could not copy file '.$filename; } else { + &extract_media($content,$count,$tempexport,$href,'resource'); $repstatus = 'ok'; } - } elsif ($caller eq 'noedit') { + } elsif ($caller eq 'noedit' || $caller eq 'uploaded') { my $rtncode; - $repstatus = &getuploaded('GET',$url,$cdom,$cnum,$content,$rtncode); - unless ($repstatus eq 'ok') { + $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; } } @@ -700,9 +788,34 @@ sub replicate_content { $$message = 'Could not open destination file for '.$filename."\n"; } } else { - $$message = 'Could not determine name of file for '; + $$message = 'Could not determine name of file for '.$url."\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) { + my $destination = $tempexport.'/resources/'.$count.'/'.$content_type.'.xml'; + my $storetemplate; + if ($storetemplate = Apache::File->new('>'.$destination)) { + print $storetemplate $contents; + close($storetemplate); + } + return $count.'/'.$content_type.'.xml'; } - return $repstatus; } # Imports the given (name, url) resources into the course @@ -989,15 +1102,17 @@ sub editor { # ---------------------------------------------------------------- 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) { next; } + unless ($name) { $idx++; next; } $r->print(&entryline($idx,$name,$url,$folder,$allowed,$_,$coursenum)); $idx++; + $shown++; } - unless ($idx) { + unless ($shown) { $r->print(''); } $r->print('
'.&mt('Currently no documents.').'
'); @@ -1032,10 +1147,11 @@ sub entryline { $folderpath=&Apache::lonnet::escape($ENV{'form.folderpath'}); # $htmlfoldername=&HTML::Entities::encode($ENV{'form.foldername'},'<>&"'); } - my $pagepath; + my ($pagepath,$pagesymb); if ($ENV{'form.pagepath'}) { $container = 'page'; $pagepath=&Apache::lonnet::escape($ENV{'form.pagepath'}); + $pagesymb=&Apache::lonnet::escape($ENV{'form.pagesymb'}); } if ($allowed) { my $incindex=$index+1; @@ -1062,20 +1178,21 @@ sub entryline { $line.=(< +
- + $lt{
- + $lt{
$selectbox - + $lt{'rm'} - + $lt{'rn'} END } else { @@ -1150,9 +1267,13 @@ END } elsif ($url=~m|^/ext/|) { $url='/adm/wrapper'.$url; } - unless ($container eq 'page') { + $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) { @@ -1161,9 +1282,12 @@ END if ($folderpath) { $folderpath.='&' }; $folderpath.=$folderarg.'&'.$foldername; $url.='folderpath='.&Apache::lonnet::escape($folderpath); - $parameterset=&mt('Randomly Pick: '). + $parameterset=''; + } if ($ispage) { my $pagename=&Apache::lonnet::escape($pagetitle); @@ -1171,7 +1295,17 @@ END my $folderpath=$ENV{'form.folderpath'}; if ($folderpath) { $pagepath = $folderpath.'&' }; $pagepath.=$pagearg.'&'.$pagename; - $url.='pagepath='.&Apache::lonnet::escape($pagepath); + 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); } $line.=''. @@ -1187,9 +1321,9 @@ END ((&Apache::lonratedt::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i?' checked="1"':''); $line.=(< - $lt{'hd'} - + + + $parameterset @@ -1205,33 +1339,24 @@ ENDPARMS sub tiehash { my ($mode)=@_; $hashtied=0; - &Apache::lonnet::logthis(" tiehash1 -- $hashtied "); if ($ENV{'request.course.fn'}) { - &Apache::lonnet::logthis(" tiehash2 -- $hashtied "); if ($mode eq 'write') { - &Apache::lonnet::logthis(" tiehash3 -- $hashtied "); if (tie(%hash,'GDBM_File',$ENV{'request.course.fn'}.".db", &GDBM_WRCREAT(),0640)) { $hashtied=2; - &Apache::lonnet::logthis(" tiehash4 -- $hashtied "); } } else { - &Apache::lonnet::logthis(" tiehash5 -- $hashtied "); if (tie(%hash,'GDBM_File',$ENV{'request.course.fn'}.".db", &GDBM_READER(),0640)) { $hashtied=1; - &Apache::lonnet::logthis(" tiehash6 -- $hashtied "); } } } - &Apache::lonnet::logthis(" tiehash7 -- $hashtied "); } sub untiehash { - &Apache::lonnet::logthis(" untiehash1 -- $hashtied "); if ($hashtied) { untie %hash; } $hashtied=0; - &Apache::lonnet::logthis(" untiehash2 -- $hashtied "); } # --------------------------------------------------------------- check on this @@ -1587,21 +1712,14 @@ ENDHEADERS sub mark_hash_old { my $retie_hash=0; - &Apache::lonnet::logthis(" markold1 -- $hashtied $retie_hash "); if ($hashtied) { $retie_hash=1; - &Apache::lonnet::logthis(" markold2 -- $hashtied $retie_hash "); &untiehash(); - &Apache::lonnet::logthis(" markold3 -- $hashtied $retie_hash "); } &tiehash('write'); - &Apache::lonnet::logthis(" markold4 -- $hashtied $retie_hash "); $hash{'old'}=1; - &Apache::lonnet::logthis(" markold5 -- $hashtied $retie_hash "); &untiehash(); - &Apache::lonnet::logthis(" markold6 -- $hashtied $retie_hash "); if ($retie_hash) { &tiehash(); } - &Apache::lonnet::logthis(" markold7 -- $hashtied $retie_hash "); } sub is_hash_old { @@ -1618,11 +1736,18 @@ sub is_hash_old { sub changewarning { my ($r,$postexec)=@_; if (!&is_hash_old()) { return; } + my $pathvar='folderpath'; + my $path=&Apache::lonnet::escape($ENV{'form.folderpath'}); + if (defined($ENV{'form.pagepath'})) { + $pathvar='pagepath'; + $path=&Apache::lonnet::escape($ENV{'form.pagepath'}); + $path.='&symb='.&Apache::lonnet::escape($ENV{'form.pagesymb'}); + } $r->print( ''. '
'. -'

'. &mt('Changes will become active for your current session after'). ' '; - $uploadtag = ''; + $containertag = ''. + ''; + $uploadtag = ''. + ''; } if ($r->uri=~/^\/adm\/coursedocs\/showdoc\/(.*)$/) { $showdoc='/'.$1; } unless ($showdoc) { # got called from remote - $forcestandard=($ENV{'form.folder'}=~/^default_/); + 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? @@ -1832,7 +1962,7 @@ function finishpick() { '";this.document.forms.'+form+'.submit();'); } -function changename(folderpath,index,oldtitle,container) { +function changename(folderpath,index,oldtitle,container,pagesymb) { var title=prompt('New Title',oldtitle); if (title) { this.document.forms.renameform.title.value=title; @@ -1842,12 +1972,13 @@ function changename(folderpath,index,old } if (container == 'page') { this.document.forms.renameform.pagepath.value=folderpath; + this.document.forms.renameform.pagesymb.value=pagesymb; } this.document.forms.renameform.submit(); } } -function removeres(folderpath,index,oldtitle,container) { +function removeres(folderpath,index,oldtitle,container,pagesymb) { if (confirm('Remove "'+oldtitle+'"?')) { this.document.forms.renameform.cmd.value='del_'+index; if (container == 'sequence') { @@ -1855,6 +1986,7 @@ function removeres(folderpath,index,oldt } if (container == 'page') { this.document.forms.renameform.pagepath.value=folderpath; + this.document.forms.renameform.pagesymb.value=pagesymb; } this.document.forms.renameform.submit(); }