mirror of
https://github.com/maxdorninger/MediaManager.git
synced 2026-04-17 15:43:28 +02:00
Merge pull request #313 from maxdorninger/add-more-metadata-ids
Add IMDb id's
This commit is contained in:
@@ -5,6 +5,7 @@ Revises: eb0bd3cc1852
|
||||
Create Date: 2025-12-13 18:47:02.146038
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
@@ -12,8 +13,8 @@ import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = '16e78af9e5bf'
|
||||
down_revision: Union[str, None] = 'eb0bd3cc1852'
|
||||
revision: str = "16e78af9e5bf"
|
||||
down_revision: Union[str, None] = "eb0bd3cc1852"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
@@ -21,22 +22,16 @@ depends_on: Union[str, Sequence[str], None] = None
|
||||
def upgrade() -> None:
|
||||
"""Upgrade schema."""
|
||||
# Add original_language column to show table
|
||||
op.add_column(
|
||||
'show',
|
||||
sa.Column('original_language', sa.String(10), nullable=True)
|
||||
)
|
||||
|
||||
op.add_column("show", sa.Column("original_language", sa.String(10), nullable=True))
|
||||
|
||||
# Add original_language column to movie table
|
||||
op.add_column(
|
||||
'movie',
|
||||
sa.Column('original_language', sa.String(10), nullable=True)
|
||||
)
|
||||
op.add_column("movie", sa.Column("original_language", sa.String(10), nullable=True))
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
"""Downgrade schema."""
|
||||
# Remove original_language column from movie table
|
||||
op.drop_column('movie', 'original_language')
|
||||
|
||||
op.drop_column("movie", "original_language")
|
||||
|
||||
# Remove original_language column from show table
|
||||
op.drop_column('show', 'original_language')
|
||||
op.drop_column("show", "original_language")
|
||||
|
||||
35
alembic/versions/2c61f662ca9e_add_imdb_id_fields.py
Normal file
35
alembic/versions/2c61f662ca9e_add_imdb_id_fields.py
Normal file
@@ -0,0 +1,35 @@
|
||||
"""add imdb_id fields
|
||||
|
||||
Revision ID: 2c61f662ca9e
|
||||
Revises: 16e78af9e5bf
|
||||
Create Date: 2025-12-23 19:42:09.593945
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "2c61f662ca9e"
|
||||
down_revision: Union[str, None] = "16e78af9e5bf"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
"""Upgrade schema."""
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column("movie", sa.Column("imdb_id", sa.String(), nullable=True))
|
||||
op.add_column("show", sa.Column("imdb_id", sa.String(), nullable=True))
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
"""Downgrade schema."""
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column("show", "imdb_id")
|
||||
op.drop_column("movie", "imdb_id")
|
||||
# ### end Alembic commands ###
|
||||
@@ -3,8 +3,9 @@ from pydantic_settings import BaseSettings
|
||||
|
||||
class TmdbConfig(BaseSettings):
|
||||
tmdb_relay_url: str = "https://metadata-relay.dorninger.co/tmdb"
|
||||
primary_languages: list[str] = [] # ISO 639-1 language codes
|
||||
default_language: str = "en" # ISO 639-1 language codes
|
||||
primary_languages: list[str] = [] # ISO 639-1 language codes
|
||||
default_language: str = "en" # ISO 639-1 language codes
|
||||
|
||||
|
||||
class TvdbConfig(BaseSettings):
|
||||
tvdb_relay_url: str = "https://metadata-relay.dorninger.co/tvdb"
|
||||
|
||||
@@ -32,7 +32,7 @@ class TmdbMetadataProvider(AbstractMetadataProvider):
|
||||
"""
|
||||
Determine the language parameter to use for TMDB API calls.
|
||||
Returns the original language if it's in primary_languages, otherwise returns default_language.
|
||||
|
||||
|
||||
:param original_language: The original language code (ISO 639-1) of the media
|
||||
:return: Language parameter (ISO 639-1 format, e.g., 'en', 'no')
|
||||
"""
|
||||
@@ -45,8 +45,7 @@ class TmdbMetadataProvider(AbstractMetadataProvider):
|
||||
language = self.default_language
|
||||
try:
|
||||
response = requests.get(
|
||||
url=f"{self.url}/tv/shows/{id}",
|
||||
params={"language": language}
|
||||
url=f"{self.url}/tv/shows/{id}", params={"language": language}
|
||||
)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
@@ -59,13 +58,29 @@ class TmdbMetadataProvider(AbstractMetadataProvider):
|
||||
)
|
||||
raise
|
||||
|
||||
def __get_season_metadata(self, show_id: int, season_number: int, language: str | None = None) -> dict:
|
||||
def __get_show_external_ids(self, id: int) -> dict:
|
||||
try:
|
||||
response = requests.get(url=f"{self.url}/tv/shows/{id}/external_ids")
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
except requests.RequestException as e:
|
||||
log.error(f"TMDB API error getting show external IDs for ID {id}: {e}")
|
||||
if notification_manager.is_configured():
|
||||
notification_manager.send_notification(
|
||||
title="TMDB API Error",
|
||||
message=f"Failed to fetch show external IDs for ID {id} from TMDB. Error: {str(e)}",
|
||||
)
|
||||
raise
|
||||
|
||||
def __get_season_metadata(
|
||||
self, show_id: int, season_number: int, language: str | None = None
|
||||
) -> dict:
|
||||
if language is None:
|
||||
language = self.default_language
|
||||
try:
|
||||
response = requests.get(
|
||||
url=f"{self.url}/tv/shows/{show_id}/{season_number}",
|
||||
params={"language": language}
|
||||
params={"language": language},
|
||||
)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
@@ -102,7 +117,10 @@ class TmdbMetadataProvider(AbstractMetadataProvider):
|
||||
|
||||
def __get_trending_tv(self) -> dict:
|
||||
try:
|
||||
response = requests.get(url=f"{self.url}/tv/trending", params={"language": self.default_language})
|
||||
response = requests.get(
|
||||
url=f"{self.url}/tv/trending",
|
||||
params={"language": self.default_language},
|
||||
)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
except requests.RequestException as e:
|
||||
@@ -119,8 +137,7 @@ class TmdbMetadataProvider(AbstractMetadataProvider):
|
||||
language = self.default_language
|
||||
try:
|
||||
response = requests.get(
|
||||
url=f"{self.url}/movies/{id}",
|
||||
params={"language": language}
|
||||
url=f"{self.url}/movies/{id}", params={"language": language}
|
||||
)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
@@ -133,6 +150,20 @@ class TmdbMetadataProvider(AbstractMetadataProvider):
|
||||
)
|
||||
raise
|
||||
|
||||
def __get_movie_external_ids(self, id: int) -> dict:
|
||||
try:
|
||||
response = requests.get(url=f"{self.url}/movies/{id}/external_ids")
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
except requests.RequestException as e:
|
||||
log.error(f"TMDB API error getting movie external IDs for ID {id}: {e}")
|
||||
if notification_manager.is_configured():
|
||||
notification_manager.send_notification(
|
||||
title="TMDB API Error",
|
||||
message=f"Failed to fetch movie external IDs for ID {id} from TMDB. Error: {str(e)}",
|
||||
)
|
||||
raise
|
||||
|
||||
def __search_movie(self, query: str, page: int) -> dict:
|
||||
try:
|
||||
response = requests.get(
|
||||
@@ -155,7 +186,10 @@ class TmdbMetadataProvider(AbstractMetadataProvider):
|
||||
|
||||
def __get_trending_movies(self) -> dict:
|
||||
try:
|
||||
response = requests.get(url=f"{self.url}/movies/trending", params={"language": self.default_language})
|
||||
response = requests.get(
|
||||
url=f"{self.url}/movies/trending",
|
||||
params={"language": self.default_language},
|
||||
)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
except requests.RequestException as e:
|
||||
@@ -170,10 +204,10 @@ class TmdbMetadataProvider(AbstractMetadataProvider):
|
||||
def download_show_poster_image(self, show: Show) -> bool:
|
||||
# Determine which language to use based on show's original_language
|
||||
language = self.__get_language_param(show.original_language)
|
||||
|
||||
|
||||
# Fetch metadata in the appropriate language to get localized poster
|
||||
show_metadata = self.__get_show_metadata(show.external_id, language=language)
|
||||
|
||||
|
||||
# downloading the poster
|
||||
# all pictures from TMDB should already be jpeg, so no need to convert
|
||||
if show_metadata["poster_path"] is not None:
|
||||
@@ -206,20 +240,24 @@ class TmdbMetadataProvider(AbstractMetadataProvider):
|
||||
if language is None:
|
||||
show_metadata = self.__get_show_metadata(id)
|
||||
language = show_metadata.get("original_language")
|
||||
|
||||
|
||||
# Determine which language to use for metadata
|
||||
language = self.__get_language_param(language)
|
||||
|
||||
|
||||
# Fetch show metadata in the appropriate language
|
||||
show_metadata = self.__get_show_metadata(id, language=language)
|
||||
|
||||
|
||||
# get imdb id
|
||||
external_ids = self.__get_show_external_ids(id=id)
|
||||
imdb_id = external_ids.get("imdb_id")
|
||||
|
||||
season_list = []
|
||||
# inserting all the metadata into the objects
|
||||
for season in show_metadata["seasons"]:
|
||||
season_metadata = self.__get_season_metadata(
|
||||
show_id=show_metadata["id"],
|
||||
show_id=show_metadata["id"],
|
||||
season_number=season["season_number"],
|
||||
language=language
|
||||
language=language,
|
||||
)
|
||||
episode_list = []
|
||||
|
||||
@@ -255,6 +293,7 @@ class TmdbMetadataProvider(AbstractMetadataProvider):
|
||||
metadata_provider=self.name,
|
||||
ended=show_metadata["status"] in ENDED_STATUS,
|
||||
original_language=show_metadata.get("original_language"),
|
||||
imdb_id=imdb_id,
|
||||
)
|
||||
|
||||
return show
|
||||
@@ -287,19 +326,18 @@ class TmdbMetadataProvider(AbstractMetadataProvider):
|
||||
)
|
||||
else:
|
||||
poster_url = None
|
||||
|
||||
|
||||
# Determine which name to use based on primary_languages
|
||||
original_language = result.get("original_language")
|
||||
original_name = result.get("original_name")
|
||||
display_name = result["name"]
|
||||
|
||||
|
||||
overview = result["overview"]
|
||||
# Use original name if language is in primary_languages and skip overview
|
||||
if original_language and original_language in self.primary_languages:
|
||||
display_name = original_name
|
||||
overview = None
|
||||
|
||||
|
||||
formatted_results.append(
|
||||
MetaDataProviderSearchResult(
|
||||
poster_path=poster_url,
|
||||
@@ -334,13 +372,17 @@ class TmdbMetadataProvider(AbstractMetadataProvider):
|
||||
if language is None:
|
||||
movie_metadata = self.__get_movie_metadata(id=id)
|
||||
language = movie_metadata.get("original_language")
|
||||
|
||||
|
||||
# Determine which language to use for metadata
|
||||
language = self.__get_language_param(language)
|
||||
|
||||
|
||||
# Fetch movie metadata in the appropriate language
|
||||
movie_metadata = self.__get_movie_metadata(id=id, language=language)
|
||||
|
||||
|
||||
# get imdb id
|
||||
external_ids = self.__get_movie_external_ids(id=id)
|
||||
imdb_id = external_ids.get("imdb_id")
|
||||
|
||||
year = media_manager.metadataProvider.utils.get_year_from_date(
|
||||
movie_metadata["release_date"]
|
||||
)
|
||||
@@ -352,6 +394,7 @@ class TmdbMetadataProvider(AbstractMetadataProvider):
|
||||
year=year,
|
||||
metadata_provider=self.name,
|
||||
original_language=movie_metadata.get("original_language"),
|
||||
imdb_id=imdb_id,
|
||||
)
|
||||
|
||||
return movie
|
||||
@@ -384,18 +427,18 @@ class TmdbMetadataProvider(AbstractMetadataProvider):
|
||||
)
|
||||
else:
|
||||
poster_url = None
|
||||
|
||||
|
||||
# Determine which name to use based on primary_languages
|
||||
original_language = result.get("original_language")
|
||||
original_title = result.get("original_title")
|
||||
display_name = result["title"]
|
||||
|
||||
|
||||
overview = result["overview"]
|
||||
# Use original name if language is in primary_languages and skip overview
|
||||
if original_language and original_language in self.primary_languages:
|
||||
display_name = original_title
|
||||
overview = None
|
||||
|
||||
|
||||
formatted_results.append(
|
||||
MetaDataProviderSearchResult(
|
||||
poster_path=poster_url,
|
||||
@@ -418,10 +461,12 @@ class TmdbMetadataProvider(AbstractMetadataProvider):
|
||||
def download_movie_poster_image(self, movie: Movie) -> bool:
|
||||
# Determine which language to use based on movie's original_language
|
||||
language = self.__get_language_param(movie.original_language)
|
||||
|
||||
|
||||
# Fetch metadata in the appropriate language to get localized poster
|
||||
movie_metadata = self.__get_movie_metadata(id=movie.external_id, language=language)
|
||||
|
||||
movie_metadata = self.__get_movie_metadata(
|
||||
id=movie.external_id, language=language
|
||||
)
|
||||
|
||||
# downloading the poster
|
||||
# all pictures from TMDB should already be jpeg, so no need to convert
|
||||
if movie_metadata["poster_path"] is not None:
|
||||
|
||||
@@ -77,6 +77,14 @@ class TvdbMetadataProvider(AbstractMetadataProvider):
|
||||
seasons = []
|
||||
seasons_ids = [season["id"] for season in series["seasons"]]
|
||||
|
||||
# get imdb id from remote ids
|
||||
imdb_id = None
|
||||
remote_ids = series.get("remoteIds", None)
|
||||
if remote_ids:
|
||||
for remote_id in remote_ids:
|
||||
if remote_id.get("type") == 2:
|
||||
imdb_id = remote_id.get("id")
|
||||
|
||||
for season in seasons_ids:
|
||||
s = self.__get_season(id=season)
|
||||
# the seasons need to be filtered to a certain type,
|
||||
@@ -119,6 +127,7 @@ class TvdbMetadataProvider(AbstractMetadataProvider):
|
||||
metadata_provider=self.name,
|
||||
seasons=seasons,
|
||||
ended=False,
|
||||
imdb_id=imdb_id,
|
||||
)
|
||||
|
||||
return show
|
||||
@@ -267,17 +276,22 @@ class TvdbMetadataProvider(AbstractMetadataProvider):
|
||||
:rtype: Movie
|
||||
"""
|
||||
movie = self.__get_movie(id)
|
||||
try:
|
||||
year = movie["year"]
|
||||
except KeyError:
|
||||
year = None
|
||||
|
||||
# get imdb id from remote ids
|
||||
imdb_id = None
|
||||
remote_ids = movie.get("remoteIds", None)
|
||||
if remote_ids:
|
||||
for remote_id in remote_ids:
|
||||
if remote_id.get("type") == 2:
|
||||
imdb_id = remote_id.get("id")
|
||||
|
||||
movie = Movie(
|
||||
name=movie["name"],
|
||||
overview="TVDB does not provide overviews",
|
||||
year=year,
|
||||
overview="Overviews are not supported with TVDB",
|
||||
year=movie.get("year"),
|
||||
external_id=movie["id"],
|
||||
metadata_provider=self.name,
|
||||
imdb_id=imdb_id,
|
||||
)
|
||||
|
||||
return movie
|
||||
|
||||
@@ -20,6 +20,8 @@ class Movie(Base):
|
||||
year: Mapped[int | None]
|
||||
library: Mapped[str] = mapped_column(default="")
|
||||
original_language: Mapped[str | None] = mapped_column(default=None)
|
||||
imdb_id: Mapped[str | None] = mapped_column(default=None)
|
||||
|
||||
movie_requests: Mapped[list["MovieRequest"]] = relationship(
|
||||
"MovieRequest", back_populates="movie", cascade="all, delete-orphan"
|
||||
)
|
||||
|
||||
@@ -116,6 +116,7 @@ class MovieRepository:
|
||||
db_movie.overview = movie.overview
|
||||
db_movie.year = movie.year
|
||||
db_movie.original_language = movie.original_language
|
||||
db_movie.imdb_id = movie.imdb_id
|
||||
else: # Insert new movie
|
||||
log.debug(f"Creating new movie: {movie.name}")
|
||||
db_movie = Movie(**movie.model_dump())
|
||||
@@ -435,10 +436,12 @@ class MovieRepository:
|
||||
name: str | None = None,
|
||||
overview: str | None = None,
|
||||
year: int | None = None,
|
||||
imdb_id: str | None = None,
|
||||
) -> MovieSchema:
|
||||
"""
|
||||
Update attributes of an existing movie.
|
||||
|
||||
:param imdb_id: The new IMDb ID for the movie.
|
||||
:param movie_id: The ID of the movie to update.
|
||||
:param name: The new name for the movie.
|
||||
:param overview: The new overview for the movie.
|
||||
@@ -459,6 +462,9 @@ class MovieRepository:
|
||||
if year is not None and db_movie.year != year:
|
||||
db_movie.year = year
|
||||
updated = True
|
||||
if imdb_id is not None and db_movie.imdb_id != imdb_id:
|
||||
db_movie.imdb_id = imdb_id
|
||||
updated = True
|
||||
|
||||
if updated:
|
||||
self.db.commit()
|
||||
|
||||
@@ -24,6 +24,7 @@ class Movie(BaseModel):
|
||||
metadata_provider: str
|
||||
library: str = "Default"
|
||||
original_language: str | None = None
|
||||
imdb_id: str | None = None
|
||||
|
||||
|
||||
class MovieFile(BaseModel):
|
||||
|
||||
@@ -63,7 +63,10 @@ class MovieService:
|
||||
self.notification_service = notification_service
|
||||
|
||||
def add_movie(
|
||||
self, external_id: int, metadata_provider: AbstractMetadataProvider, language: str | None = None
|
||||
self,
|
||||
external_id: int,
|
||||
metadata_provider: AbstractMetadataProvider,
|
||||
language: str | None = None,
|
||||
) -> Movie | None:
|
||||
"""
|
||||
Add a new movie to the database.
|
||||
@@ -72,7 +75,9 @@ class MovieService:
|
||||
:param metadata_provider: The name of the metadata provider.
|
||||
:param language: Optional language code (ISO 639-1) to fetch metadata in.
|
||||
"""
|
||||
movie_with_metadata = metadata_provider.get_movie_metadata(id=external_id, language=language)
|
||||
movie_with_metadata = metadata_provider.get_movie_metadata(
|
||||
id=external_id, language=language
|
||||
)
|
||||
saved_movie = self.movie_repository.save_movie(movie=movie_with_metadata)
|
||||
metadata_provider.download_movie_poster_image(movie=saved_movie)
|
||||
return saved_movie
|
||||
@@ -699,7 +704,9 @@ class MovieService:
|
||||
log.debug(f"Found movie: {db_movie.name} for metadata update.")
|
||||
|
||||
# Use stored original_language preference for metadata fetching
|
||||
fresh_movie_data = metadata_provider.get_movie_metadata(id=db_movie.external_id, language=db_movie.original_language)
|
||||
fresh_movie_data = metadata_provider.get_movie_metadata(
|
||||
id=db_movie.external_id, language=db_movie.original_language
|
||||
)
|
||||
if not fresh_movie_data:
|
||||
log.warning(
|
||||
f"Could not fetch fresh metadata for movie {db_movie.name} (External ID: {db_movie.external_id}) from {db_movie.metadata_provider}."
|
||||
@@ -712,6 +719,7 @@ class MovieService:
|
||||
name=fresh_movie_data.name,
|
||||
overview=fresh_movie_data.overview,
|
||||
year=fresh_movie_data.year,
|
||||
imdb_id=fresh_movie_data.imdb_id,
|
||||
)
|
||||
|
||||
updated_movie = self.movie_repository.get_movie_by_id(movie_id=db_movie.id)
|
||||
|
||||
@@ -23,6 +23,8 @@ class Show(Base):
|
||||
library: Mapped[str] = mapped_column(default="")
|
||||
original_language: Mapped[str | None] = mapped_column(default=None)
|
||||
|
||||
imdb_id: Mapped[str | None] = mapped_column(default=None)
|
||||
|
||||
seasons: Mapped[list["Season"]] = relationship(
|
||||
back_populates="show", cascade="all, delete"
|
||||
)
|
||||
|
||||
@@ -136,6 +136,7 @@ class TvRepository:
|
||||
db_show.overview = show.overview
|
||||
db_show.year = show.year
|
||||
db_show.original_language = show.original_language
|
||||
db_show.imdb_id = show.imdb_id
|
||||
else: # Insert new show
|
||||
db_show = Show(
|
||||
id=show.id,
|
||||
@@ -146,6 +147,7 @@ class TvRepository:
|
||||
year=show.year,
|
||||
ended=show.ended,
|
||||
original_language=show.original_language,
|
||||
imdb_id=show.imdb_id,
|
||||
seasons=[
|
||||
Season(
|
||||
id=season.id,
|
||||
@@ -643,10 +645,13 @@ class TvRepository:
|
||||
year: int | None = None,
|
||||
ended: bool | None = None,
|
||||
continuous_download: bool | None = None,
|
||||
imdb_id: str | None = None,
|
||||
) -> ShowSchema: # Removed poster_url from params
|
||||
"""
|
||||
Update attributes of an existing show.
|
||||
|
||||
:param imdb_id: The new IMDb ID for the show.
|
||||
:param continuous_download: The new continuous download status for the show.
|
||||
:param show_id: The ID of the show to update.
|
||||
:param name: The new name for the show.
|
||||
:param overview: The new overview for the show.
|
||||
@@ -677,6 +682,9 @@ class TvRepository:
|
||||
):
|
||||
db_show.continuous_download = continuous_download
|
||||
updated = True
|
||||
if imdb_id is not None and db_show.imdb_id != imdb_id:
|
||||
db_show.imdb_id = imdb_id
|
||||
updated = True
|
||||
if updated:
|
||||
self.db.commit()
|
||||
self.db.refresh(db_show)
|
||||
|
||||
@@ -58,7 +58,10 @@ router = APIRouter()
|
||||
},
|
||||
)
|
||||
def add_a_show(
|
||||
tv_service: tv_service_dep, metadata_provider: metadata_provider_dep, show_id: int, language: str | None = None
|
||||
tv_service: tv_service_dep,
|
||||
metadata_provider: metadata_provider_dep,
|
||||
show_id: int,
|
||||
language: str | None = None,
|
||||
):
|
||||
try:
|
||||
show = tv_service.add_show(
|
||||
|
||||
@@ -57,6 +57,8 @@ class Show(BaseModel):
|
||||
library: str = "Default"
|
||||
original_language: str | None = None
|
||||
|
||||
imdb_id: str | None = None
|
||||
|
||||
seasons: list[Season]
|
||||
|
||||
|
||||
|
||||
@@ -69,7 +69,10 @@ class TvService:
|
||||
self.notification_service = notification_service
|
||||
|
||||
def add_show(
|
||||
self, external_id: int, metadata_provider: AbstractMetadataProvider, language: str | None = None
|
||||
self,
|
||||
external_id: int,
|
||||
metadata_provider: AbstractMetadataProvider,
|
||||
language: str | None = None,
|
||||
) -> Show | None:
|
||||
"""
|
||||
Add a new show to the database.
|
||||
@@ -78,7 +81,9 @@ class TvService:
|
||||
:param metadata_provider: The name of the metadata provider.
|
||||
:param language: Optional language code (ISO 639-1) to fetch metadata in.
|
||||
"""
|
||||
show_with_metadata = metadata_provider.get_show_metadata(id=external_id, language=language)
|
||||
show_with_metadata = metadata_provider.get_show_metadata(
|
||||
id=external_id, language=language
|
||||
)
|
||||
saved_show = self.tv_repository.save_show(show=show_with_metadata)
|
||||
metadata_provider.download_show_poster_image(show=saved_show)
|
||||
return saved_show
|
||||
@@ -758,7 +763,9 @@ class TvService:
|
||||
# old_poster_url = db_show.poster_url # poster_url removed from db_show
|
||||
|
||||
# Use stored original_language preference for metadata fetching
|
||||
fresh_show_data = metadata_provider.get_show_metadata(id=db_show.external_id, language=db_show.original_language)
|
||||
fresh_show_data = metadata_provider.get_show_metadata(
|
||||
id=db_show.external_id, language=db_show.original_language
|
||||
)
|
||||
if not fresh_show_data:
|
||||
log.warning(
|
||||
f"Could not fetch fresh metadata for show {db_show.name} (External ID: {db_show.external_id}) from {db_show.metadata_provider}."
|
||||
@@ -773,6 +780,7 @@ class TvService:
|
||||
overview=fresh_show_data.overview,
|
||||
year=fresh_show_data.year,
|
||||
ended=fresh_show_data.ended,
|
||||
imdb_id=fresh_show_data.imdb_id,
|
||||
continuous_download=db_show.continuous_download
|
||||
if fresh_show_data.ended is False
|
||||
else False,
|
||||
|
||||
@@ -27,9 +27,15 @@ else:
|
||||
async def get_tmdb_show(show_id: int, language: str = "en"):
|
||||
return TV(show_id).info(language=language)
|
||||
|
||||
@router.get("/tv/shows/{show_id}/external_ids")
|
||||
async def get_tmdb_show_external_ids(show_id: int):
|
||||
return TV(show_id).external_ids()
|
||||
|
||||
@router.get("/tv/shows/{show_id}/{season_number}")
|
||||
async def get_tmdb_season(season_number: int, show_id: int, language: str = "en"):
|
||||
return TV_Seasons(season_number=season_number, tv_id=show_id).info(language=language)
|
||||
return TV_Seasons(season_number=season_number, tv_id=show_id).info(
|
||||
language=language
|
||||
)
|
||||
|
||||
@router.get("/movies/trending")
|
||||
async def get_tmdb_trending_movies(language: str = "en"):
|
||||
@@ -42,3 +48,7 @@ else:
|
||||
@router.get("/movies/{movie_id}")
|
||||
async def get_tmdb_movie(movie_id: int, language: str = "en"):
|
||||
return Movies(movie_id).info(language=language)
|
||||
|
||||
@router.get("/movies/{movie_id}/external_ids")
|
||||
async def get_tmdb_movie_external_ids(movie_id: int):
|
||||
return Movies(movie_id).external_ids()
|
||||
|
||||
6
web/src/lib/api/api.d.ts
vendored
6
web/src/lib/api/api.d.ts
vendored
@@ -1338,6 +1338,8 @@ export interface components {
|
||||
library: string;
|
||||
/** Original Language */
|
||||
original_language?: string | null;
|
||||
/** Imdb Id */
|
||||
imdb_id?: string | null;
|
||||
};
|
||||
/** MovieRequest */
|
||||
MovieRequest: {
|
||||
@@ -1439,6 +1441,8 @@ export interface components {
|
||||
library: string;
|
||||
/** Original Language */
|
||||
original_language?: string | null;
|
||||
/** Imdb Id */
|
||||
imdb_id?: string | null;
|
||||
/**
|
||||
* Downloaded
|
||||
* @default false
|
||||
@@ -1697,6 +1701,8 @@ export interface components {
|
||||
library: string;
|
||||
/** Original Language */
|
||||
original_language?: string | null;
|
||||
/** Imdb Id */
|
||||
imdb_id?: string | null;
|
||||
/** Seasons */
|
||||
seasons: components['schemas']['Season'][];
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user