From 340f8c9e81a26731d96c188b79b71401fab5c4f2 Mon Sep 17 00:00:00 2001 From: "madjid.asa" Date: Thu, 28 Dec 2023 18:04:02 +0100 Subject: [PATCH 1/4] add method in query set to have outdated conv --- lemarche/conversations/models.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lemarche/conversations/models.py b/lemarche/conversations/models.py index a9b9e004a..8e2699650 100644 --- a/lemarche/conversations/models.py +++ b/lemarche/conversations/models.py @@ -1,3 +1,4 @@ +from datetime import timedelta from uuid import uuid4 from django.conf import settings @@ -33,6 +34,14 @@ def get_conv_from_uuid(self, conv_uuid: str, version=1): else: return self.get(Q(sender_encoded__endswith=conv_uuid) | Q(siae_encoded__endswith=conv_uuid)) + def oudated_conversations(self): + """the conversations must be deleted after six month + So we get all conversations outdated with this method (30) + """ + # we use shortcut of 30 days x 6 month because timedelta don't accept months + six_months_ago = timezone.now() - timedelta(days=30 * 6) + return self.filter(created_at__lte=six_months_ago) + class Conversation(models.Model): KIND_SEARCH = "SEARCH" From 9e628559f0176d484b1d0a9eb99213e774dbc8f8 Mon Sep 17 00:00:00 2001 From: "madjid.asa" Date: Thu, 28 Dec 2023 18:04:52 +0100 Subject: [PATCH 2/4] add management command and cron setup --- ...ersations_delete_outdated_conversations.sh | 22 +++++++++++++++++++ clevercloud/cron.json | 3 ++- .../commands/delete_outdated_conversations.py | 17 ++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100755 clevercloud/conversations_delete_outdated_conversations.sh create mode 100644 lemarche/conversations/management/commands/delete_outdated_conversations.py diff --git a/clevercloud/conversations_delete_outdated_conversations.sh b/clevercloud/conversations_delete_outdated_conversations.sh new file mode 100755 index 000000000..69c14f958 --- /dev/null +++ b/clevercloud/conversations_delete_outdated_conversations.sh @@ -0,0 +1,22 @@ +#!/bin/bash -l + +# delete outdated conversations + +# Do not run if this env var is not set: +if [[ -z "$CRON_TENDER_SEND_VALIDATED_ENABLED" ]]; then + echo "CRON_CONVERSATIONS_DELETE_OUTDATED_CONVERSATIONS not set. Exiting..." + exit 0 +fi + +# About clever cloud cronjobs: +# https://www.clever-cloud.com/doc/tools/crons/ + +if [[ "$INSTANCE_NUMBER" != "0" ]]; then + echo "Instance number is ${INSTANCE_NUMBER}. Stop here." + exit 0 +fi + +# $APP_HOME is set by default by clever cloud. +cd $APP_HOME + +django-admin delete_outdated_conversations.sh diff --git a/clevercloud/cron.json b/clevercloud/cron.json index a09fa0514..e7eacc19f 100644 --- a/clevercloud/cron.json +++ b/clevercloud/cron.json @@ -2,6 +2,7 @@ "0 0 * * * $ROOT/clevercloud/siaes_export_all_siae_to_file.sh", "15 0 * * * $ROOT/clevercloud/stats_export_user_download_list_to_file.sh", "30 0 * * * $ROOT/clevercloud/stats_export_user_search_list_to_file.sh", + "0 6 * * * $ROOT/clevercloud/conversations_delete_outdated_conversations.sh", "0 1 * * * $ROOT/clevercloud/tenders_update_count_fields.sh", "0 7 * * 1 $ROOT/clevercloud/siaes_sync_with_emplois_inclusion.sh", "5 7 * * 1 $ROOT/clevercloud/siaes_sync_c2_c4.sh", @@ -18,4 +19,4 @@ "10 9 * * * $ROOT/clevercloud/tenders_send_siae_interested_reminder_emails.sh", "20 9 * * * $ROOT/clevercloud/tenders_send_author_incremental.sh", "*/5 8-15 * * 1-5 $ROOT/clevercloud/tenders_send_validated.sh" -] +] \ No newline at end of file diff --git a/lemarche/conversations/management/commands/delete_outdated_conversations.py b/lemarche/conversations/management/commands/delete_outdated_conversations.py new file mode 100644 index 000000000..63340ddbc --- /dev/null +++ b/lemarche/conversations/management/commands/delete_outdated_conversations.py @@ -0,0 +1,17 @@ +from django.core.management.base import BaseCommand + +from lemarche.conversations.models import Conversation + + +class Command(BaseCommand): + """ + Command to send validated tenders + + Note: run via a CRON every day + Usage: python manage.py delete_outdated_conversations + """ + + def handle(self, *args, **options): + oudated_conversations = Conversation.objects.oudated_conversations() + numb_delete, _ = oudated_conversations.delete() + self.stdout.write(f"Delete {numb_delete} conversation(s)") From f143d29963888400440f69c56790e2f50af05fa3 Mon Sep 17 00:00:00 2001 From: Raphael Odini Date: Mon, 8 Jan 2024 15:16:14 +0100 Subject: [PATCH 3/4] Fix typos --- .../conversations_delete_outdated_conversations.sh | 4 ++-- .../commands/delete_outdated_conversations.py | 12 ++++++------ lemarche/conversations/models.py | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/clevercloud/conversations_delete_outdated_conversations.sh b/clevercloud/conversations_delete_outdated_conversations.sh index 69c14f958..87e31a018 100755 --- a/clevercloud/conversations_delete_outdated_conversations.sh +++ b/clevercloud/conversations_delete_outdated_conversations.sh @@ -3,7 +3,7 @@ # delete outdated conversations # Do not run if this env var is not set: -if [[ -z "$CRON_TENDER_SEND_VALIDATED_ENABLED" ]]; then +if [[ -z "$CRON_CONVERSATIONS_DELETE_OUTDATED_CONVERSATIONS" ]]; then echo "CRON_CONVERSATIONS_DELETE_OUTDATED_CONVERSATIONS not set. Exiting..." exit 0 fi @@ -19,4 +19,4 @@ fi # $APP_HOME is set by default by clever cloud. cd $APP_HOME -django-admin delete_outdated_conversations.sh +django-admin delete_outdated_conversations diff --git a/lemarche/conversations/management/commands/delete_outdated_conversations.py b/lemarche/conversations/management/commands/delete_outdated_conversations.py index 63340ddbc..26e1b078b 100644 --- a/lemarche/conversations/management/commands/delete_outdated_conversations.py +++ b/lemarche/conversations/management/commands/delete_outdated_conversations.py @@ -1,17 +1,17 @@ -from django.core.management.base import BaseCommand - from lemarche.conversations.models import Conversation +from lemarche.utils.commands import BaseCommand class Command(BaseCommand): """ - Command to send validated tenders + Command to delete outdated conversations Note: run via a CRON every day Usage: python manage.py delete_outdated_conversations """ def handle(self, *args, **options): - oudated_conversations = Conversation.objects.oudated_conversations() - numb_delete, _ = oudated_conversations.delete() - self.stdout.write(f"Delete {numb_delete} conversation(s)") + self.stdout_info("Delete script of outdated conversations") + conversations_outdated = Conversation.objects.outdated_conversations() + deleted_count, _ = conversations_outdated.delete() + self.stdout_info(f"Deleted {deleted_count} outdated conversation(s)") diff --git a/lemarche/conversations/models.py b/lemarche/conversations/models.py index 8e2699650..5dab1fec8 100644 --- a/lemarche/conversations/models.py +++ b/lemarche/conversations/models.py @@ -34,7 +34,7 @@ def get_conv_from_uuid(self, conv_uuid: str, version=1): else: return self.get(Q(sender_encoded__endswith=conv_uuid) | Q(siae_encoded__endswith=conv_uuid)) - def oudated_conversations(self): + def outdated_conversations(self): """the conversations must be deleted after six month So we get all conversations outdated with this method (30) """ From 57fcd5bb90f3eb8478decc2fd11f70ccba5c5050 Mon Sep 17 00:00:00 2001 From: Raphael Odini Date: Mon, 8 Jan 2024 15:26:39 +0100 Subject: [PATCH 4/4] Rename cron. Add test --- ...versations.sh => conversations_delete_outdated.sh} | 4 ++-- clevercloud/cron.json | 2 +- .../commands/delete_outdated_conversations.py | 3 ++- lemarche/conversations/models.py | 6 +++--- lemarche/conversations/tests.py | 11 +++++++++++ 5 files changed, 19 insertions(+), 7 deletions(-) rename clevercloud/{conversations_delete_outdated_conversations.sh => conversations_delete_outdated.sh} (73%) diff --git a/clevercloud/conversations_delete_outdated_conversations.sh b/clevercloud/conversations_delete_outdated.sh similarity index 73% rename from clevercloud/conversations_delete_outdated_conversations.sh rename to clevercloud/conversations_delete_outdated.sh index 87e31a018..b12f0889d 100755 --- a/clevercloud/conversations_delete_outdated_conversations.sh +++ b/clevercloud/conversations_delete_outdated.sh @@ -3,8 +3,8 @@ # delete outdated conversations # Do not run if this env var is not set: -if [[ -z "$CRON_CONVERSATIONS_DELETE_OUTDATED_CONVERSATIONS" ]]; then - echo "CRON_CONVERSATIONS_DELETE_OUTDATED_CONVERSATIONS not set. Exiting..." +if [[ -z "$CRON_CONVERSATIONS_DELETE_OUTDATED" ]]; then + echo "CRON_CONVERSATIONS_DELETE_OUTDATED not set. Exiting..." exit 0 fi diff --git a/clevercloud/cron.json b/clevercloud/cron.json index e7eacc19f..6cf9cc0f6 100644 --- a/clevercloud/cron.json +++ b/clevercloud/cron.json @@ -2,8 +2,8 @@ "0 0 * * * $ROOT/clevercloud/siaes_export_all_siae_to_file.sh", "15 0 * * * $ROOT/clevercloud/stats_export_user_download_list_to_file.sh", "30 0 * * * $ROOT/clevercloud/stats_export_user_search_list_to_file.sh", - "0 6 * * * $ROOT/clevercloud/conversations_delete_outdated_conversations.sh", "0 1 * * * $ROOT/clevercloud/tenders_update_count_fields.sh", + "0 6 * * * $ROOT/clevercloud/conversations_delete_outdated.sh", "0 7 * * 1 $ROOT/clevercloud/siaes_sync_with_emplois_inclusion.sh", "5 7 * * 1 $ROOT/clevercloud/siaes_sync_c2_c4.sh", "10 7 * * 1 $ROOT/clevercloud/siaes_update_api_entreprise_fields.sh", diff --git a/lemarche/conversations/management/commands/delete_outdated_conversations.py b/lemarche/conversations/management/commands/delete_outdated_conversations.py index 26e1b078b..28adb4db5 100644 --- a/lemarche/conversations/management/commands/delete_outdated_conversations.py +++ b/lemarche/conversations/management/commands/delete_outdated_conversations.py @@ -12,6 +12,7 @@ class Command(BaseCommand): def handle(self, *args, **options): self.stdout_info("Delete script of outdated conversations") - conversations_outdated = Conversation.objects.outdated_conversations() + conversations_outdated = Conversation.objects.outdated() + self.stdout_info(f"Found {conversations_outdated.count()} outdated conversation(s) to delete") deleted_count, _ = conversations_outdated.delete() self.stdout_info(f"Deleted {deleted_count} outdated conversation(s)") diff --git a/lemarche/conversations/models.py b/lemarche/conversations/models.py index 5dab1fec8..27165e7aa 100644 --- a/lemarche/conversations/models.py +++ b/lemarche/conversations/models.py @@ -34,11 +34,11 @@ def get_conv_from_uuid(self, conv_uuid: str, version=1): else: return self.get(Q(sender_encoded__endswith=conv_uuid) | Q(siae_encoded__endswith=conv_uuid)) - def outdated_conversations(self): + def outdated(self): """the conversations must be deleted after six month - So we get all conversations outdated with this method (30) + So we get all conversations outdated with this method """ - # we use shortcut of 30 days x 6 month because timedelta don't accept months + # we use shortcut of 30 days x 6 month because timedelta doesn't accept months six_months_ago = timezone.now() - timedelta(days=30 * 6) return self.filter(created_at__lte=six_months_ago) diff --git a/lemarche/conversations/tests.py b/lemarche/conversations/tests.py index 4a0ee290a..dfb7d64a0 100644 --- a/lemarche/conversations/tests.py +++ b/lemarche/conversations/tests.py @@ -1,4 +1,7 @@ +from datetime import timedelta + from django.test import TestCase +from django.utils import timezone from lemarche.conversations import constants as conversation_constants from lemarche.conversations.factories import ConversationFactory @@ -66,6 +69,14 @@ def test_with_answer_stats(self): self.assertEqual(conversation_queryset.get(id=self.conversation.id).answer_count_annotated, 0) self.assertEqual(conversation_queryset.get(id=self.conversation_with_answer.id).answer_count_annotated, 1) + def test_outdated(self): + one_year_ago = timezone.now() - timedelta(days=365) + ConversationFactory(created_at=one_year_ago) + five_weeks_ago = timezone.now() - timedelta(weeks=5) + ConversationFactory(created_at=five_weeks_ago) + self.assertEqual(Conversation.objects.all().count(), 2 + 2) + self.assertEqual(Conversation.objects.outdated().count(), 1) + class TemplateTransactionalModelTest(TestCase): @classmethod