paulo@48: import os paulo@48: import stat paulo@48: import datetime paulo@48: paulo@48: import html paulo@48: paulo@48: paulo@48: def _get_cwd(environ): paulo@48: ROOTPATH = "pauloang.com" paulo@48: path_info = environ.get("PATH_INFO", '') paulo@48: return [ROOTPATH] + [i for i in path_info.split('/') if len(i) > 0] paulo@48: paulo@48: paulo@48: def _get_breadcrumb(cwd): paulo@48: h = html.HTML() paulo@48: for (i, d) in enumerate(cwd[:-1]): paulo@48: h.a(d, href='/' + '/'.join(cwd[1:i+1])) paulo@48: h.text('/') paulo@48: h.text(cwd[-1]) paulo@48: return h paulo@48: paulo@48: paulo@48: def main(environ): paulo@48: cwd = _get_cwd(environ) paulo@48: dirs = [] paulo@48: paulo@48: for i in os.listdir("."): paulo@48: if i[0] != '.' and os.path.isdir(i): paulo@48: statobj = os.stat(i) paulo@48: mtime = datetime.datetime.fromtimestamp(statobj.st_mtime) paulo@48: modeok = (statobj.st_mode & stat.S_IXOTH) and (statobj.st_mode & stat.S_IROTH) paulo@48: dirs.append((i, modeok, mtime)) paulo@48: paulo@48: root = html.HTML("html") paulo@48: TITLE_FMT = "-[%s]-" paulo@48: title = TITLE_FMT % '/'.join(cwd) paulo@48: paulo@48: header = root.header paulo@48: header.title(title) paulo@48: header.link(rel="stylesheet", type="text/css", href="index.css") paulo@48: paulo@48: body = root.body paulo@48: body.h1(TITLE_FMT % str(_get_breadcrumb(cwd)), escape=False) paulo@48: paulo@49: body_table = body.table(klass="index") paulo@48: paulo@48: for (i, modeok, mtime) in sorted(dirs, key=lambda x: x[2], reverse=True): paulo@48: if modeok: paulo@48: r = body_table.tr paulo@48: r.td.div(mtime.isoformat(), klass="index_date") paulo@48: r.td.a(i, href=i) paulo@48: paulo@48: return unicode(root).encode("utf-8") paulo@48: paulo@48: paulo@48: def app(environ, start_response): paulo@48: response_body = main(environ) paulo@48: response_headers = [ paulo@48: ("Content-Type", "text/html; charset=UTF-8"), paulo@48: ("Content-Length", str(len(response_body))), paulo@48: ] paulo@48: start_response("200 OK", response_headers) paulo@48: paulo@48: return [response_body]