--- loncom/publisher/lonpubdir.pm	2008/08/08 10:08:48	1.110
+++ loncom/publisher/lonpubdir.pm	2011/10/21 18:04:51	1.128
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Construction Space Directory Lister
 #
-# $Id: lonpubdir.pm,v 1.110 2008/08/08 10:08:48 bisitz Exp $
+# $Id: lonpubdir.pm,v 1.128 2011/10/21 18:04:51 www Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -47,73 +47,50 @@ sub handler {
 
   my $r=shift;
 
-  my $fn;
-
-
-
-  $fn = getEffectiveUrl($r);
-
   # Validate access to the construction space and get username@domain.
 
   my $uname;
   my $udom;
 
-  ($uname,$udom)=
-    &Apache::loncacc::constructaccess(
-             $fn,$r->dir_config('lonDefDomain')); 
+  ($uname,$udom)=&Apache::loncacc::constructaccess($r->uri); 
   unless (($uname) && ($udom)) {
-     $r->log_reason($uname.' at '.$udom.
-         ' trying to list directory '.$env{'form.filename'}.
-         ' ('.$fn.') - not authorized', 
-         $r->filename); 
      return HTTP_NOT_ACCEPTABLE;
   }
 
-  # Remove trailing / from directory name.
+# ----------------------------------------------------------- Start page output
 
+  my $fn=$r->filename;
   $fn=~s/\/$//;
 
-  unless ($fn) { 
-     $r->log_reason($env{'user.name'}.' at '.$env{'user.domain'}.
-         ' trying to list empty directory', $r->filename); 
-     return HTTP_NOT_FOUND;
-  } 
-
-# ----------------------------------------------------------- Start page output
-
   my $thisdisfn=$fn;
-  $thisdisfn=~s/^\/home\/$uname\/public_html//;	# subdirectory part of
-                                                # construction space. 
   my $docroot=$r->dir_config('lonDocRoot');     # Apache  londocument root.
+  $thisdisfn=~s/^\Q$docroot\E\/priv//;
 
-  my $resdir=$docroot.'/res/'.$udom.'/'.$uname.$thisdisfn; # Resource directory
-  my $targetdir=$udom.'/'.$uname.$thisdisfn; # Publiction target directory.
-  my $linkdir='/priv/'.$uname.$thisdisfn;      # Full URL name of constr space.
+  my $resdir=$docroot.'/res'.$thisdisfn; # Resource directory
+  my $targetdir='/res'.$thisdisfn; # Publication target directory.
+  my $linkdir='/priv'.$thisdisfn;      # Full URL name of constr space.
 
   my %bombs=&Apache::lonmsg::all_url_author_res_msg($uname,$udom);
 
   &startpage($r, $uname, $udom, $thisdisfn);   # Put out the start of page.
-  if ($env{'environment.remote'} eq 'off') {
-      &dircontrols($r,$uname,$udom,$thisdisfn);    # Put out actions for directory, 
+  &dircontrols($r,$uname,$udom,$thisdisfn);    # Put out actions for directory, 
                                                # browse/upload + new file page.
-  } else {
-      &pubbuttons($r,$uname,$thisdisfn);
-  }
   &resourceactions($r,$uname,$udom,$thisdisfn); #Put out form used for printing/deletion etc.
 
   my $numdir = 0;
   my $numres = 0;
   
   # Start off the directory table.
-  $r->print('<h3>'.&mt('Directory Contents:').'</h3>');
-  $r->print('<table id="LC_browser"><tr>'.
-            '<th>'.&mt('Type').'</th>'.
-            '<th>'.&mt('Actions').'</th>'.
-            '<th>'.&mt('Name').'</th>'.
-            '<th>'.&mt('Title').'</th>'.
-	    '<th>'.&mt('Status').'</th>'.
-            '<th>'.&mt('Last Modified').
-	    '</th></tr>'."\n");
+  $r->print(&Apache::loncommon::start_data_table()
+           .&Apache::loncommon::start_data_table_header_row()
+           .'<th>'.&mt('Type').'</th>'
+           .'<th>'.&mt('Actions').'</th>'
+           .'<th>'.&mt('Name').'</th>'
+           .'<th>'.&mt('Title').'</th>'
+           .'<th colspan="2">'.&mt('Status').'</th>'
+           .'<th>'.&mt('Last Modified').'</th>'
+           .&Apache::loncommon::end_data_table_header_row()
+  );
 
   my $filename;
   my $dirptr=16384;		# Mask indicating a directory in stat.cmode.
