From d8935590551dfa708ce46d458c920feb42e3ea2f Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Tue, 7 Oct 2008 21:39:19 -0700 Subject: Bringing over patch from Alex Gaynor to fix SQL params when using django.contrib.gis. --- debug_toolbar/panels/sql.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'debug_toolbar') diff --git a/debug_toolbar/panels/sql.py b/debug_toolbar/panels/sql.py index a4c18f6..dbf92c6 100644 --- a/debug_toolbar/panels/sql.py +++ b/debug_toolbar/panels/sql.py @@ -5,6 +5,7 @@ from django.db import connection from django.db.backends import util from django.template.loader import render_to_string from django.utils import simplejson +from django.utils.encoding import force_unicode from django.utils.hashcompat import sha_constructor class DatabaseStatTracker(util.CursorDebugWrapper): @@ -20,7 +21,7 @@ class DatabaseStatTracker(util.CursorDebugWrapper): stop = time.time() _params = None try: - _params = simplejson.dumps(params) + _params = simplejson.dumps([force_unicode(x) for x in params]) except TypeError: pass # object not JSON serializable # We keep `sql` to maintain backwards compatibility -- cgit v1.2.3 From 285a03c0d1ab0f4b6567278f1e1871e2d5c3e21d Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Tue, 7 Oct 2008 22:43:32 -0700 Subject: Since we're concatenating params, make the default empty value a string. --- debug_toolbar/panels/sql.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'debug_toolbar') diff --git a/debug_toolbar/panels/sql.py b/debug_toolbar/panels/sql.py index dbf92c6..56b83a0 100644 --- a/debug_toolbar/panels/sql.py +++ b/debug_toolbar/panels/sql.py @@ -19,7 +19,7 @@ class DatabaseStatTracker(util.CursorDebugWrapper): return self.cursor.execute(sql, params) finally: stop = time.time() - _params = None + _params = '' try: _params = simplejson.dumps([force_unicode(x) for x in params]) except TypeError: -- cgit v1.2.3 From 07407876a608a4d573dbd6ee4cee2d3798f752c5 Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Tue, 7 Oct 2008 23:09:29 -0700 Subject: Fix inconsistent SQL timings. All SQL timings are milliseconds now. --- debug_toolbar/panels/sql.py | 4 ++-- debug_toolbar/templates/debug_toolbar/panels/sql.html | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'debug_toolbar') diff --git a/debug_toolbar/panels/sql.py b/debug_toolbar/panels/sql.py index 56b83a0..fc53247 100644 --- a/debug_toolbar/panels/sql.py +++ b/debug_toolbar/panels/sql.py @@ -27,7 +27,7 @@ class DatabaseStatTracker(util.CursorDebugWrapper): # We keep `sql` to maintain backwards compatibility self.db.queries.append({ 'sql': self.db.ops.last_executed_query(self.cursor, sql, params), - 'time': stop - start, + 'time': (stop - start) * 1000, # convert to ms 'raw_sql': sql, 'params': _params, 'hash': sha_constructor(settings.SECRET_KEY + sql + _params).hexdigest(), @@ -47,7 +47,7 @@ class SQLDebugPanel(DebugPanel): self._sql_time = 0 def title(self): - self._sql_time = sum(map(lambda q: float(q['time']) * 1000, connection.queries)) + self._sql_time = sum(map(lambda q: float(q['time']), connection.queries)) return '%d SQL %s (%.2fms)' % ( len(connection.queries), (len(connection.queries) == 1) and 'query' or 'queries', diff --git a/debug_toolbar/templates/debug_toolbar/panels/sql.html b/debug_toolbar/templates/debug_toolbar/panels/sql.html index d35d83e..f6ff64f 100644 --- a/debug_toolbar/templates/debug_toolbar/panels/sql.html +++ b/debug_toolbar/templates/debug_toolbar/panels/sql.html @@ -10,12 +10,12 @@ {% for query in queries %} - {{ query.time|floatformat:"4" }} + {{ query.time|floatformat:"2" }} {% if query.params %} - SELECT - EXPLAIN - PROFILE + SELECT + EXPLAIN + PROFILE {% endif %} {{ query.sql|safe }} -- cgit v1.2.3 From 3b393d7b7fd3f134b5011462e2206f1e1f9144e5 Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Tue, 9 Dec 2008 12:43:38 -0800 Subject: Django seems to only produce LEFT OUTER JOINs, so search for that. --- debug_toolbar/panels/sql.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'debug_toolbar') diff --git a/debug_toolbar/panels/sql.py b/debug_toolbar/panels/sql.py index fc53247..e202994 100644 --- a/debug_toolbar/panels/sql.py +++ b/debug_toolbar/panels/sql.py @@ -74,7 +74,7 @@ def reformat_sql(sql): sql = sql.replace('` FROM ', '`\nFROM\n\t') sql = sql.replace(' WHERE ', '\nWHERE\n\t') sql = sql.replace(' INNER JOIN ', '\nINNER JOIN\n\t') - sql = sql.replace(' OUTER JOIN ', '\nOUTER JOIN\n\t') + sql = sql.replace(' LEFT OUTER JOIN ', '\nLEFT OUTER JOIN\n\t') sql = sql.replace(' ORDER BY ', '\nORDER BY\n\t') # Use Pygments to highlight SQL if it's available try: -- cgit v1.2.3 From 64794a5a1d342ffeceae9ddaa55c81384d54702f Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Tue, 9 Dec 2008 12:44:07 -0800 Subject: Only show the SQL profile if we're using a MySQL database backend. --- debug_toolbar/panels/sql.py | 1 + debug_toolbar/templates/debug_toolbar/panels/sql.html | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'debug_toolbar') diff --git a/debug_toolbar/panels/sql.py b/debug_toolbar/panels/sql.py index e202994..22d2690 100644 --- a/debug_toolbar/panels/sql.py +++ b/debug_toolbar/panels/sql.py @@ -65,6 +65,7 @@ class SQLDebugPanel(DebugPanel): context = { 'queries': sql_queries, 'sql_time': self._sql_time, + 'is_mysql': settings.DATABASE_ENGINE == 'mysql', } return render_to_string('debug_toolbar/panels/sql.html', context) diff --git a/debug_toolbar/templates/debug_toolbar/panels/sql.html b/debug_toolbar/templates/debug_toolbar/panels/sql.html index f6ff64f..7de2220 100644 --- a/debug_toolbar/templates/debug_toolbar/panels/sql.html +++ b/debug_toolbar/templates/debug_toolbar/panels/sql.html @@ -15,7 +15,9 @@ {% if query.params %} SELECT EXPLAIN - PROFILE + {% if is_mysql %} + PROFILE + {% endif %} {% endif %} {{ query.sql|safe }} -- cgit v1.2.3 From 7eb5b38bcbb71dddf7f33026ab70594fce02c6a5 Mon Sep 17 00:00:00 2001 From: Adam Gomaa Date: Thu, 9 Oct 2008 15:56:09 -0400 Subject: Fix the number of queries shown in the title, which was overreporting by self._offset (sometimes 0). --- debug_toolbar/panels/sql.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'debug_toolbar') diff --git a/debug_toolbar/panels/sql.py b/debug_toolbar/panels/sql.py index 22d2690..7396c3a 100644 --- a/debug_toolbar/panels/sql.py +++ b/debug_toolbar/panels/sql.py @@ -48,9 +48,10 @@ class SQLDebugPanel(DebugPanel): def title(self): self._sql_time = sum(map(lambda q: float(q['time']), connection.queries)) + num_queries = len(connection.queries) - self._offset return '%d SQL %s (%.2fms)' % ( - len(connection.queries), - (len(connection.queries) == 1) and 'query' or 'queries', + num_queries, + (num_queries == 1) and 'query' or 'queries', self._sql_time ) -- cgit v1.2.3 From d58f119fc17bd15edee5f3ac783703a8aec534b8 Mon Sep 17 00:00:00 2001 From: Martin Maney Date: Sat, 8 Nov 2008 11:33:19 -0600 Subject: Added fine-grained CPU usage to timer --- debug_toolbar/panels/timer.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'debug_toolbar') diff --git a/debug_toolbar/panels/timer.py b/debug_toolbar/panels/timer.py index ea8ed4a..a1d6355 100644 --- a/debug_toolbar/panels/timer.py +++ b/debug_toolbar/panels/timer.py @@ -1,4 +1,4 @@ -import time +import time, resource from debug_toolbar.panels import DebugPanel class TimerDebugPanel(DebugPanel): @@ -9,12 +9,16 @@ class TimerDebugPanel(DebugPanel): def process_request(self, request): self._start_time = time.time() + self._start_rusage = resource.getrusage(resource.RUSAGE_SELF) def process_response(self, request, response): self.total_time = (time.time() - self._start_time) * 1000 + self._end_rusage = resource.getrusage(resource.RUSAGE_SELF) def title(self): - return 'Time: %0.2fms' % (self.total_time) + utime = self._end_rusage.ru_utime - self._start_rusage.ru_utime + stime = self._end_rusage.ru_stime - self._start_rusage.ru_stime + return 'Time: %0.2fms, %0.2fms CPU' % (self.total_time, (utime + stime) * 1000.0) def url(self): return '' -- cgit v1.2.3 From 47d1a4ff38bc48a6dd54246556434a72c0476bb0 Mon Sep 17 00:00:00 2001 From: Martin Maney Date: Sat, 8 Nov 2008 19:48:18 -0600 Subject: Added more of the rusage stats in a drop-down panel (some items were commented out after I was reminded that not all of the original BSD items are supported under Linux) --- debug_toolbar/panels/timer.py | 43 +++++++++++++++++++++- .../templates/debug_toolbar/panels/timer.html | 7 ++++ 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 debug_toolbar/templates/debug_toolbar/panels/timer.html (limited to 'debug_toolbar') diff --git a/debug_toolbar/panels/timer.py b/debug_toolbar/panels/timer.py index a1d6355..b93c843 100644 --- a/debug_toolbar/panels/timer.py +++ b/debug_toolbar/panels/timer.py @@ -1,11 +1,16 @@ import time, resource + +from django.template.loader import render_to_string + from debug_toolbar.panels import DebugPanel + class TimerDebugPanel(DebugPanel): """ Panel that displays the time a response took in milliseconds. """ name = 'Timer' + has_content = True def process_request(self, request): self._start_time = time.time() @@ -23,5 +28,41 @@ class TimerDebugPanel(DebugPanel): def url(self): return '' + def _elapsed_ru(self, name): + return getattr(self._end_rusage, name) - getattr(self._start_rusage, name) + def content(self): - return '' + + utime = 1000 * self._elapsed_ru('ru_utime') + stime = 1000 * self._elapsed_ru('ru_stime') + vcsw = self._elapsed_ru('ru_nvcsw') + ivcsw = self._elapsed_ru('ru_nivcsw') + minflt = self._elapsed_ru('ru_minflt') + majflt = self._elapsed_ru('ru_majflt') + +# these are documented as not meaningful under Linux. If you're running BSD +# feel free to enable them, and add any others that I hadn't gotten to before +# I noticed that I was getting nothing but zeroes and that the docs agreed. :-( +# +# blkin = self._elapsed_ru('ru_inblock') +# blkout = self._elapsed_ru('ru_oublock') +# swap = self._elapsed_ru('ru_nswap') +# rss = self._end_rusage.ru_maxrss +# srss = self._end_rusage.ru_ixrss +# urss = self._end_rusage.ru_idrss +# usrss = self._end_rusage.ru_isrss + + rows = ( + ('User CPU time', '%0.3f msec' % utime), + ('System CPU time', '%0.3f msec' % stime), + ('Total CPU time', '%0.3f msec' % (utime + stime)), + ('Elapsed time', '%0.3f msec' % self.total_time), + ('Context switches', '%d voluntary, %d involuntary' % (vcsw, ivcsw)), +# ('Memory use', '%d max RSS, %d shared, %d unshared' % (rss, srss, urss + usrss)), +# ('Page faults', '%d no i/o, %d requiring i/o' % (minflt, majflt)), +# ('Disk operations', '%d in, %d out, %d swapout' % (blkin, blkout, swap)), + ) + context = { + 'rows': rows, + } + return render_to_string('debug_toolbar/panels/timer.html', context) diff --git a/debug_toolbar/templates/debug_toolbar/panels/timer.html b/debug_toolbar/templates/debug_toolbar/panels/timer.html new file mode 100644 index 0000000..161507c --- /dev/null +++ b/debug_toolbar/templates/debug_toolbar/panels/timer.html @@ -0,0 +1,7 @@ +

