diff options
| -rw-r--r-- | debug_toolbar/panels/cache.py | 9 | ||||
| -rw-r--r-- | debug_toolbar/panels/headers.py | 13 | ||||
| -rw-r--r-- | debug_toolbar/panels/logging.py | 31 | ||||
| -rw-r--r-- | debug_toolbar/panels/profiling.py | 10 | ||||
| -rw-r--r-- | debug_toolbar/panels/redirects.py | 11 | ||||
| -rw-r--r-- | debug_toolbar/panels/request.py | 8 | ||||
| -rw-r--r-- | debug_toolbar/panels/settings.py | 5 | ||||
| -rw-r--r-- | debug_toolbar/panels/signals.py | 8 | ||||
| -rw-r--r-- | debug_toolbar/panels/sql/panel.py | 33 | ||||
| -rw-r--r-- | debug_toolbar/panels/templates/panel.py | 22 | ||||
| -rw-r--r-- | debug_toolbar/panels/timer.py | 81 | ||||
| -rw-r--r-- | debug_toolbar/panels/versions.py | 13 | ||||
| -rw-r--r-- | tests/panels/test_profiling.py | 2 | ||||
| -rw-r--r-- | tests/panels/test_request.py | 4 | ||||
| -rw-r--r-- | tests/panels/test_sql.py | 2 | ||||
| -rw-r--r-- | tests/panels/test_template.py | 2 | 
16 files changed, 103 insertions, 151 deletions
| diff --git a/debug_toolbar/panels/cache.py b/debug_toolbar/panels/cache.py index c2808a1..d08723f 100644 --- a/debug_toolbar/panels/cache.py +++ b/debug_toolbar/panels/cache.py @@ -131,9 +131,7 @@ class CachePanel(Panel):      """      Panel that displays the cache statistics.      """ -    name = 'Cache'      template = 'debug_toolbar/panels/cache.html' -    has_content = True      def __init__(self, *args, **kwargs):          super(CachePanel, self).__init__(*args, **kwargs) @@ -183,9 +181,11 @@ class CachePanel(Panel):              'backend': backend          }) -    def nav_title(self): -        return _('Cache') +    # Implement the Panel API +    nav_title = _('Cache') + +    @property      def nav_subtitle(self):          cache_calls = len(self.calls)          return ungettext('%(cache_calls)d call in %(time).2fms', @@ -193,6 +193,7 @@ class CachePanel(Panel):                           cache_calls) % {'cache_calls': cache_calls,                                           'time': self.total_time} +    @property      def title(self):          count = len(getattr(settings, 'CACHES', ['default']))          return ungettext('Cache calls from %(count)d backend', diff --git a/debug_toolbar/panels/headers.py b/debug_toolbar/panels/headers.py index 3ee499d..0138299 100644 --- a/debug_toolbar/panels/headers.py +++ b/debug_toolbar/panels/headers.py @@ -12,11 +12,8 @@ class HeadersPanel(Panel):      """      A panel to display HTTP headers.      """ -    name = 'Headers' -    template = 'debug_toolbar/panels/headers.html' -    has_content = True      # List of environment variables we want to display -    environ_filter = set(( +    ENVIRON_FILTER = set((          'CONTENT_LENGTH',          'CONTENT_TYPE',          'DJANGO_SETTINGS_MODULE', @@ -35,11 +32,9 @@ class HeadersPanel(Panel):          'TZ',      )) -    def nav_title(self): -        return _('Headers') +    title = _('Headers') -    def title(self): -        return _('Headers') +    template = 'debug_toolbar/panels/headers.html'      def process_request(self, request):          wsgi_env = list(sorted(request.META.items())) @@ -48,7 +43,7 @@ class HeadersPanel(Panel):          if 'Cookie' in self.request_headers:              self.request_headers['Cookie'] = '=> see Request panel'          self.environ = OrderedDict( -            (k, v) for (k, v) in wsgi_env if k in self.environ_filter) +            (k, v) for (k, v) in wsgi_env if k in self.ENVIRON_FILTER)          self.record_stats({              'request_headers': self.request_headers,              'environ': self.environ, diff --git a/debug_toolbar/panels/logging.py b/debug_toolbar/panels/logging.py index a37e000..f07281b 100644 --- a/debug_toolbar/panels/logging.py +++ b/debug_toolbar/panels/logging.py @@ -105,35 +105,28 @@ if logbook_supported:  class LoggingPanel(Panel): -    name = 'Logging'      template = 'debug_toolbar/panels/logging.html' -    has_content = True      def __init__(self, *args, **kwargs):          super(LoggingPanel, self).__init__(*args, **kwargs)          self._records = {} -    def process_request(self, request): -        collector.clear_records() - -    def process_response(self, request, response): -        records = self.get_and_delete() -        self.record_stats({'records': records}) - -    def get_and_delete(self): -        records = collector.get_records() -        self._records[threading.currentThread()] = records -        collector.clear_records() -        return records - -    def nav_title(self): -        return _("Logging") +    nav_title = _("Logging") +    @property      def nav_subtitle(self):          records = self._records[threading.currentThread()]          record_count = len(records)          return ungettext('%(count)s message', '%(count)s messages',                           record_count) % {'count': record_count} -    def title(self): -        return _('Log Messages') +    title = _('Log Messages') + +    def process_request(self, request): +        collector.clear_records() + +    def process_response(self, request, response): +        records = collector.get_records() +        self._records[threading.currentThread()] = records +        collector.clear_records() +        self.record_stats({'records': records}) diff --git a/debug_toolbar/panels/profiling.py b/debug_toolbar/panels/profiling.py index 9443e34..f4d32c4 100644 --- a/debug_toolbar/panels/profiling.py +++ b/debug_toolbar/panels/profiling.py @@ -144,15 +144,9 @@ class ProfilingPanel(Panel):      """      Panel that displays profiling information.      """ -    name = 'Profiling' -    template = 'debug_toolbar/panels/profiling.html' -    has_content = True - -    def nav_title(self): -        return _('Profiling') +    title = _('Profiling') -    def title(self): -        return _('Profiling') +    template = 'debug_toolbar/panels/profiling.html'      def _unwrap_closure_and_profile(self, func):          if not hasattr(func, '__code__'): diff --git a/debug_toolbar/panels/redirects.py b/debug_toolbar/panels/redirects.py index 9deeb69..52b2077 100644 --- a/debug_toolbar/panels/redirects.py +++ b/debug_toolbar/panels/redirects.py @@ -2,7 +2,7 @@ from __future__ import absolute_import, unicode_literals  from django.core.handlers.wsgi import STATUS_CODE_TEXT  from django.shortcuts import render -from django.utils.translation import ugettext as _ +from django.utils.translation import ugettext_lazy as _  from debug_toolbar.panels import Panel @@ -11,15 +11,16 @@ class RedirectsPanel(Panel):      """      Panel that intercepts redirects and displays a page with debug info.      """ -    name = 'Redirects' - -    has_content = False      @property      def enabled(self):          default = 'on' if self.toolbar.config['INTERCEPT_REDIRECTS'] else 'off'          return self.toolbar.request.COOKIES.get('djdt' + self.panel_id, default) == 'on' +    has_content = False + +    nav_title = _('Intercept redirects') +      def process_response(self, request, response):          if 300 <= int(response.status_code) < 400:              redirect_to = response.get('Location', None) @@ -36,5 +37,3 @@ class RedirectsPanel(Panel):                  response.cookies = cookies          return response -    def nav_title(self): -        return _('Intercept redirects') diff --git a/debug_toolbar/panels/request.py b/debug_toolbar/panels/request.py index 934946a..28f5e22 100644 --- a/debug_toolbar/panels/request.py +++ b/debug_toolbar/panels/request.py @@ -13,15 +13,9 @@ class RequestPanel(Panel):      """      A panel to display request variables (POST/GET, session, cookies).      """ -    name = 'Request'      template = 'debug_toolbar/panels/request.html' -    has_content = True -    def nav_title(self): -        return _('Request') - -    def title(self): -        return _('Request') +    title = _('Request')      def process_response(self, request, response):          self.record_stats({ diff --git a/debug_toolbar/panels/settings.py b/debug_toolbar/panels/settings.py index b7af57d..2729128 100644 --- a/debug_toolbar/panels/settings.py +++ b/debug_toolbar/panels/settings.py @@ -12,12 +12,9 @@ class SettingsPanel(Panel):      """      A panel to display all variables in django.conf.settings      """ -    name = 'Settings'      template = 'debug_toolbar/panels/settings.html' -    has_content = True -    def nav_title(self): -        return _('Settings') +    nav_title = _('Settings')      def title(self):          return _('Settings from <code>%s</code>') % settings.SETTINGS_MODULE diff --git a/debug_toolbar/panels/signals.py b/debug_toolbar/panels/signals.py index 74d1faa..269f091 100644 --- a/debug_toolbar/panels/signals.py +++ b/debug_toolbar/panels/signals.py @@ -14,9 +14,7 @@ from debug_toolbar.panels import Panel  class SignalsPanel(Panel): -    name = "Signals"      template = 'debug_toolbar/panels/signals.html' -    has_content = True      SIGNALS = {          'request_started': request_started, @@ -33,9 +31,6 @@ class SignalsPanel(Panel):          'post_syncdb': post_syncdb,      } -    def nav_title(self): -        return _("Signals") -      def nav_subtitle(self):          signals = self.get_stats()['signals']          num_receivers = sum(len(s[2]) for s in signals) @@ -51,8 +46,7 @@ class SignalsPanel(Panel):                           num_receivers) % {'num_receivers': num_receivers,                                             'num_signals': num_signals} -    def title(self): -        return _("Signals") +    title = _("Signals")      @property      def signals(self): diff --git a/debug_toolbar/panels/sql/panel.py b/debug_toolbar/panels/sql/panel.py index 3bfbe60..f4133db 100644 --- a/debug_toolbar/panels/sql/panel.py +++ b/debug_toolbar/panels/sql/panel.py @@ -49,10 +49,6 @@ class SQLPanel(Panel):      Panel that displays information about the SQL queries run while processing      the request.      """ -    name = 'SQL' -    template = 'debug_toolbar/panels/sql.html' -    has_content = True -      def __init__(self, *args, **kwargs):          super(SQLPanel, self).__init__(*args, **kwargs)          self._offset = dict((k, len(connections[k].queries)) for k in connections) @@ -104,26 +100,31 @@ class SQLPanel(Panel):          self._sql_time += kwargs['duration']          self._num_queries += 1 -    @classmethod -    def get_urls(cls): -        return patterns('debug_toolbar.panels.sql.views',               # noqa -            url(r'^sql_select/$', 'sql_select', name='sql_select'), -            url(r'^sql_explain/$', 'sql_explain', name='sql_explain'), -            url(r'^sql_profile/$', 'sql_profile', name='sql_profile'), -        ) +    # Implement the Panel API -    def nav_title(self): -        return _('SQL') +    nav_title = _('SQL') +    @property      def nav_subtitle(self):          return __("%d query in %.2fms", "%d queries in %.2fms",                    self._num_queries) % (self._num_queries, self._sql_time) +    @property      def title(self):          count = len(self._databases) -        return __('SQL Queries from %(count)d connection', -                  'SQL Queries from %(count)d connections', -                  count) % dict(count=count) +        return __('SQL queries from %(count)d connection', +                  'SQL queries from %(count)d connections', +                  count) % {'count': count} + +    template = 'debug_toolbar/panels/sql.html' + +    @classmethod +    def get_urls(cls): +        return patterns('debug_toolbar.panels.sql.views',               # noqa +            url(r'^sql_select/$', 'sql_select', name='sql_select'), +            url(r'^sql_explain/$', 'sql_explain', name='sql_explain'), +            url(r'^sql_profile/$', 'sql_profile', name='sql_profile'), +        )      def enable_instrumentation(self):          # This is thread-safe because database connections are thread-local. diff --git a/debug_toolbar/panels/templates/panel.py b/debug_toolbar/panels/templates/panel.py index c745b83..ec0fc47 100644 --- a/debug_toolbar/panels/templates/panel.py +++ b/debug_toolbar/panels/templates/panel.py @@ -48,10 +48,6 @@ class TemplatesPanel(Panel):      """      A panel that lists all templates used during processing of a response.      """ -    name = 'Templates' -    template = 'debug_toolbar/panels/templates.html' -    has_content = True -      def __init__(self, *args, **kwargs):          super(TemplatesPanel, self).__init__(*args, **kwargs)          self.templates = [] @@ -113,19 +109,23 @@ class TemplatesPanel(Panel):          kwargs['context'] = [force_text(item) for item in context_list]          self.templates.append(kwargs) -    @classmethod -    def get_urls(cls): -        return patterns('debug_toolbar.panels.templates.views',         # noqa -            url(r'^template_source/$', 'template_source', name='template_source'), -        ) +    # Implement the Panel API -    def nav_title(self): -        return _('Templates') +    nav_title = _('Templates') +    @property      def title(self):          num_templates = len(self.templates)          return _('Templates (%(num_templates)s rendered)') % {'num_templates': num_templates} +    template = 'debug_toolbar/panels/templates.html' + +    @classmethod +    def get_urls(cls): +        return patterns('debug_toolbar.panels.templates.views',         # noqa +            url(r'^template_source/$', 'template_source', name='template_source'), +        ) +      def process_response(self, request, response):          context_processors = dict(              [ diff --git a/debug_toolbar/panels/timer.py b/debug_toolbar/panels/timer.py index 900b624..6df4d4d 100644 --- a/debug_toolbar/panels/timer.py +++ b/debug_toolbar/panels/timer.py @@ -1,9 +1,9 @@  from __future__ import absolute_import, unicode_literals  try: -    import resource +    import resource     # Not available on Win32 systems  except ImportError: -    pass  # Will fail on Win32 systems +    resource = None  import time  from django.template.loader import render_to_string  from django.utils.translation import ugettext as _ @@ -14,21 +14,44 @@ class TimerPanel(Panel):      """      Panel that displays the time a response took in milliseconds.      """ -    name = 'Timer' + +    def nav_subtitle(self): +        stats = self.get_stats() +        if hasattr(self, '_start_rusage'): +            utime = self._end_rusage.ru_utime - self._start_rusage.ru_utime +            stime = self._end_rusage.ru_stime - self._start_rusage.ru_stime +            return _('CPU: %(cum)0.2fms (%(total)0.2fms)') % { +                'cum': (utime + stime) * 1000.0, +                'total': stats['total_time'] +            } +        elif 'total_time' in stats: +            return _('TOTAL: %0.2fms') % stats['total_time'] +        else: +            return '' + +    has_content = resource is not None + +    title = _('Time') +      template = 'debug_toolbar/panels/timer.html' -    try:  # if resource module not available, don't show content panel -        resource -    except NameError: -        has_content = False -        has_resource = False -    else: -        has_content = True -        has_resource = True +    @property +    def content(self): +        stats = self.get_stats() +        rows = ( +            (_('User CPU time'), _('%(utime)0.3f msec') % stats), +            (_('System CPU time'), _('%(stime)0.3f msec') % stats), +            (_('Total CPU time'), _('%(total)0.3f msec') % stats), +            (_('Elapsed time'), _('%(total_time)0.3f msec') % stats), +            (_('Context switches'), _('%(vcsw)d voluntary, %(ivcsw)d involuntary') % stats), +        ) +        context = self.context.copy() +        context.update({'rows': rows}) +        return render_to_string(self.template, context)      def process_request(self, request):          self._start_time = time.time() -        if self.has_resource: +        if self.has_content:              self._start_rusage = resource.getrusage(resource.RUSAGE_SELF)      def process_response(self, request, response): @@ -58,39 +81,5 @@ class TimerPanel(Panel):          self.record_stats(stats) -    def nav_title(self): -        return _('Timer') - -    def nav_subtitle(self): -        stats = self.get_stats() - -        if hasattr(self, '_start_rusage'): -            utime = self._end_rusage.ru_utime - self._start_rusage.ru_utime -            stime = self._end_rusage.ru_stime - self._start_rusage.ru_stime -            return _('CPU: %(cum)0.2fms (%(total)0.2fms)') % { -                'cum': (utime + stime) * 1000.0, -                'total': stats['total_time'] -            } -        elif 'total_time' in stats: -            return _('TOTAL: %0.2fms') % stats['total_time'] -        else: -            return '' - -    def title(self): -        return _('Time') -      def _elapsed_ru(self, name):          return getattr(self._end_rusage, name) - getattr(self._start_rusage, name) - -    def content(self): -        stats = self.get_stats() -        rows = ( -            (_('User CPU time'), _('%(utime)0.3f msec') % stats), -            (_('System CPU time'), _('%(stime)0.3f msec') % stats), -            (_('Total CPU time'), _('%(total)0.3f msec') % stats), -            (_('Elapsed time'), _('%(total_time)0.3f msec') % stats), -            (_('Context switches'), _('%(vcsw)d voluntary, %(ivcsw)d involuntary') % stats), -        ) -        context = self.context.copy() -        context.update({'rows': rows}) -        return render_to_string(self.template, context) diff --git a/debug_toolbar/panels/versions.py b/debug_toolbar/panels/versions.py index 6028115..529c2b9 100644 --- a/debug_toolbar/panels/versions.py +++ b/debug_toolbar/panels/versions.py @@ -15,18 +15,13 @@ class VersionsPanel(Panel):      """      Shows versions of Python, Django, and installed apps if possible.      """ -    name = 'Versions' -    template = 'debug_toolbar/panels/versions.html' -    has_content = True - -    def nav_title(self): -        return _('Versions') - +    @property      def nav_subtitle(self):          return 'Django %s' % django.get_version() -    def title(self): -        return _('Versions') +    title = _('Versions') + +    template = 'debug_toolbar/panels/versions.html'      def process_response(self, request, response):          versions = [('Python', '%d.%d.%d' % sys.version_info[:3])] diff --git a/tests/panels/test_profiling.py b/tests/panels/test_profiling.py index ccc8f2f..7e61c62 100644 --- a/tests/panels/test_profiling.py +++ b/tests/panels/test_profiling.py @@ -28,7 +28,7 @@ class ProfilingPanelTestCase(BaseTestCase):          self.panel.process_view(self.request, regular_view, ('profiling',), {})          self.panel.process_response(self.request, self.response)          self.assertIn('func_list', self.panel.get_stats()) -        self.assertIn('regular_view', self.panel.content()) +        self.assertIn('regular_view', self.panel.content)      # These two tests fail randomly for a reason I don't understand. diff --git a/tests/panels/test_request.py b/tests/panels/test_request.py index 16843c4..1c60ec7 100644 --- a/tests/panels/test_request.py +++ b/tests/panels/test_request.py @@ -19,7 +19,7 @@ class RequestPanelTestCase(BaseTestCase):              self.request.session['là'.encode('utf-8')] = 'là'.encode('utf-8')          self.panel.process_request(self.request)          self.panel.process_response(self.request, self.response) -        content = self.panel.content() +        content = self.panel.content          if six.PY3:              self.assertIn('où', content)          else: @@ -30,4 +30,4 @@ class RequestPanelTestCase(BaseTestCase):          self.request.path = '/non_ascii_request/'          self.panel.process_request(self.request)          self.panel.process_response(self.request, self.response) -        self.assertIn('nôt åscíì', self.panel.content()) +        self.assertIn('nôt åscíì', self.panel.content) diff --git a/tests/panels/test_sql.py b/tests/panels/test_sql.py index a6990a3..ece533c 100644 --- a/tests/panels/test_sql.py +++ b/tests/panels/test_sql.py @@ -55,7 +55,7 @@ class SQLPanelTestCase(BaseTestCase):          self.panel.process_response(self.request, self.response)          # ensure the panel renders correctly -        self.assertIn('café', self.panel.content()) +        self.assertIn('café', self.panel.content)      @unittest.skipUnless(connection.vendor == 'postgresql',                           'Test valid only on PostgreSQL') diff --git a/tests/panels/test_template.py b/tests/panels/test_template.py index 8cb29f2..f964727 100644 --- a/tests/panels/test_template.py +++ b/tests/panels/test_template.py @@ -46,4 +46,4 @@ class TemplatesPanelTestCase(BaseTestCase):          c = Context({'object': NonAsciiRepr()})          t.render(c)          self.panel.process_response(self.request, self.response) -        self.assertIn('nôt åscíì', self.panel.content()) +        self.assertIn('nôt åscíì', self.panel.content) | 
