diff options
author | Jeremy Kerr <jk@ozlabs.org> | 2011-03-29 22:18:54 +0800 |
---|---|---|
committer | Jeremy Kerr <jk@ozlabs.org> | 2011-04-14 17:24:15 +0800 |
commit | f94d40159168d0811de576328b77fd2a553039af (patch) | |
tree | f3e8b81347f832159462ef51437a49a192eea1e9 /apps/patchwork/utils.py | |
parent | 798a73b8bfb41f742e78e481ab9c961556e117b3 (diff) | |
download | patchwork-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.py | 59 |
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 |