]> git.openstreetmap.org Git - osqa.git/blob - forum/management/commands/send_email_alerts.py
Tried to fix OSQA 266, Emails sent from the cron job are not using the website locale.
[osqa.git] / forum / management / commands / send_email_alerts.py
1 from datetime import datetime, timedelta
2 from django.core.management.base import NoArgsCommand
3 from django.utils.translation import ugettext as _
4 from django.template import loader, Context, Template
5 from django.core.mail import EmailMultiAlternatives
6 from django.utils import translation
7 from django.conf import settings
8 from forum import settings
9 from forum.settings.email import EMAIL_DIGEST_CONTROL
10 from forum import actions
11 from forum.models import KeyValue, Action, User, QuestionSubscription
12 from forum.utils.mail import send_email
13 import logging
14
15 class QuestionRecord:
16     def __init__(self, question):
17         self.question = question
18         self.records = []
19
20     def log_activity(self, activity):
21         self.records.append(activity)
22
23     def get_activity_since(self, since):
24         activity = [r for r in self.records if r.action_date > since]
25         answers = [a for a in activity if a.action_type == "answer"]
26         comments = [a for a in activity if a.activity_type == "comment"]
27
28         accepted = [a for a in activity if a.activity_type == "accept_answer"]
29
30         if len(accepted):
31             accepted = accepted[-1:][0]
32         else:
33             accepted = None
34
35         return {
36         'answers': answers,
37         'comments': comments,
38         'accepted': accepted,
39         }
40
41
42 class Command(NoArgsCommand):
43     def handle_noargs(self, **options):
44         try:
45             translation.activate(settings.LANGUAGE_CODE)
46         except:
47             logging.error("Unable to set the locale in the send emails cron job")
48
49         digest_control = EMAIL_DIGEST_CONTROL.value
50
51         if digest_control is None:
52             digest_control = KeyValue(key='DIGEST_CONTROL', value={
53             'LAST_DAILY': datetime.now() - timedelta(days=1),
54             'LAST_WEEKLY': datetime.now() - timedelta(days=1),
55             })
56
57         self.send_digest('daily', 'd', digest_control.value['LAST_DAILY'])
58         digest_control.value['LAST_DAILY'] = datetime.now()
59
60         if digest_control.value['LAST_WEEKLY'] + timedelta(days=7) <= datetime.now():
61             self.send_digest('weekly', 'w', digest_control.value['LAST_WEEKLY'])
62             digest_control.value['LAST_WEEKLY'] = datetime.now()
63
64         EMAIL_DIGEST_CONTROL.set_value(digest_control)
65
66
67     def send_digest(self, name, char_in_db, control_date):
68         new_questions, question_records = self.prepare_activity(control_date)
69         new_users = User.objects.filter(date_joined__gt=control_date)
70
71         digest_subject = settings.EMAIL_SUBJECT_PREFIX + _('Daily digest')
72
73         users = User.objects.filter(subscription_settings__enable_notifications=True)
74
75         msgs = []
76
77         for u in users:
78             context = {
79             'user': u,
80             'digest_type': name,
81             }
82
83             if u.subscription_settings.member_joins == char_in_db:
84                 context['new_users'] = new_users
85             else:
86                 context['new_users'] = False
87
88             if u.subscription_settings.subscribed_questions == char_in_db:
89                 activity_in_subscriptions = []
90
91                 for id, r in question_records.items():
92                     try:
93                         subscription = QuestionSubscription.objects.get(question=r.question, user=u)
94
95                         record = r.get_activity_since(subscription.last_view)
96
97                         if not u.subscription_settings.notify_answers:
98                             del record['answers']
99
100                         if not u.subscription_settings.notify_comments:
101                             if u.subscription_settings.notify_comments_own_post:
102                                 record.comments = [a for a in record.comments if a.user == u]
103                                 record['own_comments_only'] = True
104                             else:
105                                 del record['comments']
106
107                         if not u.subscription_settings.notify_accepted:
108                             del record['accepted']
109
110                         if record.get('answers', False) or record.get('comments', False) or record.get('accepted', False
111                                                                                                        ):
112                             activity_in_subscriptions.append({'question': r.question, 'activity': record})
113                     except:
114                         pass
115
116                 context['activity_in_subscriptions'] = activity_in_subscriptions
117             else:
118                 context['activity_in_subscriptions'] = False
119
120             if u.subscription_settings.new_question == char_in_db:
121                 context['new_questions'] = new_questions
122                 context['watched_tags_only'] = False
123             elif u.subscription_settings.new_question_watched_tags == char_in_db:
124                 context['new_questions'] = [q for q in new_questions if
125                                             q.tags.filter(id__in=u.marked_tags.filter(user_selections__reason='good')
126                                                           ).count() > 0]
127                 context['watched_tags_only'] = True
128             else:
129                 context['new_questions'] = False
130
131             if context['new_users'] or context['activity_in_subscriptions'] or context['new_questions']:
132                 send_email(digest_subject, [(u.username, u.email)], "notifications/digest.html", context, threaded=False
133                            )
134
135
136     def prepare_activity(self, since):
137         all_activity = Action.objects.filter(canceled=False, action_date__gt=since, action_type__in=(
138         actions.AskAction.get_type(), actions.AnswerAction.get_type(),
139         actions.CommentAction.get_type(), actions.AcceptAnswerAction.get_type()
140         )).order_by('action_date')
141
142         question_records = {}
143         new_questions = []
144
145         for activity in all_activity:
146             try:
147                 question = activity.node.abs_parent
148
149                 if not question.id in question_records:
150                     question_records[question.id] = QuestionRecord(question)
151
152                 question_records[question.id].log_activity(activity)
153
154                 if activity.action_type == "ask":
155                     new_questions.append(question)
156             except:
157                 pass
158
159         return new_questions, question_records
160