summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeny Fadeev <evgeny.fadeev@gmail.com>2014-07-09 08:51:30 -0300
committerEvgeny Fadeev <evgeny.fadeev@gmail.com>2014-07-09 08:51:30 -0300
commit5a6370fccd50663bdf570a18d59bffb875ea487e (patch)
tree4be6a5a2cfc6bfd2d9a277ee2c737bdf78700be0
parent75dcc201873b6d49715d4661e8361cf65b9bc838 (diff)
downloadaskbot-5a6370fccd50663bdf570a18d59bffb875ea487e.tar.gz
askbot-5a6370fccd50663bdf570a18d59bffb875ea487e.tar.bz2
askbot-5a6370fccd50663bdf570a18d59bffb875ea487e.zip
enabled "decline with reason" moderation and improved moderation feature
-rw-r--r--askbot/media/js/user.js320
-rw-r--r--askbot/media/js/utils.js6
-rw-r--r--askbot/media/style/style.css4
-rw-r--r--askbot/media/style/style.less7
-rw-r--r--askbot/models/post.py45
-rw-r--r--askbot/templates/moderation/manage_reject_reasons_dialog.html43
-rw-r--r--askbot/templates/moderation/queue.html6
-rw-r--r--askbot/templates/moderation/reject_post_dialog.html109
-rw-r--r--askbot/views/moderation.py31
-rw-r--r--askbot/views/users.py5
10 files changed, 159 insertions, 417 deletions
diff --git a/askbot/media/js/user.js b/askbot/media/js/user.js
index 90ca2a7b..b2ff5658 100644
--- a/askbot/media/js/user.js
+++ b/askbot/media/js/user.js
@@ -1,131 +1,3 @@
-//todo: refactor this into "Inbox" object or more specialized
-/*
-var setup_inbox = function(){
-
- var getSelected = function(){
-
- var id_list = new Array();
- var elements = $('#responses input:checked').parent();
-
- elements.each(function(index, element){
- var id = $(element).attr('id').replace(/^re_/,'');
- id_list.push(id);
- });
-
- if (id_list.length === 0){
- alert(gettext('Please select at least one item'));
- }
-
- return {id_list: id_list, elements: elements};
- };
-
- var submit = function(id_list, elements, action_type){
- if (action_type == 'delete' || action_type == 'mark_new' || action_type == 'mark_seen' || action_type == 'remove_flag' || action_type == 'delete_post'){
- $.ajax({
- type: 'POST',
- cache: false,
- dataType: 'json',
- data: JSON.stringify({memo_list: id_list, action_type: action_type}),
- url: askbot['urls']['manageInbox'],
- success: function(response_data){
- if (response_data['success'] == true){
- if (action_type == 'delete' || action_type == 'remove_flag' || action_type == 'delete_post'){
- elements.remove();
- }
- else if (action_type == 'mark_new'){
- elements.addClass('highlight');
- elements.addClass('new');
- elements.removeClass('seen');
- }
- else if (action_type == 'mark_seen'){
- elements.removeClass('highlight');
- elements.addClass('seen');
- elements.removeClass('new');
- }
- }
- else {
- showMessage($('#responses'), response_data['message']);
- }
- }
- });
- }
- };
-
- var startAction = function(action_type){
- var data = getSelected();
- if (data['id_list'].length === 0){
- return;
- }
- if (action_type == 'delete'){
- msg = ngettext('Delete this notification?',
- 'Delete these notifications?', data['id_list'].length);
- if (confirm(msg) === false){
- return;
- }
- }
- if (action_type == 'close'){
- msg = ngettext('Close this entry?',
- 'Close these entries?', data['id_list'].length);
- if (confirm(msg) === false){
- return;
- }
- }
- if (action_type == 'remove_flag'){
- msg = ngettext(
- 'Remove all flags and approve this entry?',
- 'Remove all flags and approve these entries?',
- data['id_list'].length
- );
- if (confirm(msg) === false){
- return;
- }
- }
- submit(data['id_list'], data['elements'], action_type);
- };
- setupButtonEventHandlers($('#re_mark_seen'), function(){startAction('mark_seen')});
- setupButtonEventHandlers($('#re_mark_new'), function(){startAction('mark_new')});
- setupButtonEventHandlers($('#re_dismiss'), function(){startAction('delete')});
- setupButtonEventHandlers($('#re_remove_flag'), function(){startAction('remove_flag')});
- //setupButtonEventHandlers($('#re_close'), function(){startAction('close')});
- setupButtonEventHandlers(
- $('#sel_all'),
- function(){
- setCheckBoxesIn('#responses .new', true);
- setCheckBoxesIn('#responses .seen', true);
- }
- );
- setupButtonEventHandlers(
- $('#sel_seen'),
- function(){
- setCheckBoxesIn('#responses .seen', true);
- }
- );
- setupButtonEventHandlers(
- $('#sel_new'),
- function(){
- setCheckBoxesIn('#responses .new', true);
- }
- );
- setupButtonEventHandlers(
- $('#sel_none'),
- function(){
- setCheckBoxesIn('#responses .new', false);
- setCheckBoxesIn('#responses .seen', false);
- }
- );
-
- if ($('body').hasClass('inbox-flags')) {
- var responses = $('.response-parent');
- responses.each(function(idx, response) {
- var control = new PostModerationControls();
- control.setParent($(response));
- control.setReasonsDialog(rejectPostDialog);
- rejectPostDialog.addPostModerationControl(control);
- $(response).append(control.getElement());
- });
- }
-};
-*/
var setup_inbox = function(){
var page = $('.inbox-flags');
if (page.length) {
@@ -153,63 +25,6 @@ var setup_badge_details_toggle = function(){
};
/**
-* response notifications
-*/
-var Inbox = function() {
- WrappedElement.call(this);
-};
-inherits(Inbox, WrappedElement);
-
-Inbox.prototype.getMemoId = function() {
- return this._parent_element.data('responseId');
-};
-
-Inbox.prototype.getMemoElement = function() {
- var reId = this.getMemoId();
- return $('#re_' + reId);
-};
-
-Inbox.prototype.removeMemo = function() {
- this.getMemoElement().remove();
-};
-
-Inbox.prototype.markMemo = function() {
- var memo = this.getMemoElement();
- var checkbox = memo.find('input[type="checkbox"]');
- checkbox.attr('checked', true);
-};
-
-Inbox.prototype.moderatePost = function(reasonId, actionType){
- var me = this;
- var data = {
- reject_reason_id: reasonId,
- memo_list: [me.getMemoId()],
- action_type: actionType
- };
- $.ajax({
- type: 'POST',
- dataType: 'json',
- cache: false,
- data: JSON.stringify(data),
- url: askbot['urls']['manageInbox'],
- success: function(data){
- if (data['success']){
- me.removeMemo();
- me.dispose();
- if (actionType === 'delete') {
- notify.show(gettext('Post deleted'));
- } else if (actionType === 'remove_flag') {
- notify.show(gettext('Post approved'));
- }
- } else {
- notify.show(data['message']);
- }
- }
- });
-};
-
-
-/**
* the dropdown menu with selection of reasons
* to reject posts and a button that starts menu to
* manage the list of reasons
@@ -233,11 +48,17 @@ DeclineAndExplainMenu.prototype.addReason = function(id, title) {
li.append(button);
button.html(title);
button.data('reasonId', id);
+ button.attr('data-reason-id', id);
this._addReasonBtn.parent().before(li);
this.setupDeclinePostHandler(button);
};
+DeclineAndExplainMenu.prototype.removeReason = function(id) {
+ var btn = this._element.find('a[data-reason-id="' + id + '"]');
+ btn.parent().remove();
+};
+
DeclineAndExplainMenu.prototype.setControls = function(controls) {
this._controls = controls;
};
@@ -266,6 +87,8 @@ DeclineAndExplainMenu.prototype.decorate = function(element) {
manageReasonsDialog.decorate($('#manage-reject-reasons-modal'));
this._manageReasonsDialog = manageReasonsDialog;
manageReasonsDialog.setMenu(this);
+
+ setupButtonEventHandlers(addReasonBtn, function() { manageReasonsDialog.show(); });
};
/**
@@ -350,7 +173,7 @@ PostModerationControls.prototype.getModHandler = function(action, items, optReas
url: askbot['urls']['moderatePostEdits'],
success: function(response_data){
if (response_data['success'] == true){
- me.removeEntries(selectedEditIds);
+ me.removeEntries(response_data['memo_ids']);
}
if (response_data['message']) {
me.showMessage(response_data['message']);
@@ -411,7 +234,7 @@ var ManageRejectReasonsDialog = function(){
WrappedElement.call(this);
this._selected_edit_ids = null;
this._selected_reason_id = null;
- this._state = null;//'select', 'preview', 'add-new'
+ this._state = null;//'select', 'add-new'
this._postModerationControls = [];
this._selectedEditDataReader = undefined;
};
@@ -421,6 +244,10 @@ ManageRejectReasonsDialog.prototype.setMenu = function(menu) {
this._reasonsMenu = menu;
};
+ManageRejectReasonsDialog.prototype.getMenu = function() {
+ return this._reasonsMenu;
+};
+
ManageRejectReasonsDialog.prototype.setSelectedEditDataReader = function(func) {
this._selectedEditDataReader = func;
};
@@ -445,11 +272,8 @@ ManageRejectReasonsDialog.prototype.setState = function(state){
if (this._element){
this._selector.hide();
this._adder.hide();
- this._previewer.hide();
if (state === 'select'){
this._selector.show();
- } else if (state === 'preview'){
- this._previewer.show();
} else if (state === 'add-new'){
this._adder.show();
}
@@ -573,8 +397,10 @@ ManageRejectReasonsDialog.prototype.startSavingReason = function(callback){
title: title_input.getVal(),
details: details_input.getVal()
};
+ var reasonIsNew = true;
if (this._selected_reason_id){
data['reason_id'] = this._selected_reason_id;
+ reasonIsNew = false;
}
var me = this;
@@ -589,6 +415,9 @@ ManageRejectReasonsDialog.prototype.startSavingReason = function(callback){
if (data['success']){
//show current reason data and focus on it
me.addSelectableReason(data);
+ if (reasonIsNew) {
+ me.getMenu().addReason(data['reason_id'], data['title']);
+ }
if (callback){
callback(data);
} else {
@@ -601,47 +430,13 @@ ManageRejectReasonsDialog.prototype.startSavingReason = function(callback){
});
};
-ManageRejectReasonsDialog.prototype.rejectPost = function(reason_id){
- var me = this;
- var memos = this._selected_edit_data['elements'];
- var memo_ids = this._selected_edit_data['id_list'];
- var data = {
- reject_reason_id: reason_id,
- memo_list: memo_ids,
- action_type: 'delete_post'
- };
- $.ajax({
- type: 'POST',
- dataType: 'json',
- cache: false,
- data: JSON.stringify(data),
- url: askbot['urls']['manageInbox'],
- success: function(data){
- if (data['success']){
- $.each(memos, function(idx, memo) {
- $(memo).next('.post-moderation-controls').remove();
- $(memo).remove();
- });
- me.hide();
- } else {
- //only fatal errors here
- me.setErrors(data['message']);
- }
- }
- });
-};
-
-ManageRejectReasonsDialog.prototype.setPreviewerData = function(data){
- this._selected_reason_id = data['id'];
- this._element.find('.selected-reason-title').html(data['title']);
- this._element.find('.selected-reason-details').html(data['details']);
-};
-
ManageRejectReasonsDialog.prototype.startEditingReason = function(){
- var title = this._element.find('.selected-reason-title').html();
- var details = this._element.find('.selected-reason-details').html();
+ var data = this._select_box.getSelectedItemData();
+ var title = $(data['title']).text();
+ var details = data['details'];
this._title_input.setVal(title);
this._details_input.setVal(details);
+ this._selected_reason_id = data['id'];
this.setState('add-new');
};
@@ -668,6 +463,8 @@ ManageRejectReasonsDialog.prototype.startDeletingReason = function(){
success: function(data){
if (data['success']){
select_box.removeItem(reason_id);
+ me.hideEditButtons();
+ me.getMenu().removeReason(reason_id);
} else {
me.setSelectorErrors(data['message']);
}
@@ -680,12 +477,21 @@ ManageRejectReasonsDialog.prototype.startDeletingReason = function(){
}
};
+ManageRejectReasonsDialog.prototype.hideEditButtons = function() {
+ this._editButton.hide();
+ this._deleteButton.hide();
+};
+
+ManageRejectReasonsDialog.prototype.showEditButtons = function() {
+ this._editButton.show();
+ this._deleteButton.show();
+};
+
ManageRejectReasonsDialog.prototype.decorate = function(element){
this._element = element;
//set default state according to the # of available reasons
this._selector = $(element).find('#reject-edit-modal-select');
this._adder = $(element).find('#reject-edit-modal-add-new');
- this._previewer = $(element).find('#reject-edit-modal-preview');
if (this._selector.find('li').length > 0){
this.setState('select');
this.resetInputs();
@@ -694,10 +500,9 @@ ManageRejectReasonsDialog.prototype.decorate = function(element){
this.resetInputs();
}
- $(this._element).find('.dropdown-toggle').dropdown();
-
var select_box = new SelectBox();
select_box.decorate($(this._selector.find('.select-box')));
+ select_box.setSelectHandler(function() { me.showEditButtons() });
this._select_box = select_box;
//setup tipped-inputs
@@ -706,8 +511,7 @@ ManageRejectReasonsDialog.prototype.decorate = function(element){
title_input.decorate($(reject_title_input));
this._title_input = title_input;
- var reject_details_input = $(this._element)
- .find('textarea.reject-reason-details');
+ var reject_details_input = $(this._element).find('textarea.reject-reason-details');
var details_input = new TippedInput();
details_input.decorate($(reject_details_input));
@@ -722,6 +526,7 @@ ManageRejectReasonsDialog.prototype.decorate = function(element){
me.resetInputs();
me.resetSelectedReasonId();
me.setState('select');
+ me.hideEditButtons();
}
);
@@ -731,64 +536,25 @@ ManageRejectReasonsDialog.prototype.decorate = function(element){
);
setupButtonEventHandlers(
- $(this._element).find('.save-reason-and-reject'),
- function(){
- me.startSavingReason(
- function(data){
- me.rejectPost(data['reason_id']);
- }
- );
- }
- );
-
- setupButtonEventHandlers(
- $(this._element).find('.reject'),
- function(){
- me.rejectPost(me.getSelectedReasonId());
- }
- );
-
- setupButtonEventHandlers(
- element.find('.select-other-reason'),
- function(){
- me.resetInputs();
- me.setState('select');
- }
- )
-
- setupButtonEventHandlers(
element.find('.add-new-reason'),
function(){
me.resetSelectedReasonId();
me.resetInputs();
- me.setState('add-new')
- }
- );
-
- setupButtonEventHandlers(
- element.find('.select-this-reason'),
- function(){
- var data = select_box.getSelectedItemData();
- if (data['id']){
- me.setState('preview');
- me.setPreviewerData(data);
- } else {
- me.setSelectorErrors(
- gettext('A reason must be selected to reject post.')
- )
- }
+ me.setState('add-new') ;
}
);
+ this._editButton = element.find('.edit-this-reason');
setupButtonEventHandlers(
- element.find('.edit-reason'),
+ this._editButton,
function(){
me.startEditingReason();
}
);
+ this._deleteButton = element.find('.delete-this-reason');
setupButtonEventHandlers(
- element.find('.delete-this-reason'),
+ this._deleteButton,
function(){
me.startDeletingReason();
}
diff --git a/askbot/media/js/utils.js b/askbot/media/js/utils.js
index a3eb2028..7d877b4b 100644
--- a/askbot/media/js/utils.js
+++ b/askbot/media/js/utils.js
@@ -2487,11 +2487,15 @@ SelectBox.prototype.setSelectHandler = function(handler) {
this._select_handler = handler;
};
+SelectBox.prototype.getSelectHandlerInternal = function() {
+ return this._select_handler;
+};
+
SelectBox.prototype.getSelectHandler = function(item) {
var me = this;
- var handler = this._select_handler;
return function(){
me.selectItem(item);
+ var handler = me.getSelectHandlerInternal();
handler(item.getData());
};
};
diff --git a/askbot/media/style/style.css b/askbot/media/style/style.css
index 7d1cd135..a22c5e48 100644
--- a/askbot/media/style/style.css
+++ b/askbot/media/style/style.css
@@ -4286,6 +4286,10 @@ textarea.tipped-input {
width: 515px;
margin-bottom: 0px;
}
+.modal-body > input[type="text"] {
+ width: 515px;
+ font-style: normal;
+}
.tag-subscriptions {
border-spacing: 10px;
border-collapse: separate;
diff --git a/askbot/media/style/style.less b/askbot/media/style/style.less
index 55f237ae..e0ea5942 100644
--- a/askbot/media/style/style.less
+++ b/askbot/media/style/style.less
@@ -4502,6 +4502,13 @@ textarea.tipped-input {
width: 515px;
margin-bottom: 0px;
}
+.modal-body > input[type="text"] {
+ width: 515px;
+ font-style: normal;
+}
+.alert .close {
+ right: -38px;
+}
.tag-subscriptions {
border-spacing: 10px;
diff --git a/askbot/models/post.py b/askbot/models/post.py
index 94b96370..31396d67 100644
--- a/askbot/models/post.py
+++ b/askbot/models/post.py
@@ -2221,28 +2221,29 @@ class PostRevision(models.Model):
self.post.thread.save()
#give message to the poster
- if self.by_email:
- #todo: move this to the askbot.mail module
- from askbot.mail import send_mail
- email_context = {
- 'site': askbot_settings.APP_SHORT_NAME
- }
- body_text = _(
- 'Thank you for your post to %(site)s. '
- 'It will be published after the moderators review.'
- ) % email_context
- send_mail(
- subject_line = _('your post to %(site)s') % email_context,
- body_text = body_text,
- recipient_list = [self.author.email,],
- )
+ if askbot_settings.CONTENT_MODERATION_MODE == 'premoderation':
+ if self.by_email:
+ #todo: move this to the askbot.mail module
+ from askbot.mail import send_mail
+ email_context = {
+ 'site': askbot_settings.APP_SHORT_NAME
+ }
+ body_text = _(
+ 'Thank you for your post to %(site)s. '
+ 'It will be published after the moderators review.'
+ ) % email_context
+ send_mail(
+ subject_line = _('your post to %(site)s') % email_context,
+ body_text = body_text,
+ recipient_list = [self.author.email,],
+ )
- else:
- message = _(
- 'Your post was placed on the moderation queue '
- 'and will be published after the moderator approval.'
- )
- self.author.message_set.create(message = message)
+ else:
+ message = _(
+ 'Your post was placed on the moderation queue '
+ 'and will be published after the moderator approval.'
+ )
+ self.author.message_set.create(message = message)
activity_type = const.TYPE_ACTIVITY_MODERATED_NEW_POST
else:
@@ -2333,7 +2334,7 @@ class PostRevision(models.Model):
'title': self.title,
'html': sanitized_html
}
- elif self.post.is_answer():
+ else:
return sanitized_html
def get_snippet(self, max_length = 120):
diff --git a/askbot/templates/moderation/manage_reject_reasons_dialog.html b/askbot/templates/moderation/manage_reject_reasons_dialog.html
new file mode 100644
index 00000000..f9ef0e31
--- /dev/null
+++ b/askbot/templates/moderation/manage_reject_reasons_dialog.html
@@ -0,0 +1,43 @@
+<div class="modal" style="display:none" id="manage-reject-reasons-modal">
+ <div class="modal-header">
+ <a class="close" data-dismiss="modal">x</a>
+ <h3>{% trans %}Manage post flag/reject reasons{% endtrans %}</h3>
+ </div>
+ <div id="reject-edit-modal-add-new">{# create new reject reason #}
+ <div class="modal-body">
+ <input
+ class="reject-reason-title tipped-input blank"
+ type="text"
+ value="{% trans %}1) Enter a brief description of why you are rejecting the post.{% endtrans %}"
+ />
+ <textarea class="reject-reason-details tipped-input blank"
+ >{% trans %}2) Please enter details here. This text will be sent to the user.{% endtrans %}</textarea>
+ </div>
+ <div class="modal-footer">
+ <div class="btn-toolbar">
+ <a class="btn save-reason">{% trans %}Save reason{% endtrans %}</a>
+ <a class="btn">{% trans %}Cancel{% endtrans %}</a>
+ </div>
+ </div>
+ </div>
+ <div id="reject-edit-modal-select">{# select one of existing reasons #}
+ <div class="modal-body">
+ <ul class="select-box">
+ {% for reason in post_reject_reasons %}
+ <li
+ class="select-box-item"
+ data-original-title="{{reason.details.text|escape}}"
+ data-item-id="{{reason.id}}"
+ >{{reason.title|escape}}</li>
+ {% endfor %}
+ </ul>
+ </div>
+ <div class="modal-footer">
+ <div class="btn-toolbar">
+ <a class="btn edit-this-reason" style="display: none;">{% trans %}Edit this reason{% endtrans %}</a>
+ <a class="btn delete-this-reason" style="display: none;">{% trans %}Delete this reason{% endtrans %}</a>
+ <a class="btn add-new-reason">{% trans %}Add a new reason{% endtrans %}</a>
+ </div>
+ </div>
+ </div>
+</div>
diff --git a/askbot/templates/moderation/queue.html b/askbot/templates/moderation/queue.html
index e204b86d..a0789a6d 100644
--- a/askbot/templates/moderation/queue.html
+++ b/askbot/templates/moderation/queue.html
@@ -12,7 +12,7 @@
</div>
<a class="btn approve-posts">{% trans %}approve posts{% endtrans %}</a>
<a class="btn approve-posts-users" id="re_approve_posts_users">{% trans %}approve posts and users{% endtrans %}</a>
- <!--div class="btn-group dropdown decline-reasons-menu">
+ <div class="btn-group dropdown decline-reasons-menu">
<span class="btn btn-info dropdown-toggle">
<span>{% trans %}decline and explain why{% endtrans %}</span>
<span class="caret"></span>
@@ -27,7 +27,7 @@
<a class="manage-reasons">{% trans %}add/manage reject reasons{% endtrans %}</a>
</li>
</ul>
- </div-->
+ </div>
<a class="btn btn-danger decline-block-users">{% trans %}delete posts and block users{% endtrans %}</a>
{% if settings.IP_MODERATION_ENABLED %}
<a class="btn btn-danger decline-block-users-ips">{% trans %}delete posts, block users and IPs{% endtrans %}</a>
@@ -35,7 +35,7 @@
</div>
<p style="margin-top: 12px;">Attention: approval of users removes them from the queue and approves ALL of their posts, blocking of the users
DELETES ALL OF THEIR POSTS. There is no easy undo at the moment.</p>
- {% include "moderation/reject_post_dialog.html" %}
+ {% include "moderation/manage_reject_reasons_dialog.html" %}
<div class="action-status"><span></span></div>
<div class="messages">
{% for message in messages %}{# messages are grouped by question, using the "nested_messages" #}
diff --git a/askbot/templates/moderation/reject_post_dialog.html b/askbot/templates/moderation/reject_post_dialog.html
deleted file mode 100644
index 24c75769..00000000
--- a/askbot/templates/moderation/reject_post_dialog.html
+++ /dev/null
@@ -1,109 +0,0 @@
-<div class="modal" style="display:none" id="manage-reject-reasons-modal">
- <div class="modal-header">
- <a class="close" data-dismiss="modal">x</a>
- <h3>{% trans %}Reject the post(s)?{% endtrans %}</h3>
- </div>
- <div id="reject-edit-modal-add-new">{# create new reject reason #}
- <div class="modal-body">
- <input
- class="reject-reason-title tipped-input blank"
- type="text"
- value="{% trans %}1) Enter a brief description of why you are rejecting the post.{% endtrans %}"
- />
- <textarea class="reject-reason-details tipped-input blank"
- >{% trans %}2) Please enter details here. This text will be sent to the user.{% endtrans %}</textarea>
- </div>
- <div class="modal-footer">
- <div class="btn-toolbar">
- <div class="btn-group dropup">
- <button class="btn btn-danger save-reason-and-reject"
- >{% trans %}Use this reason &amp; reject{% endtrans %}</button>
- <button class="btn btn-danger dropdown-toggle" data-toggle="dropdown">
- <span class="caret"></span>
- </button>
- <ul class="dropdown-menu">
- <li>
- <a class="select-other-reason" href="#"
- >{% trans %}Use other reason{% endtrans %}</a>
- </li>
- </ul>
- </div>
- <div class="btn-group">
- <a class="btn save-reason"
- >{% trans %}Save reason, but do not reject{% endtrans %}</a>
- </div>
- <div class="btn-group">
- <a class="btn cancel">{% trans %}Cancel{% endtrans %}</a>
- </div>
- </div>
- </div>
- </div>
- <div id="reject-edit-modal-select">{# select one of existing reasons #}
- <div class="modal-body">
- <p>{% trans %}Please, choose a reason for the rejection.{% endtrans %}</p>
- <ul class="select-box">
- {% for reason in post_reject_reasons %}
- <li
- class="select-box-item"
- data-original-title="{{reason.details.text|escape}}"
- data-item-id="{{reason.id}}"
- >{{reason.title|escape}}</li>
- {% endfor %}
- </ul>
- </div>
- <div class="modal-footer">
- <div class="btn-toolbar">
- <div class="btn-group dropup">
- <a class="btn select-this-reason"
- >{% trans %}Select this reason{% endtrans %}</a>
- <a class="btn dropdown-toggle" data-toggle="dropdown">
- <span class="caret"></span>
- </a>
- <ul class="dropdown-menu">
- <li>
- <a class="delete-this-reason"
- >{% trans %}Delete this reason{% endtrans %}</a>
- </li>
- </ul>
- </div>
- <div class="btn-group">
- <a class="btn add-new-reason"
- >{% trans %}Add a new reason{% endtrans %}</a>
- </div>
- <div class="btn-group">
- <a class="btn cancel">{% trans %}Cancel{% endtrans %}</a>
- </div>
- </div>
- </div>
- </div>
- <div id="reject-edit-modal-preview">{# preview reject reason #}
- <div class="modal-body">
- <p>{% trans %}You have selected reason for the rejection <strong>"<span class="selected-reason-title"></span>"</strong>. The text below will be sent to the user and the post(s) will be deleted:{% endtrans %}</p>
- <textarea disabled="disabled" class="selected-reason-details"></textarea>
- </div>
- <div class="modal-footer">
- <div class="btn-toolbar">
- <div class="btn-group dropup">
- <a class="btn btn-danger reject"
- >{% trans %}Use this reason &amp; reject{% endtrans %}</a>
- <a class="btn btn-danger dropdown-toggle" data-toggle="dropdown">
- <span class="caret"></span>
- </a>
- <ul class="dropdown-menu">
- <li>
- <a class="select-other-reason"
- >{% trans %}Use other reason{% endtrans %}</a>
- </li>
- </ul>
- </div>
- <div class="btn-group">
- <a class="btn edit-reason"
- >{% trans %}Edit this reason{% endtrans %}</a>
- </div>
- <div class="btn-group">
- <a class="btn cancel">{% trans %}Cancel{% endtrans %}</a>
- </div>
- </div>
- </div>
- </div>
-</div>
diff --git a/askbot/views/moderation.py b/askbot/views/moderation.py
index 94561348..8166cb12 100644
--- a/askbot/views/moderation.py
+++ b/askbot/views/moderation.py
@@ -58,7 +58,10 @@ def moderate_post_edits(request):
memo_set = models.ActivityAuditStatus.objects.filter(
id__in=post_data['edit_ids']
).select_related('activity')
- result = {'message': ''}
+ result = {
+ 'message': '',
+ 'memo_ids': set()
+ }
if post_data['action'] == 'decline-with-reason':
num_posts = 0
@@ -125,6 +128,8 @@ def moderate_post_edits(request):
activity_type__in=mod_activity_types
)
num_posts = items.count()
+ memo_set = models.ActivityAuditStatus.objects.filter(user=request.user, activity__in=items)
+ result['memo_ids'].update(memo_set.values_list('id', flat=True))
items.delete()
if num_posts > 0:
@@ -135,8 +140,23 @@ def moderate_post_edits(request):
editors = get_editors(memo_set, exclude=request.user)
num_posts = 0
for editor in editors:
+ #block user
editor.set_status('b')
+ #delete all content by the user
num_posts += request.user.delete_all_content_authored_by_user(editor)
+ #delete all moderation queue items
+ mod_activity_types = (
+ const.TYPE_ACTIVITY_MARK_OFFENSIVE,
+ const.TYPE_ACTIVITY_MODERATED_NEW_POST,
+ const.TYPE_ACTIVITY_MODERATED_POST_EDIT
+ )
+ items = models.Activity.objects.filter(
+ activity_type__in=mod_activity_types,
+ user=editor
+ )
+ memo_set = models.ActivityAuditStatus.objects.filter(user=request.user, activity__in=items)
+ result['memo_ids'].update(memo_set.values_list('id', flat=True))
+ items.delete()
if num_posts:
posts_message = ungettext('%d post deleted', '%d posts deleted', num_posts) % num_posts
@@ -148,7 +168,8 @@ def moderate_post_edits(request):
result['message'] = concat_messages(result['message'], users_message)
moderate_ips = getattr(django_settings, 'ASKBOT_IP_MODERATION_ENABLED', False)
- if moderate_ips and 'ips' in post_data and post_data['action'] == 'block':
+ if moderate_ips and 'ips' in post_data['items'] and post_data['action'] == 'block':
+ ips = set()
for memo in memo_set:
obj = memo.activity.content_object
if isinstance(obj, models.PostRevision):
@@ -157,7 +178,9 @@ def moderate_post_edits(request):
#to make sure to not block the admin and
#in case REMOTE_ADDR is a proxy server - not
#block access to the site
- ips.remove(request.META['REMOTE_ADDR'])
+ my_ip = request.META['REMOTE_ADDR']
+ if my_ip in ips:
+ ips.remove(request.META['REMOTE_ADDR'])
from stopforumspam.models import Cache
already_blocked = Cache.objects.filter(ip__in=ips)
@@ -173,6 +196,8 @@ def moderate_post_edits(request):
ips_message = ungettext('%d ip blocked', '%d ips blocked', num_ips) % num_ips
result['message'] = concat_messages(result['message'], ips_message)
+ result['memo_ids'].update(set(memo_set.values_list('id', flat=True)))
+ result['memo_ids'] = list(result['memo_ids'])
memo_set.delete()
request.user.update_response_counts()
if result['message']:
diff --git a/askbot/views/users.py b/askbot/views/users.py
index 504e654b..7c3c87c3 100644
--- a/askbot/views/users.py
+++ b/askbot/views/users.py
@@ -787,7 +787,8 @@ def user_responses(request, user, context):
#3) "package" data for the output
response_list = list()
for memo in memo_set:
- if memo.activity.content_object is None:
+ obj = memo.activity.content_object
+ if obj is None:
continue#a temp plug due to bug in the comment deletion
response = {
'id': memo.id,
@@ -800,7 +801,7 @@ def user_responses(request, user, context):
'message_type': memo.activity.get_activity_type_display(),
'question_id': memo.activity.question.id,
'followup_messages': list(),
- 'content': memo.activity.content_object.html,
+ 'content': obj.html or obj.text,
}
response_list.append(response)