mirror of
https://github.com/pallets-eco/flask-debugtoolbar.git
synced 2025-12-31 02:29:33 -06:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a758a9df7a | ||
|
|
5eea25882c | ||
|
|
e954cd9fae | ||
|
|
03d79be02c | ||
|
|
7f17d2ce57 | ||
|
|
30fba11f36 | ||
|
|
d474a6a689 | ||
|
|
83d398d9d5 | ||
|
|
3929742d9c | ||
|
|
70abd78e55 | ||
|
|
dbea74b626 | ||
|
|
c6102aeb14 | ||
|
|
10c9c1ae5d | ||
|
|
9e600c6e13 | ||
|
|
9b8a8afa97 | ||
|
|
39ac97a7e0 | ||
|
|
a5cb5a709f |
31
CHANGES.rst
31
CHANGES.rst
@@ -1,6 +1,37 @@
|
||||
Changes
|
||||
=======
|
||||
|
||||
0.13.0 (Unreleased)
|
||||
-------------------
|
||||
|
||||
Enhancements:
|
||||
- ??
|
||||
|
||||
Fixes:
|
||||
- ??
|
||||
|
||||
0.12.1 (2022-03-28)
|
||||
-------------------
|
||||
|
||||
Fixes:
|
||||
- Correct changelog and docs URLs on PyPI
|
||||
|
||||
|
||||
0.12.0 (2022-03-28)
|
||||
-------------------
|
||||
|
||||
Enhancements:
|
||||
- Add flask.g section to show g object content. by @Yaser-Amiri in https://github.com/flask-debugtoolbar/flask-debugtoolbar/pull/118
|
||||
- Support gzip response by @zaw007 in https://github.com/flask-debugtoolbar/flask-debugtoolbar/pull/154
|
||||
- Update PyPI metadata files: add `setup.cfg` etc by @jeffwidman in https://github.com/flask-debugtoolbar/flask-debugtoolbar/pull/164
|
||||
|
||||
Fixes:
|
||||
- Remove deprecated Jinja with_ extension for Jinja 3.0 (related to Flask 2.0) by @nickjj in https://github.com/flask-debugtoolbar/flask-debugtoolbar/pull/157
|
||||
- Fix SQLAlchemy SELECT/EXPLAIN to use url_for to respect app prefixes.… by @mattaw in https://github.com/flask-debugtoolbar/flask-debugtoolbar/pull/143
|
||||
- Setup DB properly by @jeffwidman in https://github.com/flask-debugtoolbar/flask-debugtoolbar/pull/148
|
||||
- prefixed css classes, fixes #152 by @jnnkB in https://github.com/flask-debugtoolbar/flask-debugtoolbar/pull/153
|
||||
|
||||
|
||||
0.11.0 (2020-02-18)
|
||||
-------------------
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@ 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.
|
||||
|
||||
.. image:: https://travis-ci.org/mgood/flask-debugtoolbar.png?branch=master
|
||||
:target: https://travis-ci.org/mgood/flask-debugtoolbar
|
||||
.. image:: https://travis-ci.org/flask-debugtoolbar/flask-debugtoolbar.png?branch=master
|
||||
:target: https://travis-ci.org/flask-debugtoolbar/flask-debugtoolbar
|
||||
|
||||
|
||||
Installation
|
||||
|
||||
@@ -13,9 +13,12 @@
|
||||
|
||||
import datetime
|
||||
import os
|
||||
import pkg_resources
|
||||
import sys
|
||||
import time
|
||||
|
||||
import flask_debugtoolbar
|
||||
|
||||
|
||||
BUILD_DATE = datetime.datetime.utcfromtimestamp(int(os.environ.get('SOURCE_DATE_EPOCH', time.time())))
|
||||
|
||||
@@ -56,10 +59,10 @@ copyright = u'2012-{0}'.format(BUILD_DATE.year)
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '0.11.0'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '0.11.0'
|
||||
release = flask_debugtoolbar.__version__
|
||||
# The short X.Y version.
|
||||
version = '.'.join(release.split('.')[:2])
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
||||
@@ -29,6 +29,11 @@ class ExampleModel(db.Model):
|
||||
value = db.Column(db.String(100), primary_key=True)
|
||||
|
||||
|
||||
@app.before_first_request
|
||||
def setup():
|
||||
db.create_all()
|
||||
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
app.logger.info("Hello there")
|
||||
@@ -38,11 +43,6 @@ def index():
|
||||
|
||||
@app.route('/redirect')
|
||||
def redirect_example():
|
||||
|
||||
response = redirect(url_for('index'))
|
||||
response.set_cookie('test_cookie', '1')
|
||||
return response
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
db.create_all()
|
||||
|
||||
@@ -1,14 +1,25 @@
|
||||
import os
|
||||
import warnings
|
||||
|
||||
from flask import Blueprint, current_app, request, g, send_from_directory
|
||||
from flask import Blueprint, current_app, request, g, send_from_directory, url_for
|
||||
from flask.globals import _request_ctx_stack
|
||||
from jinja2 import __version__ as __jinja_version__
|
||||
from jinja2 import Environment, PackageLoader
|
||||
from werkzeug.urls import url_quote_plus
|
||||
|
||||
from flask_debugtoolbar.compat import iteritems
|
||||
from flask_debugtoolbar.toolbar import DebugToolbar
|
||||
from flask_debugtoolbar.utils import decode_text
|
||||
from flask_debugtoolbar.utils import decode_text, gzip_compress, gzip_decompress
|
||||
|
||||
try:
|
||||
# Python 3.8+
|
||||
from importlib.metadata import version
|
||||
|
||||
__version__ = version("Flask-DebugToolbar")
|
||||
except ImportError:
|
||||
import pkg_resources
|
||||
|
||||
__version__ = pkg_resources.get_distribution("Flask-DebugToolbar").version
|
||||
|
||||
|
||||
module = Blueprint('debugtoolbar', __name__)
|
||||
@@ -44,15 +55,20 @@ class DebugToolbarExtension(object):
|
||||
def __init__(self, app=None):
|
||||
self.app = app
|
||||
self.debug_toolbars = {}
|
||||
jinja_extensions = ['jinja2.ext.i18n']
|
||||
|
||||
if __jinja_version__[0] == '2':
|
||||
jinja_extensions.append('jinja2.ext.with_')
|
||||
|
||||
# Configure jinja for the internal templates and add url rules
|
||||
# for static data
|
||||
self.jinja_env = Environment(
|
||||
autoescape=True,
|
||||
extensions=['jinja2.ext.i18n', 'jinja2.ext.with_'],
|
||||
extensions=jinja_extensions,
|
||||
loader=PackageLoader(__name__, 'templates'))
|
||||
self.jinja_env.filters['urlencode'] = url_quote_plus
|
||||
self.jinja_env.filters['printable'] = _printable
|
||||
self.jinja_env.globals['url_for'] = url_for
|
||||
|
||||
if app is not None:
|
||||
self.init_app(app)
|
||||
@@ -99,6 +115,7 @@ class DebugToolbarExtension(object):
|
||||
'flask_debugtoolbar.panels.logger.LoggingPanel',
|
||||
'flask_debugtoolbar.panels.route_list.RouteListDebugPanel',
|
||||
'flask_debugtoolbar.panels.profiler.ProfilerDebugPanel',
|
||||
'flask_debugtoolbar.panels.g.GDebugPanel',
|
||||
),
|
||||
}
|
||||
|
||||
@@ -198,7 +215,10 @@ class DebugToolbarExtension(object):
|
||||
response.headers['content-type'].startswith('text/html')):
|
||||
return response
|
||||
|
||||
response_html = response.data.decode(response.charset)
|
||||
if 'gzip' in response.headers.get('Content-Encoding', ''):
|
||||
response_html = gzip_decompress(response.data).decode(response.charset)
|
||||
else:
|
||||
response_html = response.data.decode(response.charset)
|
||||
|
||||
no_case = response_html.lower()
|
||||
body_end = no_case.rfind('</body>')
|
||||
@@ -223,6 +243,8 @@ class DebugToolbarExtension(object):
|
||||
|
||||
content = ''.join((before, toolbar_html, after))
|
||||
content = content.encode(response.charset)
|
||||
if 'gzip' in response.headers.get('Content-Encoding', ''):
|
||||
content = gzip_compress(content)
|
||||
response.response = [content]
|
||||
response.content_length = len(content)
|
||||
|
||||
|
||||
29
flask_debugtoolbar/panels/g.py
Normal file
29
flask_debugtoolbar/panels/g.py
Normal file
@@ -0,0 +1,29 @@
|
||||
from flask import g
|
||||
from flask_debugtoolbar.panels import DebugPanel
|
||||
|
||||
_ = lambda x: x
|
||||
|
||||
|
||||
class GDebugPanel(DebugPanel):
|
||||
"""
|
||||
A panel to display flask.g content.
|
||||
"""
|
||||
name = 'g'
|
||||
has_content = True
|
||||
|
||||
def nav_title(self):
|
||||
return _('flask.g')
|
||||
|
||||
def title(self):
|
||||
return _('flask.g content')
|
||||
|
||||
def url(self):
|
||||
return ''
|
||||
|
||||
def content(self):
|
||||
context = self.context.copy()
|
||||
context.update({
|
||||
'g_content': g.__dict__
|
||||
})
|
||||
return self.render('panels/g.html', context)
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
}
|
||||
|
||||
#flDebug #flDebugToolbar li>a,
|
||||
#flDebug #flDebugToolbar li>div.contentless {
|
||||
#flDebug #flDebugToolbar li>div.flDebugContentless {
|
||||
font-weight:normal;
|
||||
font-style:normal;
|
||||
text-decoration:none;
|
||||
@@ -68,7 +68,7 @@
|
||||
background-color:#ffc;
|
||||
}
|
||||
|
||||
#flDebug #flDebugToolbar li.active {
|
||||
#flDebug #flDebugToolbar li.flDebugActive {
|
||||
background-image:url(../img/indicator.png);
|
||||
background-repeat:no-repeat;
|
||||
background-position:left center;
|
||||
@@ -76,7 +76,7 @@
|
||||
padding-left:10px;
|
||||
}
|
||||
|
||||
#flDebug #flDebugToolbar li.active a:hover {
|
||||
#flDebug #flDebugToolbar li.flDebugActive a:hover {
|
||||
color:#b36a60;
|
||||
background-color:transparent;
|
||||
}
|
||||
@@ -89,7 +89,7 @@
|
||||
font-variant:small-caps;
|
||||
}
|
||||
|
||||
#flDebug #flDebugToolbar li .switch {
|
||||
#flDebug #flDebugToolbar li .flDebugSwitch {
|
||||
font-size: 10px;
|
||||
position: absolute;
|
||||
display: block;
|
||||
@@ -101,11 +101,11 @@
|
||||
right: 2px;
|
||||
}
|
||||
|
||||
#flDebug #flDebugToolbar li .switch.active {
|
||||
#flDebug #flDebugToolbar li .flDebugSwitch.flDebugActive {
|
||||
background-image: url(../img/tick.png);
|
||||
}
|
||||
|
||||
#flDebug #flDebugToolbar li .switch.inactive {
|
||||
#flDebug #flDebugToolbar li .flDebugSwitch.flDebugInactive {
|
||||
background-image: url(../img/tick-red.png);
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@
|
||||
opacity:0.75;
|
||||
}
|
||||
|
||||
#flDebug a#flShowToolBarButton {
|
||||
#flDebug a#flDebugShowToolBarButton {
|
||||
display:block;
|
||||
height:75px;
|
||||
width:30px;
|
||||
@@ -138,7 +138,7 @@
|
||||
opacity:0.5;
|
||||
}
|
||||
|
||||
#flDebug a#flShowToolBarButton:hover {
|
||||
#flDebug a#flDebugShowToolBarButton:hover {
|
||||
background-color:#111;
|
||||
padding-right:6px;
|
||||
border-top-color:#FFE761;
|
||||
@@ -157,7 +157,7 @@
|
||||
background-color:#f5f5f5;
|
||||
}
|
||||
|
||||
#flDebug .panelContent {
|
||||
#flDebug .flDebugPanelContentParent {
|
||||
display:none;
|
||||
position:fixed;
|
||||
margin:0;
|
||||
@@ -170,7 +170,7 @@
|
||||
z-index:100000000;
|
||||
}
|
||||
|
||||
#flDebug .panelContent > div {
|
||||
#flDebug .flDebugPanelContentParent > div {
|
||||
border-bottom:1px solid #ddd;
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
#flDebug .panelContent table {
|
||||
#flDebug .flDebugPanelContentParent table {
|
||||
border:1px solid #ccc;
|
||||
border-collapse:collapse;
|
||||
width:100%;
|
||||
@@ -232,29 +232,29 @@
|
||||
margin-top:0.8em;
|
||||
overflow: auto;
|
||||
}
|
||||
#flDebug .panelContent tbody td,
|
||||
#flDebug .panelContent tbody th {
|
||||
#flDebug .flDebugPanelContentParent tbody td,
|
||||
#flDebug .flDebugPanelContentParent tbody th {
|
||||
vertical-align:top;
|
||||
padding:2px 3px;
|
||||
}
|
||||
#flDebug .panelContent thead th {
|
||||
#flDebug .flDebugPanelContentParent thead th {
|
||||
padding:1px 6px 1px 3px;
|
||||
text-align:left;
|
||||
font-weight:bold;
|
||||
font-size:14px;
|
||||
}
|
||||
#flDebug .panelContent tbody th {
|
||||
#flDebug .flDebugPanelContentParent tbody th {
|
||||
width:12em;
|
||||
text-align:right;
|
||||
color:#666;
|
||||
padding-right:.5em;
|
||||
}
|
||||
|
||||
#flDebug .panelContent ol li {
|
||||
#flDebug .flDebugPanelContentParent ol li {
|
||||
margin: 0 0 1em 2em;
|
||||
}
|
||||
|
||||
#flDebug .panelContent pre {
|
||||
#flDebug .flDebugPanelContentParent pre {
|
||||
border:1px solid #ccc;
|
||||
background-color:#fff;
|
||||
display:block;
|
||||
@@ -266,7 +266,7 @@
|
||||
background-color:#fff;
|
||||
}
|
||||
|
||||
#flDebug .panelContent .flDebugClose {
|
||||
#flDebug .flDebugPanelContentParent .flDebugClose {
|
||||
text-indent:-9999999px;
|
||||
display:block;
|
||||
position:absolute;
|
||||
@@ -277,38 +277,38 @@
|
||||
background:url(../img/close.png) no-repeat center center;
|
||||
}
|
||||
|
||||
#flDebug .panelContent .flDebugClose:hover {
|
||||
#flDebug .flDebugPanelContentParent .flDebugClose:hover {
|
||||
background-image:url(../img/close_hover.png);
|
||||
}
|
||||
|
||||
#flDebug .panelContent .flDebugClose.flDebugBack {
|
||||
#flDebug .flDebugPanelContentParent .flDebugClose.flDebugBack {
|
||||
background-image:url(../img/back.png);
|
||||
}
|
||||
|
||||
#flDebug .panelContent .flDebugClose.flDebugBack:hover {
|
||||
#flDebug .flDebugPanelContentParent .flDebugClose.flDebugBack:hover {
|
||||
background-image:url(../img/back_hover.png);
|
||||
}
|
||||
|
||||
#flDebug .panelContent dt, #flDebug .panelContent dd {
|
||||
#flDebug .flDebugPanelContentParent dt, #flDebug .flDebugPanelContentParent dd {
|
||||
display:block;
|
||||
}
|
||||
|
||||
#flDebug .panelContent dt {
|
||||
#flDebug .flDebugPanelContentParent dt {
|
||||
margin-top:0.75em;
|
||||
}
|
||||
|
||||
#flDebug .panelContent dd {
|
||||
#flDebug .flDebugPanelContentParent dd {
|
||||
margin-left:10px;
|
||||
}
|
||||
|
||||
#flDebug a.toggleTemplate {
|
||||
#flDebug a.flDebugToggleTemplate {
|
||||
padding:4px;
|
||||
background-color:#bbb;
|
||||
-moz-border-radius:3px;
|
||||
-webkit-border-radius:3px;
|
||||
}
|
||||
|
||||
#flDebug a.toggleTemplate:hover {
|
||||
#flDebug a.flDebugToggleTemplate:hover {
|
||||
padding:4px;
|
||||
background-color:#444;
|
||||
color:#ffe761;
|
||||
@@ -317,11 +317,11 @@
|
||||
}
|
||||
|
||||
|
||||
#flDebug a.flTemplateShowContext, #flDebug a.flTemplateShowContext span.toggleArrow {
|
||||
#flDebug a.flDebugTemplateShowContext, #flDebug a.flDebugTemplateShowContext span.flDebugToggleArrow {
|
||||
color:#999;
|
||||
}
|
||||
|
||||
#flDebug a.flTemplateShowContext:hover, #flDebug a.flTemplateShowContext:hover span.toggleArrow {
|
||||
#flDebug a.flDebugTemplateShowContext:hover, #flDebug a.flDebugTemplateShowContext:hover span.flDebugToggleArrow {
|
||||
color:#000;
|
||||
cursor:pointer;
|
||||
}
|
||||
@@ -334,7 +334,7 @@
|
||||
z-index:100000002;
|
||||
}
|
||||
|
||||
#flDebug .flSQLHideStacktraceDiv tbody th {
|
||||
#flDebug .flDebugHideStacktraceDiv tbody th {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
@@ -373,25 +373,25 @@
|
||||
#flDebug .highlight .cp { color:#333 } /* Comment.Preproc */
|
||||
|
||||
/* tablesorted */
|
||||
#flDebug table.tablesorter {
|
||||
#flDebug table.flDebugTablesorter {
|
||||
width: 100%;
|
||||
}
|
||||
#flDebug table.tablesorter thead th, table.tablesorter tfoot th {
|
||||
#flDebug table.flDebugTablesorter thead th, table.flDebugTablesorter tfoot th {
|
||||
padding-right: 20px;
|
||||
}
|
||||
#flDebug table.tablesorter thead th {
|
||||
#flDebug table.flDebugTablesorter thead th {
|
||||
background: url(../img/bg.gif) center right no-repeat;
|
||||
cursor: pointer;
|
||||
}
|
||||
#flDebug table.tablesorter tbody tr.odd td {
|
||||
#flDebug table.flDebugTablesorter tbody tr.odd td {
|
||||
background-color: #F0F0F6;
|
||||
}
|
||||
#flDebug table.tablesorter thead .headerSortUp {
|
||||
#flDebug table.flDebugTablesorter thead .headerSortUp {
|
||||
background-image: url(../img/asc.gif);
|
||||
}
|
||||
#flDebug table.tablesorter thead .headerSortDown {
|
||||
#flDebug table.flDebugTablesorter thead .headerSortDown {
|
||||
background-image: url(../img/desc.gif);
|
||||
}
|
||||
#flDebug table.tablesorter thead .headerSortDown, #flDebug table.tablesorter thead .headerSortUp {
|
||||
#flDebug table.flDebugTablesorter thead .headerSortDown, #flDebug table.flDebugTablesorter thead .headerSortUp {
|
||||
background-color: #8dbdd8;
|
||||
}
|
||||
|
||||
@@ -14,16 +14,16 @@
|
||||
current = $('#flDebug #' + this.className + '-content');
|
||||
if (current.is(':visible')) {
|
||||
$(document).trigger('close.flDebug');
|
||||
$(this).parent().removeClass('active');
|
||||
$(this).parent().removeClass('flDebugActive');
|
||||
} else {
|
||||
$('.panelContent').hide(); // Hide any that are already open
|
||||
$('.flDebugPanelContentParent').hide(); // Hide any that are already open
|
||||
current.show();
|
||||
$('#flDebugToolbar li').removeClass('active');
|
||||
$(this).parent().addClass('active');
|
||||
$('#flDebugToolbar li').removeClass('flDebugActive');
|
||||
$(this).parent().addClass('flDebugActive');
|
||||
}
|
||||
return false;
|
||||
});
|
||||
$('#flDebugPanelList li .switch').click(function() {
|
||||
$('#flDebugPanelList li .flDebugSwitch').click(function() {
|
||||
var $panel = $(this).parent();
|
||||
var $this = $(this);
|
||||
var dom_id = $panel.attr('id');
|
||||
@@ -33,13 +33,13 @@
|
||||
var active = (active_str) ? active_str.split(';') : [];
|
||||
active = $.grep(active, function(n,i) { return n != dom_id; });
|
||||
|
||||
if ($this.hasClass('active')) {
|
||||
$this.removeClass('active');
|
||||
$this.addClass('inactive');
|
||||
if ($this.hasClass('flDebugActive')) {
|
||||
$this.removeClass('flDebugActive');
|
||||
$this.addClass('flDebugInactive');
|
||||
} else {
|
||||
active.push(dom_id);
|
||||
$this.removeClass('inactive');
|
||||
$this.addClass('active');
|
||||
$this.removeClass('flDebugInactive');
|
||||
$this.addClass('flDebugActive');
|
||||
}
|
||||
|
||||
if (active.length > 0) {
|
||||
@@ -54,10 +54,10 @@
|
||||
});
|
||||
$('#flDebug a.flDebugClose').click(function() {
|
||||
$(document).trigger('close.flDebug');
|
||||
$('#flDebugToolbar li').removeClass('active');
|
||||
$('#flDebugToolbar li').removeClass('flDebugActive');
|
||||
return false;
|
||||
});
|
||||
$('#flDebug a.remoteCall').click(function() {
|
||||
$('#flDebug a.flDebugRemoteCall').click(function() {
|
||||
$('#flDebugWindow').load(this.href, {}, function() {
|
||||
$('#flDebugWindow a.flDebugBack').click(function() {
|
||||
$(this).parent().parent().hide();
|
||||
@@ -67,20 +67,20 @@
|
||||
$('#flDebugWindow').show();
|
||||
return false;
|
||||
});
|
||||
$('#flDebugTemplatePanel a.flTemplateShowContext').click(function() {
|
||||
fldt.toggle_arrow($(this).children('.toggleArrow'))
|
||||
$('#flDebugTemplatePanel a.flDebugTemplateShowContext').click(function() {
|
||||
fldt.toggle_arrow($(this).children('.flDebugToggleArrow'))
|
||||
fldt.toggle_content($(this).parent().next());
|
||||
return false;
|
||||
});
|
||||
$('#flDebugSQLPanel a.flSQLShowStacktrace').click(function() {
|
||||
fldt.toggle_content($('.flSQLHideStacktraceDiv', $(this).parents('tr')));
|
||||
$('#flDebugSQLPanel a.flDebugShowStacktrace').click(function() {
|
||||
fldt.toggle_content($('.flDebugHideStacktraceDiv', $(this).parents('tr')));
|
||||
return false;
|
||||
});
|
||||
$('#flHideToolBarButton').click(function() {
|
||||
$('#flDebugHideToolBarButton').click(function() {
|
||||
fldt.hide_toolbar(true);
|
||||
return false;
|
||||
});
|
||||
$('#flShowToolBarButton').click(function() {
|
||||
$('#flDebugShowToolBarButton').click(function() {
|
||||
fldt.show_toolbar();
|
||||
return false;
|
||||
});
|
||||
@@ -91,8 +91,8 @@
|
||||
return;
|
||||
}
|
||||
// If a panel is open, close that
|
||||
if ($('.panelContent').is(':visible')) {
|
||||
$('.panelContent').hide();
|
||||
if ($('.flDebugPanelContentParent').is(':visible')) {
|
||||
$('.flDebugPanelContentParent').hide();
|
||||
return;
|
||||
}
|
||||
// Otherwise, just minimize the toolbar
|
||||
@@ -106,7 +106,7 @@
|
||||
} else {
|
||||
fldt.show_toolbar(false);
|
||||
}
|
||||
$('#flDebug table.tablesorter').each(function() {
|
||||
$('#flDebug table.flDebugTablesorter').each(function() {
|
||||
var headers = {};
|
||||
$(this).find('thead th').each(function(idx, elem) {
|
||||
headers[idx] = $(elem).data();
|
||||
@@ -137,8 +137,8 @@
|
||||
// close any sub panels
|
||||
$('#flDebugWindow').hide();
|
||||
// close all panels
|
||||
$('.panelContent').hide();
|
||||
$('#flDebugToolbar li').removeClass('active');
|
||||
$('.flDebugPanelContentParent').hide();
|
||||
$('#flDebugToolbar li').removeClass('flDebugActive');
|
||||
// finally close toolbar
|
||||
$('#flDebugToolbar').hide('fast');
|
||||
$('#flDebugToolbarHandle').show();
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<div style="display: none;" id="flDebugToolbar">
|
||||
<ol id="flDebugPanelList">
|
||||
{% if panels %}
|
||||
<li><a id="flHideToolBarButton" href="#" title="Hide Toolbar">Hide »</a></li>
|
||||
<li><a id="flDebugHideToolBarButton" href="#" title="Hide Toolbar">Hide »</a></li>
|
||||
{% else %}
|
||||
<li id="flDebugButton">DEBUG</li>
|
||||
{% endif %}
|
||||
@@ -17,7 +17,7 @@
|
||||
{% if panel.has_content %}
|
||||
<a href="{{ panel.url()|default("#") }}" title="{{ panel.title() }}" class="{{ panel.dom_id() }}">
|
||||
{% else %}
|
||||
<div class="contentless">
|
||||
<div class="flDebugContentless">
|
||||
{% endif %}
|
||||
|
||||
{{ panel.nav_title() }}
|
||||
@@ -29,29 +29,29 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if panel.user_activate %}
|
||||
<span class="switch {{ 'active' if panel.is_active else 'inactive' }}" title="Enable or disable the panel"></span>
|
||||
<span class="flDebugSwitch {{ 'flDebugActive' if panel.is_active else 'flDebugInactive' }}" title="Enable or disable the panel"></span>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ol>
|
||||
</div>
|
||||
<div style="display:none;" id="flDebugToolbarHandle">
|
||||
<a title="Show Toolbar" id="flShowToolBarButton" href="#">«</a>
|
||||
<a title="Show Toolbar" id="flDebugShowToolBarButton" href="#">«</a>
|
||||
</div>
|
||||
{% for panel in panels %}
|
||||
{% if panel.has_content %}
|
||||
<div id="{{ panel.dom_id() }}-content" class="panelContent">
|
||||
<div id="{{ panel.dom_id() }}-content" class="flDebugPanelContentParent">
|
||||
<div class="flDebugPanelTitle">
|
||||
<a href="" class="flDebugClose">Close</a>
|
||||
<h3>{{ panel.title()|safe }}</h3>
|
||||
</div>
|
||||
<div class="flDebugPanelContent">
|
||||
<div class="scroll">
|
||||
<div class="flDebugScroll">
|
||||
{{ panel.content()|safe }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<div id="flDebugWindow" class="panelContent"></div>
|
||||
<div id="flDebugWindow" class="flDebugPanelContentParent"></div>
|
||||
</div>
|
||||
|
||||
16
flask_debugtoolbar/templates/panels/g.html
Normal file
16
flask_debugtoolbar/templates/panels/g.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Key</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for key, value in g_content|dictsort %}
|
||||
<tr class="{{ loop.cycle('flDebugOdd', 'flDebugEven') }}">
|
||||
<td>{{ key|escape }}</td>
|
||||
<td>{{ value|escape }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -1,4 +1,4 @@
|
||||
<table id="debug_toolbar_profiler_table" class="tablesorter">
|
||||
<table id="flDebugProfilerTable" class="flDebugTablesorter">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-sorter="digit">Calls</th>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<table class="tablesorter">
|
||||
<table class="flDebugTablesorter">
|
||||
<thead>
|
||||
<tr>
|
||||
<th> (ms)</th>
|
||||
@@ -13,14 +13,14 @@
|
||||
<td>{{ '%.4f'|format(query.duration * 1000) }}</td>
|
||||
<td>
|
||||
{% if query.signed_query %}
|
||||
<a class="remoteCall" href="/_debug_toolbar/views/sqlalchemy/sql_select?query={{ query.signed_query }}&duration={{ query.duration|urlencode }}">SELECT</a><br />
|
||||
<a class="remoteCall" href="/_debug_toolbar/views/sqlalchemy/sql_explain?query={{ query.signed_query }}&duration={{ query.duration|urlencode }}">EXPLAIN</a><br />
|
||||
<a class="flDebugRemoteCall" href="{{ url_for('debugtoolbar.sql_select', explain=False, query=query.signed_query, duration=query.duration )}}">SELECT</a><br />
|
||||
<a class="flDebugRemoteCall" href="{{ url_for('debugtoolbar.sql_select', explain=True, query=query.signed_query, duration=query.duration )}}">EXPLAIN</a><br />
|
||||
{% endif %}
|
||||
</td>
|
||||
<td title="{{ query.context_long }}">
|
||||
{{ query.context }}
|
||||
</td>
|
||||
<td class="syntax">
|
||||
<td class="flDebugSyntax">
|
||||
<div class="flDebugSqlWrap">
|
||||
<div class="flDebugSql">{{ query.sql }}</div>
|
||||
</div>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<h5>Configure Flask-SQLAlchemy:</h5>
|
||||
<p>
|
||||
The Flask-SQLAlchemy extension needs to be configured for this application.
|
||||
Please see the <a href="http://flask-sqlalchemy.pocoo.org/latest/quickstart/">
|
||||
Please see the <a href="https://flask-sqlalchemy.palletsprojects.com/en/master/quickstart/">
|
||||
Flask-SQLAlchemy documentation</a> for details.
|
||||
</p>
|
||||
</li>
|
||||
@@ -35,7 +35,7 @@
|
||||
<pre>app.config['SQLALCHEMY_RECORD_QUERIES'] = True</pre>
|
||||
<p>
|
||||
See the
|
||||
<a href="http://flask-sqlalchemy.pocoo.org/latest/api/#flask.ext.sqlalchemy.get_debug_queries">
|
||||
<a href="https://flask-sqlalchemy.palletsprojects.com/en/master/api/#flask_sqlalchemy.get_debug_queries">
|
||||
documention of Flask-SQLAlchemy's <code>get_debug_queries()</code></a>
|
||||
for additional details.
|
||||
</p>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<dd>{{ '%.4f'|format(duration * 1000) }} ms</dd>
|
||||
</dl>
|
||||
{% if result %}
|
||||
<table class="flSqlSelect">
|
||||
<table class="flDebugSelect">
|
||||
<thead>
|
||||
<tr>
|
||||
{% for h in headers %}
|
||||
|
||||
@@ -18,46 +18,46 @@
|
||||
{% set toolbar_height = 25 %}
|
||||
{% set editor_width = request.cookies.get('fldt_editor_size')|int(40) %}
|
||||
|
||||
#panel, #editor, #preview, #splitter, #toolbar {
|
||||
#flDebugPanel, #flDebugEditor, #flDebugPreview, #flDebugSplitter, #flDebugToolbar {
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
-ms-box-sizing: border-box;
|
||||
border: none;
|
||||
}
|
||||
#panel, #preview { position: fixed; }
|
||||
#panel > div { position: absolute; }
|
||||
#flDebugPanel, #flDebugPreview { position: fixed; }
|
||||
#flDebugPanel > div { position: absolute; }
|
||||
|
||||
#panel { width: {{ editor_width }}%; height: 100%; top: 0; left: 0; bottom: 0; }
|
||||
#toolbar { top: 0; width: 100%; height: {{ toolbar_height }}px; border-bottom: 1px solid black; padding: 2px 4px; }
|
||||
#editor { top: {{ toolbar_height }}px; bottom: 0; width: 100%; }
|
||||
#preview { top: 0; bottom: 0; right: 0; height: 100%; width: {{ 100 - editor_width }}%; }
|
||||
#flDebugPanel { width: {{ editor_width }}%; height: 100%; top: 0; left: 0; bottom: 0; }
|
||||
#flDebugToolbar { top: 0; width: 100%; height: {{ toolbar_height }}px; border-bottom: 1px solid black; padding: 2px 4px; }
|
||||
#flDebugEditor { top: {{ toolbar_height }}px; bottom: 0; width: 100%; }
|
||||
#flDebugPreview { top: 0; bottom: 0; right: 0; height: 100%; width: {{ 100 - editor_width }}%; }
|
||||
|
||||
/* need a dummy element over the page so that drag events don't get captured by the preview iframe */
|
||||
#drag-handler { display: none; position: fixed; width: 100%; height: 100%; z-index: 1000; }
|
||||
#splitter { width: 8px; height: 100%; top: 0; bottom: 0; right: -1px; z-index: 999; cursor: e-resize; border-right: 1px solid black; }
|
||||
#flDebugDragHandler { display: none; position: fixed; width: 100%; height: 100%; z-index: 1000; }
|
||||
#flDebugSplitter { width: 8px; height: 100%; top: 0; bottom: 0; right: -1px; z-index: 999; cursor: e-resize; border-right: 1px solid black; }
|
||||
|
||||
.CodeMirror, .CodeMirror-scroll { height: 100%; }
|
||||
.syntax-error { background: red !important; }
|
||||
|
||||
#toolbar button { margin: 0; }
|
||||
#save { float: left; }
|
||||
#close { float: right; }
|
||||
#flDebugToolbar button { margin: 0; }
|
||||
#flDebugSave { float: left; }
|
||||
#flDebugClose { float: right; }
|
||||
{% endwith %}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="drag-handler"></div>
|
||||
<div id="panel">
|
||||
<div id="toolbar">
|
||||
<button id="save">Save</button>
|
||||
<button id="close">Close</button>
|
||||
<div id="flDebugDragHandler"></div>
|
||||
<div id="flDebugPanel">
|
||||
<div id="flDebugToolbar">
|
||||
<button id="flDebugSave">Save</button>
|
||||
<button id="flDebugClose">Close</button>
|
||||
</div>
|
||||
<div id="editor">
|
||||
<div id="flDebugEditor">
|
||||
<textarea name="{{ templates[0].name }}" id="code">{{ templates[0].source }}</textarea>
|
||||
</div>
|
||||
<div id="splitter"></div>
|
||||
<div id="flDebugSplitter"></div>
|
||||
</div>
|
||||
<iframe id="preview"></iframe>
|
||||
<iframe id="flDebugPreview"></iframe>
|
||||
|
||||
<script src="{{ static_path }}codemirror/codemirror.js"></script>
|
||||
<script src="{{ static_path }}codemirror/util/closetag.js"></script>
|
||||
@@ -68,11 +68,11 @@
|
||||
<script src="{{ static_path }}codemirror/mode/htmlmixed/htmlmixed.js"></script>
|
||||
<script src="{{ static_path }}codemirror/mode/jinja2/jinja2.js"></script>
|
||||
<script>{% raw %}
|
||||
$('#drag-handler')
|
||||
$('#flDebugDragHandler')
|
||||
.mousemove(function(e) {
|
||||
var size = 100 * e.pageX / $(document).width();
|
||||
$('#panel').css('width', size + '%');
|
||||
$('#preview').css('width', (100 - size) + '%');
|
||||
$('#flDebugPanel').css('width', size + '%');
|
||||
$('#flDebugPreview').css('width', (100 - size) + '%');
|
||||
return false;
|
||||
})
|
||||
.mouseup(function(e) {
|
||||
@@ -82,12 +82,12 @@
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#splitter').mousedown(function() {
|
||||
$('#drag-handler').show();
|
||||
$('#flDebugSplitter').mousedown(function() {
|
||||
$('#flDebugDragHandler').show();
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#save').click(function() {
|
||||
$('#flDebugSave').click(function() {
|
||||
$.ajax({
|
||||
type: 'POST'
|
||||
, url: document.baseURI + '/save'
|
||||
@@ -95,7 +95,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
$('#close').click(function() {
|
||||
$('#flDebugClose').click(function() {
|
||||
document.location = document.location;
|
||||
});
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
}
|
||||
});
|
||||
|
||||
var previewFrame = document.getElementById('preview');
|
||||
var previewFrame = document.getElementById('flDebugPreview');
|
||||
var preview = previewFrame.contentDocument || previewFrame.contentWindow.document;
|
||||
var errorLine = null;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<body>
|
||||
<h1>Redirect ({{ redirect_code }})</h1>
|
||||
<p>Location: <a href="{{ redirect_to }}">{{ redirect_to }}</a></p>
|
||||
<p class="notice">
|
||||
<p class="flDebugNotice">
|
||||
The Flask Debug Toolbar has intercepted a redirect to the above URL for
|
||||
debug viewing purposes. You can click the above link to continue with the
|
||||
redirect as normal. If you'd like to disable this feature, you can set the
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import itertools
|
||||
import os.path
|
||||
import sys
|
||||
import io
|
||||
import gzip
|
||||
|
||||
try:
|
||||
from pygments import highlight
|
||||
@@ -83,3 +85,14 @@ def format_sql(query, args):
|
||||
query,
|
||||
SqlLexer(),
|
||||
HtmlFormatter(noclasses=True, style=PYGMENT_STYLE)))
|
||||
|
||||
def gzip_compress(data, compresslevel=6):
|
||||
buff = io.BytesIO()
|
||||
with gzip.GzipFile(fileobj=buff, mode='wb', compresslevel=compresslevel) as f:
|
||||
f.write(data)
|
||||
return buff.getvalue()
|
||||
|
||||
|
||||
def gzip_decompress(data):
|
||||
with gzip.GzipFile(fileobj=io.BytesIO(data), mode='rb') as f:
|
||||
return f.read()
|
||||
|
||||
6
pyproject.toml
Normal file
6
pyproject.toml
Normal file
@@ -0,0 +1,6 @@
|
||||
[build-system]
|
||||
requires = [
|
||||
"setuptools>=42",
|
||||
"wheel"
|
||||
]
|
||||
build-backend = "setuptools.build_meta"
|
||||
37
setup.cfg
37
setup.cfg
@@ -1,2 +1,35 @@
|
||||
[bdist_wheel]
|
||||
universal=1
|
||||
[metadata]
|
||||
name = Flask-DebugToolbar
|
||||
version = 0.12.1
|
||||
author = Michael van Tellingen
|
||||
author_email = michaelvantellingen@gmail.com
|
||||
maintainer = Matt Good
|
||||
maintainer_email = matt@matt-good.net
|
||||
description = A toolbar overlay for debugging Flask applications.
|
||||
long_description = file: README.rst
|
||||
long_description_content_type = text/x-rst
|
||||
keywords = flask, debug, toolbar
|
||||
url = https://github.com/flask-debugtoolbar/flask-debugtoolbar
|
||||
project_urls =
|
||||
Changelog = https://github.com/flask-debugtoolbar/flask-debugtoolbar/blob/master/CHANGES.rst
|
||||
Documentation = https://flask-debugtoolbar.readthedocs.io/
|
||||
classifiers =
|
||||
Development Status :: 4 - Beta
|
||||
Environment :: Web Environment
|
||||
Framework :: Flask
|
||||
Intended Audience :: Developers
|
||||
License :: OSI Approved :: BSD License
|
||||
Operating System :: OS Independent
|
||||
Programming Language :: Python
|
||||
Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
||||
Topic :: Software Development :: Libraries :: Python Modules
|
||||
|
||||
[options]
|
||||
packages = find:
|
||||
package_dir = = flask_debugtoolbar
|
||||
include_package_data = True
|
||||
python_requires = >=2.7
|
||||
# Dependencies are in setup.py for GitHub's dependency graph.
|
||||
|
||||
[options.packages.find]
|
||||
where = flask_debugtoolbar
|
||||
|
||||
40
setup.py
40
setup.py
@@ -1,48 +1,12 @@
|
||||
import os
|
||||
from setuptools import setup
|
||||
|
||||
|
||||
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 = ''
|
||||
|
||||
|
||||
# Metadata goes in setup.cfg. These are here for GitHub's dependency graph.
|
||||
setup(
|
||||
name='Flask-DebugToolbar',
|
||||
version='0.11.0',
|
||||
url='https://flask-debugtoolbar.readthedocs.io/',
|
||||
license='BSD',
|
||||
author='Michael van Tellingen',
|
||||
author_email='michaelvantellingen@gmail.com',
|
||||
maintainer='Matt Good',
|
||||
maintainer_email='matt@matt-good.net',
|
||||
description='A toolbar overlay for debugging Flask applications.',
|
||||
long_description=README + '\n\n' + CHANGES,
|
||||
zip_safe=False,
|
||||
platforms='any',
|
||||
include_package_data=True,
|
||||
packages=['flask_debugtoolbar',
|
||||
'flask_debugtoolbar.panels'
|
||||
],
|
||||
name="Flask-DebugToolbar",
|
||||
install_requires=[
|
||||
'Flask>=0.8',
|
||||
'Blinker',
|
||||
'itsdangerous',
|
||||
'werkzeug',
|
||||
],
|
||||
classifiers=[
|
||||
'Development Status :: 4 - Beta',
|
||||
'Environment :: Web Environment',
|
||||
'Intended Audience :: Developers',
|
||||
'License :: OSI Approved :: BSD License',
|
||||
'Operating System :: OS Independent',
|
||||
'Programming Language :: Python',
|
||||
'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
|
||||
'Topic :: Software Development :: Libraries :: Python Modules'
|
||||
]
|
||||
)
|
||||
|
||||
@@ -23,8 +23,12 @@ class Foo(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
|
||||
|
||||
@app.before_first_request
|
||||
def setup():
|
||||
db.create_all()
|
||||
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
db.create_all()
|
||||
Foo.query.filter_by(id=1).all()
|
||||
return render_template('basic_app.html')
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def mock_env_development(monkeypatch):
|
||||
monkeypatch.setenv("FLASK_ENV", "development")
|
||||
|
||||
Reference in New Issue
Block a user