From a060d30bb763aedcf7c4acabae0cdc3369d1835a Mon Sep 17 00:00:00 2001 From: mvantellingen Date: Tue, 1 Feb 2011 23:36:32 +0100 Subject: [PATCH] Initial structure for the debugtoolbar --- flaskext/__init__.py | 0 flaskext/debugtoolbar/__init__.py | 57 +++++++++++++++++++++++ flaskext/debugtoolbar/panels/__init__.py | 0 flaskext/debugtoolbar/panels/logger.py | 35 ++++++++++++++ flaskext/debugtoolbar/static/css/main.css | 0 flaskext/debugtoolbar/templates/base.html | 0 flaskext/debugtoolbar/views.py | 9 ++++ 7 files changed, 101 insertions(+) create mode 100644 flaskext/__init__.py create mode 100644 flaskext/debugtoolbar/__init__.py create mode 100644 flaskext/debugtoolbar/panels/__init__.py create mode 100644 flaskext/debugtoolbar/panels/logger.py create mode 100644 flaskext/debugtoolbar/static/css/main.css create mode 100644 flaskext/debugtoolbar/templates/base.html create mode 100644 flaskext/debugtoolbar/views.py diff --git a/flaskext/__init__.py b/flaskext/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/flaskext/debugtoolbar/__init__.py b/flaskext/debugtoolbar/__init__.py new file mode 100644 index 0000000..f59eff9 --- /dev/null +++ b/flaskext/debugtoolbar/__init__.py @@ -0,0 +1,57 @@ +import os + +from flask import request_finished +from flask.helpers import send_from_directory +from jinja2 import Environment, PackageLoader +from werkzeug.routing import Rule, Submount + +from .panels.logger import handler +from .views import views_module + + +def replace_insensitive(string, target, replacement): + """ + Similar to string.replace() but is case insensitive + Code borrowed from: http://forums.devshed.com/python-programming-11/case-insensitive-string-replace-490921.html + """ + no_case = string.lower() + index = no_case.rfind(target.lower()) + if index >= 0: + return string[:index] + replacement + string[index + len(target):] + else: # no results so return the original string + return string + + +class DebugToolbar(object): + _static_dir = os.path.join(os.path.dirname(__file__), 'static') + + def __init__(self, app): + self.jinja_env = Environment(loader=PackageLoader(__name__, 'templates')) + request_finished.connect(self.process_response, app) + + app.url_map.add(Submount('/_debug_toolbar', [ + Rule('/static/', endpoint='_debug_toolbar.static'), + Rule('/css/main.css', endpoint='_debug_toolbar.example') + ])) + + app.register_module(views_module) + app.view_functions['_debug_toolbar.static'] = self.send_static_file + + def send_static_file(self, filename): + return send_from_directory(self._static_dir, filename) + + def render_toolbar(self): + template = self.jinja_env.get_template('base.html') + content = template.render() + return content + + def process_response(self, sender, response): + if response.is_sequence: + response_html = response.data + toolbar_html = self.render_toolbar() + + response.response = [ + replace_insensitive( + response_html, + '', + toolbar_html + '')] diff --git a/flaskext/debugtoolbar/panels/__init__.py b/flaskext/debugtoolbar/panels/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/flaskext/debugtoolbar/panels/logger.py b/flaskext/debugtoolbar/panels/logger.py new file mode 100644 index 0000000..39f7a4c --- /dev/null +++ b/flaskext/debugtoolbar/panels/logger.py @@ -0,0 +1,35 @@ +""" +Logger panel (taken from django-debug-toolbar) + +""" +import threading +import logging + +class ThreadTrackingHandler(logging.Handler): + def __init__(self): + logging.Handler.__init__(self) + self.records = {} # a dictionary that maps threads to log records + + def emit(self, record): + self.get_records().append(record) + + def get_records(self, thread=None): + """ + Returns a list of records for the provided thread, of if none is provided, + returns a list for the current thread. + """ + if thread is None: + thread = threading.currentThread() + if thread not in self.records: + self.records[thread] = [] + return self.records[thread] + + def clear_records(self, thread=None): + if thread is None: + thread = threading.currentThread() + if thread in self.records: + del self.records[thread] + +handler = ThreadTrackingHandler() +logging.root.setLevel(logging.NOTSET) +logging.root.addHandler(handler) diff --git a/flaskext/debugtoolbar/static/css/main.css b/flaskext/debugtoolbar/static/css/main.css new file mode 100644 index 0000000..e69de29 diff --git a/flaskext/debugtoolbar/templates/base.html b/flaskext/debugtoolbar/templates/base.html new file mode 100644 index 0000000..e69de29 diff --git a/flaskext/debugtoolbar/views.py b/flaskext/debugtoolbar/views.py new file mode 100644 index 0000000..8343b28 --- /dev/null +++ b/flaskext/debugtoolbar/views.py @@ -0,0 +1,9 @@ +from flask import Module + +__all__ = ['views_module'] + +mod = views_module = Module(__name__) + +@mod.endpoint('_debug_toolbar.example') +def example_view(): + return "example"