diff --git a/PTT/handlers.py b/PTT/handlers.py index 5aa7edc..a7c51a4 100644 --- a/PTT/handlers.py +++ b/PTT/handlers.py @@ -29,7 +29,7 @@ def add_defaults(parser: Parser): parser.add_handler("date", regex.compile(r"(?:\W|^)(\[?\]?(?:0[1-9]|[12][0-9]|3[01])([. \-/\\])(?:0[1-9]|1[012])\2(?:19[6-9]|20[01])[0-9][\])]?)(?:\W|$)"), date("DD MM YYYY"), {"remove": True}) parser.add_handler("date", regex.compile(r"(?:\W)(\[?\]?(?:0[1-9]|1[012])([. \-/\\])(?:0[1-9]|[12][0-9]|3[01])\2(?:[0][1-9]|[0126789][0-9])[\])]?)(?:\W|$)"), date("MM DD YY"), {"remove": True}) parser.add_handler("date", regex.compile(r"(?:\W)(\[?\]?(?:0[1-9]|[12][0-9]|3[01])([. \-/\\])(?:0[1-9]|1[012])\2(?:[0][1-9]|[0126789][0-9])[\])]?)(?:\W|$)"), date("DD MM YY"), {"remove": True}) - parser.add_handler("date", regex.compile(r"(?:\W|^)(\[?\]?(?:0?[1-9]|[12][0-9]|3[01])[. ]?(?:st|nd|rd|th)?([. \-\/\\])(?:feb(?:ruary)?|jan(?:uary)?|mar(?:ch)?|apr(?:il)?|may|june?|july?|aug(?:ust)?|sept?(?:ember)?|oct(?:ober)?|nov(?:ember)?|dec(?:ember)?)\2(?:19[7-9]|20[012])[0-9][\])]?)(?:\W|$)", regex.IGNORECASE), date(["DD MMM YYYY", "Do MMM YYYY", "Do MMMM YYYY"]), {"remove": True}) + parser.add_handler("date", regex.compile(r"(?:\W|^)([([]?(?:0?[1-9]|[12][0-9]|3[01])[. ]?(?:st|nd|rd|th)?([. \-/\\])(?:feb(?:ruary)?|jan(?:uary)?|mar(?:ch)?|apr(?:il)?|may|june?|july?|aug(?:ust)?|sept?(?:ember)?|oct(?:ober)?|nov(?:ember)?|dec(?:ember)?)\2(?:19[7-9]|20[012])[0-9][)\]]?)(?=\W|$)", regex.IGNORECASE), date(["DD MMM YYYY", "Do MMM YYYY", "Do MMMM YYYY"]), {"remove": True}) parser.add_handler("date", regex.compile(r"(?:\W|^)(\[?\]?(?:0?[1-9]|[12][0-9]|3[01])[. ]?(?:st|nd|rd|th)?([. \-\/\\])(?:feb(?:ruary)?|jan(?:uary)?|mar(?:ch)?|apr(?:il)?|may|june?|july?|aug(?:ust)?|sept?(?:ember)?|oct(?:ober)?|nov(?:ember)?|dec(?:ember)?)\2(?:0[1-9]|[0126789][0-9])[\])]?)(?:\W|$)", regex.IGNORECASE), date("DD MMM YY"), {"remove": True}) parser.add_handler("date", regex.compile(r"(?:\W|^)(\[?\]?20[012][0-9](?:0[1-9]|1[012])(?:0[1-9]|[12][0-9]|3[01])[\])]?)(?:\W|$)"), date("YYYYMMDD"), {"remove": True}) @@ -95,7 +95,7 @@ def add_defaults(parser: Parser): parser.add_handler("source", regex.compile(r"\bWEB[ .-]*DL(?:Rip)?\b", regex.IGNORECASE), value("WEB-DL"), {"remove": True}) parser.add_handler("source", regex.compile(r"\bWEB[ .-]*Rip\b", regex.IGNORECASE), value("WEBRip"), {"remove": True}) parser.add_handler("source", regex.compile(r"\b(?:DL|WEB|BD|BR)MUX\b", regex.IGNORECASE), none, {"remove": True}) - parser.add_handler("source", regex.compile(r"\b(DivX|XviD)\b"), none, {"remove": True}) + parser.add_handler("source", regex.compile(r"\b(DivX|XviD)\b"), none, {"remove": False}) # TODO: In the js implementation it's true. But then a test case fails in our implementation and i'm not sure why # Video depth parser.add_handler("bit_depth", regex.compile(r"\bhevc\s?10\b", regex.IGNORECASE), value("10bit")) @@ -118,6 +118,10 @@ def handle_bit_depth(context): parser.add_handler("codec", regex.compile(r"\b[xh][-. ]?26[45]", regex.IGNORECASE), lowercase, {"remove": True}) parser.add_handler("codec", regex.compile(r"\bhevc(?:\s?10)?\b", regex.IGNORECASE), value("hevc"), {"remove": True, "skipIfAlreadyFound": False}) parser.add_handler("codec", regex.compile(r"\b(?:dvix|mpeg2|divx|xvid|avc)\b", regex.IGNORECASE), lowercase, {"remove": True, "skipIfAlreadyFound": False}) + def handle_space_in_codec(context): + if context["result"].get("codec"): + context["result"]["codec"] = regex.sub("[ .-]", "", context["result"]["codec"]) + parser.add_handler("codec", handle_space_in_codec) # Audio parser.add_handler("audio", regex.compile(r"7\.1[. ]?Atmos\b", regex.IGNORECASE), value("7.1 Atmos"), {"remove": True}) @@ -132,7 +136,7 @@ def handle_bit_depth(context): parser.add_handler("audio", regex.compile(r"\bQ?AAC(?:[. ]?2[. ]0|x2)?\b", regex.IGNORECASE), value("aac"), {"remove": True}) # Group - parser.add_handler("group", regex.compile(r"- ?(?!\d+$|S\d+|\d+x|ep?\d+|[^[]+]$)([^\-. []+[^\-. [)\]\d][^\-. [)\]]*)(?:\[[\w.-]+])?(?=\.\w{2,4}$|$)", regex.IGNORECASE), none, {"remove": True}) + parser.add_handler("group", regex.compile(r"- ?(?!\d+$|S\d+|\d+x|ep?\d+|[^[]+]$)([^\-. []+[^\-. [)\]\d][^\-. [)\]]*)(?:\[[\w.-]+])?(?=\.\w{2,4}$|$)", regex.IGNORECASE), none, {"remove": False}) # TODO: I js implementation, it's True, but doesn't get removed?!.... # Container parser.add_handler("container", regex.compile(r"\.?[\[(]?\b(MKV|AVI|MP4|WMV|MPG|MPEG)\b[\])]?", regex.IGNORECASE), lowercase) @@ -170,9 +174,9 @@ def handle_volumes(context): # Seasons parser.add_handler("seasons", regex.compile(r"(?:complete\W|seasons?\W|\W|^)((?:s\d{1,2}[., +/\\&-]+)+s\d{1,2}\b)", regex.IGNORECASE), range_func, { "remove": True }) parser.add_handler("seasons", regex.compile(r"(?:complete\W|seasons?\W|\W|^)[([]?(s\d{2,}-\d{2,}\b)[)\]]?", regex.IGNORECASE), range_func, { "remove": True }) - parser.add_handler("seasons", regex.compile(r"(?:complete\W|seasons?\W|\W|^)[([]?(s[1-9]-[2-9]\b)[)\]]?", regex.IGNORECASE), range_func, { "remove": True }) + parser.add_handler("seasons", regex.compile(r"(?:complete\W|seasons?\W|\W|^)[([]?(s[1-9]-[2-9])[)\]]?", regex.IGNORECASE), range_func, { "remove": True }) parser.add_handler("seasons", regex.compile(r"(?:(?:\bthe\W)?\bcomplete\W)?(?:seasons?|[Сс]езони?|temporadas?)[. ]?[-:]?[. ]?[([]?((?:\d{1,2}[., /\\&]+)+\d{1,2}\b)[)\]]?", regex.IGNORECASE), range_func, { "remove": True }) - parser.add_handler("seasons", regex.compile(r"(?:(?:\bthe\W)?\bcomplete\W)?(?:seasons|[Сс]езони?|temporadas?)[. ]?[-:]?[. ]?[([]?((?:\d{1,2}[. -]+)+[1-9]\d?\b)[)\]]?", regex.IGNORECASE), range_func, { "remove": True }) + parser.add_handler("seasons", regex.compile(r"(?:(?:\bthe\W)?\bcomplete\W)?(?:seasons?|[Сс]езони?|temporadas?)[. ]?[-:]?[. ]?[([]?((?:\d{1,2}[.-]+)+[1-9]\d?\b)[)\]]?", regex.IGNORECASE), range_func, { "remove": True }) parser.add_handler("seasons", regex.compile(r"(?:(?:\bthe\W)?\bcomplete\W)?season[. ]?[([]?((?:\d{1,2}[. -]+)+[1-9]\d?\b)[)\]]?(?!.*\.\w{2,4}$)", regex.IGNORECASE), range_func, { "remove": True }) parser.add_handler("seasons", regex.compile(r"(?:(?:\bthe\W)?\bcomplete\W)?\bseasons?\b[. -]?(\d{1,2}[. -]?(?:to|thru|and|\+|:)[. -]?\d{1,2})\b", regex.IGNORECASE), range_func, { "remove": True }) parser.add_handler("seasons", regex.compile(r"(?:(?:\bthe\W)?\bcomplete\W)?(?:saison|seizoen|season|series|temp(?:orada)?):?[. ]?(\d{1,2})", regex.IGNORECASE), array(integer)) @@ -237,21 +241,13 @@ def handle_episodes(context): beginning_title = title[:end_index] middle_title = title[start_index:end_index] - # Regex patterns to capture episode information, avoiding common prefixes like "movie" or "film" - regex_patterns = [ - r'(?= 1 else raw_match @@ -54,12 +54,12 @@ def handler(context): param_count = len(sig.parameters) transformed = transformer(clean_match or raw_match, *([result.get(name)] if param_count > 1 else [])) - before_title_match = regex.match(r'^\[([^\[\]]+)]', title) + before_title_match = regex.match(r'^\[([^[\]]+)]', title) # or '^\[([^\[\]]+)]' is_before_title = before_title_match is not None and raw_match in before_title_match.group(1) other_matches = {k: v for k, v in matched.items() if k != name} - if name == DEBUG_HANDLER: - print(f"Other Matches: {other_matches}") + # if name == DEBUG_HANDLER: + # print(f"Other Matches: {other_matches}") is_skip_if_first = options.get('skipIfFirst', False) and other_matches and all( match.start() < other_matches[k]['match_index'] for k in other_matches ) @@ -92,6 +92,7 @@ def clean_title(raw_title): cleaned_title = regex.sub(r"[[(]movie[)\]]", "", cleaned_title, flags=regex.IGNORECASE) cleaned_title = NOT_ALLOWED_SYMBOLS_AT_START_AND_END.sub("", cleaned_title) cleaned_title = RUSSIAN_CAST_REGEX.sub("", cleaned_title) + # maybe [\[\[【★].*[\]】★][ .]?(.+) cleaned_title = regex.sub(r"^[[【★].*[\]】★][ .]?(.+)", r"\1", cleaned_title) cleaned_title = regex.sub(r"(.+)[ .]?[[【★].*[\]】★]$", r"\1", cleaned_title) cleaned_title = ALT_TITLES_REGEX.sub("", cleaned_title) @@ -159,45 +160,33 @@ def parse(self, title: str) -> dict: # type: ignore } ) - if handler.handler_name == DEBUG_HANDLER: - print(f"Result: {match_result}") + # if handler.handler_name == DEBUG_HANDLER: + # print(f"Result: {match_result}") + # + # if DEBUG_HANDLER: + # print(handler.handler_name) + # print("Title before: " + title) if match_result is None: + # if DEBUG_HANDLER: + # print("Title after: " + title) + # print(end_of_title) continue if match_result.get('remove', False): title = title[:match_result['match_index']] + title[match_result['match_index'] + len( match_result['raw_match']):] - if match_result.get('skip_from_title') and match_result.get('match_index') and match_result[ + if not match_result.get('skip_from_title') and match_result.get('match_index') and match_result[ 'match_index'] < end_of_title: end_of_title = match_result['match_index'] if match_result.get('remove') and match_result.get('skip_from_title') and match_result[ 'match_index'] < end_of_title: # adjust title index in case part of it should be removed and skipped - end_of_title -= match_result.raw_match.length - - # if match_result: - # raw_match = match_result.group(0) - # clean_match = match_result.group(1) if len(match_result.groups()) >= 1 else None - # transformed_match = raw_match if clean_match is None else clean_match - # if handler["transformer"]: - # transformed = handler["transformer"](transformed_match) - # else: - # transformed = transformed_match - # - # # If the handler demands removal, adjust the title and end_of_title accordingly. - # if options.get("remove", False) and match_result.start() < end_of_title: - # title = title[:match_result.start()] + title[match_result.end():] - # end_of_title -= len(raw_match) - # - # # Save matched data and result. - # matched[handler["name"]] = {"raw_match": raw_match, "match_index": match_result.start()} - # result[handler["name"]] = transformed - # - # # If skipping from title, adjust the title and potentially end_of_title. - # if options.get("skipFromTitle", False) and match_result.start() < end_of_title: - # title = title.replace(raw_match, "", 1) - # end_of_title = min(end_of_title, match_result.start()) + end_of_title -= len(match_result.get("raw_match", "")) + + # if DEBUG_HANDLER: + # print("Title after: " + title) + # print(end_of_title) if not result.get("episodes"): result["episodes"] = [] diff --git a/PTT/transformers.py b/PTT/transformers.py index eca8208..237fdae 100644 --- a/PTT/transformers.py +++ b/PTT/transformers.py @@ -1,4 +1,3 @@ - import arrow import regex @@ -34,11 +33,31 @@ def lowercase(input_value): def uppercase(input_value): return input_value.upper() +month_mapping = { + r"\bJanu\b": "Jan", + r"\bFebr\b": "Feb", + r"\bMarc\b": "Mar", + r"\bApri\b": "Apr", + r"\bMay\b": "May", + r"\bJune\b": "Jun", + r"\bJuly\b": "Jul", + r"\bAugu\b": "Aug", + r"\bSept\b": "Sep", + r"\bOcto\b": "Oct", + r"\bNove\b": "Nov", + r"\bDece\b": "Dec", +} + + +def convert_months(date_str): + for month, shortened in month_mapping.items(): + date_str = regex.sub(month, shortened, date_str, flags=regex.IGNORECASE) + return date_str def date(date_format): def inner(input_value): sanitized = regex.sub(r"\W+", " ", input_value).strip() - print(f"Attempting to parse date: {sanitized}") + sanitized = convert_months(sanitized) formats = [date_format] if not isinstance(date_format, list) else date_format for fmt in formats: try: diff --git a/tests/test_episodes.py b/tests/test_episodes.py index b3b86dc..a2519e0 100644 --- a/tests/test_episodes.py +++ b/tests/test_episodes.py @@ -40,13 +40,14 @@ def parser(): ("Orange Is The New Black Season 5 Episodes 1-10 INCOMPLETE (LEAKED)", list(range(1, 11))), ("Vikings.Season.05.Ep(01-10).720p.WebRip.2Ch.x265.PSA", list(range(1, 11))), ("Naruto Shippuden Ep 107 - Strange Bedfellows.mkv", [107]), - - ("Friends - [7x23-24] - The One with Monica and Chandler's Wedding + Audio Commentary.mkv", [23, 24]), + ("Friends - [7x23-24] - The One with Monica and Chandler's Wedding + Audio Commentary.mkv", list(range(23, 25))), ("Yu-Gi-Oh 3x089 - Awakening of Evil (Part 4).avi", [89]), ("611-612 - Desperate Measures, Means & Ends.mp4", [611, 612]), ("[TBox] Dragon Ball Z Full 1-291(Subbed Jap Vers)", list(range(1, 292))), ("Naruto Shippuden - 107 - Strange Bedfellows.mkv", [107]), - ("[AnimeRG] Naruto Shippuden - 107 [720p] [x265] [pseudo].mkv", [107]) + ("[AnimeRG] Naruto Shippuden - 107 [720p] [x265] [pseudo].mkv", [107]), + ("Game.of.Thrones.S01.e01-02.2160p.UHD.BluRay.x265-Morpheus", list(range(1, 3))), + ("Breaking Bad S03e01-13 (1080p Ita Eng Spa h265 SubS) 2ndREPACK byMe7alh", list(range(1, 14))), ]) def test_episode_parser(release_name, expected_episode, parser): result = parser.parse(release_name) diff --git a/tests/test_main.py b/tests/test_main.py index 0ef6347..da1001f 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -16,28 +16,35 @@ def parser(): 'title': 'sons of anarchy', 'resolution': '480p', 'seasons': [5], - 'season': 5, 'episodes': [10], - 'episode': 10, 'source': 'BluRay', 'codec': 'x264', - 'group': 'GAnGSteR' + 'group': 'GAnGSteR', + 'languages': [] }), ("Color.Of.Night.Unrated.DC.VostFR.BRrip.x264", { 'title': 'Color Of Night', 'unrated': True, 'languages': ['french'], 'source': 'BRRip', - 'codec': 'x264' + 'codec': 'x264', + 'seasons': [], + 'episodes': [] }), ("Da Vinci Code DVDRip", { 'title': 'Da Vinci Code', - 'source': 'DVDRip' + 'source': 'DVDRip', + 'languages': [], + 'seasons': [], + 'episodes': [] }), ("Some.girls.1998.DVDRip", { 'title': 'Some girls', 'source': 'DVDRip', - 'year': 1998 + 'year': 1998, + 'languages': [], + 'seasons': [], + 'episodes': [] }), ("Ecrit.Dans.Le.Ciel.1954.MULTI.DVDRIP.x264.AC3-gismo65", { 'title': 'Ecrit Dans Le Ciel', @@ -47,7 +54,9 @@ def parser(): 'dubbed': True, 'codec': 'x264', 'audio': 'ac3', - 'group': 'gismo65' + 'group': 'gismo65', + 'seasons': [], + 'episodes': [] }), ("2019 After The Fall Of New York 1983 REMASTERED BDRip x264-GHOULS", { 'title': '2019 After The Fall Of New York', @@ -55,7 +64,10 @@ def parser(): 'remastered': True, 'year': 1983, 'codec': 'x264', - 'group': 'GHOULS' + 'group': 'GHOULS', + 'languages': [], + 'seasons': [], + 'episodes': [] }), ("Ghost In The Shell 2017 720p HC HDRip X264 AC3-EVO", { 'title': 'Ghost In The Shell', @@ -65,7 +77,10 @@ def parser(): 'resolution': '720p', 'codec': 'x264', 'audio': 'ac3', - 'group': 'EVO' + 'group': 'EVO', + 'languages': [], + 'seasons': [], + 'episodes': [] }), ("Rogue One 2016 1080p BluRay x264-SPARKS", { 'title': 'Rogue One', @@ -73,7 +88,10 @@ def parser(): 'year': 2016, 'resolution': '1080p', 'codec': 'x264', - 'group': 'SPARKS' + 'group': 'SPARKS', + 'languages': [], + 'seasons': [], + 'episodes': [] }), ("Desperation 2006 Multi Pal DvdR9-TBW1973", { 'title': 'Desperation', @@ -82,7 +100,9 @@ def parser(): 'languages': ['multi audio'], 'dubbed': True, 'region': 'R9', - 'group': 'TBW1973' + 'group': 'TBW1973', + 'seasons': [], + 'episodes': [] }), ("Maman, j'ai raté l'avion 1990 VFI 1080p BluRay DTS x265-HTG", { 'title': "Maman, j'ai raté l'avion", @@ -92,24 +112,31 @@ def parser(): 'resolution': '1080p', 'languages': ['french'], 'codec': 'x265', - 'group': 'HTG' + 'group': 'HTG', + 'seasons': [], + 'episodes': [] }), ("Game of Thrones - The Complete Season 3 [HDTV]", { 'title': 'Game of Thrones', 'seasons': [3], - 'season': 3, - 'source': 'HDTV' + 'source': 'HDTV', + 'languages': [], + 'episodes': [] }), ("The Sopranos: The Complete Series (Season 1,2,3,4,5&6) + Extras", { 'title': 'The Sopranos', 'seasons': [1, 2, 3, 4, 5, 6], - 'complete': True + 'complete': True, + 'languages': [], + 'episodes': [] }), ("Skins Season S01-S07 COMPLETE UK Soundtrack 720p WEB-DL", { 'seasons': [1, 2, 3, 4, 5, 6, 7], 'title': 'Skins', 'resolution': '720p', - 'source': 'WEB-DL' + 'source': 'WEB-DL', + 'languages': [], + 'episodes': [] }), ("Futurama.COMPLETE.S01-S07.720p.BluRay.x265-HETeam", { 'title': 'Futurama', @@ -117,57 +144,67 @@ def parser(): 'resolution': '720p', 'source': 'BluRay', 'codec': 'x265', - 'group': 'HETeam' + 'group': 'HETeam', + 'languages': [], + 'episodes': [] }), ("You.[Uncut].S01.SweSub.1080p.x264-Justiso", { 'title': 'You', 'seasons': [1], - 'season': 1, 'languages': ['swedish'], 'resolution': '1080p', 'codec': 'x264', 'group': 'Justiso', + 'episodes': [] }), ("Stephen Colbert 2019 10 25 Eddie Murphy 480p x264-mSD [eztv]", { 'title': 'Stephen Colbert', 'date': '2019-10-25', 'resolution': '480p', 'codec': 'x264', + 'languages': [], + 'seasons': [], + 'episodes': [] }), ("House MD Season 7 Complete MKV", { 'title': 'House MD', - 'season': 7, 'seasons': [7], - 'container': 'mkv' + 'container': 'mkv', + 'languages': [], + 'episodes': [] }), ("2008 The Incredible Hulk Feature Film.mp4", { 'title': 'The Incredible Hulk Feature Film', 'year': 2008, 'container': 'mp4', - 'extension': 'mp4' + 'extension': 'mp4', + 'languages': [], + 'seasons': [], + 'episodes': [] }), ("【4月/悠哈璃羽字幕社】[UHA-WINGS][不要输!恶之军团][Makeruna!! Aku no Gundan!][04][1080p AVC_AAC][简繁外挂][sc_tc]", { 'title': 'Makeruna!! Aku no Gundan!', 'episodes': [4], - 'episode': 4, 'resolution': '1080p', 'codec': 'avc', 'audio': 'aac', + 'languages': [], + 'seasons': [], }), ("[GM-Team][国漫][西行纪之集结篇][The Westward Ⅱ][2019][17][AVC][GB][1080P]", { 'title': 'The Westward Ⅱ', 'year': 2019, 'episodes': [17], - 'episode': 17, 'resolution': '1080p', 'codec': 'avc', - 'group': 'GM-Team' + 'group': 'GM-Team', + 'languages': [], + 'seasons': [], }), ("Черное зеркало / Black Mirror / Сезон 4 / Серии 1-6 (6) [2017, США, WEBRip 1080p] MVO + Eng Sub", { 'title': 'Black Mirror', 'year': 2017, 'seasons': [4], - 'season': 4, 'episodes': [1, 2, 3, 4, 5, 6], 'languages': ['english'], 'resolution': '1080p', @@ -176,29 +213,33 @@ def parser(): ("[neoHEVC] Student Council's Discretion / Seitokai no Ichizon [Season 1] [BD 1080p x265 HEVC AAC]", { 'title': "Student Council's Discretion / Seitokai no Ichizon", 'seasons': [1], - 'season': 1, 'resolution': '1080p', 'source': 'BDRip', 'audio': 'aac', 'codec': 'hevc', - 'group': 'neoHEVC' + 'group': 'neoHEVC', + 'languages': [], + 'episodes': [] }), ("[Commie] Chihayafuru 3 - 21 [BD 720p AAC] [5F1911ED].mkv", { 'title': "Chihayafuru 3", 'episodes': [21], - 'episode': 21, 'resolution': '720p', 'source': 'BDRip', 'audio': 'aac', 'container': 'mkv', 'extension': 'mkv', - 'episodeCode': "5F1911ED", - 'group': "Commie" + 'episode_code': "5F1911ED", + 'group': "Commie", + 'languages': [], + 'seasons': [], }), ("[DVDRip-ITA]The Fast and the Furious: Tokyo Drift [CR-Bt]", { 'title': "The Fast and the Furious: Tokyo Drift", 'source': 'DVDRip', - 'languages': ['italian'] + 'languages': ['italian'], + 'seasons': [], + 'episodes': [] }), ("[BluRay Rip 720p ITA AC3 - ENG AC3 SUB] Hostel[2005]-LIFE[ultimafrontiera]", { 'title': "Hostel", @@ -207,27 +248,31 @@ def parser(): 'source': 'BRRip', 'audio': 'ac3', 'languages': ['english', 'italian'], - 'group': "LIFE" + 'group': "LIFE", + 'seasons': [], + 'episodes': [] }), ("[OFFICIAL ENG SUB] Soul Land Episode 121-125 [1080p][Soft Sub][Web-DL][Douluo Dalu][斗罗大陆]", { 'title': "Soul Land", 'episodes': [121, 122, 123, 124, 125], 'resolution': '1080p', 'source': 'WEB-DL', - 'languages': ['english'] + 'languages': ['english'], + 'seasons': [], }), ("[720p] The God of Highschool Season 1", { 'title': "The God of Highschool", 'seasons': [1], - 'season': 1, - 'resolution': '720p' + 'resolution': '720p', + 'languages': [], + 'episodes': [] }), ("Heidi Audio Latino DVDRip [cap. 3 Al 18]", { 'title': "Heidi", 'episodes': [3], - 'episode': 3, 'source': 'DVDRip', - 'languages': ['latino'] + 'languages': ['latino'], + 'seasons': [], }) ]) def test_random_releases_parse(parser, release_name, expected): diff --git a/tests/test_parser.py b/tests/test_parser.py index 6365fec..726c76b 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -15,7 +15,7 @@ def test_parsed_output(parser): result = parser.parse(test_case) assert isinstance(result, dict) assert "title" in result - assert "episodeCode" in result + assert "episode_code" in result assert "resolution" in result assert "codec" in result assert "audio" in result @@ -53,7 +53,7 @@ def test_season_parser(parser): def test_episode_code(parser): test_case = "[Golumpa] Fairy Tail - 214 [FuniDub 720p x264 AAC] [5E46AC39]" result = parser.parse(test_case) - assert result["episodeCode"] == "5E46AC39" + assert result["episode_code"] == "5E46AC39" # def test_languages_parser(parser): # test_cases = [ diff --git a/tests/test_season.py b/tests/test_season.py index 3ca7fdf..adcc20d 100644 --- a/tests/test_season.py +++ b/tests/test_season.py @@ -40,6 +40,22 @@ def parser(): ("Stargate Atlantis ALL Seasons - S01 / S02 / S03 / S04 / S05", list(range(1, 6))), ("Stargate Atlantis Complete (Season 1 2 3 4 5) 720p HEVC x265", list(range(1, 6))), ("Skam.S01-S02-S03.SweSub.720p.WEB-DL.H264", list(range(1, 4))), + ("Игра престолов / Game of Thrones [S1-8] (2011-2019) Blu-Ray Remux 2160p | 4K | HEVC | HDR | Dolby Vision | D, P", list(range(1, 9))), + ("Игра престолов / Game of Thrones (2011-2019) BDRemux [H.264/1080p] (S1-8E1-73 of 73) AlexFilm, LostFilm, FoxLife, Ren-TV, Kravec, Jaskier, FocusStudio, NewStudio, FOX, AMS, OmskBird", list(range(1, 9))), + ("Game.of.Thrones.S01-07.LostFilm.AlexFilm.Dub.Eng.BDRip.1080p", list(range(1, 8))), + ("Game.of.Thrones.S01.2160p.UHD.BluRay.x265-SpaceHD13", [1]), + ("Game_Of_Thrones_Season 01", [1]), + ("Game.of.Thrones.S01.e01-02.2160p.UHD.BluRay.x265-Morpheus", [1]), + ("Spongebob Squarepants Season 1-8 DvdRip", list(range(1, 9))), + ("[DBDRaws][海绵宝宝 第一季spongebob squarepants Season 1][0120TV][1080P][WebRip][HEVC10bit][AC3][MKV]", [1]), + ("Supernatural_s15_LostFilm_1080p", [15]), + ("Supernatural (2005) Season 15 S15 (1080p BluRay x265 HEVC 10bit AAC 5.1 Silence)", [15]), + ("Supernatural Season 1-10 1 2 3 4 5 6 7 8 9 10 Complete HD {KURD}", list(range(1, 11))), + ("Breaking Bad - Complete Season 1,2,3,4,5 + Extras - BluRay 1080p", list(range(1, 6))), + ("Breaking Bad Season 1, 2 & 3 + Extras Blu-ray BDRip TSV", list(range(1, 4))), + ("Silo.Season.1.2160p.DV.H265-MIXED", [1]), + ("Stranger.Things.S01-S04.1080p.WEB-DL.DDP5.1.x264-AOC", list(range(1, 5))), + ("Stranger.Things.Netflix.S01 S04.Complete.1080p 720p.MKV.MP4.AAC.WEB-DL [62.1GB]", list(range(1, 5))), ]) def test_season_detection(parser, release_name, expected_seasons): result = parser.parse(release_name)