refactor(release): type media_type/parse_path as true enums

ParsedRelease.media_type is now MediaTypeToken (not str) and parse_path
is ParsePath (not str). __post_init__ keeps a tolerant constructor that
coerces raw strings via the enum, so callers passing 'movie'/'direct'
still work transparently. Since both enums inherit from str, existing
string comparisons and JSON serialization remain unchanged.
This commit is contained in:
2026-05-19 14:21:27 +02:00
parent da484d7474
commit f338b08706
+13 -6
View File
@@ -119,11 +119,11 @@ class ParsedRelease:
codec: str | None # x265, HEVC, … codec: str | None # x265, HEVC, …
group: str # release group, "UNKNOWN" if missing group: str # release group, "UNKNOWN" if missing
tech_string: str # quality.source.codec joined with dots tech_string: str # quality.source.codec joined with dots
media_type: str = MediaTypeToken.UNKNOWN.value # one of MediaTypeToken values media_type: MediaTypeToken = MediaTypeToken.UNKNOWN
site_tag: str | None = ( site_tag: str | None = (
None # site watermark stripped from name, e.g. "TGx", "OxTorrent.vc" None # site watermark stripped from name, e.g. "TGx", "OxTorrent.vc"
) )
parse_path: str = ParsePath.DIRECT.value # one of ParsePath values parse_path: ParsePath = ParsePath.DIRECT
languages: list[str] = field(default_factory=list) # ["MULTI", "VFF"], ["FRENCH"], … languages: list[str] = field(default_factory=list) # ["MULTI", "VFF"], ["FRENCH"], …
audio_codec: str | None = None # "DTS-HD.MA", "DDP", "EAC3", … audio_codec: str | None = None # "DTS-HD.MA", "DDP", "EAC3", …
audio_channels: str | None = None # "5.1", "7.1", "2.0", … audio_channels: str | None = None # "5.1", "7.1", "2.0", …
@@ -158,16 +158,23 @@ class ParsedRelease:
f"ParsedRelease.episode_end ({self.episode_end}) < " f"ParsedRelease.episode_end ({self.episode_end}) < "
f"episode ({self.episode})" f"episode ({self.episode})"
) )
if self.media_type not in _VALID_MEDIA_TYPES: # Coerce raw strings into their enum form (tolerant constructor).
if not isinstance(self.media_type, MediaTypeToken):
try:
self.media_type = MediaTypeToken(self.media_type)
except ValueError:
raise ValidationError( raise ValidationError(
f"ParsedRelease.media_type invalid: {self.media_type!r} " f"ParsedRelease.media_type invalid: {self.media_type!r} "
f"(expected one of {sorted(_VALID_MEDIA_TYPES)})" f"(expected one of {sorted(_VALID_MEDIA_TYPES)})"
) ) from None
if self.parse_path not in _VALID_PARSE_PATHS: if not isinstance(self.parse_path, ParsePath):
try:
self.parse_path = ParsePath(self.parse_path)
except ValueError:
raise ValidationError( raise ValidationError(
f"ParsedRelease.parse_path invalid: {self.parse_path!r} " f"ParsedRelease.parse_path invalid: {self.parse_path!r} "
f"(expected one of {sorted(_VALID_PARSE_PATHS)})" f"(expected one of {sorted(_VALID_PARSE_PATHS)})"
) ) from None
@property @property
def is_season_pack(self) -> bool: def is_season_pack(self) -> bool: