[PATCH 2/2] utils: Rename to 'notifications'

Stephen Finucane stephenfinucane at hotmail.com
Fri Sep 2 07:38:54 AEST 2016


Every function in this file is related to notifications. Rename the
file and functions therein to something more meaningful.

Signed-off-by: Stephen Finucane <stephenfinucane at hotmail.com>
---
 patchwork/management/commands/cron.py |   5 +-
 patchwork/notifications.py            | 116 ++++++++++++++++++++++++++++++++++
 patchwork/tests/test_expiry.py        |  10 +--
 patchwork/tests/test_notifications.py |   2 +-
 patchwork/utils.py                    | 113 ---------------------------------
 5 files changed, 125 insertions(+), 121 deletions(-)
 create mode 100644 patchwork/notifications.py
 delete mode 100644 patchwork/utils.py

diff --git a/patchwork/management/commands/cron.py b/patchwork/management/commands/cron.py
index 4272177..e3e906a 100644
--- a/patchwork/management/commands/cron.py
+++ b/patchwork/management/commands/cron.py
@@ -19,7 +19,8 @@
 
 from django.core.management.base import BaseCommand
 
-from patchwork.utils import send_notifications, do_expiry
+from patchwork.notifications import expire_notifications
+from patchwork.notifications import send_notifications
 
 
 class Command(BaseCommand):
@@ -32,4 +33,4 @@ class Command(BaseCommand):
             self.stderr.write("Failed sending to %s: %s" %
                               (recipient.email, error))
 
-        do_expiry()
+        expire_notifications()
diff --git a/patchwork/notifications.py b/patchwork/notifications.py
new file mode 100644
index 0000000..5420401
--- /dev/null
+++ b/patchwork/notifications.py
@@ -0,0 +1,116 @@
+# Patchwork - automated patch tracking system
+# Copyright (C) 2008 Jeremy Kerr <jk at ozlabs.org>
+#
+# This file is part of the Patchwork package.
+#
+# Patchwork is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# Patchwork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Patchwork; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+import datetime
+import itertools
+
+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 Count, Q, F
+
+from patchwork.compat import render_to_string
+from patchwork.models import EmailConfirmation
+from patchwork.models import EmailOptout
+from patchwork.models import PatchChangeNotification
+
+
+def send_notifications():
+    date_limit = datetime.datetime.now() - datetime.timedelta(
+        minutes=settings.NOTIFICATION_DELAY_MINUTES)
+
+    # 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)
+
+    errors = []
+
+    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():
+            pks = [n.pk for n in notifications]
+            PatchChangeNotification.objects.filter(pk__in=pks).delete()
+
+        if EmailOptout.is_optout(recipient.email):
+            delete_notifications()
+            continue
+
+        context = {
+            'site': Site.objects.get_current(),
+            'notifications': notifications,
+            'projects': projects,
+        }
+
+        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.NOTIFICATION_FROM_EMAIL,
+                               to=[recipient.email],
+                               headers={'Precedence': 'bulk'})
+
+        try:
+            message.send()
+        except Exception as ex:
+            errors.append((recipient, ex))
+            continue
+
+        delete_notifications()
+
+    return errors
+
+
+def expire_notifications():
+    """Expire any pending confirmations.
+
+    Users whose registration confirmation has expired are removed.
+    """
+    # expire any invalid confirmations
+    q = (Q(date__lt=datetime.datetime.now() - EmailConfirmation.validity) |
+         Q(active=False))
+    EmailConfirmation.objects.filter(q).delete()
+
+    # remove inactive users with no pending confirmation
+    pending_confs = EmailConfirmation.objects.values('user')
+    users = User.objects.filter(is_active=False,
+                                last_login=F('date_joined')).exclude(
+                                    id__in=pending_confs)
+
+    # delete users
+    users.delete()
diff --git a/patchwork/tests/test_expiry.py b/patchwork/tests/test_expiry.py
index 7622464..054d156 100644
--- a/patchwork/tests/test_expiry.py
+++ b/patchwork/tests/test_expiry.py
@@ -25,9 +25,9 @@ from django.test import TestCase
 from patchwork.models import EmailConfirmation
 from patchwork.models import Patch
 from patchwork.models import Person
+from patchwork.notifications import expire_notifications
 from patchwork.tests.utils import create_patch
 from patchwork.tests.utils import create_user
