aboutsummaryrefslogtreecommitdiffstats
path: root/debug_toolbar/toolbar/loader.py
blob: f9262f82a5304080bfb473ccdcb798e7257f394a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
"""
The main DebugToolbar class that loads and renders the Toolbar.
"""

from __future__ import unicode_literals

from django.conf import settings
from django.template.loader import render_to_string
from django.utils.datastructures import SortedDict
from django.utils.importlib import import_module

from debug_toolbar.utils.settings import CONFIG


class DebugToolbar(object):

    def __init__(self, request):
        self.request = request
        self._panels = SortedDict()
        base_url = self.request.META.get('SCRIPT_NAME', '')
        self.config = {}
        self.config.update(CONFIG)
        self.template_context = {
            'BASE_URL': base_url,  # for backwards compatibility
            'STATIC_URL': settings.STATIC_URL,
            'TOOLBAR_ROOT_TAG_ATTRS': self.config['ROOT_TAG_ATTRS'],
        }

        self.load_panels()
        self.stats = {}

    def _get_panels(self):
        return list(self._panels.values())
    panels = property(_get_panels)

    def get_panel(self, cls):
        return self._panels[cls]

    def load_panels(self):
        """
        Populate debug panels
        """
        global panel_classes
        for panel_class in panel_classes:
            panel_instance = panel_class(self, context=self.template_context)
            self._panels[panel_class] = panel_instance

    def render_toolbar(self):
        """
        Renders the overall Toolbar with panels inside.
        """
        context = self.template_context.copy()
        context.update({
            'panels': self.panels,
            'toolbar_id': save_toolbar(self),
        })
        return render_to_string('debug_toolbar/base.html', context)


panel_classes = []


def load_panel_classes():
    from django.conf import settings
    from django.core.exceptions import ImproperlyConfigured

    # Check if settings has a DEBUG_TOOLBAR_PANELS, otherwise use default
    panels = getattr(settings, 'DEBUG_TOOLBAR_PANELS', (
        'debug_toolbar.panels.version.VersionDebugPanel',
        'debug_toolbar.panels.timer.TimerDebugPanel',
        'debug_toolbar.panels.settings_vars.SettingsVarsDebugPanel',
        'debug_toolbar.panels.headers.HeaderDebugPanel',
        'debug_toolbar.panels.request_vars.RequestVarsDebugPanel',
        'debug_toolbar.panels.sql.SQLDebugPanel',
        'debug_toolbar.panels.template.TemplateDebugPanel',
        'debug_toolbar.panels.cache.CacheDebugPanel',
        'debug_toolbar.panels.signals.SignalDebugPanel',
        'debug_toolbar.panels.logger.LoggingPanel',
    ))
    for panel_path in panels:
        try:
            dot = panel_path.rindex('.')
        except ValueError:
            raise ImproperlyConfigured(
                "%s isn't a debug panel module" % panel_path)
        panel_module, panel_classname = panel_path[:dot], panel_path[dot + 1:]
        try:
            mod = import_module(panel_module)
        except ImportError as e:
            raise ImproperlyConfigured(
                'Error importing debug panel %s: "%s"' %
                (panel_module, e))
        try:
            panel_class = getattr(mod, panel_classname)
        except AttributeError:
            raise ImproperlyConfigured(
                'Toolbar Panel module "%s" does not define a "%s" class' %
                (panel_module, panel_classname))
        panel_classes.append(panel_class)


toolbar_counter = 0
toolbar_results = SortedDict()


def save_toolbar(toolbar):
    global toolbar_counter, toolbar_results
    toolbar_counter += 1
    toolbar_results[toolbar_counter] = toolbar
    for _ in range(len(toolbar_results) - CONFIG['RESULTS_CACHE_SIZE']):
        # When we drop support for Python 2.6 and switch to
        # collections.OrderedDict, use popitem(last=False).
        del toolbar_results[toolbar_results.keyOrder[0]]
    return toolbar_counter


def get_saved_toolbar(toolbar_id):
    return toolbar_results.get(toolbar_id)