mirror of
https://github.com/maxdorninger/MediaManager.git
synced 2026-04-17 15:13:24 +02:00
add logic to backend to automatically download new seasons
This commit is contained in:
@@ -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 ###
|
||||
@@ -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"
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)],
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user