mirror of
https://github.com/maxdorninger/MediaManager.git
synced 2026-04-17 15:13:24 +02:00
run linter and formatter
This commit is contained in:
@@ -8,8 +8,6 @@ Create Date: 2025-05-27 21:36:18.532068
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "93fb07842385"
|
||||
|
||||
@@ -13,6 +13,4 @@ class JackettConfig(BaseSettings):
|
||||
enabled: bool | None = False
|
||||
api_key: str | None = None
|
||||
url: str = "http://localhost:9696"
|
||||
indexers: list[str] = [
|
||||
"all"
|
||||
]
|
||||
indexers: list[str] = ["all"]
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from typing import Annotated
|
||||
|
||||
from fastapi import Depends, Path
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from media_manager.database import DbSessionDependency
|
||||
from media_manager.tv.repository import TvRepository
|
||||
@@ -27,7 +26,7 @@ tv_service_dep = Annotated[TvService, Depends(get_tv_service)]
|
||||
|
||||
def get_show_by_id(
|
||||
tv_service: tv_service_dep,
|
||||
show_id: ShowId = Path(..., description="The ID of the show")
|
||||
show_id: ShowId = Path(..., description="The ID of the show"),
|
||||
) -> Show:
|
||||
show = tv_service.get_show_by_id(show_id)
|
||||
return show
|
||||
@@ -38,7 +37,7 @@ show_dep = Annotated[Show, Depends(get_show_by_id)]
|
||||
|
||||
def get_season_by_id(
|
||||
tv_service: tv_service_dep,
|
||||
season_id: SeasonId = Path(..., description="The ID of the season")
|
||||
season_id: SeasonId = Path(..., description="The ID of the season"),
|
||||
) -> Season:
|
||||
return tv_service.get_season(season_id=season_id)
|
||||
|
||||
|
||||
@@ -4,4 +4,5 @@ class MediaAlreadyExists(ValueError):
|
||||
|
||||
class NotFoundError(Exception):
|
||||
"""Custom exception for when an entity is not found."""
|
||||
|
||||
pass
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
from sqlalchemy import select, delete
|
||||
from sqlalchemy.exc import IntegrityError, SQLAlchemyError # Keep SQLAlchemyError for broader exception handling
|
||||
from sqlalchemy.exc import (
|
||||
IntegrityError,
|
||||
SQLAlchemyError,
|
||||
) # Keep SQLAlchemyError for broader exception handling
|
||||
from sqlalchemy.orm import Session, joinedload
|
||||
|
||||
from media_manager.torrent.models import Torrent
|
||||
@@ -174,7 +177,9 @@ class TvRepository:
|
||||
except IntegrityError as e:
|
||||
self.db.rollback()
|
||||
log.error(f"Integrity error while saving show {show.name}: {e}")
|
||||
raise ValueError(f"Show with this primary key or unique constraint violation: {e.orig}")
|
||||
raise ValueError(
|
||||
f"Show with this primary key or unique constraint violation: {e.orig}"
|
||||
)
|
||||
except SQLAlchemyError as e:
|
||||
self.db.rollback()
|
||||
log.error(f"Database error while saving show {show.name}: {e}")
|
||||
@@ -275,16 +280,23 @@ class TvRepository:
|
||||
try:
|
||||
request_to_delete = self.db.get(SeasonRequest, season_request_id)
|
||||
if not request_to_delete:
|
||||
log.warning(f"Season request with id {season_request_id} not found for deletion.")
|
||||
raise NotFoundError(f"Season request with id {season_request_id} not found.")
|
||||
log.warning(
|
||||
f"Season request with id {season_request_id} not found for deletion."
|
||||
)
|
||||
raise NotFoundError(
|
||||
f"Season request with id {season_request_id} not found."
|
||||
)
|
||||
|
||||
stmt = delete(SeasonRequest).where(SeasonRequest.id == season_request_id)
|
||||
result = self.db.execute(stmt)
|
||||
if result.rowcount == 0:
|
||||
log.warning(
|
||||
f"Season request with id {season_request_id} not found during delete execution (rowcount 0).")
|
||||
f"Season request with id {season_request_id} not found during delete execution (rowcount 0)."
|
||||
)
|
||||
self.db.commit()
|
||||
log.info(f"Successfully deleted season request with id: {season_request_id}")
|
||||
log.info(
|
||||
f"Successfully deleted season request with id: {season_request_id}"
|
||||
)
|
||||
except SQLAlchemyError as e:
|
||||
self.db.rollback()
|
||||
log.error(
|
||||
@@ -292,9 +304,7 @@ class TvRepository:
|
||||
)
|
||||
raise
|
||||
|
||||
def get_season_by_number(
|
||||
self, season_number: int, show_id: ShowId
|
||||
) -> SeasonSchema:
|
||||
def get_season_by_number(self, season_number: int, show_id: ShowId) -> SeasonSchema:
|
||||
"""
|
||||
Retrieve a season by its number and show ID.
|
||||
|
||||
@@ -348,16 +358,12 @@ class TvRepository:
|
||||
)
|
||||
results = self.db.execute(stmt).scalars().unique().all()
|
||||
log.info(f"Successfully retrieved {len(results)} season requests.")
|
||||
return [
|
||||
RichSeasonRequestSchema.model_validate(x) for x in results
|
||||
]
|
||||
return [RichSeasonRequestSchema.model_validate(x) for x in results]
|
||||
except SQLAlchemyError as e:
|
||||
log.error(f"Database error while retrieving season requests: {e}")
|
||||
raise
|
||||
|
||||
def add_season_file(
|
||||
self, season_file: SeasonFileSchema
|
||||
) -> SeasonFileSchema:
|
||||
def add_season_file(self, season_file: SeasonFileSchema) -> SeasonFileSchema:
|
||||
"""
|
||||
Adds a season file record to the database.
|
||||
|
||||
@@ -374,7 +380,9 @@ class TvRepository:
|
||||
self.db.refresh(db_model)
|
||||
# Assuming SeasonFile model has an 'id' attribute after refresh for logging.
|
||||
# If not, this line or the model needs adjustment.
|
||||
log.info(f"Successfully added season file. Torrent ID: {db_model.torrent_id}, Path: {db_model.file_path}")
|
||||
log.info(
|
||||
f"Successfully added season file. Torrent ID: {db_model.torrent_id}, Path: {db_model.file_path}"
|
||||
)
|
||||
return SeasonFileSchema.model_validate(db_model)
|
||||
except IntegrityError as e:
|
||||
self.db.rollback()
|
||||
@@ -393,9 +401,7 @@ class TvRepository:
|
||||
:return: The number of season files removed.
|
||||
:raises SQLAlchemyError: If a database error occurs.
|
||||
"""
|
||||
log.debug(
|
||||
f"Attempting to remove season files for torrent_id: {torrent_id}"
|
||||
)
|
||||
log.debug(f"Attempting to remove season files for torrent_id: {torrent_id}")
|
||||
try:
|
||||
stmt = delete(SeasonFile).where(SeasonFile.torrent_id == torrent_id)
|
||||
result = self.db.execute(stmt)
|
||||
@@ -429,18 +435,14 @@ class TvRepository:
|
||||
log.info(
|
||||
f"Successfully retrieved {len(results)} season files for season_id: {season_id}"
|
||||
)
|
||||
return [
|
||||
SeasonFileSchema.model_validate(sf) for sf in results
|
||||
]
|
||||
return [SeasonFileSchema.model_validate(sf) for sf in results]
|
||||
except SQLAlchemyError as e:
|
||||
log.error(
|
||||
f"Database error retrieving season files for season_id {season_id}: {e}"
|
||||
)
|
||||
raise
|
||||
|
||||
def get_torrents_by_show_id(
|
||||
self, show_id: ShowId
|
||||
) -> list[TorrentSchema]:
|
||||
def get_torrents_by_show_id(self, show_id: ShowId) -> list[TorrentSchema]:
|
||||
"""
|
||||
Retrieve all torrents associated with a given show ID.
|
||||
|
||||
@@ -463,9 +465,7 @@ class TvRepository:
|
||||
)
|
||||
return [TorrentSchema.model_validate(torrent) for torrent in results]
|
||||
except SQLAlchemyError as e:
|
||||
log.error(
|
||||
f"Database error retrieving torrents for show_id {show_id}: {e}"
|
||||
)
|
||||
log.error(f"Database error retrieving torrents for show_id {show_id}: {e}")
|
||||
raise
|
||||
|
||||
def get_all_shows_with_torrents(self) -> list[ShowSchema]:
|
||||
@@ -493,9 +493,7 @@ class TvRepository:
|
||||
log.error(f"Database error retrieving all shows with torrents: {e}")
|
||||
raise
|
||||
|
||||
def get_seasons_by_torrent_id(
|
||||
self, torrent_id: TorrentId
|
||||
) -> list[SeasonNumber]:
|
||||
def get_seasons_by_torrent_id(self, torrent_id: TorrentId) -> list[SeasonNumber]:
|
||||
"""
|
||||
Retrieve season numbers associated with a given torrent ID.
|
||||
|
||||
@@ -533,15 +531,11 @@ class TvRepository:
|
||||
:raises NotFoundError: If the season request is not found.
|
||||
:raises SQLAlchemyError: If a database error occurs.
|
||||
"""
|
||||
log.debug(
|
||||
f"Attempting to retrieve season request with id: {season_request_id}"
|
||||
)
|
||||
log.debug(f"Attempting to retrieve season request with id: {season_request_id}")
|
||||
try:
|
||||
request = self.db.get(SeasonRequest, season_request_id)
|
||||
if not request:
|
||||
log.warning(
|
||||
f"Season request with id {season_request_id} not found."
|
||||
)
|
||||
log.warning(f"Season request with id {season_request_id} not found.")
|
||||
raise NotFoundError(
|
||||
f"Season request with id {season_request_id} not found."
|
||||
)
|
||||
@@ -579,7 +573,5 @@ class TvRepository:
|
||||
log.info(f"Successfully retrieved show for season_id: {season_id}")
|
||||
return ShowSchema.model_validate(result)
|
||||
except SQLAlchemyError as e:
|
||||
log.error(
|
||||
f"Database error retrieving show by season_id {season_id}: {e}"
|
||||
)
|
||||
log.error(f"Database error retrieving show by season_id {season_id}: {e}")
|
||||
raise
|
||||
|
||||
@@ -23,7 +23,12 @@ from media_manager.tv.schemas import (
|
||||
UpdateSeasonRequest,
|
||||
RichSeasonRequest,
|
||||
)
|
||||
from media_manager.tv.dependencies import tv_service_dep, season_dep, show_dep, tv_repository_dep
|
||||
from media_manager.tv.dependencies import (
|
||||
tv_service_dep,
|
||||
season_dep,
|
||||
show_dep,
|
||||
tv_repository_dep,
|
||||
)
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@@ -45,7 +50,9 @@ router = APIRouter()
|
||||
status.HTTP_409_CONFLICT: {"model": str, "description": "Show already exists"},
|
||||
},
|
||||
)
|
||||
def add_a_show(tv_service: tv_service_dep, show_id: int, metadata_provider: str = "tmdb"):
|
||||
def add_a_show(
|
||||
tv_service: tv_service_dep, show_id: int, metadata_provider: str = "tmdb"
|
||||
):
|
||||
try:
|
||||
show = tv_service.add_show(
|
||||
external_id=show_id,
|
||||
@@ -118,9 +125,6 @@ def get_a_shows_torrents(show: show_dep, tv_service: tv_service_dep):
|
||||
return tv_service.get_torrents_for_show(show=show)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# --------------------------------
|
||||
# MANAGE REQUESTS
|
||||
# --------------------------------
|
||||
@@ -163,13 +167,9 @@ def delete_season_request(
|
||||
user: Annotated[User, Depends(current_active_user)],
|
||||
request_id: SeasonRequestId,
|
||||
):
|
||||
request = tv_service.get_season_request_by_id(
|
||||
season_request_id=request_id
|
||||
)
|
||||
request = tv_service.get_season_request_by_id(season_request_id=request_id)
|
||||
if user.is_superuser or request.requested_by.id == user.id:
|
||||
tv_service.delete_season_request(
|
||||
season_request_id=request_id
|
||||
)
|
||||
tv_service.delete_season_request(season_request_id=request_id)
|
||||
log.info(f"User {user.id} deleted season request {request_id}.")
|
||||
else:
|
||||
log.warning(
|
||||
@@ -216,21 +216,21 @@ def update_request(
|
||||
)
|
||||
if request.requested_by.id == user.id or user.is_superuser:
|
||||
updated_season_request.requested_by = UserRead.model_validate(user)
|
||||
tv_service.update_season_request(
|
||||
season_request=updated_season_request
|
||||
)
|
||||
tv_service.update_season_request(season_request=updated_season_request)
|
||||
return
|
||||
|
||||
|
||||
@router.get(
|
||||
"/seasons/{season_id}/files",
|
||||
dependencies=[Depends(current_active_user)],
|
||||
response_model=list[PublicSeasonFile]
|
||||
response_model=list[PublicSeasonFile],
|
||||
)
|
||||
def get_season_files(
|
||||
season: season_dep, tv_service: tv_service_dep
|
||||
) -> list[PublicSeasonFile]:
|
||||
return tv_service.get_public_season_files_by_season_id(season_id=season.id)
|
||||
|
||||
|
||||
# --------------------------------
|
||||
# MANAGE TORRENTS
|
||||
# --------------------------------
|
||||
@@ -289,9 +289,7 @@ def download_a_torrent(
|
||||
def search_metadata_providers_for_a_show(
|
||||
tv_service: tv_service_dep, query: str, metadata_provider: str = "tmdb"
|
||||
):
|
||||
return tv_service.search_for_show(
|
||||
query=query, metadata_provider=metadata_provider
|
||||
)
|
||||
return tv_service.search_for_show(query=query, metadata_provider=metadata_provider)
|
||||
|
||||
|
||||
@router.get(
|
||||
@@ -300,6 +298,4 @@ def search_metadata_providers_for_a_show(
|
||||
response_model=list[MetaDataProviderShowSearchResult],
|
||||
)
|
||||
def get_recommended_shows(tv_service: tv_service_dep, metadata_provider: str = "tmdb"):
|
||||
return tv_service.get_popular_shows(
|
||||
metadata_provider=metadata_provider
|
||||
)
|
||||
return tv_service.get_popular_shows(metadata_provider=metadata_provider)
|
||||
|
||||
@@ -11,7 +11,6 @@ from media_manager.torrent.repository import get_seasons_files_of_torrent
|
||||
from media_manager.torrent.schemas import Torrent
|
||||
from media_manager.torrent.service import TorrentService
|
||||
from media_manager.tv import log
|
||||
from media_manager.tv.exceptions import MediaAlreadyExists
|
||||
from media_manager.tv.schemas import (
|
||||
Show,
|
||||
ShowId,
|
||||
@@ -24,12 +23,12 @@ from media_manager.tv.schemas import (
|
||||
PublicSeason,
|
||||
PublicShow,
|
||||
PublicSeasonFile,
|
||||
SeasonNumber,
|
||||
SeasonRequestId,
|
||||
RichSeasonRequest,
|
||||
)
|
||||
from media_manager.torrent.schemas import QualityStrings
|
||||
from media_manager.tv.repository import TvRepository
|
||||
from tv.exceptions import NotFoundError
|
||||
|
||||
|
||||
class TvService:
|
||||
@@ -59,14 +58,18 @@ class TvService:
|
||||
"""
|
||||
return self.tv_repository.add_season_request(season_request=season_request)
|
||||
|
||||
def get_season_request_by_id(self, season_request_id: SeasonRequestId) -> SeasonRequest | None:
|
||||
def get_season_request_by_id(
|
||||
self, season_request_id: SeasonRequestId
|
||||
) -> SeasonRequest | None:
|
||||
"""
|
||||
Get a season request by its ID.
|
||||
|
||||
:param season_request_id: The ID of the season request.
|
||||
:return: The season request or None if not found.
|
||||
"""
|
||||
return self.tv_repository.get_season_request(season_request_id=season_request_id)
|
||||
return self.tv_repository.get_season_request(
|
||||
season_request_id=season_request_id
|
||||
)
|
||||
|
||||
def update_season_request(self, season_request: SeasonRequest) -> SeasonRequest:
|
||||
"""
|
||||
@@ -86,14 +89,18 @@ class TvService:
|
||||
"""
|
||||
self.tv_repository.delete_season_request(season_request_id=season_request_id)
|
||||
|
||||
def get_public_season_files_by_season_id(self, season_id: SeasonId) -> list[PublicSeasonFile]:
|
||||
def get_public_season_files_by_season_id(
|
||||
self, season_id: SeasonId
|
||||
) -> list[PublicSeasonFile]:
|
||||
"""
|
||||
Get all public season files for a given season ID.
|
||||
|
||||
:param season_id: The ID of the season.
|
||||
:return: A list of public season files.
|
||||
"""
|
||||
season_files = self.tv_repository.get_season_files_by_season_id(season_id=season_id)
|
||||
season_files = self.tv_repository.get_season_files_by_season_id(
|
||||
season_id=season_id
|
||||
)
|
||||
public_season_files = [PublicSeasonFile.model_validate(x) for x in season_files]
|
||||
result = []
|
||||
for season_file in public_season_files:
|
||||
@@ -102,8 +109,12 @@ class TvService:
|
||||
result.append(season_file)
|
||||
return result
|
||||
|
||||
def check_if_show_exists(self, external_id: int = None, metadata_provider: str = None,
|
||||
show_id: ShowId = None) -> bool:
|
||||
def check_if_show_exists(
|
||||
self,
|
||||
external_id: int = None,
|
||||
metadata_provider: str = None,
|
||||
show_id: ShowId = None,
|
||||
) -> bool:
|
||||
"""
|
||||
Check if a show exists in the database.
|
||||
|
||||
@@ -115,21 +126,26 @@ class TvService:
|
||||
"""
|
||||
if external_id and metadata_provider:
|
||||
try:
|
||||
self.tv_repository.get_show_by_external_id(external_id=external_id, metadata_provider=metadata_provider)
|
||||
self.tv_repository.get_show_by_external_id(
|
||||
external_id=external_id, metadata_provider=metadata_provider
|
||||
)
|
||||
return True
|
||||
except:
|
||||
except NotFoundError:
|
||||
return False
|
||||
elif show_id:
|
||||
try:
|
||||
self.tv_repository.get_show_by_id(show_id=show_id)
|
||||
return True
|
||||
except:
|
||||
except NotFoundError:
|
||||
return False
|
||||
else:
|
||||
raise ValueError("External ID and metadata provider or Show ID must be provided")
|
||||
raise ValueError(
|
||||
"External ID and metadata provider or Show ID must be provided"
|
||||
)
|
||||
|
||||
def get_all_available_torrents_for_a_season(self, season_number: int, show_id: ShowId,
|
||||
search_query_override: str = None) -> list[IndexerQueryResult]:
|
||||
def get_all_available_torrents_for_a_season(
|
||||
self, season_number: int, show_id: ShowId, search_query_override: str = None
|
||||
) -> list[IndexerQueryResult]:
|
||||
"""
|
||||
Get all available torrents for a given season.
|
||||
|
||||
@@ -138,7 +154,9 @@ class TvService:
|
||||
:param search_query_override: Optional override for the search query.
|
||||
:return: A list of indexer query results.
|
||||
"""
|
||||
log.debug(f"getting all available torrents for season {season_number} for show {show_id}")
|
||||
log.debug(
|
||||
f"getting all available torrents for season {season_number} for show {show_id}"
|
||||
)
|
||||
show = self.tv_repository.get_show_by_id(show_id=show_id)
|
||||
if search_query_override:
|
||||
search_query = search_query_override
|
||||
@@ -146,11 +164,14 @@ class TvService:
|
||||
# TODO: add more Search query strings and combine all the results, like "season 3", "s03", "s3"
|
||||
search_query = show.name + " s" + str(season_number).zfill(2)
|
||||
|
||||
torrents: list[IndexerQueryResult] = media_manager.indexer.service.search(query=search_query,
|
||||
db=self.tv_repository.db)
|
||||
torrents: list[IndexerQueryResult] = media_manager.indexer.service.search(
|
||||
query=search_query, db=self.tv_repository.db
|
||||
)
|
||||
|
||||
if search_query_override:
|
||||
log.debug(f"Found with search query override {torrents.__len__()} torrents: {torrents}")
|
||||
log.debug(
|
||||
f"Found with search query override {torrents.__len__()} torrents: {torrents}"
|
||||
)
|
||||
return torrents
|
||||
|
||||
result: list[IndexerQueryResult] = []
|
||||
@@ -168,7 +189,9 @@ class TvService:
|
||||
"""
|
||||
return self.tv_repository.get_shows()
|
||||
|
||||
def search_for_show(self, query: str, metadata_provider: str) -> list[MetaDataProviderShowSearchResult]:
|
||||
def search_for_show(
|
||||
self, query: str, metadata_provider: str
|
||||
) -> list[MetaDataProviderShowSearchResult]:
|
||||
"""
|
||||
Search for shows using a given query.
|
||||
|
||||
@@ -178,11 +201,15 @@ class TvService:
|
||||
"""
|
||||
results = media_manager.metadataProvider.search_show(query, metadata_provider)
|
||||
for result in results:
|
||||
if self.check_if_show_exists(external_id=result.external_id, metadata_provider=metadata_provider):
|
||||
if self.check_if_show_exists(
|
||||
external_id=result.external_id, metadata_provider=metadata_provider
|
||||
):
|
||||
result.added = True
|
||||
return results
|
||||
|
||||
def get_popular_shows(self, metadata_provider: str) -> list[MetaDataProviderShowSearchResult]:
|
||||
def get_popular_shows(
|
||||
self, metadata_provider: str
|
||||
) -> list[MetaDataProviderShowSearchResult]:
|
||||
"""
|
||||
Get popular shows from a given metadata provider.
|
||||
|
||||
@@ -195,7 +222,9 @@ class TvService:
|
||||
|
||||
filtered_results = []
|
||||
for result in results:
|
||||
if not self.check_if_show_exists(external_id=result.external_id, metadata_provider=metadata_provider):
|
||||
if not self.check_if_show_exists(
|
||||
external_id=result.external_id, metadata_provider=metadata_provider
|
||||
):
|
||||
filtered_results.append(result)
|
||||
|
||||
return filtered_results
|
||||
@@ -231,7 +260,9 @@ class TvService:
|
||||
:param season_id: The ID of the season.
|
||||
:return: True if the season is downloaded, False otherwise.
|
||||
"""
|
||||
season_files = self.tv_repository.get_season_files_by_season_id(season_id=season_id)
|
||||
season_files = self.tv_repository.get_season_files_by_season_id(
|
||||
season_id=season_id
|
||||
)
|
||||
for season_file in season_files:
|
||||
if self.season_file_exists_on_file(season_file=season_file):
|
||||
return True
|
||||
@@ -254,7 +285,9 @@ class TvService:
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_show_by_external_id(self, external_id: int, metadata_provider: str) -> Show | None:
|
||||
def get_show_by_external_id(
|
||||
self, external_id: int, metadata_provider: str
|
||||
) -> Show | None:
|
||||
"""
|
||||
Get a show by its external ID and metadata provider.
|
||||
|
||||
@@ -293,8 +326,12 @@ class TvService:
|
||||
show_torrents = self.tv_repository.get_torrents_by_show_id(show_id=show.id)
|
||||
rich_season_torrents = []
|
||||
for show_torrent in show_torrents:
|
||||
seasons = self.tv_repository.get_seasons_by_torrent_id(torrent_id=show_torrent.id)
|
||||
season_files = get_seasons_files_of_torrent(db=self.tv_repository.db, torrent_id=show_torrent.id)
|
||||
seasons = self.tv_repository.get_seasons_by_torrent_id(
|
||||
torrent_id=show_torrent.id
|
||||
)
|
||||
season_files = get_seasons_files_of_torrent(
|
||||
db=self.tv_repository.db, torrent_id=show_torrent.id
|
||||
)
|
||||
file_path_suffix = season_files[0].file_path_suffix if season_files else ""
|
||||
season_torrent = RichSeasonTorrent(
|
||||
torrent_id=show_torrent.id,
|
||||
@@ -323,8 +360,12 @@ class TvService:
|
||||
shows = self.tv_repository.get_all_shows_with_torrents()
|
||||
return [self.get_torrents_for_show(show=show) for show in shows]
|
||||
|
||||
def download_torrent(self, public_indexer_result_id: IndexerQueryResultId, show_id: ShowId,
|
||||
override_show_file_path_suffix: str = "") -> Torrent:
|
||||
def download_torrent(
|
||||
self,
|
||||
public_indexer_result_id: IndexerQueryResultId,
|
||||
show_id: ShowId,
|
||||
override_show_file_path_suffix: str = "",
|
||||
) -> Torrent:
|
||||
"""
|
||||
Download a torrent for a given indexer result and show.
|
||||
|
||||
@@ -336,10 +377,14 @@ class TvService:
|
||||
indexer_result = media_manager.indexer.service.get_indexer_query_result(
|
||||
db=self.tv_repository.db, result_id=public_indexer_result_id
|
||||
)
|
||||
show_torrent = TorrentService(db=self.tv_repository.db).download(indexer_result=indexer_result)
|
||||
show_torrent = TorrentService(db=self.tv_repository.db).download(
|
||||
indexer_result=indexer_result
|
||||
)
|
||||
|
||||
for season_number in indexer_result.season:
|
||||
season = self.tv_repository.get_season_by_number(season_number=season_number, show_id=show_id)
|
||||
season = self.tv_repository.get_season_by_number(
|
||||
season_number=season_number, show_id=show_id
|
||||
)
|
||||
season_file = SeasonFile(
|
||||
season_id=season.id,
|
||||
quality=indexer_result.quality,
|
||||
@@ -349,7 +394,9 @@ class TvService:
|
||||
self.tv_repository.add_season_file(season_file=season_file)
|
||||
return show_torrent
|
||||
|
||||
def download_approved_season_request(self, season_request: SeasonRequest, show: Show) -> bool:
|
||||
def download_approved_season_request(
|
||||
self, season_request: SeasonRequest, show: Show
|
||||
) -> bool:
|
||||
"""
|
||||
Download an approved season request.
|
||||
|
||||
@@ -359,19 +406,27 @@ class TvService:
|
||||
:raises ValueError: If the season request is not authorized.
|
||||
"""
|
||||
if not season_request.authorized:
|
||||
log.error(f"Season request {season_request.id} is not authorized for download")
|
||||
raise ValueError(f"Season request {season_request.id} is not authorized for download")
|
||||
log.error(
|
||||
f"Season request {season_request.id} is not authorized for download"
|
||||
)
|
||||
raise ValueError(
|
||||
f"Season request {season_request.id} is not authorized for download"
|
||||
)
|
||||
|
||||
log.info(f"Downloading approved season request {season_request.id}")
|
||||
|
||||
season = self.get_season(season_id=season_request.season_id)
|
||||
torrents = self.get_all_available_torrents_for_a_season(season_number=season.number, show_id=show.id)
|
||||
torrents = self.get_all_available_torrents_for_a_season(
|
||||
season_number=season.number, show_id=show.id
|
||||
)
|
||||
available_torrents: list[IndexerQueryResult] = []
|
||||
|
||||
for torrent in torrents:
|
||||
if (torrent.quality > season_request.wanted_quality or
|
||||
torrent.quality < season_request.min_quality or
|
||||
torrent.seeders < 3):
|
||||
if (
|
||||
torrent.quality > season_request.wanted_quality
|
||||
or torrent.quality < season_request.min_quality
|
||||
or torrent.seeders < 3
|
||||
):
|
||||
log.info(
|
||||
f"Skipping torrent {torrent.title} with quality {torrent.quality} for season {season.id}, because it does not match the requested quality {season_request.wanted_quality}"
|
||||
)
|
||||
@@ -393,7 +448,9 @@ class TvService:
|
||||
|
||||
available_torrents.sort()
|
||||
|
||||
torrent = TorrentService(db=self.tv_repository.db).download(indexer_result=available_torrents[0])
|
||||
torrent = TorrentService(db=self.tv_repository.db).download(
|
||||
indexer_result=available_torrents[0]
|
||||
)
|
||||
season_file = SeasonFile(
|
||||
season_id=season.id,
|
||||
quality=torrent.quality,
|
||||
@@ -421,11 +478,17 @@ def auto_download_all_approved_season_requests() -> None:
|
||||
for season_request in season_requests:
|
||||
if season_request.authorized:
|
||||
log.info(f"Processing season request {season_request.id} for download")
|
||||
show = tv_repository.get_show_by_season_id(season_id=season_request.season_id)
|
||||
if tv_service.download_approved_season_request(season_request=season_request, show_id=show.id):
|
||||
show = tv_repository.get_show_by_season_id(
|
||||
season_id=season_request.season_id
|
||||
)
|
||||
if tv_service.download_approved_season_request(
|
||||
season_request=season_request, show_id=show.id
|
||||
):
|
||||
count += 1
|
||||
else:
|
||||
log.warning(f"Failed to download season request {season_request.id} for show {show.name}")
|
||||
log.warning(
|
||||
f"Failed to download season request {season_request.id} for show {show.name}"
|
||||
)
|
||||
|
||||
log.info(f"Auto downloaded {count} approved season requests")
|
||||
db.close()
|
||||
|
||||
Reference in New Issue
Block a user