Speed up Movies

This commit is contained in:
2025-11-04 13:07:46 +01:00
parent 4d1f4b484a
commit ffe0af7932
8 changed files with 799 additions and 142 deletions
+155 -77
View File
@@ -257,50 +257,27 @@ try {
JOIN seasons se ON se.id = e.season_id
JOIN shows sh ON sh.id = se.show_id
WHERE 1=1";
// Prefer extracting show status directly from JSON and include cliffhanger column if present
$selectWithYearJson = "SELECT e.*,
CASE e.status WHEN 1 THEN 'Progress' WHEN 2 THEN 'Done' ELSE 'Init' END AS status,
sh.resolution AS resolution,
sh.poster_path AS poster_path,
sh.first_air_year AS first_air_year,
sh.id AS show_id,
sh.download_path AS download_path,
JSON_UNQUOTE(JSON_EXTRACT(sh.json, '$.status')) AS show_status,
sh.cliffhanger AS show_cliffhanger,
sh.json AS show_json,
se.season_number, sh.name AS show_name ".$base;
$selectNoYearJson = "SELECT e.*,
CASE e.status WHEN 1 THEN 'Progress' WHEN 2 THEN 'Done' ELSE 'Init' END AS status,
sh.resolution AS resolution,
sh.poster_path AS poster_path,
NULL AS first_air_year,
sh.id AS show_id,
sh.download_path AS download_path,
JSON_UNQUOTE(JSON_EXTRACT(sh.json, '$.status')) AS show_status,
sh.cliffhanger AS show_cliffhanger,
sh.json AS show_json,
se.season_number, sh.name AS show_name ".$base;
// Fallback selects without JSON_EXTRACT (older MySQL) — frontend will parse from show_json
$selectWithYear = "SELECT e.*,
CASE e.status WHEN 1 THEN 'Progress' WHEN 2 THEN 'Done' ELSE 'Init' END AS status,
sh.resolution AS resolution,
sh.poster_path AS poster_path,
sh.first_air_year AS first_air_year,
sh.id AS show_id,
sh.download_path AS download_path,
sh.cliffhanger AS show_cliffhanger,
sh.json AS show_json,
se.season_number, sh.name AS show_name ".$base;
$selectNoYear = "SELECT e.*,
CASE e.status WHEN 1 THEN 'Progress' WHEN 2 THEN 'Done' ELSE 'Init' END AS status,
sh.resolution AS resolution,
sh.poster_path AS poster_path,
NULL AS first_air_year,
sh.id AS show_id,
sh.download_path AS download_path,
sh.cliffhanger AS show_cliffhanger,
sh.json AS show_json,
se.season_number, sh.name AS show_name ".$base;
// JSON-aware select (keine first_air_year-Spalte voraussetzen)
$selectJson = "SELECT e.*,
CASE e.status WHEN 1 THEN 'Progress' WHEN 2 THEN 'Done' ELSE 'Init' END AS status,
sh.resolution AS resolution,
sh.poster_path AS poster_path,
sh.id AS show_id,
sh.download_path AS download_path,
JSON_UNQUOTE(JSON_EXTRACT(sh.json, '$.status')) AS show_status,
sh.cliffhanger AS show_cliffhanger,
sh.json AS show_json,
se.season_number, sh.name AS show_name ".$base;
// Fallback ohne JSON_EXTRACT (ältere MySQL-Versionen)
$selectNoJson = "SELECT e.*,
CASE e.status WHEN 1 THEN 'Progress' WHEN 2 THEN 'Done' ELSE 'Init' END AS status,
sh.resolution AS resolution,
sh.poster_path AS poster_path,
sh.id AS show_id,
sh.download_path AS download_path,
sh.cliffhanger AS show_cliffhanger,
sh.json AS show_json,
se.season_number, sh.name AS show_name ".$base;
$run = function(string $sql) use ($pdo, $statusVal, $q, $offset, $limit) {
$params = [];
@@ -315,45 +292,18 @@ try {
};
try {
$rows = $run($selectWithYearJson);
$rows = $run($selectJson);
resp(['ok'=>true,'items'=>$rows]);
} catch (Throwable $e) {
$msg = $e->getMessage();
if (strpos($msg, 'Unknown column') !== false) {
// Maybe first_air_year missing — try JSON version without year
try {
$rows = $run($selectNoYearJson);
resp(['ok'=>true,'items'=>$rows]);
} catch (Throwable $e2) {
$msg2 = $e2->getMessage();
if (stripos($msg2, 'JSON_EXTRACT') !== false || stripos($msg2, 'Unknown function') !== false) {
// Fallback to non-JSON_EXTRACT selects
try {
$rows = $run($selectWithYear);
resp(['ok'=>true,'items'=>$rows]);
} catch (Throwable $e3) {
if (strpos($e3->getMessage(), 'Unknown column') !== false) {
$rows = $run($selectNoYear);
resp(['ok'=>true,'items'=>$rows]);
} else { throw $e3; }
}
} else { throw $e2; }
}
} elseif (stripos($msg, 'JSON_EXTRACT') !== false || stripos($msg, 'Unknown function') !== false) {
// JSON functions not available
try {
$rows = $run($selectWithYear);
resp(['ok'=>true,'items'=>$rows]);
} catch (Throwable $e4) {
if (strpos($e4->getMessage(), 'Unknown column') !== false) {
$rows = $run($selectNoYear);
resp(['ok'=>true,'items'=>$rows]);
} else { throw $e4; }
}
if (stripos($msg, 'JSON_EXTRACT') !== false || stripos($msg, 'Unknown function') !== false) {
// JSON-Funktionen nicht verfügbar -> Fallback ohne JSON
$rows = $run($selectNoJson);
resp(['ok'=>true,'items'=>$rows]);
} else { throw $e; }
}
}
// Movie list handling
if ($type==='movie') {
$statusVal = null;
if ($status) {
@@ -372,6 +322,134 @@ try {
fail('unsupported type');
}
case 'get_series_summary': {
// Optional: increase GROUP_CONCAT limit for very large shows
try { $pdo->query('SET SESSION group_concat_max_len = 1048576'); } catch (Throwable $e) {}
$sql = "
SELECT
sh.id AS show_id,
sh.name,
sh.poster_path,
sh.resolution,
sh.download_path,
sh.cliffhanger,
sh.json,
sa.season_status,
sa.seasons_eps,
(af.progress_sum > 0) AS any_progress,
(af.init_sum > 0) AS any_init
FROM shows sh
LEFT JOIN (
SELECT t.show_id,
GROUP_CONCAT(CONCAT(t.season_number, ':', t.init_cnt, ',', t.prog_cnt, ',', t.done_cnt, ',', t.total_cnt)
ORDER BY t.season_number SEPARATOR '|') AS season_status,
GROUP_CONCAT(CONCAT(t.season_number, ':', t.eps_list)
ORDER BY t.season_number SEPARATOR ';') AS seasons_eps
FROM (
SELECT se.show_id,
se.season_number,
SUM(CASE WHEN e.status IS NULL OR e.status = 0 THEN 1 ELSE 0 END) AS init_cnt,
SUM(CASE WHEN e.status = 1 THEN 1 ELSE 0 END) AS prog_cnt,
SUM(CASE WHEN e.status = 2 THEN 1 ELSE 0 END) AS done_cnt,
COUNT(e.id) AS total_cnt,
GROUP_CONCAT(CONCAT(e.episode_number, '|', COALESCE(e.status,0))
ORDER BY e.episode_number SEPARATOR ',') AS eps_list
FROM seasons se
LEFT JOIN episodes e ON e.season_id = se.id
WHERE se.season_number > 0
GROUP BY se.show_id, se.season_number
) AS t
GROUP BY t.show_id
) AS sa ON sa.show_id = sh.id
LEFT JOIN (
SELECT se.show_id,
SUM(CASE WHEN e.status = 1 THEN 1 ELSE 0 END) AS progress_sum,
SUM(CASE WHEN e.status IS NULL OR e.status = 0 THEN 1 ELSE 0 END) AS init_sum
FROM seasons se
LEFT JOIN episodes e ON e.season_id = se.id
WHERE se.season_number > 0
GROUP BY se.show_id
) AS af ON af.show_id = sh.id
ORDER BY sh.name ASC";
try {
$stmt = $pdo->query($sql);
$rows = $stmt->fetchAll();
resp(['ok' => true, 'items' => $rows]);
} catch (Throwable $e) {
// Fallback for legacy schemas using column name 'state' instead of 'status'
$msg = $e->getMessage();
if (strpos($msg, 'Unknown column') !== false || ($e instanceof PDOException && $e->getCode()==='42S22')) {
$sql2 = str_replace(['e.status', 'COALESCE(e.status,0)'], ['e.state', 'COALESCE(e.state,0)'], $sql);
$stmt = $pdo->query($sql2);
$rows = $stmt->fetchAll();
resp(['ok' => true, 'items' => $rows]);
} else {
throw $e;
}
}
}
case 'get_show_episodes': {
$showId = (int)($in['show_id'] ?? 0);
if (!$showId) fail('bad params');
$base = "FROM episodes e
JOIN seasons se ON se.id = e.season_id
JOIN shows sh ON sh.id = se.show_id
WHERE se.show_id = ? AND se.season_number > 0";
$selectJson = "SELECT e.*,
CASE e.status WHEN 1 THEN 'Progress' WHEN 2 THEN 'Done' ELSE 'Init' END AS status,
sh.resolution AS resolution,
sh.poster_path AS poster_path,
sh.id AS show_id,
sh.download_path AS download_path,
JSON_UNQUOTE(JSON_EXTRACT(sh.json, '$.status')) AS show_status,
sh.cliffhanger AS show_cliffhanger,
sh.json AS show_json,
se.season_number, sh.name AS show_name ".$base.
" ORDER BY se.season_number ASC, e.episode_number ASC";
$selectNoJson = "SELECT e.*,
CASE e.status WHEN 1 THEN 'Progress' WHEN 2 THEN 'Done' ELSE 'Init' END AS status,
sh.resolution AS resolution,
sh.poster_path AS poster_path,
sh.id AS show_id,
sh.download_path AS download_path,
sh.cliffhanger AS show_cliffhanger,
sh.json AS show_json,
se.season_number, sh.name AS show_name ".$base.
" ORDER BY se.season_number ASC, e.episode_number ASC";
try {
$stmt = $pdo->prepare($selectJson);
$stmt->execute([$showId]);
$rows = $stmt->fetchAll();
resp(['ok'=>true,'items'=>$rows]);
} catch (Throwable $e) {
$msg = $e->getMessage();
if (stripos($msg, 'JSON_EXTRACT') !== false || stripos($msg, 'Unknown function') !== false) {
$stmt = $pdo->prepare($selectNoJson);
$stmt->execute([$showId]);
$rows = $stmt->fetchAll();
resp(['ok'=>true,'items'=>$rows]);
}
// Fallback for legacy 'state' column instead of 'status'
if (strpos($msg, 'Unknown column') !== false || ($e instanceof PDOException && $e->getCode()==='42S22')) {
$selectJson2 = str_replace('e.status', 'e.state', $selectJson);
try {
$stmt = $pdo->prepare($selectJson2);
$stmt->execute([$showId]);
$rows = $stmt->fetchAll();
resp(['ok'=>true,'items'=>$rows]);
} catch (Throwable $e2) {
$selectNoJson2 = str_replace('e.status', 'e.state', $selectNoJson);
$stmt = $pdo->prepare($selectNoJson2);
$stmt->execute([$showId]);
$rows = $stmt->fetchAll();
resp(['ok'=>true,'items'=>$rows]);
}
}
throw $e;
}
}
case 'get_show_by_tmdb': {
$tmdbId = (int)($in['tmdb_id'] ?? 0);
if (!$tmdbId) fail('bad params');