Initial commit of django based commenting system for sphinx. Already has
authoramit
Thu, 30 Sep 2010 11:36:30 +0530
changeset 0 54f784230511
child 1 5574cfc2b28d
Initial commit of django based commenting system for sphinx. Already has most of the boiler plate code.
hsbook_back.js
sphinx_django/__init__.py
sphinx_django/__init__.pyc
sphinx_django/admin.py
sphinx_django/db_script.py
sphinx_django/db_script.py~
sphinx_django/manage.py
sphinx_django/settings.py
sphinx_django/settings.pyc
sphinx_django/settings.py~
sphinx_django/sphinxcomment/__init__.py
sphinx_django/sphinxcomment/__init__.pyc
sphinx_django/sphinxcomment/admin.py
sphinx_django/sphinxcomment/admin.pyc
sphinx_django/sphinxcomment/admin.py~
sphinx_django/sphinxcomment/models.py
sphinx_django/sphinxcomment/models.pyc
sphinx_django/sphinxcomment/models.py~
sphinx_django/sphinxcomment/tests.py
sphinx_django/sphinxcomment/views.py
sphinx_django/sphinxcomment/views.pyc
sphinx_django/sphinxcomment/views.py~
sphinx_django/support/hsbook.js
sphinx_django/templates/404.html
sphinx_django/templates/500.html
sphinx_django/templates/boilerplate.html
sphinx_django/templates/comment.html
sphinx_django/templates/feeds/comments_description.html
sphinx_django/templates/feeds/comments_title.html
sphinx_django/templates/simple.html
sphinx_django/test.db
sphinx_django/urls.py
sphinx_django/urls.pyc
sphinx_django/urls.py~
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hsbook_back.js	Thu Sep 30 11:36:30 2010 +0530
@@ -0,0 +1,80 @@
+function qid(id) {
+  return id.replace(/([.:])/g, "\\$1");
+}
+
+function beforeComment(formData, jqForm, options) {
+  var form = jqForm[0];
+  if (!form.comment.value) {
+    $(options.target + " span.comment_error").empty().append(
+      "<span class=\"comment_error\">Your comment is empty</span>");
+    return false;
+  }
+  if (!form.name.value) {
+    $(options.target + " span.comment_error").empty().append(
+      "<span class=\"comment_error\">Please provide a name</span>");
+    return false;
+  }
+  $(options.target + " span.comment_error").empty().after(
+    "<img src=\"/support/icons/throbber.gif\" style=\"vertical-align: middle\"/>");
+  $(options.target + " input[@name=submit]").attr("disabled", true);
+}
+
+function ajaxifyForm(id) {
+  var q = qid(id);
+
+  $("#form_" + q).ajaxForm({ beforeSubmit: beforeComment,
+			     success: function() { ajaxifyForm(id); },
+			     target: "#comments_" + q });
+}
+
+function toggleComment(id) {
+  $("#toggle_" + qid(id)).nextAll().toggle();
+  return false;
+}
+
+function loadComments(id) {
+  $("#comments_" + qid(id)).load(location.protocol + "//" + location.host +
+				 "/comments/single/" + id + "/", function() {
+    ajaxifyForm(id);
+  });
+  return false;
+}
+
+function loadAllComments() {
+  $("a.commenttoggle").each(function() {
+    var id = $(this).attr("pid");
+    if (id) {
+      loadComments(id);
+    }
+  });
+}
+
+
+
+$(document).ready(function() {
+  function loading(id) {
+    return " <span id=\"comments_" + id + "\" class=\"comment\">" +
+      "<span pid=\"" + id + "\" class=\"commenttoggle\"><p>Loading...." +
+      "</span>";
+  }
+
+$("p[@id]").each(function() {
+    $(this).append(loading($(this).attr("id")));
+		   });
+$("p[@id]").each(function() {
+		   var url_string=window.location.pathname;
+		   var temp = new Array();
+		   temp = url_string.split('/');
+		   var chap_name=temp[temp.length-1].split('.')[0];
+
+		   $.getJSON("http://127.0.0.1:8000/count/"+chap_name, function(data) {
+	      $.each(data , function(id) {
+		       $("span.commenttoggle").replaceWith("<a class='commenttoggle'" + "href='comments: show / hide'>" + data.count +" "+"comments" + "</a>");
+ 		   });
+
+
+
+	    });
+		  });
+
+		  });
Binary file sphinx_django/__init__.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sphinx_django/admin.py	Thu Sep 30 11:36:30 2010 +0530
@@ -0,0 +1,24 @@
+from django.contrib import admin
+from sphinx_django.sphinxcomment.models import Comment, Element
+
+class CommentAdmin(admin.ModelAdmin):
+    list_display = ['element', 'submitter_name', 'comment', 'reviewed',
+                    'hidden', 'date']
+    search_fields = ['comment']
+    date_hierarchy = 'date'
+    list_filter = ['date', 'submitter_name']
+    search_fields = ['title', 'submitter_name', 'submitter_url']
+    fieldsets = (
+        (None, {'fields': ('submitter_name', 'element', 'comment')}),
+        ('Review and presentation state', {'fields': ('reviewed', 'hidden')}),
+        ('Other info', {'fields': ('submitter_url', 'ip')}),
+        )
+    # XXX: adding 'date' to the 'Other info' fieldset results in a
+    # ImproperlyConfigured error. :S
+
+class ElementAdmin(admin.ModelAdmin):
+    search_fields = ['id', 'chapter_name']
+    list_filter = ['chapter_name', 'title']
+
+admin.site.register(Comment, CommentAdmin)
+admin.site.register(Element, ElementAdmin)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sphinx_django/db_script.py	Thu Sep 30 11:36:30 2010 +0530
@@ -0,0 +1,17 @@
+from sqlalchemy import *
+
+db = create_engine('sqlite:///test.db')
+
+db.echo = False  # Try changing this to True and see what happens
+
+metadata = MetaData(db)
+
+chapter = Table('Chapter', metadata,
+    Column('id', Integer, primary_key=True),
+    Column('name', String(40)),
+)
+chapter.create()
+
+i = chapter.insert()
+i.execute(name='basic_func')
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sphinx_django/db_script.py~	Thu Sep 30 11:36:30 2010 +0530
@@ -0,0 +1,17 @@
+from sqlalchemy import *
+
+db = create_engine('sqlite:///test.db')
+
+db.echo = False  # Try changing this to True and see what happens
+
+metadata = MetaData(db)
+
+chapter = Table('Chapter', metadata,
+    Column('id', Integer, primary_key=True),
+    Column('name', String(40)),
+)
+chapter.create()
+
+i = users.insert()
+i.execute(name='basic_func')
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sphinx_django/manage.py	Thu Sep 30 11:36:30 2010 +0530
@@ -0,0 +1,11 @@
+#!/usr/bin/python
+from django.core.management import execute_manager
+try:
+    import settings # Assumed to be in the same directory.
+except ImportError:
+    import sys
+    sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
+    sys.exit(1)
+
+if __name__ == "__main__":
+    execute_manager(settings)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sphinx_django/settings.py	Thu Sep 30 11:36:30 2010 +0530
@@ -0,0 +1,83 @@
+# Django settings for sphinx_django project.
+
+DEBUG = True
+TEMPLATE_DEBUG = DEBUG
+
+ADMINS = (
+    ('Amit Sethi', 'amit.pureenergy@gmail.com'),
+)
+
+MANAGERS = ADMINS
+
+DATABASE_ENGINE = 'sqlite3'           # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
+DATABASE_NAME = 'test.db'             # Or path to database file if using sqlite3.
+DATABASE_USER = ''             # Not used with sqlite3.
+DATABASE_PASSWORD = ''         # Not used with sqlite3.
+DATABASE_HOST = ''             # Set to empty string for localhost. Not used with sqlite3.
+DATABASE_PORT = ''             # Set to empty string for default. Not used with sqlite3.
+
+# Local time zone for this installation. Choices can be found here:
+# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
+# although not all choices may be available on all operating systems.
+# If running in a Windows environment this must be set to the same as your
+# system time zone.
+TIME_ZONE = 'America/Chicago'
+
+# Language code for this installation. All choices can be found here:
+# http://www.i18nguy.com/unicode/language-identifiers.html
+LANGUAGE_CODE = 'en-us'
+
+SITE_ID = 1
+
+# If you set this to False, Django will make some optimizations so as not
+# to load the internationalization machinery.
+USE_I18N = True
+
+# Absolute path to the directory that holds media.
+# Example: "/home/media/media.lawrence.com/"
+MEDIA_ROOT = ''
+
+# URL that handles the media served from MEDIA_ROOT. Make sure to use a
+# trailing slash if there is a path component (optional in other cases).
+# Examples: "http://media.lawrence.com", "http://example.com/media/"
+MEDIA_URL = ''
+
+# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
+# trailing slash.
+# Examples: "http://foo.com/media/", "/media/".
+ADMIN_MEDIA_PREFIX = '/media/'
+
+# Make this unique, and don't share it with anybody.
+SECRET_KEY = '21^&3e-nh_hxqkruwj72gtwy^$i6t$#gbn&r36u0tj+ydk&&g8'
+
+# List of callables that know how to import templates from various sources.
+TEMPLATE_LOADERS = (
+    'django.template.loaders.filesystem.load_template_source',
+    'django.template.loaders.app_directories.load_template_source',
+#     'django.template.loaders.eggs.load_template_source',
+)
+
+MIDDLEWARE_CLASSES = (
+    'django.middleware.common.CommonMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+)
+
+ROOT_URLCONF = 'sphinx_django.urls'
+
+TEMPLATE_DIRS = (
+    "/home/amit/review/sphinx_django/templates/"
+    
+    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
+    # Always use forward slashes, even on Windows.
+    # Don't forget to use absolute paths, not relative paths.
+)
+
+INSTALLED_APPS = (
+    'django.contrib.admin',
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.sites',
+    'sphinx_django.sphinxcomment',
+)
Binary file sphinx_django/settings.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sphinx_django/settings.py~	Thu Sep 30 11:36:30 2010 +0530
@@ -0,0 +1,81 @@
+# Django settings for sphinx_django project.
+
+DEBUG = True
+TEMPLATE_DEBUG = DEBUG
+
+ADMINS = (
+    # ('Your Name', 'your_email@domain.com'),
+)
+
+MANAGERS = ADMINS
+
+DATABASE_ENGINE = 'sqlite3'           # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
+DATABASE_NAME = 'test.db'             # Or path to database file if using sqlite3.
+DATABASE_USER = ''             # Not used with sqlite3.
+DATABASE_PASSWORD = ''         # Not used with sqlite3.
+DATABASE_HOST = ''             # Set to empty string for localhost. Not used with sqlite3.
+DATABASE_PORT = ''             # Set to empty string for default. Not used with sqlite3.
+
+# Local time zone for this installation. Choices can be found here:
+# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
+# although not all choices may be available on all operating systems.
+# If running in a Windows environment this must be set to the same as your
+# system time zone.
+TIME_ZONE = 'America/Chicago'
+
+# Language code for this installation. All choices can be found here:
+# http://www.i18nguy.com/unicode/language-identifiers.html
+LANGUAGE_CODE = 'en-us'
+
+SITE_ID = 1
+
+# If you set this to False, Django will make some optimizations so as not
+# to load the internationalization machinery.
+USE_I18N = True
+
+# Absolute path to the directory that holds media.
+# Example: "/home/media/media.lawrence.com/"
+MEDIA_ROOT = ''
+
+# URL that handles the media served from MEDIA_ROOT. Make sure to use a
+# trailing slash if there is a path component (optional in other cases).
+# Examples: "http://media.lawrence.com", "http://example.com/media/"
+MEDIA_URL = ''
+
+# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
+# trailing slash.
+# Examples: "http://foo.com/media/", "/media/".
+ADMIN_MEDIA_PREFIX = '/media/'
+
+# Make this unique, and don't share it with anybody.
+SECRET_KEY = '21^&3e-nh_hxqkruwj72gtwy^$i6t$#gbn&r36u0tj+ydk&&g8'
+
+# List of callables that know how to import templates from various sources.
+TEMPLATE_LOADERS = (
+    'django.template.loaders.filesystem.load_template_source',
+    'django.template.loaders.app_directories.load_template_source',
+#     'django.template.loaders.eggs.load_template_source',
+)
+
+MIDDLEWARE_CLASSES = (
+    'django.middleware.common.CommonMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+)
+
+ROOT_URLCONF = 'sphinx_django.urls'
+
+TEMPLATE_DIRS = (
+    "/home/amit/review/sphinx_django/templates/"
+
+    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
+    # Always use forward slashes, even on Windows.
+    # Don't forget to use absolute paths, not relative paths.
+)
+
+INSTALLED_APPS = (
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.sites',
+)
Binary file sphinx_django/sphinxcomment/__init__.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sphinx_django/sphinxcomment/admin.py	Thu Sep 30 11:36:30 2010 +0530
@@ -0,0 +1,22 @@
+from django.contrib import admin
+from sphinx_django.sphinxcomment.models import Comment, Element
+
+class CommentAdmin(admin.ModelAdmin):
+    list_display = ['element', 'submitter_name', 'comment', 'date']
+    search_fields = ['comment']
+    date_hierarchy = 'date'
+    list_filter = ['date', 'submitter_name']
+    search_fields = ['title', 'submitter_name', 'submitter_url']
+    fieldsets = (
+        (None, {'fields': ('submitter_name', 'element', 'comment')}),
+               ('Other info', {'fields': ('submitter_url', 'ip')}),
+        )
+    # XXX: adding 'date' to the 'Other info' fieldset results in a
+    # ImproperlyConfigured error. :S
+
+class ElementAdmin(admin.ModelAdmin):
+    search_fields = ['chapter_name']
+    list_filter = ['chapter_name']
+
+admin.site.register(Comment, CommentAdmin)
+admin.site.register(Element, ElementAdmin)
Binary file sphinx_django/sphinxcomment/admin.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sphinx_django/sphinxcomment/admin.py~	Thu Sep 30 11:36:30 2010 +0530
@@ -0,0 +1,24 @@
+from django.contrib import admin
+from sphinx_django.sphinxcomment.models import Comment, Element
+
+class CommentAdmin(admin.ModelAdmin):
+    list_display = ['element', 'submitter_name', 'comment', 'reviewed',
+                    'hidden', 'date']
+    search_fields = ['comment']
+    date_hierarchy = 'date'
+    list_filter = ['date', 'submitter_name']
+    search_fields = ['title', 'submitter_name', 'submitter_url']
+    fieldsets = (
+        (None, {'fields': ('submitter_name', 'element', 'comment')}),
+        ('Review and presentation state', {'fields': ('reviewed', 'hidden')}),
+        ('Other info', {'fields': ('submitter_url', 'ip')}),
+        )
+    # XXX: adding 'date' to the 'Other info' fieldset results in a
+    # ImproperlyConfigured error. :S
+
+class ElementAdmin(admin.ModelAdmin):
+    search_fields = ['id', 'chapter']
+    list_filter = ['chapter', 'title']
+
+admin.site.register(Comment, CommentAdmin)
+admin.site.register(Element, ElementAdmin)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sphinx_django/sphinxcomment/models.py	Thu Sep 30 11:36:30 2010 +0530
@@ -0,0 +1,34 @@
+from django.db import models
+
+# Create your models here.
+from django.db import models
+
+
+mutable = True
+
+class Element(models.Model):
+    chapter_name = models.CharField('Chapter name', max_length=100, editable=False,
+                               db_index=True)
+
+
+    def __unicode__(self):
+        return self.chapter_name
+    
+class Comment(models.Model):
+    element = models.ForeignKey(Element,
+        help_text='ID of paragraph that was commented on')
+    comment = models.TextField(editable=mutable,
+        help_text='Text of submitted comment (please do not modify)')
+    submitter_name = models.CharField('Submitter', max_length=64,
+        help_text='Self-reported name of submitter (may be bogus)')
+    submitter_url = models.URLField('URL', blank=True, editable=mutable,
+        help_text='Self-reported URL of submitter (may be empty or bogus)')
+    ip = models.IPAddressField('IP address', editable=mutable,
+        help_text='IP address from which comment was submitted')
+    date = models.DateTimeField('date submitted', auto_now=True,
+                                auto_now_add=True)
+
+    def __unicode__(self):
+        return self.comment[:32]
+
+    
Binary file sphinx_django/sphinxcomment/models.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sphinx_django/sphinxcomment/models.py~	Thu Sep 30 11:36:30 2010 +0530
@@ -0,0 +1,47 @@
+from django.db import models
+
+# Create your models here.
+from django.db import models
+import sha
+
+mutable = True
+
+class Chapter(models.Model):
+    id = models.CharField('ID attribute', max_length=64, editable=False,
+                          primary_key=True)
+    chapter = models.CharField('Chapter ID', max_length=100, editable=False,
+                               db_index=True)
+
+
+    def __unicode__(self):
+        return self.id
+    
+class Comment(models.Model):
+    element = models.ForeignKey(Element,
+        help_text='ID of paragraph that was commented on')
+    comment = models.TextField(editable=mutable,
+        help_text='Text of submitted comment (please do not modify)')
+    submitter_name = models.CharField('Submitter', max_length=64,
+        help_text='Self-reported name of submitter (may be bogus)')
+    submitter_url = models.URLField('URL', blank=True, editable=mutable,
+        help_text='Self-reported URL of submitter (may be empty or bogus)')
+    ip = models.IPAddressField('IP address', editable=mutable,
+        help_text='IP address from which comment was submitted')
+    date = models.DateTimeField('date submitted', auto_now=True,
+                                auto_now_add=True)
+    reviewed = models.BooleanField(default=False, db_index=True,
+        help_text='Has this comment been reviewed by an author?')
+    hidden = models.BooleanField(default=False, db_index=True,
+        help_text='Has this comment been hidden from public display?')
+
+    def __unicode__(self):
+        return self.comment[:32]
+
+    def get_absolute_url(self):
+        s = sha.new()
+        s.update(repr(self.comment))
+        s.update(repr(self.submitter_name))
+        s.update(str(self.date))
+        return '/read/%s.html#%s?comment=%s&uuid=%s' % (
+            self.element.chapter, self.element.id, self.id, s.hexdigest()[:20]
+            )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sphinx_django/sphinxcomment/tests.py	Thu Sep 30 11:36:30 2010 +0530
@@ -0,0 +1,23 @@
+"""
+This file demonstrates two different styles of tests (one doctest and one
+unittest). These will both pass when you run "manage.py test".
+
+Replace these 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.failUnlessEqual(1 + 1, 2)
+
+__test__ = {"doctest": """
+Another way to test that 1 + 1 is equal to 2.
+
+>>> 1 + 1 == 2
+True
+"""}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sphinx_django/sphinxcomment/views.py	Thu Sep 30 11:36:30 2010 +0530
@@ -0,0 +1,118 @@
+# Create your views here.
+from django.http import HttpResponse
+from django.utils.simplejson import dumps 
+from django.contrib.csrf.middleware import csrf_exempt
+import django.forms as forms
+from django.db import connection
+from django.http import HttpResponse
+from sphinxcomment.models import Comment, Element
+from django.shortcuts import get_object_or_404, render_to_response
+from django.template import Context
+from django.template.loader import get_template
+from django.utils.simplejson import dumps 
+
+def dump_queries():
+    # requires settings.DEBUG to be set to True in order to work
+    if len(connection.queries) == 1:
+        print connection.queries
+    else:
+        qs = {}
+        for q in connection.queries:
+            qs[q['sql']] = qs.setdefault(q['sql'], 0) + 1
+        for q in sorted(qs.items(), key=lambda x: x[1], reverse=True):
+            print q
+        print len(connection.queries)
+
+class CommentForm(forms.Form):
+    id = forms.CharField(widget=forms.HiddenInput)
+    name = forms.CharField(max_length=64)
+    url = forms.URLField(max_length=128, required=False)
+    comment = forms.CharField(widget=forms.Textarea(attrs={
+        'rows': 8, 'cols': 60
+        }))
+    remember = forms.BooleanField(initial=True, required=False)
+
+def comments_by_chapter(chapter):
+    objs = []
+    for c in Comment.objects.filter(element__chapter_name=chapter).order_by('date'):
+        objs.append(c)
+    return objs
+
+def chapter(request):
+#    template = get_template('comment.html')
+#    resp = {}
+    # for elt, comments in comments_by_chapter(id).iteritems():
+    form = CommentForm(initial={
+            'id': 'elt',
+            'name': 'name'
+            })
+    resp['elt'] = template.render(Context({
+            'id': 'elt',
+            'form': form,
+            'length': 5,
+            'query': 'abcde',
+            }))
+    return HttpResponse(dumps(resp), mimetype='application/json')
+
+def chapter_count(request,chapter_name):
+    comment_count = comments_by_chapter(chapter_name)
+    resp={}
+    resp['count']=len(comment_count)
+
+
+    return HttpResponse(dumps(resp), mimetype='application/json')
+    
+def single(request, id, form=None, newid=None):
+    queryset = Comment.objects.filter(element=id, hidden=False).order_by('date')
+    if form is None:
+        form = CommentForm(initial={
+            'id': id,
+            'name': request.session.get('name', ''),
+            })
+    try:
+        error = form.errors[0]
+    except:
+        error = ''
+    return render_to_response('comment.html', {
+        'id': id,
+        'form': form,
+        'length': len(queryset),
+        'query': queryset,
+        'newid': newid or True,
+        'error': error,
+        })
+
+def submit(request, id):
+    element = get_object_or_404(Element, id=id)
+    form = None
+    newid = None
+    if request.method == 'POST':
+        form = CommentForm(request.POST)
+        if form.is_valid():
+            data = form.cleaned_data
+            if data.get('remember'):
+                request.session['name'] = data['name']
+                request.session['url'] = data['url']
+            else:
+                request.session.pop('name', None)
+                request.session.pop('url', None)
+            c = Comment(element=element,
+                        comment=data['comment'],
+                        submitter_name=data['name'],
+                        submitter_url=data['url'],
+                        ip=request.META.get('REMOTE_ADDR'))
+            c.save()
+            newid = c.id
+            form = None
+    return single(request, id, form, newid)
+
+def test(request):
+    print request
+    string="<p>test comment</p>"
+    return HttpResponse(dumps(string),mimetype="application/json")
+    
+       
+
+#return HttpResponse(dumps(string),mimetype="text/plain")
+#test= csrf_exempt(test)
+
Binary file sphinx_django/sphinxcomment/views.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sphinx_django/sphinxcomment/views.py~	Thu Sep 30 11:36:30 2010 +0530
@@ -0,0 +1,118 @@
+# Create your views here.
+from django.http import HttpResponse
+from django.utils.simplejson import dumps 
+from django.contrib.csrf.middleware import csrf_exempt
+import django.forms as forms
+from django.db import connection
+from django.http import HttpResponse
+from sphinxcomment.models import Comment, Element
+from django.shortcuts import get_object_or_404, render_to_response
+from django.template import Context
+from django.template.loader import get_template
+from django.utils.simplejson import dumps 
+
+# def dump_queries():
+#     # requires settings.DEBUG to be set to True in order to work
+#     if len(connection.queries) == 1:
+#         print connection.queries
+#     else:
+#         qs = {}
+#         for q in connection.queries:
+#             qs[q['sql']] = qs.setdefault(q['sql'], 0) + 1
+#         for q in sorted(qs.items(), key=lambda x: x[1], reverse=True):
+#             print q
+#         print len(connection.queries)
+
+class CommentForm(forms.Form):
+    id = forms.CharField(widget=forms.HiddenInput)
+    name = forms.CharField(max_length=64)
+    url = forms.URLField(max_length=128, required=False)
+    comment = forms.CharField(widget=forms.Textarea(attrs={
+        'rows': 8, 'cols': 60
+        }))
+    remember = forms.BooleanField(initial=True, required=False)
+
+def comments_by_chapter(chapter):
+    objs = {}
+    for c in Comment.objects.filter(element__chapter=id, hidden=False).order_by('date'):
+        objs.setdefault(c.element_id, []).append(c)
+    return objs
+
+def chapter(request):
+#    template = get_template('comment.html')
+#    resp = {}
+    # for elt, comments in comments_by_chapter(id).iteritems():
+    form = CommentForm(initial={
+            'id': 'elt',
+            'name': 'name'
+            })
+    resp['elt'] = template.render(Context({
+            'id': 'elt',
+            'form': form,
+            'length': 5,
+            'query': 'abcde',
+            }))
+    return HttpResponse(dumps(resp), mimetype='application/json')
+
+def chapter_count(request):
+#     resp = comments_by_chapter(chapter_name)
+# #   for elt, comments in resp.iteritems():
+# #        resp[elt] = len(comments)
+    resp={}
+    resp['elt']=5
+    return HttpResponse(dumps(resp), mimetype='application/json')
+    
+def single(request, id, form=None, newid=None):
+    queryset = Comment.objects.filter(element=id, hidden=False).order_by('date')
+    if form is None:
+        form = CommentForm(initial={
+            'id': id,
+            'name': request.session.get('name', ''),
+            })
+    try:
+        error = form.errors[0]
+    except:
+        error = ''
+    return render_to_response('comment.html', {
+        'id': id,
+        'form': form,
+        'length': len(queryset),
+        'query': queryset,
+        'newid': newid or True,
+        'error': error,
+        })
+
+def submit(request, id):
+    element = get_object_or_404(Element, id=id)
+    form = None
+    newid = None
+    if request.method == 'POST':
+        form = CommentForm(request.POST)
+        if form.is_valid():
+            data = form.cleaned_data
+            if data.get('remember'):
+                request.session['name'] = data['name']
+                request.session['url'] = data['url']
+            else:
+                request.session.pop('name', None)
+                request.session.pop('url', None)
+            c = Comment(element=element,
+                        comment=data['comment'],
+                        submitter_name=data['name'],
+                        submitter_url=data['url'],
+                        ip=request.META.get('REMOTE_ADDR'))
+            c.save()
+            newid = c.id
+            form = None
+    return single(request, id, form, newid)
+
+def test(request):
+    print request
+    string="<p>test comment</p>"
+    return HttpResponse(dumps(string),mimetype="application/json")
+    
+       
+
+#return HttpResponse(dumps(string),mimetype="text/plain")
+#test= csrf_exempt(test)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sphinx_django/support/hsbook.js	Thu Sep 30 11:36:30 2010 +0530
@@ -0,0 +1,126 @@
+function qid(id) {
+  return id.replace(/([.:])/g, "\\$1");
+}
+
+function beforeComment(formData, jqForm, options) {
+  var form = jqForm[0];
+  if (!form.comment.value) {
+    $(options.target + " span.comment_error").empty().append(
+      "<span class=\"comment_error\">Your comment is empty</span>");
+    return false;
+  }
+  if (!form.name.value) {
+    $(options.target + " span.comment_error").empty().append(
+      "<span class=\"comment_error\">Please provide a name</span>");
+    return false;
+  }
+  $(options.target + " span.comment_error").empty().after(
+    "<img src=\"/support/icons/throbber.gif\" style=\"vertical-align: middle\"/>");
+  $(options.target + " input[@name=submit]").attr("disabled", true);
+}
+
+function ajaxifyForm(id) {
+  var q = qid(id);
+  
+  $("#form_" + q).ajaxForm({ beforeSubmit: beforeComment,
+			     success: function() { ajaxifyForm(id); },
+			     target: "#comments_" + q });
+}
+
+function toggleComment(id) {
+  $("#toggle_" + qid(id)).nextAll().toggle();
+  return false;
+}
+
+function loadComments(id) {
+  $("#comments_" + qid(id)).load(location.protocol + "//" + location.host +
+				 "/comments/single/" + id + "/", function() {
+    ajaxifyForm(id);
+  });
+  return false;
+}
+
+function loadAllComments() {
+  $("a.commenttoggle").each(function() {
+    var id = $(this).attr("pid");
+    if (id) {
+      loadComments(id);
+    }
+  });
+}
+
+
+//this part works don't change
+// $(document).ready(function() {
+//   function loading(id) {
+//     return " <span id=\"comments_" + id + "\" class=\"comment\">" +
+//       "<span pid=\"" + id + "\" class=\"commenttoggle\">Loading..." +
+//       "</span></span>";
+//   }
+//   $("p")
+//     .after("<p style='display: none;'><a onclick='return loadAllComments()'>" +
+// 	   "Load all comments (<b>slow</b>)</a></p>")
+//     .toggle(function() { $(this).nextAll().show("normal"); },
+// 	    function() { $(this).nextAll().hide("normal"); })
+//     .hover(function() { $(this).fadeTo("normal", 0.8); },
+// 	   function() { $(this).fadeTo("normal", 0.35); });
+//    $(".chapter p[@id]").each(function() {
+//      $(this).append(loading($(this).attr("id")));
+//        }); });
+//    // $(".chapter table[@id].equation").each(function() {
+//    //   id = $(this).attr("id");
+//    //   $("#" + id + " tr").after('<tr><td colspan="4">' + loading($(this).attr("id")) + '</td></tr>');
+//    // });
+//    // $(".chapter pre[@id]").each(function() {
+//    //   $(this).after(loading($(this).attr("id")));
+//   //     })    
+
+$(document).ready(function() {
+  function loading(id) {
+    return " <span id=\"comments_" + id + "\" class=\"comment\">" +
+      "<span pid=\"" + id + "\" class=\"commenttoggle\">bleeding..." +
+      "</span></span>";
+  } 
+  $("p")
+    .after("<p style='display: none;'><a onclick='return loadAllComments()'>" +
+	   "Load all comments (<b>slow</b>)</a></p>")
+    .toggle(function() { $(this).nextAll().show("normal"); },
+	    function() { $(this).nextAll().hide("normal"); })
+    .hover(function() { $(this).fadeTo("normal", 0.8); },
+	   function() { $(this).fadeTo("normal", 0.35); });
+      
+//
+  $("p").each(function() {
+     $(this).append(loading($(this).attr("id")));
+      });
+//   // $(".chapter table[@id].equation").each(function() {
+//   //   id = $(this).attr("id");
+//   //   $("#" + id + " tr").after('<tr><td colspan="4">' + loading($(this).attr("id")) + '</td></tr>');
+//   // });
+//   // $(".chapter pre[@id]").each(function() {
+//   //   $(this).after(loading($(this).attr("id")));
+//   //     });
+    
+
+//   // var chapid = $("div.preface, div.chapter, div.appendix, div.bibliography").attr("id");
+//   // $("#chapterfeed").attr("href",
+//   // 			 $("#chapterfeed").attr("href") + chapid + "/");
+//   // $.getJSON(location.protocol + "//" + location.host + "/comments/chapter/" +
+//   // 	    chapid + "/count/", function(data) {
+$("p").onclick(function() {
+//   //   //   var s = item == 1 ? "" : "s";
+      // $(".chapter p[@id]").each(function() {
+       	      $(this).replace(
+       	 "<a class='commenttoggle'"+ "href='comments: show / hide'>" +  " comment"+ "</a>"); 
+//   //   // 	"pid='" + id + "' " +
+//   //   // 	"onclick='return loadComments(\"" + id + "\")' " +
+    }); }); 
+//   //   });  
+// //     $("span.commenttoggle").each(function() {
+// //       var id = $(this).attr("pid");
+// //       $(this).replaceWith("<a class='commenttoggle' id='toggle_" + id + "' " +
+// // 			  "onclick='return loadComments(\"" + id + "\")' " +
+// // 			  "href='comment: add'>No comments</a>");
+// //     });
+// //   });
+// // });
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sphinx_django/templates/404.html	Thu Sep 30 11:36:30 2010 +0530
@@ -0,0 +1,8 @@
+{% extends "simple.html" %}
+
+{% block title %}Page Not Found{% endblock %}
+
+{% block body %}
+<p>Sorry, we hit <a href="http://www.haskell.org/haskellwiki/Bottom">&perp;</a> when trying to find the
+page you requested.</p>
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sphinx_django/templates/500.html	Thu Sep 30 11:36:30 2010 +0530
@@ -0,0 +1,11 @@
+{% extends "simple.html" %}
+
+{% block title %}Internal Server Error{% endblock %}
+
+{% block body %}
+<p>Sorry, we hit <a
+href="http://www.haskell.org/haskellwiki/Bottom">&perp;</a> when
+trying to process your request.  If possible, please let <a
+href="mailto:bos@serpentine.com">Bryan</a> know that this problem happened,
+and what you were doing when it occurred.</p>
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sphinx_django/templates/boilerplate.html	Thu Sep 30 11:36:30 2010 +0530
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+  <head>
+    <title>{% block pagetitle %}Mercurial: The Definitive Guide{% endblock %}</title>
+    <link rel="stylesheet" href="/support/styles.css" type="text/css"/>
+    <link rel="alternate" type="application/atom+xml" title="Comments"
+      href="/feeds/comments/"/>
+    <link rel="shortcut icon" type="image/png" href="/support/figs/favicon.png"/>
+    <script type="text/javascript" src="/support/jquery.js"></script>
+      <script type="text/javascript" src="/support/form.js"></script>
+    <script type="text/javascript" src="/support/hsbook.js"></script>
+  </head>
+
+  <body>
+    {% block bodycontent %}{% endblock %}
+
+    <div class="hgbookfooter"> <p><img src="/support/figs/rss.png"> Want to stay
+	up to date? Subscribe to comment feeds for any chapter, or
+	the <a class="feed"
+	  href="/feeds/comments/">entire book</a>.</p> <p>Copyright
+	2006, 2007, 2008, 2009 Bryan O'Sullivan.
+	  Icons by
+	  <a href="mailto:mattahan@gmail.com">Paul Davey</a> aka <a
+	  href="http://mattahan.deviantart.com/">Mattahan</a>.</p>
+    </div>
+
+    <script type="text/javascript">
+    var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+    document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+    </script>
+    <script type="text/javascript">
+    try {
+    var pageTracker = _gat._getTracker("UA-1805907-5");
+    pageTracker._trackPageview();
+    } catch(err) {}</script>
+  </body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sphinx_django/templates/comment.html	Thu Sep 30 11:36:30 2010 +0530
@@ -0,0 +1,62 @@
+{% ifequal length 1 %}
+  <a class="commenttoggle" id="toggle_{{ id }}"
+      onclick="return toggleComment('{{ id }}')"
+      href="comments: show / hide">One comment</a>
+{% else %}
+  {% if length %}
+    <a class="commenttoggle" id="toggle_{{ id }}"
+      onclick="return toggleComment('{{ id }}')"
+      href="comments: show / hide">{{ length }} comments</a>
+  {% else %}
+    <a class="commenttoggle" id="toggle_{{ id }}"
+      onclick="return toggleComment('{{ id }}')"
+      href="comments: show / hide">No comments</a>
+    <div class="comment" {% if not newid %} style="display: none;" {% endif %}>
+      <div class="comment_body">Be the first to comment on this paragraph!</div>
+    </div>
+  {% endif %}
+{% endifequal %}
+{% for c in query %}
+  <div class="{% ifequal c.id newid %}new_{% endifequal %}comment"
+      {% if not newid %} style="display: none;" {% endif %}
+    id="comment{{ c.id }}">
+    <a name="comment{{ c.id }}"/>
+    <div class="comment_header">
+	<span class="comment_id"><a href="/admin/comments/comment/{{ c.id }}/">{{ c.id }}</a></span>
+      {% if c.submitter_url %}
+	<span class="comment_name"><a rel="nofollow"
+	  href="{{ c.submitter_url }}">{{ c.submitter_name|escape }}</a></span>
+      {% else %}
+	<span class="comment_name">{{ c.submitter_name|escape }}</span>
+      {% endif %}
+      <span class="comment_date">{{ c.date|date:"Y-m-d" }}</span>
+      {% if c.reviewed %}
+	<span class="comment_reviewed">(reviewed)</span>
+      {% endif %}
+      {% ifequal c.id newid %}
+	<span class="comment_thanks">thank you for your comment!</span>
+      {% endifequal %}
+    </div>
+    <div class="comment_body">{{ c.comment|escape|linebreaks }}</div>
+  </div>
+{% endfor %}
+<form class="comment" id="form_{{ id }}" action="/comments/submit/{{ id }}/"
+    method="post" {% if not newid %} style="display: none;" {% endif %}>
+  {{ form.id }}
+  <table>
+    <tbody>
+      <tr><td align="right" valign="top">Comment<br><a class="comment_help"
+		href="web.html#web.comment">[ help ]</a></td>
+	  <td>{{ form.comment }}</td></tr>
+      <tr><td align="right">Your name</td><td>{{ form.name }}
+	    <span class="comment_help"><b>Required</b> so we can <a
+		href="web.html#web.comment.name">give you credit</a></span></td></tr>
+      <tr><td align="right">Your URL</td><td>{{ form.url }}
+	    <span class="comment_help"><b>Optional</b> link to blog, home page,
+	      <i>etc</i>.</span></td></tr>
+      <tr><td align="right">Remember you?</td><td>{{ form.remember }}</td></tr>
+      <tr><td/><td><input name="submit" type="submit"
+	      value="Submit Comment"/><span class="comment_error">{{ error }}</span></td></tr>
+    </tbody>
+  </table>
+</form>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sphinx_django/templates/feeds/comments_description.html	Thu Sep 30 11:36:30 2010 +0530
@@ -0,0 +1,12 @@
+<p>On {{ obj.date|date:"Y-m-d" }},
+      {% if obj.submitter_url %}
+	<a rel="nofollow" href="{{ obj.submitter_url }}">{{ obj.submitter_name|escape }}</a>
+      {% else %}
+	{{ obj.submitter_name|escape }}
+      {% endif %}
+commented on &#8220;{{ obj.element.title|escape }}&#8221;:</p>
+<blockquote>
+{{ obj.comment|escape|linebreaks }}
+</blockquote>
+<p>To see this comment in context or to respond, visit <a
+	href="http://{{ site.domain }}{{ obj.get_absolute_url }}">{{ site.domain }}</a></p>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sphinx_django/templates/feeds/comments_title.html	Thu Sep 30 11:36:30 2010 +0530
@@ -0,0 +1,1 @@
+Comment on &#8220;{{ obj.element.title|escape }}&#8221;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sphinx_django/templates/simple.html	Thu Sep 30 11:36:30 2010 +0530
@@ -0,0 +1,7 @@
+{% extends "boilerplate.html" %}
+
+{% block bodycontent %}
+<div class="navheader"><h1>{% block title %}{% endblock %}</h1></div>
+
+<div class="basetemplate">{% block body %}{% endblock %}</div>
+{% endblock %}
Binary file sphinx_django/test.db has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sphinx_django/urls.py	Thu Sep 30 11:36:30 2010 +0530
@@ -0,0 +1,25 @@
+from django.conf.urls.defaults import *
+from django.contrib import admin
+# Uncomment the next two lines to enable the admin:
+# from django.contrib import admin
+admin.autodiscover()
+
+urlpatterns = patterns('',
+    # Example:
+    # (r'^sphinx_django/', include('sphinx_django.foo.urls')),
+
+    (r'^test/','sphinxcomment.views.test' ),
+    (r'chapter/', 'sphinxcomment.views.chapter'),
+    (r'count/(?P<chapter_name>[^/]+)/?$', 'sphinxcomment.views.chapter_count'),                  
+    (r'single/(?P<id>[^/]+)/?$', 'sphinxcomment.views.single'),
+    (r'submit/(?P<id>[^/]+)/?$', 'sphinxcomment.views.submit'),
+    (r'^static/(?P<path>.*)$', 'django.views.static.serve',
+     {'document_root': '/home/amit/review/sttp/_build/html/'}),
+                       
+    # Uncomment the admin/doc line below and add 'django.contrib.admindocs' 
+    # to INSTALLED_APPS to enable admin documentation:
+    # (r'^admin/doc/', include('django.contrib.admindocs.urls')),
+
+    # Uncomment the next line to enable the admin:
+     (r'^admin/', include(admin.site.urls)),
+)
Binary file sphinx_django/urls.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sphinx_django/urls.py~	Thu Sep 30 11:36:30 2010 +0530
@@ -0,0 +1,25 @@
+from django.conf.urls.defaults import *
+from django.contrib import admin
+# Uncomment the next two lines to enable the admin:
+# from django.contrib import admin
+admin.autodiscover()
+
+urlpatterns = patterns('',
+    # Example:
+    # (r'^sphinx_django/', include('sphinx_django.foo.urls')),
+
+    (r'^test/','sphinxcomment.views.test' ),
+    (r'chapter/', 'sphinxcomment.views.chapter'),
+    (r'count/', 'sphinxcomment.views.chapter_count'),                  
+    (r'single/(?P<id>[^/]+)/?$', 'sphinxcomment.views.single'),
+    (r'submit/(?P<id>[^/]+)/?$', 'sphinxcomment.views.submit'),
+    (r'^static/(?P<path>.*)$', 'django.views.static.serve',
+     {'document_root': '/home/amit/review/sttp/_build/html/'}),
+                       
+    # Uncomment the admin/doc line below and add 'django.contrib.admindocs' 
+    # to INSTALLED_APPS to enable admin documentation:
+    # (r'^admin/doc/', include('django.contrib.admindocs.urls')),
+
+    # Uncomment the next line to enable the admin:
+     (r'^admin/', include(admin.site.urls)),
+)