Fix tv seasons categorization

This commit is contained in:
DariusIII
2026-08-11 12:35:48 +02:00
parent 45c766d217
commit c85ee543c5
5 changed files with 177 additions and 6 deletions
@@ -27,6 +27,12 @@ class MovieCategorizer extends AbstractCategorizer
return true;
}
// A standalone Sxx token identifies a full TV season even when year or
// edition markers appear before the source and quality markers.
if ($context->hasStandaloneSeasonToken()) {
return true;
}
// Skip if it looks like a TV episode (S01E01) or season pack (S01.1080p)
if (preg_match('/[._ -]S\d{1,3}[._ -]?(E\d|D\d|Complete|Full|1080|720|480|2160|WEB|HDTV|BluRay|NF|AMZN)/i', $context->releaseName)) {
return true;
@@ -46,7 +46,7 @@ class TvCategorizer extends AbstractCategorizer
return $result;
}
if (! $this->looksLikeTV($name)) {
if (! $this->looksLikeTV($context)) {
return $this->noMatch();
}
@@ -77,15 +77,22 @@ class TvCategorizer extends AbstractCategorizer
if ($result = $this->checkSD($name)) {
return $result;
}
if ($result = $this->checkOther($name)) {
if ($result = $this->checkOther($context)) {
return $result;
}
return $this->noMatch();
}
protected function looksLikeTV(string $name): bool
protected function looksLikeTV(ReleaseContext $context): bool
{
$name = $context->releaseName;
// Standalone season token: S01, S02, etc. Quality markers may appear later.
if ($context->hasStandaloneSeasonToken()) {
return true;
}
// Season + Episode pattern: S01E01, S01.E01, S1D1, etc.
if (preg_match('/[._ -]s\d{1,3}[._ -]?(e|d(isc)?)\d{1,3}([._ -]|$)/i', $name)) {
return true;
@@ -284,14 +291,16 @@ class TvCategorizer extends AbstractCategorizer
return null;
}
protected function checkOther(string $name): ?CategorizationResult
protected function checkOther(ReleaseContext $context): ?CategorizationResult
{
$name = $context->releaseName;
// Season + episode pattern
if (preg_match('/[._ -]s\d{1,3}[._ -]?(e|d(isc)?)\d{1,3}([._ -]|$)/i', $name)) {
return $this->matched(Category::TV_OTHER, 0.6, 'tv_other');
}
// Season pack pattern (S01, S02, etc.) with any quality marker
if (preg_match('/[._ -]S\d{1,3}[._ -]/i', $name)) {
// Standalone season pack pattern (S01, S02, etc.)
if ($context->hasStandaloneSeasonToken()) {
return $this->matched(Category::TV_OTHER, 0.6, 'tv_season_pack');
}
@@ -9,6 +9,8 @@ namespace App\Services\Categorization;
*/
class ReleaseContext
{
private const string STANDALONE_SEASON_TOKEN_REGEX = '/(?:^|[._ -])S\d{1,3}(?=$|[._ -])/i';
public function __construct(
public readonly string $releaseName,
public readonly int|string $groupId,
@@ -50,6 +52,14 @@ class ReleaseContext
return (bool) preg_match($pattern, $this->groupName);
}
/**
* Check whether the release name contains a delimiter-bounded season-pack token.
*/
public function hasStandaloneSeasonToken(): bool
{
return preg_match(self::STANDALONE_SEASON_TOKEN_REGEX, $this->releaseName) === 1;
}
/**
* Check if this release has adult/XXX markers.
*/