mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Support complete comment deletion.
This commit is contained in:
@@ -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">\
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user