From 4eabcad8390a74b625fce3958805d8a8e2a5033e Mon Sep 17 00:00:00 2001 From: DariusIII Date: Fri, 14 Nov 2025 11:13:24 +0100 Subject: [PATCH] Update tv episodes handling --- Blacklight/Releases.php | 55 ++++++++++++++++----- Blacklight/processing/tv/TV.php | 3 ++ app/Http/Controllers/SeriesController.php | 16 ++++-- resources/views/series/viewseries.blade.php | 22 +++++++++ 4 files changed, 82 insertions(+), 14 deletions(-) diff --git a/Blacklight/Releases.php b/Blacklight/Releases.php index c4474342d..dfee65b1f 100644 --- a/Blacklight/Releases.php +++ b/Blacklight/Releases.php @@ -20,6 +20,8 @@ use Illuminate\Support\Facades\Log; */ class Releases extends Release { + private const CACHE_VERSION_KEY = 'releases:cache_version'; + // RAR/ZIP Password indicator. public const PASSWD_NONE = 0; // No password. @@ -51,6 +53,7 @@ class Releases extends Release */ public function getBrowseRange($page, $cat, $start, $num, $orderBy, int $maxAge = -1, array $excludedCats = [], int|string $groupName = -1, int $minSize = 0): mixed { + $cacheVersion = $this->getCacheVersion(); $page = max(1, $page); $start = max(0, $start); @@ -96,7 +99,8 @@ class Releases extends Release ($start === 0 ? ' LIMIT '.$num : ' LIMIT '.$num.' OFFSET '.$start) ); - $releases = Cache::get(md5($qry.$page)); + $cacheKey = md5($cacheVersion.$qry.$page); + $releases = Cache::get($cacheKey); if ($releases !== null) { return $releases; } @@ -106,7 +110,7 @@ class Releases extends Release $sql[0]->_totalcount = $sql[0]->_totalrows = $possibleRows; } $expiresAt = now()->addMinutes(config('nntmux.cache_expiry_medium')); - Cache::put(md5($qry.$page), $sql, $expiresAt); + Cache::put($cacheKey, $sql, $expiresAt); return $sql; } @@ -480,7 +484,7 @@ class Releases extends Release ); // Check cache - $cacheKey = md5($sql); + $cacheKey = md5($this->getCacheVersion().$sql); $releases = Cache::get($cacheKey); if ($releases !== null) { return $releases; @@ -787,10 +791,15 @@ class Releases extends Release */ public function tvSearch(array $siteIdArr = [], string $series = '', string $episode = '', string $airDate = '', int $offset = 0, int $limit = 100, string $name = '', array $cat = [-1], int $maxAge = -1, int $minSize = 0, array $excludedCategories = []): mixed { - $cacheKey = md5(serialize(func_get_args()).'tvSearch'); - $cached = Cache::get($cacheKey); - if ($cached !== null) { - return $cached; + $shouldCache = ! (isset($siteIdArr['id']) && (int) $siteIdArr['id'] > 0); + $rawCacheKey = md5(serialize(func_get_args()).'tvSearch'); + $cacheKey = null; + if ($shouldCache) { + $cacheKey = md5($this->getCacheVersion().$rawCacheKey); + $cached = Cache::get($cacheKey); + if ($cached !== null) { + return $cached; + } } $conditions = [ @@ -810,6 +819,8 @@ class Releases extends Release } if (! empty($siteConditions)) { + $siteUsesVideoIdOnly = count($siteConditions) === 1 && isset($siteIdArr['id']) && (int) $siteIdArr['id'] > 0; + $seriesFilter = ($series !== '') ? sprintf('AND tve.series = %d', (int) preg_replace('/^s0*/i', '', $series)) : ''; $episodeFilter = ($episode !== '') ? sprintf('AND tve.episode = %d', (int) preg_replace('/^e0*/i', '', $episode)) : ''; $airDateFilter = ($airDate !== '') ? sprintf('AND DATE(tve.firstaired) = %s', escapeString($airDate)) : ''; @@ -836,11 +847,15 @@ class Releases extends Release $videoJoinCondition = sprintf('AND v.id IN (%s)', implode(',', array_map('intval', $videoIds))); } - if (! empty($episodeIds)) { + if (! empty($episodeIds) && ! $siteUsesVideoIdOnly) { $conditions[] = sprintf('r.tv_episodes_id IN (%s)', implode(',', array_map('intval', $episodeIds))); $episodeJoinCondition = sprintf('AND tve.id IN (%s)', implode(',', array_map('intval', $episodeIds))); $needsEpisodeJoin = true; } + + if ($siteUsesVideoIdOnly) { + $needsEpisodeJoin = false; + } } } @@ -932,7 +947,12 @@ class Releases extends Release $whereSql ); - $sql = sprintf('%s ORDER BY r.postdate DESC LIMIT %d OFFSET %d', $baseSql, $limit, $offset); + $limitClause = ''; + if ($limit > 0) { + $limitClause = sprintf(' LIMIT %d OFFSET %d', $limit, $offset); + } + + $sql = sprintf('%s ORDER BY r.postdate DESC%s', $baseSql, $limitClause); $releases = $this->fromQuery($sql); if ($releases->isNotEmpty()) { @@ -946,12 +966,25 @@ class Releases extends Release $releases[0]->_totalrows = $countResult[0]->count ?? 0; } - $expiresAt = now()->addMinutes(config('nntmux.cache_expiry_medium')); - Cache::put($cacheKey, $releases, $expiresAt); + if ($shouldCache && $cacheKey !== null) { + $expiresAt = now()->addMinutes(config('nntmux.cache_expiry_medium')); + Cache::put($cacheKey, $releases, $expiresAt); + } return $releases; } + public static function bumpCacheVersion(): void + { + $current = Cache::get(self::CACHE_VERSION_KEY, 1); + Cache::forever(self::CACHE_VERSION_KEY, $current + 1); + } + + private function getCacheVersion(): int + { + return Cache::get(self::CACHE_VERSION_KEY, 1); + } + /** * Search TV Shows via APIv2. * diff --git a/Blacklight/processing/tv/TV.php b/Blacklight/processing/tv/TV.php index ee7ed54b7..8c7a505d6 100755 --- a/Blacklight/processing/tv/TV.php +++ b/Blacklight/processing/tv/TV.php @@ -10,6 +10,7 @@ use App\Models\TvInfo; use App\Models\Video; use Blacklight\ColorCLI; use Blacklight\processing\Videos; +use Blacklight\Releases; use Blacklight\utility\Country; use Illuminate\Support\Facades\DB; @@ -159,6 +160,8 @@ abstract class TV extends Videos Release::query() ->where('id', $releaseId) ->update(['videos_id' => $videoId, 'tv_episodes_id' => $episodeId]); + + Releases::bumpCacheVersion(); } /** diff --git a/app/Http/Controllers/SeriesController.php b/app/Http/Controllers/SeriesController.php index 47733dddd..67b7038a7 100644 --- a/app/Http/Controllers/SeriesController.php +++ b/app/Http/Controllers/SeriesController.php @@ -27,10 +27,12 @@ class SeriesController extends BasePageController $catarray = []; $catarray[] = $category; - $page = $request->has('page') && is_numeric($request->input('page')) ? $request->input('page') : 1; - $offset = ($page - 1) * config('nntmux.items_per_page'); + $seriesLimit = (int) config('nntmux.series_view_limit', 0); + $page = $request->has('page') && is_numeric($request->input('page')) ? (int) $request->input('page') : 1; + $page = max($page, 1); + $offset = $seriesLimit > 0 ? ($page - 1) * $seriesLimit : 0; - $rel = $releases->tvSearch(['id' => $id], '', '', '', $offset, 1000, '', $catarray, -1); + $rel = $releases->tvSearch(['id' => $id], '', '', '', $offset, $seriesLimit, '', $catarray, -1); $show = Video::getByVideoID($id); @@ -224,6 +226,8 @@ class SeriesController extends BasePageController } $catid = $category !== -1 ? $category : ''; + $totalRows = ($rel && $rel->count() > 0) ? ($rel[0]->_totalrows ?? $rel->count()) : 0; + $totalPages = $seriesLimit > 0 ? (int) ceil(max($totalRows, 1) / $seriesLimit) : 1; $this->viewData = array_merge($this->viewData, [ 'seasons' => $seasons, @@ -241,6 +245,12 @@ class SeriesController extends BasePageController 'totalSeasonsAvailable' => $totalSeasonsAvailable, 'totalSeasonsAired' => $totalSeasonsAired, 'totalEpisodesAired' => $totalEpisodesAired, + 'pagination' => [ + 'per_page' => $seriesLimit, + 'current_page' => $page, + 'total_pages' => $totalPages, + 'total_rows' => $totalRows, + ], 'meta_title' => 'View TV Series', 'meta_keywords' => 'view,series,tv,show,description,details', 'meta_description' => 'View TV Series', diff --git a/resources/views/series/viewseries.blade.php b/resources/views/series/viewseries.blade.php index 474f11466..89d30ec74 100644 --- a/resources/views/series/viewseries.blade.php +++ b/resources/views/series/viewseries.blade.php @@ -301,6 +301,28 @@ No episodes/releases found for this series. @endif + @if(!empty($pagination['per_page']) && $pagination['per_page'] > 0 && ($pagination['total_pages'] ?? 1) > 1) +
+
+ Page {{ $pagination['current_page'] }} of {{ $pagination['total_pages'] }} + ({{ number_format($pagination['total_rows']) }} total releases) +
+
+ @php + $prevPage = max($pagination['current_page'] - 1, 1); + $nextPage = min($pagination['current_page'] + 1, $pagination['total_pages']); + @endphp + + Previous + + + Next + +
+
+ @endif @endif