#!/usr/bin/env python2.4
# -*- coding: utf-8 -*-
"""
WWW-sovellukset (TJTA270) Viikkotehtävän ratkaisu
Copyright (c) Esa-Matti Suuronen
This file is part of Sokkeli web framework.
Sokkeli is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Sokkeli is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Sokkeli. If not, see .
"""
import cgi
import os
import re
import sapluuna
from request import SokkeliRequest
import config
static_url = re.compile(r".*\+\+static/(.+)$")
content_types = {
"css": "text/css",
"html": "text/html",
"htm": "text/html",
"txt": "text/plain",
"zip": "application/zip",
"png": "image/png",
"jpeg": "image/jpeg",
"jpg": "image/jpeg",
}
def _format_known_paths():
return "\n".join(path for path, callable in config.urlmap)
def _request_path():
return os.environ.get('PATH_INFO', '/').strip()
def serve_static(filename):
"""
Lazy static file sharing
"""
ext = filename.split(".")[-1]
filepath = os.path.join(config.static_dir, filename)
# Let cgitb handle exceptions
file = open(filepath, "r")
yield "Content-Type: " + content_types.get(ext, "text/plain")
yield "\n\n"
while True:
data = file.read(1024)
if not data:
break
yield data
file.close()
def cgi_dispatcher():
static_match = static_url.match(_request_path())
if static_match:
return serve_static(static_match.group(1))
for pattern, callable in config.urlmap:
matcher = re.compile(pattern)
match = matcher.match(_request_path())
if match:
page = callable(*match.groups())
try:
return page.render_response()
except AttributeError:
return page
return response_404(_request_path())
def mod_python_dispatcher(req):
static_match = static_url.match(req.path_info)
if static_match:
return serve_static(static_match.group(1))
for pattern, callable in config.urlmap:
matcher = re.compile(pattern)
match = matcher.match(req.path_info)
if match:
page = callable(SokkeliRequest(req), *match.groups())
try:
return page.run()
except AttributeError:
return page
return response_404(req.path_info, req=req)
def response_404(path, msg="", req=None):
# TODO: Add 404 header
import pprint, sys, inspect
error_page = sapluuna.Sapluuna(sapluuna.read_template_from_file('404.html'))
if req:
form = req
else:
form = cgi.FieldStorage()
return error_page.render(dict(
version=sys.version,
environ=pprint.pformat(dict(os.environ)),
form="
".join(
str([attr, str(getattr(form, attr))])
for attr in dir(form)
if getattr(form, attr) is not None
),
path=path,
paths=_format_known_paths(),
))
if __name__ == '__main__':
pass