summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--askbot/models/post.py4
-rw-r--r--askbot/models/question.py17
-rw-r--r--askbot/skins/common/media/js/post.js21
-rw-r--r--askbot/skins/common/templates/question/answer_controls.html31
-rw-r--r--askbot/skins/default/media/images/publish.pngbin0 -> 282 bytes
-rw-r--r--askbot/skins/default/media/images/unpublish.pngbin0 -> 294 bytes
-rw-r--r--askbot/skins/default/media/style/style.less10
-rw-r--r--askbot/skins/default/templates/question.html27
-rw-r--r--askbot/skins/default/templates/question/javascript.html2
-rw-r--r--askbot/tests/thread_model_tests.py6
-rw-r--r--askbot/views/commands.py24
-rw-r--r--askbot/views/readers.py1
12 files changed, 107 insertions, 36 deletions
diff --git a/askbot/models/post.py b/askbot/models/post.py
index 7fac40bc..173da32c 100644
--- a/askbot/models/post.py
+++ b/askbot/models/post.py
@@ -571,6 +571,10 @@ class Post(models.Model):
user_filter = user_filter & models.Q(groups__in=self.groups.all())
return User.objects.filter(user_filter)
+ def has_group(self, group):
+ """true if post belongs to the group"""
+ return self.groups.filter(id=group.id).exists()
+
def add_to_groups(self, groups):
#todo: use bulk-creation
for group in groups:
diff --git a/askbot/models/question.py b/askbot/models/question.py
index f85e82df..5793f301 100644
--- a/askbot/models/question.py
+++ b/askbot/models/question.py
@@ -675,6 +675,17 @@ class Thread(models.Model):
#use len to cache the queryset
return len(self.get_answers_by_user(user)) > 0
+ def has_moderator(self, user):
+ """true if ``user`` is also a thread moderator"""
+ if user.is_anonymous():
+ return False
+ elif askbot_settings.GROUPS_ENABLED:
+ if user.is_administrator_or_moderator():
+ user_groups = user.get_groups(private=True)
+ thread_groups = self.get_groups_shared_with()
+ return bool(set(user_groups) & set(thread_groups))
+ return False
+
def requires_response_moderation(self, author):
"""true, if answers by a given author must be moderated
before publishing to the enquirers"""
@@ -732,7 +743,7 @@ class Thread(models.Model):
the method get_post_data()"""
if askbot_settings.GROUPS_ENABLED:
#temporary plug: bypass cache where groups are enabled
- return self.get_post_data(sort_method = sort_method, user = user)
+ return self.get_post_data(sort_method=sort_method, user=user)
key = self.get_post_data_cache_key(sort_method)
post_data = cache.cache.get(key)
if not post_data:
@@ -818,7 +829,7 @@ class Thread(models.Model):
#if moderated - then author is guaranteed to be the
#limited visibility enquirer
published_answers = self.posts.get_answers(
- user=self.author#todo: may be > 1
+ user=question_post.author#todo: may be > 1
).filter(
deleted=False
).order_by(
@@ -829,7 +840,7 @@ class Thread(models.Model):
}[sort_method]
)
#now put those answers first
- for answer in reversed(answers):
+ for answer in reversed(published_answers):
answers.remove(answer)
answers.insert(0, answer)
published_answer_ids.append(answer.id)
diff --git a/askbot/skins/common/media/js/post.js b/askbot/skins/common/media/js/post.js
index 3c320f76..71718199 100644
--- a/askbot/skins/common/media/js/post.js
+++ b/askbot/skins/common/media/js/post.js
@@ -3962,6 +3962,27 @@ $(document).ready(function() {
deleter.setPostId(post_id);
deleter.decorate($(element).find('.question-delete'));
});
+ //todo: convert to "control" class
+ var publishBtns = $('.answer-publish, .answer-unpublish');
+ publishBtns.each(function(idx, btn) {
+ setupButtonEventHandlers($(btn), function() {
+ var answerId = $(btn).data('answerId');
+ $.ajax({
+ type: 'POST',
+ dataType: 'json',
+ data: {'answer_id': answerId},
+ url: askbot['urls']['publishAnswer'],
+ success: function(data) {
+ if (data['success']) {
+ window.location.reload(true);
+ } else {
+ showMessage($(btn), data['message']);
+ }
+ }
+ });
+ });
+ });
+
if (askbot['settings']['tagSource'] == 'category-tree') {
var catSelectorLoader = new CategorySelectorLoader();
catSelectorLoader.decorate($('#retag'));
diff --git a/askbot/skins/common/templates/question/answer_controls.html b/askbot/skins/common/templates/question/answer_controls.html
index 21d12dd6..4efc7247 100644
--- a/askbot/skins/common/templates/question/answer_controls.html
+++ b/askbot/skins/common/templates/question/answer_controls.html
@@ -9,26 +9,20 @@
</a>
</span>
<span
+ id="post-{{answer.id}}-publish"
class="action-link"
- id="answer-publish-{{ answer.id }}"
+>
{% if answer.id in published_answer_ids %}
- title="{% trans %}unpublish{% endtrans %}"
+ <a
+ class="answer-unpublish"
+ data-answer-id="{{ answer.id }}"
+ >{% trans %}unpublish{% endtrans %}</a>
{% else %}
- title="{% trans %}publish{% endtrans %}"
+ <a
+ class="answer-publish"
+ data-answer-id="{{ answer.id}}"
+ >{% trans %}publish{% endtrans %}</a>
{% endif %}
->
- <form action="{% url publish_answer %}">{% csrf_token %}
- <input type="hidden" name="answer_id" id="id_answer_id" value="{{answer.id}}"/>
- <input
- type="submit"
- name=""
- {% if answer.id in published_answer_ids %}
- name="{% trans %}unpublish{% endtrans %}"
- {% else %}
- name="{% trans %}publish{% endtrans %}"
- {% endif %}
- />
- </form>
</span>
<span id='post-{{answer.id}}-delete' class="action-link delete-post">
<a class="question-delete"
@@ -69,6 +63,7 @@
</form>
</span>
<script type="text/javascript">
- askbot['functions']['hideConvertAnswerLinks']('{{answer.id}}');
- askbot['functions']['renderPostControls']('{{answer.id}}');
+ askbot['functions']['hideConvertAnswerLinks']('{{ answer.id }}');
+ askbot['functions']['hidePublishAnswerLink']('{{ answer.id }}');
+ askbot['functions']['renderPostControls']('{{ answer.id }}');
</script>
diff --git a/askbot/skins/default/media/images/publish.png b/askbot/skins/default/media/images/publish.png
new file mode 100644
index 00000000..038a87d2
--- /dev/null
+++ b/askbot/skins/default/media/images/publish.png
Binary files differ
diff --git a/askbot/skins/default/media/images/unpublish.png b/askbot/skins/default/media/images/unpublish.png
new file mode 100644
index 00000000..bfac25b1
--- /dev/null
+++ b/askbot/skins/default/media/images/unpublish.png
Binary files differ
diff --git a/askbot/skins/default/media/style/style.less b/askbot/skins/default/media/style/style.less
index f3151cf0..83fd4b9b 100644
--- a/askbot/skins/default/media/style/style.less
+++ b/askbot/skins/default/media/style/style.less
@@ -1964,14 +1964,20 @@ ul#related-tags li {
}
.post-controls, .answer-controls{
.question-delete{
- background: url(../images/delete.png) no-repeat center left;
+ background: url(../images/delete.png) no-repeat left 2px;
padding-left:11px;
}
.question-flag{
background: url(../images/flag.png) no-repeat center left;
}
+ .answer-publish{
+ background: url(../images/publish.png) no-repeat center left;
+ }
+ .answer-unpublish{
+ background: url(../images/unpublish.png) no-repeat 2px center;
+ }
.question-edit{
- background: url(../images/edit2.png) no-repeat center left;
+ background: url(../images/edit2.png) no-repeat 2px center;
}
.question-retag{
background: url(../images/retag.png) no-repeat center left;
diff --git a/askbot/skins/default/templates/question.html b/askbot/skins/default/templates/question.html
index 794853c2..57c71068 100644
--- a/askbot/skins/default/templates/question.html
+++ b/askbot/skins/default/templates/question.html
@@ -14,6 +14,7 @@
<script type="text/javascript">
/*<![CDATA[*/
//below is pure cross-browser javascript, no jQuery
+ askbot['data']['userIsThreadModerator'] = {% if user_is_thread_moderator %}true{% else %}false{% endif %};
(function(){
var data = askbot['data'];
if (data['userIsAuthenticated']){
@@ -59,20 +60,29 @@
var answer_convert_id = 'post-' + post_id + '-convert';
var convert_answer = document.getElementById(answer_convert_id);
if (data['userIsAdminOrMod']){
- var answer_id = 'post-id-' + post_id;
- var answer_container = document.getElementById(answer_id);
- var answer_element= answer_container.getElementsByClassName('answer-body')[0].children[1];
- if (answer_element.textContent.length > 300){
- convert_answer.parentNode.removeChild(convert_answer);
- }
+ var answer_id = 'post-id-' + post_id;
+ var answer_container = document.getElementById(answer_id);
+ var answer_element= answer_container.getElementsByClassName('answer-body')[0].children[1];
+ if (answer_element.textContent.length > 300){
+ convert_answer.parentNode.removeChild(convert_answer);
+ }
} else{
- convert_answer.parentNode.removeChild(convert_answer);
+ convert_answer.parentNode.removeChild(convert_answer);
+ }
+ }
+
+ function hidePublishAnswerLink(postId) {
+ if (data['userIsThreadModerator'] === false) {
+ //hide publish/unpublish answer links
+ var answerId = 'post-' + postId + '-publish';
+ var pubBtn = document.getElementById(answerId);
+ pubBtn.parentNode.removeChild(pubBtn);
}
}
function render_post_controls(post_id){
if (data['userIsAdminOrMod']){
- return;//all functions on
+ return;//all remaining functions stay on
}
if (data['user_posts'] === undefined) {
return;
@@ -189,6 +199,7 @@
askbot['functions']['renderAddAnswerButton'] = render_add_answer_button;
askbot['functions']['hideConvertLinks'] = hide_convert_links;
askbot['functions']['hideConvertAnswerLinks'] = hide_convert_answer_links;
+ askbot['functions']['hidePublishAnswerLink'] = hidePublishAnswerLink;
})();
/*]]>*/
</script>
diff --git a/askbot/skins/default/templates/question/javascript.html b/askbot/skins/default/templates/question/javascript.html
index df81ede2..5dca2522 100644
--- a/askbot/skins/default/templates/question/javascript.html
+++ b/askbot/skins/default/templates/question/javascript.html
@@ -21,6 +21,8 @@
askbot['urls']['delete_post'] = '{% url delete_post %}';
askbot['urls']['get_html_template'] = '{% url get_html_template %}';
askbot['urls']['getGroupsList'] = '{% url get_groups_list %}';
+ askbot['urls']['publishAnswer'] = '{% url publish_answer %}';
+ askbot['data']['userIsThreadModerator'] = {% if user_is_thread_moderator %}true{% else %}false{% endif %};
askbot['messages']['addComment'] = '{% trans %}post a comment{% endtrans %}';
{% if settings.SAVE_COMMENT_ON_ENTER %}
askbot['settings']['saveCommentOnEnter'] = true;
diff --git a/askbot/tests/thread_model_tests.py b/askbot/tests/thread_model_tests.py
index 4e576028..5472216b 100644
--- a/askbot/tests/thread_model_tests.py
+++ b/askbot/tests/thread_model_tests.py
@@ -94,7 +94,11 @@ class ThreadModelTestsWithGroupsEnabled(AskbotTestCase):
#publish the answer
self.client.login(user_id=self.admin.id, method='force')
- self.client.post(reverse('publish_answer'), data={'answer_id': answer.id})
+ self.client.post(
+ reverse('publish_answer'),
+ data={'answer_id': answer.id},
+ HTTP_X_REQUESTED_WITH='XMLHttpRequest'
+ )
#todo: test redirect
answer = self.reload_object(answer)
diff --git a/askbot/views/commands.py b/askbot/views/commands.py
index 2ed12738..bc63277f 100644
--- a/askbot/views/commands.py
+++ b/askbot/views/commands.py
@@ -1380,17 +1380,33 @@ def get_editor(request):
}
return HttpResponse(simplejson.dumps(data), mimetype='application/json')
+@csrf.csrf_exempt
+@decorators.ajax_only
@decorators.post_only
def publish_answer(request):
"""will publish or unpublish answer, if
current thread is moderated
"""
+ denied_msg = _('Sorry, only thread moderators can use this function')
+ if request.user.is_authenticated():
+ if request.user.is_administrator_or_moderator() is False:
+ raise exceptions.PermissionDenied(denied_msg)
#todo: assert permission
answer_id = IntegerField().clean(request.POST['answer_id'])
answer = models.Post.objects.get(id=answer_id, post_type='answer')
+
+ if answer.thread.has_moderator(request.user) is False:
+ raise exceptions.PermissionDenied(denied_msg)
+
enquirer = answer.thread._question_post().author
enquirer_group = enquirer.get_personal_group()
- answer.add_to_groups([enquirer_group])
- #todo: notify enquirer by email about the post
- request.user.message_set.create(message='The answer is published, thank you.')
- return HttpResponseRedirect(answer.get_absolute_url())
+
+ if answer.has_group(enquirer_group):
+ message = _('The answer is now unpublished')
+ answer.remove_from_groups([enquirer_group])
+ else:
+ answer.add_to_groups([enquirer_group])
+ message = _('The answer is now published')
+ #todo: notify enquirer by email about the post
+ request.user.message_set.create(message=message)
+ return {'redirect_url': answer.get_absolute_url()}
diff --git a/askbot/views/readers.py b/askbot/views/readers.py
index 3e3eca39..c2391cab 100644
--- a/askbot/views/readers.py
+++ b/askbot/views/readers.py
@@ -573,6 +573,7 @@ def question(request, id):#refactor - long subroutine. display question body, an
'question' : question_post,
'thread': thread,
'thread_is_moderated': thread.is_moderated(),
+ 'user_is_thread_moderator': thread.has_moderator(request.user),
'published_answer_ids': published_answer_ids,
'answer' : answer_form,
'answers' : page_objects.object_list,