[scrobbles] Add fix playback position command
This commit is contained in:
@ -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")
|
||||
)
|
||||
Reference in New Issue
Block a user