]> git.openstreetmap.org Git - osqa.git/blob - forum/subscriptions.py
24479b74ced3819747c45eab84f0a00abefbc798
[osqa.git] / forum / subscriptions.py
1 import os
2 import re
3 import datetime
4 import logging
5 from forum.models import User, Question, Comment, QuestionSubscription, SubscriptionSettings, Answer
6 from forum.utils.mail import send_template_email
7 from django.utils.translation import ugettext as _
8 from forum.actions import AskAction, AnswerAction, CommentAction, AcceptAnswerAction, UserJoinsAction, QuestionViewAction
9 from forum import settings
10 from django.db.models import Q, F
11
12 def create_subscription_if_not_exists(question, user):
13     try:
14         subscription = QuestionSubscription.objects.get(question=question, user=user)
15     except:
16         subscription = QuestionSubscription(question=question, user=user)
17         subscription.save()
18
19 def filter_subscribers(subscribers):
20     subscribers = subscribers.exclude(is_active=False)
21
22     if settings.DONT_NOTIFY_UNVALIDATED:
23         return subscribers.exclude(email_isvalid=False)
24     else:
25         return subscribers
26
27 def question_posted(action, new):
28     question = action.node
29
30     subscribers = User.objects.filter(
31             Q(subscription_settings__enable_notifications=True, subscription_settings__new_question='i') |
32             (Q(subscription_settings__new_question_watched_tags='i') &
33               Q(marked_tags__name__in=question.tagnames.split(' ')) &
34               Q(tag_selections__reason='good'))
35     ).exclude(id=question.author.id).distinct()
36
37     subscribers = filter_subscribers(subscribers)
38
39     send_template_email(subscribers, "notifications/newquestion.html", {'question': question})
40
41     subscription = QuestionSubscription(question=question, user=question.author)
42     subscription.save()
43
44     new_subscribers = User.objects.filter(
45             Q(subscription_settings__all_questions=True) |
46             Q(subscription_settings__all_questions_watched_tags=True,
47                     marked_tags__name__in=question.tagnames.split(' '),
48                     tag_selections__reason='good'))
49
50     for user in new_subscribers:
51         create_subscription_if_not_exists(question, user)
52
53 AskAction.hook(question_posted)
54
55
56 def answer_posted(action, new):
57     answer = action.node
58     question = answer.question
59
60     subscribers = question.subscribers.filter(
61             subscription_settings__enable_notifications=True,
62             subscription_settings__notify_answers=True,
63             subscription_settings__subscribed_questions='i'
64     ).exclude(id=answer.author.id).distinct()
65
66     subscribers = filter_subscribers(subscribers)
67
68     send_template_email(subscribers, "notifications/newanswer.html", {'answer': answer})
69
70     create_subscription_if_not_exists(question, answer.author)
71
72 AnswerAction.hook(answer_posted)
73
74
75 def comment_posted(action, new):
76     comment = action.node
77     post = comment.parent
78
79     if post.__class__ == Question:
80         question = post
81     else:
82         question = post.question
83
84     q_filter = Q(subscription_settings__notify_comments=True) | Q(subscription_settings__notify_comments_own_post=True, id=post.author.id)
85
86     inreply = re.search('@\w+', comment.comment)
87     if inreply is not None:
88         q_filter = q_filter | Q(subscription_settings__notify_reply_to_comments=True,
89                                 username__istartswith=inreply.group(0)[1:],
90                                 nodes__parent=post, nodes__node_type="comment")
91
92     subscribers = question.subscribers.filter(
93             q_filter, subscription_settings__subscribed_questions='i', subscription_settings__enable_notifications=True
94     ).exclude(id=comment.user.id).distinct()
95
96     subscribers = filter_subscribers(subscribers)
97
98
99     send_template_email(subscribers, "notifications/newcomment.html", {'comment': comment})
100
101     create_subscription_if_not_exists(question, comment.user)
102
103 CommentAction.hook(comment_posted)
104
105
106 def answer_accepted(action, new):
107     question = action.node.question
108
109     subscribers = question.subscribers.filter(
110             subscription_settings__enable_notifications=True,
111             subscription_settings__subscribed_questions='i'
112     ).exclude(id=action.node.nstate.accepted.by.id).distinct()
113     
114     subscribers = filter_subscribers(subscribers)
115
116     send_template_email(subscribers, "notifications/answeraccepted.html", {'answer': action.node})
117
118 AcceptAnswerAction.hook(answer_accepted)
119
120
121 def member_joined(action, new):
122     subscribers = User.objects.filter(
123             subscription_settings__enable_notifications=True,
124             subscription_settings__member_joins='i'
125     ).exclude(id=action.user.id).distinct()
126
127     subscribers = filter_subscribers(subscribers)
128
129     send_template_email(subscribers, "notifications/newmember.html", {'newmember': action.user})
130
131 UserJoinsAction.hook(member_joined)
132
133 def question_viewed(action, new):
134     if not action.viewuser.is_authenticated():
135         return
136
137     try:
138         subscription = QuestionSubscription.objects.get(question=action.node, user=action.viewuser)
139         subscription.last_view = datetime.datetime.now()
140         subscription.save()
141     except:
142         if action.viewuser.subscription_settings.questions_viewed:
143             subscription = QuestionSubscription(question=action.node, user=action.viewuser)
144             subscription.save()
145
146 QuestionViewAction.hook(question_viewed)
147
148
149 #todo: translate this
150 #record_answer_event_re = re.compile("You have received (a|\d+) .*new response.*")
151 #def record_answer_event(instance, created, **kwargs):
152 #    if created:
153 #        q_author = instance.question.author
154 #        found_match = False
155 #        #print 'going through %d messages' % q_author.message_set.all().count()
156 #        for m in q_author.message_set.all():
157 ##            #print m.message
158 # #           match = record_answer_event_re.search(m.message)
159 #            if match:
160 #                found_match = True
161 #                try:
162 #                    cnt = int(match.group(1))
163 #                except:
164 #                    cnt = 1
165 ##                m.message = u"You have received %d <a href=\"%s?sort=responses\">new responses</a>."\
166 # #                           % (cnt+1, q_author.get_profile_url())
167 #
168 #                m.save()
169 #                break
170 #        if not found_match:
171 #            msg = u"You have received a <a href=\"%s?sort=responses\">new response</a>."\
172 #                    % q_author.get_profile_url()
173 #
174 #            q_author.message_set.create(message=msg)
175 #
176 #post_save.connect(record_answer_event, sender=Answer)