Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ajax Requests panel - proof of concept #253

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions debug_toolbar/media/debug_toolbar/js/toolbar.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -83,6 +83,25 @@ window.djdt = (function(window, document, jQuery) {
}); });
return; return;
}); });
function refreshAjaxPanel() {
$.get('/__debug__/ajax_request/', function(data) {
$('#djDebugAjaxPanel .djDebugPanelContent div.scroll').html(data);
var num_reqs = $('#djDebugAjaxPanel .djDebugPanelContent tbody tr').length;
$('a.djDebugAjaxPanel small').html(num_reqs + ' requests');
});
}
$('#djDebug a.djAjaxLoad').live('click', function(e) {
e.preventDefault();
var req_id = $(this).attr('data-requestid');
$.get('/__debug__/ajax_request/' + req_id + '/', function(data) {
$('#djDebugWrapper').wrap('<div>').parent().html(data);
refreshAjaxPanel();
});
});
$('#djAjaxRefreshBtn').live('click', function(e) {
e.preventDefault();
refreshAjaxPanel();
});
function getSubcalls(row) { function getSubcalls(row) {
var id = row.attr('id'); var id = row.attr('id');
return $('.djDebugProfileRow[id^="'+id+'_"]'); return $('.djDebugProfileRow[id^="'+id+'_"]');
Expand Down
6 changes: 3 additions & 3 deletions debug_toolbar/media/debug_toolbar/js/toolbar.min.js

Large diffs are not rendered by default.

22 changes: 16 additions & 6 deletions debug_toolbar/middleware.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
""" """
import imp import imp
import thread import thread
import datetime


from django.conf import settings from django.conf import settings
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
Expand Down Expand Up @@ -127,11 +128,20 @@ def process_response(self, request, response):
response.get('Content-Type', '').split(';')[0] in _HTML_TYPES: response.get('Content-Type', '').split(';')[0] in _HTML_TYPES:
for panel in toolbar.panels: for panel in toolbar.panels:
panel.process_response(request, response) panel.process_response(request, response)
response.content = replace_insensitive( content = smart_unicode(response.content)
smart_unicode(response.content), ddt_html = smart_unicode(toolbar.render_toolbar())
self.tag, if self.tag in content:
smart_unicode(toolbar.render_toolbar() + self.tag)) response.content = replace_insensitive(content, self.tag,
if response.get('Content-Length', None): ddt_html + self.tag)
response['Content-Length'] = len(response.content) if response.get('Content-Length', None):
response['Content-Length'] = len(response.content)
if request.is_ajax():
from debug_toolbar.panels.ajax import AjaxDebugPanel
try:
ajax_panel = toolbar.get_panel(AjaxDebugPanel)
except IndexError:
ajax_panel = None
if ajax_panel:
ajax_panel.record(request, ddt_html)
del self.__class__.debug_toolbars[ident] del self.__class__.debug_toolbars[ident]
return response return response
66 changes: 66 additions & 0 deletions debug_toolbar/panels/ajax.py
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,66 @@
import time
import uuid
import inspect
import datetime

from django.utils.translation import ugettext_lazy as _
from debug_toolbar.panels import DebugPanel


class AjaxDebugPanel(DebugPanel):
"""
Panel that displays recent AJAX requests.
"""
name = 'Ajax'
template = 'debug_toolbar/panels/ajax.html'
has_content = True
session_key = 'debug_toolbar_ajax_requests'

def __init__(self, *args, **kwargs):
super(AjaxDebugPanel, self).__init__(*args, **kwargs)
self._num_requests = 0

def nav_title(self):
return _('Ajax')

def nav_subtitle(self):
# TODO l10n: use ngettext
return "%d request%s" % (
self._num_requests,
(self._num_requests == 1) and '' or 's'
)

def title(self):
return _('Ajax Requests')

def url(self):
return ''

def storage(self, request):
if self.session_key not in request.session:
request.session[self.session_key] = []
return request.session[self.session_key]

def record(self, request, ddt_html):
self.storage(request).append({
'id': str(uuid.uuid4()),
'time': datetime.datetime.now(),
'path': request.path,
'html': ddt_html,
})

def get_html(self, request, req_id):
for ajax_request in self.storage(request):
if ajax_request['id'] == req_id:
return ajax_request['html']

def get_context(self, request):
return {
'ajax_requests': self.storage(request),
}

def process_request(self, request):
self._num_requests = len(self.storage(request))

def process_response(self, request, response):
self.record_stats(self.get_context(request))
2 changes: 2 additions & 0 deletions debug_toolbar/templates/debug_toolbar/base.html
Original file line number Original file line Diff line number Diff line change
@@ -1,4 +1,5 @@
{% load i18n %} {% load i18n %}
<div id="djDebugWrapper">
<style type="text/css"> <style type="text/css">
@media print { #djDebug {display:none;}} @media print { #djDebug {display:none;}}
{{ css }} {{ css }}
Expand Down Expand Up @@ -52,3 +53,4 @@ <h3>{{ panel.title|safe }}</h3>
{% endfor %} {% endfor %}
<div id="djDebugWindow" class="panelContent"></div> <div id="djDebugWindow" class="panelContent"></div>
</div> </div>
</div>
19 changes: 19 additions & 0 deletions debug_toolbar/templates/debug_toolbar/panels/ajax.html
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,19 @@
{% load i18n %}
<table>
<thead>
<tr>
<th>{% trans "Request Time" %}</th>
<th>{% trans "Request Path" %}</th>
</tr>
</thead>
<tbody>
{% for ajax_req in ajax_requests %}
<tr id='djAjaxReq-{{ ajax_req.id }}' class="{% cycle 'djDebugOdd' 'djDebugEven' %}">
<td>{{ ajax_req.time }}</td>
<td><a class='djAjaxLoad' data-requestid='{{ ajax_req.id }}' href='' title='Load the toolbar for this request'>{{ ajax_req.path }}</a></td>
</tr>
{% endfor %}
</tbody>
</table>
<br/>
<button id='djAjaxRefreshBtn' type='button'>{% trans 'Refresh' %}</button>
1 change: 1 addition & 0 deletions debug_toolbar/toolbar/loader.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def __init__(self, request):
#'debug_toolbar.panels.cache.CacheDebugPanel', #'debug_toolbar.panels.cache.CacheDebugPanel',
'debug_toolbar.panels.signals.SignalDebugPanel', 'debug_toolbar.panels.signals.SignalDebugPanel',
'debug_toolbar.panels.logger.LoggingPanel', 'debug_toolbar.panels.logger.LoggingPanel',
'debug_toolbar.panels.ajax.AjaxDebugPanel',
) )
self.load_panels() self.load_panels()
self.stats = {} self.stats = {}
Expand Down
2 changes: 2 additions & 0 deletions debug_toolbar/urls.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@
url(r'^%s/sql_explain/$' % _PREFIX, 'debug_toolbar.views.sql_explain', name='sql_explain'), url(r'^%s/sql_explain/$' % _PREFIX, 'debug_toolbar.views.sql_explain', name='sql_explain'),
url(r'^%s/sql_profile/$' % _PREFIX, 'debug_toolbar.views.sql_profile', name='sql_profile'), url(r'^%s/sql_profile/$' % _PREFIX, 'debug_toolbar.views.sql_profile', name='sql_profile'),
url(r'^%s/template_source/$' % _PREFIX, 'debug_toolbar.views.template_source', name='template_source'), url(r'^%s/template_source/$' % _PREFIX, 'debug_toolbar.views.template_source', name='template_source'),
url(r'^%s/ajax_request/$' % _PREFIX, 'debug_toolbar.views.ajax_list', name='ajax_list'),
url(r'^%s/ajax_request/(?P<req_id>[\w-]+)/$' % _PREFIX, 'debug_toolbar.views.ajax_request', name='ajax_request'),
) )
35 changes: 34 additions & 1 deletion debug_toolbar/views.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import os import os
import django.views.static import django.views.static
from django.conf import settings from django.conf import settings
from django.http import HttpResponseBadRequest from django.http import HttpResponse, HttpResponseBadRequest
from django.shortcuts import render_to_response from django.shortcuts import render_to_response
from django.utils import simplejson from django.utils import simplejson
from django.utils.hashcompat import sha_constructor from django.utils.hashcompat import sha_constructor
Expand Down Expand Up @@ -204,3 +204,36 @@ def template_source(request):
'source': source, 'source': source,
'template_name': template_name 'template_name': template_name
}) })


def ajax_request(request, req_id):
"""
Returns the Debug Toolbar HTML for the given request ID.
"""
from debug_toolbar.panels.ajax import AjaxDebugPanel
from debug_toolbar.middleware import DebugToolbarMiddleware
toolbar = DebugToolbarMiddleware.get_current()
try:
ajax_panel = toolbar.get_panel(AjaxDebugPanel)
except IndexError:
raise ValueError('AjaxDebugPanel must be enabled to use this view.')
ddt_html = ajax_panel.get_html(request, req_id)
if ddt_html:
return HttpResponse(ddt_html)
else:
return HttpResponseBadRequest('No such request {0}'.format(req_id))


def ajax_list(request):
"""
Returns the latest list of AJAX requests in HTML format.
"""
from debug_toolbar.panels.ajax import AjaxDebugPanel
from debug_toolbar.middleware import DebugToolbarMiddleware
toolbar = DebugToolbarMiddleware.get_current()
try:
ajax_panel = toolbar.get_panel(AjaxDebugPanel)
except IndexError:
raise ValueError('AjaxDebugPanel must be enabled to use this view.')
context = ajax_panel.get_context(request)
return render_to_response('debug_toolbar/panels/ajax.html', context)