diff options
-rw-r--r-- | PythonTBC/settings.py | 2 | ||||
-rw-r--r-- | PythonTBC/urls.py | 2 | ||||
-rw-r--r-- | requirements.txt | 1 | ||||
-rw-r--r-- | tbc/static/js/hitcount-jquery.js | 60 | ||||
-rw-r--r-- | tbc/static/js/jquery.postcsrf.js | 59 | ||||
-rw-r--r-- | tbc/templates/tbc/book-details.html | 24 |
6 files changed, 147 insertions, 1 deletions
diff --git a/PythonTBC/settings.py b/PythonTBC/settings.py index dbec227..033882e 100644 --- a/PythonTBC/settings.py +++ b/PythonTBC/settings.py @@ -136,6 +136,7 @@ INSTALLED_APPS = ( 'django.contrib.admin', # Uncomment the next line to enable admin documentation: # 'django.contrib.admindocs', + 'hitcount', 'tbc', 'comments', #'south', @@ -143,6 +144,7 @@ INSTALLED_APPS = ( 'tbc_error_page', 'taggit', 'taggit_templatetags2', + ) SESSION_SERIALIZER = 'django.contrib.sessions.serializers.JSONSerializer' diff --git a/PythonTBC/urls.py b/PythonTBC/urls.py index 77d166a..9cae5d6 100644 --- a/PythonTBC/urls.py +++ b/PythonTBC/urls.py @@ -27,7 +27,7 @@ urlpatterns = [ url(r'^admin-tools/commenting', commentingapp.views.commenting, name = 'commenting'), url(r'^admin-tools/error_page', tbc_error_page.views.error, name = 'error_page'), url(r'^admin-tools/broken_page', tbc_error_page.views.broken, name = 'broken_page'), - + url(r'hitcount/', include('hitcount.urls', namespace='hitcount')), ] diff --git a/requirements.txt b/requirements.txt index ac72f30..ab8f58a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,3 +14,4 @@ wsgiref==0.1.2 scrapy==1.0.3 django-taggit django-taggit-templatetags2 +django-hitcount diff --git a/tbc/static/js/hitcount-jquery.js b/tbc/static/js/hitcount-jquery.js new file mode 100644 index 0000000..e7106b3 --- /dev/null +++ b/tbc/static/js/hitcount-jquery.js @@ -0,0 +1,60 @@ +$(document).ready(function() { + /** + * https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax + * + * Remember you will need to ensure csrf tokens by adding: + * @ensure_csrf_cookie to your views that require this javascript + * + * Also, you will probably want to include this with your other sitewide + * javascript files ... this is just an example. + */ + + if ( typeof hitcountJS === 'undefined' ) { + // since this is loaded on every page only do something + // if a hit is going to be counted + return; + } + + var hitcountPK = hitcountJS['hitcountPK']; + var hitcountURL = hitcountJS['hitcountURL']; + var csrftoken = getCookie('csrftoken'); + + $.ajaxSetup({ + beforeSend: function(xhr, settings) { + if (!csrfSafeMethod(settings.type) && !this.crossDomain) { + xhr.setRequestHeader("X-CSRFToken", csrftoken); + } + } + }); + + $.post( hitcountURL, { "hitcountPK" : hitcountPK }, + function(data, status) { + + console.log(data); // just so you can see the response + + if (data.status == 'error') { + // do something for error? + } + }, 'json'); +}); + +function getCookie(name) { + 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; +} + +function csrfSafeMethod(method) { + // these HTTP methods do not require CSRF protection + return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); +} diff --git a/tbc/static/js/jquery.postcsrf.js b/tbc/static/js/jquery.postcsrf.js new file mode 100644 index 0000000..911626a --- /dev/null +++ b/tbc/static/js/jquery.postcsrf.js @@ -0,0 +1,59 @@ +/** + * Wrapper for jQuery's $.post() that retrieves the CSRF token from the browser + * cookie and sets then sets "X-CSRFToken" header in one fell swoop. + * + * Based on the example code given at the Django docs: + * https://docs.djangoproject.com/en/1.9/ref/csrf/#ajax + * + * Use as you would $.post(). + */ + +(function($) { + + $.postCSRF = function(url, data, callback, type) { + + function csrfSafeMethod(method) { + // these HTTP methods do not require CSRF protection + return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); + } + + function getCookie(name) { + 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; + } + + var csrftoken = getCookie('csrftoken'); + + // shift arguments if data argument was omitted + if ($.isFunction(data)) { + type = type || callback; + callback = data; + data = undefined; + } + + return $.ajax(jQuery.extend({ + url: url, + type: "POST", + dataType: type, + data: data, + success: callback, + beforeSend: function(xhr, settings) { + if (!csrfSafeMethod(settings.type) && !this.crossDomain) { + xhr.setRequestHeader("X-CSRFToken", csrftoken); + } + } + }, jQuery.isPlainObject(url) && url)); + }; + +}(jQuery)); diff --git a/tbc/templates/tbc/book-details.html b/tbc/templates/tbc/book-details.html index fc67847..579b2db 100644 --- a/tbc/templates/tbc/book-details.html +++ b/tbc/templates/tbc/book-details.html @@ -2,6 +2,24 @@ {% load static %} {% block script %} +{% load staticfiles %} +<script src="{% static 'js/jquery.postcsrf.js' %}"></script> + +{% load hitcount_tags %} +{% get_hit_count_js_variables for book as hitcount %} +<script type="text/javascript"> +jQuery(document).ready(function($) { + // use the template tags in our JavaScript call + $.postCSRF("{{ hitcount.ajax_url }}", { hitcountPK : "{{ hitcount.pk }}" }) + .done(function(data){ + $('<i />').text(data.hit_counted).attr('id','hit-counted-value').appendTo('#hit-counted'); + $('#hit-response').text(data.hit_message); + }).fail(function(data){ + console.log('POST failed'); + console.log(data); + }); +}); +</script> <script> function redirectToIpynb(notebook) { @@ -50,6 +68,7 @@ function redirectToIpynb(notebook) <tr> <td>Author: </td> <td>{{ book.author }}</td> + </tr> <tr> <td>Publisher: </td> @@ -79,7 +98,12 @@ function redirectToIpynb(notebook) <td>GitHub: </td> <td><a href= 'https://github.com/FOSSEE/Python-Textbook-Companions/tree/master/{{ book.title.split|join:"_" }}_by_{{ book.author.split|join:"_" }}' target="_blank">{{ book.title }}</a></td> </tr> +<!--<tr> + <td>Page Hits: </td> +<td>{% get_hit_count for book %}</td> +</tr> +--> </table> </div> |