From ba059e520f7f209607bdd9466b768d864d9b4b25 Mon Sep 17 00:00:00 2001 From: Tomasz Zielinski Date: Fri, 9 Dec 2011 14:24:05 +0100 Subject: Tickets 104, 107: Changes to post creation methods to make them use Thread where reasonable --- askbot/models/__init__.py | 25 ++++-- askbot/models/answer.py | 41 ++++----- askbot/models/content.py | 3 +- askbot/models/question.py | 126 ++++++++++++++------------- askbot/tests/on_screen_notification_tests.py | 11 +-- 5 files changed, 107 insertions(+), 99 deletions(-) diff --git a/askbot/models/__init__.py b/askbot/models/__init__.py index 9a9082b5..3ba9825e 100644 --- a/askbot/models/__init__.py +++ b/askbot/models/__init__.py @@ -1273,7 +1273,7 @@ def user_post_question( if timestamp is None: timestamp = datetime.datetime.now() - question = Question.objects.create_new( + thread = Thread.objects.create_new( author = self, title = title, text = body_text, @@ -1282,6 +1282,11 @@ def user_post_question( wiki = wiki, is_anonymous = is_anonymous, ) + question = thread._question() + if question.author != self: + raise ValueError('question.author != self') + question.author = self # HACK: Some tests require that question.author IS exactly the same object as self-user (kind of identity map which Django doesn't provide), + # because they set some attributes for that instance and expect them to be changed also for question.author return question def user_edit_comment(self, comment = None, body_text = None): @@ -1405,13 +1410,13 @@ def user_post_answer( if timestamp is None: timestamp = datetime.datetime.now() answer = Answer.objects.create_new( - question = question, - author = self, - text = body_text, - added_at = timestamp, - email_notify = follow, - wiki = wiki - ) + thread = question.thread, + author = self, + text = body_text, + added_at = timestamp, + email_notify = follow, + wiki = wiki + ) award_badges_signal.send(None, event = 'post_answer', actor = self, @@ -2545,7 +2550,7 @@ def remove_flag_offensive(instance, mark_by, **kwargs): activity.delete() -def record_update_tags(question, tags, user, timestamp, **kwargs): +def record_update_tags(thread, tags, user, timestamp, **kwargs): """ This function sends award badges signal on each updated tag the badges that respond to the 'ta @@ -2558,6 +2563,8 @@ def record_update_tags(question, tags, user, timestamp, **kwargs): timestamp = timestamp ) + question = thread._question() + activity = Activity( user=user, active_at=datetime.datetime.now(), diff --git a/askbot/models/answer.py b/askbot/models/answer.py index 745fc1c0..93ef5edc 100644 --- a/askbot/models/answer.py +++ b/askbot/models/answer.py @@ -5,18 +5,10 @@ from askbot.models import content from askbot import const class AnswerManager(models.Manager): - def create_new( - self, - question=None, - author=None, - added_at=None, - wiki=False, - text='', - email_notify=False - ): - + def create_new(self, thread, author, added_at, text, wiki=False, email_notify=False): + # TODO: Some of this code will go to Post.objects.create_new answer = Answer( - question = question, + question = thread._question(), author = author, added_at = added_at, wiki = wiki, @@ -28,7 +20,7 @@ class AnswerManager(models.Manager): answer.last_edited_at = added_at answer.wikified_at = added_at - answer.parse_and_save(author = author) + answer.parse_and_save(author=author) answer.add_revision( author = author, @@ -37,17 +29,16 @@ class AnswerManager(models.Manager): comment = const.POST_STATUS['default_version'], ) - #update question data - question.thread.set_last_activity(last_activity_at=added_at, last_activity_by=author) - - question.thread.answer_count +=1 - question.thread.save() + #update thread data + thread.set_last_activity(last_activity_at=added_at, last_activity_by=author) + thread.answer_count +=1 + thread.save() #set notification/delete if email_notify: - question.thread.followed_by.add(author) + thread.followed_by.add(author) else: - question.thread.followed_by.remove(author) + thread.followed_by.remove(author) return answer @@ -64,9 +55,13 @@ class Answer(content.Content): class AnonymousAnswer(AnonymousContent): question = models.ForeignKey('Question', related_name='anonymous_answers') - def publish(self,user): + def publish(self, user): added_at = datetime.datetime.now() - Answer.objects.create_new(question=self.question,wiki=self.wiki, - added_at=added_at,text=self.text, - author=user) + Answer.objects.create_new( + thread=self.question.thread, + author=user, + added_at=added_at, + wiki=self.wiki, + text=self.text + ) self.delete() diff --git a/askbot/models/content.py b/askbot/models/content.py index 951ac2ef..1ec11d72 100644 --- a/askbot/models/content.py +++ b/askbot/models/content.py @@ -16,7 +16,6 @@ from askbot import const from askbot.models.meta import Comment, Vote from askbot.models.user import EmailFeedSetting from askbot.models.tag import Tag, MarkedTag, tags_match_some_wildcard -from askbot.models.post import PostRevision from askbot.models.base import parse_post_text, parse_and_save_post from askbot.conf import settings as askbot_settings from askbot import exceptions @@ -756,6 +755,7 @@ class Content(models.Model): comment = const.POST_STATUS['default_version'] else: comment = 'No.%s Revision' % rev_no + from askbot.models.post import PostRevision return PostRevision.objects.create_answer_revision( answer=self, author=author, @@ -782,6 +782,7 @@ class Content(models.Model): else: comment = 'No.%s Revision' % rev_no + from askbot.models.post import PostRevision return PostRevision.objects.create_question_revision( question = self, revision = rev_no, diff --git a/askbot/models/question.py b/askbot/models/question.py index 0e47bcf4..0cff2a89 100644 --- a/askbot/models/question.py +++ b/askbot/models/question.py @@ -68,6 +68,48 @@ class ThreadManager(models.Manager): return '"' + '", "'.join(tag_list) + last_topic + def create(self, *args, **kwargs): + raise NotImplementedError + + def create_new(self, title, author, added_at, wiki, text, tagnames=None, is_anonymous=False): + # TODO: Some of this code will go to Post.objects.create_new + + thread = super(ThreadManager, self).create(title=title, tagnames=tagnames, last_activity_at=added_at, last_activity_by=author) + + question = Question( + thread=thread, + author = author, + added_at = added_at, + wiki = wiki, + is_anonymous = is_anonymous, + #html field is denormalized in .save() call + text = text, + #summary field is denormalized in .save() call + ) + if question.wiki: + #DATED COMMENT + #todo: this is confusing - last_edited_at field + #is used as an indicator whether question has been edited + #but in principle, post creation should count as edit as well + question.last_edited_by = question.author + question.last_edited_at = added_at + question.wikified_at = added_at + + question.parse_and_save(author = author) + + question.add_revision( + author = author, + is_anonymous = is_anonymous, + text = text, + comment = const.POST_STATUS['default_version'], + revised_at = added_at, + ) + + # INFO: Question has to be saved before update_tags() is called + thread.update_tags(tagnames = tagnames, user = author, timestamp = added_at) + + return thread + class Thread(models.Model): title = models.CharField(max_length=300) @@ -210,7 +252,7 @@ class Thread(models.Model): def update_tags(self, tagnames = None, user = None, timestamp = None): """ - Updates Tag associations for a question to match the given + Updates Tag associations for a thread to match the given tagname string. When tags are removed and their use count hits 0 - the tag is @@ -221,9 +263,9 @@ class Thread(models.Model): Tag use counts are recalculated A signal tags updated is sent - """ - thread_question = self._question() + *IMPORTANT*: self._question() has to exist when update_tags() is called! + """ previous_tags = list(self.tags.all()) previous_tagnames = set([tag.name for tag in previous_tags]) @@ -283,7 +325,7 @@ class Thread(models.Model): if modified_tags: Tag.objects.update_use_counts(modified_tags) signals.tags_updated.send(None, - question = thread_question, + thread = self, tags = modified_tags, user = user, timestamp = timestamp @@ -307,9 +349,9 @@ class Thread(models.Model): #thread_question.thread.last_activity_at = retagged_at thread_question.last_edited_by = retagged_by #thread_question.thread.last_activity_by = retagged_by - thread_question.save() + thread_question.save() - # Update the Question's tag associations + # Update the Thread's tag associations self.update_tags(tagnames=tagnames, user=retagged_by, timestamp=retagged_at) # Create a new revision @@ -346,52 +388,9 @@ class Thread(models.Model): class QuestionQuerySet(models.query.QuerySet): - """Custom query set subclass for :class:`~askbot.models.Question` """ - #todo: becomes thread query set - def create_new( - self, - title = None, - author = None, - added_at = None, - wiki = False, - is_anonymous = False, - tagnames = None, - text = None - ): - #todo: some work from this method will go to thread - #and some - merged with the Answer.objects.create_new - - question = Question( - thread=Thread.objects.create(title=title, tagnames=tagnames, last_activity_at=added_at, last_activity_by=author), - author = author, - added_at = added_at, - wiki = wiki, - is_anonymous = is_anonymous, - #html field is denormalized in .save() call - text = text, - #summary field is denormalized in .save() call - ) - if question.wiki: - #DATED COMMENT - #todo: this is confusing - last_edited_at field - #is used as an indicator whether question has been edited - #but in principle, post creation should count as edit as well - question.last_edited_by = question.author - question.last_edited_at = added_at - question.wikified_at = added_at - - question.parse_and_save(author = author) - question.thread.update_tags(tagnames = tagnames, user = author, timestamp = added_at) - - question.add_revision( - author = author, - is_anonymous = is_anonymous, - text = text, - comment = const.POST_STATUS['default_version'], - revised_at = added_at, - ) - return question + Custom query set subclass for :class:`~askbot.models.Question` + """ def get_by_text_query(self, search_query): """returns a query set of questions, @@ -724,7 +723,12 @@ class QuestionManager(BaseQuerySetManager): """chainable custom query set manager for questions """ - #todo: becomes thread manager + def create(self, *args, **kwargs): + raise NotImplementedError + + def create_new(self, *args, **kwargs): + raise NotImplementedError + def get_query_set(self): return QuestionQuerySet(self.model) @@ -784,13 +788,13 @@ class AnonymousQuestion(AnonymousContent): def publish(self,user): added_at = datetime.datetime.now() - Question.objects.create_new( - title = self.title, - added_at = added_at, - author = user, - wiki = self.wiki, - is_anonymous = self.is_anonymous, - tagnames = self.tagnames, - text = self.text, - ) + Thread.objects.create_new( + title = self.title, + added_at = added_at, + author = user, + wiki = self.wiki, + is_anonymous = self.is_anonymous, + tagnames = self.tagnames, + text = self.text, + ) self.delete() diff --git a/askbot/tests/on_screen_notification_tests.py b/askbot/tests/on_screen_notification_tests.py index 0d668542..8fe695c8 100644 --- a/askbot/tests/on_screen_notification_tests.py +++ b/askbot/tests/on_screen_notification_tests.py @@ -98,7 +98,7 @@ class OnScreenUpdateNotificationTests(TestCase): #users 1x work on question, 2x and 3x on the answers #users x4 do not do anyting in the setup code - self.question = models.Question.objects.create_new( + self.thread = models.Thread.objects.create_new( title = 'test question', author = self.u11, added_at = datetime.datetime.now(), @@ -106,6 +106,7 @@ class OnScreenUpdateNotificationTests(TestCase): tagnames = 'test', text = 'hey listen up', ) + self.question = self.thread._question() self.comment12 = self.question.add_comment( user = self.u12, comment = 'comment12' @@ -115,7 +116,7 @@ class OnScreenUpdateNotificationTests(TestCase): comment = 'comment13' ) self.answer1 = models.Answer.objects.create_new( - question = self.question, + thread = self.thread, author = self.u21, added_at = datetime.datetime.now(), text = 'answer1' @@ -129,7 +130,7 @@ class OnScreenUpdateNotificationTests(TestCase): comment = 'comment23' ) self.answer2 = models.Answer.objects.create_new( - question = self.question, + thread = self.thread, author = self.u31, added_at = datetime.datetime.now(), text = 'answer2' @@ -568,7 +569,7 @@ class OnScreenUpdateNotificationTests(TestCase): time.sleep(1) timestamp = datetime.datetime.now() self.answer3 = models.Answer.objects.create_new( - question = self.question, + thread = self.thread, author = self.u11, added_at = timestamp, text = 'answer3' @@ -596,7 +597,7 @@ class OnScreenUpdateNotificationTests(TestCase): time.sleep(1) timestamp = datetime.datetime.now() self.answer3 = models.Answer.objects.create_new( - question = self.question, + thread = self.thread, author = self.u31, added_at = timestamp, text = 'answer4' -- cgit v1.2.3-1-g7c22