]> git.openstreetmap.org Git - osqa.git/blob - forum/modules/template_loader.py/forum/management/commands/send_email_alerts.py
85b83fae6e9be646e61dd266886454e7b4877893
[osqa.git] / forum / modules / template_loader.py / forum / management / commands / send_email_alerts.py
1 import datetime
2 from forum.models import *
3 from forum import settings
4 from django.db import models
5 from forum.utils.mail import send_template_email
6 from django.core.management.base import NoArgsCommand
7 from forum.settings.email import EMAIL_DIGEST_FLAG
8 from django.utils import translation
9 import logging
10
11 SHOW_N_MORE_ACTIVE_NEW_MEMBERS = 5
12 SUB_QUESTION_LIST_LENGTH = 5
13 TRY_N_USER_TAGS = 5
14
15
16
17 class DigestQuestionsIndex(object):
18     def __init__(self, from_date):
19         self.from_date = from_date
20
21         new_questions = Question.objects.filter_state(deleted=False).\
22             filter(added_at__gt=from_date).\
23             annotate(n_actions=models.Count('actions')).\
24             annotate(child_count=models.Count('all_children'))
25
26         hotness = lambda q: 3*q.child_count + q.n_actions
27
28         for q in new_questions:
29             q.hotness=hotness(q)
30
31         self.questions = sorted(new_questions, lambda q1, q2: q2.hotness - q1.hotness)
32         self.count = len(self.questions)
33
34     def unseen_question(self, user, question):
35         try:
36             subscription = QuestionSubscription.objects.get(question=q, user=user)
37         except:
38             subscription = None
39
40         return (not subscription) or subscription.last_view < q.last_activity_at
41
42     def get_for_user(self, user):
43         user_tags = list(user.marked_tags.filter(user_selections__reason='good'))
44
45         if len(user_tags) < TRY_N_USER_TAGS:
46             user_tags += list(Tag.objects.filter(models.Q(nodes__author=user) | models.Q(nodes__children__author=user)) \
47                 .annotate(user_tag_usage_count=models.Count('name')).order_by('-user_tag_usage_count')[:TRY_N_USER_TAGS - len(user_tags)])
48
49         user_tag_names = set([t.name for t in user_tags])
50
51
52         subscriptions = user.subscriptions.filter(added_at__lt=self.from_date, last_activity_at__gt=models.F('questionsubscription__last_view')
53                                                   ).order_by('-questionsubscription__last_view')[:SUB_QUESTION_LIST_LENGTH]
54
55         unseen_questions = [q for q in self.questions if self.unseen_question(user, q)]
56
57         interesting = []
58
59         for q in unseen_questions:
60             if len(set(q.tagname_list()) & user_tag_names): interesting.append(q)
61
62
63         may_help = []
64         if len(interesting):
65             if len(interesting) > SUB_QUESTION_LIST_LENGTH:
66                 may_help = interesting[SUB_QUESTION_LIST_LENGTH:][-SUB_QUESTION_LIST_LENGTH:]
67                 interesting = interesting[:SUB_QUESTION_LIST_LENGTH]
68         else:
69             interesting = unseen_questions[:SUB_QUESTION_LIST_LENGTH]
70
71         return {'interesting': interesting, 'may_help': may_help, 'subscriptions': subscriptions}
72
73
74
75
76 class Command(NoArgsCommand):
77     def handle_noargs(self, **options):
78         try:
79             translation.activate(settings.LANGUAGE_CODE)
80         except:
81             logging.error("Unable to set the locale in the send emails cron job")
82
83         digest_control = EMAIL_DIGEST_FLAG.value
84
85         if digest_control is None:
86             digest_control = {
87             'LAST_DAILY': datetime.datetime.now() - datetime.timedelta(days=1),
88             'LAST_WEEKLY': datetime.datetime.now() - datetime.timedelta(days=1),
89             }
90
91         from_date = digest_control['LAST_DAILY']
92         digest_control['LAST_DAILY'] = datetime.datetime.now()
93
94         EMAIL_DIGEST_FLAG.set_value(digest_control)
95
96         users = User.objects.filter(subscription_settings__enable_notifications=True, subscription_settings__send_digest=True)
97         new_members = User.objects.filter(is_active=True, date_joined__gt=from_date).annotate(n_actions=models.Count('actions')).order_by('-n_actions')
98
99         new_member_count = new_members.count()
100
101         if new_member_count >= SHOW_N_MORE_ACTIVE_NEW_MEMBERS:
102             new_members = new_members[:SHOW_N_MORE_ACTIVE_NEW_MEMBERS]
103             show_all_users = True
104         else:
105             show_all_users = False
106
107         digest = DigestQuestionsIndex(from_date)
108
109         if (not new_member_count) and (not digest.count):
110             return
111
112         send_template_email(users, "notifications/digest.html", locals())
113
114