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
 
  16     def __init__(self, question):
 
  17         self.question = question
 
  20     def log_activity(self, activity):
 
  21         self.records.append(activity)
 
  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"]
 
  28         accepted = [a for a in activity if a.activity_type == "accept_answer"]
 
  31             accepted = accepted[-1:][0]
 
  42 class Command(NoArgsCommand):
 
  43     def handle_noargs(self, **options):
 
  45             translation.activate(settings.LANGUAGE_CODE)
 
  47             logging.error("Unable to set the locale in the send emails cron job")
 
  49         digest_control = EMAIL_DIGEST_CONTROL.value
 
  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),
 
  57         self.send_digest('daily', 'd', digest_control.value['LAST_DAILY'])
 
  58         digest_control.value['LAST_DAILY'] = datetime.now()
 
  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()
 
  64         EMAIL_DIGEST_CONTROL.set_value(digest_control)
 
  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)
 
  71         digest_subject = settings.EMAIL_SUBJECT_PREFIX + _('Daily digest')
 
  73         users = User.objects.filter(subscription_settings__enable_notifications=True)
 
  83             if u.subscription_settings.member_joins == char_in_db:
 
  84                 context['new_users'] = new_users
 
  86                 context['new_users'] = False
 
  88             if u.subscription_settings.subscribed_questions == char_in_db:
 
  89                 activity_in_subscriptions = []
 
  91                 for id, r in question_records.items():
 
  93                         subscription = QuestionSubscription.objects.get(question=r.question, user=u)
 
  95                         record = r.get_activity_since(subscription.last_view)
 
  97                         if not u.subscription_settings.notify_answers:
 
 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
 
 105                                 del record['comments']
 
 107                         if not u.subscription_settings.notify_accepted:
 
 108                             del record['accepted']
 
 110                         if record.get('answers', False) or record.get('comments', False) or record.get('accepted', False
 
 112                             activity_in_subscriptions.append({'question': r.question, 'activity': record})
 
 116                 context['activity_in_subscriptions'] = activity_in_subscriptions
 
 118                 context['activity_in_subscriptions'] = False
 
 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')
 
 127                 context['watched_tags_only'] = True
 
 129                 context['new_questions'] = False
 
 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
 
 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')
 
 142         question_records = {}
 
 145         for activity in all_activity:
 
 147                 question = activity.node.abs_parent
 
 149                 if not question.id in question_records:
 
 150                     question_records[question.id] = QuestionRecord(question)
 
 152                 question_records[question.id].log_activity(activity)
 
 154                 if activity.action_type == "ask":
 
 155                     new_questions.append(question)
 
 159         return new_questions, question_records