~ntt-pf-lab/nova/monkey_patch_notification

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/twisted/web/util.py

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- test-case-name: twisted.web.test.test_web -*-
 
2
# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
 
3
# See LICENSE for details.
 
4
 
 
5
 
 
6
from cStringIO import StringIO
 
7
import linecache
 
8
import string, re
 
9
import types
 
10
 
 
11
from twisted.python import failure
 
12
 
 
13
from twisted.web import html, resource
 
14
 
 
15
 
 
16
def redirectTo(URL, request):
 
17
    request.redirect(URL)
 
18
    return """
 
19
<html>
 
20
    <head>
 
21
        <meta http-equiv=\"refresh\" content=\"0;URL=%(url)s\">
 
22
    </head>
 
23
    <body bgcolor=\"#FFFFFF\" text=\"#000000\">
 
24
    <a href=\"%(url)s\">click here</a>
 
25
    </body>
 
26
</html>
 
27
""" % {'url': URL}
 
28
 
 
29
class Redirect(resource.Resource):
 
30
 
 
31
    isLeaf = 1
 
32
 
 
33
    def __init__(self, url):
 
34
        resource.Resource.__init__(self)
 
35
        self.url = url
 
36
 
 
37
    def render(self, request):
 
38
        return redirectTo(self.url, request)
 
39
 
 
40
    def getChild(self, name, request):
 
41
        return self
 
42
 
 
43
class ChildRedirector(Redirect):
 
44
    isLeaf = 0
 
45
    def __init__(self, url):
 
46
        # XXX is this enough?
 
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)
 
52
 
 
53
    def getChild(self, name, request):
 
54
        newUrl = self.url
 
55
        if not newUrl.endswith('/'):
 
56
            newUrl += '/'
 
57
        newUrl += name
 
58
        return ChildRedirector(newUrl)
 
59
 
 
60
 
 
61
from twisted.python import urlpath
 
62
 
 
63
class ParentRedirect(resource.Resource):
 
64
    """
 
65
    I redirect to URLPath.here().
 
66
    """
 
67
    isLeaf = 1
 
68
    def render(self, request):
 
69
        return redirectTo(urlpath.URLPath.fromRequest(request).here(), request)
 
70
 
 
71
    def getChild(self, request):
 
72
        return self
 
73
 
 
74
 
 
75
class DeferredResource(resource.Resource):
 
76
    """
 
77
    I wrap up a Deferred that will eventually result in a Resource
 
78
    object.
 
79
    """
 
80
    isLeaf = 1
 
81
 
 
82
    def __init__(self, d):
 
83
        resource.Resource.__init__(self)
 
84
        self.d = d
 
85
 
 
86
    def getChild(self, name, request):
 
87
        return self
 
88
 
 
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
 
93
        return NOT_DONE_YET
 
94
 
 
95
    def _cbChild(self, child, request):
 
96
        request.render(resource.getChildForRequest(child, request))
 
97
 
 
98
    def _ebChild(self, reason, request):
 
99
        request.processingFailed(reason)
 
100
        return reason
 
101
 
 
102
 
 
103
stylesheet = """
 
104
<style type="text/css">
 
105
    p.error {
 
106
      color: red;
 
107
      font-family: Verdana, Arial, helvetica, sans-serif;
 
108
      font-weight: bold;
 
109
    }
 
110
 
 
111
    div {
 
112
      font-family: Verdana, Arial, helvetica, sans-serif;
 
113
    }
 
114
 
 
115
    div.stackTrace {
 
116
    }
 
117
 
 
118
    div.frame {
 
119
      padding: 1em;
 
120
      background: white;
 
121
      border-bottom: thin black dashed;
 
122
    }
 
123
 
 
124
    div.firstFrame {
 
125
      padding: 1em;
 
126
      background: white;
 
127
      border-top: thin black dashed;
 
128
      border-bottom: thin black dashed;
 
129
    }
 
130
 
 
131
    div.location {
 
132
    }
 
133
 
 
134
    div.snippet {
 
135
      margin-bottom: 0.5em;
 
136
      margin-left: 1em;
 
137
      background: #FFFFDD;
 
138
    }
 
139
 
 
140
    div.snippetHighlightLine {
 
141
      color: red;
 
142
    }
 
143
 
 
144
    span.code {
 
145
      font-family: "Courier New", courier, monotype;
 
146
    }
 
147
 
 
148
    span.function {
 
149
      font-weight: bold;
 
150
      font-family: "Courier New", courier, monotype;
 
151
    }
 
152
 
 
153
    table.variables {
 
154
      border-collapse: collapse;
 
155
      margin-left: 1em;
 
156
    }
 
157
 
 
158
    td.varName {
 
159
      vertical-align: top;
 
160
      font-weight: bold;
 
161
      padding-left: 0.5em;
 
162
      padding-right: 0.5em;
 
163
    }
 
164
 
 
165
    td.varValue {
 
166
      padding-left: 0.5em;
 
167
      padding-right: 0.5em;
 
168
    }
 
169
 
 
170
    div.variables {
 
171
      margin-bottom: 0.5em;
 
172
    }
 
173
 
 
174
    span.heading {
 
175
      font-weight: bold;
 
176
    }
 
177
 
 
178
    div.dict {
 
179
      background: #cccc99;
 
180
      padding: 2px;
 
181
      float: left;
 
182
    }
 
183
 
 
184
    td.dictKey {
 
185
      background: #ffff99;
 
186
      font-weight: bold;
 
187
    }
 
188
 
 
189
    td.dictValue {
 
190
      background: #ffff99;
 
191
    }
 
192
 
 
193
    div.list {
 
194
      background: #7777cc;
 
195
      padding: 2px;
 
196
      float: left;
 
197
    }
 
198
 
 
199
    div.listItem {
 
200
      background: #9999ff;
 
201
    }
 
202
 
 
203
    div.instance {
 
204
      background: #cc7777;
 
205
      padding: 2px;
 
206
      float: left;
 
207
    }
 
208
 
 
209
    span.instanceName {
 
210
      font-weight: bold;
 
211
      display: block;
 
212
    }
 
213
 
 
214
    span.instanceRepr {
 
215
      background: #ff9999;
 
216
      font-family: "Courier New", courier, monotype;
 
217
    }
 
218
 
 
219
    div.function {
 
220
      background: orange;
 
221
      font-weight: bold;
 
222
      float: left;
 
223
    }
 
224
</style>
 
225
"""
 
