1
# -*- test-case-name: twisted.web.test.test_web -*-
2
# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
3
# See LICENSE for details.
6
from cStringIO import StringIO
11
from twisted.python import failure
13
from twisted.web import html, resource
16
def redirectTo(URL, request):
21
<meta http-equiv=\"refresh\" content=\"0;URL=%(url)s\">
23
<body bgcolor=\"#FFFFFF\" text=\"#000000\">
24
<a href=\"%(url)s\">click here</a>
29
class Redirect(resource.Resource):
33
def __init__(self, url):
34
resource.Resource.__init__(self)
37
def render(self, request):
38
return redirectTo(self.url, request)
40
def getChild(self, name, request):
43
class ChildRedirector(Redirect):
45
def __init__(self, url):
47
if ((url.find('://') == -1)
48
and (not url.startswith('..'))
49
and (not url.startswith('/'))):
50
raise ValueError("It seems you've given me a redirect (%s) that is a child of myself! That's not good, it'll cause an infinite redirect." % url)
51
Redirect.__init__(self, url)
53
def getChild(self, name, request):
55
if not newUrl.endswith('/'):
58
return ChildRedirector(newUrl)
61
from twisted.python import urlpath
63
class ParentRedirect(resource.Resource):
65
I redirect to URLPath.here().
68
def render(self, request):
69
return redirectTo(urlpath.URLPath.fromRequest(request).here(), request)
71
def getChild(self, request):
75
class DeferredResource(resource.Resource):
77
I wrap up a Deferred that will eventually result in a Resource
82
def __init__(self, d):
83
resource.Resource.__init__(self)
86
def getChild(self, name, request):
89
def render(self, request):
90
self.d.addCallback(self._cbChild, request).addErrback(
91
self._ebChild,request)
92
from twisted.web.server import NOT_DONE_YET
95
def _cbChild(self, child, request):
96
request.render(resource.getChildForRequest(child, request))
98
def _ebChild(self, reason, request):
99
request.processingFailed(reason)
104
<style type="text/css">
107
font-family: Verdana, Arial, helvetica, sans-serif;
112
font-family: Verdana, Arial, helvetica, sans-serif;
121
border-bottom: thin black dashed;
127
border-top: thin black dashed;
128
border-bottom: thin black dashed;
135
margin-bottom: 0.5em;
140
div.snippetHighlightLine {
145
font-family: "Courier New", courier, monotype;
150
font-family: "Courier New", courier, monotype;
154
border-collapse: collapse;
162
padding-right: 0.5em;
167
padding-right: 0.5em;
171
margin-bottom: 0.5em;
216
font-family: "Courier New", courier, monotype;
229
return htmlReprTypes.get(type(x), htmlUnknown)(x)
235
rx = "<repr failed! %s instance at %s>" % (x.__class__, id(x))
239
return '<code>'+html.escape(saferepr(x))+'</code>'
244
w('<div class="dict"><span class="heading">Dictionary instance @ %s</span>' % hex(id(d)))
245
w('<table class="dict">')
246
for k, v in d.items():
248
if k == '__builtins__':
249
v = 'builtin dictionary'
250
w('<tr><td class="dictKey">%s</td><td class="dictValue">%s</td></tr>' % (htmlrepr(k), htmlrepr(v)))
257
w('<div class="list"><span class="heading">List instance @ %s</span>' % hex(id(l)))
259
w('<div class="listItem">%s</div>' % htmlrepr(i))
264
if hasattr(i, "__html__"):
267
s = html.escape(saferepr(i))
268
return '''<div class="instance"><span class="instanceName">%s instance @ %s</span>
269
<span class="instanceRepr">%s</span></div>
270
''' % (i.__class__, hex(id(i)), s)
273
return html.escape(saferepr(s))
276
return ('<div class="function">' +
277
html.escape("function %s in file %s at line %s" %
278
(f.__name__, f.func_code.co_filename,
279
f.func_code.co_firstlineno))+
282
htmlReprTypes = {types.DictType: htmlDict,
283
types.ListType: htmlList,
284
types.InstanceType: htmlInst,
285
types.StringType: htmlString,
286
types.FunctionType: htmlFunc}
290
def htmlIndent(snippetLine):
291
ret = string.replace(string.replace(html.escape(string.rstrip(snippetLine)),
293
'\t', ' ')
296
def formatFailure(myFailure):
299
<p class="error">%s: %s</p>
303
<div class="location">%s, line %s in <span class="function">%s</span></div>
306
snippetLineHTML = """
307
<div class="snippetLine"><span class="lineno">%s</span><span class="code">%s</span></div>
310
snippetHighlightLineHTML = """
311
<div class="snippetHighlightLine"><span class="lineno">%s</span><span class="code">%s</span></div>
315
<tr class="varRow"><td class="varName">%s</td><td class="varValue">%s</td></tr>
318
if not isinstance(myFailure, failure.Failure):
319
return html.PRE(str(myFailure))
323
w('<a href="#tbend">')
324
w(exceptionHTML % (html.escape(str(myFailure.type)),
325
html.escape(str(myFailure.value))))
327
w('<div class="stackTrace">')
329
for method, filename, lineno, localVars, globalVars in myFailure.frames:
330
if filename == '<string>':
333
w('<div class="firstFrame">')
336
w('<div class="frame">')
337
w(frameHTML % (filename, lineno, method))
339
w('<div class="snippet">')
341
for snipLineNo in range(lineno-2, lineno+2):
342
snipLine = linecache.getline(filename, snipLineNo)
343
textSnippet += snipLine
344
snipLine = htmlIndent(snipLine)
345
if snipLineNo == lineno:
346
w(snippetHighlightLineHTML % (snipLineNo, snipLine))
348
w(snippetLineHTML % (snipLineNo, snipLine))
352
for name, var in localVars:
353
if name == 'self' and hasattr(var, '__dict__'):
354
usedVars = [ (key, value) for (key, value) in var.__dict__.items()
355
if re.search(r'\W'+'self.'+key+r'\W', textSnippet) ]
357
w('<div class="variables"><b>Self</b>')
358
w('<table class="variables">')
359
for key, value in usedVars:
360
w(variableHTML % (key, htmlrepr(value)))
364
# Local and global vars
365
for nm, varList in ('Locals', localVars), ('Globals', globalVars):
366
usedVars = [ (name, var) for (name, var) in varList
367
if re.search(r'\W'+name+r'\W', textSnippet) ]
369
w('<div class="variables"><b>%s</b><table class="variables">' % nm)
370
for name, var in usedVars:
371
w(variableHTML % (name, htmlrepr(var)))
375
w('</div>') # stacktrace
376
w('<a name="tbend"> </a>')
377
w(exceptionHTML % (html.escape(str(myFailure.type)),
378
html.escape(str(myFailure.value))))