From e487f5068331879192ea0e0b6b44f754a31a9715 Mon Sep 17 00:00:00 2001 From: Colin Powell Date: Thu, 6 Apr 2023 13:53:22 -0400 Subject: [PATCH] Add a command to remove zombie scrobbles --- .../commands/delete_zombie_scrobbles.py | 29 +++++++++++++++++++ vrobbler/apps/scrobbles/utils.py | 27 +++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 vrobbler/apps/scrobbles/management/commands/delete_zombie_scrobbles.py diff --git a/vrobbler/apps/scrobbles/management/commands/delete_zombie_scrobbles.py b/vrobbler/apps/scrobbles/management/commands/delete_zombie_scrobbles.py new file mode 100644 index 0000000..55ad915 --- /dev/null +++ b/vrobbler/apps/scrobbles/management/commands/delete_zombie_scrobbles.py @@ -0,0 +1,29 @@ +from django.core.management.base import BaseCommand, no_translations +from vrobbler.apps.scrobbles.utils import delete_zombie_scrobbles + + +class Command(BaseCommand): + def add_arguments(self, parser): + parser.add_argument( + "--delete", + action="store_true", + help="Delete poll instead of closing it", + ) + + def handle(self, *args, **options): + dry_run = True + if options["delete"]: + dry_run = False + scrobbles_found = delete_zombie_scrobbles(dry_run) + + if not scrobbles_found: + print(f"No zombie scrobbles found to delete") + return + + if not dry_run: + print(f"Deleted {scrobbles_found} zombie scrobbles") + return + + print( + f"Found {scrobbles_found} zombie scrobbles, use --delete to remove them" + ) diff --git a/vrobbler/apps/scrobbles/utils.py b/vrobbler/apps/scrobbles/utils.py index 2a6034e..70ab4dd 100644 --- a/vrobbler/apps/scrobbles/utils.py +++ b/vrobbler/apps/scrobbles/utils.py @@ -1,4 +1,5 @@ import logging +from datetime import timedelta from urllib.parse import unquote from dateutil.parser import ParserError, parse @@ -212,3 +213,29 @@ def import_lastfm_for_all_users(): ) continue process_lastfm_import.delay(lfm_import.id) + + +def delete_zombie_scrobbles(dry_run=True): + """Look for any scrobble over a day old that is not paused and still in progress and delete it""" + Scrobble = apps.get_model("scrobbles", "Scrobble") + now = timezone.now() + three_days_ago = now - timedelta(days=3) + + # TODO This should be part of a custom manager + zombie_scrobbles = Scrobble.objects.filter( + timestamp__lte=three_days_ago, + is_paused=False, + played_to_completion=False, + ) + + zombies_found = zombie_scrobbles.count() + + if not dry_run: + logger.info(f"Deleted {zombies_found} zombie scrobbles") + zombie_scrobbles.delete() + return zombies_found + + logger.info( + f"Found {zombies_found} zombie scrobbles to delete, use dry_run=False to proceed" + ) + return zombies_found