@@ -139,44 +116,12 @@ sub handler {
   }
   closedir(DIR);
 
-  $r->print('</table>'.&Apache::loncommon::end_page());
+  $r->print(&Apache::loncommon::end_data_table()
+           .&Apache::loncommon::end_page()
+  );
   return OK;  
 }
-#
-#  Gets the effective URL of the request and returns it:
-#    $effn = getEffectiveUrl($r);
-#       $r  - The Apache Request object.
-sub getEffectiveUrl {
-    my $r = shift;
-    my $fn;
-    
-    if ($env{'form.filename'}) {	# If a form filename is defined.
-	$fn=$env{'form.filename'};
-	#
-	#   Replace the ~username of the URL with /home/username/public_html
-	#   so that we don't have to worry about ~ expansion internally.
-	#
-	$fn=~s/^http\:\/\/[^\/]+\///;
-        $fn=~s/^\///;
-        $fn=~s{~($LONCAPA::username_re)}{/home/$1/public_html};
-	
-	#  Remove trailing / strings (?) 
-	
-	$fn=~s/\/[^\/]+$//;
-    } else {
-	#   If no form is defined, use request filename.
-	$fn = $r->filename();
-	my $lonDocRoot=$r->dir_config('lonDocRoot');
-	if ( $fn =~ /$lonDocRoot/ ) {
-	    #internal authentication, needs fixup.
-	    $fn = $r->uri(); # non users do not get the full path request
-                             # through SCRIPT_FILENAME
-	    $fn=~s{^/~($LONCAPA::username_re)}{/home/$1/public_html};
-	}
-    }
-    $fn=~s/\/+/\//g;
-    return $fn;
-}
+
 #
 #   Output the header of the page.  This includes:
 #   - The HTML header 
@@ -196,25 +141,21 @@ sub startpage {
 
     my $formaction='/priv/'.$uname.$thisdisfn.'/';
     $formaction=~s|/+|/|g;
-    my $pagetitle .= &Apache::loncommon::help_open_menu('','',3,'Authoring').
-        '<font face="Arial, Helvetica, sans-serif" size="+1"><b>'.&mt('Construction Space').'</b>:</font>&nbsp;'.
-        '<form name="dirs" method="post" action="'.$formaction.
-        '" target="_parent"><tt><b>'.
-        &Apache::lonhtmlcommon::crumbs($uname.$thisdisfn.'/','_top','/priv','','+1',1)."</b></tt><br />".
-        &Apache::lonhtmlcommon::select_recent('construct','recent',
-                 'this.form.action=this.form.recent.value;this.form.submit()').
-              '</form>';
     &Apache::lonhtmlcommon::store_recent('construct',$formaction,$formaction);
-    if ($env{'environment.remote'} eq 'off') {
-	$env{'request.noversionuri'}=$currdir.'/';
-	$r->print(&Apache::loncommon::start_page('Construction Space',undef,
-						 {'body_title' =>
-						      $pagetitle,}));
-    } else {
-	$r->print(&Apache::loncommon::start_page('Construction Space',undef,
-						 { 'only_body' => 1,}));
-	$r->print($pagetitle);
-    }
+
+    &Apache::lonhtmlcommon::clear_breadcrumbs();
+    &Apache::lonhtmlcommon::add_breadcrumb({
+        'text'  => 'Construction Space',
+        'href'  => &Apache::loncommon::authorspace(),
+    });
+    # breadcrumbs (and tools) will be created 
+    # in start_page->bodytag->innerregister
+
+    $env{'request.noversionuri'}=$currdir.'/';
+    $r->print(&Apache::loncommon::start_page('Construction Space',undef));
+
+    $r->print(&Apache::loncommon::head_subbox(
+                &Apache::loncommon::CSTR_pageheader(1)));
 
     my $esc_thisdisfn = &Apache::loncommon::escape_single($thisdisfn);
     my $doctitle = 'LON-CAPA '.&mt('Construction Space');
@@ -233,7 +174,7 @@ parent.lastknownpriv='/~$uname$esc_thisd
             document.publishdir.filename.value = theform.filename.value;
 	    document.publishdir.submit();
         }
