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