[scrobbles] Add fix playback position command
All checks were successful
build & deploy / test (push) Successful in 1m59s
build & deploy / build-and-deploy (push) Successful in 29s

This commit is contained in:
2026-05-01 21:02:45 -04:00
parent 5175a9a39a
commit 752b4afaa9

View File

@ -0,0 +1,69 @@
from datetime import timedelta
from django.core.management.base import BaseCommand
from django.db.models import F, Q
from vrobbler.apps.scrobbles.models import Scrobble
class Command(BaseCommand):
help = "Recalculate playback_position_seconds for scrobbles of a given media type"
def add_arguments(self, parser):
parser.add_argument(
"media_type",
type=str,
help="Media type to fix (e.g., Video, Track, VideoGame)",
)
parser.add_argument(
"--dry-run",
action="store_true",
help="Show what would be changed without making changes",
)
def handle(self, *args, **options):
media_type = options["media_type"]
dry_run = options["dry_run"]
valid_types = [choice[0] for choice in Scrobble.MediaType.choices]
if media_type not in valid_types:
self.stdout.write(
self.style.ERROR(
f"Invalid media_type '{media_type}'. Valid types: {', '.join(valid_types)}"
)
)
return
scrobbles = Scrobble.objects.filter(
media_type=media_type,
timestamp__isnull=False,
stop_timestamp__isnull=False,
)
total = scrobbles.count()
self.stdout.write(f"Found {total} scrobbles of type '{media_type}'")
updated = 0
for scrobble in scrobbles.iterator():
calculated = int(
(scrobble.stop_timestamp - scrobble.timestamp).total_seconds()
)
if scrobble.playback_position_seconds != calculated:
self.stdout.write(
f" Scrobble {scrobble.id}: {scrobble.playback_position_seconds} -> {calculated}"
)
if not dry_run:
scrobble.playback_position_seconds = calculated
scrobble.save(update_fields=["playback_position_seconds"])
updated += 1
if dry_run:
self.stdout.write(
self.style.WARNING(
f"Dry run: would update {updated} scrobbles. Use without --dry-run to apply."
)
)
else:
self.stdout.write(
self.style.SUCCESS(f"Updated {updated} scrobbles")
)