[videos] Refactor lookup to use new library

This commit is contained in:
2025-11-17 17:56:15 -05:00
parent cd5dc25642
commit 7addd50577
5 changed files with 89 additions and 96 deletions

View File

@ -1,4 +1,5 @@
from dataclasses import dataclass
import re
import logging
from typing import Optional
from uuid import uuid4
@ -27,6 +28,8 @@ from vrobbler.apps.scrobbles.dataclasses import BaseLogData, WithPeopleLogData
YOUTUBE_VIDEO_URL = "https://www.youtube.com/watch?v="
YOUTUBE_CHANNEL_URL = "https://www.youtube.com/channel/"
YOUTUBE_ID_PATTERN = re.compile(r'^[A-Za-z0-9_-]{11}$')
IMDB_VIDEO_URL = "https://www.imdb.com/title/tt"
logger = logging.getLogger(__name__)
@ -136,6 +139,13 @@ class Series(TimeStampedModel):
url = self.cover_image_medium.url
return url
def save_image_from_url(self, url: str, force_update: bool = False):
if not self.cover_image or (force_update and url):
r = requests.get(url)
if r.status_code == 200:
fname = f"{self.title}_{self.uuid}.jpg"
self.cover_image.save(fname, ContentFile(r.content), save=True)
def scrobbles_for_user(self, user_id: int, include_playing=False):
from scrobbles.models import Scrobble
@ -184,6 +194,31 @@ class Series(TimeStampedModel):
if genres := imdb_dict.get("genres"):
self.genre.add(*genres)
@classmethod
def find_or_create(cls, imdb_id: str, overwrite: bool = True):
series, created = cls.objects.get_or_create(imdb_id=imdb_id)
if not (created or overwrite):
return series
vdict, _, cover, genres = lookup_video_from_imdb(
imdb_id
).as_dict_with_cover_and_genres()
vdict.pop("video_type")
vdict["name"] = vdict.pop("title")
for k, v in vdict.items():
setattr(series, k, v)
series.save()
if cover:
series.save_image_from_url(cover)
if genres:
series.genre.add(*genres)
return series
class Video(ScrobblableMixin):
COMPLETION_PERCENT = getattr(settings, "VIDEO_COMPLETION_PERCENT", 90)
@ -304,7 +339,7 @@ class Video(ScrobblableMixin):
if not created and not overwrite:
return video
vdict, cover, genres = lookup_video_from_youtube(
vdict, _, cover, genres = lookup_video_from_youtube(
youtube_id
).as_dict_with_cover_and_genres()
if created or overwrite:
@ -320,28 +355,38 @@ class Video(ScrobblableMixin):
def get_from_imdb_id(
cls, imdb_id: str, overwrite: bool = False
) -> "Video":
if "tt" in imdb_id:
imdb_id = imdb_id[2:]
video, created = cls.objects.get_or_create(imdb_id=imdb_id)
if not created and not overwrite:
return video
vdict, cover, genres = lookup_video_from_tmdb(
vdict, series_id, cover, genres = lookup_video_from_imdb(
imdb_id
).as_dict_with_cover_and_genres()
if created or overwrite:
for k, v in vdict.items():
setattr(video, k, v)
if series_id:
video.tv_series = Series.find_or_create(imdb_id=series_id)
video.save()
video.save_image_from_url(cover)
video.genre.add(*genres)
if cover:
video.save_image_from_url(cover)
if genres:
video.genre.add(*genres)
return video
@classmethod
def find_or_create(
cls, data_dict: dict, post_keys: dict = JELLYFIN_POST_KEYS
) -> Optional["Video"]:
"""Thes smallest of wrappers around our actual get or create utility."""
imdb_key = post_keys.get("IMDB_ID", "").replace("tt", "")
return cls.get_from_imdb_id(data_dict.get(imdb_key))
def find_or_create(cls, source_id: str, overwrite: bool = True) -> "Video":
if "tt" in source_id:
return cls.get_from_imdb_id(source_id)
if bool(YOUTUBE_ID_PATTERN.match(source_id)):
return cls.get_from_youtube_id(source_id)
#TODO scrobble but without a video obj?
logger.warning("Video ID not recognized, not scrobbling")
return