summaryrefslogtreecommitdiff
path: root/tbc
diff options
context:
space:
mode:
Diffstat (limited to 'tbc')
-rw-r--r--tbc/admin.py2
-rw-r--r--tbc/forms.py2
-rw-r--r--tbc/models.py20
-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
-rw-r--r--tbc/urls.py107
-rw-r--r--tbc/views.py14
8 files changed, 217 insertions, 71 deletions
diff --git a/tbc/admin.py b/tbc/admin.py
index 30b5b34..4707d33 100644
--- a/tbc/admin.py
+++ b/tbc/admin.py
@@ -1,4 +1,4 @@
-from models import *
+from .models import *
from django.contrib import admin
admin.site.register(Profile)
diff --git a/tbc/forms.py b/tbc/forms.py
index aa3b477..effe45b 100644
--- a/tbc/forms.py
+++ b/tbc/forms.py
@@ -16,7 +16,7 @@ class UserProfileForm(forms.ModelForm):
self.fields['about_proj'].label = "How did you come to know about the project"
class Meta:
model = Profile
- exclude = ('user')
+ exclude = ('user',)
widgets = {
'about':forms.TextInput(attrs={'placeholder':'Tell us about yourself'}),
'dob':forms.TextInput(attrs={'placeholder':'mm/dd/yyyy'}),
diff --git a/tbc/models.py b/tbc/models.py
index 7deb31c..9b2adbf 100644
--- a/tbc/models.py
+++ b/tbc/models.py
@@ -2,7 +2,7 @@ from django.db import models
from django.contrib.auth.models import User
from PythonTBC import settings
from django.contrib.admin.models import LogEntry
-from local import sitemap_path
+from .local import sitemap_path
from taggit.managers import TaggableManager
CATEGORY = (("fluid mechanics", "Fluid Mechanics"),
@@ -82,7 +82,7 @@ class Profile(models.Model):
about_proj = models.CharField(max_length=50, choices=ABOUT_PROJ)
city = models.CharField(max_length=50, default=None)
state = models.CharField(max_length=50, default=None)
- pin_code = models.IntegerField(max_length=6, default=None)
+ pin_code = models.IntegerField(default=None)
def __unicode__(self):
name = self.user.first_name or 'Profile'
return '%s'%(name)
@@ -103,7 +103,7 @@ class Book(models.Model):
isbn = models.CharField(max_length=50)
edition = models.CharField(max_length=15)
year_of_pub = models.CharField(max_length=4)
- no_chapters = models.IntegerField(max_length=2, default=0, blank=True)
+ no_chapters = models.IntegerField(default=0, blank=True)
contributor = models.ForeignKey(Profile)
reviewer = models.ForeignKey(Reviewer)
approved = models.BooleanField(default=False)
@@ -144,7 +144,7 @@ class TempBook(models.Model):
isbn = models.CharField(max_length=50)
edition = models.CharField(max_length=15)
year_of_pub = models.CharField(max_length=4)
- no_chapters = models.IntegerField(max_length=2)
+ no_chapters = models.IntegerField()
def __unicode__(self):
name = self.title or 'Book'
return '%s'%(name)
@@ -177,12 +177,12 @@ class ActivityLog(LogEntry):
class AicteBook(models.Model):
title = models.TextField()
- author = models.CharField(max_length=300L)
- category = models.CharField(max_length=32L)
- publisher_place = models.CharField(max_length=200L)
- isbn = models.CharField(max_length=50L)
- edition = models.CharField(max_length=15L)
- year_of_pub = models.CharField(max_length=4L)
+ author = models.CharField(max_length=300)
+ category = models.CharField(max_length=32)
+ publisher_place = models.CharField(max_length=200)
+ isbn = models.CharField(max_length=50)
+ edition = models.CharField(max_length=15)
+ year_of_pub = models.CharField(max_length=4)
proposed = models.BooleanField(default=False)
def __unicode__(self):
notebook = self.title or 'Book'
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>
diff --git a/tbc/urls.py b/tbc/urls.py
index 3db075b..4177f2f 100644
--- a/tbc/urls.py
+++ b/tbc/urls.py
@@ -1,61 +1,64 @@
from django.conf.urls import patterns, include, url
+from django.conf import settings
+from django.conf.urls.static import static
+from django.contrib import admin
+import tbc.views
-
-urlpatterns = patterns('',
- url(r'^$', 'tbc.views.home', name='home'),
- url(r'^internship-forms/$', 'tbc.views.internship_forms', name='internship_forms'),
- url(r'^about-pythontbc/$', 'tbc.views.about_pytbc', name='about_pytbc'),
+urlpatterns = [
+ url(r'^$', tbc.views.home, name='home'),
+ url(r'^internship-forms/$', tbc.views.internship_forms, name='internship_forms'),
+ url(r'^about-pythontbc/$', tbc.views.about_pytbc, name='about_pytbc'),
- url(r'^sample-notebook/$', 'tbc.views.sample_ipynb', name='sample_ipynb'),
- url(r'^register/$', 'tbc.views.user_register', name='user_register'),
- url(r'^login/$', 'tbc.views.user_login', name='user_login'),
- url(r'^logout/$', 'tbc.views.user_logout', name='user_logout'),
- url(r'^profile/$', 'tbc.views.user_profile', name='user_profile'),
- url(r'^update-profile/$', 'tbc.views.update_profile', name='update_profile'),
- url(r'^forgot-password/$', 'tbc.views.forgot_password', name='forgot_password'),
- url(r'^update-password/$', 'tbc.views.update_password', name='update_password'),
- url(r'^admin-tools/$', 'tbc.views.admin_tools', name='admin_tools'),
+ url(r'^sample-notebook/$', tbc.views.sample_ipynb, name='sample_ipynb'),
+ url(r'^register/$', tbc.views.user_register, name='user_register'),
+ url(r'^login/$', tbc.views.user_login, name='user_login'),
+ url(r'^logout/$', tbc.views.user_logout, name='user_logout'),
+ url(r'^profile/$', tbc.views.user_profile, name='user_profile'),
+ url(r'^update-profile/$', tbc.views.update_profile, name='update_profile'),
+ url(r'^forgot-password/$', tbc.views.forgot_password, name='forgot_password'),
+ url(r'^update-password/$', tbc.views.update_password, name='update_password'),
+ url(r'^admin-tools/$', tbc.views.admin_tools, name='admin_tools'),
- url(r'^submit-proposal/$', 'tbc.views.submit_proposal', name='submit_proposal'),
- url(r'^submit-aicte-proposal/$', 'tbc.views.list_aicte', name='list_aicte'),
- url(r'^submit-aicte-proposal/(?P<aicte_book_id>\d+)/$', 'tbc.views.submit_aicte_proposal', name='submit_aicte_proposal'),
- url(r'^submit-book/$', 'tbc.views.submit_book', name='submit_book'),
- url(r'^submit-sample/$', 'tbc.views.submit_sample', name='submit_sample'),
- url(r'^submit-sample/(?P<proposal_id>\d+)$', 'tbc.views.submit_sample', name='submit_sample'),
- url(r'^submit-sample/(?P<proposal_id>\d+)/(?P<old_notebook_id>\d+)$', 'tbc.views.submit_sample', name='submit_sample'),
- url(r'^confirm-book-details/$', 'tbc.views.confirm_book_details', name='confirm_book_details'),
- url(r'^submit-book-old/$', 'tbc.views.submit_book', name='submit_book'),
- url(r'^submit-code/$', 'tbc.views.submit_code', name='submit_code'),
- url(r'^submit-code-old/(?P<book_id>\d+)$', 'tbc.views.submit_code_old', name='submit_code_old'),
- url(r'^update-content/(?P<book_id>\d+)$', 'tbc.views.update_content', name='update_content'),
- url(r'^get-zip/(?P<book_id>\d+)$', 'tbc.views.get_zip', name='get_zip'),
- url(r'^browse-books/$', 'tbc.views.browse_books', name='browse_books'),
- url(r'^browse-books/(?P<category>.+)$', 'tbc.views.browse_books', name='browse_books'),
- url(r'^convert-notebook/(?P<notebook_path>.+)$', 'tbc.views.convert_notebook', name='convert_notebook'),
- url(r'^book-details/(?P<book_id>\d+)/$', 'tbc.views.book_details', name='book_details'),
- url(r'^completed-books/$', 'tbc.views.completed_books', name='completed_books'),
- url(r'^completed-books/(?P<category>.+)$', 'tbc.views.completed_books', name='completed_books'),
- url(r'^books-under-progress/$', 'tbc.views.books_under_progress', name='books_under_progress'),
- url(r'^redirect-ipynb/(?P<notebook_path>.+)$', 'tbc.views.redirect_to_ipynb', name='redirect_to_ipynb'),
- url(r'^get-certificate/$', 'tbc.views.get_certificate', name='get_certificate'),
- url(r'^get-certificate/(?P<book_id>\d+)/$', 'tbc.views.get_certificate', name='get_certificate'),
+ url(r'^submit-proposal/$', tbc.views.submit_proposal, name='submit_proposal'),
+ url(r'^submit-aicte-proposal/$', tbc.views.list_aicte, name='list_aicte'),
+ url(r'^submit-aicte-proposal/(?P<aicte_book_id>\d+)/$', tbc.views.submit_aicte_proposal, name='submit_aicte_proposal'),
+ url(r'^submit-book/$', tbc.views.submit_book, name='submit_book'),
+ url(r'^submit-sample/$', tbc.views.submit_sample, name='submit_sample'),
+ url(r'^submit-sample/(?P<proposal_id>\d+)$', tbc.views.submit_sample, name='submit_sample'),
+ url(r'^submit-sample/(?P<proposal_id>\d+)/(?P<old_notebook_id>\d+)$', tbc.views.submit_sample, name='submit_sample'),
+ url(r'^confirm-book-details/$', tbc.views.confirm_book_details, name='confirm_book_details'),
+ url(r'^submit-book-old/$', tbc.views.submit_book, name='submit_book'),
+ url(r'^submit-code/$', tbc.views.submit_code, name='submit_code'),
+ url(r'^submit-code-old/(?P<book_id>\d+)$', tbc.views.submit_code_old, name='submit_code_old'),
+ url(r'^update-content/(?P<book_id>\d+)$', tbc.views.update_content, name='update_content'),
+ url(r'^get-zip/(?P<book_id>\d+)$', tbc.views.get_zip, name='get_zip'),
+ url(r'^browse-books/$', tbc.views.browse_books, name='browse_books'),
+ url(r'^browse-books/(?P<category>.+)$', tbc.views.browse_books, name='browse_books'),
+ url(r'^convert-notebook/(?P<notebook_path>.+)$', tbc.views.convert_notebook, name='convert_notebook'),
+ url(r'^book-details/(?P<book_id>\d+)/$', tbc.views.book_details, name='book_details'),
+ url(r'^completed-books/$', tbc.views.completed_books, name='completed_books'),
+ url(r'^completed-books/(?P<category>.+)$', tbc.views.completed_books, name='completed_books'),
+ url(r'^books-under-progress/$', tbc.views.books_under_progress, name='books_under_progress'),
+ url(r'^redirect-ipynb/(?P<notebook_path>.+)$', tbc.views.redirect_to_ipynb, name='redirect_to_ipynb'),
+ url(r'^get-certificate/$', tbc.views.get_certificate, name='get_certificate'),
+ url(r'^get-certificate/(?P<book_id>\d+)/$', tbc.views.get_certificate, name='get_certificate'),
- url(r'^book-review/$', 'tbc.views.book_review', name='book_review'),
- url(r'^proposal-review/$', 'tbc.views.review_proposals', name='review_proposals'),
- url(r'^proposal-review/(?P<proposal_id>\d+)/(?P<textbook_id>\d+)$', 'tbc.views.review_proposals', name='review_proposals'),
- url(r'^disapprove-sample-notebook/(?P<proposal_id>\d+)$', 'tbc.views.disapprove_proposal', name='disapprove_proposal'),
- url(r'^allot-book/(?P<proposal_id>\d+)$', 'tbc.views.allot_book', name='allot_book'),
- url(r'^reject-proposal/(?P<proposal_id>\d+)$', 'tbc.views.reject_proposal', name='reject_proposal'),
- url(r'^book-review/(?P<book_id>\d+)$', 'tbc.views.book_review', name='book_review'),
- url(r'^approve-book/(?P<book_id>\d+)$', 'tbc.views.approve_book', name='approve_book'),
- url(r'^notify-changes/(?P<book_id>\d+)$', 'tbc.views.notify_changes', name='notify_changes'),
- url(r'^brokenbooks/$', 'tbc.views.get_broken_books', name='broken_books'),
- url(r'^link-image/$', 'tbc.views.link_image', name='link_image'),
- url(r'^books/$', 'tbc.views.books', name='books'),
- url(r'^edit-book/(?P<book_id>\d+)/$', 'tbc.views.edit_book', name='edit_book'),
+ url(r'^book-review/$', tbc.views.book_review, name='book_review'),
+ url(r'^proposal-review/$', tbc.views.review_proposals, name='review_proposals'),
+ url(r'^proposal-review/(?P<proposal_id>\d+)/(?P<textbook_id>\d+)$', tbc.views.review_proposals, name='review_proposals'),
+ url(r'^disapprove-sample-notebook/(?P<proposal_id>\d+)$', tbc.views.disapprove_proposal, name='disapprove_proposal'),
+ url(r'^allot-book/(?P<proposal_id>\d+)$', tbc.views.allot_book, name='allot_book'),
+ url(r'^reject-proposal/(?P<proposal_id>\d+)$', tbc.views.reject_proposal, name='reject_proposal'),
+ url(r'^book-review/(?P<book_id>\d+)$', tbc.views.book_review, name='book_review'),
+ url(r'^approve-book/(?P<book_id>\d+)$', tbc.views.approve_book, name='approve_book'),
+ url(r'^notify-changes/(?P<book_id>\d+)$', tbc.views.notify_changes, name='notify_changes'),
+ url(r'^brokenbooks/$', tbc.views.get_broken_books, name='broken_books'),
+ url(r'^link-image/$', tbc.views.link_image, name='link_image'),
+ url(r'^books/$', tbc.views.books, name='books'),
+ url(r'^edit-book/(?P<book_id>\d+)/$', tbc.views.edit_book, name='edit_book'),
# ajax urls
- url(r'^ajax/matching-books/$', 'tbc.views.ajax_matching_books', name='AjaxMatchingBooks'),
+ url(r'^ajax/matching-books/$', tbc.views.ajax_matching_books, name='AjaxMatchingBooks'),
-)
+]
diff --git a/tbc/views.py b/tbc/views.py
index d14093e..52a9478 100644
--- a/tbc/views.py
+++ b/tbc/views.py
@@ -3,17 +3,17 @@ from django.contrib.contenttypes.models import ContentType
from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.shortcuts import render_to_response, redirect
from django.views.decorators.csrf import csrf_exempt
-from django.core.context_processors import csrf
+from django.template.context_processors import csrf
from django.contrib.auth import authenticate, login, logout
from django.contrib.admin.models import CHANGE
from django.contrib.auth.decorators import login_required
from django.template import RequestContext
-from models import *
+from .models import *
from tbc.forms import *
-import local
+from . import local
import os
import zipfile
-import StringIO
+import io
import smtplib
import shutil
import string
@@ -21,7 +21,7 @@ import random
import json
import subprocess
from email.mime.text import MIMEText
-
+import StringIO
def add_log(user, object, flag, message, proposal_id=None, chat='No message'):
'''Creates log entry of the user activities.'''
@@ -1049,7 +1049,7 @@ def generate_zip(book_id):
def get_zip(request, book_id=None):
user = request.user
s, zipfile_name = generate_zip(book_id)
- resp = HttpResponse(s.getvalue(), mimetype = "application/x-zip-compressed")
+ resp = HttpResponse(s.getvalue(), content_type = "application/x-zip-compressed")
resp['Content-Disposition'] = 'attachment; filename=%s' % zipfile_name
return resp
@@ -1362,7 +1362,7 @@ def get_certificate(request, book_id=None):
else:
error = True
add_log(user, book, CHANGE, err, proposal_id)
- except Exception, e:
+ except Exception as e:
error = True
add_log(user, book, CHANGE, e, proposal_id)