Synopsis - Synopsis/Formatters/HTML/Views/Directory.py

File: Synopsis/Formatters/HTML/Views/Directory.py

      1#
      2# Copyright (C) 2000 Stephen Davies
      3# Copyright (C) 2000 Stefan Seefeld
      4# All rights reserved.
      5# Licensed to the public under the terms of the GNU LGPL (>= 2),
      6# see the file COPYING for details.
      7#
      8
      9from Synopsis import config
     10from Synopsis.Processor import Parameter
     11from Synopsis.Formatters.HTML.View import View
     12from Synopsis.Formatters.HTML.Tags import *
     13import os, stat, os.path, time, re
     14
     15def compile_glob(globstr):
     16    """Returns a compiled regular expression for the given glob string. A
     17    glob string is something like "*.?pp" which gets translated into
     18    "^.*\..pp$"."""
     19    glob = globstr.replace('.', '\.')
     20    glob = glob.replace('?', '.')
     21    glob = glob.replace('*', '.*')
     22    glob = re.compile('^%s$'%glob)
     23    return glob
     24
     25class Directory(View):
     26    """A view that lists the content of a directory."""
     27
     28    src_dir = Parameter('', 'starting point for directory listing')
     29    base_path = Parameter('', 'path prefix to strip off of the file names')
     30    exclude = Parameter([], 'TODO: define an exclusion mechanism (glob based ?)')
     31
     32    def filename(self):
     33
     34        return self.__filename
     35
     36    def title(self):
     37
     38        return 'Directory Listing'
     39
     40    def root(self):
     41
     42        if self.main:
     43            url = self.directory_layout.index()
     44        else:
     45            url = self.directory_layout.special('dir')
     46        return url, self.title()
     47
     48    def filename_for_dir(self, dir):
     49        """Returns the output filename for the given input directory."""
     50
     51        if dir == self.src_dir:
     52            return self.root()[0]
     53        else:
     54            scope = rel(self.src_dir, dir).split(os.sep)
     55            return self.directory_layout.scoped_special('dir', scope)
     56
     57    def register(self, frame):
     58
     59        View.register(self, frame)
     60        self._exclude = [compile_glob(e) for e in self.exclude]
     61        self.__filename = self.root()[0]
     62
     63    def register_filenames(self):
     64
     65        dirs = [self.src_dir]
     66        while dirs:
     67            dir = dirs.pop(0)
     68            for entry in os.listdir(os.path.abspath(dir)):
     69                exclude = 0
     70                for re in self._exclude:
     71                    if re.match(entry):
     72                        exclude = 1
     73                        break
     74                if exclude:
     75                    continue
     76                entry_path = os.path.join(dir, entry)
     77                if os.path.isdir(entry_path):
     78                    filename = self.filename_for_dir(dir)
     79                    self.processor.register_filename(filename, self, entry_path)
     80                    dirs.append(entry_path)
     81
     82    def process(self):
     83
     84        self.process_dir(self.src_dir)
     85
     86    def process_dir(self, path):
     87
     88        # Find the filename
     89        self.__filename = self.filename_for_dir(path)
     90
     91        # Start the file
     92        self.start_file()
     93        self.write_navigation_bar()
     94        # Write intro stuff
     95        root = ''
     96        if self.base_path != self.src_dir:
     97            rel(self.base_path, self.src_dir)
     98        if not len(root) or root[-1] != '/': root = root + '/'
     99        if path is self.src_dir:
    100            self.write('<h1> '+root)
    101        else:
    102            self.write('<h1>' + href(self.root()[0], root + ' '))
    103            dirscope = []
    104            scope = rel(self.src_dir, path).split(os.sep)
    105
    106            for dir in scope[:-1]:
    107                dirscope.append(dir)
    108                dirlink = self.directory_layout.scoped_special('dir', dirscope)
    109                dirlink = rel(self.filename(), dirlink)
    110
    111                self.write(href(dirlink, dir+'/ '))
    112            if len(scope) > 0:
    113                self.write(scope[-1]+'/')
    114        self.write(' - Directory listing</h1>')
    115        # Start the table
    116        self.write('<table summary="Directory Listing">\n')
    117        self.write('<tr><th align=left>Name</th>')
    118        self.write('<th align="right">Size (bytes)</th>')
    119        self.write('<th align="right">Last modified (GMT)</th></tr>\n')
    120        # List all files in the directory
    121        entries = os.listdir(os.path.abspath(path))
    122        entries.sort()
    123        files = []
    124        dirs = []
    125        for entry in entries:
    126         exclude = 0
    127         for re in self._exclude:
    128            if re.match(entry):
    129               exclude = 1
    130               break
    131         if exclude:
    132            continue
    133         entry_path = os.path.join(path, entry)
    134         info = os.stat(entry_path)
    135         if stat.S_ISDIR(info[stat.ST_MODE]):
    136            # A directory, process now
    137            scope = rel(self.src_dir, entry_path).split(os.sep)
    138            linkpath = self.directory_layout.scoped_special('dir', scope)
    139            linkpath = rel(self.filename(), linkpath)
    140            self.write('<tr><td>%s</td><td></td><td align="right">%s</td></tr>\n'%(
    141               href(linkpath, entry+'/'),
    142               time.asctime(time.gmtime(info[stat.ST_MTIME]))))
    143            dirs.append(entry_path)
    144         else:
    145            files.append((entry_path, entry, info))
    146
    147        for path, entry, info in files:
    148            size = info[stat.ST_SIZE]
    149            timestr = time.asctime(time.gmtime(info[stat.ST_MTIME]))
    150            # strip of base_path
    151            path = path[len(self.base_path):]
    152            if path[0] == '/': path = path[1:]
    153            linkpath = self.directory_layout.file_source(path)
    154            rego = self.processor.filename_info(linkpath)
    155            if rego:
    156                linkurl = rel(self.filename(), linkpath)
    157                self.write('<tr><td>%s</td><td align="right">%d</td><td align="right">%s</td></tr>\n'%(
    158                    href(linkurl, entry, target='content'), size, timestr))
    159            else:
    160                # print "No link for",linkpath
    161                self.write('<tr><td>%s</td><td align="right">%d</td><td align="right">%s</td></tr>\n'%(
    162                    entry, size, timestr))
    163        # End the table and file
    164        self.write('</table>')
    165        self.end_file()
    166
    167        # recursively create all child directory views
    168        for dir in dirs:
    169            self.process_dir(dir)
    170
    171    def end_file(self):
    172        """Overrides end_file to provide synopsis logo"""
    173
    174        self.write('\n')
    175        now = time.strftime(r'%c', time.localtime(time.time()))
    176        logo = img(src=rel(self.filename(), 'synopsis.png'), alt='logo')
    177        logo = href('http://synopsis.fresco.org', logo + ' synopsis', target='_blank')
    178        logo += ' (version %s)'%config.version
    179        self.write(div('logo', 'Generated on ' + now + ' by \n<br/>\n' + logo))
    180        View.end_file(self)
    181

Generated on Thu Apr 16 16:27:15 2009 by
synopsis (version devel)