[LON-CAPA-cvs] cvs: loncom /publisher lonpubdir.pm

musolffc musolffc at source.lon-capa.org
Mon Apr 21 17:26:42 EDT 2014


musolffc		Mon Apr 21 21:26:42 2014 EDT

  Modified files:              
    /loncom/publisher	lonpubdir.pm 
  Log:
  Resources in authoring space can now be sorted by Type, Title, Status, and Size.  Reverse sorting is also possible by re-selecting a column heading.
  
  The size of files is displayed in kB.  Including the recursive size of directories proved to be too slow.  The following simple functions were added:
  getTitle
  getStatus
  isMetaSame
  
  
-------------- next part --------------
Index: loncom/publisher/lonpubdir.pm
diff -u loncom/publisher/lonpubdir.pm:1.151 loncom/publisher/lonpubdir.pm:1.152
--- loncom/publisher/lonpubdir.pm:1.151	Sun Apr  6 19:39:04 2014
+++ loncom/publisher/lonpubdir.pm	Mon Apr 21 21:26:41 2014
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Authoring Space Directory Lister
 #
-# $Id: lonpubdir.pm,v 1.151 2014/04/06 19:39:04 raeburn Exp $
+# $Id: lonpubdir.pm,v 1.152 2014/04/21 21:26:41 musolffc Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -44,119 +44,196 @@
 
 sub handler {
 
-  my $r=shift;
+    my $r=shift;
 
-  # Validate access to the construction space and get username:domain.
+    # Validate access to the construction space and get username:domain.
 
-  my $uname;
-  my $udom;
+    my $uname;
+    my $udom;
 
-  ($uname,$udom)=&Apache::lonnet::constructaccess($r->uri); 
-  unless (($uname) && ($udom)) {
-     return HTTP_NOT_ACCEPTABLE;
-  }
+    ($uname,$udom)=&Apache::lonnet::constructaccess($r->uri); 
+    unless (($uname) && ($udom)) {
+        return HTTP_NOT_ACCEPTABLE;
+    }
 
 # ----------------------------------------------------------- Start page output
 
-  my $fn=$r->filename;
-  $fn=~s/\/$//;
+    my $fn=$r->filename;
+    $fn=~s/\/$//;
+    my $thisdisfn=$fn;
 
-  my $thisdisfn=$fn;
-  my $docroot=$r->dir_config('lonDocRoot');     # Apache  londocument root.
-  $thisdisfn=~s/^\Q$docroot\E\/priv//;
-
-  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.
-  &dircontrols($r,$uname,$udom,$thisdisfn);    # Put out actions for directory, 
-                                               # browse/upload + new file page.
-  &resourceactions($r,$uname,$udom,$thisdisfn); #Put out form used for printing/deletion etc.
+    my $docroot=$r->dir_config('lonDocRoot');     # Apache  londocument root.
+    $thisdisfn=~s/^\Q$docroot\E\/priv//;
+    
+    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.
+    &dircontrols($r,$uname,$udom,$thisdisfn);   # Put out actions for directory, 
+                                                # browse/upload + new file page.
+    &resourceactions($r,$uname,$udom,$thisdisfn); # Put out form used for printing/deletion etc.
 
-  my $numdir = 0;
-  my $numres = 0;
+    my $numdir = 0;
+    my $numres = 0;
   
-  # Retrieving value for sortby from QUERY_STRING
-  &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['sortby']);
+    # Retrieving value for "sortby" and "sortorder" from QUERY_STRING
+    &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
+        ['sortby','sortorder']);
+
+    # Sort by name as default, not reversed
+    if (! exists($env{'form.sortby'})) { $env{'form.sortby'} = 'filename' }
+    if (! exists($env{'form.sortorder'})) { $env{'form.sortorder'} = '' }
+
+    my $sortby = $env{'form.sortby'};
+    my $sortorder = $env{'form.sortorder'};
+
+    # Start off the directory table.
+    $r->print(&Apache::loncommon::start_data_table()
+        .&Apache::loncommon::start_data_table_header_row()
+        .'<th><a href="'.$linkdir.'/?sortby=filetype&sortorder='
+            .((($sortby eq "filetype") && ($sortorder ne 'rev')) ? 'rev' : '') 
+            .'">'.&mt('Type')
+            .'<span class="LC_fontsize_small"> ▼</span></a></th>'
+        .'<th>'.&mt('Actions').'</th>'
+        .'<th><a href="'.$linkdir.'/?sortby=filename&sortorder='
+            .((($sortby eq "filename") && ($sortorder ne 'rev')) ? 'rev' : '') 
+            .'">'.&mt('Name')
+            .'<span class="LC_fontsize_small"> ▼</span></a></th>'
+        .'<th><a href="'.$linkdir.'/?sortby=title&sortorder='
+            .((($sortby eq "title") && ($sortorder ne 'rev')) ? 'rev' : '') 
+            .'">'.&mt('Title')
+            .'<span class="LC_fontsize_small"> ▼</span></a></th>'
+        .'<th colspan="2"><a href="'.$linkdir.'/?sortby=pubstatus&sortorder='
+            .((($sortby eq "pubstatus") && ($sortorder ne 'rev')) ? 'rev' : '') 
+            .'">'.&mt('Status')
+            .'<span class="LC_fontsize_small"> ▼</span></a></th>'
+        .'<th><a href="'.$linkdir.'/?sortby=cmtime&sortorder='
+            .((($sortby eq "cmtime") && ($sortorder ne 'rev')) ? 'rev' : '') 
+            .'">'.&mt('Last Modified')
+            .'<span class="LC_fontsize_small"> ▼</span></a></th>'
+        .'<th><a href="'.$linkdir.'/?sortby=size&sortorder='
+            .((($sortby eq "size") && ($sortorder ne 'rev')) ? 'rev' : '') 
+            .'">'.&mt('Size').' (kB)'
+            .'<span class="LC_fontsize_small"> ▼</span></a></th>'
+        .&Apache::loncommon::end_data_table_header_row()
+    );
 