226
 
 
227
 
 
228
def htmlrepr(x):
 
229
    return htmlReprTypes.get(type(x), htmlUnknown)(x)
 
230
 
 
231
def saferepr(x):
 
232
    try:
 
233
        rx = repr(x)
 
234
    except:
 
235
        rx = "<repr failed! %s instance at %s>" % (x.__class__, id(x))
 
236
    return rx
 
237
 
 
238
def htmlUnknown(x):
 
239
    return '<code>'+html.escape(saferepr(x))+'</code>'
 
240
 
 
241
def htmlDict(d):
 
242
    io = StringIO()
 
243
    w = io.write
 
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():
 
247
 
 
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)))
 
251
    w('</table></div>')
 
252
    return io.getvalue()
 
253
 
 
254
def htmlList(l):
 
255
    io = StringIO()
 
256
    w = io.write
 
257
    w('<div class="list"><span class="heading">List instance @ %s</span>' % hex(id(l)))
 
258
    for i in l:
 
259
        w('<div class="listItem">%s</div>' % htmlrepr(i))
 
260
    w('</div>')
 
261
    return io.getvalue()
 
262
 
 
263
def htmlInst(i):
 
264
    if hasattr(i, "__html__"):
 
265
        s = i.__html__()
 
266
    else:
 
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)
 
271
 
 
272
def htmlString(s):
 
273
    return html.escape(saferepr(s))
 
274
 
 
275
def htmlFunc(f):
 
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))+
 
280
            '</div>')
 
281
 
 
282
htmlReprTypes = {types.DictType: htmlDict,
 
283
                 types.ListType: htmlList,
 
284
                 types.InstanceType: htmlInst,
 
285
                 types.StringType: htmlString,
 
286
                 types.FunctionType: htmlFunc}
 
287
 
 
288
 
 
289
 
 
290
def htmlIndent(snippetLine):
 
291
    ret = string.replace(string.replace(html.escape(string.rstrip(snippetLine)),
 
292
                                  '  ', '&nbsp;'),
 
293
                   '\t', '&nbsp; &nbsp; &nbsp; &nbsp; ')
 
294
    return ret
 
295
 
 
296
def formatFailure(myFailure):
 
297
 
 
298
    exceptionHTML = """
 
299
<p class="error">%s: %s</p>
 
300
"""
 
301
 
 
302
    frameHTML = """
 
303
<div class="location">%s, line %s in <span class="function">%s</span></div>
 
304
"""
 
305
 
 
306
    snippetLineHTML = """
 
307
<div class="snippetLine"><span class="lineno">%s</span><span class="code">%s</span></div>
 
308
"""
 
309
 
 
310
    snippetHighlightLineHTML = """
 
311
<div class="snippetHighlightLine"><span class="lineno">%s</span><span class="code">%s</span></div>
 
312
"""
 
313
 
 
314
    variableHTML = """
 
315
<tr class="varRow"><td class="varName">%s</td><td class="varValue">%s</td></tr>
 
316
"""
 
317
 
 
318
    if not isinstance(myFailure, failure.Failure):
 
319
        return html.PRE(str(myFailure))
 
320
    io = StringIO()
 
321
    w = io.write
 
322
    w(stylesheet)
 
323
    w('<a href="#tbend">')
 
324
    w(exceptionHTML % (html.escape(str(myFailure.type)),
 
325
                       html.escape(str(myFailure.value))))
 
326
    w('</a>')
 
327
    w('<div class="stackTrace">')
 
328
    first = 1
 
329
    for method, filename, lineno, localVars, globalVars in myFailure.frames:
 
330
        if filename == '<string>':
 
331
            continue
 
332
        if first:
 
333
            w('<div class="firstFrame">')
 
334
            first = 0
 
335
        else:
 
336
            w('<div class="frame">')
 
337
        w(frameHTML % (filename, lineno, method))
 
338
 
 
339
        w('<div class="snippet">')
 
340
        textSnippet = ''
 
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))
 
347
            else:
 
348
                w(snippetLineHTML % (snipLineNo, snipLine))
 
349
        w('</div>')
 
350
 
 
351
        # Instance variables
 
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) ]
 
356
                if usedVars:
 
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)))
 
361
                    w('</table></div>')
 
362
                break
 
363
 
 
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) ]
 
368
            if usedVars:
 
369
                w('<div class="variables"><b>%s</b><table class="variables">' % nm)
 
370
                for name, var in usedVars:
 
371
                    w(variableHTML % (name, htmlrepr(var)))
 
372
                w('</table></div>')
 
373
 
 
374
        w('</div>') # frame
 
375
    w('</div>') # stacktrace
 
376
    w('<a name="tbend"> </a>')
 
377
    w(exceptionHTML % (html.escape(str(myFailure.type)),
 
378
                       html.escape(str(myFailure.value))))
 
379
 
 
380
    return io.getvalue()