From 0529397a880f5457b3d001f1c1c2bacd30a1a1d7 Mon Sep 17 00:00:00 2001
From: Christophe Henry <contact@c-henry.fr>
Date: Wed, 16 Oct 2019 18:12:01 +0200
Subject: [PATCH] feat: Script deletion of old notifications
 (startinblox/applications/sib-app#228)

---
 README.md                                     | 49 ++++++++++++++++-
 djangoldp_notification/factories.py           |  3 +-
 .../commands/suppress_old_notifications.py    | 52 +++++++++++++++++++
 3 files changed, 102 insertions(+), 2 deletions(-)
 create mode 100644 djangoldp_notification/management/commands/suppress_old_notifications.py

diff --git a/README.md b/README.md
index 965a7e1..a5b0b59 100644
--- a/README.md
+++ b/README.md
@@ -44,4 +44,51 @@ When an object is saved, a notification is created for all the subscriptions rel
 
 ## Send email when new notification
 
-When a notification is created, an email is sent to the user.
\ No newline at end of file
+When a notification is created, an email is sent to the user.
+
+# Django commands
+
+This package also bring a few Django managment command. You can use them 
+at the root of your SIB project.
+
+## `mock_notification`
+
+This lets you create mocked notifications. Useful for develpment.  
+
+Usage:
+
+```
+python3 manage.py mock_notification [--size <number_of_notifications>]
+```
+
+Will create the number of dummy notifications specified by `--size`. 
+By default, 0.
+
+## `suppress_old_notifications`
+
+Will suppress old notification. This is a maintenance command to prevent 
+the server to blow under the weight of your notifications.
+
+Usage:
+
+```
+python3 manage.py mock_notification [--older <time_period>]
+```
+
+This will erase notification older than the time period specified by 
+`--older`. By default, 72h ago. `time_period` is expressed in minutes. 
+`d`, `h` and `m` suffix are also valid to express periods in days, 
+hours and minutes.
+
+Examples:
+
+```shell
+# Default. Will delete notifications older than 72h
+python3 manage.py mock_notification
+# Default. Will delete notifications older than 10 minutes ago
+python3 manage.py mock_notification --older 10
+# Default. Will delete notifications older than 10 days ago
+python3 manage.py mock_notification --older 10d
+# Default. Will delete notifications older than 10 hours ago
+python3 manage.py mock_notification --older 10h
+```
diff --git a/djangoldp_notification/factories.py b/djangoldp_notification/factories.py
index e36dd62..10664b3 100644
--- a/djangoldp_notification/factories.py
+++ b/djangoldp_notification/factories.py
@@ -1,5 +1,6 @@
 import factory
 from django.conf import settings
+from django.apps import apps
 
 from .models import Notification
 from django.db.models.signals import post_save
@@ -12,7 +13,7 @@ class NotificationFactory(factory.django.DjangoModelFactory):
     type = factory.Faker('text', max_nb_chars=50)
     summary = factory.Faker('paragraph', nb_sentences=3, variable_nb_sentences=True)
     author = factory.Faker('url')
-    user = factory.Iterator(settings.AUTH_USER_MODEL.objects.all())
+    user = factory.Iterator(apps.get_model(settings.AUTH_USER_MODEL).objects.all())
     date = factory.Faker('past_datetime')
     unread = factory.Faker('boolean')
     object = factory.Faker('url')
\ No newline at end of file
diff --git a/djangoldp_notification/management/commands/suppress_old_notifications.py b/djangoldp_notification/management/commands/suppress_old_notifications.py
new file mode 100644
index 0000000..d270117
--- /dev/null
+++ b/djangoldp_notification/management/commands/suppress_old_notifications.py
@@ -0,0 +1,52 @@
+from textwrap import dedent
+from datetime import datetime, timedelta
+
+from django.core.management.base import BaseCommand, CommandError
+from djangoldp_notification.models import Notification
+
+
+def _compute_time_limit(timeout):
+    """
+    >>> _compute_time_limit('10')
+    10
+    >>> _compute_time_limit('10h')
+    600
+    >>> _compute_time_limit('10m')
+    10
+    >>> _compute_time_limit('10d')
+    14400
+    """
+    try:
+        if timeout.endswith("d"):
+            return int(timeout[:-1]) * 24 * 60
+        elif timeout.endswith("h"):
+            return int(timeout[:-1]) * 60
+        elif timeout.endswith("m"):
+            return int(timeout[:-1])
+        else:
+            return int(timeout)
+    except ValueError:
+        raise CommandError("--older option is not correct")
+
+
+class Command(BaseCommand):
+    help = "Suppress notifications older than 72h"
+
+    def add_arguments(self, parser):
+        parser.add_argument(
+            "--older",
+            action="store",
+            default="72h",
+            help=dedent(
+                """
+                Set a different time period for notifications to be deleted. Default is 72h
+                This parameters takes a interger value in minutes by default. 'd', 'h' and 'm' suffix also work.
+                Examples: --older 10d, --older 10
+                """
+            ),
+        )
+
+    def handle(self, *args, **options):
+        older_than = _compute_time_limit(options["older"])
+        limit = datetime.today() - timedelta(minutes=older_than)
+        Notification.objects.filter(date__lte=limit).delete()
-- 
GitLab