mirror of
https://github.com/maxdorninger/MediaManager.git
synced 2026-08-04 02:52:16 -04:00
163 lines
7.5 KiB
Python
163 lines
7.5 KiB
Python
from typing import Annotated
|
|
|
|
from fastapi import APIRouter, Depends, status
|
|
from fastapi.responses import JSONResponse
|
|
|
|
import tv.repository
|
|
import tv.service
|
|
from auth.db import User
|
|
from auth.schemas import UserRead
|
|
from auth.users import current_active_user, current_superuser
|
|
from backend.src.database import DbSessionDependency
|
|
from indexer.schemas import PublicIndexerQueryResult, IndexerQueryResultId
|
|
from metadataProvider.schemas import MetaDataProviderShowSearchResult
|
|
from torrent.schemas import Torrent
|
|
from tv.exceptions import MediaAlreadyExists
|
|
from tv.schemas import Show, SeasonRequest, ShowId, RichShowTorrent, PublicShow, PublicSeasonFile, SeasonNumber, \
|
|
CreateSeasonRequest, SeasonRequestId, UpdateSeasonRequest, RichSeasonRequest
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
# --------------------------------
|
|
# CREATE AND DELETE SHOWS
|
|
# --------------------------------
|
|
|
|
@router.post("/shows", status_code=status.HTTP_201_CREATED, dependencies=[Depends(current_active_user)],
|
|
responses={status.HTTP_201_CREATED: {"model": Show, "description": "Successfully created show"},
|
|
status.HTTP_409_CONFLICT: {"model": str, "description": "Show already exists"}, })
|
|
def add_a_show(db: DbSessionDependency, show_id: int, metadata_provider: str = "tmdb"):
|
|
try:
|
|
show = tv.service.add_show(db=db, external_id=show_id, metadata_provider=metadata_provider, )
|
|
except MediaAlreadyExists as e:
|
|
return JSONResponse(status_code=status.HTTP_409_CONFLICT, content={"message": str(e)})
|
|
return show
|
|
|
|
|
|
@router.delete("/shows/{show_id}", status_code=status.HTTP_200_OK, dependencies=[Depends(current_active_user)])
|
|
def delete_a_show(db: DbSessionDependency, show_id: ShowId):
|
|
db.delete(db.get(Show, show_id))
|
|
db.commit()
|
|
|
|
|
|
# --------------------------------
|
|
# GET SHOW INFORMATION
|
|
# --------------------------------
|
|
|
|
@router.get("/shows", dependencies=[Depends(current_active_user)], response_model=list[Show])
|
|
def get_all_shows(db: DbSessionDependency, external_id: int = None, metadata_provider: str = "tmdb"):
|
|
if external_id is not None:
|
|
return tv.service.get_show_by_external_id(db=db, external_id=external_id, metadata_provider=metadata_provider)
|
|
else:
|
|
return tv.service.get_all_shows(db=db)
|
|
|
|
|
|
@router.get("/shows/torrents", dependencies=[Depends(current_active_user)], response_model=list[RichShowTorrent])
|
|
def get_shows_with_torrents(db: DbSessionDependency):
|
|
"""
|
|
get all shows that are associated with torrents
|
|
:return: A list of shows with all their torrents
|
|
"""
|
|
result = tv.service.get_all_shows_with_torrents(db=db)
|
|
return result
|
|
|
|
|
|
@router.get("/shows/{show_id}", dependencies=[Depends(current_active_user)], response_model=PublicShow)
|
|
def get_a_show(db: DbSessionDependency, show_id: ShowId):
|
|
return tv.service.get_public_show_by_id(db=db, show_id=show_id)
|
|
|
|
|
|
@router.get("/shows/{show_id}/torrents", dependencies=[Depends(current_active_user)], response_model=RichShowTorrent)
|
|
def get_a_shows_torrents(db: DbSessionDependency, show_id: ShowId):
|
|
return tv.service.get_torrents_for_show(db=db, show=tv.service.get_show_by_id(db=db, show_id=show_id))
|
|
|
|
|
|
# TODO: replace by route with season_id rather than show_id and season_number
|
|
@router.get("/shows/{show_id}/{season_number}/files", status_code=status.HTTP_200_OK,
|
|
dependencies=[Depends(current_active_user)])
|
|
def get_season_files(db: DbSessionDependency, season_number: SeasonNumber, show_id: ShowId) -> list[PublicSeasonFile]:
|
|
return tv.service.get_public_season_files_by_season_number(db=db, season_number=season_number, show_id=show_id)
|
|
|
|
|
|
# --------------------------------
|
|
# MANAGE REQUESTS
|
|
# --------------------------------
|
|
|
|
@router.post("/seasons/requests", status_code=status.HTTP_204_NO_CONTENT)
|
|
def request_a_season(db: DbSessionDependency, user: Annotated[User, Depends(current_active_user)],
|
|
season_request: CreateSeasonRequest):
|
|
"""
|
|
adds request flag to a season
|
|
"""
|
|
request: SeasonRequest = SeasonRequest.model_validate(season_request)
|
|
request.requested_by = UserRead.model_validate(user)
|
|
|
|
tv.service.request_season(db=db, season_request=request)
|
|
return
|
|
|
|
|
|
@router.get("/seasons/requests", status_code=status.HTTP_200_OK, dependencies=[Depends(current_active_user)],
|
|
response_model=list[RichSeasonRequest])
|
|
def get_season_requests(db: DbSessionDependency) -> list[RichSeasonRequest]:
|
|
return tv.service.get_all_season_requests(db=db)
|
|
|
|
|
|
@router.patch("/seasons/requests/{season_request_id}", status_code=status.HTTP_204_NO_CONTENT)
|
|
def authorize_request(db: DbSessionDependency, user: Annotated[User, Depends(current_superuser)],
|
|
season_request_id: SeasonRequestId, authorized_status: bool = False):
|
|
"""
|
|
updates the request flag to true
|
|
"""
|
|
season_request: SeasonRequest = tv.repository.get_season_request(db=db, season_request_id=season_request_id)
|
|
season_request.authorized_by = UserRead.model_validate(user)
|
|
season_request.authorized = authorized_status
|
|
tv.service.update_season_request(db=db, season_request=season_request)
|
|
return
|
|
|
|
|
|
@router.put("/seasons/requests/{season_request_id}", status_code=status.HTTP_204_NO_CONTENT)
|
|
def update_request(db: DbSessionDependency, user: Annotated[User, Depends(current_superuser)],
|
|
season_request: UpdateSeasonRequest):
|
|
season_request: SeasonRequest = SeasonRequest.model_validate(season_request)
|
|
season_request.requested_by = UserRead.model_validate(user)
|
|
tv.service.update_season_request(db=db, season_request=season_request)
|
|
return
|
|
|
|
|
|
@router.delete("/seasons/requests/{season_request_id}", status_code=status.HTTP_204_NO_CONTENT,
|
|
dependencies=[Depends(current_active_user)])
|
|
def delete_season_request(db: DbSessionDependency, request_id: SeasonRequestId):
|
|
tv.service.delete_season_request(db=db, season_request_id=request_id)
|
|
|
|
|
|
# --------------------------------
|
|
# MANAGE TORRENTS
|
|
# --------------------------------
|
|
|
|
# 1 is the default for season_number because it returns multi season torrents
|
|
@router.get("/torrents", status_code=status.HTTP_200_OK, dependencies=[Depends(current_superuser)],
|
|
response_model=list[PublicIndexerQueryResult])
|
|
def get_torrents_for_a_season(db: DbSessionDependency, show_id: ShowId, season_number: int = 1,
|
|
search_query_override: str = None):
|
|
return tv.service.get_all_available_torrents_for_a_season(db=db, season_number=season_number, show_id=show_id,
|
|
search_query_override=search_query_override)
|
|
|
|
|
|
# download a torrent
|
|
@router.post("/torrents", status_code=status.HTTP_200_OK, response_model=Torrent,
|
|
dependencies=[Depends(current_superuser)])
|
|
def download_a_torrent(db: DbSessionDependency, public_indexer_result_id: IndexerQueryResultId, show_id: ShowId,
|
|
override_file_path_suffix: str = ""):
|
|
return tv.service.download_torrent(db=db, public_indexer_result_id=public_indexer_result_id, show_id=show_id,
|
|
override_show_file_path_suffix=override_file_path_suffix)
|
|
|
|
|
|
# --------------------------------
|
|
# SEARCH SHOWS ON METADATA PROVIDERS
|
|
# --------------------------------
|
|
|
|
@router.get("/search", dependencies=[Depends(current_active_user)],
|
|
response_model=list[MetaDataProviderShowSearchResult])
|
|
def search_metadata_providers_for_a_show(db: DbSessionDependency, query: str, metadata_provider: str = "tmdb"):
|
|
return tv.service.search_for_show(query=query, metadata_provider=metadata_provider, db=db)
|