# -*- test-case-name: twisted.web.test.test_web -*- # Copyright (c) 2001-2004 Twisted Matrix Laboratories. # See LICENSE for details. from cStringIO import StringIO from twisted.python import failure import html import resource import linecache import string, re import types def redirectTo(URL, request): request.redirect(URL) return """ click here """ % {'url': URL} class Redirect(resource.Resource): isLeaf = 1 def __init__(self, url): resource.Resource.__init__(self) self.url = url def render(self, request): return redirectTo(self.url, request) def getChild(self, name, request): return self class ChildRedirector(Redirect): isLeaf = 0 def __init__(self, url): # XXX is this enough? if ((url.find('://') == -1) and (not url.startswith('..')) and (not url.startswith('/'))): 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) Redirect.__init__(self, url) def getChild(self, name, request): newUrl = self.url if not newUrl.endswith('/'): newUrl += '/' newUrl += name return ChildRedirector(newUrl) from twisted.python import urlpath class ParentRedirect(resource.Resource): """ I redirect to URLPath.here(). """ isLeaf = 1 def render(self, request): return redirectTo(urlpath.URLPath.fromRequest(request).here(), request) def getChild(self, request): return self class DeferredResource(resource.Resource): """ I wrap up a Deferred that will eventually result in a Resource object. """ isLeaf = 1 def __init__(self, d): resource.Resource.__init__(self) self.d = d def getChild(self, name, request): return self def render(self, request): self.d.addCallback(self._cbChild, request).addErrback( self._ebChild,request) from twisted.web.server import NOT_DONE_YET return NOT_DONE_YET def _cbChild(self, child, request): result = resource.getChildForRequest(child, request).render(request) from twisted.web.server import NOT_DONE_YET if result == NOT_DONE_YET: return else: request.write(result) request.finish() def _ebChild(self, reason, request): request.processingFailed(reason) return reason stylesheet = """ """ def htmlrepr(x): return htmlReprTypes.get(type(x), htmlUnknown)(x) def saferepr(x): try: rx = repr(x) except: rx = "" % (x.__class__, id(x)) return rx def htmlUnknown(x): return ''+html.escape(saferepr(x))+'' def htmlDict(d): io = StringIO() w = io.write w('
Dictionary instance @ %s' % hex(id(d))) w('') for k, v in d.items(): if k == '__builtins__': v = 'builtin dictionary' w('' % (htmlrepr(k), htmlrepr(v))) w('
%s%s
') return io.getvalue() def htmlList(l): io = StringIO() w = io.write w('
List instance @ %s' % hex(id(l))) for i in l: w('
%s
' % htmlrepr(i)) w('
') return io.getvalue() def htmlInst(i): if hasattr(i, "__html__"): s = i.__html__() else: s = html.escape(saferepr(i)) return '''
%s instance @ %s %s
''' % (i.__class__, hex(id(i)), s) def htmlString(s): return html.escape(saferepr(s)) def htmlFunc(f): return ('
' + html.escape("function %s in file %s at line %s" % (f.__name__, f.func_code.co_filename, f.func_code.co_firstlineno))+ '
') htmlReprTypes = {types.DictType: htmlDict, types.ListType: htmlList, types.InstanceType: htmlInst, types.StringType: htmlString, types.FunctionType: htmlFunc} def htmlIndent(snippetLine): ret = string.replace(string.replace(html.escape(string.rstrip(snippetLine)), ' ', ' '), '\t', '        ') return ret def formatFailure(myFailure): exceptionHTML = """

%s: %s

""" frameHTML = """
%s, line %s in %s
""" snippetLineHTML = """
%s%s
""" snippetHighlightLineHTML = """
%s%s
""" variableHTML = """ %s%s """ if not isinstance(myFailure, failure.Failure): return html.PRE(str(myFailure)) io = StringIO() w = io.write w(stylesheet) w('') w(exceptionHTML % (html.escape(str(myFailure.type)), html.escape(str(myFailure.value)))) w('') w('
') first = 1 for method, filename, lineno, localVars, globalVars in myFailure.frames: if filename == '': continue if first: w('
') first = 0 else: w('
') w(frameHTML % (filename, lineno, method)) w('
') textSnippet = '' for snipLineNo in range(lineno-2, lineno+2): snipLine = linecache.getline(filename, snipLineNo) textSnippet += snipLine snipLine = htmlIndent(snipLine) if snipLineNo == lineno: w(snippetHighlightLineHTML % (snipLineNo, snipLine)) else: w(snippetLineHTML % (snipLineNo, snipLine)) w('
') # Instance variables for name, var in localVars: if name == 'self' and hasattr(var, '__dict__'): usedVars = [ (key, value) for (key, value) in var.__dict__.items() if re.search(r'\W'+'self.'+key+r'\W', textSnippet) ] if usedVars: w('
Self') w('') for key, value in usedVars: w(variableHTML % (key, htmlrepr(value))) w('
') break # Local and global vars for nm, varList in ('Locals', localVars), ('Globals', globalVars): usedVars = [ (name, var) for (name, var) in varList if re.search(r'\W'+name+r'\W', textSnippet) ] if usedVars: w('
%s' % nm) for name, var in usedVars: w(variableHTML % (name, htmlrepr(var))) w('
') w('
') # frame w('
') # stacktrace w(' ') w(exceptionHTML % (html.escape(str(myFailure.type)), html.escape(str(myFailure.value)))) return io.getvalue()