965df6c8c18a76e41e659f92eccf08ef57f4fe30
[wrw.git] / wrw / resp.py
1 from . import dispatch, proto, env
2 from .sp import xhtml
3 h = xhtml.cons()
4
5 __all__ = ["skeleton", "skelfor", "setskel", "usererror"]
6
7 class skeleton(object):
8     def page(self, req, title, *content):
9         return xhtml.forreq(req, h.html(self.head(req, title), h.body(*content)))
10
11     def head(self, req, title):
12         return xhtml.head(title=title)
13
14     def error(self, req, message, *detail):
15         return self.page(req, message, h.h1(message), h.p(*detail))
16
17     def message(self, req, message, *detail):
18         return self.page(req, message, h.h1(message), h.p(*detail))
19
20 defskel = env.var(skeleton())
21
22 def getskel(req):
23     return [defskel.val]
24 def skelfor(req):
25     return req.item(getskel)[0]
26 def setskel(req, skel):
27     req.item(getskel)[0] = skel
28
29 class usererror(dispatch.restart):
30     def __init__(self, message, *detail):
31         super().__init__()
32         self.message = message
33         self.detail = detail
34
35     def handle(self, req):
36         return skelfor(req).error(req, self.message, *self.detail)
37
38 class message(dispatch.restart):
39     def __init__(self, message, *detail):
40         super().__init__()
41         self.message = message
42         self.detail = detail
43
44     def handle(self, req):
45         return skelfor(req).message(req, self.message, *self.detail)
46
47 class httperror(usererror):
48     def __init__(self, status, message=None, detail=None):
49         if message is None:
50             message = proto.statusinfo[status][0]
51         if detail is None:
52             detail = (proto.statusinfo[status][1],)
53         super().__init__(message, *detail)
54         self.status = status
55
56     def handle(self, req):
57         req.status(self.status, self.message)
58         return super().handle(req)
59
60 class notfound(httperror):
61     def __init__(self):
62         return super().__init__(404)
63
64 class redirect(dispatch.restart):
65     bases = {"url": proto.requrl,
66              "script": proto.scripturl,
67              "site": proto.siteurl}
68
69     def __init__(self, url, status=303, base="url"):
70         super().__init__()
71         self.url = url
72         self.status = status
73         self.bases[base]
74         self.base = base
75
76     def handle(self, req):
77         req.status(self.status, "Redirect")
78         req.ohead["Location"] = proto.appendurl(self.bases[self.base](req), self.url)
79         req.ohead["Content-Length"] = 0
80         return []
81
82 class unmodified(dispatch.restart):
83     def handle(self, req):
84         req.status(304, "Not Modified")
85         req.ohead["Content-Length"] = "0"
86         return []