24 Commits
0.6 ... 0.6.1

Author SHA1 Message Date
Matt Good
e92c102bc9 Prepare 0.6.1 release 2012-02-15 12:35:58 -08:00
Matt Good
20a302c3b4 Fix request vars display for non-string values (fixes #14) 2012-02-15 12:28:28 -08:00
Matt Good
bdbc570c91 Fix memory leak from holding reference to toolbar (fixes #10) 2012-02-14 23:56:36 -08:00
Matt Good
17b629742d Add protocol to django-debug-toolbar link in readme 2012-02-14 19:17:49 -08:00
Matt Good
54a18b8cf2 Improve the readme example (fixes #8) 2012-02-14 19:14:37 -08:00
Matt Good
a48efe822a Escape non-printable values in request vars panel (fixes #9) 2012-02-14 18:51:21 -08:00
Matt Good
45ce65c058 Merge branch 'mono-fonts' 2012-01-31 11:03:38 -08:00
Matt Good
89fbe2e6b5 Let DEBUG_TB_ENABLED take precedence over app.debug 2012-01-31 11:02:30 -08:00
Matt Good
e5feff5884 Merge pull request #7 from joeshaw/joeshaw-enabled-setting
add DEBUG_TB_ENABLED setting which overrides app.debug check
2012-01-31 10:59:32 -08:00
Matt Good
93008a8e53 Make table bodies use mono-spaced font 2012-01-31 10:52:55 -08:00
Matt Good
8bb829e1e4 Make font reset easier to override 2012-01-31 10:25:17 -08:00
Matt Good
70478ffcc2 Merge pull request #5 from kennethreitz/patch-1
Requiring setuptools is evil :)
2012-01-31 00:50:27 -08:00
Joe Shaw
6f6b1cb47d add DEBUG_TB_ENABLED setting which overrides app.debug check 2012-01-30 23:41:43 -05:00
Kenneth Reitz
1834443246 Requiring setuptools is evil :) 2012-01-30 22:26:37 -05:00
Matt Good
c3c2714ace Merge pull request #3 from kennethreitz/readme
Updated Readme
2012-01-30 17:50:38 -08:00
Kenneth Reitz
884451669c (sp) 2012-01-30 20:48:03 -05:00
Matt Good
0bdc3f7e59 Merge pull request #2 from kennethreitz/logo
Flask Logo
2012-01-30 17:47:45 -08:00
Kenneth Reitz
43b069905d readme fix 2012-01-30 20:46:41 -05:00
Kenneth Reitz
d85ce273af squash all the PNGs 2012-01-30 20:42:00 -05:00
Kenneth Reitz
69d137c2d7 new django flask icon 2012-01-30 20:41:50 -05:00
Kenneth Reitz
7988e5f472 new read me 2012-01-30 20:29:57 -05:00
Matt Good
1c8465cdd9 Minor style update (trailing whitespace and "if len()") 2012-01-04 08:49:25 -08:00
Matt Good
f59705a7e7 Merge commit 'd886f5a606f26d78df457e7041c5666e0e5bbc6d' 2012-01-04 08:42:21 -08:00
Dmitry Ishutkin
d886f5a606 add hosts setting
app.config['DEBUG_TB_HOSTS']

Example: app.config['DEBUG_TB_HOSTS'] = ( '127.0.0.1', '::1' )

If the request’s REMOTE_ADDR is not in this list, the toolbar will not
be displayed and the exception handler will not be active. This should
be a tuple. Default: (). Empty list remains backward compatibility. If
DEBUG_TB_HOSTS not specified in app.config, the debug toolbar is shown
for all addresses.
2011-09-30 18:30:56 +08:00
17 changed files with 195 additions and 118 deletions

36
CHANGES.rst Normal file
View File

@@ -0,0 +1,36 @@
Changes
=======
0.6.1 (2012-02-15)
------------------
Fixes:
- Memory leak when toolbar was enabled
- UnicodeDecodeError when request data contained binary data (e.g. session values)
Enhancements:
- ``DEBUG_TB_ENABLED`` config setting to explicitly enable or disable the toolbar
- ``DEBUG_TB_HOSTS`` config setting to enable toolbar only for specific remote hosts
- New logo for Flask instead of Django
- Monospaced font on table data
Thanks to kennethreitz and joeshaw for their contributions.
0.6 (2012-01-04)
----------------
Flask 0.8 or higher is required
Enhancements:
- Flask 0.8 compatibility
Thanks to mvantellingen

12
README
View File

@@ -1,12 +0,0 @@
Flask Debug-toolbar
A port of the django-debug toolbar (github.com/robhudson/django-debug-toolbar)
to Flask.
Usage::
from flask import Flask
from flask_debugtoolbar import DebugToolbarExtension
app = Flask(__name__)
toolbar = DebugToolbarExtension(app)

36
README.rst Normal file
View File

@@ -0,0 +1,36 @@
Flask Debug-toolbar
===================
This is a port of the excellent `django-debug-toolbar <https://github.com/django-debug-toolbar/django-debug-toolbar>`_
for Flask applications.
Usage
-----
Installing the debug toolbar is simple::
from flask import Flask
from flask_debugtoolbar import DebugToolbarExtension
app = Flask(__name__)
# the toolbar is only enabled in debug mode:
app.debug = True
# set a 'SECRET_KEY' to enable the Flask session cookies
app.config['SECRET_KEY'] = '<replace with a secret key>'
toolbar = DebugToolbarExtension(app)
The toolbar will automatically be injected into Jinja templates when debug mode is on.
In production, setting ``app.debug = False`` will disable the toolbar.
Installation
------------
Installing is simple with pip::
$ pip install flask-debugtoolbar

View File

@@ -14,6 +14,7 @@ app.config['DEBUG_TB_INTERCEPT_REDIRECTS'] = True
# 'flask_debugtoolbar.panels.logger.LoggingPanel',
# 'flask_debugtoolbar.panels.timer.TimerDebugPanel',
#)
#app.config['DEBUG_TB_HOSTS'] = ('127.0.0.1', '::1' )
app.config['SECRET_KEY'] = 'asd'
app.config['DEBUG'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'

View File

@@ -25,6 +25,15 @@ def replace_insensitive(string, target, replacement):
return string
def _printable(value):
if isinstance(value, unicode):
return value.encode('unicode_escape')
elif isinstance(value, str):
return value.encode('string_escape')
else:
return repr(value)
class DebugToolbarExtension(object):
_static_dir = os.path.realpath(
os.path.join(os.path.dirname(__file__), 'static'))
@@ -34,8 +43,9 @@ class DebugToolbarExtension(object):
def __init__(self, app):
self.app = app
self.debug_toolbars = {}
self.hosts = ()
if not app.debug:
if not app.config.get('DEBUG_TB_ENABLED', app.debug):
return
if not app.config.get('SECRET_KEY'):
@@ -45,8 +55,11 @@ class DebugToolbarExtension(object):
DebugToolbar.load_panels(app)
self.hosts = app.config.get('DEBUG_TB_HOSTS', ())
self.app.before_request(self.process_request)
self.app.after_request(self.process_response)
self.app.teardown_request(self.teardown_request)
# Monkey-patch the Flask.dispatch_request method
app.dispatch_request = self.dispatch_request
@@ -58,6 +71,7 @@ class DebugToolbarExtension(object):
extensions=['jinja2.ext.i18n'],
loader=PackageLoader(__name__, 'templates'))
self.jinja_env.filters['urlencode'] = url_quote_plus
self.jinja_env.filters['printable'] = _printable
app.add_url_rule('/_debug_toolbar/static/<path:filename>',
'_debug_toolbar.static', self.send_static_file)
@@ -90,6 +104,10 @@ class DebugToolbarExtension(object):
"""Return a boolean to indicate if we need to show the toolbar."""
if request.path.startswith('/_debug_toolbar/'):
return False
if self.hosts and request.remote_addr not in self.hosts:
return False
return True
def send_static_file(self, filename):
@@ -160,6 +178,9 @@ class DebugToolbarExtension(object):
return response
def teardown_request(self, exc):
self.debug_toolbars.pop(request._get_current_object(), None)
def render(self, template_name, context):
template = self.jinja_env.get_template(template_name)
return template.render(**context)

View File

@@ -1,5 +1,4 @@
/* Debug Toolbar CSS Reset, adapted from Eric Meyer's CSS Reset */
#flDebug {color:#000;background:#FFF;}
#flDebug, #flDebug div, #flDebug span, #flDebug applet, #flDebug object, #flDebug iframe,
#flDebug h1, #flDebug h2, #flDebug h3, #flDebug h4, #flDebug h5, #flDebug h6, #flDebug p, #flDebug blockquote, #flDebug pre,
#flDebug a, #flDebug abbr, #flDebug acronym, #flDebug address, #flDebug big, #flDebug cite, #flDebug code,
@@ -18,10 +17,16 @@
color:#000;
vertical-align:baseline;
background:transparent;
font-family:sans-serif;
font-family: inherit;
text-align:left;
}
#flDebug { font-family: sans-serif; color: #000; background: #fff; }
#flDebug tbody, #flDebug code {
font-family: Consolas, Monaco, "Bitstream Vera Sans Mono", "Lucida Console", monospace;
}
#flDebug #flDebugToolbar {
background:#111;
width:200px;
@@ -152,7 +157,6 @@
#flDebug code {
display:block;
font-family:Consolas, Monaco, "Bitstream Vera Sans Mono", "Lucida Console", monospace;
white-space:pre;
overflow:auto;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 575 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 604 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 711 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 404 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 607 B

