From 85c72339a35288f8d310416421318e7897886f6b Mon Sep 17 00:00:00 2001 From: Evgeny Fadeev Date: Fri, 9 Jul 2010 19:22:00 -0400 Subject: email notifications seem to work correctly --- askbot/management/commands/send_email_alerts.py | 11 +- askbot/models/__init__.py | 29 +++- askbot/models/content.py | 14 +- askbot/models/meta.py | 9 ++ .../default/templates/instant_notification.html | 5 +- askbot/tests.py | 159 ++++++++++++++++++--- 6 files changed, 194 insertions(+), 33 deletions(-) diff --git a/askbot/management/commands/send_email_alerts.py b/askbot/management/commands/send_email_alerts.py index ee387d59..a5144d32 100644 --- a/askbot/management/commands/send_email_alerts.py +++ b/askbot/management/commands/send_email_alerts.py @@ -365,14 +365,16 @@ class Command(NoArgsCommand): new_ans = Answer.objects.filter( question=q, - added_at__gt=emailed_at + added_at__gt=emailed_at, + deleted=False, ) new_ans = new_ans.exclude(author=user) meta_data['new_ans'] = len(new_ans) ans_rev = AnswerRevision.objects.filter( - answer__question=q, - revised_at__gt=emailed_at + answer__question = q, + answer__deleted = False, + revised_at__gt = emailed_at ) ans_rev = ans_rev.exclude(author=user) meta_data['ans_rev'] = len(ans_rev) @@ -380,11 +382,14 @@ class Command(NoArgsCommand): comments = meta_data.get('comments', 0) mentions = meta_data.get('mentions', 0) + #print meta_data #finally skip question if there are no news indeed if len(q_rev) + len(new_ans) + len(ans_rev) + comments + mentions == 0: meta_data['skip'] = True + #print 'skipping' else: meta_data['skip'] = False + #print 'not skipping' update_info.active_at = datetime.datetime.now() if DEBUG_THIS_COMMAND == False: update_info.save() #save question email update activity diff --git a/askbot/models/__init__.py b/askbot/models/__init__.py index fe5a3279..555209b2 100644 --- a/askbot/models/__init__.py +++ b/askbot/models/__init__.py @@ -84,6 +84,16 @@ def user_post_comment( #print len(Comment.objects.all()) return comment +def user_delete_post( + self, + post = None, + timestamp = None + ): + if isinstance(post, Comment): + post.delete() + else: + auth.onDeleted(post, self, timestamp = timestamp) + def user_post_question( self, title = None, @@ -111,6 +121,19 @@ def user_post_question( ) return question +def user_is_following(self, followed_item): + if isinstance(followed_item, Question): + followers = User.objects.filter( + id = self.id, + followed_questions = followed_item, + ) + if self in followers: + return True + else: + return False + else: + raise NotImplementedError('function only works for questions so far') + def user_post_answer( self, question = None, @@ -386,6 +409,7 @@ User.add_to_class('get_absolute_url', user_get_absolute_url) User.add_to_class('post_question', user_post_question) User.add_to_class('post_answer', user_post_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) User.add_to_class('upvote', upvote) User.add_to_class('downvote', downvote) @@ -398,6 +422,7 @@ User.add_to_class('delete_messages', delete_messages) User.add_to_class('toggle_favorite_question', toggle_favorite_question) User.add_to_class('follow_question', user_follow_question) User.add_to_class('unfollow_question', user_unfollow_question) +User.add_to_class('is_following', user_is_following) User.add_to_class('decrement_response_count', user_decrement_response_count) User.add_to_class('increment_response_count', user_increment_response_count) @@ -441,7 +466,9 @@ def format_instant_notification_body( 'origin_post_title': origin_post.title, 'user_subscriptions_url': user_subscriptions_url, } - return template.render(Context(update_data)) + output = template.render(Context(update_data)) + #print output + return output #todo: action def send_instant_notifications_about_activity_in_post( diff --git a/askbot/models/content.py b/askbot/models/content.py index 2a14b9d2..57f9ee97 100644 --- a/askbot/models/content.py +++ b/askbot/models/content.py @@ -86,7 +86,10 @@ class Content(models.Model): comment class has it's own variant which does have quite a bit of duplicated code at the moment """ + #print '------------------' + #print 'in content function' subscriber_set = set() + #print 'potential subscribers: ', potential_subscribers #1) mention subscribers - common to questions and answers if mentioned_users: @@ -99,17 +102,18 @@ class Content(models.Model): origin_post = self.get_origin_post() + #print origin_post + #2) individually selected - make sure that users #are individual subscribers to this question selective_subscribers = origin_post.followed_by.all() - #print [s for s in selective_subscribers] + #print 'question followers are ', [s for s in selective_subscribers] if selective_subscribers: selective_subscribers = EmailFeedSetting.filter_subscribers( potential_subscribers = selective_subscribers, feed_type = 'q_sel', frequency = 'i' ) - #print 'selective_subscribers filtereed are ', selective_subscribers for subscriber in selective_subscribers: if origin_post.passes_tag_filter_for_user(subscriber): #print subscriber, ' passes tag filter' @@ -117,6 +121,7 @@ class Content(models.Model): else: #print 'does not pass tag filter' pass + #print 'selective subscribers: ', selective_subscribers #subscriber_set.update(selective_subscribers) @@ -147,12 +152,13 @@ class Content(models.Model): answer_authors.update(authors) if answer_authors: - answer_authors = EmailFeedSetting.filter_subscribers( + answer_subscribers = EmailFeedSetting.filter_subscribers( potential_subscribers = answer_authors, frequency = 'i', feed_type = 'q_ans', ) - subscriber_set.update(answer_authors) + subscriber_set.update(answer_subscribers) + #print 'answer subscribers: ', answer_subscribers #print 'exclude_list is ', exclude_list subscriber_set -= set(exclude_list) diff --git a/askbot/models/meta.py b/askbot/models/meta.py index 7c52ae3c..13ddd803 100644 --- a/askbot/models/meta.py +++ b/askbot/models/meta.py @@ -136,6 +136,8 @@ class Comment(base.MetaContent, base.UserContent): argument potential_subscribers is required as it saves on db hits """ + #print 'in meta function' + #print 'potential subscribers: ', potential_subscribers subscriber_set = set() @@ -154,6 +156,7 @@ class Comment(base.MetaContent, base.UserContent): frequency = 'i' ) subscriber_set.update(comment_subscribers) + #print 'comment subscribers: ', comment_subscribers origin_post = self.get_origin_post() selective_subscribers = origin_post.followed_by.all() @@ -168,16 +171,22 @@ class Comment(base.MetaContent, base.UserContent): subscriber_set.add(subscriber) subscriber_set.update(selective_subscribers) + #print 'selective subscribers: ', selective_subscribers global_subscribers = EmailFeedSetting.filter_subscribers( feed_type = 'q_all', frequency = 'i' ) + #print 'global subscribers: ', global_subscribers subscriber_set.update(global_subscribers) + + #print 'exclude list is: ', exclude_list if exclude_list: subscriber_set -= set(exclude_list) + #print 'final list of subscribers:', subscriber_set + return list(subscriber_set) def get_time_of_last_edit(self): diff --git a/askbot/skins/default/templates/instant_notification.html b/askbot/skins/default/templates/instant_notification.html index db2f5a05..c958c41b 100644 --- a/askbot/skins/default/templates/instant_notification.html +++ b/askbot/skins/default/templates/instant_notification.html @@ -1,7 +1,6 @@ {% load i18n %} {% load smart_if %} {% blocktrans %}

