[videos] Add cmd to cleanup series metadata
Some checks failed
build / test (push) Has been cancelled
Some checks failed
build / test (push) Has been cancelled
This commit is contained in:
@ -88,7 +88,7 @@ fetching and simple saving.
|
||||
*** Metadata sources
|
||||
**** Scraper
|
||||
|
||||
* Backlog [3/23] :vrobbler:project:personal:
|
||||
* Backlog [4/24] :vrobbler:project:personal:
|
||||
** TODO [#C] Create small utility to clean up tracks scrobbled with wonky playback times :bug:music:scrobbles:
|
||||
:PROPERTIES:
|
||||
:ID: 702462cf-d54b-48c6-8a7c-78b8de751deb
|
||||
@ -590,6 +590,10 @@ We should rename `email_scrobble_board_game` to reflect the fact that it's just
|
||||
a helper method to create board game scrobbles given a json blob. It's
|
||||
independent of the email flow it was originally creatdd for
|
||||
|
||||
** DONE [#B] Add script to clean up TV series metadata :videos:metadata:
|
||||
:PROPERTIES:
|
||||
:ID: a468b328-59d9-f84b-9ddb-087216783453
|
||||
:END:
|
||||
** DONE [#A] Update youtube video detail pages with links to channel :videos:templates:
|
||||
:PROPERTIES:
|
||||
:ID: 8b87cb42-09e5-a3f5-136f-182f967fa81f
|
||||
|
||||
@ -0,0 +1,68 @@
|
||||
import logging
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.db import transaction
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Enrich TV series metadata from TMDB/OMDB APIs"
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
"--force",
|
||||
action="store_true",
|
||||
help="Overwrite existing cover image",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--dry-run",
|
||||
action="store_true",
|
||||
help="Show what would be done without making changes",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--imdb-id",
|
||||
type=str,
|
||||
help="Only process series with this imdb_id",
|
||||
)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
from videos.models import Series
|
||||
|
||||
force = options["force"]
|
||||
dry_run = options["dry_run"]
|
||||
imdb_id = options["imdb_id"]
|
||||
|
||||
qs = Series.objects.all()
|
||||
if imdb_id:
|
||||
qs = qs.filter(imdb_id=imdb_id)
|
||||
|
||||
total = qs.count()
|
||||
self.stdout.write(f"Processing {total} series")
|
||||
|
||||
if dry_run:
|
||||
for series in qs.iterator():
|
||||
self.stdout.write(
|
||||
f" [DRY RUN] Would fix {series.name} (imdb_id={series.imdb_id})"
|
||||
)
|
||||
return
|
||||
|
||||
updated = 0
|
||||
errors = 0
|
||||
for series in qs.iterator():
|
||||
try:
|
||||
with transaction.atomic():
|
||||
series.fix_metadata(force_update=force)
|
||||
updated += 1
|
||||
self.stdout.write(f" [{updated}/{total}] {series.name}")
|
||||
except Exception as e:
|
||||
errors += 1
|
||||
self.stdout.write(
|
||||
self.style.ERROR(
|
||||
f" Error updating series {series.name} (imdb_id={series.imdb_id}): {e}"
|
||||
)
|
||||
)
|
||||
|
||||
self.stdout.write(
|
||||
self.style.SUCCESS(f"\nDone! {updated} series updated, {errors} errors")
|
||||
)
|
||||
@ -330,16 +330,18 @@ class Series(TimeStampedModel):
|
||||
logger.warning(f"No imdb data for {self}")
|
||||
return
|
||||
|
||||
cover_url = imdb_dict.get("cover_url")
|
||||
|
||||
if (not self.cover_image or force_update) and cover_url:
|
||||
r = requests.get(cover_url)
|
||||
if video_metadata.cover_url and (not self.cover_image or force_update):
|
||||
r = requests.get(video_metadata.cover_url)
|
||||
if r.status_code == 200:
|
||||
fname = f"{self.name}_{self.uuid}.jpg"
|
||||
self.cover_image.save(fname, ContentFile(r.content), save=True)
|
||||
|
||||
if genres := imdb_dict.get("genres"):
|
||||
self.genre.add(*genres)
|
||||
self.plot = video_metadata.plot
|
||||
self.imdb_rating = video_metadata.imdb_rating
|
||||
self.save()
|
||||
|
||||
if video_metadata.genres:
|
||||
self.genre.add(*video_metadata.genres)
|
||||
|
||||
@classmethod
|
||||
def find_or_create(cls, imdb_id: str, overwrite: bool = True):
|
||||
|
||||
Reference in New Issue
Block a user