summaryrefslogtreecommitdiffstats
path: root/apps/patchwork/utils.py
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2011-03-29 22:18:54 +0800
committerJeremy Kerr <jk@ozlabs.org>2011-04-14 17:24:15 +0800
commitf94d40159168d0811de576328b77fd2a553039af (patch)
treef3e8b81347f832159462ef51437a49a192eea1e9 /apps/patchwork/utils.py
parent798a73b8bfb41f742e78e481ab9c961556e117b3 (diff)
downloadpatchwork-f94d40159168d0811de576328b77fd2a553039af.tar.bz2
patchwork-f94d40159168d0811de576328b77fd2a553039af.tar.xz
notifications: Add code to send notifications
Add a function (patchwork.utils.send_notifications) to process the PatchChangeNotification queue. We try to group mail to the same sender, by waiting settings.NOTIFICATION_DELAY_MINUTES to allow other notifications to arrive. Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Diffstat (limited to 'apps/patchwork/utils.py')
-rw-r--r--apps/patchwork/utils.py59
1 files changed, 58 insertions, 1 deletions
diff --git a/apps/patchwork/utils.py b/apps/patchwork/utils.py
index e41ffb6..94b3f53 100644
--- a/apps/patchwork/utils.py
+++ b/apps/patchwork/utils.py
@@ -18,8 +18,17 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-from patchwork.models import Bundle, Project, BundlePatch
+import itertools
+import datetime
from django.shortcuts import get_object_or_404
+from django.template.loader import render_to_string
+from django.contrib.sites.models import Site
+from django.conf import settings
+from django.core.mail import EmailMessage
+from django.db.models import Max
+from patchwork.forms import MultiplePatchForm
+from patchwork.models import Bundle, Project, BundlePatch, UserProfile, \
+ PatchChangeNotification
def get_patch_ids(d, prefix = 'patch_id'):
ids = []
@@ -137,3 +146,51 @@ def set_bundle(user, project, action, data, patches, context):
bundle.save()
return []
+
+def send_notifications():
+ date_limit = datetime.datetime.now() - \
+ datetime.timedelta(minutes =
+ settings.NOTIFICATION_DELAY_MINUTES)
+
+ # This gets funky: we want to filter out any notifications that should
+ # be grouped with other notifications that aren't ready to go out yet. To
+ # do that, we join back onto PatchChangeNotification (PCN -> Patch ->
+ # Person -> Patch -> max(PCN.last_modified)), filtering out any maxima
+ # that are with the date_limit.
+ qs = PatchChangeNotification.objects \
+ .annotate(m = Max('patch__submitter__patch__patchchangenotification'
+ '__last_modified')) \
+ .filter(m__lt = date_limit)
+
+ groups = itertools.groupby(qs.order_by('patch__submitter'),
+ lambda n: n.patch.submitter)
+
+ errors = []
+
+ for (recipient, notifications) in groups:
+ notifications = list(notifications)
+ context = {
+ 'site': Site.objects.get_current(),
+ 'person': recipient,
+ 'notifications': notifications,
+ }
+ subject = render_to_string(
+ 'patchwork/patch-change-notification-subject.text',
+ context).strip()
+ content = render_to_string('patchwork/patch-change-notification.mail',
+ context)
+
+ message = EmailMessage(subject = subject, body = content,
+ from_email = settings.DEFAULT_FROM_EMAIL,
+ to = [recipient.email],
+ headers = {'Precedence': 'bulk'})
+
+ try:
+ message.send()
+ except ex:
+ errors.append((recipient, ex))
+ continue
+
+ PatchChangeNotification.objects.filter(pk__in = notifications).delete()
+
+ return errors