-from patchwork.utils import do_expiry
 
 
 class TestRegistrationExpiry(TestCase):
@@ -50,7 +50,7 @@ class TestRegistrationExpiry(TestCase):
                 datetime.timedelta(hours=1))
         user, conf = self.register(date)
 
-        do_expiry()
+        expire_notifications()
 
         self.assertFalse(User.objects.filter(pk=user.pk).exists())
         self.assertFalse(
@@ -61,7 +61,7 @@ class TestRegistrationExpiry(TestCase):
                 datetime.timedelta(hours=1))
         user, conf = self.register(date)
 
-        do_expiry()
+        expire_notifications()
 
         self.assertTrue(User.objects.filter(pk=user.pk).exists())
         self.assertTrue(
@@ -75,7 +75,7 @@ class TestRegistrationExpiry(TestCase):
         conf.user.save()
         conf.deactivate()
 
-        do_expiry()
+        expire_notifications()
 
         self.assertTrue(User.objects.filter(pk=user.pk).exists())
         self.assertFalse(
@@ -100,7 +100,7 @@ class TestRegistrationExpiry(TestCase):
         conf.save()
 
         # ... which expires
-        do_expiry()
+        expire_notifications()
 
         # we should see no matching user
         self.assertFalse(User.objects.filter(email=patch.submitter.email)
diff --git a/patchwork/tests/test_notifications.py b/patchwork/tests/test_notifications.py
index 5c426fc..6cd3200 100644
--- a/patchwork/tests/test_notifications.py
+++ b/patchwork/tests/test_notifications.py
@@ -25,11 +25,11 @@ from django.test import TestCase
 
 from patchwork.models import EmailOptout
 from patchwork.models import PatchChangeNotification
+from patchwork.notifications import send_notifications
 from patchwork.tests.utils import create_patch
 from patchwork.tests.utils import create_patches
 from patchwork.tests.utils import create_project
 from patchwork.tests.utils import create_state
-from patchwork.utils import send_notifications
 
 
 class PatchNotificationModelTest(TestCase):
diff --git a/patchwork/utils.py b/patchwork/utils.py
deleted file mode 100644
index b496af4..0000000
--- a/patchwork/utils.py
+++ /dev/null
@@ -1,113 +0,0 @@
-# Patchwork - automated patch tracking system
-# Copyright (C) 2008 Jeremy Kerr <jk at ozlabs.org>
-#
-# This file is part of the Patchwork package.
-#
-# Patchwork is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# Patchwork is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Patchwork; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-from __future__ import absolute_import
-
-import datetime
-import itertools
-
-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 Count, Q, F
-
-from patchwork.compat import render_to_string
-from patchwork.models import (PatchChangeNotification, EmailOptout,
-                              EmailConfirmation)
-
-
-def send_notifications():
-    date_limit = datetime.datetime.now() - datetime.timedelta(
-        minutes=settings.NOTIFICATION_DELAY_MINUTES)
-
-    # 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)
-
-    errors = []
-
-    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():
-            pks = [n.pk for n in notifications]
-            PatchChangeNotification.objects.filter(pk__in=pks).delete()
-
-        if EmailOptout.is_optout(recipient.email):
-            delete_notifications()
-            continue
-
-        context = {
-            'site': Site.objects.get_current(),
-            'notifications': notifications,
-            'projects': projects,
-        }
-
-        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.NOTIFICATION_FROM_EMAIL,
-                               to=[recipient.email],
-                               headers={'Precedence': 'bulk'})
-
-        try:
-            message.send()
-        except Exception as ex:
-            errors.append((recipient, ex))
-            continue
-
-        delete_notifications()
-
-    return errors
-
-
-def do_expiry():
-    # expire any pending confirmations
-    q = (Q(date__lt=datetime.datetime.now() - EmailConfirmation.validity) |
-         Q(active=False))
-    EmailConfirmation.objects.filter(q).delete()
-
-    # expire inactive users with no pending confirmation
-    pending_confs = EmailConfirmation.objects.values('user')
-    users = User.objects.filter(is_active=False,
-                                last_login=F('date_joined')).exclude(
-                                    id__in=pending_confs)
-
-    # delete users
-    users.delete()
-- 
2.7.4



More information about the Patchwork mailing list