]> git.openstreetmap.org Git - osqa.git/blob - forum/subscriptions.py
ALteration of the schema to a single content model. As a bonus there is a complete...
[osqa.git] / forum / subscriptions.py
1 import os\r
2 import re\r
3 import datetime\r
4 from forum.models import User, Question, Comment, QuestionSubscription, SubscriptionSettings, Answer\r
5 from forum.models.user import activity_record\r
6 from forum.utils.mail import send_email\r
7 from forum.views.readers import question_view\r
8 from django.utils.translation import ugettext as _\r
9 from django.conf import settings\r
10 from django.db.models import Q, F\r
11 from django.db.models.signals import post_save\r
12 from django.contrib.contenttypes.models import ContentType\r
13 import const\r
14 \r
15 def create_subscription_if_not_exists(question, user):\r
16     try:\r
17         subscription = QuestionSubscription.objects.get(question=question, user=user)\r
18     except:\r
19         subscription = QuestionSubscription(question=question, user=user)\r
20         subscription.save()\r
21 \r
22 def apply_default_filters(queryset, excluded_id):\r
23     return queryset.values('email', 'username').exclude(id=excluded_id)\r
24 \r
25 def create_recipients_dict(usr_list):\r
26     return [(s['username'], s['email'], {'username': s['username']}) for s in usr_list]\r
27 \r
28 def question_posted(instance, created, **kwargs):\r
29     if not created: return\r
30 \r
31     question = instance\r
32 \r
33     subscribers = User.objects.values('email', 'username').filter(\r
34             Q(subscription_settings__enable_notifications=True, subscription_settings__new_question='i') |\r
35             (Q(subscription_settings__new_question_watched_tags='i') &\r
36               Q(marked_tags__name__in=question.tagnames.split(' ')) &\r
37               Q(tag_selections__reason='good'))\r
38     ).exclude(id=question.author.id).distinct()\r
39 \r
40     recipients = create_recipients_dict(subscribers)\r
41 \r
42     send_email(settings.EMAIL_SUBJECT_PREFIX + _("New question on %(app_name)s") % dict(app_name=settings.APP_SHORT_NAME),\r
43                recipients, "notifications/newquestion.html", {\r
44         'question': question,\r
45     })\r
46 \r
47     if question.author.subscription_settings.questions_asked:\r
48         subscription = QuestionSubscription(question=question, user=question.author)\r
49         subscription.save()\r
50 \r
51     new_subscribers = User.objects.filter(\r
52             Q(subscription_settings__all_questions=True) |\r
53             Q(subscription_settings__all_questions_watched_tags=True,\r
54                     marked_tags__name__in=question.tagnames.split(' '),\r
55                     tag_selections__reason='good'))\r
56 \r
57     for user in new_subscribers:\r
58         create_subscription_if_not_exists(question, user)\r
59 \r
60 #post_save.connect(question_posted, sender=Question)\r
61 \r
62 \r
63 def answer_posted(instance, created, **kwargs):\r
64     if not created: return\r
65 \r
66     answer = instance\r
67     question = answer.question\r
68 \r
69     subscribers = question.subscribers.values('email', 'username').filter(\r
70             subscription_settings__enable_notifications=True,\r
71             subscription_settings__notify_answers=True,\r
72             subscription_settings__subscribed_questions='i'\r
73     ).exclude(id=answer.author.id).distinct()\r
74     recipients = create_recipients_dict(subscribers)\r
75 \r
76     send_email(settings.EMAIL_SUBJECT_PREFIX + _("New answer to '%(question_title)s'") % dict(question_title=question.title),\r
77                recipients, "notifications/newanswer.html", {\r
78         'question': question,\r
79         'answer': answer\r
80     })\r
81 \r
82     if answer.author.subscription_settings.questions_answered:\r
83         create_subscription_if_not_exists(question, answer.author)\r
84 \r
85 post_save.connect(answer_posted, sender=Answer)\r
86 \r
87 \r
88 def comment_posted(sender, instance, **kwargs):\r
89     comment = instance.content_object\r
90     post = comment.content_object\r
91 \r
92     if post.__class__ == Question:\r
93         question = post\r
94     else:\r
95         question = post.question\r
96 \r
97     subscribers = question.subscribers.values('email', 'username')\r
98 \r
99     q_filter = Q(subscription_settings__notify_comments=True) | Q(subscription_settings__notify_comments_own_post=True, id=post.author.id)\r
100 \r
101     inreply = re.search('@\w+', comment.comment)\r
102     if inreply is not None:\r
103         q_filter = q_filter | Q(subscription_settings__notify_reply_to_comments=True,\r
104                                 username__istartswith=inreply.group(0)[1:],\r
105                                 comments__object_id=post.id,\r
106                                 comments__content_type=ContentType.objects.get_for_model(post.__class__)\r
107                                 )\r
108 \r
109     subscribers = subscribers.filter(\r
110             q_filter, subscription_settings__subscribed_questions='i', subscription_settings__enable_notifications=True \r
111     ).exclude(id=comment.user.id).distinct()\r
112 \r
113     recipients = create_recipients_dict(subscribers)\r
114 \r
115     send_email(settings.EMAIL_SUBJECT_PREFIX + _("New comment on %(question_title)s") % dict(question_title=question.title),\r
116                recipients, "notifications/newcomment.html", {\r
117                 'comment': comment,\r
118                 'post': post,\r
119                 'question': question,\r
120     })\r
121 \r
122     if comment.user.subscription_settings.questions_commented:\r
123         create_subscription_if_not_exists(question, comment.user)\r
124 \r
125 activity_record.connect(comment_posted, sender=const.TYPE_ACTIVITY_COMMENT_QUESTION, weak=False)\r
126 activity_record.connect(comment_posted, sender=const.TYPE_ACTIVITY_COMMENT_ANSWER, weak=False)\r
127 \r
128 \r
129 def answer_accepted(instance, created, **kwargs):\r
130     if not created and 'accepted' in instance.get_dirty_fields() and instance.accepted:\r
131         question = instance.question\r
132 \r
133         subscribers = question.subscribers.values('email', 'username').filter(\r
134                 subscription_settings__enable_notifications=True,\r
135                 subscription_settings__notify_accepted=True,\r
136                 subscription_settings__subscribed_questions='i'\r
137         ).exclude(id=instance.accepted_by.id).distinct()\r
138         recipients = create_recipients_dict(subscribers)\r
139 \r
140         send_email(settings.EMAIL_SUBJECT_PREFIX + _("An answer to '%(question_title)s' was accepted") % dict(question_title=question.title),\r
141                    recipients, "notifications/answeraccepted.html", {\r
142             'question': question,\r
143             'answer': instance\r
144         })\r
145 \r
146 post_save.connect(answer_accepted, sender=Answer)\r
147 \r
148 \r
149 def member_joined(sender, instance, created, **kwargs):\r
150     if not created:\r
151         return\r
152         \r
153     subscribers = User.objects.values('email', 'username').filter(\r
154             subscription_settings__enable_notifications=True,\r
155             subscription_settings__member_joins='i'\r
156     ).exclude(id=instance.id).distinct()\r
157 \r
158     recipients = create_recipients_dict(subscribers)\r
159 \r
160     send_email(settings.EMAIL_SUBJECT_PREFIX + _("%(username)s is a new member on %(app_name)s") % dict(username=instance.username, app_name=settings.APP_SHORT_NAME),\r
161                recipients, "notifications/newmember.html", {\r
162         'newmember': instance,\r
163     })\r
164 \r
165     sub_settings = SubscriptionSettings(user=instance)\r
166     sub_settings.save()\r
167 \r
168 post_save.connect(member_joined, sender=User, weak=False)\r
169 \r
170 def question_viewed(instance, user, **kwargs):\r
171     if not user.is_authenticated():\r
172         return\r
173         \r
174     try:\r
175         subscription = QuestionSubscription.objects.get(question=instance, user=user)\r
176         subscription.last_view = datetime.datetime.now()\r
177         subscription.save()\r
178     except:\r
179         if user.subscription_settings.questions_viewed:\r
180             subscription = QuestionSubscription(question=instance, user=user)\r
181             subscription.save()\r
182 \r
183 question_view.connect(question_viewed)\r
184 \r
185 #todo: this stuff goes temporarily here\r
186 from forum.models import Award, Answer\r
187 \r
188 def notify_award_message(instance, created, **kwargs):\r
189     if created:\r
190         user = instance.user\r
191 \r
192         msg = (u"Congratulations, you have received a badge '%s'. " \\r
193                 + u"Check out <a href=\"%s\">your profile</a>.") \\r
194                 % (instance.badge.name, user.get_profile_url())\r
195 \r
196         user.message_set.create(message=msg)\r
197 \r
198 post_save.connect(notify_award_message, sender=Award)\r
199 \r
200 #todo: translate this\r
201 record_answer_event_re = re.compile("You have received (a|\d+) .*new response.*")\r
202 def record_answer_event(instance, created, **kwargs):\r
203     if created:\r
204         q_author = instance.question.author\r
205         found_match = False\r
206         #print 'going through %d messages' % q_author.message_set.all().count()\r
207         for m in q_author.message_set.all():\r
208             #print m.message\r
209             match = record_answer_event_re.search(m.message)\r
210             if match:\r
211                 found_match = True\r
212                 try:\r
213                     cnt = int(match.group(1))\r
214                 except:\r
215                     cnt = 1\r
216                 m.message = u"You have received %d <a href=\"%s?sort=responses\">new responses</a>."\\r
217                             % (cnt+1, q_author.get_profile_url())\r
218 \r
219                 m.save()\r
220                 break\r
221         if not found_match:\r
222             msg = u"You have received a <a href=\"%s?sort=responses\">new response</a>."\\r
223                     % q_author.get_profile_url()\r
224 \r
225             q_author.message_set.create(message=msg)\r
226 \r
227 post_save.connect(record_answer_event, sender=Answer)