Flask update
@@ -5,7 +5,7 @@
|
||||
|
||||
WSGI application traceback debugger.
|
||||
|
||||
:copyright: (c) 2010 by the Werkzeug Team, see AUTHORS for more details.
|
||||
:copyright: (c) 2011 by the Werkzeug Team, see AUTHORS for more details.
|
||||
:license: BSD, see LICENSE for more details.
|
||||
"""
|
||||
import mimetypes
|
||||
@@ -13,6 +13,7 @@ from os.path import join, dirname, basename, isfile
|
||||
from werkzeug.wrappers import BaseRequest as Request, BaseResponse as Response
|
||||
from werkzeug.debug.tbtools import get_current_traceback, render_console_html
|
||||
from werkzeug.debug.console import Console
|
||||
from werkzeug.security import gen_salt
|
||||
|
||||
|
||||
#: import this here because it once was documented as being available
|
||||
@@ -77,7 +78,8 @@ class DebuggedApplication(object):
|
||||
self.console_path = console_path
|
||||
self.console_init_func = console_init_func
|
||||
self.show_hidden_frames = show_hidden_frames
|
||||
self.lodgeit_url=lodgeit_url
|
||||
self.lodgeit_url = lodgeit_url
|
||||
self.secret = gen_salt(20)
|
||||
|
||||
def debug_application(self, environ, start_response):
|
||||
"""Run the application and conserve the traceback frames."""
|
||||
@@ -113,7 +115,8 @@ class DebuggedApplication(object):
|
||||
'sent.\n')
|
||||
else:
|
||||
yield traceback.render_full(evalex=self.evalex,
|
||||
lodgeit_url=self.lodgeit_url) \
|
||||
lodgeit_url=self.lodgeit_url,
|
||||
secret=self.secret) \
|
||||
.encode('utf-8', 'replace')
|
||||
|
||||
traceback.log(environ['wsgi.errors'])
|
||||
@@ -126,12 +129,13 @@ class DebuggedApplication(object):
|
||||
"""Display a standalone shell."""
|
||||
if 0 not in self.frames:
|
||||
self.frames[0] = _ConsoleFrame(self.console_init_func())
|
||||
return Response(render_console_html(), mimetype='text/html')
|
||||
return Response(render_console_html(secret=self.secret),
|
||||
mimetype='text/html')
|
||||
|
||||
def paste_traceback(self, request, traceback):
|
||||
"""Paste the traceback and return a JSON response."""
|
||||
paste_id = traceback.paste(self.lodgeit_url)
|
||||
return Response('{"url": "%sshow/%s/", "id": %s}'
|
||||
return Response('{"url": "%sshow/%s/", "id": "%s"}'
|
||||
% (self.lodgeit_url, paste_id, paste_id),
|
||||
mimetype='application/json')
|
||||
|
||||
@@ -162,15 +166,18 @@ class DebuggedApplication(object):
|
||||
if request.args.get('__debugger__') == 'yes':
|
||||
cmd = request.args.get('cmd')
|
||||
arg = request.args.get('f')
|
||||
secret = request.args.get('s')
|
||||
traceback = self.tracebacks.get(request.args.get('tb', type=int))
|
||||
frame = self.frames.get(request.args.get('frm', type=int))
|
||||
if cmd == 'resource' and arg:
|
||||
response = self.get_resource(request, arg)
|
||||
elif cmd == 'paste' and traceback is not None:
|
||||
elif cmd == 'paste' and traceback is not None and \
|
||||
secret == self.secret:
|
||||
response = self.paste_traceback(request, traceback)
|
||||
elif cmd == 'source' and frame:
|
||||
elif cmd == 'source' and frame and self.secret == secret:
|
||||
response = self.get_source(request, frame)
|
||||
elif self.evalex and cmd is not None and frame is not None:
|
||||
elif self.evalex and cmd is not None and frame is not None and \
|
||||
self.secret == secret:
|
||||
response = self.execute_command(request, cmd, frame)
|
||||
elif self.evalex and self.console_path is not None and \
|
||||
request.path == self.console_path:
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
Interactive console support.
|
||||
|
||||
:copyright: (c) 2010 by the Werkzeug Team, see AUTHORS for more details.
|
||||
:copyright: (c) 2011 by the Werkzeug Team, see AUTHORS for more details.
|
||||
:license: BSD.
|
||||
"""
|
||||
import sys
|
||||
@@ -35,10 +35,14 @@ class HTMLStringO(object):
|
||||
pass
|
||||
|
||||
def seek(self, n, mode=0):
|
||||
raise IOError('Bad file descriptor')
|
||||
pass
|
||||
|
||||
def readline(self):
|
||||
raise IOError('Bad file descriptor')
|
||||
if len(self._buffer) == 0:
|
||||
return ''
|
||||
ret = self._buffer[0]
|
||||
del self._buffer[0]
|
||||
return ret
|
||||
|
||||
def reset(self):
|
||||
val = ''.join(self._buffer)
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
werkzeug.debug.render
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Render the traceback debugging page.
|
||||
|
||||
:copyright: (c) 2010 by the Werkzeug Team, see AUTHORS for more details.
|
||||
:license: BSD, see LICENSE for more details.
|
||||
"""
|
||||
import pprint
|
||||
from os.path import dirname, join
|
||||
|
||||
from werkzeug.templates import Template
|
||||
|
||||
|
||||
def get_template(name):
|
||||
return Template.from_file(join(dirname(__file__), 'shared', name),
|
||||
unicode_mode=False, errors='ignore')
|
||||
|
||||
|
||||
def load_resource(res):
|
||||
try:
|
||||
f = file(join(dirname(__file__), 'shared', res))
|
||||
except IOError:
|
||||
return ''
|
||||
try:
|
||||
return f.read()
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
|
||||
t_body = get_template('body.tmpl')
|
||||
t_codetable = get_template('codetable.tmpl')
|
||||
t_vartable = get_template('vartable.tmpl')
|
||||
|
||||
|
||||
def code_table(frame):
|
||||
from werkzeug.debug.util import Namespace
|
||||
lines = []
|
||||
lineno = frame['context_lineno']
|
||||
if lineno is not None:
|
||||
lineno += 1
|
||||
for l in frame['pre_context']:
|
||||
lines.append(Namespace(mode='pre', lineno=lineno, code=l))
|
||||
lineno += 1
|
||||
lines.append(Namespace(mode='cur', lineno=lineno,
|
||||
code=frame['context_line']))
|
||||
lineno += 1
|
||||
for l in frame['post_context']:
|
||||
lines.append(Namespace(mode='post', lineno=lineno, code=l))
|
||||
lineno += 1
|
||||
else:
|
||||
lines.append(Namespace(mode='cur', lineno=1,
|
||||
code='Sourcecode not available'))
|
||||
|
||||
return t_codetable.render(lines=lines)
|
||||
|
||||
|
||||
def var_table(var):
|
||||
def safe_pformat(x):
|
||||
try:
|
||||
lines = pprint.pformat(x).splitlines()
|
||||
except Exception:
|
||||
return '?'
|
||||
tmp = []
|
||||
for line in lines:
|
||||
if len(line) > 79:
|
||||
line = line[:79] + '...'
|
||||
tmp.append(line)
|
||||
return '\n'.join(tmp)
|
||||
|
||||
# dicts
|
||||
if isinstance(var, dict) or hasattr(var, 'items'):
|
||||
value = var.items()
|
||||
if not value:
|
||||
typ = 'empty'
|
||||
else:
|
||||
typ = 'dict'
|
||||
value.sort()
|
||||
value = [(repr(key), safe_pformat(val)) for key, val in value]
|
||||
|
||||
# lists
|
||||
elif isinstance(var, list):
|
||||
if not var:
|
||||
typ = 'empty'
|
||||
else:
|
||||
typ = 'list'
|
||||
value = [safe_pformat(item) for item in var]
|
||||
|
||||
# others
|
||||
else:
|
||||
typ = 'simple'
|
||||
value = repr(var)
|
||||
|
||||
return t_vartable.render(type=typ, value=value)
|
||||
|
||||
|
||||
def debug_page(context):
|
||||
tc = context.to_dict()
|
||||
tc['var_table'] = var_table
|
||||
tc['code_table'] = code_table
|
||||
return t_body.render(tc)
|
||||
@@ -10,7 +10,7 @@
|
||||
Together with the CSS and JavaScript files of the debugger this gives
|
||||
a colorful and more compact output.
|
||||
|
||||
:copyright: (c) 2010 by the Werkzeug Team, see AUTHORS for more details.
|
||||
:copyright: (c) 2011 by the Werkzeug Team, see AUTHORS for more details.
|
||||
:license: BSD.
|
||||
"""
|
||||
import sys
|
||||
|
||||
|
Before Width: | Height: | Size: 507 B After Width: | Height: | Size: 507 B |
@@ -45,7 +45,7 @@ $(function() {
|
||||
sourceView.slideUp('fast');
|
||||
});
|
||||
$.get(document.location.pathname, {__debugger__: 'yes', cmd:
|
||||
'source', frm: frameID}, function(data) {
|
||||
'source', frm: frameID, s: SECRET}, function(data) {
|
||||
$('table', sourceView)
|
||||
.replaceWith(data);
|
||||
if (!sourceView.is(':visible'))
|
||||
@@ -96,7 +96,8 @@ $(function() {
|
||||
$.ajax({
|
||||
dataType: 'json',
|
||||
url: document.location.pathname,
|
||||
data: {__debugger__: 'yes', tb: TRACEBACK, cmd: 'paste'},
|
||||
data: {__debugger__: 'yes', tb: TRACEBACK, cmd: 'paste',
|
||||
s: SECRET},
|
||||
success: function(data) {
|
||||
$('div.plain span.pastemessage')
|
||||
.removeClass('pastemessage')
|
||||
@@ -134,7 +135,7 @@ function openShell(consoleNode, target, frameID) {
|
||||
.submit(function() {
|
||||
var cmd = command.val();
|
||||
$.get(document.location.pathname, {
|
||||
__debugger__: 'yes', cmd: cmd, frm: frameID}, function(data) {
|
||||
__debugger__: 'yes', cmd: cmd, frm: frameID, s: SECRET}, function(data) {
|
||||
var tmp = $('<div>').html(data);
|
||||
$('span.extended', tmp).each(function() {
|
||||
var hidden = $(this).wrap('<span>').hide();
|
||||
|
||||
|
Before Width: | Height: | Size: 191 B After Width: | Height: | Size: 191 B |
|
Before Width: | Height: | Size: 200 B After Width: | Height: | Size: 200 B |
|
Before Width: | Height: | Size: 818 B After Width: | Height: | Size: 818 B |
@@ -23,7 +23,7 @@ textarea { font-family: 'Consolas', 'Monaco', 'Bitstream Vera Sans Mono',
|
||||
div.debugger { text-align: left; padding: 12px; margin: auto;
|
||||
background-color: white; }
|
||||
h1 { font-size: 36px; margin: 0 0 0.3em 0; }
|
||||
div.detail p { margin: 0 0 8px 13px; font-size: 14px; }
|
||||
div.detail p { margin: 0 0 8px 13px; font-size: 14px; white-space: pre-wrap; }
|
||||
div.explanation { margin: 20px 13px; font-size: 15px; color: #555; }
|
||||
div.footer { font-size: 13px; text-align: right; margin: 30px 0;
|
||||
color: #86989B; }
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
This module provides various traceback related utility functions.
|
||||
|
||||
:copyright: (c) 2010 by the Werkzeug Team, see AUTHORS for more details.
|
||||
:copyright: (c) 2011 by the Werkzeug Team, see AUTHORS for more details.
|
||||
:license: BSD.
|
||||
"""
|
||||
import re
|
||||
@@ -42,7 +42,8 @@ HEADER = u'''\
|
||||
<script type="text/javascript">
|
||||
var TRACEBACK = %(traceback_id)d,
|
||||
CONSOLE_MODE = %(console)s,
|
||||
EVALEX = %(evalex)s
|
||||
EVALEX = %(evalex)s,
|
||||
SECRET = "%(secret)s";
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
@@ -127,11 +128,12 @@ SOURCE_LINE_HTML = u'''\
|
||||
'''
|
||||
|
||||
|
||||
def render_console_html():
|
||||
def render_console_html(secret):
|
||||
return CONSOLE_HTML % {
|
||||
'evalex': 'true',
|
||||
'console': 'true',
|
||||
'title': 'Console',
|
||||
'secret': secret,
|
||||
'traceback_id': -1
|
||||
}
|
||||
|
||||
@@ -261,7 +263,7 @@ class Traceback(object):
|
||||
"""Create a paste and return the paste id."""
|
||||
from xmlrpclib import ServerProxy
|
||||
srv = ServerProxy('%sxmlrpc/' % lodgeit_url)
|
||||
return srv.pastes.newPaste('pytb', self.plaintext)
|
||||
return srv.pastes.newPaste('pytb', self.plaintext, '', '', '', True)
|
||||
|
||||
def render_summary(self, include_title=True):
|
||||
"""Render the traceback for the interactive console."""
|
||||
@@ -296,7 +298,8 @@ class Traceback(object):
|
||||
'description': description_wrapper % escape(self.exception)
|
||||
}
|
||||
|
||||
def render_full(self, evalex=False, lodgeit_url=None):
|
||||
def render_full(self, evalex=False, lodgeit_url=None,
|
||||
secret=None):
|
||||
"""Render the Full HTML page with the traceback info."""
|
||||
exc = escape(self.exception)
|
||||
return PAGE_HTML % {
|
||||
@@ -309,7 +312,8 @@ class Traceback(object):
|
||||
'summary': self.render_summary(include_title=False),
|
||||
'plaintext': self.plaintext,
|
||||
'plaintext_cs': re.sub('-{2,}', '-', self.plaintext),
|
||||
'traceback_id': self.id
|
||||
'traceback_id': self.id,
|
||||
'secret': secret
|
||||
}
|
||||
|
||||
def generate_plaintext_traceback(self):
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
werkzeug.debug.utils
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Various other utilities.
|
||||
|
||||
:copyright: (c) 2010 by the Werkzeug Team, see AUTHORS for more details.
|
||||
:license: BSD.
|
||||
"""
|
||||
from os.path import join, dirname
|
||||
from werkzeug.templates import Template
|
||||
|
||||
|
||||
def get_template(filename):
|
||||
return Template.from_file(join(dirname(__file__), 'templates', filename))
|
||||
|
||||
|
||||
def render_template(template_filename, **context):
|
||||
return get_template(template_filename).render(**context)
|
||||