--- loncom/interface/londocs.pm	2005/06/26 15:42:52	1.191
+++ loncom/interface/londocs.pm	2005/09/20 07:52:03	1.206
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Documents
 #
-# $Id: londocs.pm,v 1.191 2005/06/26 15:42:52 raeburn Exp $
+# $Id: londocs.pm,v 1.206 2005/09/20 07:52:03 albertel Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -166,7 +166,10 @@ sub dumpcourse {
 	$crs=~s/\_/\//g;
 	foreach (keys %replacehash) {
 	    my $newfilename=$title.'/'.$replacehash{$_};
+	    $newfilename=~s/\.(\w+)$//;
+	    my $ext=$1;
 	    $newfilename=&clean($newfilename);
+	    $newfilename.='.'.$ext;
 	    my @dirs=split(/\//,$newfilename);
 	    my $path='/home/'.$ca.'/public_html';
 	    my $makepath=$path;
@@ -249,11 +252,10 @@ sub dumpcourse {
 # ------------------------------------------------------ Generate "export" button
 
 sub exportbutton {
-    return '';
     return '</td><td bgcolor="#DDDDCC">'.
             '<input type="submit" name="exportcourse" value="'.
             &mt('Export Course to IMS').'" />'.
-            &Apache::loncommon::help_open_topic('Docs_Export_Course_Docs');
+    &Apache::loncommon::help_open_topic('Docs_Export_Course_Docs');
 }
 
 sub exportcourse {
@@ -491,10 +493,21 @@ 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".
+'  <metadata>
+    <schema></schema>
+    <imsmd:lom>
+      <imsmd:general>
+        <imsmd:identifier>'.$env{'request.course.id'}.'</imsmd:identifier>
+        <imsmd:title>
+          <imsmd:langstring xml:lang="en">'.$env{'course.'.$env{'request.course.id'}.'.description'}.'</imsmd:langstring>
+        </imsmd:title>
+      </imsmd:general>
+    </imsmd:lom>
+  </metadata>'."\n".
 '  <organizations default="ORG-'.$env{'request.course.id'}.'-'.$now.'">'."\n".
 '    <organization identifier="ORG-'.$env{'request.course.id'}.'-'.$now.'"'.
 ' structure="hierarchical">'."\n".
-'      <title>'.$env{'request.'.$env{'request.course.id'}.'.description'}.'</title>'
+'      <title>'.$env{'course.'.$env{'request.course.id'}.'.description'}.'</title>'
     } else {
         $$outcome .= 'An error occurred opening the IMS manifest file.<br />'
 ;
@@ -542,7 +555,6 @@ sub build_package {
     $count = 0;
     my $imsresources;
     my $pkgdepth;
-    my $included = 0;
     while ($curRes = $it->next()) {
         if ($curRes == $it->BEGIN_MAP()) {
             $prevdepth = $depth;
@@ -565,10 +577,13 @@ sub build_package {
                 unless ($curRes->is_sequence()) {
                     $resourceref = 'identifierref="RES-'.$env{'request.course.id'}.'-'.$count.'"';
                 }
-                if (($depth <= $prevdepth) && ($count > 1) && ($included)) {
-                    print $ims_manifest "\n".'  </item>'."\n";
+                my $step = $prevdepth - $depth;
+                if (($step >= 0) && ($count > 1)) {
+                    while ($step >= 0) {
+                        print $ims_manifest "\n".'  </item>'."\n";
+                        $step --;
+                    }
                 }
-                $included = 1;
                 $prevdepth = $depth;
 
                 my $itementry =
@@ -610,8 +625,6 @@ sub build_package {
                     }
                 }
                 $pkgdepth = $depth;
-            } else {
-                $included = 0;
             }
         }
     }
@@ -646,7 +659,6 @@ 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';
@@ -700,6 +712,7 @@ sub process_content {
         if ($2 eq $env{'user.domain'} && $3 eq $env{'user.name'})  {
             $canedit= 1;
         }
+# only include problem code where current user is author
         if ($canedit) {
             $$content_file = &replicate_content($cdom,$cnum,$tempexport,$symb,$count,\$message,$href,'resource');
         } else {
@@ -748,11 +761,13 @@ sub replicate_content {
         if ($copiedfile = Apache::File->new('>'.$destination)) {
             my $content;
             if ($caller eq 'resource') {
-                $content = &Apache::lonnet::getfile('/home/httpd/html/res/'.$url);
+                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($content,$count,$tempexport,$href,'resource');
+                    &extract_media($url,$cdom,$cnum,\$content,$count,$tempexport,$href,$message,'resource');
                     $repstatus = 'ok';
                 }
             } elsif ($caller eq 'uploaded' || $caller eq 'templateupload') {
@@ -760,10 +775,10 @@ sub replicate_content {
                 $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');
+                        &extract_media($url,$cdom,$cnum,\$content,$count,$tempexport,$href,$message,'uploaded');
                     }
                 } else {
-                    $$message = 'Could not render '.$url.' server message - '.$rtncode;
+                    $$message = 'Could not render '.$url.' server message - '.$rtncode."<br />\n";
                 }
             } 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. 
@@ -775,23 +790,85 @@ sub replicate_content {
             }
             close($copiedfile);
         } else {
-            $$message = 'Could not open destination file for '.$filename."\n";
+            $$message = 'Could not open destination file for '.$filename."<br />\n";
         }
     } else {
-        $$message = 'Could not determine name of file for '.$symb."\n";
+        $$message = 'Could not determine name of file for '.$symb."<br />\n";
     }
     if ($repstatus eq 'ok') {
-        $content_name = $count.'/'.$filename;
+        $content_name = 'resources/'.$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. 
+    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,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."<br />\n";
+        }
+    }
     return;
 }
 
@@ -812,9 +889,9 @@ sub store_template {
                 close($storetemplate);
             }
             if ($content_type eq 'external') {
-                return $count.'/'.$content_type.'.html';
+                return 'resources/'.$count.'/'.$content_type.'.html';
             } else {
-                return $count.'/'.$content_type.'.xml';
+                return 'resources/'.$count.'/'.$content_type.'.xml';
             }
         }
     }
@@ -1037,7 +1114,7 @@ sub editor {
                 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)$/)) {
+			($url!~/\.(page|sequence|problem|exam|quiz|assess|survey|form|library|task)$/)) {
 			&Apache::lonnet::removeuploadedurl($url);
 		    } else {
 			&Apache::lonratedt::makezombie($Apache::lonratedt::order[$idx]);
@@ -1175,7 +1252,7 @@ FOLDERINFO
 }
 
 sub process_file_upload {
-    my ($upload_output,$coursenum,$coursedom,$allfiles,$codebase) = @_;
+    my ($upload_output,$coursenum,$coursedom,$allfiles,$codebase,$uploadcmd) = @_;
 # upload a file, if present
     my $parseaction;
    if ($env{'form.parserflag'}) {
@@ -1183,10 +1260,10 @@ sub process_file_upload {
     }
     my $phase_status;
     my $folder=$env{'form.folder'};
-    if ($folder eq '' || $folder eq 'supplemental') {
+    if ($folder eq '') {
         $folder='default';
     }
-    if ( ($folder=~/^$1/) || ($1 eq 'default') ) {
+    if ( ($folder=~/^$uploadcmd/) || ($uploadcmd eq 'default') ) {
         my $errtext='';
         my $fatal=0;
         my $container='sequence';
@@ -1203,10 +1280,13 @@ sub process_file_upload {
             return 'failed';
         }
         my $destination = 'docs/';
-        if ($folder eq 'default') {
+        if ($folder =~ /^supplemental/) {
+            $destination = 'supplemental/';
+        }
+        if (($folder eq 'default') || ($folder eq 'supplemental')) {
             $destination .= 'default/';
-        } elsif ($folder =~ /^default_(\d+)$/) {
-            $destination .=  $1.'/';
+        } elsif ($folder =~ /^(default|supplemental)_(\d+)$/) {
+            $destination .=  $2.'/';
         }
 # this is for a course, not a user, so set coursedoc flag
 # probably the only place in the system where this should be "1"
@@ -1285,9 +1365,12 @@ sub process_secondary_uploads {
     my ($upload_output,$coursedom,$coursenum,$formname,$num,$newidx) = @_;
     my $folder=$env{'form.folder'};
     my $destination = 'docs/';
-    if ($folder eq 'default') {
+    if ($folder =~ /^supplemental/) {
+        $destination = 'supplemental/';
+    }
+    if (($folder eq 'default') || ($folder eq 'supplemental')) {
         $destination .= 'default/';
-    } elsif ($folder =~ /^default_(\d+)$/) {
+    } elsif ($folder =~ /^(default|supplemental)_(\d+)$/) {
         $destination .=  $1.'/';
     }
     $destination .= $newidx;
@@ -1667,8 +1750,15 @@ sub verifycontent {
 	     &mt('Return to DOCS').'</a>');
 }
 
+
 # -------------------------------------------------------------- Check Versions
 
+sub devalidateversioncache {
+    my $src=shift;
+    &Apache::lonnet::devalidate_cache_new('courseresversion',$env{'request.course.id'}.'_'.
+					  &Apache::lonnet::clutter($src));
+}
+
 sub checkversions {
     my $r=shift;
     my $html=&Apache::lonxml::xmlbegin();
@@ -1695,6 +1785,7 @@ sub checkversions {
 	foreach (keys %hash) {
 	    if ($_=~/^ids\_(\/res\/.+)$/) {
 		$newsetversions{$1}='mostrecent';
+                &devalidateversioncache($1);
 	    }
 	}
     } elsif ($env{'form.setcurrent'}) {
@@ -1704,6 +1795,7 @@ sub checkversions {
 		my $getvers=&Apache::lonnet::getversion($1);
 		if ($getvers>0) {
 		    $newsetversions{$1}=$getvers;
+		    &devalidateversioncache($1);
 		}
 	    }
 	}
@@ -1714,6 +1806,7 @@ sub checkversions {
 		my $src=$1;
 		if (($env{$_}) && ($env{$_} ne $setversions{$src})) {
 		    $newsetversions{$src}=$env{$_};
+		    &devalidateversioncache($src);
 		}
 	    }
 	}
@@ -1943,7 +2036,7 @@ sub changewarning {
 	if (defined($env{'form.pagepath'})) {
 	    $pathvar='pagepath';
 	    $path=&Apache::lonnet::escape($env{'form.pagepath'});
-	    $path.='&amp;symb='.&Apache::lonnet::escape($env{'form.pagesymb'});
+	    $path.='&amp;pagesymb='.&Apache::lonnet::escape($env{'form.pagesymb'});
 	}
 	$url='/adm/coursedocs?'.$pathvar.'='.$path;
     }
@@ -2246,7 +2339,7 @@ ENDNEWSCRIPT
 # Process file upload - phase one - upload and parse primary file.  
           $upload_result = &process_file_upload(\$upload_output,$coursenum,
 						$coursedom,\%allfiles,
-						\%codebase);
+						\%codebase,$1);
           if ($upload_result eq 'phasetwo') {
               $r->print($upload_output);
           }
@@ -2647,7 +2740,15 @@ ENDBLOCK
 <tr><td bgcolor="#DDDDDD">
 <form action="/adm/coursedocs" method="post" enctype="multipart/form-data">
 <input type="file" name="uploaddoc" size="40">
-<br />$lt{'comment'}:<br />
+<br />
+<br />
+<nobr>
+<label>$lt{'parse'}?
+<input type="checkbox" name="parserflag" />
+</label>
+</nobr>
+<br /><br />
+$lt{'comment'}:<br />
 <textarea cols=50 rows=4 name='comment'>
 </textarea>
 <br />