-  # Default sort by 'Name'
-  if (! exists($env{'form.sortby'})) {
-    $env{'form.sortby'} = 'filename';
-  }
-
-  # Start off the directory table.
-  $r->print(&Apache::loncommon::start_data_table()
-           .&Apache::loncommon::start_data_table_header_row()
-           .'<th>'.&mt('Type').'</th>'
-           .'<th>'.&mt('Actions').'</th>'
-           .'<th><a href="'.$linkdir.'/?sortby=filename">'.&mt('Name').'<span class="LC_fontsize_small"> ▼</span></a></th>'
-           .'<th>'.&mt('Title').'</th>'
-           .'<th colspan="2">'.&mt('Status').'</th>'
-           .'<th><a href="'.$linkdir.'/?sortby=cmtime">'.&mt('Last Modified').'<span class="LC_fontsize_small"> ▼</span></a></th>'
-           .&Apache::loncommon::end_data_table_header_row()
-  );
-
-  my $filename;
-  my $dirptr=16384;		# Mask indicating a directory in stat.cmode.
-
-  opendir(DIR,$fn);
-  my $filehash = {};
-  my $sortby = $env{'form.sortby'};
-  my @files=sort {uc($a) cmp uc($b)} (readdir(DIR));
-  foreach my $filename (@files) {
-     next if ($filename eq '.DS_Store');
-     my ($cmode,$cmtime)=(stat($fn.'/'.$filename))[2,9];
-     # If you want to sort by "last modified", we need to make this hash.
-     if ($sortby eq 'cmtime') {
-       $filehash->{ $filename } = {"cmtime" => $cmtime,};
-     }
-     # Otherwise sort by name.  Don't bother with filehash.  Continue printing contents.
-     else {
-         my $extension='';
-         if ($filename=~/\.(\w+)$/) { $extension=$1; }
-         if ($cmode&$dirptr) {
-             &putdirectory($r, $thisdisfn, $linkdir, $filename, $cmtime,$targetdir,\%bombs,\$numdir);
-         } elsif (&Apache::loncommon::fileembstyle($extension) ne 'hdn') {
-             &putresource($r, $udom, $uname, $filename, $thisdisfn, $resdir, 
-                         $targetdir, $linkdir, $cmtime,\%bombs,\$numres);
-         } else {
-            # "hidden" extension and not a directory, so hide it away.
-         }
-     }
-  };
-
-  # Sorting files by "last modified" if that's what you selected   
-  if ($sortby eq 'cmtime') {
-      my @sorted_files = sort {
-        $filehash->{$b}->{$sortby} <=> $filehash->{$a}->{$sortby}
-        } (keys(%{$filehash}));
-      foreach my $filename (@sorted_files) {
-         my ($cmode,$cmtime)=(stat($fn.'/'.$filename))[2,9];
-         my $extension='';
-         if ($filename=~/\.(\w+)$/) { $extension=$1; }
-         if ($cmode&$dirptr) {
-             &putdirectory($r, $thisdisfn, $linkdir, $filename, $cmtime,$targetdir,\%bombs,\$numdir);
-         } elsif (&Apache::loncommon::fileembstyle($extension) ne 'hdn') {
-             &putresource($r, $udom, $uname, $filename, $thisdisfn, $resdir, 
-                         $targetdir, $linkdir, $cmtime,\%bombs,\$numres);
-         } else {
-            # "hidden" extension and not a directory, so hide it away.
-         };
-      };
-  };
-  
-  closedir(DIR);
+    my $dirptr=16384;		# Mask indicating a directory in stat.cmode.
+
+    opendir(DIR,$fn);
+    my $filehash = {};
+    my @files= readdir(DIR);
+    foreach my $filename (@files) {
+        # Skip .DS_Store and hidden files
+        my ($extension) = ($filename=~/\.(\w+)$/);
+        next if (($filename eq '.DS_Store') 
+                || &Apache::loncommon::fileembstyle($extension) eq 'hdn');
+
+        my ($cmode,$csize,$cmtime)=(stat($fn.'/'.$filename))[2,7,9];
+        my $linkfilename = &HTML::Entities::encode('/priv'.$thisdisfn.'/'.$filename,'<>&"');
+        # Identify type of file according to icon used
+        my ($filetype) = (&Apache::loncommon::icon($filename) =~ m{/(\w+).gif$}); 
+        my $cstr_dir = $r->dir_config('lonDocRoot').'/priv'.$thisdisfn;
+        my $meta_same = &isMetaSame($cstr_dir, $resdir, $filename);
+        
+        # Store size, title, and status for files but not directories
+        my $size = (!($cmode&$dirptr)) ? $csize/1024. : 0;
+        my ($status, $pubstatus, $title, $fulltitle);
+        if (!($cmode&$dirptr)) {
+            ($status, $pubstatus) = &getStatus($resdir, $targetdir, $cstr_dir, 
+                $filename, $linkfilename, $cmtime, $meta_same);
+            ($fulltitle, $title) = &getTitle($resdir, $targetdir, $filename, 
+                                        $linkfilename, $meta_same, \%bombs);
+        } else {
+            ($status, $pubstatus) = ('','');
+            ($fulltitle, $title) = ('','');
+        }
+
+        # This hash will allow sorting
+        $filehash->{ $filename } = {
+            "cmtime"            => $cmtime,
+            "size"              => $size,
+            "cmode"             => $cmode,
+            "filetype"          => $filetype,
+            "title"             => $title,
+            "fulltitle"         => $fulltitle,
+            "status"            => $status,
+            "pubstatus"         => $pubstatus,
+            "linkfilename"      => $linkfilename,
+        }
+    }
+   
+    my @sorted_files;
+    # Sorting by something other than "Name".  Name is the secondary key.
+    if ($sortby =~ m{cmtime|size}) {    # Numeric fields
+        # First check if order should be reversed
+        if ($sortorder eq "rev") {
+            @sorted_files = sort {
+                $filehash->{$a}->{$sortby} <=> $filehash->{$b}->{$sortby}
+                    or
+                uc($a) cmp uc($b)
+            } (keys(%{$filehash}));
+        } else {
+            @sorted_files = sort {
+                $filehash->{$b}->{$sortby} <=> $filehash->{$a}->{$sortby}
+                    or
+                uc($a) cmp uc($b)
+            } (keys(%{$filehash}));
+        }
+    } elsif ($sortby =~ m{filetype|title|status}) {     # String fields
+        if ($sortorder eq "rev") {
+            @sorted_files = sort {
+                $filehash->{$b}->{$sortby} cmp $filehash->{$a}->{$sortby}
+                    or
+                uc($a) cmp uc($b)
+            } (keys(%{$filehash}));
+        } else {
+            @sorted_files = sort {
+                $filehash->{$a}->{$sortby} cmp $filehash->{$b}->{$sortby}
+                    or
+                uc($a) cmp uc($b)
+            } (keys(%{$filehash}));
+        }
+
+    # Sort by "Name" is the default
+    } else { 
+        if ($sortorder eq "rev") {
+            @sorted_files = sort {uc($b) cmp uc($a)} (keys(%{$filehash}));
+        } else {
+            @sorted_files = sort {uc($a) cmp uc($b)} (keys(%{$filehash}));
+        }
+    }
+
+    # Print the sorted resources
+    foreach my $filename (@sorted_files) {
+        if ($filehash->{$filename}->{"cmode"}&$dirptr) {        # Directories
+            &putdirectory($r, $thisdisfn, $linkdir, $filename, 
+                $filehash->{$filename}->{"cmtime"}, 
+                $targetdir, \%bombs, \$numdir);
+        } else {                                                # Files
+            &putresource($r, $udom, $uname, $filename, $thisdisfn, $resdir,
+                $targetdir, $linkdir, $filehash->{$filename}->{"cmtime"}, 
+                $filehash->{$filename}->{"size"}, \$numres, 
+                $filehash->{$filename}->{"linkfilename"},
+                $filehash->{$filename}->{"fulltitle"},
+                $filehash->{$filename}->{"status"},
+                $filehash->{$filename}->{"pubstatus"});
+        }
+    }
+
+    closedir(DIR);
+
+    $r->print( &Apache::loncommon::end_data_table()
+        .&Apache::loncommon::end_page() );
 
