"""Define a handler that generates an index for directories. """ import os import stat from datetime import datetime from os.path import basename, isdir, isfile, join import aspen STYLE = """\ body {font-family: "Trebuchet MS", sans-serif;} table {font-family: monospace;} .dir {font-weight: bold;} .file {} td {padding: 0 1em 0 0; white-space: nowrap;} td.size {text-align: right;} th {text-align: left; white-space: nowrap;} tr.even {background: #eee;} tr:hover {background: #eef;} #footer {font-size: smaller; font-style: italic;} """ KB = 1024 MB = KB * 1024 GB = MB * 1024 TB = GB * 1024 PB = TB * 1024 EB = PB * 1024 def _get_size(stats): """Given a stat struct, return a size string. """ size = float(stats[stat.ST_SIZE]) if size < KB: return '%d    B' % (size) elif size < MB: return '%.1f kB' % (size / KB) elif size < GB: return '%.1f MB' % (size / MB) elif size < TB: return '%.1f GB' % (size / GB) elif size < PB: return '%.1f TB' % (size / TB) # :^) elif size < EB: return '%.1f PB' % (size / PB) # :^D else: return '%.1f EB' % (size / EB) # 8^D def _get_time(stats): """Given a stat struct, return a date stamp string. """ return str(datetime.fromtimestamp(stats[stat.ST_MTIME])) def wsgi(environ, start_response): """Serve an automatic index for a directory. """ fspath = environ['PATH_TRANSLATED'] assert isdir(fspath) # sanity check root = aspen.paths.root urlpath = fspath[len(root):] + os.sep urlpath = '/'.join(urlpath.split(os.sep)) title = urlpath and urlpath or '/' # Gather dirs, files, and others under this directory. # ==================================================== # We have to loop here and again below in order to guarantee sorted output. dirs = [] files = [] others = [] for name in os.listdir(fspath): _fspath = join(fspath, name) # Don't list some things. # ======================= if _fspath == aspen.paths.__: # magic directory continue if basename(_fspath) == 'README.aspen': # README.aspen continue if basename(_fspath).startswith('.'): # hidden files continue _urlpath = urlpath + name x = (_fspath, _urlpath, name) el = others if isdir(_fspath): el = dirs elif isfile(_fspath): el = files el.append(x) dirs.sort() files.sort() others.sort() # Generate the HTML. # ================== out = ['%s' % title] def a(s): out.append(s + '\r\n') a('' % STYLE) a('

%s

' % title) a('') a('') i = 0 if environ['PATH_TRANSLATED'] != root: a('') i += 1 for el in (dirs, files, others): for _fspath, _urlpath, name in el: stats = os.stat(_fspath) a('' % ((i%2) and 'even' or 'odd')) if isdir(_fspath): a(' ' % (_urlpath, name)) a(' ') elif isfile(_fspath): a(' ' % (_urlpath, name)) a(' ' % _get_size(stats)) else: a(' ') a(' ' % _get_time(stats)) a('') i += 1 a('
NameSizeLast Modified
../  
%s/ %s%s%s' % name) a('  %s
') a('
' % aspen.__version__) a('') # Send it off. # ============ start_response('200 OK', [('Content-Type', 'text/html')]) return out