After

Width:  |  Height:  |  Size: 444 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 B

After

Width:  |  Height:  |  Size: 70 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 538 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 634 B

After

Width:  |  Height:  |  Size: 569 B

View File

@@ -1,123 +1,104 @@
<h4>View information</h4>
<table>
<thead>
<tr>
<th>View Function</th>
<th>args</th>
<th>kwargs</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ view_func }}</td>
<td>{{ view_args|default("None") }}</td>
<td>
{% if view_kwargs.items() %}
{% for k, v in view_kwargs.items() %}
{{ k }}={{ v }}{% if not loop.last %}, {% endif %}
{% endfor %}
{% else %}
None
{% endif %}
</td>
</tr>
</tbody>
<thead>
<tr>
<th>View Function</th>
<th>args</th>
<th>kwargs</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ view_func }}</td>
<td>{{ view_args|default("None") }}</td>
<td>
{% if view_kwargs.items() %}
{% for k, v in view_kwargs.items() %}
{{ k }}={{ v }}{% if not loop.last %}, {% endif %}
{% endfor %}
{% else %}
None
{% endif %}
</td>
</tr>
</tbody>
</table>
{% macro show_map(map) %}
<table>
<colgroup>
<col style="width:20%"/>
<col/>
</colgroup>
<thead>
<tr>
<th>Variable</th>
<th>Value</th>
</tr>
</thead>
<tbody>
{% for key, value in map %}
<tr class="{{ loop.cycle('flDebugOdd' 'flDebugEven') }}">
<td>{{ key|printable }}</td>
<td>{{ value|printable }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endmacro %}
<h4>COOKIES Variables</h4>
{% if cookies %}
<table>
<colgroup>
<col style="width:20%"/>
<col/>
</colgroup>
<thead>
<tr>
<th>Variable</th>
<th>Value</th>
</tr>
</thead>
<tbody>
{% for key, value in cookies %}
<tr class="{{ loop.cycle('flDebugOdd' 'flDebugEven') }}">
<td>{{ key|escape }}</td>
<td>{{ value|escape }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{{ show_map(cookies) }}
{% else %}
<p>No COOKIE data</p>
<p>No COOKIE data</p>
{% endif %}
<h4>SESSION Variables</h4>
{% if session %}
<table>
<colgroup>
<col style="width:20%"/>
<col/>
</colgroup>
<thead>
<tr>
<th>Variable</th>
<th>Value</th>
</tr>
</thead>
<tbody>
{% for key, value in session %}
<tr class="{{ loop.cycle('flDebugOdd' 'flDebugEven') }}">
<td>{{ key|escape }}</td>
<td>{{ value|escape }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{{ show_map(session) }}
{% else %}
<p>No SESSION data</p>
<p>No SESSION data</p>
{% endif %}
{% macro show_multi_map(map) %}
<table>
<thead>
<tr>
<th>Variable</th>
<th>Value</th>
</tr>
</thead>
<tbody>
{% for key, value in map %}
<tr class="{{ loop.cycle('flDebugOdd' 'flDebugEven') }}">
<td>{{ key|printable }}</td>
<td>
{%- set sep = joiner() -%}
{%- for v in value -%}
{{ sep() }}{{ v|printable }}
{%- endfor -%}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endmacro %}
<h4>GET Variables</h4>
{% if get %}
<table>
<thead>
<tr>
<th>Variable</th>
<th>Value</th>
</tr>
</thead>
<tbody>
{% for key, value in get %}
<tr class="{{ loop.cycle('flDebugOdd' 'flDebugEven') }}">
<td>{{ key|escape }}</td>
<td>{{ value|join(", ")|escape }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{{ show_multi_map(get) }}
{% else %}
<p>No GET data</p>
<p>No GET data</p>
{% endif %}
<h4>POST Variables</h4>
{% if post %}
<table>
<thead>
<tr>
<th>Variable</th>
<th>Value</th>
</tr>
</thead>
<tbody>
{% for key, value in post %}
<tr class="{{ loop.cycle('row1' 'row2') }}">
<td>{{ key|escape }}</td>
<td>{{ value|join(", ")|escape }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{{ show_multi_map(post) }}
{% else %}
<p>No POST data</p>
<p>No POST data</p>
{% endif %}

View File

@@ -1,9 +1,20 @@
import os
from setuptools import setup, find_packages
here = os.path.abspath(os.path.dirname(__file__))
try:
README = open(os.path.join(here, 'README.rst')).read()
CHANGES = open(os.path.join(here, 'CHANGES.rst')).read()
except:
README = ''
CHANGES = ''
setup(
name='Flask-DebugToolbar',
version='0.6',
version='0.6.1',
url='http://github.com/mgood/flask-debugtoolbar',
license='BSD',
author='Michael van Tellingen',
@@ -11,7 +22,7 @@ setup(
maintainer='Matt Good',
maintainer_email='matt@matt-good.net',
description='A port of the Django debug toolbar to Flask',
long_description=__doc__,
long_description=README + '\n\n' + CHANGES,
zip_safe=False,
platforms='any',
include_package_data=True,
@@ -19,7 +30,6 @@ setup(
'flask_debugtoolbar.panels'
],
install_requires=[
'setuptools',
'Flask>=0.8',
'Blinker',
],