-        if (theform.dirtask.options[theform.dirtask.selectedIndex].value == 'editcat') {
+        if (theform.dirtask.options[theform.dirtask.selectedIndex].value == 'editmeta') {
             top.location=theform.filename.value+'default.meta'
         }
         if (theform.dirtask.options[theform.dirtask.selectedIndex].value == 'printdir' ) {
@@ -263,7 +204,7 @@ parent.lastknownpriv='/~$uname$esc_thisd
         if (theform.diraction.options[theform.diraction.selectedIndex].value == "publish") {
             theform.submit();
         }
-        if (theform.diraction.options[theform.diraction.selectedIndex].value == "editcat") {
+        if (theform.diraction.options[theform.diraction.selectedIndex].value == "editmeta") {
             top.location=theform.filename.value+'default.meta'
         }
         if (theform.diraction.options[theform.diraction.selectedIndex].value == "printdir") {
@@ -327,12 +268,6 @@ parent.lastknownpriv='/~$uname$esc_thisd
 </script>
 ENDPUBDIRSCRIPT
     $r->print($pubdirscript);
-
-    if ((($uname ne $env{'user.name'}) || ($udom ne $env{'user.domain'})) &&
-	$env{'environment.remote'} ne 'off') {
-	$r->print('<h3>'.&mt('Co-Author').': '.$uname.' at '.$udom.
-		  '</h3>');
-    }
 }
 
 sub dircontrols {
@@ -348,7 +283,7 @@ sub dircontrols {
                                        list => 'List Directory',
                                        uplo => 'Upload file',  
                                        dele => 'Delete',
-                                       edit => 'Edit Catalog Information', 
+                                       edit => 'Edit Metadata', 
                                        sela => 'Select Action',
                                        nfil => 'New file',
                                        nhtm => 'New HTML file',
@@ -373,42 +308,46 @@ sub dircontrols {
                                       );
     my $mytype = $lt{'type'}; # avoid conflict with " and ' in javascript
     $r->print(<<END);
-        <table id="LC_cstr_controls">
-         <tr>
-          <th>$lt{'acti'}</th>
-          <th>$lt{'updc'}</th>
-          <th>$lt{'crea'}</th>
-        </tr>
-        <tr>
-         <td>
-          <form name="curractions" method="post" action="">
-           <select name="dirtask" onchange="currdiract(this.form)">
+<div class="LC_columnSection">
+  <div>
+    <form name="curractions" method="post" action="">
+      <fieldset>
+        <legend>$lt{'acti'}</legend>
+        <select name="dirtask" onchange="currdiract(this.form)">
             <option>$lt{'sela'}</option>
             <option value="publish">$lt{'pubd'}</option>
-            <option value="editcat">$lt{'edit'}</option>
+            <option value="editmeta">$lt{'edit'}</option>
             <option value="printdir">$lt{'prnt'}</option>
             <option value="delete">$lt{'dedr'}</option>
-           </select>
-           <input type="hidden" name="filename" value="/~$uname$thisdisfn/" />
-          </form>
-          <form name="publishdir" method="post" action="/adm/publish" target="_parent">
-           <input type="hidden" name="pubrec" value="" />
-           <input type="hidden" name="filename" value="" />
-          </form>
-          <form name="printdir" method="post" action="/adm/printout" target="_parent">
-           <input type="hidden" name="postdata" value="" />
-          </form>
-         </td>
-         <td>
-	    <form name="upublisher" enctype="multipart/form-data" method="post" action="/adm/upload" target="_parent">
-	      <input type="hidden" name="filename" value="/~$uname$thisdisfn/" />
-	      <input type="file" name="upfile" size="20" />
-	      <input type="button" value="$lt{'uplo'}"  onclick="checkUpload(this.form)" />
-	    </form>
-	 </td>
-	 <td>
-	    <form name="fileaction" method="post" action="/adm/cfile" target="_parent">
-	      <span style="white-space: nowrap">
+        </select>
+        <input type="hidden" name="filename" value="/~$uname$thisdisfn/" />
+      </fieldset>
+    </form>
+    <form name="publishdir" method="post" action="/adm/publish" target="_parent">
+      <input type="hidden" name="pubrec" value="" />
+      <input type="hidden" name="filename" value="" />
+    </form>
+    <form name="printdir" method="post" action="/adm/printout" target="_parent">
+      <input type="hidden" name="postdata" value="" />
+    </form>
+  </div>
+
+  <div>
+    <form name="upublisher" enctype="multipart/form-data" method="post" action="/adm/upload" target="_parent">
+      <fieldset>
+        <legend>$lt{'updc'}</legend>
+        <input type="hidden" name="filename" value="/~$uname$thisdisfn/" />
+        <input type="file" name="upfile" size="20" />
+        <input type="button" value="$lt{'uplo'}"  onclick="checkUpload(this.form)" />
+      </fieldset>
+    </form>
+  </div>
+
+  <div>
+    <form name="fileaction" method="post" action="/adm/cfile" target="_parent">
+      <fieldset>
+              <legend>$lt{'crea'}</legend>
+	      <span class="LC_nobreak">
 		<input type="hidden" name="filename" value="/~$uname$thisdisfn/" />
                   <script type="text/javascript">
                     function validate_go() {
@@ -434,24 +373,13 @@ sub dircontrols {
 	            <option value="newdir">$lt{'nsub'}:</option>
 		  </select>&nbsp;<input type="text" name="newfilename" value="$lt{'type'}" onfocus="if (this.value == '$mytype') this.value=''" />&nbsp;<input type="button" value="Go" onclick="validate_go();" />
 		 </span>
-		</form>
-	  </td>
-         </tr>
-        </table>
+      </fieldset>
+    </form>
+  </div>
+</div>
 END
 }
 
-sub pubbuttons {
-    my ($r,$uname,$thisdisfn) = @_;
-    $r->print('<form method="post" action="/adm/publish" target="_parent">'.
-              '<table><tr><td><input type="hidden" name="filename" value="/~'.
-               $uname.$thisdisfn.'/" />'.
-              '<input type="submit" value="'.&mt('Publish Directory').'" /></td><td>'.
-'<input type="button" onclick="window.location='."'/~".
-               $uname.$thisdisfn."/default.meta'".'" value="'.
-&mt('Edit Directory Catalog Information').'" /></td></tr></table></form>');
-}
-
 sub resourceactions {
     my ($r,$uname,$udom,$thisdisfn) = @_;
     $r->print(<<END);
@@ -550,7 +478,7 @@ sub putdirectory {
                       '<option selected="selected">'.&mt('Select action').'</option>'.
                       '<option value="open">'.&mt('Open').'</option>'.
                       '<option value="publish">'.&mt('Publish').'</option>'.
-                      '<option value="editcat">'.&mt('Edit catalog information').'</option>'.
+                      '<option value="editmeta">'.&mt('Edit Metadata').'</option>'.
                       '<option value="printdir">'.&mt('Print directory').'</option>'.
                       '<option value="delete">'.&mt('Delete directory').'</option>'.
                     '</select>'.
@@ -562,11 +490,11 @@ sub putdirectory {
         }
 	$r->print('<tr class="LC_browser_folder">'.
 		  '<td><img src="'.
-		  $Apache::lonnet::perlvar{'lonIconsURL'}.'/folder_closed.gif" alt="folder" /></td>'.
+		  $Apache::lonnet::perlvar{'lonIconsURL'}.'/navmap.folder.closed.gif" alt="folder" /></td>'.
 		  '<td>'.$actionitem.'</td>'.
 		  '<td><span class="LC_filename"><a href="'.&HTML::Entities::encode($here.'/'.$dirname,'<>&"').'/" target="_parent">'.
 		  $disfilename.'</a></span></td>'.
-		        '<td colspan="2">'.($kaputt?&Apache::lonhtmlcommon::authorbombs($resdir.'/'.$disfilename.'/'):'').$Apache::lonpublisher::metadatafields{'title'});
+		        '<td colspan="3">'.($kaputt?&Apache::lonhtmlcommon::authorbombs($resdir.'/'.$disfilename.'/'):'').$Apache::lonpublisher::metadatafields{'title'});
 	if ($Apache::lonpublisher::metadatafields{'subject'} ne '') {
 	    $r->print(' <i>'.
 		      $Apache::lonpublisher::metadatafields{'subject'}.
@@ -621,9 +549,17 @@ sub putresource {
 	    $meta_same = 0;
 	}
 	$publish_button=&mt('Re-publish');
-	my $rights_status =
-	    &mt(&getCopyRightString($targetdir.'/'.$filename)).' '.
-	    &mt(&getSourceRightString($targetdir.'/'.$filename));
+
+        my $rights_status =
+            &mt(&getCopyRightString($targetdir.'/'.$filename)).', ';
+
+        my %lt_SourceRight = &Apache::lonlocal::texthash(
+               'open'   => 'Source: open',
+               'closed' => 'Source: closed',
+        );
+        $rights_status .=
+            $lt_SourceRight{&getSourceRightString($targetdir.'/'.$filename)};
+
 	$title = '<a href="/res/'.$targetdir.'/'.$filename.
 	    '.meta" target="cat">'.
 	    &getTitleString($targetdir.'/'.$filename).'</a>';
@@ -688,7 +624,7 @@ sub putresource {
     }
     my $pub_select = '';
     &create_pubselect($r,\$pub_select,$udom,$uname,$thisdisfn,$filename,$resdir,$pubstatus,$publish_button,$numres);
-    $r->print('<tr class="LC_browser_file_'.$pubstatus.'">'.
+    $r->print(&Apache::loncommon::start_data_table_row().
 	      '<td>'.($filename=~/[\#\~]$/?'&nbsp;':
 		      '<img src="'.&Apache::loncommon::icon($filename).'" alt="" />').'</td>'.
               '<td>'.$pub_select.'</td>'.
@@ -697,9 +633,11 @@ sub putresource {
                $filename.'</a></span>'.$editlink2.$editlink.
 	      '</td>'.
 	      '<td>'.$title.'</td>'.
-	      '<td>'.$status.'</td>'.
+              '<td class="LC_browser_file_'.$pubstatus.'">&nbsp;&nbsp;</td>'. # Display publication status
+              '<td>'.$status.'</td>'.
 	      '<td>'.&Apache::lonlocal::locallocaltime($cmtime).'</td>'.
-	      "</tr>\n");
+	      &Apache::loncommon::end_data_table_row()
+    );
     return OK;
 }
 
@@ -785,6 +723,7 @@ sub CategorizeFiles {
 1;
 __END__
 
+
 =head1 NAME
 
 Apache::lonpubdir - Construction space directory lister
@@ -840,4 +779,64 @@ run through list of files and attempt to
 
 =back
 
+=head1 SUBROUTINES:
+
+=over
+
+=item startpage($r, $uame, $udom, $thisdisfn)
+
+Output the header of the page.  This includes:
+ - The HTML header 
+ - The H1/H3  stuff which includes the directory.
+ 
+    startpage($r, $uame, $udom, $thisdisfn);
+        $r     - The apache request object.
+        $uname - User name.
+        $udom  - Domain name the user is logged in under.
+        $thisdisfn - Displayable version of the filename.
+
+=item getTitleString($fullname)
+
+    Get the title string or "[untitled]" if the file has no title metadata:
+    Without the latter substitution, it's impossible to examine metadata for
+    untitled resources.  Resources may be legitimately untitled, to prevent
+    searches from locating them.
+    
+    $str = getTitleString($fullname);
+        $fullname - Fully qualified filename to check.
+
+=item putdirectory(r, base, here, dirname, modtime)
+
+    Put out a directory table row:
+    
+    putdirectory($r, $base, $here, $dirname, $modtime)
+        $r       - Apache request object.
+        $reqfile - File in request.
+        $here    - Where we are in directory tree.
+        $dirname - Name of directory special file.
+        $modtime - Encoded modification time.
+
+=item CategorizeFiles($location, $files)
+    
+    Categorize files in the directory.
+    For each file in a list of files in a file directory, 
+    the  file categorized as one of:
+        - directory  
+        - sequence
+        - problem 
+        - Other resource.
+
+    For each file the modification date is determined as well.
+    Returned is a list of sublists:
+        (directories, sequences, problems, other)
+    each of the sublists contains entries of the following form (sorted by filename):
+    (filename, typecode, lastmodtime)
+    
+        $list = CategorizeFiles($location, $files)
+        $location   - Directory in which the files live (relative to our execution)
+        $files      - list of files.
+
+=back
+
 =cut
+