[videos] Switch to TMDB for scraping videos

This commit is contained in:
2025-06-13 11:19:15 -04:00
parent d5da8ae701
commit 24ac545f55
6 changed files with 154 additions and 4 deletions

View File

@ -25,6 +25,7 @@ class VideoMetadata:
60 # Silly default, but things break if this is 0 or null
)
imdb_id: Optional[str]
tmdb_id: Optional[str]
youtube_id: Optional[str]
# IMDB specific
@ -35,6 +36,7 @@ class VideoMetadata:
tv_series_id: Optional[int]
plot: Optional[str]
imdb_rating: Optional[str]
tmdb_rating: Optional[str]
cover_url: Optional[str]
overview: Optional[str]
@ -59,6 +61,6 @@ class VideoMetadata:
video_dict = vars(self)
cover = None
if "cover_url" in video_dict.keys():
cover = video_dict.pop("cover_url")
genres = video_dict.pop("genres")
cover = video_dict.pop("cover_url", "")
genres = video_dict.pop("genres", [])
return video_dict, cover, genres

View File

@ -0,0 +1,18 @@
# Generated by Django 4.2.19 on 2025-06-13 15:04
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('videos', '0022_alter_video_run_time_seconds'),
]
operations = [
migrations.AddField(
model_name='video',
name='tmdb_rating',
field=models.FloatField(blank=True, null=True),
),
]

View File

@ -20,6 +20,7 @@ from scrobbles.mixins import (
from taggit.managers import TaggableManager
from videos.metadata import VideoMetadata
from videos.sources.imdb import lookup_video_from_imdb
from videos.sources.tmdb import lookup_video_from_tmdb
from videos.sources.youtube import lookup_video_from_youtube
YOUTUBE_VIDEO_URL = "https://www.youtube.com/watch?v="
@ -206,6 +207,7 @@ class Video(ScrobblableMixin):
next_imdb_id = models.CharField(max_length=20, **BNULL)
imdb_id = models.CharField(max_length=20, **BNULL)
imdb_rating = models.FloatField(**BNULL)
tmdb_rating = models.FloatField(**BNULL)
cover_image = models.ImageField(upload_to="videos/video/", **BNULL)
cover_image_small = ImageSpecField(
source="cover_image",
@ -307,11 +309,13 @@ 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_imdb(
vdict, cover, genres = lookup_video_from_tmdb(
imdb_id
).as_dict_with_cover_and_genres()
if created or overwrite:

View File

@ -0,0 +1,77 @@
import logging
from django.conf import settings
from themoviedb import TMDb
from tmdbv3api import TV, TMDb as TMDb_direct
from videos.metadata import VideoMetadata, VideoType
key = getattr(settings, "TMDB_API_KEY", "33de8d24785931068ae356510dcfbac8")
key = "33de8d24785931068ae356510dcfbac8"
tmdb_direct = TMDb_direct()
tmdb_direct.api_key = "33de8d24785931068ae356510dcfbac8"
tmdb = TMDb(key=key, language="en-US", region="US")
TMDB_STILL_URL = "https://image.tmdb.org/t/p/original"
logger = logging.getLogger(__name__)
def lookup_video_from_tmdb(
name_or_id: str, kind: str = "movie"
) -> VideoMetadata:
from videos.models import Series
imdb_id = name_or_id
if name_or_id.startswith("tt"):
imdb_id = name_or_id[2:]
video_metadata = VideoMetadata(imdb_id=imdb_id)
imdb_result: dict = {}
tmdb_result = tmdb.find().by_imdb("tt" + imdb_id)
if not tmdb_result:
logger.info(
"[lookup_video_from_tmdb] no video found on tmdb",
extra={"name_or_id": name_or_id},
)
return None
video_metadata = VideoMetadata(imdb_id=imdb_id)
media = None
show = None
if len(tmdb_result.movie_results) > 0:
media = tmdb_result.movie_results[0]
video_metadata.video_type = VideoType.MOVIE.value
if len(tmdb_result.tv_episode_results) > 0:
video_metadata.video_type = VideoType.TV_EPISODE.value
media = tmdb_result.tv_episode_results[0]
series_imdb_id = TV().external_ids(media.show_id).imdb_id[2:]
series, created = Series.objects.get_or_create(imdb_id=series_imdb_id)
if created:
show_data = TV().details(tv_id=media.show_id)
series.name = show_data.name
series.save()
video_metadata.tv_series_id = series.id
if not media:
logger.warning("Video not found on TMDB", extra={"imdb_id":imdb_id})
return video_metadata
video_metadata.tmdb_id = media.id
video_metadata.cover_url = TMDB_STILL_URL + media.still_path # TODO: enrich this with TMDB url
video_metadata.run_time_seconds = media.runtime * 60
video_metadata.title = media.name
video_metadata.episode_number = media.episode_number
video_metadata.season_number = media.season_number
#video_metadata.next_imdb_id = imdb_result.get("next episode", None)
video_metadata.year = media.air_date.year
video_metadata.plot = media.overview
video_metadata.imdb_rating = media.vote_average
#video_metadata.genres = imdb_result.get("genres", [])
return video_metadata