Skip to content

Instantly share code, notes, and snippets.

@jdp jdp/
Created Feb 10, 2016

What would you like to do?
Serve directory listing kinda like a GitHub project page
#!/usr/bin/env python
import cgi
import os
import mistune
from SimpleHTTPServer import SimpleHTTPRequestHandler
from SocketServer import TCPServer
from cStringIO import StringIO
class ReadmeHandler(SimpleHTTPRequestHandler):
def readme(self, path):
with open(os.path.join(path, '')) as f:
return mistune.markdown(
except IOError:
return ""
def list_directory(self, path):
"""Helper to produce a directory listing (absent index.html).
Return value is either a file object, or None (indicating an
error). In either case, the headers are sent, making the
interface the same as for send_head().
Also appends the contents of a readme if it exists.
list = os.listdir(path)
except os.error:
self.send_error(404, "No permission to list directory")
return None
list.sort(lambda a, b: cmp(a.lower(), b.lower()))
f = StringIO()
f.write('<head><meta charset="UTF-8"></head>')
f.write("<title>Directory listing for %s</title>\n" % self.path)
f.write("<h2>Directory listing for %s</h2>\n" % self.path)
for name in list:
fullname = os.path.join(path, name)
displayname = linkname = name = cgi.escape(name)
# Append / for directories or @ for symbolic links
if os.path.isdir(fullname):
displayname = name + "/"
linkname = name + "/"
if os.path.islink(fullname):
displayname = name + "@"
# Note: a link to a directory displays with @ and links with /
f.write('<li><a href="%s">%s</a>\n' % (linkname, displayname))
self.send_header("Content-type", "text/html")
return f
port = os.environ.get('PORT', 8000)
server = TCPServer(('', port), ReadmeHandler)
if __name__ == '__main__':
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.