-  $r->print(&Apache::loncommon::end_data_table()
-           .&Apache::loncommon::end_page()
-  );
-  return OK;  
+    return OK;  
 }
 
-#
+
+
 #   Output the header of the page.  This includes:
 #   - The HTML header 
 #   - The H1/H3  stuff which includes the directory.
@@ -550,51 +627,71 @@
 	}
 	$r->print($Apache::lonpublisher::metadatafields{'keywords'}.'</td>'.
 		  '<td>'.&Apache::lonlocal::locallocaltime($modtime).'</td>'.
+	          '<td></td>'.
 		  "</tr>\n");
     }
     return OK;
 }
-#
-#   Put a table row for a file resource.
-#
-sub putresource {
-    my ($r, $udom, $uname, $filename, $thisdisfn, 
-	$resdir, $targetdir, $linkdir,
-	$cmtime,$bombs,$numres) = @_;
-    &Apache::lonnet::devalidate_cache_new('meta',$targetdir.'/'.$filename);
-    my $pubstatus = 'unpublished';
-    my $status=&mt('Unpublished');
-    my $css_class='LC_browser_file';
+
+sub getTitle {
+    my ($resdir, $targetdir, $filename, $linkfilename, $meta_same, $bombs) = @_;
     my $title='';
-    my $publish_button=&mt('Publish');
-    my $cstr_dir = $r->dir_config('lonDocRoot').'/priv'.$thisdisfn;
-    my $linkfilename=&HTML::Entities::encode('/priv'.$thisdisfn.'/'.$filename,'<>&"');
+    my $titleString = &getTitleString($targetdir.'/'.$filename);
+    if (-e $resdir.'/'.$filename) {
+	$title = '<a href="'.$targetdir.'/'.$filename.
+	    '.meta" target="cat">'.$titleString.'</a>';
+        if (!$meta_same) {
+	    $title = &mt('Metadata Modified').'<br />'.$title.
+		'<br />'.
+                &Apache::loncommon::modal_link(
+                    '/adm/diff?filename='.$linkfilename.'.meta'.'&versiontwo=priv',
+                    &mt('Metadata Diffs'),600,500);
+	    $title.="\n".'<br />'.
+                &Apache::loncommon::modal_link(
+                    '/adm/retrieve?filename='.$linkfilename.'.meta&inhibitmenu=yes&add_modal=yes',
+                    &mt('Retrieve Metadata'),600,500);
+        } 
+    }
+    # Allow editing metadata of published and unpublished resources
+    $title .= "\n".'<br />' if ($title);
+    $title .= '<a href="'.$linkfilename.'.meta">'.
+              ($$bombs{&Apache::lonnet::declutter($targetdir.'/'.$filename)}?
+                  '<img src="/adm/lonMisc/bomb.gif" border="0" alt="'.&mt('bomb').'" />':
+                  &mt('Edit Metadata')).
+              '</a>';
+
+    return ($title, $titleString);
+}
+
+
+sub isMetaSame {
+    my ($cstr_dir, $resdir, $filename) = @_;
+    my $meta_cmtime = (stat($cstr_dir.'/'.$filename.'.meta'))[9];
+    my $meta_rmtime = (stat($resdir.'/'.$filename.'.meta'))[9];
+    return (&Apache::londiff::are_different_files($resdir.'/'.$filename.'.meta',
+            $cstr_dir.'/'.$filename.'.meta') && $meta_rmtime < $meta_cmtime) 
+        ? 0 : 1;
+}
+    
+
+sub getStatus {    
+    my ($resdir, $targetdir, $cstr_dir, $filename,  
+            $linkfilename, $cmtime, $meta_same) = @_;
+    my $pubstatus = 'unpublished';
+    my $status = &mt('Unpublished');
 
     if (-e $resdir.'/'.$filename) {
-        my $same=0;
-	my ($rdev,$rino,$rmode,$rnlink,
-	    $ruid,$rgid,$rrdev,$rsize,
-	    $ratime,$rmtime,$rctime,
-	    $rblksize,$rblocks)=stat($resdir.'/'.$filename);
-        if ($rmtime>=$cmtime) {
-           $same=1;
+        my $same = 0;
+        if ((stat($resdir.'/'.$filename))[9] >= $cmtime) {
+            $same = 1;
         } else {
            if (&Apache::londiff::are_different_files($resdir.'/'.$filename,
 						     $cstr_dir.'/'.$filename)) {
-              $same=0;
+              $same = 0;
            } else {
-              $same=1;
+              $same = 1;
            }
         }
-	my $meta_cmtime = (stat($cstr_dir.'/'.$filename.'.meta'))[9];
-	my $meta_rmtime = (stat($resdir.'/'.$filename.'.meta'))[9];
-	my $meta_same = 1;
-	if ($meta_rmtime < $meta_cmtime
-	    && &Apache::londiff::are_different_files($resdir.'/'.$filename.'.meta',
-						     $cstr_dir.'/'.$filename.'.meta')) {
-	    $meta_same = 0;
-	}
-	$publish_button=&mt('Re-publish');
 
         my $rights_status =
             &mt(&getCopyRightString($targetdir.'/'.$filename)).', ';
@@ -606,9 +703,6 @@
         $rights_status .=
             $lt_SourceRight{&getSourceRightString($targetdir.'/'.$filename)};
 
-	$title = '<a href="'.$targetdir.'/'.$filename.
-	    '.meta" target="cat">'.
-	    &getTitleString($targetdir.'/'.$filename).'</a>';
 	if ($same) {
 	    if (&Apache::lonnet::metadata($targetdir.'/'.$filename,'obsolete')) {
                 $pubstatus = 'obsolete';
@@ -633,28 +727,24 @@
                              &mt('Diffs'),600,500);
 	    }
 	} 
-	if (!$meta_same) {
-	    $title = &mt('Metadata Modified').'<br />'.$title.
-		'<br />'.
-                &Apache::loncommon::modal_link(
-                    '/adm/diff?filename='.$linkfilename.'.meta'.'&versiontwo=priv',
-                    &mt('Metadata Diffs'),600,500);
-	    $title.="\n".'<br />'.
-                &Apache::loncommon::modal_link(
-                    '/adm/retrieve?filename='.$linkfilename.'.meta&inhibitmenu=yes&add_modal=yes',
-                    &mt('Retrieve Metadata'),600,500);
-	}
+
 	$status.="\n".'<br />'.
              &Apache::loncommon::modal_link(
                  '/adm/retrieve?filename='.$linkfilename.'&inhibitmenu=yes&add_modal=yes',&mt('Retrieve'),600,500);
     }
-    # Allow editing metadata of published and unpublished resources
-    $title .= "\n".'<br />' if ($title);
-    $title .= '<a href="'.$linkfilename.'.meta">'.
-              ($$bombs{&Apache::lonnet::declutter($targetdir.'/'.$filename)}?
-                  '<img src="/adm/lonMisc/bomb.gif" border="0" alt="'.&mt('bomb').'" />':
-                  &mt('Edit Metadata')).
-              '</a>';
+
+    return ($status, $pubstatus);
+}
+
+
+#
+#   Put a table row for a file resource.
+#
+sub putresource {
+    my ($r, $udom, $uname, $filename, $thisdisfn, $resdir, $targetdir, 
+            $linkdir, $cmtime, $size, $numres, $linkfilename, $title, 
+            $status, $pubstatus) = @_;
+    &Apache::lonnet::devalidate_cache_new('meta',$targetdir.'/'.$filename);
 
     my $editlink='';
     my $editlink2='';
@@ -671,6 +761,7 @@
     if ($filename=~/\.(zip|tar|bz2|gz|tar.gz|tar.bz2|tgz)$/) {
 	$editlink=' (<a target="_parent" href="/adm/cfile?decompress='.$linkfilename.'">'.&mt('Decompress').'</a>)';
     }
+    my $publish_button = (-e $resdir.'/'.$filename) ? &mt('Re-publish') : &mt('Publish');
     my $pub_select = '';
     &create_pubselect($r,\$pub_select,$udom,$uname,$thisdisfn,$filename,$resdir,$pubstatus,$publish_button,$numres);
     $r->print(&Apache::loncommon::start_data_table_row().
@@ -685,6 +776,7 @@
               '<td class="LC_browser_file_'.$pubstatus.'">  </td>'. # Display publication status
               '<td>'.$status.'</td>'.
 	      '<td>'.&Apache::lonlocal::locallocaltime($cmtime).'</td>'.
+	      '<td>'.sprintf "%.1f", $size.'</td>'.
 	      &Apache::loncommon::end_data_table_row()
     );
     return OK;
@@ -846,4 +938,3 @@
 =back
 
 =cut
-


More information about the LON-CAPA-cvs mailing list