diff options
author | Evgeny Fadeev <evgeny.fadeev@gmail.com> | 2012-09-13 11:29:06 -0400 |
---|---|---|
committer | Evgeny Fadeev <evgeny.fadeev@gmail.com> | 2012-09-13 11:29:06 -0400 |
commit | 32c8811baba52f22e08d954d97dfc45ec20602d4 (patch) | |
tree | 1e173e2e815a2b8bba1e2bb751aa378da22b4177 | |
parent | c2587287e11a31ced679e7127af2b204ce559abd (diff) | |
download | askbot-32c8811baba52f22e08d954d97dfc45ec20602d4.tar.gz askbot-32c8811baba52f22e08d954d97dfc45ec20602d4.tar.bz2 askbot-32c8811baba52f22e08d954d97dfc45ec20602d4.zip |
answer publishing seems to work fully
-rw-r--r-- | askbot/models/post.py | 4 | ||||
-rw-r--r-- | askbot/models/question.py | 17 | ||||
-rw-r--r-- | askbot/skins/common/media/js/post.js | 21 | ||||
-rw-r--r-- | askbot/skins/common/templates/question/answer_controls.html | 31 | ||||
-rw-r--r-- | askbot/skins/default/media/images/publish.png | bin | 0 -> 282 bytes | |||
-rw-r--r-- | askbot/skins/default/media/images/unpublish.png | bin | 0 -> 294 bytes | |||
-rw-r--r-- | askbot/skins/default/media/style/style.less | 10 | ||||
-rw-r--r-- | askbot/skins/default/templates/question.html | 27 | ||||
-rw-r--r-- | askbot/skins/default/templates/question/javascript.html | 2 | ||||
-rw-r--r-- | askbot/tests/thread_model_tests.py | 6 | ||||
-rw-r--r-- | askbot/views/commands.py | 24 | ||||
-rw-r--r-- | askbot/views/readers.py | 1 |
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 Binary files differnew file mode 100644 index 00000000..038a87d2 --- /dev/null +++ b/askbot/skins/default/media/images/publish.png diff --git a/askbot/skins/default/media/images/unpublish.png b/askbot/skins/default/media/images/unpublish.png Binary files differnew file mode 100644 index 00000000..bfac25b1 --- /dev/null +++ b/askbot/skins/default/media/images/unpublish.png 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, |