diff --git a/.gitignore b/.gitignore index e208dc9..3c1d049 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /test.xml /uv.lock +/main.py diff --git a/src/watfag/__init__.py b/src/watfag/__init__.py index 5becc17..5c4105c 100644 --- a/src/watfag/__init__.py +++ b/src/watfag/__init__.py @@ -1 +1 @@ -__version__ = "1.0.0" +__version__ = "1.0.1" diff --git a/src/watfag/parsers/generic/__init__.py b/src/watfag/parsers/generic/__init__.py index 24c8165..d840ed3 100644 --- a/src/watfag/parsers/generic/__init__.py +++ b/src/watfag/parsers/generic/__init__.py @@ -3,8 +3,9 @@ from pathlib import Path from pkgutil import iter_modules from typing import Optional, Type -from parsers.generic.parsers import DataParser -from parsers.generic.watfag import WATFAG, SeedStatus +from watfag.parsers.generic.parsers import DataParser +from watfag.parsers.generic.watfag import * +from watfag.parsers.generic.watfag import WATFAG class Release: @@ -23,6 +24,18 @@ class Release: self.seed_status: Optional[SeedStatus] = None self.parser_results: dict[str, bool] = {} # Stores which parsers have been run and their results. + self.group: Optional[Group] = None + self.group_name: Optional[str] = None + self.quality: Optional[Resolution] = None + self.source: Optional[Source] = None + self.streaming: Optional[StreamingService] = None + self.video_codec: Optional[VideoCodec] = None + self.audio_codec: Optional[AudioCodec] = None + self.audio_layout: Optional[AudioLayout] = None + self.dynamic_range: Optional[DynamicRange] = None + self.repack: Optional[Repack] = None + self.multi: Optional[Multi] = None + def __lt__(self, other): return self.watfag < other.watfag @@ -63,6 +76,7 @@ class GenericParser: class ParserManager: """Manages and runs parsers on releases.""" + def __init__(self): self.parsers: list[Type[DataParser]] = [] self.collect_parsers() diff --git a/src/watfag/parsers/generic/audio.py b/src/watfag/parsers/generic/audio.py index b87cd22..4ac707f 100644 --- a/src/watfag/parsers/generic/audio.py +++ b/src/watfag/parsers/generic/audio.py @@ -1,8 +1,8 @@ import regex as re -from parsers.generic import GenericParser -from parsers.generic.parsers import DataParser -from parsers.generic.watfag import AudioCodec, AudioLayout +from watfag.parsers.generic import GenericParser +from watfag.parsers.generic.parsers import DataParser +from watfag.parsers.generic.watfag import AudioCodec, AudioLayout patterns = [ re.compile( diff --git a/src/watfag/parsers/generic/group.py b/src/watfag/parsers/generic/group.py index 05ac78c..e69cb61 100644 --- a/src/watfag/parsers/generic/group.py +++ b/src/watfag/parsers/generic/group.py @@ -1,8 +1,8 @@ import regex as re -from parsers.generic import GenericParser -from parsers.generic.watfag import Group -from parsers.generic.parsers import DataParser +from watfag.parsers.generic import GenericParser +from watfag.parsers.generic.watfag import Group +from watfag.parsers.generic.parsers import DataParser patterns = [ re.compile(r"(?:-| - )(?P[a-zA-Z0-9 &]*)\)?$", re.UNICODE), diff --git a/src/watfag/parsers/generic/hdr.py b/src/watfag/parsers/generic/hdr.py index 83ab364..3b3f8e1 100644 --- a/src/watfag/parsers/generic/hdr.py +++ b/src/watfag/parsers/generic/hdr.py @@ -1,8 +1,8 @@ import regex as re -from parsers.generic import GenericParser -from parsers.generic.parsers import CheckParser -from parsers.generic.watfag import DynamicRange +from watfag.parsers.generic import GenericParser +from watfag.parsers.generic.parsers import CheckParser +from watfag.parsers.generic.watfag import DynamicRange checks = { re.compile(r"hybrid|do?vi? ?hdr(?:10)?[\+p]?", re.IGNORECASE): DynamicRange.HYBRID, diff --git a/src/watfag/parsers/generic/multi.py b/src/watfag/parsers/generic/multi.py index be63b90..b0cd55d 100644 --- a/src/watfag/parsers/generic/multi.py +++ b/src/watfag/parsers/generic/multi.py @@ -1,8 +1,8 @@ import regex as re -from parsers.generic import GenericParser -from parsers.generic.parsers import CheckParser -from parsers.generic.watfag import Multi +from watfag.parsers.generic import GenericParser +from watfag.parsers.generic.parsers import CheckParser +from watfag.parsers.generic.watfag import Multi checks = { re.compile(r"multi", re.IGNORECASE): Multi.MULTI diff --git a/src/watfag/parsers/generic/parsers.py b/src/watfag/parsers/generic/parsers.py index 8b6c3ac..276b912 100644 --- a/src/watfag/parsers/generic/parsers.py +++ b/src/watfag/parsers/generic/parsers.py @@ -3,7 +3,7 @@ from typing import Optional, TYPE_CHECKING from regex import Pattern if TYPE_CHECKING: - from parsers.generic import WATFAG, Release + from watfag.parsers.generic import WATFAG, Release class DataParser: diff --git a/src/watfag/parsers/generic/repack.py b/src/watfag/parsers/generic/repack.py index 86942fc..b79fbbe 100644 --- a/src/watfag/parsers/generic/repack.py +++ b/src/watfag/parsers/generic/repack.py @@ -1,8 +1,8 @@ import regex as re -from parsers.generic import GenericParser -from parsers.generic.parsers import CheckParser -from parsers.generic.watfag import Repack +from watfag.parsers.generic import GenericParser +from watfag.parsers.generic.parsers import CheckParser +from watfag.parsers.generic.watfag import Repack checks = { re.compile(r"repack", re.IGNORECASE): Repack.REPACK, diff --git a/src/watfag/parsers/generic/resolution.py b/src/watfag/parsers/generic/resolution.py index bb7f5ee..6d507d8 100644 --- a/src/watfag/parsers/generic/resolution.py +++ b/src/watfag/parsers/generic/resolution.py @@ -1,8 +1,8 @@ import regex as re -from parsers.generic import GenericParser -from parsers.generic.parsers import CheckParser -from parsers.generic.watfag import Resolution +from watfag.parsers.generic import GenericParser +from watfag.parsers.generic.parsers import CheckParser +from watfag.parsers.generic.watfag import Resolution checks = { re.compile(r"2160p", re.IGNORECASE): Resolution.UHD, diff --git a/src/watfag/parsers/generic/seeders.py b/src/watfag/parsers/generic/seeders.py index f6aa90c..9f643e7 100644 --- a/src/watfag/parsers/generic/seeders.py +++ b/src/watfag/parsers/generic/seeders.py @@ -1,8 +1,8 @@ import regex as re -from parsers.generic import GenericParser -from parsers.generic.parsers import CheckParser -from parsers.generic.watfag import SeedStatus +from watfag.parsers.generic import GenericParser +from watfag.parsers.generic.parsers import CheckParser +from watfag.parsers.generic.watfag import SeedStatus class SeederParser(CheckParser, GenericParser): def parse(self) -> bool: diff --git a/src/watfag/parsers/generic/source.py b/src/watfag/parsers/generic/source.py index cb473b6..94c67ac 100644 --- a/src/watfag/parsers/generic/source.py +++ b/src/watfag/parsers/generic/source.py @@ -1,8 +1,8 @@ import regex as re -from parsers.generic import GenericParser -from parsers.generic.parsers import CheckParser -from parsers.generic.watfag import Source +from watfag.parsers.generic import GenericParser +from watfag.parsers.generic.parsers import CheckParser +from watfag.parsers.generic.watfag import Source checks = { re.compile(r"remux", re.IGNORECASE): Source.REMUX, diff --git a/src/watfag/parsers/generic/streaming.py b/src/watfag/parsers/generic/streaming.py index 1a7a593..5833091 100644 --- a/src/watfag/parsers/generic/streaming.py +++ b/src/watfag/parsers/generic/streaming.py @@ -1,8 +1,8 @@ import regex as re -from parsers.generic import GenericParser -from parsers.generic.parsers import CheckParser -from parsers.generic.watfag import StreamingService +from watfag.parsers.generic import GenericParser +from watfag.parsers.generic.parsers import CheckParser +from watfag.parsers.generic.watfag import StreamingService checks = { re.compile(r"ATVP"): StreamingService.ATVP, diff --git a/src/watfag/parsers/generic/video_codec.py b/src/watfag/parsers/generic/video_codec.py index aadf23d..c49e0e0 100644 --- a/src/watfag/parsers/generic/video_codec.py +++ b/src/watfag/parsers/generic/video_codec.py @@ -1,8 +1,8 @@ import regex as re -from parsers.generic import GenericParser -from parsers.generic.parsers import CheckParser -from parsers.generic.watfag import VideoCodec +from watfag.parsers.generic import GenericParser +from watfag.parsers.generic.parsers import CheckParser +from watfag.parsers.generic.watfag import VideoCodec checks = { re.compile(r"avc|[hx][\. -]?264", re.IGNORECASE): VideoCodec.AVC, diff --git a/src/watfag/parsers/movie/__init__.py b/src/watfag/parsers/movie/__init__.py index 17fdd0c..68604ac 100644 --- a/src/watfag/parsers/movie/__init__.py +++ b/src/watfag/parsers/movie/__init__.py @@ -3,32 +3,22 @@ from pathlib import Path from pkgutil import iter_modules from typing import Optional -from parsers.generic import Release, ParserManager -from parsers.generic.watfag import * +from watfag.parsers.generic import Release, ParserManager class MovieRelease(Release): """Holds info representing a release of a movie.""" + def __init__(self, unparsed_text, dl_link, **kwargs): super().__init__(unparsed_text, dl_link, **kwargs) self.title: str = "" self.year: int = 0 self.edition: Optional[str] = None - self.group: Optional[Group] = None - self.group_name: Optional[str] = None - self.quality: Optional[Resolution] = None - self.source: Optional[Source] = None - self.streaming: Optional[StreamingService] = None - self.video_codec: Optional[VideoCodec] = None - self.audio_codec: Optional[AudioCodec] = None - self.audio_layout: Optional[AudioLayout] = None - self.dynamic_range: Optional[DynamicRange] = None - self.repack: Optional[Repack] = None - self.multi: Optional[Multi] = None def __str__(self): parts = [f"{self.title} ({self.year})" + (f" [{self.edition}]" if self.edition else "")] - for attr in ['quality', 'video_codec', 'audio_codec', 'audio_layout', 'dynamic_range', 'repack', 'multi', 'source']: + for attr in ['quality', 'video_codec', 'audio_codec', 'audio_layout', 'dynamic_range', 'repack', 'multi', + 'source']: value = getattr(self, attr) parts.append(f"{attr.capitalize()}: {value if value else 'Unknown'}") if self.streaming: @@ -39,12 +29,14 @@ class MovieRelease(Release): parts.append(f"WATFAG: {self.watfag:.2f}") return " | ".join(parts) + class MovieParser: """ This class can be inherited by any parser that is specific to movies. It allows dynamic importing of parser classes and provides a method to run all parsers on a given movie release. """ + class MovieParserManager(ParserManager): """Parses movie releases.""" diff --git a/src/watfag/parsers/movie/edition.py b/src/watfag/parsers/movie/edition.py index 168fcc5..eb69c62 100644 --- a/src/watfag/parsers/movie/edition.py +++ b/src/watfag/parsers/movie/edition.py @@ -1,8 +1,8 @@ import regex as re -from parsers.generic.parsers import DataParser -from parsers.movie import MovieParser, MovieRelease -from parsers.movie.title_year import edition_regex +from watfag.parsers.generic.parsers import DataParser +from watfag.parsers.movie import MovieParser, MovieRelease +from watfag.parsers.movie.title_year import edition_regex class EditionParser(DataParser, MovieParser): diff --git a/src/watfag/parsers/movie/title_year.py b/src/watfag/parsers/movie/title_year.py index 5b4c0ed..ba44af7 100644 --- a/src/watfag/parsers/movie/title_year.py +++ b/src/watfag/parsers/movie/title_year.py @@ -1,7 +1,7 @@ import regex as re -from parsers.generic.parsers import DataParser -from parsers.movie import MovieParser, MovieRelease +from watfag.parsers.generic.parsers import DataParser +from watfag.parsers.movie import MovieParser, MovieRelease # Shamelessly stolen from Radarr: https://github.com/Radarr/Radarr/blob/develop/src/NzbDrone.Core/Parser/Parser.cs edition_regex = r"\(?\b(?P(((Recut.|Extended.|Ultimate.)?(Director.?s|Collector.?s|Theatrical|Ultimate|Extended|Despecialized|(Special|Rouge|Final|Assembly|Imperial|Diamond|Signature|Hunter|Rekall)(?=(.(Cut|Edition|Version)))|\d{2,3}(th)?.Anniversary)(?:.(Cut|Edition|Version))?(.(Extended|Uncensored|Remastered|Unrated|Uncut|Open.?Matte|IMAX|Fan.?Edit))?|((Uncensored|Remastered|Unrated|Uncut|Open?.Matte|IMAX|Fan.?Edit|Restored|((2|3|4)in1))))))\b\)?" diff --git a/src/watfag/parsers/tvboxset/__init__.py b/src/watfag/parsers/tvboxset/__init__.py index 31f2c79..0eb9f29 100644 --- a/src/watfag/parsers/tvboxset/__init__.py +++ b/src/watfag/parsers/tvboxset/__init__.py @@ -3,8 +3,7 @@ from pathlib import Path from pkgutil import iter_modules from typing import Optional -from parsers.generic import Release, ParserManager -from parsers.generic.watfag import * +from watfag.parsers.generic import Release, ParserManager class TVBoxSetRelease(Release): @@ -13,17 +12,6 @@ class TVBoxSetRelease(Release): super().__init__(unparsed_text, dl_link, **kwargs) self.show_title: str = "" self.seasons: Optional[str] = None - self.group: Optional[Group] = None - self.group_name: Optional[str] = None - self.quality: Optional[Resolution] = None - self.source: Optional[Source] = None - self.streaming: Optional[StreamingService] = None - self.video_codec: Optional[VideoCodec] = None - self.audio_codec: Optional[AudioCodec] = None - self.audio_layout: Optional[AudioLayout] = None - self.dynamic_range: Optional[DynamicRange] = None - self.repack: Optional[Repack] = None - self.multi: Optional[Multi] = None def __str__(self): parts = [f"{self.show_title} (Seasons: {self.seasons})"] @@ -46,7 +34,6 @@ class TVBoxSetParser: class TVBoxSetParserManager(ParserManager): """Parses TV box set releases.""" - def collect_parsers(self): """Dynamically imports all TV box set parsers.""" super().collect_parsers() diff --git a/src/watfag/parsers/tvboxset/title_seasons.py b/src/watfag/parsers/tvboxset/title_seasons.py index a4a4e3f..8aa2016 100644 --- a/src/watfag/parsers/tvboxset/title_seasons.py +++ b/src/watfag/parsers/tvboxset/title_seasons.py @@ -1,7 +1,7 @@ import regex as re -from parsers.generic.parsers import DataParser -from parsers.tvboxset import TVBoxSetParser, TVBoxSetRelease +from watfag.parsers.generic.parsers import DataParser +from watfag.parsers.tvboxset import TVBoxSetParser, TVBoxSetRelease patterns = [ re.compile( # Show Name S01-S02 (year) diff --git a/src/watfag/search.py b/src/watfag/search.py index 84024ec..d2f2543 100644 --- a/src/watfag/search.py +++ b/src/watfag/search.py @@ -2,9 +2,9 @@ from xml.etree import ElementTree from httpx import AsyncClient -from parsers.generic import Release -from parsers.movie import MovieRelease, MovieParserManager -from parsers.tvboxset import TVBoxSetRelease, TVBoxSetParserManager +from watfag.parsers.generic import Release +from watfag.parsers.movie import MovieRelease, MovieParserManager +from watfag.parsers.tvboxset import TVBoxSetRelease, TVBoxSetParserManager class Jackett: