This commit is contained in:
+11
-4
@@ -16,7 +16,7 @@ from api.models import (
|
||||
MovieUpdateRequest, EpisodeUpdateRequest, BulkUpdateRequest
|
||||
)
|
||||
from api.web_routes import (
|
||||
get_movies_list, get_tv_series_list, get_series_episodes, get_missing_dates_report,
|
||||
get_movies_list, get_tv_series_list, get_series_episodes, get_series_sources, get_missing_dates_report,
|
||||
get_dashboard_stats, update_movie_date, update_episode_date, bulk_update_source,
|
||||
get_movie_date_options, get_episode_date_options
|
||||
)
|
||||
@@ -1043,15 +1043,22 @@ def register_routes(app, dependencies: dict):
|
||||
return await get_movies_list(dependencies, skip, limit, has_date, source_filter, search, imdb_search)
|
||||
|
||||
@app.get("/api/series")
|
||||
async def _series_list(skip: int = 0, limit: int = 50, search: Optional[str] = None):
|
||||
"""Get paginated TV series list"""
|
||||
return await get_tv_series_list(dependencies, skip, limit, search)
|
||||
async def _series_list(skip: int = 0, limit: int = 50, search: Optional[str] = None,
|
||||
imdb_search: Optional[str] = None, date_filter: Optional[str] = None,
|
||||
source_filter: Optional[str] = None):
|
||||
"""Get paginated TV series list with filtering"""
|
||||
return await get_tv_series_list(dependencies, skip, limit, search, imdb_search, date_filter, source_filter)
|
||||
|
||||
@app.get("/api/series/{imdb_id}/episodes")
|
||||
async def _series_episodes(imdb_id: str):
|
||||
"""Get episodes for a specific series"""
|
||||
return await get_series_episodes(dependencies, imdb_id)
|
||||
|
||||
@app.get("/api/series/sources")
|
||||
async def _series_sources():
|
||||
"""Get list of available episode sources for filtering"""
|
||||
return await get_series_sources(dependencies)
|
||||
|
||||
@app.get("/api/reports/missing-dates")
|
||||
async def _missing_dates_report():
|
||||
"""Get report of content missing dateadded"""
|
||||
|
||||
+47
-3
@@ -90,7 +90,10 @@ async def get_movies_list(dependencies: dict,
|
||||
async def get_tv_series_list(dependencies: dict,
|
||||
skip: int = Query(0, ge=0),
|
||||
limit: int = Query(50, le=500),
|
||||
search: Optional[str] = Query(None)):
|
||||
search: Optional[str] = Query(None),
|
||||
imdb_search: Optional[str] = Query(None),
|
||||
date_filter: Optional[str] = Query(None),
|
||||
source_filter: Optional[str] = Query(None)):
|
||||
"""Get paginated list of TV series with episode counts"""
|
||||
db = dependencies["db"]
|
||||
|
||||
@@ -100,12 +103,35 @@ async def get_tv_series_list(dependencies: dict,
|
||||
# Build dynamic query
|
||||
where_conditions = []
|
||||
params = []
|
||||
having_conditions = []
|
||||
having_params = []
|
||||
|
||||
if search:
|
||||
where_conditions.append("(s.imdb_id LIKE ? OR s.path LIKE ?)")
|
||||
params.extend([f"%{search}%", f"%{search}%"])
|
||||
|
||||
if imdb_search:
|
||||
where_conditions.append("s.imdb_id LIKE ?")
|
||||
params.append(f"%{imdb_search}%")
|
||||
|
||||
if source_filter:
|
||||
# Need to check episodes for source filter
|
||||
where_conditions.append("e.source = ?")
|
||||
params.append(source_filter)
|
||||
|
||||
if date_filter:
|
||||
if date_filter == "complete":
|
||||
# All episodes have dates
|
||||
having_conditions.append("COUNT(e.episode) > 0 AND COUNT(CASE WHEN e.dateadded IS NULL OR e.dateadded = '' THEN 1 END) = 0")
|
||||
elif date_filter == "incomplete":
|
||||
# Some episodes have dates, some don't
|
||||
having_conditions.append("COUNT(e.episode) > 0 AND COUNT(CASE WHEN e.dateadded IS NOT NULL AND e.dateadded != '' THEN 1 END) > 0 AND COUNT(CASE WHEN e.dateadded IS NULL OR e.dateadded = '' THEN 1 END) > 0")
|
||||
elif date_filter == "none":
|
||||
# No episodes have dates
|
||||
having_conditions.append("COUNT(e.episode) > 0 AND COUNT(CASE WHEN e.dateadded IS NOT NULL AND e.dateadded != '' THEN 1 END) = 0")
|
||||
|
||||
where_clause = " AND ".join(where_conditions) if where_conditions else "1=1"
|
||||
having_clause = " AND ".join(having_conditions) if having_conditions else ""
|
||||
|
||||
# Get total count
|
||||
count_query = f"SELECT COUNT(*) FROM series s WHERE {where_clause}"
|
||||
@@ -113,6 +139,7 @@ async def get_tv_series_list(dependencies: dict,
|
||||
total_count = cursor.fetchone()[0]
|
||||
|
||||
# Get series with episode statistics
|
||||
having_part = f" HAVING {having_clause}" if having_clause else ""
|
||||
query = f"""
|
||||
SELECT
|
||||
s.imdb_id,
|
||||
@@ -124,11 +151,11 @@ async def get_tv_series_list(dependencies: dict,
|
||||
FROM series s
|
||||
LEFT JOIN episodes e ON s.imdb_id = e.imdb_id
|
||||
WHERE {where_clause}
|
||||
GROUP BY s.imdb_id, s.path, s.last_updated
|
||||
GROUP BY s.imdb_id, s.path, s.last_updated{having_part}
|
||||
ORDER BY s.last_updated DESC
|
||||
LIMIT ? OFFSET ?
|
||||
"""
|
||||
cursor.execute(query, params + [limit, skip])
|
||||
cursor.execute(query, params + having_params + [limit, skip])
|
||||
|
||||
series = []
|
||||
for row in cursor.fetchall():
|
||||
@@ -150,6 +177,23 @@ async def get_tv_series_list(dependencies: dict,
|
||||
}
|
||||
|
||||
|
||||
async def get_series_sources(dependencies: dict):
|
||||
"""Get unique sources from episodes table for filtering"""
|
||||
db = dependencies["db"]
|
||||
|
||||
with db.get_connection() as conn:
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("""
|
||||
SELECT DISTINCT source
|
||||
FROM episodes
|
||||
WHERE source IS NOT NULL AND source != ''
|
||||
ORDER BY source
|
||||
""")
|
||||
|
||||
sources = [row[0] for row in cursor.fetchall()]
|
||||
return {"sources": sources}
|
||||
|
||||
|
||||
async def get_series_episodes(dependencies: dict, imdb_id: str):
|
||||
"""Get all episodes for a specific TV series"""
|
||||
db = dependencies["db"]
|
||||
|
||||
Reference in New Issue
Block a user