Resource Usage

+ + + {% for row in rows %} + + {% endfor %} +
{{ row.1 }}{{ row.0 }}
-- cgit v1.2.3 From 9f5c2280ec25c162b720a6e864b081934126cecc Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Tue, 9 Dec 2008 14:14:46 -0800 Subject: Minor cleanup and template change to previous commit. --- debug_toolbar/panels/timer.py | 5 ++--- .../templates/debug_toolbar/panels/timer.html | 22 ++++++++++++++++++---- 2 files changed, 20 insertions(+), 7 deletions(-) (limited to 'debug_toolbar') diff --git a/debug_toolbar/panels/timer.py b/debug_toolbar/panels/timer.py index b93c843..cafdb05 100644 --- a/debug_toolbar/panels/timer.py +++ b/debug_toolbar/panels/timer.py @@ -1,7 +1,6 @@ -import time, resource - +import resource +import time from django.template.loader import render_to_string - from debug_toolbar.panels import DebugPanel diff --git a/debug_toolbar/templates/debug_toolbar/panels/timer.html b/debug_toolbar/templates/debug_toolbar/panels/timer.html index 161507c..1b077c6 100644 --- a/debug_toolbar/templates/debug_toolbar/panels/timer.html +++ b/debug_toolbar/templates/debug_toolbar/panels/timer.html @@ -1,7 +1,21 @@

