summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2010-11-21 13:17:11 +0100
committerGeorg Brandl <georg@python.org>2010-11-21 13:17:11 +0100
commitbdf27419e46bc005de470207fdecd4a07a1c8e57 (patch)
treef43e39134f78da338e4874bf7af118de80f43776
parent69713fb26d028dcbd43708f9bd156edf8ba705b2 (diff)
downloadsphinx-git-bdf27419e46bc005de470207fdecd4a07a1c8e57.tar.gz
Support complete comment deletion.
-rw-r--r--sphinx/themes/basic/static/websupport.js18
-rw-r--r--sphinx/websupport/__init__.py17
-rw-r--r--sphinx/websupport/storage/sqlalchemy_db.py3
-rw-r--r--sphinx/websupport/storage/sqlalchemystorage.py25
4 files changed, 43 insertions, 20 deletions
diff --git a/sphinx/themes/basic/static/websupport.js b/sphinx/themes/basic/static/websupport.js
index 3881a42bc..29f0a5dd8 100644
--- a/sphinx/themes/basic/static/websupport.js
+++ b/sphinx/themes/basic/static/websupport.js
@@ -353,6 +353,14 @@
data: {id: id},
success: function(data, textStatus, request) {
var div = $('#cd' + id);
+ if (data == 'delete') {
+ // Moderator mode: remove the comment and all children immediately
+ div.slideUp('fast', function() {
+ div.remove();
+ });
+ return;
+ }
+ // User mode: only mark the comment as deleted
div
.find('span.user-id:first')
.text('[deleted]').end()
@@ -507,7 +515,9 @@
addComment($('#rf' + id));
closeReply(id);
});
- div.slideDown('fast');
+ div.slideDown('fast', function() {
+ $('#rf' + id).find('textarea').focus();
+ });
}
/**
@@ -567,7 +577,7 @@
div.find('#' + direction + 'u' + comment.id).show();
}
- if (comment.text != '[deleted]') {
+ if (opts.moderator || comment.text != '[deleted]') {
div.find('a.reply').show();
if (comment.proposal_diff)
div.find('#sp' + comment.id).show();
@@ -693,7 +703,9 @@
<p class="add-a-comment">Add a comment\
(<a href="#" class="comment-markup" id="ab<%id%>">markup</a>):</p>\
<div class="comment-markup-box" id="mb<%id%>">\
- Comment markup: </div>\
+ reStructured text markup: <i>*emph*</i>, <b>**strong**</b>, \
+ <tt>``code``</tt>, \
+ code blocks: <tt>::</tt> and an indented block after blank line</div>\
<form method="post" id="cf<%id%>" class="comment-form" action="">\
<textarea name="comment" cols="80"></textarea>\
<p class="propose-button">\
diff --git a/sphinx/websupport/__init__.py b/sphinx/websupport/__init__.py
index 9a476ad98..d483a1ff8 100644
--- a/sphinx/websupport/__init__.py
+++ b/sphinx/websupport/__init__.py
@@ -266,13 +266,16 @@ class WebSupport(object):
return self.storage.get_data(node_id, username, moderator)
def delete_comment(self, comment_id, username='', moderator=False):
- """Delete a comment. Doesn't actually delete the comment, but
- instead replaces the username and text files with "[deleted]" so
- as not to leave any comments orphaned.
+ """Delete a comment.
- If `moderator` is True, the comment will always be deleted. If
- `moderator` is False, the comment will only be deleted if the
- `username` matches the `username` on the comment.
+ If `moderator` is True, the comment and all descendants will be deleted
+ from the database, and the function returns ``True``.
+
+ If `moderator` is False, the comment will be marked as deleted (but not
+ removed from the database so as not to leave any comments orphaned), but
+ only if the `username` matches the `username` on the comment. The
+ username and text files are replaced with "[deleted]" . In this case,
+ the function returns ``False``.
This raises :class:`~sphinx.websupport.errors.UserNotAuthorizedError`
if moderator is False and `username` doesn't match username on the
@@ -282,7 +285,7 @@ class WebSupport(object):
:param username: the username requesting the deletion.
:param moderator: whether the requestor is a moderator.
"""
- self.storage.delete_comment(comment_id, username, moderator)
+ return self.storage.delete_comment(comment_id, username, moderator)
def add_comment(self, text, node_id='', parent_id='', displayed=True,
username=None, time=None, proposal=None,
diff --git a/sphinx/websupport/storage/sqlalchemy_db.py b/sphinx/websupport/storage/sqlalchemy_db.py
index 4e2757a9e..dd4bf8822 100644
--- a/sphinx/websupport/storage/sqlalchemy_db.py
+++ b/sphinx/websupport/storage/sqlalchemy_db.py
@@ -33,7 +33,7 @@ class Node(Base):
def nested_comments(self, username, moderator):
"""Create a tree of comments. First get all comments that are
- descendents of this node, then convert them to a tree form.
+ descendants of this node, then convert them to a tree form.
:param username: the name of the user to get comments for.
:param moderator: whether the user is moderator.
@@ -56,6 +56,7 @@ class Node(Base):
# Filter out all comments not descending from this node.
q = q.filter(Comment.path.like(str(self.id) + '.%'))
+ # Filter out all comments that are not moderated yet.
if not moderator:
q = q.filter(Comment.displayed == True)
diff --git a/sphinx/websupport/storage/sqlalchemystorage.py b/sphinx/websupport/storage/sqlalchemystorage.py
index 6f13c91b6..a83c7623f 100644
--- a/sphinx/websupport/storage/sqlalchemystorage.py
+++ b/sphinx/websupport/storage/sqlalchemystorage.py
@@ -88,12 +88,23 @@ class SQLAlchemyStorage(StorageBackend):
session = Session()
comment = session.query(Comment).\
filter(Comment.id == comment_id).one()
- if moderator or comment.username == username:
+ if moderator:
+ # moderator mode: delete the comment and all descendants
+ # find descendants via path
+ session.query(Comment).filter(
+ Comment.path.like(comment.path + '.%')).delete(False)
+ session.delete(comment)
+ session.commit()
+ session.close()
+ return True
+ elif comment.username == username:
+ # user mode: do not really delete, but remove text and proposal
comment.username = '[deleted]'
comment.text = '[deleted]'
comment.proposal = ''
session.commit()
session.close()
+ return False
else:
session.close()
raise UserNotAuthorizedError()
@@ -154,20 +165,16 @@ class SQLAlchemyStorage(StorageBackend):
def accept_comment(self, comment_id):
session = Session()
-
- # XXX assignment to "comment" needed?
- comment = session.query(Comment).filter(
- Comment.id == comment_id).update(
- {Comment.displayed: True})
+ session.query(Comment).filter(Comment.id == comment_id).update(
+ {Comment.displayed: True}
+ )
session.commit()
session.close()
def reject_comment(self, comment_id):
session = Session()
-
- comment = session.query(Comment).\
- filter(Comment.id == comment_id).one()
+ comment = session.query(Comment).filter(Comment.id == comment_id).one()
session.delete(comment)
session.commit()