From f237fdf287e007d78ecc9996bbb87383cfc8d493 Mon Sep 17 00:00:00 2001 From: Evgeny Fadeev Date: Mon, 9 Aug 2010 19:55:29 -0400 Subject: editing and retagging is under moderation rules --- askbot/auth.py | 38 ---- askbot/models/__init__.py | 142 ++++++++++++- askbot/models/question.py | 13 +- askbot/skins/default/templates/question.html | 10 +- askbot/skins/default/templates/question_retag.html | 5 +- askbot/templatetags/extra_filters.py | 14 +- askbot/tests/permission_assertion_tests.py | 227 +++++++++++++++++++++ askbot/urls.py | 5 + askbot/views/commands.py | 48 ++--- askbot/views/writers.py | 197 ++++++++++-------- 10 files changed, 525 insertions(+), 174 deletions(-) diff --git a/askbot/auth.py b/askbot/auth.py index 33caed13..381143b5 100644 --- a/askbot/auth.py +++ b/askbot/auth.py @@ -18,41 +18,6 @@ import logging from askbot.conf import settings as askbot_settings -def can_retag_questions(user): - """Determines if a User can retag Questions.""" - if user.is_authenticated(): - if user.reputation >= askbot_settings.MIN_REP_TO_RETAG_OTHERS_QUESTIONS: - if user.reputation < askbot_settings.MIN_REP_TO_EDIT_OTHERS_POSTS: - return True - if user.is_superuser: - return True - return False - -def can_edit_post(user, post): - """Determines if a User can edit the given Question or Answer.""" - if user.is_authenticated(): - if user.id == post.author_id: - if user.is_blocked(): - return False - else: - return True - if post.wiki: - if user.reputation >= askbot_settings.MIN_REP_TO_EDIT_WIKI: - return True - if user.reputation >= askbot_settings.MIN_REP_TO_EDIT_OTHERS_POSTS: - return True - if user.is_administrator() or user.is_moderator(): - return True - return False - -def can_close_question(user, question): - """Determines if a User can close the given Question.""" - return user.is_authenticated() and ( - (user.id == question.author_id and - user.reputation >= askbot_settings.MIN_REP_TO_CLOSE_OWN_QUESTIONS) or - user.reputation >= askbot_settings.MIN_REP_TO_CLOSE_OTHERS_QUESTIONS or - user.is_superuser) - def can_lock_posts(user): """Determines if a User can lock Questions or Answers.""" return user.is_authenticated() and ( @@ -71,9 +36,6 @@ def can_accept_answer(user, question, answer): return True return False -def can_view_deleted_post(user, post): - return user.is_superuser - # user preferences view permissions def is_user_self(request_user, target_user): return (request_user.is_authenticated() and request_user == target_user) diff --git a/askbot/models/__init__.py b/askbot/models/__init__.py index cc68939f..316e1a77 100644 --- a/askbot/models/__init__.py +++ b/askbot/models/__init__.py @@ -274,12 +274,40 @@ def user_assert_can_post_comment(self, parent_post = None): return raise e +def user_assert_can_see_deleted_post(self, post = None): + + error_message = _( + 'This post has been deleted and can be seen only ' + \ + 'by post ownwers, site administrators and moderators' + ) + _assert_user_can( + user = self, + post = post, + admin_or_moderator_required = True, + owner_can = True, + general_error_message = error_message + ) + +def user_assert_can_edit_deleted_post(self, post = None): + assert(post.deleted == True) + try: + self.assert_can_see_deleted_post(post) + except django_exceptions.PermissionDenied, e: + error_message = _( + 'Sorry, only moderators, site administrators ' + \ + 'and post owners can edit deleted posts' + ) + raise django_exceptions.PermissionDenied(error_message) def user_assert_can_edit_post(self, post = None): """assertion that raises exceptions.PermissionDenied when user is not authorised to edit this post """ + if post.deleted == True: + self.assert_can_edit_deleted_post(post) + return + blocked_error_message = _( 'Sorry, since your account is blocked ' + \ 'you cannot edit posts' @@ -288,12 +316,20 @@ def user_assert_can_edit_post(self, post = None): 'Sorry, since your account is suspended ' + \ 'you can edit only your own posts' ) - low_rep_error_message = _( - 'Sorry, to edit other people\' posts, a minimum ' + \ - 'reputation of %(min_rep)s is required' - ) % \ - {'min_rep': askbot_settings.MIN_REP_TO_EDIT_OTHERS_POSTS} - min_rep_setting = askbot_settings.MIN_REP_TO_EDIT_OTHERS_POSTS + if post.wiki == True: + low_rep_error_message = _( + 'Sorry, to edit wiki\' posts, a minimum ' + \ + 'reputation of %(min_rep)s is required' + ) % \ + {'min_rep': askbot_settings.MIN_REP_TO_EDIT_WIKI} + min_rep_setting = askbot_settings.MIN_REP_TO_EDIT_WIKI + else: + low_rep_error_message = _( + 'Sorry, to edit other people\' posts, a minimum ' + \ + 'reputation of %(min_rep)s is required' + ) % \ + {'min_rep': askbot_settings.MIN_REP_TO_EDIT_OTHERS_POSTS} + min_rep_setting = askbot_settings.MIN_REP_TO_EDIT_OTHERS_POSTS _assert_user_can( user = self, @@ -305,6 +341,17 @@ def user_assert_can_edit_post(self, post = None): min_rep_setting = min_rep_setting ) + +def user_assert_can_edit_question(self, question = None): + assert(isinstance(question, Question)) + self.assert_can_edit_post(question) + + +def user_assert_can_edit_answer(self, answer = None): + assert(isinstance(answer, Answer)) + self.assert_can_edit_post(answer) + + def user_assert_can_delete_post(self, post = None): if isinstance(post, Question): self.assert_can_delete_question(question = post) @@ -489,7 +536,18 @@ def user_assert_can_flag_offensive(self, post = None): raise django_exceptions.PermissionDenied(flags_exceeded_error_message) -def user_assert_can_retag_questions(self): +def user_assert_can_retag_question(self, question = None): + + if question.deleted == True: + try: + self.assert_can_edit_deleted_post(question) + except django_exceptions.PermissionDenied: + error_message = _( + 'Sorry, only question owners, ' + \ + 'site administrators and moderators ' + \ + 'can retag deleted questions' + ) + raise django_exceptions.PermissionDenied(error_message) blocked_error_message = _( 'Sorry, since your account is blocked ' + \ @@ -503,12 +561,12 @@ def user_assert_can_retag_questions(self): 'Sorry, to retag questions a minimum ' + \ 'reputation of %(min_rep)s is required' ) % \ - {'min_rep': askbot_settings.MIN_REP_TO_RETAG_QUESTIONS} - min_rep_setting = askbot_settings.MIN_REP_TO_RETAG_QUESTIONS + {'min_rep': askbot_settings.MIN_REP_TO_RETAG_OTHERS_QUESTIONS} + min_rep_setting = askbot_settings.MIN_REP_TO_RETAG_OTHERS_QUESTIONS _assert_user_can( user = self, - post = post, + post = question, owner_can = True, blocked_error_message = blocked_error_message, suspended_error_message = suspended_error_message, @@ -596,6 +654,20 @@ def user_post_comment( #print len(Comment.objects.all()) return comment +@auto_now_timestamp +def user_retag_question( + self, + question = None, + tags = None, + timestamp = None, + ): + self.assert_can_retag_question(question) + question.retag( + retagged_by = self, + retagged_at = timestamp, + tagnames = tags, + ) + def user_delete_comment( self, comment = None, @@ -708,6 +780,47 @@ def user_post_question( ) return question +@auto_now_timestamp +def user_edit_question( + self, + question = None, + title = None, + body_text = None, + revision_comment = None, + tags = None, + wiki = False, + timestamp = None + ): + self.assert_can_edit_question(question) + question.apply_edit( + edited_at = timestamp, + edited_by = self, + title = title, + text = body_text, + #todo: summary name clash in question and question revision + comment = revision_comment, + tags = tags, + wiki = wiki, + ) + +@auto_now_timestamp +def user_edit_answer( + self, + answer = None, + body_text = None, + revision_comment = None, + wiki = False, + timestamp = None + ): + self.assert_can_edit_answer(answer) + answer.apply_edit( + edited_at = timestamp, + edited_by = self, + text = body_text, + comment = revision_comment, + wiki = wiki, + ) + def user_is_following(self, followed_item): if isinstance(followed_item, Question): followers = User.objects.filter( @@ -1129,7 +1242,10 @@ User.add_to_class( ) User.add_to_class('get_absolute_url', user_get_absolute_url) User.add_to_class('post_question', user_post_question) +User.add_to_class('edit_question', user_edit_question) +User.add_to_class('retag_question', user_retag_question) User.add_to_class('post_answer', user_post_answer) +User.add_to_class('edit_answer', user_edit_answer) User.add_to_class('post_comment', user_post_comment) User.add_to_class('delete_post', user_delete_post) User.add_to_class('visit_question', user_visit_question) @@ -1174,10 +1290,14 @@ User.add_to_class('assert_can_post_question', user_assert_can_post_question) User.add_to_class('assert_can_post_answer', user_assert_can_post_answer) User.add_to_class('assert_can_post_comment', user_assert_can_post_comment) User.add_to_class('assert_can_edit_post', user_assert_can_edit_post) +User.add_to_class('assert_can_edit_deleted_post', user_assert_can_edit_deleted_post) +User.add_to_class('assert_can_see_deleted_post', user_assert_can_see_deleted_post) +User.add_to_class('assert_can_edit_question', user_assert_can_edit_question) +User.add_to_class('assert_can_edit_answer', user_assert_can_edit_answer) User.add_to_class('assert_can_close_question', user_assert_can_close_question) User.add_to_class('assert_can_reopen_question', user_assert_can_reopen_question) User.add_to_class('assert_can_flag_offensive', user_assert_can_flag_offensive) -User.add_to_class('assert_can_retag_questions', user_assert_can_retag_questions) +User.add_to_class('assert_can_retag_question', user_assert_can_retag_question) #todo: do we need assert_can_delete_post User.add_to_class('assert_can_delete_post', user_assert_can_delete_post) User.add_to_class('assert_can_restore_post', user_assert_can_restore_post) diff --git a/askbot/models/question.py b/askbot/models/question.py index f75b87b6..044f8856 100644 --- a/askbot/models/question.py +++ b/askbot/models/question.py @@ -369,13 +369,14 @@ class Question(content.Content, DeletableContent): self.last_activity_at = retagged_at self.last_edited_by = retagged_by self.last_activity_by = retagged_by + self.save() # Update the Question's tag associations - signals.tags_updated = self.objects.update_tags( - self, - tagnames, - retagged_by - ) + tags_updated = Question.objects.update_tags( + self, + tagnames, + retagged_by + ) # Create a new revision latest_revision = self.get_latest_revision() @@ -388,8 +389,6 @@ class Question(content.Content, DeletableContent): summary = const.POST_STATUS['retagged'], text = latest_revision.text ) - # send tags updated singal - signals.tags_updated.send(sender=Question, question=self) def get_origin_post(self): return self diff --git a/askbot/skins/default/templates/question.html b/askbot/skins/default/templates/question.html index ad24fe6f..cf4acc97 100644 --- a/askbot/skins/default/templates/question.html +++ b/askbot/skins/default/templates/question.html @@ -140,7 +140,15 @@ {% joinitems using '|' %} {% if request.user|can_edit_post:question %} - {% trans 'edit' %} + + {% trans 'edit' %} + + {% else %} + {% if request.user|can_retag_question:question %} + + {% trans 'retag' %} + + {% endif %} {% endif %} {% separator %} {% if question.closed %} diff --git a/askbot/skins/default/templates/question_retag.html b/askbot/skins/default/templates/question_retag.html index 19ee704b..555faccd 100644 --- a/askbot/skins/default/templates/question_retag.html +++ b/askbot/skins/default/templates/question_retag.html @@ -1,6 +1,7 @@ {% extends "base.html" %} {% load extra_tags %} +{% load i18n %} {% block title %}{% spaceless %}{% trans "Change tags" %}{% endspaceless %}{% endblock %} {% block forejs %} @@ -53,7 +54,7 @@
-
+

{{ question.get_question_title }}

@@ -70,7 +71,7 @@
-   +   diff --git a/askbot/templatetags/extra_filters.py b/askbot/templatetags/extra_filters.py index 6cdd87e3..14e3817e 100644 --- a/askbot/templatetags/extra_filters.py +++ b/askbot/templatetags/extra_filters.py @@ -89,13 +89,15 @@ can_reopen_question = make_template_filter_from_permission_assertion( filter_name = 'can_reopen_question' ) -@register.filter -def can_retag_questions(user): - return auth.can_retag_questions(user) +can_edit_post = make_template_filter_from_permission_assertion( + assertion_name = 'assert_can_edit_post', + filter_name = 'can_edit_post' + ) -@register.filter -def can_edit_post(user, post): - return auth.can_edit_post(user, post) +can_retag_question = make_template_filter_from_permission_assertion( + assertion_name = 'assert_can_retag_question', + filter_name = 'can_retag_question' + ) @register.filter def can_see_offensive_flags(user, post): diff --git a/askbot/tests/permission_assertion_tests.py b/askbot/tests/permission_assertion_tests.py index d4c34eb6..65ba6f47 100644 --- a/askbot/tests/permission_assertion_tests.py +++ b/askbot/tests/permission_assertion_tests.py @@ -471,6 +471,233 @@ class ReopenQuestionPermissionAssertionTests(utils.AskbotTestCase): self.other_user.set_status('s') self.assert_cannot_reopen(user = self.other_user) +class EditQuestionPermissionAssertionTests(utils.AskbotTestCase): + + def setUp(self): + self.create_user() + self.create_user(username = 'other_user') + self.post = self.post_question() + self.min_rep = askbot_settings.MIN_REP_TO_EDIT_OTHERS_POSTS + self.min_rep_wiki = askbot_settings.MIN_REP_TO_EDIT_WIKI + + def assert_user_can( + self, + user = None, + ): + if user is None: + user = self.user + + user.assert_can_edit_post(self.post) + self.assertTrue( + template_filters.can_edit_post(user, self.post) + ) + + def assert_user_cannot( + self, + user = None, + ): + if user is None: + user = self.user + + self.assertRaises( + exceptions.PermissionDenied, + user.assert_can_edit_post, + self.post + ) + self.assertFalse( + template_filters.can_edit_post(user, self.post) + ) + + def assert_other_can(self): + self.assert_user_can(user = self.other_user) + + def assert_other_cannot(self): + self.assert_user_cannot(user = self.other_user) + + def test_admin_can_edit(self): + self.other_user.is_superuser = True + self.assert_other_can() + + def test_admin_can_edit_deleted(self): + self.post.deleted = True + self.other_user.is_superuser = True + self.assert_other_can() + + def test_mod_can_edit(self): + self.other_user.set_status('m') + self.assert_other_can() + + def test_low_rep_user_cannot_edit_others_post(self): + assert(self.other_user.reputation < self.min_rep) + self.assert_other_cannot() + + def test_low_rep_user_cannot_edit_others_wiki(self): + self.post.wiki = True + assert(self.other_user.reputation < self.min_rep_wiki) + self.assert_other_cannot() + + def test_low_rep_user_can_edit_own_wiki(self): + self.post.wiki = True + self.assert_user_can() + + def test_medium_rep_user_can_edit_others_wiki(self): + self.post.wiki = True + self.other_user.reputation = self.min_rep_wiki + self.assert_other_can() + + def test_high_rep_user_can_edit_others_post(self): + self.other_user.reputation = self.min_rep + self.assert_other_can() + + #def test_medium_rep_user_can_edit_others_wiki(self): + #def test_low_rep_user_can_edit_own_wiki(self): + #def test_low_rep_user_cannot_edit_others_wiki(self): + #def test_high_rep_blocked_cannot_edit_others_wiki(self): + def test_medium_rep_user_cannot_edit_others_post(self): + self.other_user.reputation = self.min_rep_wiki + self.assert_other_cannot() + + def test_high_rep_user_cannot_edit_others_deleted_post(self): + self.other_user.reputation = self.min_rep + self.post.deleted = True + self.assert_other_cannot() + + def test_high_rep_user_cannot_edit_others_deleted_wiki(self): + self.other_user.reputation = self.min_rep + self.post.deleted = True + self.post.wiki = True + self.assert_other_cannot() + + def test_low_rep_suspended_can_edit_own_post(self): + self.user.set_status('s') + assert(self.user.reputation < self.min_rep) + self.assert_user_can() + + def test_low_rep_suspended_can_edit_own_deleted_post(self): + self.user.set_status('s') + self.post.deleted = True + self.assert_user_can() + + def test_high_rep_suspended_cannot_edit_others_deleted_post(self): + self.other_user.reputation = self.min_rep + self.other_user.set_status('s') + self.post.deleted = True + self.assert_other_cannot() + + def test_high_rep_suspended_cannot_edit_others_post(self): + self.other_user.set_status('s') + self.other_user.reputation = self.min_rep + self.assert_other_cannot() + + def test_high_rep_blocked_cannot_edit_own_post(self): + self.user.set_status('b') + self.user.reputation = self.min_rep + self.assert_user_cannot() + + def test_high_rep_blocked_cannot_edit_others_post(self): + self.user.set_status('b') + self.user.reputation = self.min_rep + self.assert_user_cannot() + + def test_high_rep_blocked_cannot_edit_others_deleted_post(self): + self.other_user.set_status('b') + self.other_user.reputation = self.min_rep + self.post.deleted = True + self.assert_other_cannot() + + def test_high_rep_blocked_cannot_edit_others_wiki(self): + self.other_user.set_status('b') + self.other_user.reputation = self.min_rep + self.post.wiki = True + self.assert_other_cannot() + +class EditAnswerPermissionAssertionTests( + EditQuestionPermissionAssertionTests + ): + def setUp(self): + super( + EditAnswerPermissionAssertionTests, + self, + ).setUp() + self.post = self.post_answer(question = self.post) + + def assert_user_can( + self, + user = None, + ): + if user is None: + user = self.user + + user.assert_can_edit_answer(self.post) + self.assertTrue( + template_filters.can_edit_post(user, self.post) + ) + + def assert_user_cannot( + self, + user = None, + ): + if user is None: + user = self.user + + self.assertRaises( + exceptions.PermissionDenied, + user.assert_can_edit_answer, + self.post + ) + self.assertFalse( + template_filters.can_edit_post(user, self.post) + ) + + +class RetagQuestionPermissionAssertionTests( + EditQuestionPermissionAssertionTests + ): + + def setUp(self): + super( + RetagQuestionPermissionAssertionTests, + self, + ).setUp() + self.min_rep = askbot_settings.MIN_REP_TO_RETAG_OTHERS_QUESTIONS + + def assert_user_can( + self, + user = None, + ): + if user is None: + user = self.user + + user.assert_can_retag_question(self.post) + self.assertTrue( + template_filters.can_retag_question(user, self.post) + ) + + def assert_user_cannot( + self, + user = None, + ): + if user is None: + user = self.user + + self.assertRaises( + exceptions.PermissionDenied, + user.assert_can_retag_question, + self.post + ) + self.assertFalse( + template_filters.can_edit_post(user, self.post) + ) + def test_medium_rep_user_can_edit_others_wiki(self): + pass + def test_low_rep_user_can_edit_own_wiki(self): + pass + def test_low_rep_user_cannot_edit_others_wiki(self): + pass + def test_high_rep_blocked_cannot_edit_others_wiki(self): + pass + def test_medium_rep_user_cannot_edit_others_post(self): + pass class FlagOffensivePermissionAssertionTests(PermissionAssertionTestCase): diff --git a/askbot/urls.py b/askbot/urls.py index 1415d624..974cbf26 100644 --- a/askbot/urls.py +++ b/askbot/urls.py @@ -74,6 +74,11 @@ urlpatterns = patterns('', app.writers.edit_question, name='edit_question' ), + url( + r'^%s(?P\d+)/%s$' % (_('questions/'), _('retag/')), + app.writers.retag_question, + name='retag_question' + ), url( r'^%s(?P\d+)/%s$' % (_('questions/'), _('close/')), app.commands.close, diff --git a/askbot/views/commands.py b/askbot/views/commands.py index ac334a7f..b52bba1d 100644 --- a/askbot/views/commands.py +++ b/askbot/views/commands.py @@ -160,38 +160,38 @@ def vote(request, id): answer = get_object_or_404(Answer, id=answer_id) auth.onAnswerAccept(answer, request.user) else: - raise Exception( + raise exceptions.PermissionDenied( 'Sorry, only question owner can accept the answer' ) else: - raise Exception( + raise exceptions.PermissionDenied( _('Sorry, but anonymous users cannot accept answers') ) elif vote_type in ('1', '2', '5', '6'):#Q&A up/down votes - ############################### - # all this can be avoided with - # better query parameters - vote_direction = 'up' - if vote_type in ('2','6'): - vote_direction = 'down' - - if vote_type in ('5', '6'): - #todo: fix this weirdness - why postId here - #and not with question? - id = request.POST.get('postId') - post = get_object_or_404(Answer, id=id) - else: - post = get_object_or_404(Question, id=id) - # - ###################### - - response_data = process_vote( - user = request.user, - vote_direction = vote_direction, - post = post - ) + ############################### + # all this can be avoided with + # better query parameters + vote_direction = 'up' + if vote_type in ('2','6'): + vote_direction = 'down' + + if vote_type in ('5', '6'): + #todo: fix this weirdness - why postId here + #and not with question? + id = request.POST.get('postId') + post = get_object_or_404(Answer, id=id) + else: + post = get_object_or_404(Question, id=id) + # + ###################### + + response_data = process_vote( + user = request.user, + vote_direction = vote_direction, + post = post + ) elif vote_type in ['7', '8']: #flag question or answer diff --git a/askbot/views/writers.py b/askbot/views/writers.py index 65e58352..8a9e7d80 100644 --- a/askbot/views/writers.py +++ b/askbot/views/writers.py @@ -178,10 +178,11 @@ def ask(request):#view used to ask a new question }, context_instance=RequestContext(request)) @login_required -def edit_question(request, id):#edit or retag a question +def old_edit_question(request, id):#edit or retag a question """view to edit question """ question = get_object_or_404(models.Question, id=id) + if question.deleted and not auth.can_view_deleted_post(request.user, question): raise Http404 if auth.can_edit_post(request.user, question): @@ -191,115 +192,141 @@ def edit_question(request, id):#edit or retag a question else: raise Http404 -def _retag_question(request, question):#non-url subview of edit question - just retag - """retag question sub-view used by - view "edit_question" +@login_required +def retag_question(request, id): + """retag question view """ - if request.method == 'POST': - form = forms.RetagQuestionForm(question, request.POST) - if form.is_valid(): - if form.has_changed(): - question.retag( - retagged_by = request.user, - retagged_at = datetime.datetime.now(), - tagnames = form.cleaned_data['tags'], - ) - return HttpResponseRedirect(question.get_absolute_url()) - else: - form = forms.RetagQuestionForm(question) - return render_to_response('question_retag.html', { - 'active_tab': 'questions', - 'question': question, - 'form' : form, - 'tags' : _get_tags_cache_json(), - }, context_instance=RequestContext(request)) + question = get_object_or_404(models.Question, id = id) + + try: + request.user.assert_can_retag_question(question) + if request.method == 'POST': + form = forms.RetagQuestionForm(question, request.POST) + if form.is_valid(): + if form.has_changed(): + request.user.retag_question( + question = question, + tags = form.cleaned_data['tags'] + ) + return HttpResponseRedirect(question.get_absolute_url()) + else: + form = forms.RetagQuestionForm(question) + return render_to_response('question_retag.html', { + 'active_tab': 'questions', + 'question': question, + 'form' : form, + 'tags' : _get_tags_cache_json(), + }, context_instance=RequestContext(request)) + except exceptions.PermissionDenied, e: + request.user.message_set.create(message = str(e)) + return HttpResponseRedirect(question.get_absolute_url()) -def _edit_question(request, question):#non-url subview of edit_question - just edit the body/title +@login_required +def edit_question(request, id): + """edit question view + """ + question = get_object_or_404(models.Question, id = id) latest_revision = question.get_latest_revision() revision_form = None - if request.method == 'POST': - if 'select_revision' in request.POST:#revert-type edit - # user has changed revistion number - revision_form = forms.RevisionForm(question, latest_revision, request.POST) - if revision_form.is_valid(): - # Replace with those from the selected revision - form = forms.EditQuestionForm(question, - models.QuestionRevision.objects.get(question=question, - revision=revision_form.cleaned_data['revision'])) - else: + try: + request.user.assert_can_edit_question(question) + if request.method == 'POST': + print request.POST + if 'select_revision' in request.POST:#revert-type edit + # user has changed revistion number + revision_form = forms.RevisionForm(question, latest_revision, request.POST) + if revision_form.is_valid(): + # Replace with those from the selected revision + form = forms.EditQuestionForm(question, + models.QuestionRevision.objects.get(question=question, + revision=revision_form.cleaned_data['revision'])) + else: + form = forms.EditQuestionForm(question, latest_revision, request.POST) + else:#new content edit + # Always check modifications against the latest revision form = forms.EditQuestionForm(question, latest_revision, request.POST) - else:#new content edit - # Always check modifications against the latest revision - form = forms.EditQuestionForm(question, latest_revision, request.POST) - if form.is_valid(): - if form.has_changed(): - edited_at = datetime.datetime.now() - edited_by = request.user - question.apply_edit( - edited_at = edited_at, - edited_by = edited_by, - title = form.cleaned_data['title'], - text = form.cleaned_data['text'], - #todo: summary name clash in question and question revision - comment = form.cleaned_data['summary'], - tags = form.cleaned_data['tags'], - wiki = form.cleaned_data.get('wiki',False), - ) + if form.is_valid(): + if form.has_changed(): + request.user.edit_question( + question = question, + title = form.cleaned_data['title'], + body_text = form.cleaned_data['text'], + revision_comment = form.cleaned_data['summary'], + tags = form.cleaned_data['tags'], + wiki = form.cleaned_data['wiki'] + ) + return HttpResponseRedirect(question.get_absolute_url()) + else: + revision_form = forms.RevisionForm(question, latest_revision) + form = forms.EditQuestionForm(question, latest_revision) + + return render_to_response('question_edit.html', { + 'active_tab': 'questions', + 'question': question, + 'revision_form': revision_form, + 'form' : form, + 'tags' : _get_tags_cache_json() + }, context_instance=RequestContext(request)) - return HttpResponseRedirect(question.get_absolute_url()) - else: - revision_form = forms.RevisionForm(question, latest_revision) - form = forms.EditQuestionForm(question, latest_revision) - return render_to_response('question_edit.html', { - 'active_tab': 'questions', - 'question': question, - 'revision_form': revision_form, - 'form' : form, - 'tags' : _get_tags_cache_json() - }, context_instance=RequestContext(request)) + except exceptions.PermissionDenied, e: + request.user.message_set.create(message = str(e)) + return HttpResponseRedirect(question.get_absolute_url()) @login_required def edit_answer(request, id): answer = get_object_or_404(models.Answer, id=id) - if answer.deleted and not auth.can_view_deleted_post(request.user, answer): - raise Http404 - elif not auth.can_edit_post(request.user, answer): - raise Http404 - else: + try: + request.user.assert_can_edit_answer(answer) latest_revision = answer.get_latest_revision() if request.method == "POST": if 'select_revision' in request.POST: # user has changed revistion number - revision_form = forms.RevisionForm(answer, latest_revision, request.POST) + revision_form = forms.RevisionForm( + answer, + latest_revision, + request.POST + ) if revision_form.is_valid(): # Replace with those from the selected revision - form = forms.EditAnswerForm(answer, - models.AnswerRevision.objects.get(answer=answer, - revision=revision_form.cleaned_data['revision'])) + rev = revision_form.cleaned_data['revision'] + selected_revision = models.AnswerRevision.objects.get( + answer = answer, + revision = rev + ) + form = forms.EditAnswerForm(answer, selected_revision) else: - form = forms.EditAnswerForm(answer, latest_revision, request.POST) + form = forms.EditAnswerForm( + answer, + latest_revision, + request.POST + ) else: form = forms.EditAnswerForm(answer, latest_revision, request.POST) if form.is_valid(): if form.has_changed(): - edited_at = datetime.datetime.now() - answer.apply_edit( - edited_at = edited_at, - edited_by = request.user, - text = form.cleaned_data['text'], - comment = form.cleaned_data['summary'], - wiki = False,#todo: fix this there is no "wiki" field on "edit answer" - ) + request.user.edit_answer( + answer = answer, + body_text = form.cleaned_data['text'], + revision_comment = form.cleaned_data['summary'], + wiki = False,#todo: add wiki field to form + ) return HttpResponseRedirect(answer.get_absolute_url()) else: revision_form = forms.RevisionForm(answer, latest_revision) form = forms.EditAnswerForm(answer, latest_revision) - return render_to_response('answer_edit.html', { - 'active_tab': 'questions', - 'answer': answer, - 'revision_form': revision_form, - 'form': form, - }, context_instance=RequestContext(request)) + return render_to_response( + 'answer_edit.html', + { + 'active_tab': 'questions', + 'answer': answer, + 'revision_form': revision_form, + 'form': form, + }, + context_instance=RequestContext(request) + ) + except exceptions.PermissionDenied, e: + request.user.message_set.create(message = str(e)) + return HttpResponseRedirect(answer.get_absolute_url()) #todo: rename this function to post_new_answer def answer(request, id):#process a new answer -- cgit v1.2.3-1-g7c22