Resource Usage

- - {% for row in rows %} - - {% endfor %} + + + + + + + + + + + + {% for key, value in rows %} + + + + + {% endfor %} +
{{ row.1 }}{{ row.0 }}
KeyValue
{{ key|escape }}{{ value|escape }}
-- cgit v1.2.3 From d163dea7a5e6f07de690a43a65409df072fdb612 Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Thu, 11 Dec 2008 14:04:45 -0800 Subject: Win32 systems don't have the resource module. This patch codes around it so only the basic timings are shown for those that don't have the resource module, and finer grained timings are shown for those that do. --- debug_toolbar/panels/timer.py | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'debug_toolbar') diff --git a/debug_toolbar/panels/timer.py b/debug_toolbar/panels/timer.py index cafdb05..352bf55 100644 --- a/debug_toolbar/panels/timer.py +++ b/debug_toolbar/panels/timer.py @@ -1,4 +1,7 @@ -import resource +try: + import resource +except ImportError: + pass # Will fail on Win32 systems import time from django.template.loader import render_to_string from debug_toolbar.panels import DebugPanel @@ -9,20 +12,32 @@ class TimerDebugPanel(DebugPanel): Panel that displays the time a response took in milliseconds. """ name = 'Timer' - has_content = True + 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 def process_request(self, request): self._start_time = time.time() - self._start_rusage = resource.getrusage(resource.RUSAGE_SELF) + if self.has_resource: + self._start_rusage = resource.getrusage(resource.RUSAGE_SELF) def process_response(self, request, response): self.total_time = (time.time() - self._start_time) * 1000 - self._end_rusage = resource.getrusage(resource.RUSAGE_SELF) + if self.has_resource: + self._end_rusage = resource.getrusage(resource.RUSAGE_SELF) def title(self): - utime = self._end_rusage.ru_utime - self._start_rusage.ru_utime - stime = self._end_rusage.ru_stime - self._start_rusage.ru_stime - return 'Time: %0.2fms, %0.2fms CPU' % (self.total_time, (utime + stime) * 1000.0) + if self.has_resource: + utime = self._end_rusage.ru_utime - self._start_rusage.ru_utime + stime = self._end_rusage.ru_stime - self._start_rusage.ru_stime + return 'Time: %0.2fms, %0.2fms CPU' % (self.total_time, (utime + stime) * 1000.0) + else: + return 'Time: %0.2fms' % (self.total_time) def url(self): return '' -- cgit v1.2.3 From bad779df7aa31b6d4ae09f3cff4f13158cde2791 Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Fri, 12 Dec 2008 15:19:06 -0800 Subject: Adding version info to module. --- debug_toolbar/__init__.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'debug_toolbar') diff --git a/debug_toolbar/__init__.py b/debug_toolbar/__init__.py index e69de29..9603d9e 100644 --- a/debug_toolbar/__init__.py +++ b/debug_toolbar/__init__.py @@ -0,0 +1,2 @@ +VERSION = (0, 0, 1) +__version__ = '.'.join(map(str, VERSION)) -- cgit v1.2.3 From a148ba84fc9d862061d6a4c7e3b2c034c60931c6 Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Wed, 17 Dec 2008 19:48:58 +0900 Subject: Fixes #19 -- Modified the middleware to only install the debug ROOT_URLCONF if the debug toolbar is actually displayed. --- debug_toolbar/middleware.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'debug_toolbar') diff --git a/debug_toolbar/middleware.py b/debug_toolbar/middleware.py index 9dd9954..8dcf454 100644 --- a/debug_toolbar/middleware.py +++ b/debug_toolbar/middleware.py @@ -44,12 +44,12 @@ class DebugToolbarMiddleware(object): return True def process_request(self, request): - if self.override_url: - debug_toolbar.urls.urlpatterns += self.original_pattern - self.override_url = False - request.urlconf = 'debug_toolbar.urls' - if self.show_toolbar(request): + if self.override_url: + debug_toolbar.urls.urlpatterns += self.original_pattern + self.override_url = False + request.urlconf = 'debug_toolbar.urls' + self.debug_toolbar = DebugToolbar(request) for panel in self.debug_toolbar.panels: panel.process_request(request) -- cgit v1.2.3 From 63394b531cd41eef831cc8a59e8b1848777ca626 Mon Sep 17 00:00:00 2001 From: Reto Aebersold Date: Tue, 13 Jan 2009 17:44:09 +0800 Subject: Load SQLDebugPanel before TemplateDebugPanel to get the right number of queries if a model __unicode__() function make some additional queries (i.e. for a related model). Signed-off-by: Rob Hudson --- debug_toolbar/toolbar/loader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'debug_toolbar') diff --git a/debug_toolbar/toolbar/loader.py b/debug_toolbar/toolbar/loader.py index b217665..2422f3d 100644 --- a/debug_toolbar/toolbar/loader.py +++ b/debug_toolbar/toolbar/loader.py @@ -18,8 +18,8 @@ class DebugToolbar(object): 'debug_toolbar.panels.settings_vars.SettingsVarsDebugPanel', 'debug_toolbar.panels.headers.HeaderDebugPanel', 'debug_toolbar.panels.request_vars.RequestVarsDebugPanel', - 'debug_toolbar.panels.template.TemplateDebugPanel', 'debug_toolbar.panels.sql.SQLDebugPanel', + 'debug_toolbar.panels.template.TemplateDebugPanel', 'debug_toolbar.panels.cache.CacheDebugPanel', 'debug_toolbar.panels.logger.LoggingPanel', ) -- cgit v1.2.3 From 9d335bed8c83981370429833d1c5fd7f31b97a5e Mon Sep 17 00:00:00 2001 From: Reto Aebersold Date: Sat, 17 Jan 2009 12:18:19 -0800 Subject: Adding ability to show/hide toolbar, using jquery.cookie.js for statefulness. Signed-off-by: Rob Hudson --- debug_toolbar/media/Makefile | 1 + debug_toolbar/media/toolbar.css | 21 +++++++++++++++++++++ debug_toolbar/media/toolbar.js | 25 +++++++++++++++++++++++++ debug_toolbar/media/toolbar.min.js | 2 +- debug_toolbar/templates/debug_toolbar/base.html | 12 +++++++++++- 5 files changed, 59 insertions(+), 2 deletions(-) (limited to 'debug_toolbar') diff --git a/debug_toolbar/media/Makefile b/debug_toolbar/media/Makefile index 7f8f2b2..a7fd227 100644 --- a/debug_toolbar/media/Makefile +++ b/debug_toolbar/media/Makefile @@ -3,6 +3,7 @@ all: compress_js compress_css compress_js: java -jar ~/bin/yuicompressor.jar toolbar.js > toolbar.min.js + java -jar ~/bin/yuicompressor.jar jquery.cookie.js > jquery.cookie.min.js compress_css: java -jar ~/bin/yuicompressor.jar --type css toolbar.css > toolbar.min.css diff --git a/debug_toolbar/media/toolbar.css b/debug_toolbar/media/toolbar.css index 2ce4226..a04f451 100644 --- a/debug_toolbar/media/toolbar.css +++ b/debug_toolbar/media/toolbar.css @@ -23,6 +23,27 @@ right:0; } +#djDebugToolbarHandle { + background: #326342; + height: 30px; + z-index: 100000000; + border-bottom: 2px solid #234f32; + position:absolute; + top:0; + left:0; + right:0; + width: 16px; +} + +#djDebugToolbarHandle ul li{ + padding: 3px 0px 0px 3px; +} + +#djDebugToolbarHandle ul li a{ + font-size: 16px; + font-weight: bold; +} + #djDebugToolbar ul { margin: 0; padding: 0; diff --git a/debug_toolbar/media/toolbar.js b/debug_toolbar/media/toolbar.js index 455a2fc..dcd52ae 100644 --- a/debug_toolbar/media/toolbar.js +++ b/debug_toolbar/media/toolbar.js @@ -1,6 +1,7 @@ var _$ = window.$; jQuery.noConflict(); jQuery(function($) { + var COOKIE_NAME = 'dj_debug_panel'; $.djDebug = function(data, klass) { $.djDebug.init(); } @@ -35,6 +36,17 @@ jQuery(function($) { $('#djDebugTemplatePanel a.djTemplateShowContext').click(function() { $.djDebug.toggle_content($(this).parent().next()); }); + $('#djHideToolBarButton').click(function() { + $.djDebug.hide_toolbar(true); + }); + $('#djShowToolBarButton').click(function() { + $.djDebug.show_toolbar(); + }); + if($.cookie(COOKIE_NAME)){ + $.djDebug.hide_toolbar(false); + }else{ + $('#djDebugToolbar').show(); + } }, open: function() { $(document).bind('keydown.djDebug', function(e) { @@ -53,6 +65,18 @@ jQuery(function($) { close: function() { $(document).trigger('close.djDebug'); return false; + }, + hide_toolbar: function(setCookie) { + $('#djDebugToolbar').hide("fast"); + $('#djDebugToolbarHandle').show(); + if(setCookie){ + $.cookie(COOKIE_NAME, 'hide', {path: '/', expires: 10 }); + } + }, + show_toolbar: function() { + $('#djDebugToolbarHandle').hide(); + $('#djDebugToolbar').show("fast"); + $.cookie(COOKIE_NAME, null, {path: '/', expires: -1 }); } }); $(document).bind('close.djDebug', function() { @@ -64,3 +88,4 @@ jQuery(function() { jQuery.djDebug(); }); $ = _$; + diff --git a/debug_toolbar/media/toolbar.min.js b/debug_toolbar/media/toolbar.min.js index 1f8b8b5..dc4b29d 100644 --- a/debug_toolbar/media/toolbar.min.js +++ b/debug_toolbar/media/toolbar.min.js @@ -1 +1 @@ -var _$=window.$;jQuery.noConflict();jQuery(function(A){A.djDebug=function(C,B){A.djDebug.init()};A.extend(A.djDebug,{init:function(){var B=null;A("#djDebugPanelList li a").click(function(){B=A("#djDebug #"+this.className);if(B.is(":visible")){A(document).trigger("close.djDebug")}else{A(".panelContent").hide();B.show();A.djDebug.open()}return false});A("#djDebug a.close").click(function(){A(document).trigger("close.djDebug");return false});A("#djDebug a.remoteCall").click(function(){A("#djDebugWindow").load(this.href,{},function(){A("#djDebugWindow a.back").click(function(){A(this).parent().hide();return false})});A("#djDebugWindow").show();return false});A("#djDebugTemplatePanel a.djTemplateShowContext").click(function(){A.djDebug.toggle_content(A(this).parent().next())})},open:function(){A(document).bind("keydown.djDebug",function(B){if(B.keyCode==27){A.djDebug.close()}})},toggle_content:function(B){if(B.is(":visible")){B.hide()}else{B.show()}},close:function(){A(document).trigger("close.djDebug");return false}});A(document).bind("close.djDebug",function(){A(document).unbind("keydown.djDebug");A(".panelContent").hide()})});jQuery(function(){jQuery.djDebug()});$=_$; \ No newline at end of file +var _$=window.$;jQuery.noConflict();jQuery(function(a){a.djDebug=function(c,b){a.djDebug.init()};a.extend(a.djDebug,{init:function(){var b=null;a("#djDebugPanelList li a").click(function(){b=a("#djDebug #"+this.className);if(b.is(":visible")){a(document).trigger("close.djDebug")}else{a(".panelContent").hide();b.show();a.djDebug.open()}return false});a("#djDebug a.close").click(function(){a(document).trigger("close.djDebug");return false});a("#djDebug a.remoteCall").click(function(){a("#djDebugWindow").load(this.href,{},function(){a("#djDebugWindow a.back").click(function(){a(this).parent().hide();return false})});a("#djDebugWindow").show();return false});a("#djDebugTemplatePanel a.djTemplateShowContext").click(function(){a.djDebug.toggle_content(a(this).parent().next())})},open:function(){a(document).bind("keydown.djDebug",function(b){if(b.keyCode==27){a.djDebug.close()}})},toggle_content:function(b){if(b.is(":visible")){b.hide()}else{b.show()}},close:function(){a(document).trigger("close.djDebug");return false}});a(document).bind("close.djDebug",function(){a(document).unbind("keydown.djDebug");a(".panelContent").hide()})});jQuery(function(){jQuery.djDebug()});$=_$; \ No newline at end of file diff --git a/debug_toolbar/templates/debug_toolbar/base.html b/debug_toolbar/templates/debug_toolbar/base.html index a6c8aef..3b8e92e 100644 --- a/debug_toolbar/templates/debug_toolbar/base.html +++ b/debug_toolbar/templates/debug_toolbar/base.html @@ -4,14 +4,19 @@ document.write(unescape('%3Cscript src="' + jquery_url + '" type="text/javascript"%3E%3C/script%3E')); } +
-
+ + {% for panel in panels %} {% if panel.has_content %}
-- cgit v1.2.3 From 184277b5d9a4658eb326d8f679618284299554a2 Mon Sep 17 00:00:00 2001 From: Reto Aebersold Date: Sat, 17 Jan 2009 12:21:27 -0800 Subject: Fixing AJAX calls to detailed SQL views. Signed-off-by: Rob Hudson --- debug_toolbar/middleware.py | 4 +++- debug_toolbar/urls.py | 12 +++++++----- debug_toolbar/views.py | 17 +++++++++++++---- 3 files changed, 23 insertions(+), 10 deletions(-) (limited to 'debug_toolbar') diff --git a/debug_toolbar/middleware.py b/debug_toolbar/middleware.py index 8dcf454..c3cf5f9 100644 --- a/debug_toolbar/middleware.py +++ b/debug_toolbar/middleware.py @@ -8,6 +8,8 @@ from django.utils.encoding import smart_unicode from django.conf.urls.defaults import include, patterns import debug_toolbar.urls from debug_toolbar.toolbar.loader import DebugToolbar +from debug_toolbar.urls import DEBUG_TB_URL_PREFIX +import os _HTML_TYPES = ('text/html', 'application/xhtml+xml') @@ -37,7 +39,7 @@ class DebugToolbarMiddleware(object): def show_toolbar(self, request): if not settings.DEBUG: return False - if request.is_ajax(): + if request.is_ajax() and not request.path.startswith(os.path.join('/', DEBUG_TB_URL_PREFIX)): #Allow ajax requests from the debug toolbar return False if not request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS: return False diff --git a/debug_toolbar/urls.py b/debug_toolbar/urls.py index 77d1a80..05233e2 100644 --- a/debug_toolbar/urls.py +++ b/debug_toolbar/urls.py @@ -7,10 +7,12 @@ this into the urlconf for the request. from django.conf.urls.defaults import * from django.conf import settings +DEBUG_TB_URL_PREFIX = '__debug__' + urlpatterns = patterns('', - url(r'^__debug__/m/(.*)$', 'debug_toolbar.views.debug_media'), - url(r'^__debug__/sql_select/$', 'debug_toolbar.views.sql_select', name='sql_select'), - url(r'^__debug__/sql_explain/$', 'debug_toolbar.views.sql_explain', name='sql_explain'), - url(r'^__debug__/sql_profile/$', 'debug_toolbar.views.sql_profile', name='sql_profile'), - url(r'^__debug__/template_source/$', 'debug_toolbar.views.template_source', name='template_source'), + url(r'^%s/m/(.*)$' % DEBUG_TB_URL_PREFIX, 'debug_toolbar.views.debug_media'), + url(r'^%s/sql_select/$' % DEBUG_TB_URL_PREFIX, 'debug_toolbar.views.sql_select', name='sql_select'), + url(r'^%s/sql_explain/$' % DEBUG_TB_URL_PREFIX, 'debug_toolbar.views.sql_explain', name='sql_explain'), + url(r'^%s/sql_profile/$' % DEBUG_TB_URL_PREFIX, 'debug_toolbar.views.sql_profile', name='sql_profile'), + url(r'^%s/template_source/$' % DEBUG_TB_URL_PREFIX, 'debug_toolbar.views.template_source', name='template_source'), ) diff --git a/debug_toolbar/views.py b/debug_toolbar/views.py index e3bb5b1..0fb4168 100644 --- a/debug_toolbar/views.py +++ b/debug_toolbar/views.py @@ -8,11 +8,17 @@ import os import django.views.static from django.conf import settings from django.db import connection -from django.http import HttpResponse, HttpResponseBadRequest +from django.http import HttpResponseBadRequest from django.shortcuts import render_to_response from django.utils import simplejson from django.utils.hashcompat import sha_constructor +class InvalidSQLError(Exception): + def __init__(self, value): + self.value = value + def __str__(self): + return repr(self.value) + def debug_media(request, path): root = getattr(settings, 'DEBUG_TOOLBAR_MEDIA_ROOT', None) if root is None: @@ -36,7 +42,7 @@ def sql_select(request): hash = sha_constructor(settings.SECRET_KEY + sql + params).hexdigest() if hash != request.GET.get('hash', ''): return HttpResponseBadRequest('Tamper alert') # SQL Tampering alert - if sql.lower().startswith('select'): + if sql.lower().strip().startswith('select'): params = simplejson.loads(params) cursor = connection.cursor() cursor.execute(sql, params) @@ -50,6 +56,7 @@ def sql_select(request): 'headers': headers, } return render_to_response('debug_toolbar/panels/sql_select.html', context) + raise InvalidSQLError("Only 'select' queries are allowed.") def sql_explain(request): """ @@ -67,7 +74,7 @@ def sql_explain(request): hash = sha_constructor(settings.SECRET_KEY + sql + params).hexdigest() if hash != request.GET.get('hash', ''): return HttpResponseBadRequest('Tamper alert') # SQL Tampering alert - if sql.lower().startswith('select'): + if sql.lower().strip().startswith('select'): params = simplejson.loads(params) cursor = connection.cursor() cursor.execute("EXPLAIN %s" % (sql,), params) @@ -81,6 +88,7 @@ def sql_explain(request): 'headers': headers, } return render_to_response('debug_toolbar/panels/sql_explain.html', context) + raise InvalidSQLError("Only 'select' queries are allowed.") def sql_profile(request): """ @@ -98,7 +106,7 @@ def sql_profile(request): hash = sha_constructor(settings.SECRET_KEY + sql + params).hexdigest() if hash != request.GET.get('hash', ''): return HttpResponseBadRequest('Tamper alert') # SQL Tampering alert - if sql.lower().startswith('select'): + if sql.lower().strip().startswith('select'): params = simplejson.loads(params) cursor = connection.cursor() cursor.execute("SET PROFILING=1") # Enable profiling @@ -116,6 +124,7 @@ def sql_profile(request): 'headers': headers, } return render_to_response('debug_toolbar/panels/sql_explain.html', context) + raise InvalidSQLError("Only 'select' queries are allowed.") def template_source(request): """ -- cgit v1.2.3 From 87754fba031019d9fcff25c5dba2563baeb7ea1b Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Sat, 17 Jan 2009 12:23:42 -0800 Subject: Minor stylistic changes to CSS and Javascript file after merge. --- debug_toolbar/media/toolbar.css | 10 +++++----- debug_toolbar/media/toolbar.js | 16 +++++++++++----- 2 files changed, 16 insertions(+), 10 deletions(-) (limited to 'debug_toolbar') diff --git a/debug_toolbar/media/toolbar.css b/debug_toolbar/media/toolbar.css index a04f451..4800157 100644 --- a/debug_toolbar/media/toolbar.css +++ b/debug_toolbar/media/toolbar.css @@ -35,13 +35,13 @@ width: 16px; } -#djDebugToolbarHandle ul li{ - padding: 3px 0px 0px 3px; +#djDebugToolbarHandle ul li { + padding: 3px 0px 0px 3px; } -#djDebugToolbarHandle ul li a{ - font-size: 16px; - font-weight: bold; +#djDebugToolbarHandle ul li a { + font-size: 16px; + font-weight: bold; } #djDebugToolbar ul { diff --git a/debug_toolbar/media/toolbar.js b/debug_toolbar/media/toolbar.js index dcd52ae..b6baa2c 100644 --- a/debug_toolbar/media/toolbar.js +++ b/debug_toolbar/media/toolbar.js @@ -42,9 +42,9 @@ jQuery(function($) { $('#djShowToolBarButton').click(function() { $.djDebug.show_toolbar(); }); - if($.cookie(COOKIE_NAME)){ + if ($.cookie(COOKIE_NAME)) { $.djDebug.hide_toolbar(false); - }else{ + } else { $('#djDebugToolbar').show(); } }, @@ -69,14 +69,20 @@ jQuery(function($) { hide_toolbar: function(setCookie) { $('#djDebugToolbar').hide("fast"); $('#djDebugToolbarHandle').show(); - if(setCookie){ - $.cookie(COOKIE_NAME, 'hide', {path: '/', expires: 10 }); + if (setCookie) { + $.cookie(COOKIE_NAME, 'hide', { + path: '/', + expires: 10 + }); } }, show_toolbar: function() { $('#djDebugToolbarHandle').hide(); $('#djDebugToolbar').show("fast"); - $.cookie(COOKIE_NAME, null, {path: '/', expires: -1 }); + $.cookie(COOKIE_NAME, null, { + path: '/', + expires: -1 + }); } }); $(document).bind('close.djDebug', function() { -- cgit v1.2.3 From a51c3a5bba2e0d0e7046cd7eaee86ac01cf097d8 Mon Sep 17 00:00:00 2001 From: Reto Aebersold Date: Thu, 15 Jan 2009 09:51:31 +0100 Subject: added missing jquery cookie plugin files Signed-off-by: Rob Hudson --- debug_toolbar/media/jquery.cookie.js | 96 ++++++++++++++++++++++++++++++++ debug_toolbar/media/jquery.cookie.min.js | 1 + 2 files changed, 97 insertions(+) create mode 100644 debug_toolbar/media/jquery.cookie.js create mode 100644 debug_toolbar/media/jquery.cookie.min.js (limited to 'debug_toolbar') diff --git a/debug_toolbar/media/jquery.cookie.js b/debug_toolbar/media/jquery.cookie.js new file mode 100644 index 0000000..6df1fac --- /dev/null +++ b/debug_toolbar/media/jquery.cookie.js @@ -0,0 +1,96 @@ +/** + * Cookie plugin + * + * Copyright (c) 2006 Klaus Hartl (stilbuero.de) + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + * + */ + +/** + * Create a cookie with the given name and value and other optional parameters. + * + * @example $.cookie('the_cookie', 'the_value'); + * @desc Set the value of a cookie. + * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true }); + * @desc Create a cookie with all available options. + * @example $.cookie('the_cookie', 'the_value'); + * @desc Create a session cookie. + * @example $.cookie('the_cookie', null); + * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain + * used when the cookie was set. + * + * @param String name The name of the cookie. + * @param String value The value of the cookie. + * @param Object options An object literal containing key/value pairs to provide optional cookie attributes. + * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object. + * If a negative value is specified (e.g. a date in the past), the cookie will be deleted. + * If set to null or omitted, the cookie will be a session cookie and will not be retained + * when the the browser exits. + * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie). + * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie). + * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will + * require a secure protocol (like HTTPS). + * @type undefined + * + * @name $.cookie + * @cat Plugins/Cookie + * @author Klaus Hartl/klaus.hartl@stilbuero.de + */ + +/** + * Get the value of a cookie with the given name. + * + * @example $.cookie('the_cookie'); + * @desc Get the value of a cookie. + * + * @param String name The name of the cookie. + * @return The value of the cookie. + * @type String + * + * @name $.cookie + * @cat Plugins/Cookie + * @author Klaus Hartl/klaus.hartl@stilbuero.de + */ +jQuery.cookie = function(name, value, options) { + if (typeof value != 'undefined') { // name and value given, set cookie + options = options || {}; + if (value === null) { + value = ''; + options.expires = -1; + } + var expires = ''; + if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) { + var date; + if (typeof options.expires == 'number') { + date = new Date(); + date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000)); + } else { + date = options.expires; + } + expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE + } + // CAUTION: Needed to parenthesize options.path and options.domain + // in the following expressions, otherwise they evaluate to undefined + // in the packed version for some reason... + var path = options.path ? '; path=' + (options.path) : ''; + var domain = options.domain ? '; domain=' + (options.domain) : ''; + var secure = options.secure ? '; secure' : ''; + document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join(''); + } else { // only name given, get cookie + var cookieValue = null; + if (document.cookie && document.cookie != '') { + var cookies = document.cookie.split(';'); + for (var i = 0; i < cookies.length; i++) { + var cookie = jQuery.trim(cookies[i]); + // Does this cookie string begin with the name we want? + if (cookie.substring(0, name.length + 1) == (name + '=')) { + cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); + break; + } + } + } + return cookieValue; + } +}; \ No newline at end of file diff --git a/debug_toolbar/media/jquery.cookie.min.js b/debug_toolbar/media/jquery.cookie.min.js new file mode 100644 index 0000000..eb129db --- /dev/null +++ b/debug_toolbar/media/jquery.cookie.min.js @@ -0,0 +1 @@ +jQuery.cookie=function(b,j,m){if(typeof j!="undefined"){m=m||{};if(j===null){j="";m.expires=-1}var e="";if(m.expires&&(typeof m.expires=="number"||m.expires.toUTCString)){var f;if(typeof m.expires=="number"){f=new Date();f.setTime(f.getTime()+(m.expires*24*60*60*1000))}else{f=m.expires}e="; expires="+f.toUTCString()}var l=m.path?"; path="+(m.path):"";var g=m.domain?"; domain="+(m.domain):"";var a=m.secure?"; secure":"";document.cookie=[b,"=",encodeURIComponent(j),e,l,g,a].join("")}else{var d=null;if(document.cookie&&document.cookie!=""){var k=document.cookie.split(";");for(var h=0;h toolbar.min.js - java -jar ~/bin/yuicompressor.jar jquery.cookie.js > jquery.cookie.min.js + java -jar ~/bin/yuicompressor.jar jquery.cookie.js >> toolbar.min.js compress_css: java -jar ~/bin/yuicompressor.jar --type css toolbar.css > toolbar.min.css diff --git a/debug_toolbar/templates/debug_toolbar/base.html b/debug_toolbar/templates/debug_toolbar/base.html index 3b8e92e..7277620 100644 --- a/debug_toolbar/templates/debug_toolbar/base.html +++ b/debug_toolbar/templates/debug_toolbar/base.html @@ -4,7 +4,6 @@ document.write(unescape('%3Cscript src="' + jquery_url + '" type="text/javascript"%3E%3C/script%3E')); } -