From patchwork Fri Mar 11 12:08:05 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Finucane X-Patchwork-Id: 596181 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id DA58E140144 for ; Fri, 11 Mar 2016 23:08:33 +1100 (AEDT) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id C180B1A0312 for ; Fri, 11 Mar 2016 23:08:33 +1100 (AEDT) X-Original-To: patchwork@lists.ozlabs.org Delivered-To: patchwork@lists.ozlabs.org Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by lists.ozlabs.org (Postfix) with ESMTP id 6B4A71A0007 for ; Fri, 11 Mar 2016 23:08:28 +1100 (AEDT) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga103.jf.intel.com with ESMTP; 11 Mar 2016 04:08:25 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.24,320,1455004800"; d="scan'208";a="931713241" Received: from irvmail001.ir.intel.com ([163.33.26.43]) by orsmga002.jf.intel.com with ESMTP; 11 Mar 2016 04:08:23 -0800 Received: from sivswdev01.ir.intel.com (sivswdev01.ir.intel.com [10.237.217.45]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id u2BC8MTb023628; Fri, 11 Mar 2016 12:08:22 GMT Received: from sivswdev01.ir.intel.com (localhost [127.0.0.1]) by sivswdev01.ir.intel.com with ESMTP id u2BC8MSo005060; Fri, 11 Mar 2016 12:08:22 GMT Received: (from sfinucan@localhost) by sivswdev01.ir.intel.com with id u2BC8Mjq005056; Fri, 11 Mar 2016 12:08:22 GMT From: Stephen Finucane To: patchwork@lists.ozlabs.org Subject: [PATCH 01/13] utils: Rework how notifications are selected Date: Fri, 11 Mar 2016 12:08:05 +0000 Message-Id: <1457698097-3264-2-git-send-email-stephen.finucane@intel.com> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1457698097-3264-1-git-send-email-stephen.finucane@intel.com> References: <1457698097-3264-1-git-send-email-stephen.finucane@intel.com> X-BeenThere: patchwork@lists.ozlabs.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Patchwork development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: patchwork-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Patchwork" The current method of filtering valid patches from invalid ones is effective, but incompatible with forthcoming rework that splits the 'Patch' model into two models. Rework this, removing the soon-to-be non-existant 'User.patch' reference. Signed-off-by: Stephen Finucane --- patchwork/utils.py | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/patchwork/utils.py b/patchwork/utils.py index 62ffc3a..4ca5642 100644 --- a/patchwork/utils.py +++ b/patchwork/utils.py @@ -26,7 +26,7 @@ from django.conf import settings from django.contrib.auth.models import User from django.contrib.sites.models import Site from django.core.mail import EmailMessage -from django.db.models import Max, Q, F +from django.db.models import Count, Q, F from django.template.loader import render_to_string from patchwork.models import (PatchChangeNotification, EmailOptout, @@ -37,14 +37,16 @@ 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) + # We delay sending notifications to a user if they have other + # notifications that are still in the "pending" state. To do this, + # we compare the total number of patch change notifications queued + # for each user against the number of "ready" notifications. + qs = PatchChangeNotification.objects.all() + qs2 = PatchChangeNotification.objects\ + .filter(last_modified__lt=date_limit)\ + .values('patch__submitter')\ + .annotate(count=Count('patch__submitter')) + qs2 = {elem['patch__submitter']: elem['count'] for elem in qs2} groups = itertools.groupby(qs.order_by('patch__submitter'), lambda n: n.patch.submitter) @@ -53,6 +55,10 @@ def send_notifications(): for (recipient, notifications) in groups: notifications = list(notifications) + + if recipient.id not in qs2 or qs2[recipient.id] < len(notifications): + continue + projects = set([n.patch.project.linkname for n in notifications]) def delete_notifications():