Modules | Files | Inheritance Tree | Inheritance Graph | Name Index | Config
File: Synopsis/Formatter/HTML/DirBrowse.py
    1| # $Id: DirBrowse.py,v 1.6 2002/11/13 03:17:19 chalky Exp $
    2| #
    3| # This file is a part of Synopsis.
    4| # Copyright (C) 2000, 2001 Stephen Davies
    5| # Copyright (C) 2000, 2001 Stefan Seefeld
    6| #
    7| # Synopsis is free software; you can redistribute it and/or modify it
    8| # under the terms of the GNU General Public License as published by
    9| # the Free Software Foundation; either version 2 of the License, or
   10| # (at your option) any later version.
   11| #
   12| # This program is distributed in the hope that it will be useful,
   13| # but WITHOUT ANY WARRANTY; without even the implied warranty of
   14| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   15| # General Public License for more details.
   16| #
   17| # You should have received a copy of the GNU General Public License
   18| # along with this program; if not, write to the Free Software
   19| # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   20| # 02111-1307, USA.
   21| #
   22| # $Log: DirBrowse.py,v $
   23| # Revision 1.6  2002/11/13 03:17:19  chalky
   24| # Fix directory heading links when using Nested layout
   25| #
   26| # Revision 1.5  2002/11/13 02:29:24  chalky
   27| # Support exclude_glob option to exclude files from listings. Remove debug info.
   28| #
   29| # Revision 1.4  2002/11/13 01:01:49  chalky
   30| # Improvements to links when using the Nested file layout
   31| #
   32| # Revision 1.3  2002/11/11 15:19:33  chalky
   33| # More fixes to get demo/C++ sxr working without frames
   34| #
   35| # Revision 1.2  2002/11/11 15:04:05  chalky
   36| # Fix bugs when start directory is ''
   37| #
   38| # Revision 1.1  2002/11/02 06:37:37  chalky
   39| # Allow non-frames output, some refactoring of page layout, new modules.
   40| #
   41| 
   42| 
   43| # System modules
   44| import os, stat, statcache, os.path, string, time
   45| 
   46| # Synopsis modules
   47| from Synopsis.Core import AST, Util
   48| 
   49| # HTML modules
   50| import Page
   51| import core
   52| from core import config
   53| from Tags import *
   54| 
   55| class DirBrowse(Page.Page):
   56|     """A page that shows the entire contents of directories, in a form similar
   57|     to LXR."""
   58|     def __init__(self, manager):
   59|         Page.Page.__init__(self, manager)
   60|         self.__filename = config.files.nameOfSpecial('dir')
   61|         self.__title = 'Directory Listing'
   62|         self.__base = config.base_dir
   63|         self.__start = config.start_dir
   64|         self.__exclude_globs = config.exclude_globs
   65| 
   66|     def filename(self):
   67|         """since FileTree generates a whole file hierarchy, this method returns the current filename,
   68|         which may change over the lifetime of this object"""
   69|         return self.__filename
   70|     def title(self):
   71|         """since FileTree generates a while file hierarchy, this method returns the current title,
   72|         which may change over the lifetime of this object"""
   73|         return self.__title
   74| 
   75|     def filename_for_dir(self, dir):
   76|         """Returns the output filename for the given input directory"""
   77|         if dir is self.__start:
   78|             return config.files.nameOfSpecial('dir')
   79|         scope = string.split(rel(self.__start, dir), os.sep)
   80|         return config.files.nameOfScopedSpecial('dir', scope)
   81| 
   82|     def register(self):
   83|         """Registers a page for each file in the hierarchy"""
   84|         #if not self.__base: return
   85|         config.set_main_page(self.__filename)
   86|         self.__filename = config.files.nameOfSpecial('dir')
   87|         self.manager.addRootPage(self.__filename, 'Files', 'main', 2)
   88| 
   89|     def register_filenames(self, start):
   90|         """Registers a page for every directory"""
   91|         dirs = [self.__start]
   92|         while dirs:
   93|             dir = dirs.pop(0)
   94|             for entry in os.listdir(os.path.abspath(dir)):
   95|                # Check if entry is in exclude list
   96|                exclude = 0
   97|                for re in self.__exclude_globs:
   98|                    if re.match(entry):
   99|                exclude = 1
  100|                if exclude:
  101|                continue
  102|                entry_path = os.path.join(dir, entry)
  103|                info = statcache.stat(entry_path)
  104|                if not stat.S_ISDIR(info[stat.ST_MODE]):
  105|                continue
  106|                filename = self.filename_for_dir(dir)
  107|                self.manager.register_filename(filename, self, entry_path)
  108|    
  109|     def process(self, start):
  110|         """Recursively visit each directory below the base path given in the
  111|         config."""
  112|         #if not self.__base: return
  113|         self.process_dir(self.__start)
  114|     
  115|     def process_dir(self, path):
  116|         """Process a directory, producing an output page for it"""
  117| 
  118|         # Find the filename
  119|         filename = self.filename_for_dir(path)
  120|         self.__filename = filename
  121| 
  122|         # Start the file
  123|         self.start_file()
  124|         self.write(self.manager.formatHeader(self.filename(), 1))
  125|         # Write intro stuff
  126|         root = rel(self.__base, self.__start)
  127|         if not len(root) or root[-1] != '/': root = root + '/'
  128|         if path is self.__start:
  129|             self.write('<h1> '+root)
  130|         else:
  131|             self.write('<h1>'+href(config.files.nameOfSpecial('dir'), root + ' '))
  132|             dirscope = []
  133|             scope = string.split(rel(self.__start, path), os.sep)
  134|             for dir in scope[:-1]:
  135|                dirscope.append(dir)
  136|                dirlink = config.files.nameOfScopedSpecial('dir', dirscope)
  137|                dirlink = rel(self.filename(), dirlink)
  138|                self.write(href(dirlink, dir+'/ '))
  139|             if len(scope) > 0:
  140|                self.write(scope[-1]+'/')
  141|         self.write(' - Directory listing</h1>')
  142|         # Start the table
  143|         self.write('<table summary="Directory Listing">\n')
  144|         self.write('<tr><th align=left>Name</th>')
  145|         self.write('<th align="right">Size (bytes)</th>')
  146|         self.write('<th align="right">Last modified (GMT)</th></tr>\n')
  147|         # List all files in the directory
  148|         entries = os.listdir(os.path.abspath(path))
  149|         entries.sort()
  150|         files = []
  151|         dirs = []
  152|         for entry in entries:
  153|             # Check if entry is in exclude list
  154|             exclude = 0
  155|             for re in self.__exclude_globs:
  156|                if re.match(entry):
  157|                exclude = 1
  158|             if exclude:
  159|                continue
  160|             entry_path = os.path.join(path, entry)
  161|             info = os.stat(entry_path)
  162|             if stat.S_ISDIR(info[stat.ST_MODE]):
  163|                # A directory, process now
  164|                scope = string.split(rel(self.__start, entry_path), os.sep)
  165|                linkpath = config.files.nameOfScopedSpecial('dir', scope)
  166|                linkpath = rel(self.filename(), linkpath)
  167|                self.write('<tr><td>%s</td><td></td><td align="right">%s</td></tr>\n'%(
  168|                    href(linkpath, entry+'/'),
  169|                    time.asctime(time.gmtime(info[stat.ST_MTIME]))))
  170|                dirs.append(entry_path)
  171|          else:
  172|                files.append((entry_path, entry, info))
  173|         for path, entry, info in files:
  174|             size = info[stat.ST_SIZE]
  175|             timestr = time.asctime(time.gmtime(info[stat.ST_MTIME]))
  176|             linkpath = config.files.nameOfFileSource(path)
  177|             rego = self.manager.filename_info(linkpath)
  178|             if rego:
  179|                linkurl = rel(self.filename(), linkpath)
  180|                self.write('<tr><td>%s</td><td align=right>%d</td><td align="right">%s</td></tr>\n'%(
  181|                    href(linkurl, entry, target="main"), size, timestr))
  182|          else:
  183|                #print "No link for",linkpath
  184|                self.write('<tr><td>%s</td><td align=right>%d</td><td align="right">%s</td></tr>\n'%(
  185|                    entry, size, timestr))
  186|         # End the table and file
  187|         self.write('</table>')
  188|         self.end_file()
  189| 
  190|         # recursively create all child directory pages
  191|         for dir in dirs:
  192|             self.process_dir(dir)
  193|         
  194| htmlPageClass = DirBrowse