diff --git a/backend/src/tv/router.py b/backend/src/tv/router.py
index b1a1015..ce54b9c 100644
--- a/backend/src/tv/router.py
+++ b/backend/src/tv/router.py
@@ -12,7 +12,8 @@ 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
+from tv.schemas import Show, SeasonRequest, ShowId, RichShowTorrent, PublicShow, SeasonId, SeasonFile, PublicSeasonFile, \
+ SeasonNumber
router = APIRouter()
@@ -65,11 +66,16 @@ def get_a_show(db: DbSessionDependency, show_id: ShowId):
return tv.service.get_show_by_id(db=db, show_id=show_id)
+@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("/season/request", status_code=status.HTTP_200_OK, dependencies=[Depends(current_active_user)])
+@router.post("/seasons/requests", status_code=status.HTTP_200_OK, dependencies=[Depends(current_active_user)])
def request_a_season(db: DbSessionDependency, season_request: SeasonRequest):
"""
adds request flag to a season
@@ -77,16 +83,25 @@ def request_a_season(db: DbSessionDependency, season_request: SeasonRequest):
tv.service.request_season(db=db, season_request=season_request)
-@router.get("/season/request", status_code=status.HTTP_200_OK, dependencies=[Depends(current_active_user)])
+@router.get("/seasons/requests", status_code=status.HTTP_200_OK, dependencies=[Depends(current_active_user)])
def get_requested_seasons(db: DbSessionDependency) -> list[SeasonRequest]:
return tv.service.get_all_requested_seasons(db=db)
-@router.delete("/season/request", status_code=status.HTTP_200_OK, dependencies=[Depends(current_active_user)])
+@router.delete("/seasons/requests", status_code=status.HTTP_200_OK, dependencies=[Depends(current_active_user)])
def unrequest_season(db: DbSessionDependency, request: SeasonRequest):
tv.service.unrequest_season(db=db, season_request=request)
+# --------------------------------
+# MANAGE SEASON FILES
+# --------------------------------
+
+
+
+
+
+
# --------------------------------
# MANAGE TORRENTS
# --------------------------------
diff --git a/backend/src/tv/schemas.py b/backend/src/tv/schemas.py
index 38c0229..420ec61 100644
--- a/backend/src/tv/schemas.py
+++ b/backend/src/tv/schemas.py
@@ -69,6 +69,10 @@ class SeasonFile(BaseModel):
torrent_id: TorrentId | None
file_path_suffix: str
+
+class PublicSeasonFile(SeasonFile):
+ downloaded: bool = False
+
class RichSeasonTorrent(BaseModel):
model_config = ConfigDict(from_attributes=True)
diff --git a/backend/src/tv/service.py b/backend/src/tv/service.py
index 98cdfca..3251180 100644
--- a/backend/src/tv/service.py
+++ b/backend/src/tv/service.py
@@ -14,7 +14,7 @@ from tv import log
from tv.exceptions import MediaAlreadyExists
from tv.repository import add_season_file, get_season_files_by_season_id
from tv.schemas import Show, ShowId, SeasonRequest, SeasonFile, SeasonId, Season, RichShowTorrent, RichSeasonTorrent, \
- PublicSeason, PublicShow
+ PublicSeason, PublicShow, PublicSeasonFile, SeasonNumber
def add_show(db: Session, external_id: int, metadata_provider: str) -> Show | None:
@@ -34,6 +34,22 @@ def unrequest_season(db: Session, season_request: SeasonRequest) -> None:
tv.repository.remove_season_from_requested_list(db=db, season_request=season_request)
+def get_public_season_files_by_season_id(db: Session, season_id: SeasonId) -> list[PublicSeasonFile]:
+ season_files = get_season_files_by_season_id(db=db, season_id=season_id)
+ public_season_files = [PublicSeasonFile.model_validate(x) for x in season_files]
+ result = []
+ for season_file in public_season_files:
+ if season_file_exists_on_file(db=db, season_file=season_file):
+ season_file.downloaded = True
+ result.append(season_file)
+ return result
+
+
+def get_public_season_files_by_season_number(db: Session, season_number: SeasonNumber, show_id: ShowId) -> list[
+ PublicSeasonFile]:
+ season = tv.repository.get_season_by_number(db=db, season_number=season_number, show_id=show_id)
+ return get_public_season_files_by_season_id(db=db, season_id=season.id)
+
def check_if_show_exists(db: Session,
external_id: int = None,
metadata_provider: str = None,
@@ -95,26 +111,25 @@ def get_show_by_id(db: Session, show_id: ShowId) -> PublicShow:
public_show.seasons = seasons
return public_show
+
def is_season_downloaded(db: Session, season_id: SeasonId) -> bool:
season_files = get_season_files_by_season_id(db=db, season_id=season_id)
for season_file in season_files:
- if season_file.torrent_id is None:
+ if season_file_exists_on_file(db=db, season_file=season_file):
return True
- else:
- torrent_file = torrent.repository.get_torrent_by_id(db=db, torrent_id=season_file.torrent_id)
- if torrent_file.imported:
- return True
return False
-def check_if_season_exists_on_file(db: Session, season_id: SeasonId) -> bool:
- season = tv.repository.get_season(season_id=season_id, db=db)
- if season:
+
+def season_file_exists_on_file(db: Session, season_file: SeasonFile) -> bool:
+ if season_file.torrent_id is None:
return True
else:
- raise ValueError(f"A season with this ID {season_id} does not exist")
-
+ torrent_file = torrent.repository.get_torrent_by_id(db=db, torrent_id=season_file.torrent_id)
+ if torrent_file.imported:
+ return True
+ return False
def get_show_by_external_id(db: Session, external_id: int, metadata_provider: str) -> Show | None:
diff --git a/web/.gitignore b/web/.gitignore
new file mode 100644
index 0000000..1f716b2
--- /dev/null
+++ b/web/.gitignore
@@ -0,0 +1,21 @@
+cache/
+node_modules
+
+.output
+.vercel
+.netlify
+.wrangler
+.svelte-kit
+build
+
+
+.DS_Store
+Thumbs.db
+
+.env
+.env.*
+!.env.example
+!.env.test
+
+vite.config.js.timestamp-*
+vite.config.ts.timestamp-*
diff --git a/web/src/lib/components/app-sidebar.svelte b/web/src/lib/components/app-sidebar.svelte
index be00a3b..eeee2b5 100644
--- a/web/src/lib/components/app-sidebar.svelte
+++ b/web/src/lib/components/app-sidebar.svelte
@@ -4,12 +4,7 @@
import TvIcon from '@lucide/svelte/icons/tv';
import LayoutPanelLeft from '@lucide/svelte/icons/layout-panel-left';
import DownloadIcon from '@lucide/svelte/icons/download';
- import Sun from "@lucide/svelte/icons/sun";
- import Moon from "@lucide/svelte/icons/moon";
- import {resetMode, setMode} from "mode-watcher";
- import {buttonVariants} from "$lib/components/ui/button/index.js";
- import * as DropdownMenu from "$lib/components/ui/dropdown-menu/index.js";
const data = {
navMain: [
{
diff --git a/web/src/lib/components/checkmark-x.svelte b/web/src/lib/components/checkmark-x.svelte
new file mode 100644
index 0000000..4d2f0a1
--- /dev/null
+++ b/web/src/lib/components/checkmark-x.svelte
@@ -0,0 +1,11 @@
+
+{#if state}
+
+ Enter the season's number you want to search for. The first, usually 1, or the
+ last season number usually yield the most season packs. Note that only Seasons
+ which are listed in the "Seasons" cell will be imported!
+
+ This is necessary to differentiate between versions of the same season/show, for
+ example a 1080p and a 4K version of a season.
+
+ {@render saveDirectoryPreview(show, filePathSuffix)}
+
+ No season information available for this show.
+
+ The custom query will override the default search string like "The Simpsons
+ Season 3". Note that only Seasons which are listed in the "Seasons" cell will be
+ imported!
+
+ This is necessary to differentiate between versions of the same season/show, for
+ example a 1080p and a 4K version of a season.
+
+ {@render saveDirectoryPreview(show, filePathSuffix)}
+
+ No season information available for this show.
+ Loading torrents... Error: {torrentsError} No torrents found for season {selectedSeasonNumber}. Try a different season.Found Torrents:
+
{
- e.target.src = logo;
- }}
- />
-
{
+ e.target.src = logo;
+ }}
+ />
+
- {:else}
- - {show.overview} -
-- Enter the season's number you want to search for. The first, usually 1, or the - last season number usually yield the most season packs. Note that only Seasons - which are listed in the "Seasons" cell will be imported! -
- -- This is necessary to differentiate between versions of the same season/show, for - example a 1080p and a 4K version of a season. -
- -- /{getFullyQualifiedShowName(show)} [{show.metadata_provider} - id-{show.external_id} - ]/Season XX/{show.name} SXXEXX {filePathSuffix === '' - ? '' - : ' - ' + filePathSuffix}.mkv -
- {:else} -- No season information available for this show. -
- {/if} -- The custom query will override the default search string like "The Simpsons - Season 3". Note that only Seasons which are listed in the "Seasons" cell will be - imported! -
- - -- This is necessary to differentiate between versions of the same season/show, for - example a 1080p and a 4K version of a season. -
- - -- /{getFullyQualifiedShowName(show)} [{show.metadata_provider} - id-{show.external_id} - ]/Season XX/{show.name} SXXEXX {filePathSuffix === '' - ? '' - : ' - ' + filePathSuffix}.mkv -
- {:else} -- No season information available for this show. -
- {/if} -Loading torrents...
-Error: {torrentsError}
- {:else if torrents.length > 0} -No torrents found for season {selectedSeasonNumber}. Try a different season.
- {/if} -
+ {:else}
+ + {show.overview} +
+{show.overview}