summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--PythonTBC/settings.py2
-rw-r--r--PythonTBC/urls.py2
-rw-r--r--requirements.txt1
-rw-r--r--tbc/static/js/hitcount-jquery.js60
-rw-r--r--tbc/static/js/jquery.postcsrf.js59
-rw-r--r--tbc/templates/tbc/book-details.html24
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: &nbsp;&nbsp;</td>
<td>{{ book.author }}</td>
+
</tr>
<tr>
<td>Publisher: &nbsp;&nbsp;</td>
@@ -79,7 +98,12 @@ function redirectToIpynb(notebook)
<td>GitHub: &nbsp;&nbsp;</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: &nbsp;&nbsp;</td>
+<td>{% get_hit_count for book %}</td>
+</tr>
+-->
</table>
</div>