From ab06fbe6bf60be18a740547db957b5c44ae6b786 Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Wed, 27 Aug 2008 23:57:17 -0700 Subject: Initial commit of basic working Debug Toolbar (that needs a lot of CSS and JS love) --- debug_toolbar/__init__.py | 0 debug_toolbar/middleware.py | 32 +++++++++++++++++ debug_toolbar/panels/__init__.py | 14 ++++++++ debug_toolbar/panels/sql.py | 19 ++++++++++ debug_toolbar/panels/version.py | 15 ++++++++ debug_toolbar/toolbar/__init__.py | 0 debug_toolbar/toolbar/loader.py | 73 +++++++++++++++++++++++++++++++++++++++ 7 files changed, 153 insertions(+) create mode 100644 debug_toolbar/__init__.py create mode 100644 debug_toolbar/middleware.py create mode 100644 debug_toolbar/panels/__init__.py create mode 100644 debug_toolbar/panels/sql.py create mode 100644 debug_toolbar/panels/version.py create mode 100644 debug_toolbar/toolbar/__init__.py create mode 100644 debug_toolbar/toolbar/loader.py (limited to 'debug_toolbar') diff --git a/debug_toolbar/__init__.py b/debug_toolbar/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/debug_toolbar/middleware.py b/debug_toolbar/middleware.py new file mode 100644 index 0000000..b2e9b29 --- /dev/null +++ b/debug_toolbar/middleware.py @@ -0,0 +1,32 @@ +""" +Debug Toolbar middleware +""" +import re +from django.conf import settings +from django.utils.safestring import mark_safe +from debug_toolbar.toolbar.loader import DebugToolbar + +_HTML_TYPES = ('text/html', 'application/xhtml+xml') +_END_HEAD_RE = re.compile(r'', re.IGNORECASE) +_END_BODY_RE = re.compile(r'', re.IGNORECASE) + +class DebugToolbarMiddleware(object): + """ + Middleware to set up Debug Toolbar on incoming request and render toolbar + on outgoing response. + """ + def __init__(self): + self.debug_toolbar = None + + def process_request(self, request): + if settings.DEBUG: + self.debug_toolbar = DebugToolbar() + self.debug_toolbar.load_panels() + return None + + def process_response(self, request, response): + if settings.DEBUG: + if response['Content-Type'].split(';')[0] in _HTML_TYPES: + #response.content = _END_HEAD_RE.sub(mark_safe(self.debug_toolbar.render_styles() + "%s" % match.group()), response.content) + response.content = _END_BODY_RE.sub(mark_safe(self.debug_toolbar.render_toolbar() + ''), response.content) + return response diff --git a/debug_toolbar/panels/__init__.py b/debug_toolbar/panels/__init__.py new file mode 100644 index 0000000..2454c56 --- /dev/null +++ b/debug_toolbar/panels/__init__.py @@ -0,0 +1,14 @@ +"""Base DebugPanel class""" + +class DebugPanel(object): + """ + Base class for debug panels. + """ + def title(self): + raise NotImplementedError + + def url(self): + raise NotImplementedError + + def content(self): + raise NotImplementedError diff --git a/debug_toolbar/panels/sql.py b/debug_toolbar/panels/sql.py new file mode 100644 index 0000000..6c180d7 --- /dev/null +++ b/debug_toolbar/panels/sql.py @@ -0,0 +1,19 @@ +from debug_toolbar.panels import DebugPanel + +class SQLDebugPanel(DebugPanel): + """ + Panel that displays information about the SQL queries run while processing the request. + """ + def title(self): + return 'SQL Queries' + + def url(self): + return '' + + def content(self): + from django.db import connection + query_info = [] + for q in connection.queries: + query_info.append('
%s
%s
' % (q['time'], q['sql'])) + return '
%s
' % (''.join(query_info)) + diff --git a/debug_toolbar/panels/version.py b/debug_toolbar/panels/version.py new file mode 100644 index 0000000..63c44b0 --- /dev/null +++ b/debug_toolbar/panels/version.py @@ -0,0 +1,15 @@ +import django +from debug_toolbar.panels import DebugPanel + +class VersionDebugPanel(DebugPanel): + """ + Panel that displays the Django version. + """ + def title(self): + return 'Version' + + def url(self): + return '' + + def content(self): + return django.get_version() diff --git a/debug_toolbar/toolbar/__init__.py b/debug_toolbar/toolbar/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/debug_toolbar/toolbar/loader.py b/debug_toolbar/toolbar/loader.py new file mode 100644 index 0000000..4c3efa2 --- /dev/null +++ b/debug_toolbar/toolbar/loader.py @@ -0,0 +1,73 @@ +""" +The main DebugToolbar class that loads and renders the Toolbar. +""" +class DebugToolbar(object): + + def __init__(self): + self.panels = [] + self.panel_list = [] + self.content_list = [] + + def load_panels(self): + """ + Populate debug panel lists from settings.DEBUG_TOOLBAR_PANELS. + """ + from django.conf import settings + from django.core import exceptions + + for panel_path in settings.DEBUG_TOOLBAR_PANELS: + try: + dot = panel_path.rindex('.') + except ValueError: + raise exceptions.ImproperlyConfigured, '%s isn\'t a debug panel module' % panel_path + panel_module, panel_classname = panel_path[:dot], panel_path[dot+1:] + try: + mod = __import__(panel_module, {}, {}, ['']) + except ImportError, e: + raise exceptions.ImproperlyConfigured, 'Error importing debug panel %s: "%s"' % (panel_module, e) + try: + panel_class = getattr(mod, panel_classname) + except AttributeError: + raise exceptions.ImproperlyConfigured, 'Toolbar Panel module "%s" does not define a "%s" class' % (panel_module, panel_classname) + + try: + panel_instance = panel_class() + except: + continue # Some problem loading panel + + self.panels.append(panel_instance) + + def render_panels(self): + """ + Renders each panel. + """ + for panel in self.panels: + div_id = 'djDebug%sPanel' % (panel.title().replace(' ', '')) + self.panel_list.append('
  • %(title)s
  • ' % ({ + 'title': panel.title(), + 'url': panel.url() or '#', + })) + self.content_list.append('

    %(title)s

    %(content)s
    ' % ({ + 'div_id': div_id, + 'title': panel.title(), + 'content': panel.content(), + })) + + def render_toolbar(self): + """ + Renders the overall Toolbar with panels inside. + """ + self.render_panels() + template = """ +
    + + %(contents)s +
    + """ + context = { + 'panels': ''.join(self.panel_list), + 'contents': ''.join(self.content_list), + } + return template % context -- cgit v1.2.3