Loading...." + - "
"; - } - -$("p[@id]").each(function() { - $(this).append(loading($(this).attr("id"))); - }); - - -var url_string=window.location.pathname; -var temp = new Array(); -temp = url_string.split('/'); -var chap_name=temp[temp.length-1].split('.')[0]; - -jQuery.getJSON("http://127.0.0.1:8000/count/"+chap_name, function(data) { - - $("span.comment").each(function(data_val) { - var id = $(this).attr("id"); - var substring=id.substr(9); - - $(this).replaceWith("" + data.count[substring] +' comments'+ ""); - - }); - - - }); - - }); - - - - - - - - - - - - - diff -r f5e18f8ed036 -r de4a2ed2f34b simplecomment.py --- a/simplecomment.py Fri Oct 15 15:59:28 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,112 +0,0 @@ -# -*- coding: utf-8 -*- -""" - sphinx.builders.webapp - ~~~~~~~~~~~~~~~~~~~~~~ - - A web application builder. - - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. - :license: BSD, see LICENSE for details. -""" - -import os -import sys -import codecs -import shutil -import cPickle -from os import path -from hashlib import md5 -from types import ListType, TupleType -import re - - -import jinja2 as j2 - -#from mercurial import commands, ui -#from mercurial.hg import repository - -from sphinx.builders.html import StandaloneHTMLBuilder -from sphinx.errors import SphinxError -from sphinx.web.dbutils import PidDb -from sphinx.web.webconfig import WebConfig -from sphinx.writers.html import HTMLTranslator - - - - - - -class SimpleCommentHTMLBuilder(StandaloneHTMLBuilder): - """ Static html pages with paragraph ids. - """ - def init(self): - self.app.add_javascript('simplecomment.js') - self.id_file_loc=os.path.join(self.outdir,'paragraph_id.py') - self.id_file=open(self.id_file_loc,'w') - self.beginning="p_list= " - self.id_dictionary={} - - StandaloneHTMLBuilder.init(self) - - def get_target_uri(self, docname, typ=None): - return docname + self.link_suffix - - def write_doc(self, docname, doctree): - StandaloneHTMLBuilder.write_doc(self, docname, doctree) - - def prepare_writing(self, docnames): - StandaloneHTMLBuilder.prepare_writing(self, docnames) - - def finish(self): - StandaloneHTMLBuilder.finish(self) - self.add_pids_to_paragraphs() - self.id_file.write(self.beginning+str(self.id_dictionary)) - - - def add_pids_to_paragraphs(self): - all_files=[] - for path,dir,filenames in os.walk(self.outdir): - for filename in filenames: - all_files.append(os.path.join(path, filename)) - - for element in all_files : - if element.split('.')[1]=='html': - self.id_list=[] - self.taggen(element) - self.id_dictionary[self.chapter.split('/')[-1]]=self.id_list - - else : - pass - - def retag(self,s): - self.biggest_id += 1 - id_name="%s_%x" % (self.chapter.split('/')[-1],self.biggest_id) - self.id_list.append(id_name) - - return '' %id_name - - - - - def taggen(self,html_file_name): - tagged = re.compile('
]*>', re.M) - self.biggest_id=0 - self.chapter=html_file_name.split('.')[0] - - try: - f = open(html_file_name).read() - f1 = re.sub('
',self.retag, f ) - - - if f1 != f: - tmpname = html_file_name+ '.tmp' - fp = open(tmpname, 'w') - fp.write(f1) - fp.close() - os.rename(tmpname,html_file_name) - - except IOError: - pass - - - diff -r f5e18f8ed036 -r de4a2ed2f34b sphinx_django/settings.py --- a/sphinx_django/settings.py Fri Oct 15 15:59:28 2010 +0530 +++ b/sphinx_django/settings.py Wed Oct 27 13:59:11 2010 +0530 @@ -1,4 +1,5 @@ # Django settings for sphinx_django project. +import os DEBUG = True TEMPLATE_DEBUG = DEBUG @@ -66,16 +67,17 @@ ROOT_URLCONF = 'sphinx_django.urls' - +templates=os.path.join(os.getcwd(),'templates') TEMPLATE_DIRS = ( - "/home/amit/review/sphinx_django/templates/" + 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. ) - +# Path of your sphinx static files +SPHINX_PROJECT = '/home/amit/review/sttp_com/_build/html' INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', diff -r f5e18f8ed036 -r de4a2ed2f34b sphinx_django/settings.pyc Binary file sphinx_django/settings.pyc has changed diff -r f5e18f8ed036 -r de4a2ed2f34b sphinx_django/settings.py~ --- a/sphinx_django/settings.py~ Fri Oct 15 15:59:28 2010 +0530 +++ b/sphinx_django/settings.py~ Wed Oct 27 13:59:11 2010 +0530 @@ -1,4 +1,5 @@ # Django settings for sphinx_django project. +import os DEBUG = True TEMPLATE_DEBUG = DEBUG @@ -65,6 +66,9 @@ ROOT_URLCONF = 'sphinx_django.urls' + + + TEMPLATE_DIRS = ( "/home/amit/review/sphinx_django/templates/" @@ -72,7 +76,8 @@ # Always use forward slashes, even on Windows. # Don't forget to use absolute paths, not relative paths. ) - +# Path of your sphinx static files +SPHINX_PROJECT = 'SPHINX STATIC FILES' INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', diff -r f5e18f8ed036 -r de4a2ed2f34b sphinx_django/sphinxcomment/views.py --- a/sphinx_django/sphinxcomment/views.py Fri Oct 15 15:59:28 2010 +0530 +++ b/sphinx_django/sphinxcomment/views.py Wed Oct 27 13:59:11 2010 +0530 @@ -10,10 +10,12 @@ from django.template import Context from django.template.loader import get_template from django.utils.simplejson import dumps - +from django.conf import settings +from os.path import join, splitext +from BeautifulSoup import BeautifulSoup as bss, Tag -placeholder_string = open('paragraph_id.py').read() -exec placeholder_string +#placeholder_string = open('paragraph_id.py').read() +#exec placeholder_string def dump_queries(): # requires settings.DEBUG to be set to True in order to work @@ -38,46 +40,36 @@ def comments_by_chapter(chapter): objs = {} - try: - para_list=p_list[chapter] - - for paragraph_id in para_list: - objs[paragraph_id]=[] - - except: - para_list=[] - - for paragraph_id in para_list: - print chapter ,paragraph_id - for c in Comment.objects.filter(element__chapter_name=chapter,element__paragraph_id=paragraph_id).order_by('date'): - - objs[paragraph_id].append(c) + for c in Comment.objects.filter(element__chapter_name=chapter).order_by('date'): + objs.setdefault(c.element.paragraph_id, []).append(c) + return objs + -def chapter(request): - template = get_template('comment.html') - resp = {} - for elt, comments in comments_by_chapter(chapter).iteritems(): - print elt ,comments - form = CommentForm(initial={ - 'paragraph_id': elt, - 'name': name - }) - resp[elt] = template.render(Context({ - 'paragraph_id': elt, - 'form': form, - 'length': len(comments), - 'query': comments, - })) - return HttpResponse(dumps(resp), mimetype='application/json') +# def chapter(request): +# template = get_template('comment.html') +# resp = {} +# for elt, comments in comments_by_chapter(chapter).iteritems(): +# print elt ,comments +# form = CommentForm(initial={ +# 'paragraph_id': elt, +# 'name': name +# }) +# resp[elt] = template.render(Context({ +# 'paragraph_id': elt, +# 'form': form, +# 'length': len(comments), +# 'query': comments, +# })) +# return HttpResponse(dumps(resp), mimetype='application/json') def chapter_count(request,chapter_name): print chapter_name @@ -98,7 +90,7 @@ if paragraph_id[-1]=='/': paragraph_id=paragraph_id[:-1] queryset = Comment.objects.filter(element=paragraph_id) - print paragraph_id + print len(queryset) if form is None: form = CommentForm(initial={ 'paragraph_id': paragraph_id, @@ -163,8 +155,27 @@ string="
test comment
" return HttpResponse(string,mimetype="text/plain") - - +def page(req, path): + if splitext(path)[1] == '.html': + soup = bss(open(join(settings.SPHINX_PROJECT, path)).read()) + head = soup.find('head') + first_script = Tag(soup, 'script') + first_script['src'] = "../_static/simplecomment.js" + first_script['type'] = "text/javascript" + second_script = Tag(soup, 'script') + second_script['src'] = "../_static/jquery.form.js" + second_script['type'] = "text/javascript" + head.insert(-1, first_script) + head.insert(-1, second_script) + counter = 0 + page_identity = path.split('.')[0].replace('/', '_') + for p in soup.findAll('p'): + p['id'] = '%s_%s' %(page_identity, counter) + counter += 1 + return HttpResponse(str(soup)) + else: + return HttpResponse(open(join(settings.SPHINX_PROJECT, path)).read()) + #return HttpResponse(dumps(string),mimetype="text/plain") #test= csrf_exempt(test) diff -r f5e18f8ed036 -r de4a2ed2f34b sphinx_django/sphinxcomment/views.pyc Binary file sphinx_django/sphinxcomment/views.pyc has changed diff -r f5e18f8ed036 -r de4a2ed2f34b sphinx_django/sphinxcomment/views.py~ --- a/sphinx_django/sphinxcomment/views.py~ Fri Oct 15 15:59:28 2010 +0530 +++ b/sphinx_django/sphinxcomment/views.py~ Wed Oct 27 13:59:11 2010 +0530 @@ -10,10 +10,12 @@ from django.template import Context from django.template.loader import get_template from django.utils.simplejson import dumps - +from django.conf import settings +from os.path import join, splitext +from BeautifulSoup import BeautifulSoup as bss, Tag -placeholder_string = open('paragraph_id.py').read() -exec placeholder_string +#placeholder_string = open('paragraph_id.py').read() +#exec placeholder_string def dump_queries(): # requires settings.DEBUG to be set to True in order to work @@ -38,44 +40,36 @@ def comments_by_chapter(chapter): objs = {} - try: - para_list=p_list[chapter] - - for paragraph_id in para_list: - objs[paragraph_id]=[] + for c in Comment.objects.filter(element__chapter_name=chapter).order_by('date'): + objs.setdefault(c.element.paragraph_id, []).append(c) + - except: - para_list=[] + + + return objs - for paragraph_id in para_list: - - for c in Comment.objects.filter(element__chapter_name=chapter,element__paragraph_id=paragraph_id).order_by('date'): - - objs[paragraph_id].append(c) - - return objs -def chapter(request): - template = get_template('comment.html') - resp = {} - for elt, comments in comments_by_chapter(chapter).iteritems(): - print elt ,comments - form = CommentForm(initial={ - 'paragraph_id': elt, - 'name': name - }) - resp[elt] = template.render(Context({ - 'paragraph_id': elt, - 'form': form, - 'length': len(comments), - 'query': comments, - })) - return HttpResponse(dumps(resp), mimetype='application/json') +# def chapter(request): +# template = get_template('comment.html') +# resp = {} +# for elt, comments in comments_by_chapter(chapter).iteritems(): +# print elt ,comments +# form = CommentForm(initial={ +# 'paragraph_id': elt, +# 'name': name +# }) +# resp[elt] = template.render(Context({ +# 'paragraph_id': elt, +# 'form': form, +# 'length': len(comments), +# 'query': comments, +# })) +# return HttpResponse(dumps(resp), mimetype='application/json') def chapter_count(request,chapter_name): print chapter_name @@ -93,9 +87,10 @@ return HttpResponse(dumps(resp), mimetype='application/json') def single(request,paragraph_id, form=None, newid=None): - paragraph_id=paragraph_id[:-1] + if paragraph_id[-1]=='/': + paragraph_id=paragraph_id[:-1] queryset = Comment.objects.filter(element=paragraph_id) - print paragraph_id + print len(queryset) if form is None: form = CommentForm(initial={ 'paragraph_id': paragraph_id, @@ -119,11 +114,13 @@ def submit(request, paragraph_id): + try: element = get_object_or_404(Element, paragraph_id=paragraph_id) except Http404: + #creating chapter name from paragraph_id surely there is a better way using the context but i do not know as yet chapter_id='_'.join(paragraph_id.split('_')[0:-1]) - chapter_name=chapter_id.replace('_','/') + chapter_name=chapter_id[-1::-1].replace('_','/',1)[-1::-1] element=Element(chapter_name=chapter_name,paragraph_id=paragraph_id) element.save() print element.chapter_name @@ -158,8 +155,27 @@ string="test comment
" return HttpResponse(string,mimetype="text/plain") - - +def page(req, path): + if splitext(path)[1] == '.html': + soup = bss(open(join(settings.SPHINX_PROJECT, path)).read()) + head = soup.find('head') + first_script = Tag(soup, 'script') + first_script['src'] = "_static/simplecomment.js" + first_script['type'] = "text/javascript" + second_script = Tag(soup, 'script') + second_script['src'] = "_static/jquery.form.js" + second_script['type'] = "text/javascript" + head.insert(-1, first_script) + head.insert(-1, second_script) + counter = 0 + page_identity = path.split('.')[0].replace('/', '_') + for p in soup.findAll('p'): + p['id'] = '%s_%s' %(page_identity, counter) + counter += 1 + return HttpResponse(str(soup)) + else: + return HttpResponse(open(join(settings.SPHINX_PROJECT, path)).read()) + #return HttpResponse(dumps(string),mimetype="text/plain") #test= csrf_exempt(test) diff -r f5e18f8ed036 -r de4a2ed2f34b sphinx_django/static/#comments.js# --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sphinx_django/static/#comments.js# Wed Oct 27 13:59:11 2010 +0530 @@ -0,0 +1,587 @@ +/* + * Java Script/JQuery glue for server-side Python code and the comments/fixes + * stuff which is being served along with the documentation. + * + * :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + * Below is a short description of the main functions used to make the tool + * work. Internal functions are not listed here. + * + ** + *** checking/downloading/printing/adding comments and fixes **************** + ** + * + * load_comments(id) -> check if database file with comments for paragraph 'id' + * exists on the server; if yes, invoke comments_found() + * function; if not, invoke no_comments() function. + * + * load_fixes(id) -> check if database file with fixes for paragraph 'id' + * exists on the server; if yes, invoke fixes_found() + * function; if not, invoke no_fixes() function. + * + * no_comments(id) -> insert a link ('No comments') to the post form after + * the paragraph 'id'. + * + * no_fixes(id) -> insert a link ('No fixes') to the post form after the + * 'No comments' string. + * + * comments_found(id) -> download the comments database file for paragraph 'id' + * and print it under the paragraph. + * + * fixes_found(id) -> download the fixes database file for paragraph 'id' + * and print it under the paragraph. + * + * print_comments(id, data) -> print comments collected in an array 'data' + * under the paragraph 'id'. + * 'data' is an array of objects; every object + * has properties like 'name', 'score', 'comment'. + * This function also prints a link at the end + * of paragraph with a number of comments hidden + * (i.e. "3 Comments"). + * + * print_fixes(id, data) -> print fixes collected in an array 'data' under + * the paragraph 'id'. + * The description for print_comments() applies. + * + * add_new_comment(id) -> ajaxify a comment post form for paragraph 'id' + * and reload comments (with load_comments() function). + * This function also validates the form and resets + * it on successful submit. + * + ** + *** displaying/hiding areas ************************************************* + ** + * + * show_hide_comments(id) -> hide fixes area, show comments area and make sure + * that the main comments/fixes area is shown + * + * show_hide_fixes(id) -> hide comments area, show fixes area and make sure + * that the main comments/fixes area is shown + * + * show_hide_submitFixFields(id) -> show/hide additional fields in the post + * form for fixes view (when 'I would like + * to submit a patch' checkbox is 'true') + * and fill them with data if needed + * + * + ** + *** rating comments/fixes *************************************************** + ** + * + * comments_up_down(id, comment_no, up_down, db) + * -> send a GET request to the server with three parameters: + * - id: paragraph id, + * - comment_no: a number of a comment to score, + * - up_down: two values possible: 'up' or 'down' + * depending on what kind of action should + * be taken ('up' means score+=1, and down + * means score-=1). + * + ** + *** sorting comments/fixes ************************************************ + ** + * + * sort_comments(id, by, db) -> sort comments for paragraph 'id' by 'by' argument + * (two values for 'by' are possible at the moment: + * 'score' and 'date'). The sorting order changes + * automatically from increasing to decreasing with + * every sort. + * + * + ** + *** threading ************************************************************ + ** + * + * new_thread(id) -> make a particular comment a new thread before submitting + * it + * + * reply_to(id, comment_no) -> make a comment a reply to comment 'comment_no' + * + ** + *** developer's actions *************************************************** + ** + * + * delete_comment(db, id, comment_no) -> delete entry from database 'db' + * located in 'id' file under + * 'comment_no' index + * + * commit_fix(node, id, fix_no) -> commit a fix located in 'id' file under + * 'fix_no' index to the repository + * + ** + *** general-use functions ************************************************ + ** + * + * empty_comments(id) -> empty the comments area + * + * empty_fixes(id) -> empty the fixes area + * + * is_developer() -> returns true when developer rights should be granted + * and false when the rights should not be granted. + * At jQuery level it's only about displaying some + * additional/developer-only-options. Real authorization + * is going on on webapp (appserver.py) level. + */ + +comments_path = "/comments/"; +fixes_path = "/fixes/"; +_db = undefined; + +// *** checking/downloading/printing/adding comments ************************ + +function load_generic(what, id, error_func, success_func) { + // if the div was filled with the comments before, empty it before appending + if(_db == 'comments') { + empty_comments(id); + } else { + empty_fixes(id); + } + + // 'what' -> 'comments_path' or 'fixes_path' variables; + var c_path = location.protocol + "//" + location.host + what + id; + $.ajax({ url: c_path, + type: 'HEAD', + error: function() { error_func(id) }, + success: function() { success_func(id)} + }); +} + +function load_comments(id) { + return load_generic(comments_path, id, no_comments, comments_found) +} + +function load_fixes(id) { + return load_generic(fixes_path, id, no_fixes, fixes_found) +} + +function get_load_cf(db) { + if(db == 'comments' || db == comments_path) { + return load_comments; + } + return load_fixes; +} + +////////////////////// + +function not_found_generic(what, id) { + // 'what' -> 'comment' or 'fix' strings + plural = what=='comment'?'comments':'fixes'; + $("a[name*=" + what + "_" + id + "]").replaceWith( + 'No ' + plural + '' + + ''); +} + +function no_comments(id) { + not_found_generic('comment', id); +} + +function no_fixes(id) { + not_found_generic('fix', id); +} + +////////////////////////////// + +function found_generic(what, id, print_func) { + var c_path = location.protocol + "//" + location.host + what + id + "?id=" + id; + $.getJSON(c_path, function(data) { + print_func(id, data); + }); +} + +function comments_found(id) { + found_generic(comments_path, id, print_comments); +} + +function fixes_found(id) { + found_generic(fixes_path, id, print_fixes); +} + +/////////////////////////////// + +function print_generic(what, id, data) { + var c_flag = (what == 'comments') ? true : false; + var singular = (what == 'comments') ? 'comment' : 'fix'; + var isdev = is_developer(); + var node = $('div[class=submitFixFields_' + id + ']').attr('value'); + + if(what == 'comments') { + empty_comments(id); + } else { + empty_fixes(id); + } + + // A 'factory' function which generates '+' and '-' buttons for every comment. + // 'what' is a kind of database (db for comments or for fixes) + // 'id' is a paragraph id. + // 'comment_no' is a place of a comment in the list of comments for given + // paragraph. + // 'up_down' is passed to POST method. It should be 'up' or 'down'. + // 'sign' is what's displayed on the button, by default it's '+' or '-'. + function rate_comment_up_down_button(what, id, comment_no, up_down, sign) { + return ' ' + sign + ' ' + } + + // in fixes view - show proposed diff + function proposed_fix(c_flag, paragraph) { + if(!c_flag) { + return '' + + 'Hide' + + ' | ' + + ' Sort by: ' + + sort_comments_by_button(what, id, 'date') + + ', ' + + sort_comments_by_button(what, id, 'score') + + ', ' + + sort_comments_by_button(what, id, 'thread') + + '.' + + ' |
' + + 'Hide' + + ' | ' + + ' Sort by: ' + + sort_comments_by_button(what, id, 'date') + + ', ' + + sort_comments_by_button(what, id, 'score') + + ', ' + + sort_comments_by_button(what, id, 'thread') + + '.' + + ' |