1#!/usr/bin/python 2import cgi 3import mimetypes 4import os 5import posixpath 6import re 7 8from mako import exceptions 9from mako.lookup import TemplateLookup 10 11root = "./" 12port = 8000 13 14lookup = TemplateLookup( 15 directories=[root + "templates", root + "htdocs"], 16 filesystem_checks=True, 17 module_directory="./modules", 18 # even better would be to use 'charset' in start_response 19 output_encoding="ascii", 20 encoding_errors="replace", 21) 22 23 24def serve(environ, start_response): 25 """serves requests using the WSGI callable interface.""" 26 fieldstorage = cgi.FieldStorage( 27 fp=environ["wsgi.input"], environ=environ, keep_blank_values=True 28 ) 29 d = dict([(k, getfield(fieldstorage[k])) for k in fieldstorage]) 30 31 uri = environ.get("PATH_INFO", "/") 32 if not uri: 33 uri = "/index.html" 34 else: 35 uri = re.sub(r"^/$", "/index.html", uri) 36 37 if re.match(r".*\.html$", uri): 38 try: 39 template = lookup.get_template(uri) 40 except exceptions.TopLevelLookupException: 41 start_response("404 Not Found", []) 42 return [str.encode("Cant find template '%s'" % uri)] 43 44 start_response("200 OK", [("Content-type", "text/html")]) 45 46 try: 47 return [template.render(**d)] 48 except: 49 return [exceptions.html_error_template().render()] 50 else: 51 u = re.sub(r"^\/+", "", uri) 52 filename = os.path.join(root, u) 53 if os.path.isfile(filename): 54 start_response("200 OK", [("Content-type", guess_type(uri))]) 55 return [open(filename, "rb").read()] 56 else: 57 start_response("404 Not Found", []) 58 return [str.encode("File not found: '%s'" % filename)] 59 60 61def getfield(f): 62 """convert values from cgi.Field objects to plain values.""" 63 if isinstance(f, list): 64 return [getfield(x) for x in f] 65 else: 66 return f.value 67 68 69extensions_map = mimetypes.types_map.copy() 70 71 72def guess_type(path): 73 """return a mimetype for the given path based on file extension.""" 74 base, ext = posixpath.splitext(path) 75 if ext in extensions_map: 76 return extensions_map[ext] 77 ext = ext.lower() 78 if ext in extensions_map: 79 return extensions_map[ext] 80 else: 81 return "text/html" 82 83 84if __name__ == "__main__": 85 import wsgiref.simple_server 86 87 server = wsgiref.simple_server.make_server("", port, serve) 88 print("Server listening on port %d" % port) 89 server.serve_forever() 90