add logic to backend to automatically download new seasons

This commit is contained in:
maxDorninger
2025-06-22 14:03:41 +02:00
parent 61cde407ff
commit 87cb9088c4
6 changed files with 102 additions and 5 deletions

View File

@@ -0,0 +1,41 @@
"""add 'continuous_download' column to show table
Revision ID: 1f340754640a
Revises: 7508237d5bc2
Create Date: 2025-06-22 13:46:01.973406
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = "1f340754640a"
down_revision: Union[str, None] = "7508237d5bc2"
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(
"show",
sa.Column(
"continuous_download",
sa.Boolean(),
nullable=False,
server_default=sa.text("false"),
),
)
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column("show", "continuous_download")
# ### end Alembic commands ###

View File

@@ -19,6 +19,7 @@ class Show(Base):
overview: Mapped[str]
year: Mapped[int | None]
ended: Mapped[bool] = mapped_column(default=False)
continuous_download: Mapped[bool] = mapped_column(default=False)
seasons: Mapped[list["Season"]] = relationship(
back_populates="show", cascade="all, delete"

View File

@@ -651,7 +651,9 @@ class TvRepository:
stmt = select(Episode).where(Episode.season_id == season_id).where(Episode.number == episode_data.number)
existing_db_episode = self.db.execute(stmt).scalar_one_or_none()
if existing_db_episode:
log.info(f"Episode {episode_data.number} already exists for season {season_id} (ID: {existing_db_episode.id}). Skipping add.")
log.info(
f"Episode {episode_data.number} already exists for season {season_id} (ID: {existing_db_episode.id}). Skipping add."
)
return EpisodeSchema.model_validate(existing_db_episode)
db_episode = Episode(
@@ -668,7 +670,7 @@ class TvRepository:
log.info(f"Successfully added episode {db_episode.number} (ID: {db_episode.id}) to season {season_id}.")
return EpisodeSchema.model_validate(db_episode)
def update_show_attributes(self, show_id: ShowId, name: str | None = None, overview: str | None = None, year: int | None = None, ended: bool|None = None) -> ShowSchema: # Removed poster_url from params
def update_show_attributes(self, show_id: ShowId, name: str | None = None, overview: str | None = None, year: int | None = None, ended: bool|None = None, continuous_download: bool|None = None) -> ShowSchema: # Removed poster_url from params
"""
Update attributes of an existing show.
@@ -698,6 +700,9 @@ class TvRepository:
if ended is not None and db_show.ended != ended:
db_show.ended = ended
updated = True
if continuous_download is not None and db_show.continuous_download != continuous_download:
db_show.continuous_download = continuous_download
updated = True
if updated:
self.db.commit()

View File

@@ -124,6 +124,23 @@ def get_a_show(show: show_dep, tv_service: tv_service_dep) -> PublicShow:
return tv_service.get_public_show_by_id(show_id=show.id)
@router.post(
"/shows/{show_id}/continuousDownload",
dependencies=[Depends(current_superuser)],
response_model=PublicShow,
)
def set_continuous_download(
show: show_dep, tv_service: tv_service_dep, continuous_download: bool
) -> PublicShow:
"""
Toggles whether future seasons of a show will be downloaded.
"""
tv_service.set_show_continuous_download(
show_id=show.id, continuous_download=continuous_download
)
return tv_service.get_public_show_by_id(show_id=show.id)
@router.get(
"/shows/{show_id}/torrents",
dependencies=[Depends(current_active_user)],

View File

@@ -53,6 +53,8 @@ class Show(BaseModel):
external_id: int
metadata_provider: str
continuous_download: bool = False
seasons: list[Season]
@@ -156,5 +158,6 @@ class PublicShow(BaseModel):
metadata_provider: str
ended: bool = False
continuous_download: bool = False
seasons: list[PublicSeason]

View File

@@ -11,7 +11,7 @@ from media_manager.database import SessionLocal
from media_manager.indexer.schemas import IndexerQueryResult
from media_manager.indexer.schemas import IndexerQueryResultId
from media_manager.metadataProvider.schemas import MetaDataProviderShowSearchResult
from media_manager.torrent.schemas import Torrent, TorrentStatus
from media_manager.torrent.schemas import Torrent, TorrentStatus, Quality
from media_manager.torrent.service import TorrentService
from media_manager.tv import log
from media_manager.tv.schemas import (
@@ -40,7 +40,9 @@ from media_manager.config import BasicConfig
from media_manager.torrent.repository import TorrentRepository
from media_manager.torrent.utils import import_file, import_torrent
from media_manager.indexer.service import IndexerService
from media_manager.metadataProvider.abstractMetaDataProvider import AbstractMetadataProvider
from media_manager.metadataProvider.abstractMetaDataProvider import (
AbstractMetadataProvider,
)
from media_manager.metadataProvider.tmdb import TmdbMetadataProvider
from media_manager.metadataProvider.tvdb import TvdbMetadataProvider
@@ -686,6 +688,19 @@ class TvService:
metadata_provider.download_show_poster_image(show=updated_show)
return updated_show
def set_show_continuous_download(
self, show_id: ShowId, continuous_download: bool
) -> Show:
"""
Set the continuous download flag for a show.
:param show_id: The ID of the show.
:param continuous_download: True to enable continuous download, False to disable.
:return: The updated Show object.
"""
return self.tv_repository.update_show_attributes(
show_id=show_id, continuous_download=continuous_download
)
def auto_download_all_approved_season_requests() -> None:
"""
@@ -790,9 +805,24 @@ def update_all_non_ended_shows_metadata() -> None:
f"Error initializing metadata provider {show.metadata_provider} for show {show.name}: {str(e)}"
)
continue
updated_show = tv_service.update_show_metadata(db_show=show, metadata_provider=metadata_provider)
updated_show = tv_service.update_show_metadata(
db_show=show, metadata_provider=metadata_provider
)
# Automatically add season requests for new seasons
existing_seasons = [x.id for x in show.seasons]
new_seasons = [x for x in updated_show.seasons if x.id not in existing_seasons]
if show.continuous_download:
for new_season in new_seasons:
log.info(
f"Automatically adding season requeest for new season {new_season.number} of show {updated_show.name}"
)
tv_service.add_season_request(SeasonRequest(min_quality=Quality.sd, wanted_quality=Quality.uhd, season_id=new_season.id, authorized=True))
if updated_show:
log.info(f"Successfully updated metadata for show: {updated_show.name}")
log.debug(f"Added new seasons: {len(new_seasons)} to show: {updated_show.name}")
else:
log.warning(f"Failed to update metadata for show: {show.name}")
db.commit()