web: fixes
Local Docker Build (Dev) / build-dev (push) Successful in 4s

This commit is contained in:
2025-10-19 12:20:34 -04:00
parent 3c4cac6177
commit 8ef4d1076c
2 changed files with 92 additions and 186 deletions
+91 -185
View File
@@ -82,26 +82,22 @@ async def get_movies_list(dependencies: dict,
if has_date is not None:
if has_date:
if db.db_type == "postgresql":
where_conditions.append("dateadded IS NOT NULL")
else:
where_conditions.append("dateadded IS NOT NULL AND dateadded != ''")
# PostgreSQL - NULL handling
where_conditions.append("dateadded IS NOT NULL")
else:
if db.db_type == "postgresql":
where_conditions.append("dateadded IS NULL")
else:
where_conditions.append("(dateadded IS NULL OR dateadded = '')")
# PostgreSQL - NULL handling
where_conditions.append("dateadded IS NULL")
if source_filter:
where_conditions.append("source = ?")
where_conditions.append("source = %s")
params.append(source_filter)
if search:
where_conditions.append("(imdb_id LIKE ? OR path LIKE ?)")
where_conditions.append("(imdb_id LIKE %s OR path LIKE %s)")
params.extend([f"%{search}%", f"%{search}%"])
if imdb_search:
where_conditions.append("imdb_id LIKE ?")
where_conditions.append("imdb_id LIKE %s")
params.append(f"%{imdb_search}%")
where_clause = " AND ".join(where_conditions) if where_conditions else "1=1"
@@ -111,23 +107,14 @@ async def get_movies_list(dependencies: dict,
cursor.execute(count_query, params)
total_count = db._get_first_value(cursor.fetchone())
# Get paginated results
if db.db_type == "postgresql":
query = f"""
SELECT imdb_id, path, released, dateadded, source, has_video_file, last_updated
FROM movies
WHERE {where_clause}
ORDER BY last_updated DESC
LIMIT %s OFFSET %s
"""
else:
query = f"""
SELECT imdb_id, path, released, dateadded, source, has_video_file, last_updated
FROM movies
WHERE {where_clause}
ORDER BY last_updated DESC
LIMIT ? OFFSET ?
"""
# Get paginated results - PostgreSQL
query = f"""
SELECT imdb_id, path, released, dateadded, source, has_video_file, last_updated
FROM movies
WHERE {where_clause}
ORDER BY last_updated DESC
LIMIT %s OFFSET %s
"""
cursor.execute(query, params + [limit, skip])
movies = []
@@ -171,16 +158,16 @@ async def get_tv_series_list(dependencies: dict,
having_conditions = []
if search:
where_conditions.append("(s.imdb_id LIKE ? OR s.path LIKE ?)")
where_conditions.append("(s.imdb_id LIKE %s OR s.path LIKE %s)")
params.extend([f"%{search}%", f"%{search}%"])
if imdb_search:
where_conditions.append("s.imdb_id LIKE ?")
where_conditions.append("s.imdb_id LIKE %s")
params.append(f"%{imdb_search}%")
if source_filter:
# Need to check episodes for source filter
where_conditions.append("e.source = ?")
where_conditions.append("e.source = %s")
params.append(source_filter)
if date_filter:
@@ -219,38 +206,22 @@ async def get_tv_series_list(dependencies: dict,
# Get series with episode statistics
having_part = f" HAVING {having_clause}" if having_clause else ""
if db.db_type == "postgresql":
query = f"""
SELECT
s.imdb_id,
s.path,
s.last_updated,
COUNT(e.episode) as total_episodes,
COUNT(CASE WHEN e.dateadded IS NOT NULL THEN 1 END) as episodes_with_dates,
COUNT(CASE WHEN e.has_video_file = TRUE THEN 1 END) as episodes_with_video
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{having_part}
ORDER BY s.last_updated DESC
LIMIT %s OFFSET %s
"""
else:
query = f"""
SELECT
s.imdb_id,
s.path,
s.last_updated,
COUNT(e.episode) as total_episodes,
COUNT(CASE WHEN e.dateadded IS NOT NULL AND e.dateadded != '' THEN 1 END) as episodes_with_dates,
COUNT(CASE WHEN e.has_video_file = 1 THEN 1 END) as episodes_with_video
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{having_part}
ORDER BY s.last_updated DESC
LIMIT ? OFFSET ?
"""
# PostgreSQL query
query = f"""
SELECT
s.imdb_id,
s.path,
s.last_updated,
COUNT(e.episode) as total_episodes,
COUNT(CASE WHEN e.dateadded IS NOT NULL THEN 1 END) as episodes_with_dates,
COUNT(CASE WHEN e.has_video_file = TRUE THEN 1 END) as episodes_with_video
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{having_part}
ORDER BY s.last_updated DESC
LIMIT %s OFFSET %s
"""
cursor.execute(query, params + [limit, skip])
series = []
@@ -287,10 +258,8 @@ async def get_series_sources(dependencies: dict):
""")
rows = cursor.fetchall()
if db.db_type == "postgresql":
sources = [list(row.values())[0] for row in rows]
else:
sources = [row[0] for row in rows]
# PostgreSQL RealDictCursor returns dict-like objects
sources = [list(row.values())[0] for row in rows]
return {"sources": sources}
@@ -360,11 +329,8 @@ async def get_series_episodes(dependencies: dict, imdb_id: str):
with db.get_connection() as conn:
cursor = conn.cursor()
# Get series info
if db.db_type == "postgresql":
cursor.execute("SELECT * FROM series WHERE imdb_id = %s", (imdb_id,))
else:
cursor.execute("SELECT * FROM series WHERE imdb_id = ?", (imdb_id,))
# Get series info - PostgreSQL
cursor.execute("SELECT * FROM series WHERE imdb_id = %s", (imdb_id,))
series_row = cursor.fetchone()
if not series_row:
raise HTTPException(status_code=404, detail="Series not found")
@@ -375,21 +341,13 @@ async def get_series_episodes(dependencies: dict, imdb_id: str):
except:
series_info['title'] = imdb_id
# Get episodes
if db.db_type == "postgresql":
cursor.execute("""
SELECT season, episode, aired, dateadded, source, has_video_file, last_updated
FROM episodes
WHERE imdb_id = %s
ORDER BY season, episode
""", (imdb_id,))
else:
cursor.execute("""
SELECT season, episode, aired, dateadded, source, has_video_file, last_updated
FROM episodes
WHERE imdb_id = ?
ORDER BY season, episode
""", (imdb_id,))
# Get episodes - PostgreSQL
cursor.execute("""
SELECT season, episode, aired, dateadded, source, has_video_file, last_updated
FROM episodes
WHERE imdb_id = %s
ORDER BY season, episode
""", (imdb_id,))
episodes = []
for row in cursor.fetchall():
@@ -411,21 +369,13 @@ async def get_missing_dates_report(dependencies: dict):
with db.get_connection() as conn:
cursor = conn.cursor()
# Movies without dates - PostgreSQL compatible
if db.db_type == "postgresql":
cursor.execute("""
SELECT imdb_id, path, released, source, last_updated
FROM movies
WHERE dateadded IS NULL OR source = 'no_valid_date_source'
ORDER BY last_updated DESC
""")
else:
cursor.execute("""
SELECT imdb_id, path, released, source, last_updated
FROM movies
WHERE dateadded IS NULL OR dateadded = '' OR source = 'no_valid_date_source'
ORDER BY last_updated DESC
""")
# Movies without dates - PostgreSQL
cursor.execute("""
SELECT imdb_id, path, released, source, last_updated
FROM movies
WHERE dateadded IS NULL OR source = 'no_valid_date_source'
ORDER BY last_updated DESC
""")
movies_missing = []
for row in cursor.fetchall():
movie = dict(row)
@@ -437,23 +387,14 @@ async def get_missing_dates_report(dependencies: dict):
movie['source_description'] = map_source_to_description(movie.get('source'))
movies_missing.append(movie)
# Episodes without dates - PostgreSQL compatible
if db.db_type == "postgresql":
cursor.execute("""
SELECT e.imdb_id, e.season, e.episode, e.aired, e.source, e.last_updated, s.path
FROM episodes e
JOIN series s ON e.imdb_id = s.imdb_id
WHERE e.dateadded IS NULL OR e.source = 'no_valid_date_source'
ORDER BY e.last_updated DESC
""")
else:
cursor.execute("""
SELECT e.imdb_id, e.season, e.episode, e.aired, e.source, e.last_updated, s.path
FROM episodes e
JOIN series s ON e.imdb_id = s.imdb_id
WHERE e.dateadded IS NULL OR e.dateadded = '' OR e.source = 'no_valid_date_source'
ORDER BY e.last_updated DESC
""")
# Episodes without dates - PostgreSQL
cursor.execute("""
SELECT e.imdb_id, e.season, e.episode, e.aired, e.source, e.last_updated, s.path
FROM episodes e
JOIN series s ON e.imdb_id = s.imdb_id
WHERE e.dateadded IS NULL OR e.source = 'no_valid_date_source'
ORDER BY e.last_updated DESC
""")
episodes_missing = []
for row in cursor.fetchall():
episode = dict(row)
@@ -465,25 +406,15 @@ async def get_missing_dates_report(dependencies: dict):
episode['source_description'] = map_source_to_description(episode.get('source'))
episodes_missing.append(episode)
# Summary statistics - PostgreSQL compatible
if db.db_type == "postgresql":
cursor.execute("SELECT COUNT(*) FROM movies WHERE dateadded IS NOT NULL")
movies_with_dates = db._get_first_value(cursor.fetchone())
cursor.execute("SELECT COUNT(*) FROM movies")
total_movies = db._get_first_value(cursor.fetchone())
cursor.execute("SELECT COUNT(*) FROM episodes WHERE dateadded IS NOT NULL")
episodes_with_dates = db._get_first_value(cursor.fetchone())
else:
cursor.execute("SELECT COUNT(*) FROM movies WHERE dateadded IS NOT NULL AND dateadded != ''")
movies_with_dates = db._get_first_value(cursor.fetchone())
cursor.execute("SELECT COUNT(*) FROM movies")
total_movies = db._get_first_value(cursor.fetchone())
cursor.execute("SELECT COUNT(*) FROM episodes WHERE dateadded IS NOT NULL AND dateadded != ''")
episodes_with_dates = db._get_first_value(cursor.fetchone())
# Summary statistics - PostgreSQL
cursor.execute("SELECT COUNT(*) FROM movies WHERE dateadded IS NOT NULL")
movies_with_dates = db._get_first_value(cursor.fetchone())
cursor.execute("SELECT COUNT(*) FROM movies")
total_movies = db._get_first_value(cursor.fetchone())
cursor.execute("SELECT COUNT(*) FROM episodes WHERE dateadded IS NOT NULL")
episodes_with_dates = db._get_first_value(cursor.fetchone())
cursor.execute("SELECT COUNT(*) FROM episodes")
total_episodes = db._get_first_value(cursor.fetchone())
@@ -512,31 +443,18 @@ async def get_dashboard_stats(dependencies: dict):
with db.get_connection() as conn:
cursor = conn.cursor()
# Enhanced statistics - PostgreSQL compatible
if db.db_type == "postgresql":
cursor.execute("SELECT COUNT(*) FROM movies WHERE dateadded IS NOT NULL")
movies_with_dates = db._get_first_value(cursor.fetchone())
cursor.execute("SELECT COUNT(*) FROM movies WHERE dateadded IS NULL OR source = 'no_valid_date_source'")
movies_without_dates = db._get_first_value(cursor.fetchone())
cursor.execute("SELECT COUNT(*) FROM episodes WHERE dateadded IS NOT NULL")
episodes_with_dates = db._get_first_value(cursor.fetchone())
cursor.execute("SELECT COUNT(*) FROM episodes WHERE dateadded IS NULL OR source = 'no_valid_date_source'")
episodes_without_dates = db._get_first_value(cursor.fetchone())
else:
cursor.execute("SELECT COUNT(*) FROM movies WHERE dateadded IS NOT NULL AND dateadded != ''")
movies_with_dates = cursor.fetchone()[0]
cursor.execute("SELECT COUNT(*) FROM movies WHERE dateadded IS NULL OR dateadded = '' OR source = 'no_valid_date_source'")
movies_without_dates = cursor.fetchone()[0]
cursor.execute("SELECT COUNT(*) FROM episodes WHERE dateadded IS NOT NULL AND dateadded != ''")
episodes_with_dates = cursor.fetchone()[0]
cursor.execute("SELECT COUNT(*) FROM episodes WHERE dateadded IS NULL OR dateadded = '' OR source = 'no_valid_date_source'")
episodes_without_dates = cursor.fetchone()[0]
# Enhanced statistics - PostgreSQL
cursor.execute("SELECT COUNT(*) FROM movies WHERE dateadded IS NOT NULL")
movies_with_dates = db._get_first_value(cursor.fetchone())
cursor.execute("SELECT COUNT(*) FROM movies WHERE dateadded IS NULL OR source = 'no_valid_date_source'")
movies_without_dates = db._get_first_value(cursor.fetchone())
cursor.execute("SELECT COUNT(*) FROM episodes WHERE dateadded IS NOT NULL")
episodes_with_dates = db._get_first_value(cursor.fetchone())
cursor.execute("SELECT COUNT(*) FROM episodes WHERE dateadded IS NULL OR source = 'no_valid_date_source'")
episodes_without_dates = db._get_first_value(cursor.fetchone())
cursor.execute("SELECT COUNT(*) FROM movies WHERE source = 'no_valid_date_source'")
movies_no_valid_source = db._get_first_value(cursor.fetchone())
@@ -545,16 +463,10 @@ async def get_dashboard_stats(dependencies: dict):
episodes_no_valid_source = db._get_first_value(cursor.fetchone())
# Recent activity (last 7 days)
if db.db_type == "postgresql":
cursor.execute("""
SELECT COUNT(*) FROM processing_history
WHERE processed_at > NOW() - INTERVAL '7 days'
""")
else:
cursor.execute("""
SELECT COUNT(*) FROM processing_history
WHERE processed_at > datetime('now', '-7 days')
""")
cursor.execute("""
SELECT COUNT(*) FROM processing_history
WHERE processed_at > NOW() - INTERVAL '7 days'
""")
recent_activity = db._get_first_value(cursor.fetchone())
# Source distribution for movies
@@ -565,10 +477,7 @@ async def get_dashboard_stats(dependencies: dict):
GROUP BY source
ORDER BY count DESC
""")
if db.db_type == "postgresql":
movie_sources = [{"source": list(row.values())[0], "source_description": map_source_to_description(list(row.values())[0]), "count": list(row.values())[1]} for row in cursor.fetchall()]
else:
movie_sources = [{"source": row[0], "source_description": map_source_to_description(row[0]), "count": row[1]} for row in cursor.fetchall()]
movie_sources = [{"source": list(row.values())[0], "source_description": map_source_to_description(list(row.values())[0]), "count": list(row.values())[1]} for row in cursor.fetchall()]
# Source distribution for episodes
cursor.execute("""
@@ -578,10 +487,7 @@ async def get_dashboard_stats(dependencies: dict):
GROUP BY source
ORDER BY count DESC
""")
if db.db_type == "postgresql":
episode_sources = [{"source": list(row.values())[0], "source_description": map_source_to_description(list(row.values())[0]), "count": list(row.values())[1]} for row in cursor.fetchall()]
else:
episode_sources = [{"source": row[0], "source_description": map_source_to_description(row[0]), "count": row[1]} for row in cursor.fetchall()]
episode_sources = [{"source": list(row.values())[0], "source_description": map_source_to_description(list(row.values())[0]), "count": list(row.values())[1]} for row in cursor.fetchall()]
# Calculate total missing dates (movies + episodes)
total_missing_dates = movies_without_dates + episodes_without_dates
@@ -753,11 +659,11 @@ async def bulk_update_source(dependencies: dict, media_type: str, old_source: st
if media_type == "movies":
# Update movies
cursor.execute("UPDATE movies SET source = ? WHERE source = ?", (new_source, old_source))
cursor.execute("UPDATE movies SET source = %s WHERE source = %s", (new_source, old_source))
updated_count = cursor.rowcount
# Add history entries
cursor.execute("SELECT imdb_id FROM movies WHERE source = ?", (new_source,))
cursor.execute("SELECT imdb_id FROM movies WHERE source = %s", (new_source,))
for row in cursor.fetchall():
db.add_processing_history(
imdb_id=row[0],
@@ -767,11 +673,11 @@ async def bulk_update_source(dependencies: dict, media_type: str, old_source: st
)
else:
# Update episodes
cursor.execute("UPDATE episodes SET source = ? WHERE source = ?", (new_source, old_source))
cursor.execute("UPDATE episodes SET source = %s WHERE source = %s", (new_source, old_source))
updated_count = cursor.rowcount
# Add history entries
cursor.execute("SELECT imdb_id, season, episode FROM episodes WHERE source = ?", (new_source,))
cursor.execute("SELECT imdb_id, season, episode FROM episodes WHERE source = %s", (new_source,))
for row in cursor.fetchall():
db.add_processing_history(
imdb_id=row[0],