From 239711ccfac16b6428edc662e0675a9ec18ace51 Mon Sep 17 00:00:00 2001 From: Evgeny Fadeev Date: Wed, 12 Sep 2012 01:33:46 -0400 Subject: moderated response sharing model seems to work internally --- askbot/models/__init__.py | 1 + askbot/models/post.py | 12 +++++++++-- askbot/models/question.py | 41 +++++++++++++++++++++++++++++------ askbot/tests/thread_model_tests.py | 44 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 8 deletions(-) diff --git a/askbot/models/__init__.py b/askbot/models/__init__.py index 9a4121c1..acd279f7 100644 --- a/askbot/models/__init__.py +++ b/askbot/models/__init__.py @@ -1852,6 +1852,7 @@ def user_post_answer( is_private = is_private, by_email = by_email ) + #add to the answerer's group answer_post.add_to_groups([self.get_personal_group()]) answer_post.thread.invalidate_cached_data() diff --git a/askbot/models/post.py b/askbot/models/post.py index 25e51b50..7fac40bc 100644 --- a/askbot/models/post.py +++ b/askbot/models/post.py @@ -220,7 +220,11 @@ class PostManager(BaseQuerySetManager): post.last_edited_at = added_at post.wikified_at = added_at - post.parse_and_save(author=author, is_private = is_private) + #possibly modify the is_private, if one of the groups + #mandates explicit publishing of the posts + is_private = is_private or thread.requires_response_moderation(author) + + post.parse_and_save(author=author, is_private=is_private) post.add_revision( author = author, @@ -507,6 +511,10 @@ class Post(models.Model): self.add_to_groups(groups) elif is_private or group_id: self.make_private(author, group_id = group_id) + elif self.thread_id:#is connected to thread + #inherit privacy scope from thread + thread_groups = self.thread.groups.all() + self.add_to_groups(thread_groups) else: self.make_public() @@ -647,7 +655,7 @@ class Post(models.Model): recipients=notify_sets['for_email'], ) - def make_private(self, user, group_id = None): + def make_private(self, user, group_id=None): """makes post private within user's groups todo: this is a copy-paste in thread and post """ diff --git a/askbot/models/question.py b/askbot/models/question.py index adf8a631..fa5c345a 100644 --- a/askbot/models/question.py +++ b/askbot/models/question.py @@ -146,7 +146,7 @@ class ThreadManager(BaseQuerySetManager): ) author_group = author.get_personal_group() - thread.add_to_groups([author_group]) + thread.add_to_groups([author_group], visibility=ThreadToGroup.SHOW_PUBLISHED_RESPONSES) question.add_to_groups([author_group]) if is_private or group_id:#add groups to thread and question @@ -575,10 +575,19 @@ class Thread(models.Model): def get_groups_shared_with(self, max_count=None): """returns query set of groups with whom thread is shared""" - groups = self.groups.exclude(name__startswith='_internal_') + thread_groups = ThreadToGroup.objects.filter( + models.Q( + thread=self, + visibility=ThreadToGroup.SHOW_ALL_RESPONSES + ) & ~models.Q( + group__name__startswith='_internal_' + ) + ) if max_count: - groups = groups[:max_count] - return groups + thread_groups = thread_groups[:max_count] + + group_ids = thread_groups.values_list('group_id', flat=True) + return Group.objects.filter(id__in=group_ids) def update_favorite_count(self): self.favourite_count = FavoriteQuestion.objects.filter(thread=self).count() @@ -666,6 +675,17 @@ class Thread(models.Model): #use len to cache the queryset return len(self.get_answers_by_user(user)) > 0 + def requires_response_moderation(self, author): + """true, if answers by a given author must be moderated + before publishing to the enquirers""" + author_groups = author.get_groups() + thread_groups = self.get_groups_shared_with() + for group in set(author_groups) & set(thread_groups): + if group.moderate_answers_to_enquirers: + return True + + return False + def tagname_meta_generator(self): return u','.join([unicode(tag) for tag in self.get_tag_names()]) @@ -909,13 +929,22 @@ class Thread(models.Model): tag__id__in=group_ids ).delete() - def add_to_groups(self, groups, recursive=False): + def add_to_groups( + self, groups, visibility=ThreadToGroup.SHOW_ALL_RESPONSES, recursive=False + ): """adds thread to a list of groups ``groups`` argument may be any iterable of groups """ for group in groups: #todo: change to bulk create when django 1.3 goes out of use - ThreadToGroup.objects.get_or_create(thread=self, group=group) + thread_group, created = ThreadToGroup.objects.get_or_create( + thread=self, + group=group + ) + + if thread_group.visibility != visibility: + thread_group.visibility = visibility + thread_group.save() if recursive == True: #comments are taken care of automatically diff --git a/askbot/tests/thread_model_tests.py b/askbot/tests/thread_model_tests.py index 13b32547..c8085655 100644 --- a/askbot/tests/thread_model_tests.py +++ b/askbot/tests/thread_model_tests.py @@ -1,6 +1,7 @@ from askbot.tests.utils import AskbotTestCase from askbot.conf import settings as askbot_settings from askbot import models +from askbot.models.tag import get_global_group import django.core.mail class ThreadModelTestsWithGroupsEnabled(AskbotTestCase): @@ -57,3 +58,46 @@ class ThreadModelTestsWithGroupsEnabled(AskbotTestCase): self.assertEqual(len(django.core.mail.outbox), 1) user = self.reload_object(self.user) self.assertEqual(user.new_response_count, 1) + + def test_answer_to_private_question_is_not_globally_visible(self): + question = self.post_question(user=self.admin, is_private=True) + answer = self.post_answer(question=question, user=self.admin, is_private=False) + global_group = get_global_group() + self.assertEqual( + global_group in set(answer.groups.all()), + False + ) + + def test_answer_to_group_question_is_not_globally_visible(self): + #ask into group where user is not a member + question = self.post_question(user=self.user, group_id=self.group.id) + #answer posted by a group member + answer = self.post_answer(question=question, user=self.admin, is_private=False) + global_group = get_global_group() + self.assertEqual( + global_group in set(answer.groups.all()), + False + ) + + + def test_restrictive_response_publishing(self): + self.group.moderate_answers_to_enquirers = True + self.group.save() + question = self.post_question(user=self.user, group_id=self.group.id) + answer = self.post_answer(question=question, user=self.admin) + + #answer and the user don't have groups in common + answer_groups = set(answer.groups.all()) + user_groups = set(self.user.get_groups()) + self.assertEqual(len(answer_groups & user_groups), 0) + + def test_permissive_response_publishing(self): + self.group.moderate_answers_to_enquirers = False + self.group.save() + question = self.post_question(user=self.user, group_id=self.group.id) + answer = self.post_answer(question=question, user=self.admin) + + #answer and user have one group in common + answer_groups = set(answer.groups.all()) + user_groups = set(self.user.get_groups()) + self.assertEqual(len(answer_groups & user_groups), 1) -- cgit v1.2.3-1-g7c22