mirror of
https://github.com/NNTmux/newznab-tmux.git
synced 2026-08-28 17:01:16 +00:00
Update imdbid handling
This commit is contained in:
@@ -453,7 +453,7 @@ if (! function_exists('getReleaseCover')) {
|
||||
|
||||
if (! empty($imdbid) && $imdbid > 0) {
|
||||
$coverType = 'movies';
|
||||
$coverId = str_pad($imdbid, 7, '0', STR_PAD_LEFT);
|
||||
$coverId = str_pad($imdbid, 8, '0', STR_PAD_LEFT);
|
||||
} elseif (! empty($musicinfo_id)) {
|
||||
$coverType = 'music';
|
||||
$coverId = $musicinfo_id;
|
||||
|
||||
@@ -82,11 +82,11 @@ class MovieBrowseService
|
||||
$totalCount = Cache::get($countCacheKey);
|
||||
|
||||
if ($totalCount === null) {
|
||||
// Use LPAD to convert movieinfo.imdbid (int) to the zero-padded varchar format
|
||||
// stored in releases.imdbid, so the index on r.imdbid can be used for the join.
|
||||
// Normalize both sides so we match whether imdbid is stored with or without
|
||||
// leading zeros (e.g. "0099348" vs "99348") in movieinfo or releases.
|
||||
$countSql = 'SELECT COUNT(DISTINCT m.imdbid) AS total '
|
||||
.'FROM movieinfo m '
|
||||
.'INNER JOIN releases r ON r.imdbid = LPAD(m.imdbid, 7, \'0\') '
|
||||
.'INNER JOIN releases r ON LPAD(TRIM(r.imdbid), 8, \'0\') = LPAD(TRIM(m.imdbid), 8, \'0\') '
|
||||
.'WHERE '.$baseWhere;
|
||||
|
||||
$totalResult = DB::select($countSql);
|
||||
@@ -122,7 +122,7 @@ class MovieBrowseService
|
||||
.'FROM ('
|
||||
.'SELECT m.imdbid, MAX(r.postdate) AS latest_postdate, COUNT(r.id) AS total_releases '
|
||||
.'FROM movieinfo m '
|
||||
.'INNER JOIN releases r ON r.imdbid = LPAD(m.imdbid, 7, \'0\') '
|
||||
.'INNER JOIN releases r ON LPAD(TRIM(r.imdbid), 8, \'0\') = LPAD(TRIM(m.imdbid), 8, \'0\') '
|
||||
.'WHERE '.$baseWhere.' '
|
||||
.'GROUP BY m.imdbid'.$innerExtraGroupBy.' '
|
||||
."ORDER BY {$innerOrderBy} {$order[1]} " // @phpstan-ignore offsetAccess.notFound
|
||||
@@ -141,18 +141,16 @@ class MovieBrowseService
|
||||
$movieImdbIds = $movies->pluck('imdbid')->toArray();
|
||||
|
||||
// Step 3: Get top 2 releases per movie using UNION ALL with LIMIT 2 per imdbid.
|
||||
// Each subquery does an index lookup on imdbid and stops after 2 rows,
|
||||
// avoiding the full-table-scan + ROW_NUMBER() materialization of millions of rows.
|
||||
// IMDB IDs are quoted as strings with leading-zero padding to match the
|
||||
// varchar format stored in releases.imdbid (e.g. '0099348'), preventing
|
||||
// implicit type casts that would bypass index usage.
|
||||
// Match releases by normalized 8-char imdbid so we find them whether stored
|
||||
// with or without leading zeros (IMDb IDs are 7–8 digits).
|
||||
$unionParts = [];
|
||||
foreach ($movieImdbIds as $id) {
|
||||
$quotedId = "'".str_pad((string) intval($id), 7, '0', STR_PAD_LEFT)."'";
|
||||
$paddedId = str_pad((string) (int) $id, 8, '0', STR_PAD_LEFT);
|
||||
$quotedId = "'".$paddedId."'";
|
||||
$unionParts[] = '(SELECT r.id, r.imdbid, r.guid, r.searchname, '
|
||||
.'r.size, r.postdate, r.adddate, r.haspreview '
|
||||
.'FROM releases r '
|
||||
."WHERE r.imdbid = {$quotedId} "
|
||||
.'WHERE LPAD(TRIM(r.imdbid), 8, \'0\') = '.$quotedId.' '
|
||||
."AND r.passwordstatus {$this->showPasswords} "
|
||||
.$catFilter
|
||||
.$whereExcluded
|
||||
@@ -163,15 +161,17 @@ class MovieBrowseService
|
||||
$releasesSql = implode(' UNION ALL ', $unionParts);
|
||||
$releases = DB::select($releasesSql);
|
||||
|
||||
// Group releases by imdbid for fast lookup
|
||||
// Group releases by normalized imdbid so lookup works regardless of stored format
|
||||
$releasesByMovie = [];
|
||||
foreach ($releases as $release) {
|
||||
$releasesByMovie[$release->imdbid][] = $release;
|
||||
$normId = str_pad((string) (int) $release->imdbid, 8, '0', STR_PAD_LEFT);
|
||||
$releasesByMovie[$normId][] = $release;
|
||||
}
|
||||
|
||||
// Attach releases to each movie object
|
||||
foreach ($movies as $movie) {
|
||||
$movie->releases = $releasesByMovie[$movie->imdbid] ?? []; // @phpstan-ignore assign.propertyReadOnly
|
||||
$normMovieId = str_pad((string) (int) $movie->imdbid, 8, '0', STR_PAD_LEFT);
|
||||
$movie->releases = $releasesByMovie[$normMovieId] ?? []; // @phpstan-ignore assign.propertyReadOnly
|
||||
}
|
||||
|
||||
// Set total count on first item (matches existing pattern used by controllers)
|
||||
@@ -193,10 +193,11 @@ class MovieBrowseService
|
||||
public function getMovieReleases(string $imdbid, array $excludedCats = []): array
|
||||
{
|
||||
$whereExcluded = count($excludedCats) > 0 ? ' AND r.categories_id NOT IN ('.implode(',', $excludedCats).')' : '';
|
||||
$paddedId = "'".str_pad((string) (int) $imdbid, 8, '0', STR_PAD_LEFT)."'";
|
||||
|
||||
$sql = 'SELECT r.id, r.guid, r.searchname, r.size, r.postdate, r.adddate, r.haspreview '
|
||||
.'FROM releases r '
|
||||
."WHERE r.imdbid = '".str_pad((string) intval($imdbid), 7, '0', STR_PAD_LEFT)."' "
|
||||
.'WHERE LPAD(TRIM(r.imdbid), 8, \'0\') = '.$paddedId.' '
|
||||
."AND r.passwordstatus {$this->showPasswords} "
|
||||
.$whereExcluded.' '
|
||||
.'ORDER BY r.postdate DESC';
|
||||
@@ -238,7 +239,18 @@ class MovieBrowseService
|
||||
$browseByArr = ['title', 'director', 'actors', 'genre', 'rating', 'year', 'imdb'];
|
||||
foreach ($browseByArr as $bb) {
|
||||
if (request()->has($bb) && ! empty(request()->input($bb))) {
|
||||
$bbv = stripslashes(request()->input($bb));
|
||||
$bbv = request()->input($bb);
|
||||
if (is_array($bbv)) {
|
||||
continue;
|
||||
}
|
||||
$bbv = stripslashes((string) $bbv);
|
||||
if ($bb === 'year') {
|
||||
if (preg_match('/^(19|20)\d{2}$/', $bbv)) {
|
||||
$browseBy .= ' AND m.year = '.escapeString($bbv);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
if ($bb === 'rating') {
|
||||
$bbv .= '.';
|
||||
}
|
||||
|
||||
@@ -356,7 +356,7 @@ class TmdbClient
|
||||
if (! empty($imdbId)) {
|
||||
// Format IMDB ID with tt prefix if it's numeric
|
||||
$imdbFormatted = is_numeric($imdbId)
|
||||
? 'tt'.str_pad((string) $imdbId, 7, '0', STR_PAD_LEFT)
|
||||
? 'tt'.str_pad((string) $imdbId, 8, '0', STR_PAD_LEFT)
|
||||
: (string) $imdbId;
|
||||
|
||||
$show = $this->findTvByExternalId($imdbFormatted, 'imdb_id');
|
||||
@@ -396,7 +396,7 @@ class TmdbClient
|
||||
$show = $this->findTvByExternalId((string) $id, 'tvdb_id');
|
||||
} elseif ($source === 'imdb') {
|
||||
$imdbFormatted = is_numeric($id)
|
||||
? 'tt'.str_pad((string) $id, 7, '0', STR_PAD_LEFT)
|
||||
? 'tt'.str_pad((string) $id, 8, '0', STR_PAD_LEFT)
|
||||
: (string) $id;
|
||||
$show = $this->findTvByExternalId($imdbFormatted, 'imdb_id');
|
||||
}
|
||||
@@ -417,7 +417,7 @@ class TmdbClient
|
||||
// Parse IMDB ID to numeric
|
||||
$imdbId = 0;
|
||||
if (! empty($externalIds['imdb_id'])) {
|
||||
preg_match('/tt(?P<imdbid>\d{6,7})$/i', $externalIds['imdb_id'], $imdb);
|
||||
preg_match('/tt(?P<imdbid>\d{6,8})$/i', $externalIds['imdb_id'], $imdb);
|
||||
$imdbId = (int) ($imdb['imdbid'] ?? 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -233,7 +233,7 @@ class TraktService
|
||||
}
|
||||
|
||||
return match ($idType) {
|
||||
'imdb' => is_numeric($id) ? 'tt'.str_pad((string) $id, 7, '0', STR_PAD_LEFT) : (string) $id,
|
||||
'imdb' => is_numeric($id) ? 'tt'.str_pad((string) $id, 8, '0', STR_PAD_LEFT) : (string) $id,
|
||||
'trakt', 'tmdb', 'tvdb' => (string) $id,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -494,7 +494,7 @@ class TmdbProvider extends AbstractTvProvider
|
||||
$imdbId = 0;
|
||||
$externalIds = TmdbClient::getArray($show, 'external_ids');
|
||||
if (! empty($externalIds['imdb_id'])) {
|
||||
preg_match('/tt(?P<imdbid>\d{6,7})$/i', $externalIds['imdb_id'], $imdb);
|
||||
preg_match('/tt(?P<imdbid>\d{6,8})$/i', $externalIds['imdb_id'], $imdb);
|
||||
$imdbId = $imdb['imdbid'] ?? 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -383,7 +383,7 @@ class TraktProvider extends AbstractTvProvider
|
||||
*/
|
||||
public function formatShowInfo(mixed $show): array
|
||||
{
|
||||
preg_match('/tt(?P<imdbid>\d{6,7})$/i', $show['ids']['imdb'], $imdb);
|
||||
preg_match('/tt(?P<imdbid>\d{6,8})$/i', $show['ids']['imdb'], $imdb);
|
||||
$this->posterUrl = $show['images']['poster']['thumb'] ?? '';
|
||||
$this->fanartUrl = $show['images']['fanart']['thumb'] ?? '';
|
||||
$this->localizedTZ = $show['airs']['timezone'] ?? '';
|
||||
@@ -435,7 +435,7 @@ class TraktProvider extends AbstractTvProvider
|
||||
|
||||
// Try IMDB ID as fallback
|
||||
if (! empty($imdbId) && $imdbId > 0) {
|
||||
$imdbFormatted = 'tt'.str_pad((string) $imdbId, 7, '0', STR_PAD_LEFT);
|
||||
$imdbFormatted = 'tt'.str_pad((string) $imdbId, 8, '0', STR_PAD_LEFT);
|
||||
$result = $tvmazeClient->getShowBySiteID('imdb', $imdbFormatted);
|
||||
if ($result !== null && isset($result->id)) {
|
||||
return (int) $result->id;
|
||||
|
||||
@@ -176,7 +176,7 @@
|
||||
@if(!empty($show['imdb']) && $show['imdb'] > 0)
|
||||
<a class="px-4 py-2 bg-yellow-100 text-yellow-800 rounded-lg hover:bg-yellow-200 inline-flex items-center text-sm font-medium transition"
|
||||
target="_blank"
|
||||
href="{{ $site['dereferrer_link'] }}https://www.imdb.com/title/tt{{ str_pad($show['imdb'], 7, '0', STR_PAD_LEFT) }}"
|
||||
href="{{ $site['dereferrer_link'] }}https://www.imdb.com/title/tt{{ str_pad($show['imdb'], 8, '0', STR_PAD_LEFT) }}"
|
||||
title="View at IMDb">
|
||||
<i class="fa fa-film mr-2"></i> IMDb
|
||||
</a>
|
||||
|
||||
Reference in New Issue
Block a user