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.conf import settings
7 from forum.models import KeyValue, Activity, User, QuestionSubscription
8 from forum.utils.mail import send_email
11 def __init__(self, question):
12 self.question = question
15 def log_activity(self, activity):
16 self.records.append(activity)
18 def get_activity_since(self, since):
19 activity = [r for r in self.records if r.active_at > since]
20 answers = [a for a in activity if a.activity_type == const.TYPE_ACTIVITY_ANSWER]
21 comments = [a for a in activity if a.activity_type in (const.TYPE_ACTIVITY_COMMENT_QUESTION, const.TYPE_ACTIVITY_COMMENT_ANSWER)]
23 accepted = [a for a in activity if a.activity_type == const.TYPE_ACTIVITY_MARK_ANSWER]
26 accepted = accepted[-1:][0]
37 class Command(NoArgsCommand):
38 def handle_noargs(self, **options):
39 digest_control = self.get_digest_control()
41 self.send_digest('daily', 'd', digest_control.value['LAST_DAILY'])
42 digest_control.value['LAST_DAILY'] = datetime.now()
44 if digest_control.value['LAST_WEEKLY'] + timedelta(days=7) <= datetime.now():
45 self.send_digest('weekly', 'w', digest_control.value['LAST_WEEKLY'])
46 digest_control.value['LAST_WEEKLY'] = datetime.now()
51 def send_digest(self, name, char_in_db, control_date):
52 new_questions, question_records = self.prepare_activity(control_date)
53 new_users = User.objects.filter(date_joined__gt=control_date)
55 digest_subject = settings.EMAIL_SUBJECT_PREFIX + _('Daily digest')
57 users = User.objects.filter(subscription_settings__enable_notifications=True)
67 if u.subscription_settings.member_joins == char_in_db:
68 context['new_users'] = new_users
70 context['new_users'] = False
72 if u.subscription_settings.subscribed_questions == char_in_db:
73 activity_in_subscriptions = []
75 for id, r in question_records.items():
77 subscription = QuestionSubscription.objects.get(question=r.question, user=u)
79 record = r.get_activity_since(subscription.last_view)
81 if not u.subscription_settings.notify_answers:
84 if not u.subscription_settings.notify_comments:
85 if u.subscription_settings.notify_comments_own_post:
86 record.comments = [a for a in record.comments if a.content_object.content_object.author == u]
87 record['own_comments_only'] = True
89 del record['comments']
91 if not u.subscription_settings.notify_accepted:
92 del record['accepted']
94 if record.get('answers', False) or record.get('comments', False) or record.get('accepted', False):
95 activity_in_subscriptions.append({'question': r.question, 'activity': record})
99 context['activity_in_subscriptions'] = activity_in_subscriptions
101 context['activity_in_subscriptions'] = False
104 if u.subscription_settings.new_question == char_in_db:
105 context['new_questions'] = new_questions
106 context['watched_tags_only'] = False
107 elif u.subscription_settings.new_question_watched_tags == char_in_db:
108 context['new_questions'] = [q for q in new_questions if
109 q.tags.filter(id__in=u.marked_tags.filter(user_selections__reason='good')).count() > 0]
110 context['watched_tags_only'] = True
112 context['new_questions'] = False
114 if context['new_users'] or context['activity_in_subscriptions'] or context['new_questions']:
115 send_email(digest_subject, (u.username, u.email), "notifications/digest.html", context, threaded=False)
118 def get_digest_control(self):
120 digest_control = KeyValue.objects.get(key='DIGEST_CONTROL')
122 digest_control = KeyValue(key='DIGEST_CONTROL', value={
123 'LAST_DAILY': datetime.now() - timedelta(days=1),
124 'LAST_WEEKLY': datetime.now() - timedelta(days=1),
127 return digest_control
129 def prepare_activity(self, since):
130 all_activity = Activity.objects.filter(active_at__gt=since, activity_type__in=(
131 const.TYPE_ACTIVITY_ASK_QUESTION, const.TYPE_ACTIVITY_ANSWER,
132 const.TYPE_ACTIVITY_COMMENT_QUESTION, const.TYPE_ACTIVITY_COMMENT_ANSWER,
133 const.TYPE_ACTIVITY_MARK_ANSWER
134 )).order_by('active_at')
136 question_records = {}
140 for activity in all_activity:
142 question = self.get_question_for_activity(activity)
144 if not question.id in question_records:
145 question_records[question.id] = QuestionRecord(question)
147 question_records[question.id].log_activity(activity)
149 if activity.activity_type == const.TYPE_ACTIVITY_ASK_QUESTION:
150 new_questions.append(question)
154 return new_questions, question_records
156 def get_question_for_activity(self, activity):
157 if activity.activity_type == const.TYPE_ACTIVITY_ASK_QUESTION:
158 question = activity.content_object
159 elif activity.activity_type == const.TYPE_ACTIVITY_ANSWER:
160 question = activity.content_object.question
161 elif activity.activity_type == const.TYPE_ACTIVITY_COMMENT_QUESTION:
162 question = activity.content_object.content_object
163 elif activity.activity_type == const.TYPE_ACTIVITY_COMMENT_ANSWER:
164 question = activity.content_object.content_object.question
165 elif activity.activity_type == const.TYPE_ACTIVITY_MARK_ANSWER:
166 question = activity.content_object.question