This commit has no recorded session.
diff
commit 912ea8bfacc18e3bb6fe8d76653a839247586993Author: Colin Powell <colin@unbl.ink>Date: Sun Jun 7 09:47:52 2026 -0400 [videos] Add OMDB enrichment when TMDb fails@@ -86,7 +86,7 @@ fetching and simple saving. **** Bookmarklet *** Metadata sources **** Scraper-* Backlog [0/13] :vrobbler:project:personal:+* Backlog [1/13] :vrobbler:project:personal: ** TODO [#C] Create small utility to clean up tracks scrobbled with wonky playback times :vrobbler:personal:bug:music:scrobbles: :PROPERTIES: :ID: 702462cf-d54b-48c6-8a7c-78b8de751deb@@ -498,7 +498,7 @@ needed import celery task. This is how the WebDAV celery task currently works. This would also be an opporunity to clean up the code around WebDAV imports and make them more re-usable for other import services. -** TODO [#B] Add OMDB source as backup when TMDB returns nothing :videos:metadata:imdb: +** DONE [#B] Add OMDB source as backup when TMDB returns nothing :videos:metadata:imdb: :PROPERTIES: :ID: 20195445-7fdd-49be-9767-103b12da0bfb :END:@@ -20,6 +20,7 @@ from scrobbles.mixins import ( ) from taggit.managers import TaggableManager from videos.metadata import VideoMetadata+from videos.sources.omdb import lookup_video_from_omdb from videos.sources.tmdb import lookup_video_from_tmdb from videos.sources.youtube import lookup_video_from_youtube @@ -255,9 +256,22 @@ class Series(TimeStampedModel): logger.info("Series not created and overwrite=False, returning") return series - vdict, _, cover, genres = lookup_video_from_tmdb(- imdb_id- ).as_dict_with_cover_and_genres()+ try:+ metadata = lookup_video_from_tmdb(imdb_id)+ except Exception as e:+ logger.warning(f"TMDB lookup failed for series {imdb_id}: {e}")+ metadata = None++ if not metadata or not metadata.title:+ metadata = lookup_video_from_omdb(imdb_id)++ if not metadata or not metadata.title:+ logger.warning(+ f"No metadata found for series {imdb_id} from TMDB or OMDB"+ )+ return series++ vdict, _, cover, genres = metadata.as_dict_with_cover_and_genres() vdict.pop("video_type") vdict["name"] = vdict.pop("title")@@ -432,9 +446,22 @@ class Video(ScrobblableMixin): if not created and not overwrite: return video - vdict, series_id, cover, genres = lookup_video_from_tmdb(- imdb_id- ).as_dict_with_cover_and_genres()+ try:+ metadata = lookup_video_from_tmdb(imdb_id)+ except Exception as e:+ logger.warning(f"TMDB lookup failed for {imdb_id}: {e}")+ metadata = None++ if not metadata or not metadata.title:+ metadata = lookup_video_from_omdb(imdb_id)++ if not metadata or not metadata.title:+ logger.warning(+ f"No metadata found for {imdb_id} from TMDB or OMDB"+ )+ return video++ vdict, series_id, cover, genres = metadata.as_dict_with_cover_and_genres() if created or overwrite: for k, v in vdict.items():@@ -0,0 +1,72 @@+import logging+import re+from typing import Optional++import requests+from django.conf import settings+from videos.metadata import VideoMetadata, VideoType++logger = logging.getLogger(__name__)++OMDB_API_KEY = getattr(settings, "OMDB_API_KEY", "")++OMDB_URL = "https://www.omdbapi.com/"+RUNTIME_RE = re.compile(r"(\d+)\s*min")+++def lookup_video_from_omdb(imdb_id: str) -> Optional[VideoMetadata]:+ if not imdb_id.startswith("tt"):+ imdb_id = f"tt{imdb_id}"++ if not OMDB_API_KEY:+ logger.warning("No OMDB API key configured")+ return None++ params = {"apikey": OMDB_API_KEY, "i": imdb_id, "plot": "full"}++ try:+ response = requests.get(OMDB_URL, params=params)+ response.raise_for_status()+ data = response.json()+ except requests.exceptions.RequestException as e:+ logger.error(f"OMDB API error for {imdb_id}: {e}")+ return None++ if data.get("Response") == "False":+ logger.info(f"OMDB no result for {imdb_id}: {data.get('Error')}")+ return None++ metadata = VideoMetadata(imdb_id=imdb_id)+ metadata.title = data.get("Title")+ metadata.plot = data.get("Plot")+ metadata.overview = data.get("Plot")++ raw_year = data.get("Year")+ if raw_year and raw_year.isdigit():+ metadata.year = int(raw_year)++ raw_rating = data.get("imdbRating")+ if raw_rating and raw_rating != "N/A":+ metadata.imdb_rating = raw_rating++ raw_cover = data.get("Poster")+ if raw_cover and raw_cover != "N/A":+ metadata.cover_url = raw_cover++ raw_runtime = data.get("Runtime")+ if raw_runtime:+ match = RUNTIME_RE.match(raw_runtime)+ if match:+ metadata.base_run_time_seconds = int(match.group(1)) * 60++ media_type = data.get("Type")+ if media_type == "movie":+ metadata.video_type = VideoType.MOVIE.value+ elif media_type in ("series", "episode"):+ metadata.video_type = VideoType.TV_EPISODE.value++ raw_genres = data.get("Genre")+ if raw_genres:+ metadata.genres = [g.strip() for g in raw_genres.split(",") if g.strip()]++ return metadata@@ -3,14 +3,11 @@ import logging import pendulum from django.conf import settings from themoviedb import TMDb-from tmdbv3api import TV, Movie, TMDb as TMDb_direct+from tmdbv3api import TV, Movie from videos.metadata import VideoMetadata, VideoType TMDB_KEY = getattr(settings, "TMDB_API_KEY", "") -tmdb_direct = TMDb_direct()-tmdb_direct.api_key = TMDB_KEY- tmdb = TMDb(key=TMDB_KEY, language="en-US", region="US") TMDB_IMAGE_URL = "https://image.tmdb.org/t/p/original"@@ -36,7 +33,7 @@ def lookup_video_from_tmdb(name_or_id: str, kind: str = "movie") -> VideoMetadat video_metadata = VideoMetadata(imdb_id=imdb_id) media = None- show = None+ show_data = None if len(tmdb_result.movie_results) > 0: media = Movie().details(tmdb_result.movie_results[0].id) video_metadata.video_type = VideoType.MOVIE.value@@ -60,6 +60,7 @@ THEAUDIODB_API_KEY = os.getenv("VROBBLER_THEAUDIODB_API_KEY", "2") PODCASTINDEX_API_KEY = os.getenv("VROBBLER_PODCASTINDEX_API_KEY", "") PODCASTINDEX_API_SECRET = os.getenv("VROBBLER_PODCASTINDEX_API_SECRET", "") TMDB_API_KEY = os.getenv("VROBBLER_TMDB_API_KEY", "")+OMDB_API_KEY = os.getenv("VROBBLER_OMDB_API_KEY", "") LASTFM_API_KEY = os.getenv("VROBBLER_LASTFM_API_KEY") LASTFM_SECRET_KEY = os.getenv("VROBBLER_LASTFM_SECRET_KEY") IGDB_CLIENT_ID = os.getenv("VROBBLER_IGDB_CLIENT_ID")