Mercurial > p > roundup > code
comparison roundup/cgi/cgitb.py @ 2564:7500a9bb8bf9
message translator is passed by the client in function arguments;
more messages marked for translation, especially in pt_html();
fix vim modeline
| author | Alexander Smishlajev <a1s@users.sourceforge.net> |
|---|---|
| date | Tue, 13 Jul 2004 10:18:00 +0000 |
| parents | cafdf8b7cc69 |
| children | b1e614c6759f |
comparison
equal
deleted
inserted
replaced
| 2563:420d5c2a49d9 | 2564:7500a9bb8bf9 |
|---|---|
| 1 # | 1 # |
| 2 # This module was written by Ka-Ping Yee, <ping@lfw.org>. | 2 # This module was written by Ka-Ping Yee, <ping@lfw.org>. |
| 3 # | 3 # |
| 4 # $Id: cgitb.py,v 1.11 2004-06-09 09:20:01 a1s Exp $ | 4 # $Id: cgitb.py,v 1.12 2004-07-13 10:18:00 a1s Exp $ |
| 5 | 5 |
| 6 """Extended CGI traceback handler by Ka-Ping Yee, <ping@lfw.org>. | 6 """Extended CGI traceback handler by Ka-Ping Yee, <ping@lfw.org>. |
| 7 """ | 7 """ |
| 8 __docformat__ = 'restructuredtext' | 8 __docformat__ = 'restructuredtext' |
| 9 | 9 |
| 10 import sys, os, types, string, keyword, linecache, tokenize, inspect, cgi | 10 import sys, os, types, string, keyword, linecache, tokenize, inspect, cgi |
| 11 import pydoc, traceback | 11 import pydoc, traceback |
| 12 | 12 |
| 13 from roundup.cgi import templating | 13 from roundup.cgi import templating, TranslationService |
| 14 | 14 |
| 15 def _(msgid): | 15 def get_translator(i18n=None): |
| 16 return templating.translationService.gettext(msgid) | 16 """Return message translation function (gettext) |
| 17 | |
| 18 Parameters: | |
| 19 i18n - translation service, such as roundup.i18n module | |
| 20 or TranslationService object. | |
| 21 | |
| 22 Return ``gettext`` attribute of the ``i18n`` object, if available | |
| 23 (must be a message translation function with one argument). | |
| 24 If ``gettext`` cannot be obtained from ``i18n``, take default | |
| 25 TranslationService. | |
| 26 | |
| 27 """ | |
| 28 try: | |
| 29 return i18n.gettext | |
| 30 except: | |
| 31 return TranslationService.get_translation().gettext | |
| 17 | 32 |
| 18 def breaker(): | 33 def breaker(): |
| 19 return ('<body bgcolor="white">' + | 34 return ('<body bgcolor="white">' + |
| 20 '<font color="white" size="-5"> > </font> ' + | 35 '<font color="white" size="-5"> > </font> ' + |
| 21 '</table>' * 5) | 36 '</table>' * 5) |
| 25 for k,v in dict.items(): | 40 for k,v in dict.items(): |
| 26 l.append('<tr><td><strong>%s</strong></td><td>%s</td></tr>'%(k, | 41 l.append('<tr><td><strong>%s</strong></td><td>%s</td></tr>'%(k, |
| 27 cgi.escape(repr(v)))) | 42 cgi.escape(repr(v)))) |
| 28 return '\n'.join(l) | 43 return '\n'.join(l) |
| 29 | 44 |
| 30 def pt_html(context=5): | 45 def pt_html(context=5, i18n=None): |
| 46 _ = get_translator(i18n) | |
| 31 esc = cgi.escape | 47 esc = cgi.escape |
| 32 l = ['<h1>Templating Error</h1>', | 48 exc_info = [esc(str(value)) for value in sys.exc_info()[:2]] |
| 33 '<p><b>%s</b>: %s</p>'%(esc(str(sys.exc_type)), | 49 l = [_('<h1>Templating Error</h1>\n' |
| 34 esc(str(sys.exc_value))), | 50 '<p><b>%(exc_type)s</b>: %(exc_value)s</p>\n' |
| 35 '<p class="help">Debugging information follows</p>', | 51 '<p class="help">Debugging information follows</p>' |
| 52 ) % {'exc_type': exc_info[0], 'exc_value': exc_info[1]}, | |
| 36 '<ol>',] | 53 '<ol>',] |
| 37 from roundup.cgi.PageTemplates.Expressions import TraversalError | 54 from roundup.cgi.PageTemplates.Expressions import TraversalError |
| 38 t = inspect.trace(context) | 55 t = inspect.trace(context) |
| 39 t.reverse() | 56 t.reverse() |
| 40 for frame, file, lnum, func, lines, index in t: | 57 for frame, file, lnum, func, lines, index in t: |
| 42 if locals.has_key('__traceback_info__'): | 59 if locals.has_key('__traceback_info__'): |
| 43 ti = locals['__traceback_info__'] | 60 ti = locals['__traceback_info__'] |
| 44 if isinstance(ti, TraversalError): | 61 if isinstance(ti, TraversalError): |
| 45 s = [] | 62 s = [] |
| 46 for name, info in ti.path: | 63 for name, info in ti.path: |
| 47 s.append('<li>"%s" (%s)</li>'%(name, esc(repr(info)))) | 64 s.append(_('<li>"%(name)s" (%(info)s)</li>') |
| 65 % {'name': name, 'info': esc(repr(info))}) | |
| 48 s = '\n'.join(s) | 66 s = '\n'.join(s) |
| 49 l.append('<li>Looking for "%s", current path:<ol>%s</ol></li>'%( | 67 l.append(_('<li>Looking for "%(name)s", ' |
| 50 ti.name, s)) | 68 'current path:<ol>%(path)s</ol></li>' |
| 69 ) % {'name': ti.name, 'path': s}) | |
| 51 else: | 70 else: |
| 52 l.append('<li>In %s</li>'%esc(str(ti))) | 71 l.append(_('<li>In %s</li>') % esc(str(ti))) |
| 53 if locals.has_key('__traceback_supplement__'): | 72 if locals.has_key('__traceback_supplement__'): |
| 54 ts = locals['__traceback_supplement__'] | 73 ts = locals['__traceback_supplement__'] |
| 55 if len(ts) == 2: | 74 if len(ts) == 2: |
| 56 supp, context = ts | 75 supp, context = ts |
| 57 s = 'A problem occurred in your template "%s".'%str(context.id) | 76 s = _('A problem occurred in your template "%s".') \ |
| 77 % str(context.id) | |
| 58 if context._v_errors: | 78 if context._v_errors: |
| 59 s = s + '<br>' + '<br>'.join( | 79 s = s + '<br>' + '<br>'.join( |
| 60 [esc(x) for x in context._v_errors]) | 80 [esc(x) for x in context._v_errors]) |
| 61 l.append('<li>%s</li>'%s) | 81 l.append('<li>%s</li>'%s) |
| 62 elif len(ts) == 3: | 82 elif len(ts) == 3: |
| 63 supp, context, info = ts | 83 supp, context, info = ts |
| 64 l.append(''' | 84 l.append(_(''' |
| 65 <li>While evaluating the %r expression on line %d | 85 <li>While evaluating the %(info)r expression on line %(line)d |
| 66 <table class="otherinfo" style="font-size: 90%%"> | 86 <table class="otherinfo" style="font-size: 90%%"> |
| 67 <tr><th colspan="2" class="header">Current variables:</th></tr> | 87 <tr><th colspan="2" class="header">Current variables:</th></tr> |
| 68 %s | 88 %(globals)s |
| 69 %s | 89 %(locals)s |
| 70 </table></li> | 90 </table></li> |
| 71 '''%(info, context.position[0], niceDict(' ', context.global_vars), | 91 ''') % { |
| 72 niceDict(' ', context.local_vars))) | 92 'info': info, |
| 93 'line': context.position[0], | |
| 94 'globals': niceDict(' ', context.global_vars), | |
| 95 'locals': niceDict(' ', context.local_vars) | |
| 96 }) | |
| 73 | 97 |
| 74 l.append(''' | 98 l.append(''' |
| 75 </ol> | 99 </ol> |
| 76 <table style="font-size: 80%%; color: gray"> | 100 <table style="font-size: 80%%; color: gray"> |
| 77 <tr><th class="header" align="left">Full traceback:</th></tr> | 101 <tr><th class="header" align="left">%s</th></tr> |
| 78 <tr><td><pre>%s</pre></td></tr> | 102 <tr><td><pre>%s</pre></td></tr> |
| 79 </table>'''%cgi.escape(''.join(traceback.format_exception(sys.exc_type, | 103 </table>''' % (_('Full traceback:'), cgi.escape(''.join( |
| 80 sys.exc_value, sys.exc_traceback)))) | 104 traceback.format_exception(*sys.exc_info()) |
| 105 )))) | |
| 81 l.append('<p> </p>') | 106 l.append('<p> </p>') |
| 82 return '\n'.join(l) | 107 return '\n'.join(l) |
| 83 | 108 |
| 84 def html(context=5): | 109 def html(context=5, i18n=None): |
| 110 _ = get_translator(i18n) | |
| 85 etype, evalue = sys.exc_type, sys.exc_value | 111 etype, evalue = sys.exc_type, sys.exc_value |
| 86 if type(etype) is types.ClassType: | 112 if type(etype) is types.ClassType: |
| 87 etype = etype.__name__ | 113 etype = etype.__name__ |
| 88 pyver = 'Python ' + string.split(sys.version)[0] + '<br>' + sys.executable | 114 pyver = 'Python ' + string.split(sys.version)[0] + '<br>' + sys.executable |
| 89 head = pydoc.html.heading( | 115 head = pydoc.html.heading( |
| 90 '<font size=+1><strong>%s</strong>: %s</font>'%(etype, evalue), | 116 _('<font size=+1><strong>%(exc_type)s</strong>: %(exc_value)s</font>') |
| 117 % {'exc_type': etype, 'exc_value': evalue}, | |
| 91 '#ffffff', '#777777', pyver) | 118 '#ffffff', '#777777', pyver) |
| 92 | 119 |
| 93 head = head + (_('<p>A problem occurred while running a Python script. ' | 120 head = head + (_('<p>A problem occurred while running a Python script. ' |
| 94 'Here is the sequence of function calls leading up to ' | 121 'Here is the sequence of function calls leading up to ' |
| 95 'the error, with the most recent (innermost) call first. ' | 122 'the error, with the most recent (innermost) call first. ' |
| 97 | 124 |
| 98 indent = '<tt><small>%s</small> </tt>' % (' ' * 5) | 125 indent = '<tt><small>%s</small> </tt>' % (' ' * 5) |
| 99 traceback = [] | 126 traceback = [] |
| 100 for frame, file, lnum, func, lines, index in inspect.trace(context): | 127 for frame, file, lnum, func, lines, index in inspect.trace(context): |
| 101 if file is None: | 128 if file is None: |
| 102 link = '''<file is None - probably inside <tt>eval</tt> or | 129 link = _("<file is None - probably inside <tt>eval</tt> " |
| 103 <tt>exec</tt>>''' | 130 "or <tt>exec</tt>>") |
| 104 else: | 131 else: |
| 105 file = os.path.abspath(file) | 132 file = os.path.abspath(file) |
| 106 link = '<a href="file:%s">%s</a>' % (file, pydoc.html.escape(file)) | 133 link = '<a href="file:%s">%s</a>' % (file, pydoc.html.escape(file)) |
| 107 args, varargs, varkw, locals = inspect.getargvalues(frame) | 134 args, varargs, varkw, locals = inspect.getargvalues(frame) |
| 108 if func == '?': | 135 if func == '?': |
| 109 call = '' | 136 call = '' |
| 110 else: | 137 else: |
| 111 call = 'in <strong>%s</strong>' % func + inspect.formatargvalues( | 138 call = _('in <strong>%s</strong>') % func + inspect.formatargvalues( |
| 112 args, varargs, varkw, locals, | 139 args, varargs, varkw, locals, |
| 113 formatvalue=lambda value: '=' + pydoc.html.repr(value)) | 140 formatvalue=lambda value: '=' + pydoc.html.repr(value)) |
| 114 | 141 |
| 115 level = ''' | 142 level = ''' |
| 116 <table width="100%%" bgcolor="#dddddd" cellspacing=0 cellpadding=2 border=0> | 143 <table width="100%%" bgcolor="#dddddd" cellspacing=0 cellpadding=2 border=0> |
| 187 | 214 |
| 188 def handler(): | 215 def handler(): |
| 189 print breaker() | 216 print breaker() |
| 190 print html() | 217 print html() |
| 191 | 218 |
| 192 # vim: set filetype=python ts=4 sw=4 et si | 219 # vim: set filetype=python ts=4 sw=4 et si : |
