diff options
author | Jayaram R Pai | 2014-07-06 23:10:02 +0530 |
---|---|---|
committer | Jayaram R Pai | 2014-07-06 23:10:02 +0530 |
commit | 4c535a956e8a6d5bb9c0b124f4180fcf9d0275e9 (patch) | |
tree | 297c4033affb5f52cb8ff2009dfcc2edc7aef45e | |
parent | 36e7f06608eb339082c2e905133bd7d83d9b36f0 (diff) | |
download | Python-TBC-Interface-4c535a956e8a6d5bb9c0b124f4180fcf9d0275e9.tar.gz Python-TBC-Interface-4c535a956e8a6d5bb9c0b124f4180fcf9d0275e9.tar.bz2 Python-TBC-Interface-4c535a956e8a6d5bb9c0b124f4180fcf9d0275e9.zip |
added comments app
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | PythonTBC/settings.py | 4 | ||||
-rw-r--r-- | PythonTBC/urls.py | 1 | ||||
-rw-r--r-- | comments/__init__.py | 0 | ||||
-rw-r--r-- | comments/forms.py | 24 | ||||
-rw-r--r-- | comments/models.py | 18 | ||||
-rw-r--r-- | comments/templates/comments/comment_base.html | 17 | ||||
-rw-r--r-- | comments/templates/comments/get_comments.html | 45 | ||||
-rw-r--r-- | comments/templates/comments/new_comment.html | 17 | ||||
-rw-r--r-- | comments/templates/comments/new_reply.html | 13 | ||||
-rw-r--r-- | comments/tests.py | 16 | ||||
-rw-r--r-- | comments/urls.py | 7 | ||||
-rw-r--r-- | comments/views.py | 111 | ||||
-rw-r--r-- | tbc/static/css/comments.css | 24 |
14 files changed, 300 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a0b4bb3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*~ +*.pyc +local.py +uploads/ diff --git a/PythonTBC/settings.py b/PythonTBC/settings.py index 51f4364..e2cafba 100644 --- a/PythonTBC/settings.py +++ b/PythonTBC/settings.py @@ -119,7 +119,8 @@ TEMPLATE_DIRS = ( # Always use forward slashes, even on Windows. # Don't forget to use absolute paths, not relative paths. join(PROJDIR, '../tbc/templates'), - join(PROJDIR, '../tbc/static/uploads') + join(PROJDIR, '../tbc/static/uploads'), + join(PROJDIR, '../comments/templates') ) INSTALLED_APPS = ( 'django.contrib.auth', @@ -133,6 +134,7 @@ INSTALLED_APPS = ( # Uncomment the next line to enable admin documentation: # 'django.contrib.admindocs', 'tbc', + 'comments', ) SESSION_SERIALIZER = 'django.contrib.sessions.serializers.JSONSerializer' diff --git a/PythonTBC/urls.py b/PythonTBC/urls.py index 7664952..d75e545 100644 --- a/PythonTBC/urls.py +++ b/PythonTBC/urls.py @@ -14,5 +14,6 @@ urlpatterns = patterns('', # Uncomment the next line to enable the admin: url(r'^admin/', include(admin.site.urls)), + url(r'^comments/', include('comments.urls')), url(r'^', include('tbc.urls', namespace='tbc')), ) diff --git a/comments/__init__.py b/comments/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/comments/__init__.py diff --git a/comments/forms.py b/comments/forms.py new file mode 100644 index 0000000..a5fb326 --- /dev/null +++ b/comments/forms.py @@ -0,0 +1,24 @@ +from django import forms + +class CommentForm(forms.Form): + book = forms.CharField(widget=forms.HiddenInput()) + chapter = forms.CharField(widget=forms.HiddenInput()) + example = forms.CharField(widget=forms.HiddenInput()) + page = forms.CharField(widget=forms.HiddenInput()) + title = forms.CharField() + body = forms.CharField(widget=forms.Textarea) + + def clean(self): + cleaned_data = self.cleaned_data + if cleaned_data.get('title', None) is None: + raise forms.ValidationError('Title cannot be empty.') + if cleaned_data.get('body', None) is None: + raise forms.ValidationError('Description cannot be empty.') + return cleaned_data + +class ReplyForm(forms.Form): + comment_id = forms.CharField(widget=forms.HiddenInput()) + body = forms.CharField(widget=forms.Textarea) + + def clean(self): + return self.cleaned_data diff --git a/comments/models.py b/comments/models.py new file mode 100644 index 0000000..390b274 --- /dev/null +++ b/comments/models.py @@ -0,0 +1,18 @@ +from django.db import models + +class Comment(models.Model): + title = models.CharField(max_length=200) + body = models.TextField() + book = models.CharField(max_length=200) + chapter = models.CharField(max_length=10) + example = models.CharField(max_length=10) + page = models.CharField(max_length=10) + date_created = models.DateTimeField(auto_now_add=True) + date_modified = models.DateTimeField(auto_now=True) + +class Reply(models.Model): + comment = models.ForeignKey(Comment) + body = models.CharField(max_length=200) + date_created = models.DateTimeField(auto_now_add=True) + date_modified = models.DateTimeField(auto_now=True) + diff --git a/comments/templates/comments/comment_base.html b/comments/templates/comments/comment_base.html new file mode 100644 index 0000000..c3a2a7b --- /dev/null +++ b/comments/templates/comments/comment_base.html @@ -0,0 +1,17 @@ +{% load static %} +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}"> + <link rel="stylesheet" href="{% static 'css/comments.css' %}"> +</head> +<body> + <div id="content-wrapper"> + {% block content %} + {% endblock %} + </div> + <script src="{% static 'js/jquery.js' %}"></script> + <script src="{% static 'js/bootstrap.min.js' %}"></script> +</body> +</html> diff --git a/comments/templates/comments/get_comments.html b/comments/templates/comments/get_comments.html new file mode 100644 index 0000000..571f815 --- /dev/null +++ b/comments/templates/comments/get_comments.html @@ -0,0 +1,45 @@ +{% extends 'comments/comment_base.html' %} +{% block content %} + +{% if comments %} + <h5 class="pull-left"><u>Recent comments</u></h5> + <a class="btn btn-primary btn-small pull-right" href="/comments/new/?book={{ book }}&chapter={{ chapter }}&example={{ example }}&page={{ page }}"> + + New comment + </a> + <div class="clearfix"></div> + <div class="accordion" id="accordion2"> + {% for comment in comments %} + <div class="accordion-group"> + <div class="accordion-heading"> + <a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion2" href="#collapse{{ forloop.counter }}"> + #{{ forloop.counter }} <em>{{ comment.title }}</em> + </a> + </div> + <div id="collapse{{ forloop.counter }}" class="accordion-body collapse"> + <div class="accordion-inner"> + <blockquote> + {{ comment.body }} + </blockquote> + <div class="replies"> + {% if comment.reply_set.all %} + <h6><u>Recent replies</u></h6> + {% endif %} + {% for reply in comment.reply_set.all %} + <div class="reply"> + <p>{{ reply.body }}</p> + </div> + {% endfor %} + <a class="btn btn-success btn-small" href="/comments/new-reply/?comment_id={{ comment.id }}">+ Reply</a> + </div> + </div> + </div> + </div> <!-- /.accordion-group --> + {% endfor %} + </div> <!-- /.accordion --> +{% else %} + <center> + <p> No comments for this example... </p> + <a class="btn btn-primary" href="/comments/new/?book={{ book }}&chapter={{ chapter }}&example={{ example }}&page={{ page }}">Create a new comment</a> + </center> +{% endif %} +{% endblock %} diff --git a/comments/templates/comments/new_comment.html b/comments/templates/comments/new_comment.html new file mode 100644 index 0000000..fa0c333 --- /dev/null +++ b/comments/templates/comments/new_comment.html @@ -0,0 +1,17 @@ +{% extends 'comments/comment_base.html' %} +{% block content %} +<div id="new-comment-form"> + <h5><u>New comment form</u></h5> + <form action="/comments/new/" method="POST" accept-charset="utf-8"> {% csrf_token %} + {{ form.errors }} + {{ form.book }} + {{ form.chapter }} + {{ form.example }} + {{ form.page }} + {{ form.title }}<br> + {{ form.body }} <br> + <input class="btn btn-primary" type="submit" value="Submit"> + <a class="btn btn-default" href="/comments/get/?book={{ book }}&chapter={{ chapter }}&example={{ example }}&page={{ page }}">Cancel</a> + </form> +</div> <!-- /#new-comment-form --> +{% endblock %} diff --git a/comments/templates/comments/new_reply.html b/comments/templates/comments/new_reply.html new file mode 100644 index 0000000..71532c8 --- /dev/null +++ b/comments/templates/comments/new_reply.html @@ -0,0 +1,13 @@ +{% extends 'comments/comment_base.html' %} +{% block content %} +<div id="new-reply-form"> + <h5><u>New reply form</u></h5> + <form action="/comments/new-reply/" method="POST" accept-charset="utf-8"> {% csrf_token %} + {{ form.errors }} + {{ form.comment_id }} + {{ form.body }} <br> + <input class="btn btn-primary" type="submit" value="Submit"> + <a class="btn btn-default" href="/comments/get/?book={{ comment.book }}&chapter={{ comment.chapter }}&example={{ comment.example }}&page={{ comment.page }}">Cancel</a> + </form> +</div> <!-- /#new-comment-form --> +{% endblock %} diff --git a/comments/tests.py b/comments/tests.py new file mode 100644 index 0000000..501deb7 --- /dev/null +++ b/comments/tests.py @@ -0,0 +1,16 @@ +""" +This file demonstrates writing tests using the unittest module. These will pass +when you run "manage.py test". + +Replace this with more appropriate tests for your application. +""" + +from django.test import TestCase + + +class SimpleTest(TestCase): + def test_basic_addition(self): + """ + Tests that 1 + 1 always equals 2. + """ + self.assertEqual(1 + 1, 2) diff --git a/comments/urls.py b/comments/urls.py new file mode 100644 index 0000000..c3a609a --- /dev/null +++ b/comments/urls.py @@ -0,0 +1,7 @@ +from django.conf.urls import patterns, include, url + +urlpatterns = patterns('', + url(r'^new/$', 'comments.views.new_comment', name='new_comment'), + url(r'^get/$', 'comments.views.get_comments', name='new_comment'), + url(r'^new-reply/$', 'comments.views.new_reply', name='new_reply'), +) diff --git a/comments/views.py b/comments/views.py new file mode 100644 index 0000000..be9d522 --- /dev/null +++ b/comments/views.py @@ -0,0 +1,111 @@ +import json + +from django.http import HttpResponse, HttpResponseRedirect +from django.shortcuts import render +from django.core.context_processors import csrf +from django.views.decorators.csrf import csrf_exempt + +from comments.forms import CommentForm, ReplyForm +from comments.models import Comment, Reply + +def get_comments(request): + # retriving comment parameters + book = request.GET.get('book', '') + chapter = request.GET.get('chapter', '') + example = request.GET.get('example', '') + page = request.GET.get('page', '') + comments = Comment.objects.filter(book=book).filter(chapter=chapter).filter(example=example) + context = { + 'comments': comments, + 'book': book, + 'chapter': chapter, + 'example': example, + 'page': page + } + return render(request, "comments/get_comments.html", context) + +def new_comment(request): + # saving the poted comment + if request.method == 'POST': + form = CommentForm(request.POST) + if form.is_valid(): + comment = Comment() + comment.book = form.cleaned_data.get("book") + comment.chapter = form.cleaned_data.get("chapter") + comment.example = form.cleaned_data.get("example") + comment.page = form.cleaned_data.get("page") + comment.title = form.cleaned_data.get("title") + comment.body = form.cleaned_data.get("body") + comment.save() + return HttpResponseRedirect( + '/comments/get/?book={0}&chapter={1}&example={2}&page={3}'.format( + comment.book, comment.chapter, comment.example, comment.page + ) + ) + else: + book = request.POST.get('book', '') + chapter = request.POST.get('chapter', '') + example = request.POST.get('example', '') + page = request.POST.get('page', '') + return HttpResponseRedirect( + '/comments/new/?book={0}&chapter={1}&example={2}&page={3}'.format( + book, chapter, example, page + ) + ) + + # retriving comment parameters + book = request.GET.get('book', '') + chapter = request.GET.get('chapter', '') + example = request.GET.get('example', '') + page = request.GET.get('page', '') + initial_values = { + 'book': book, + 'chapter': chapter, + 'example': example, + 'page': page + } + form = CommentForm(initial = initial_values) + context = { + 'form': form, + 'book': book, + 'chapter': chapter, + 'example': example, + 'page': page + } + context.update(csrf(request)) + return render(request, 'comments/new_comment.html', context) + +def new_reply(request): + if request.method == 'POST': + form = ReplyForm(request.POST) + if form.is_valid(): + comment_id = form.cleaned_data.get('comment_id') + comment = Comment.objects.get(id=comment_id) + reply = Reply() + reply.comment = comment + reply.body = form.cleaned_data.get('body') + reply.save() + return HttpResponseRedirect( + '/comments/get/?book={0}&chapter={1}&example={2}&page={3}'.format( + comment.book, comment.chapter, comment.example, comment.page + ) + ) + else: + comment_id = request.POST.get('comment_id', '') + return HttpResponseRedirect( + '/comments/new-reply/?comment_id={0}'.format( + comment_id + ) + ) + comment_id = request.GET.get('comment_id', '') + comment = Comment.objects.get(id=comment_id) + initial_values = { + 'comment_id': comment_id + } + form = ReplyForm(initial = initial_values) + context = { + 'form': form, + 'comment': comment + } + return render(request, 'comments/new_reply.html', context) + diff --git a/tbc/static/css/comments.css b/tbc/static/css/comments.css new file mode 100644 index 0000000..dc8abf3 --- /dev/null +++ b/tbc/static/css/comments.css @@ -0,0 +1,24 @@ +#content-wrapper { + max-width: 97%; +} +.accordion-inner { + background: #f5f5f5; +} +#new-comment-form input[type=text], +#new-comment-form textarea, +#new-reply-form textarea { + width: 80%; +} +#new-comment-form textarea, +#new-reply-form textarea { + height: 100px; +} +.replies { + margin-left: 15px; +} +.replies .reply { + padding: 3px; + margin: 5px 0; + background: #ffffff; + border-left: 2px solid #1dccaa; +} |