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