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