Dear {{receiving_user_name}},

{% endblocktrans %} -

{% if update_type == 'question_comment' %} {% blocktrans %}

{{update_author_name}} left a new comment @@ -22,7 +21,7 @@ for question "{{origin_post_title}}"

{% endif %} {% if update_type == 'new_question' %} {% blocktrans %} -

{{update_author_name}} asked a question +

{{update_author_name}} posted a new question {{origin_post_title}}

{% endblocktrans %} {% endif %} @@ -41,6 +40,6 @@ for question "{{origin_post_title}}"

{% blocktrans %}

Please note - you can easily change -how often you receive these notifications.

+how often you receive these notifications or unsubscribe. Thank you for your interest in our forum!

{% endblocktrans %} {% trans "

Sincerely,
Forum Administrator

" %} diff --git a/askbot/tests.py b/askbot/tests.py index 2c8da060..b68c677f 100644 --- a/askbot/tests.py +++ b/askbot/tests.py @@ -67,8 +67,11 @@ def setup_email_alert_tests(setup_func): #fill out expected result for each test test_object.expected_results['q_ask'] = {'message_count': 0, } + test_object.expected_results['q_ask_delete_answer'] = {'message_count': 0, } test_object.expected_results['question_comment'] = {'message_count': 0, } + test_object.expected_results['question_comment_delete'] = {'message_count': 0, } test_object.expected_results['answer_comment'] = {'message_count': 0, } + test_object.expected_results['answer_delete_comment'] = {'message_count': 0, } test_object.expected_results['mention_in_question'] = {'message_count': 0, } test_object.expected_results['mention_in_answer'] = {'message_count': 0, } test_object.expected_results['question_edit'] = {'message_count': 0, } @@ -263,16 +266,27 @@ class EmailAlertTests(TestCase): question = None, author = None, body_text = 'test answer body', - timestamp = None + timestamp = None, + follow = None,#None - do nothing, True/False - follow/unfollow ): """post answer with dummy content and return it """ if timestamp is None: timestamp = self.setup_timestamp + + if follow is None: + if author.is_following(question): + follow = True + else: + follow = False + elif follow not in (True, False): + raise ValueError('"follow" may be only None, True or False') + return author.post_answer( question = question, body_text = body_text, - timestamp = timestamp + timestamp = timestamp, + follow = follow, ) def check_results(self, test_key = None): @@ -295,10 +309,8 @@ class EmailAlertTests(TestCase): error_message ) - @email_alert_test - def test_answer_comment(self): - """target user posts answer and other user posts a comment - to the answer + def proto_post_answer_comment(self): + """base method for use in some tests """ question = self.post_question( author = self.other_user @@ -307,11 +319,23 @@ class EmailAlertTests(TestCase): question = question, author = self.target_user ) - self.post_comment( + comment = self.post_comment( parent_post = answer, author = self.other_user, ) - self.question = question + return comment + + @email_alert_test + def test_answer_comment(self): + """target user posts answer and other user posts a comment + to the answer + """ + self.proto_post_answer_comment() + + @email_alert_test + def test_answer_delete_comment(self): + comment = self.proto_post_answer_comment() + comment.user.delete_post(comment) @email_alert_test def test_question_edit(self): @@ -350,6 +374,16 @@ class EmailAlertTests(TestCase): ) self.question = question + def proto_question_comment(self): + question = self.post_question( + author = self.target_user, + ) + comment = self.post_comment( + author = self.other_user, + parent_post = question, + ) + return comment + @email_alert_test def test_question_comment(self): """target user posts question other user posts a comment @@ -358,29 +392,44 @@ class EmailAlertTests(TestCase): in the base class user does not receive a notification """ + self.proto_question_comment() + + @email_alert_test + def test_question_comment_delete(self): + """target user posts question other user posts a comment + target user does or does not receive email notification + depending on the setup parameters + + in the base class user does not receive a notification + """ + comment = self.proto_question_comment() + comment.user.delete_post(comment) + + def proto_test_q_ask(self): + """base method for tests that + have name containing q_ask - i.e. target asks other answers + answer is returned + """ question = self.post_question( author = self.target_user, ) - self.post_comment( + answer = self.post_answer( + question = question, author = self.other_user, - parent_post = question, ) - self.question = question + return answer @email_alert_test def test_q_ask(self): """target user posts question other user answer the question """ - question = self.post_question( - author = self.target_user, - ) - answer = self.post_answer( - question = question, - author = self.other_user, - #timestamp = self.setup_timestamp + datetime.timedelta(1) - ) - self.question = question + self.proto_test_q_ask() + + @email_alert_test + def test_q_ask_delete_answer(self): + answer = self.proto_test_q_ask() + self.other_user.delete_post(answer) @email_alert_test def test_q_ans(self): @@ -441,16 +490,55 @@ class WeeklyQAskEmailAlertTests(EmailAlertTests): self.notification_schedule['q_ask'] = 'w' self.setup_timestamp = datetime.datetime.now() - datetime.timedelta(14) self.expected_results['q_ask'] = {'message_count': 1} + self.expected_results['q_ask_delete_answer'] = {'message_count': 0} self.expected_results['question_edit'] = {'message_count': 1, } self.expected_results['answer_edit'] = {'message_count': 1, } + #local tests + self.expected_results['question_edit_reedited_recently'] = \ + {'message_count': 1} + self.expected_results['answer_edit_reedited_recently'] = \ + {'message_count': 1} + + @email_alert_test + def test_question_edit_reedited_recently(self): + question = self.post_question( + author = self.target_user + ) + self.edit_post( + post = question, + author = self.other_user, + ) + self.edit_post( + post = question, + author = self.other_user, + timestamp = datetime.datetime.now() - datetime.timedelta(1) + ) + + @email_alert_test + def test_answer_edit_reedited_recently(self): + question = self.post_question( + author = self.target_user + ) + answer = self.post_answer( + question = question, + author = self.other_user, + ) + self.edit_post( + post = answer, + author = self.other_user, + timestamp = datetime.datetime.now() - datetime.timedelta(1) + ) + class WeeklyMentionsAndCommentsEmailAlertTests(EmailAlertTests): @setup_email_alert_tests def setUp(self): self.notification_schedule['m_and_c'] = 'w' self.setup_timestamp = datetime.datetime.now() - datetime.timedelta(14) self.expected_results['question_comment'] = {'message_count': 1, } + self.expected_results['question_comment_delete'] = {'message_count': 0, } self.expected_results['answer_comment'] = {'message_count': 1, } + self.expected_results['answer_delete_comment'] = {'message_count': 0, } self.expected_results['mention_in_question'] = {'message_count': 1, } self.expected_results['mention_in_answer'] = {'message_count': 1, } @@ -468,6 +556,7 @@ class InstantQAskEmailAlertTests(EmailAlertTests): self.notification_schedule['q_ask'] = 'i' self.setup_timestamp = datetime.datetime.now() - datetime.timedelta(1) self.expected_results['q_ask'] = {'message_count': 1} + self.expected_results['q_ask_delete_answer'] = {'message_count': 1} self.expected_results['question_edit'] = {'message_count': 1, } self.expected_results['answer_edit'] = {'message_count': 1, } @@ -478,8 +567,11 @@ class InstantWholeForumEmailAlertTests(EmailAlertTests): self.setup_timestamp = datetime.datetime.now() - datetime.timedelta(1) self.expected_results['q_ask'] = {'message_count': 1, } + self.expected_results['q_ask_delete_answer'] = {'message_count': 1} self.expected_results['question_comment'] = {'message_count': 1, } + self.expected_results['question_comment_delete'] = {'message_count': 1, } self.expected_results['answer_comment'] = {'message_count': 2, } + self.expected_results['answer_delete_comment'] = {'message_count': 2, } self.expected_results['mention_in_question'] = {'message_count': 1, } self.expected_results['mention_in_answer'] = {'message_count': 2, } self.expected_results['question_edit'] = {'message_count': 1, } @@ -519,8 +611,11 @@ class LiveWeeklySelectedQuestionsEmailAlertTests(EmailAlertTests): self.follow_question = True self.expected_results['q_ask'] = {'message_count': 1, } + self.expected_results['q_ask_delete_answer'] = {'message_count': 0} self.expected_results['question_comment'] = {'message_count': 0, } + self.expected_results['question_comment_delete'] = {'message_count': 0, } self.expected_results['answer_comment'] = {'message_count': 0, } + self.expected_results['answer_delete_comment'] = {'message_count': 0, } self.expected_results['mention_in_question'] = {'message_count': 1, } self.expected_results['mention_in_answer'] = {'message_count': 1, } self.expected_results['question_edit'] = {'message_count': 1, } @@ -540,14 +635,17 @@ class LiveInstantSelectedQuestionsEmailAlertTests(EmailAlertTests): self.follow_question = True self.expected_results['q_ask'] = {'message_count': 1, } + self.expected_results['q_ask_delete_answer'] = {'message_count': 1} self.expected_results['question_comment'] = {'message_count': 1, } + self.expected_results['question_comment_delete'] = {'message_count': 1, } self.expected_results['answer_comment'] = {'message_count': 1, } - self.expected_results['mention_in_question'] = {'message_count': 1, } + self.expected_results['answer_delete_comment'] = {'message_count': 1, } + self.expected_results['mention_in_question'] = {'message_count': 0, } self.expected_results['mention_in_answer'] = {'message_count': 1, } self.expected_results['question_edit'] = {'message_count': 1, } self.expected_results['answer_edit'] = {'message_count': 1, } self.expected_results['question_and_answer_by_target'] = {'message_count': 0, } - self.expected_results['q_ans'] = {'message_count': 1, } + self.expected_results['q_ans'] = {'message_count': 0, } self.expected_results['q_ans_new_answer'] = {'message_count': 1, } class InstantMentionsAndCommentsEmailAlertTests(EmailAlertTests): @@ -556,10 +654,27 @@ class InstantMentionsAndCommentsEmailAlertTests(EmailAlertTests): self.notification_schedule['m_and_c'] = 'i' self.setup_timestamp = datetime.datetime.now() - datetime.timedelta(1) self.expected_results['question_comment'] = {'message_count': 1, } + self.expected_results['question_comment_delete'] = {'message_count': 1, } self.expected_results['answer_comment'] = {'message_count': 1, } + self.expected_results['answer_delete_comment'] = {'message_count': 1, } self.expected_results['mention_in_question'] = {'message_count': 1, } self.expected_results['mention_in_answer'] = {'message_count': 1, } + #specialized local test case + self.expected_results['question_edited_mention_stays'] = {'message_count': 1} + + @email_alert_test + def test_question_edited_mention_stays(self): + question = self.post_question( + author = self.other_user, + body_text = 'hey @target check this one', + ) + self.edit_post( + post = question, + author = self.other_user, + body_text = 'yoyo @target do look here' + ) + class InstantQAnsEmailAlertTests(EmailAlertTests): @setup_email_alert_tests def setUp(self): -- cgit v1.2.3-1-g7c22