summaryrefslogtreecommitdiff
path: root/comments
diff options
context:
space:
mode:
Diffstat (limited to 'comments')
-rw-r--r--comments/__init__.py0
-rw-r--r--comments/admin.py5
-rw-r--r--comments/forms.py26
-rw-r--r--comments/models.py20
-rw-r--r--comments/templates/comments/comment_base.html159
-rw-r--r--comments/templates/comments/get_comments.html54
-rw-r--r--comments/templates/comments/new_comment.html22
-rw-r--r--comments/templates/comments/new_reply.html34
-rw-r--r--comments/tests.py16
-rw-r--r--comments/urls.py7
-rw-r--r--comments/views.py112
11 files changed, 455 insertions, 0 deletions
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/admin.py b/comments/admin.py
new file mode 100644
index 0000000..6ac89ae
--- /dev/null
+++ b/comments/admin.py
@@ -0,0 +1,5 @@
+from models import *
+from django.contrib import admin
+
+admin.site.register(Comment)
+admin.site.register(Reply)
diff --git a/comments/forms.py b/comments/forms.py
new file mode 100644
index 0000000..b944a49
--- /dev/null
+++ b/comments/forms.py
@@ -0,0 +1,26 @@
+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)
+ email = forms.CharField()
+
+ 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)
+ email = forms.CharField()
+
+ def clean(self):
+ return self.cleaned_data
diff --git a/comments/models.py b/comments/models.py
new file mode 100644
index 0000000..0c7f70f
--- /dev/null
+++ b/comments/models.py
@@ -0,0 +1,20 @@
+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)
+ email = models.CharField(max_length=100)
+ 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)
+ email = models.CharField(max_length=100)
+ 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..4d9885a
--- /dev/null
+++ b/comments/templates/comments/comment_base.html
@@ -0,0 +1,159 @@
+{% load static %}
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <title>
+ {% block title %}
+ Python Textbook Companion Project | FOSSEE, IIT Bombay
+ {% endblock %}
+ </title>
+ {% block meta %}
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta name="description" content="">
+ <meta name="author" content="">
+ {% endblock %}
+
+ <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}" type="text/css" />
+ <link rel ="stylesheet" href="{% static 'css/responsive.css' %}" type="text/css"/>
+ <link rel ="stylesheet" href="{% static 'css/comments.css' %}" type="text/css"/>
+ <style>
+ .module-list {
+ float: left;
+ height: 220px;
+ margin-top: 20px;
+ margin-bottom: 20px;
+ margin-left: 50px;
+ padding: 10px;
+ padding-bottom: 25px;
+ position: relative;
+ width: 300px;
+ background: #2c3e50;
+ }
+ .module-list img {
+ height: 220px;
+ }
+ .module-list img:hover{
+ height: 220px;
+ border-radius: 15px;
+ }
+
+ .module-list a{
+ color: #ffffff;
+ }
+ .navbar .container {
+ max-width: 1100px;
+ }
+ #content-wrap{
+ max-width: 1100px;
+ margin: 0 auto;
+ }
+ input[type="text"] {
+ width: 100%;
+ }
+ input[type="password"] {
+ width: 100%;
+ }
+ </style>
+
+ {% block css %}
+ <style type="text/css">
+ body {
+ padding-top: 60px;
+ padding-bottom: 40px;
+ }
+ </style>
+ {% endblock %}
+
+ {% block script %}
+ {% endblock %}
+ </head>
+
+<body>
+<div class="navbar navbar navbar-fixed-top">
+ <div class="navbar-inner">
+ <div class="container">
+ <button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ </button>
+ <a class="brand" href="/">Python Textbook Companion</a>
+ <div class="nav-collapse collapse">
+
+ <ul class="nav pull-right">
+ <li class="dropdown">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">About<b class="caret"></b></a>
+ <ul class="dropdown-menu">
+ <li><a href="http://fossee.in" target="_blank">FOSSEE</a></li>
+ <li><a href="http://python.fossee.in" target="_blank">Python Team</a></li>
+ </ul>
+ </li>
+ <li class="dropdown">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">Textbooks<b class="caret"></b></a>
+ <ul class="dropdown-menu">
+ <li><a href="{% url 'tbc:CompletedBooks' %}">Completed Books</a></li>
+ <li><a href="{% url 'tbc:BooksUnderProgress' %}">Books Under Progress</a></li>
+ </ul>
+ </li>
+ <!--li><a href="{% url 'tbc:InternshipForms' %}">Internship Forms</a></li>
+
+ {% if user %}
+ <li class="dropdown">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">{{ user.first_name }}<b class="caret"></b></a>
+ <ul class="dropdown-menu">
+ <li><a href="{% url 'tbc:UserLogout' %}">Logout</a></li>
+ </ul>
+ </li>
+ {% endif %}
+
+ {% if reviewer %}
+ <li class="dropdown">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">{{ reviewer.first_name }} {{ reviewer.last_name }} <b class="caret"></b></a>
+ <ul class="dropdown-menu">
+ <li><a href="{% url 'tbc:BookReview' %}">Review Books</a></li>
+ <li><a href="{% url 'tbc:UserLogout' %}">Logout</a></li>
+ </ul>
+ </li>
+ {% endif %}
+
+ {% if anonymous %}
+ <li><a href="{% url 'tbc:UserLogin' %}">Login</a></li>
+ <li><a href="{% url 'tbc:UserRegister' %}">Sign Up</a></li>
+ {% endif %}<-->
+
+ </ul> <!--/.nav -->
+ </div><!--/.nav-collapse -->
+ </div>
+ </div>
+ </div>
+ <div class="container" id="comments-container">
+ {% block content %}
+ {% endblock %}
+ <div class="clearfix"></div>
+ <hr>
+
+ <footer>
+ <center><p>&copy; FOSSEE - IIT Bombay 2014</p></center>
+ <center><img src="{% static 'images/fossee.png' %}" width=100 height=70></center>
+ </footer>
+
+ </div> <!-- /container -->
+
+ <script src="{% static 'js/jquery.js' %}"></script>
+ <script src="{% static 'js/bootstrap.min.js' %}"></script>
+ <!-- google analytics -->
+ <script>
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+ })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+ ga('create', 'UA-44697375-2', 'fossee.in');
+ ga('send', 'pageview');
+ </script>
+ <!-- / google analytics -->
+ </body>
+</html>
+
+
diff --git a/comments/templates/comments/get_comments.html b/comments/templates/comments/get_comments.html
new file mode 100644
index 0000000..71443db
--- /dev/null
+++ b/comments/templates/comments/get_comments.html
@@ -0,0 +1,54 @@
+{% extends 'comments/comment_base.html' %}
+{% block content %}
+
+<div id="recent-comments-wrapper">
+ {% if comments %}
+ <h5 class="pull-left"><u>Recent comments</u></h5>
+ <h3></h3>
+ <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>
+ <p> Showing comments for: Book: <em>{{ book }}</em> / Chapter: <em>{{ chapter }}</em> / Example: <em>{{ example }}<em></p>
+ <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 }}
+ <small>{{ comment.email }}</small>
+ </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>
+ <small> - {{ comment.email }}</small>
+ </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>
+ <div class="well">
+ <h5>Book: {{ book }} / Chapter: {{ chapter }} / Example: {{ example }}</h5>
+ <p> <em>Be the first one to create a comment for this example.</em> </p>
+ <a class="btn btn-primary" href="/comments/new/?book={{ book }}&chapter={{ chapter }}&example={{ example }}&page={{ page }}">+ Create a new comment</a>
+ </div>
+ </center>
+ {% endif %}
+ </div> <!-- /#recent-comments-form -->
+{% endblock %}
diff --git a/comments/templates/comments/new_comment.html b/comments/templates/comments/new_comment.html
new file mode 100644
index 0000000..64c4ab0
--- /dev/null
+++ b/comments/templates/comments/new_comment.html
@@ -0,0 +1,22 @@
+{% extends 'comments/comment_base.html' %}
+{% block content %}
+<div id="new-comment-form">
+ <h5><u>New comment form</u></h5>
+ <h4>Book: <em>{{ book }}</em> / Chapter: <em>{{ chapter }}</em> / Example: <em>{{ example }}</em> / Page: <em>{{ page }}</em></h4>
+ <form action="/comments/new/" method="POST" accept-charset="utf-8"> {% csrf_token %}
+ {{ form.errors }}
+ {{ form.book }}
+ {{ form.chapter }}
+ {{ form.example }}
+ {{ form.page }}
+ <label>Comment Title:</label>
+ {{ form.title }}<br>
+ <label>Comment Description:</label>
+ {{ form.body }} <br>
+ <label>Email:</label>
+ {{ form.email }} <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..56c97f5
--- /dev/null
+++ b/comments/templates/comments/new_reply.html
@@ -0,0 +1,34 @@
+{% extends 'comments/comment_base.html' %}
+{% block content %}
+<div id="new-reply-form">
+ <u> Comment: </u> <br><br>
+ <div class="well" style="width: 78%">
+ <blockquote>
+ {{ comment.body }}
+ <small>{{ comment.email }}</small>
+ </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>
+ <small> - {{ reply.email }}</small>
+ </div>
+ {% endfor %}
+ </div>
+ </div>
+ <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 }}
+ <label>Description:</label>
+ {{ form.body }} <br>
+ <label>Email:</label>
+ {{ form.email }} <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..260678a
--- /dev/null
+++ b/comments/views.py
@@ -0,0 +1,112 @@
+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.email = form.cleaned_data.get("email", "Anonymous")
+ 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.email = form.cleaned_data.get('email', 'Anonymous')
+ 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)