From fd24eb34099e5f2ba98bcd13a60a6112de53d8ae Mon Sep 17 00:00:00 2001 From: wheat4714 <169086384+wheat4714@users.noreply.github.com> Date: Sun, 19 May 2024 04:18:25 +0100 Subject: [PATCH] Improvement/Include DS4K in x265 WEB (#62) - x265 Web now matches DS4k releases (non AV1) --------- Co-authored-by: wheat4714.usedwhensimpleloginisbanned@gmail.com Co-authored-by: santiagosayshey --- .../custom formats (radarr - master).json | 75 ++++++++++-- .../custom formats (sonarr - master).json | 55 +++++++-- tests/regex.py | 2 + tests/x265web.py | 107 ++++++++++++++++++ 4 files changed, 225 insertions(+), 14 deletions(-) create mode 100644 tests/x265web.py diff --git a/imports/custom_formats/radarr/custom formats (radarr - master).json b/imports/custom_formats/radarr/custom formats (radarr - master).json index d6d48df..63e6671 100644 --- a/imports/custom_formats/radarr/custom formats (radarr - master).json +++ b/imports/custom_formats/radarr/custom formats (radarr - master).json @@ -14785,7 +14785,7 @@ "name": "value", "label": "Regular Expression", "helpText": "Custom Format RegEx is Case Insensitive", - "value": "^(?!.*(?i:remux)).*([x]\\s?(\\.?265))", + "value": "^(?!.*(?i:remux))(?=.*(\\b[x]\\s?(\\.?265)\\b|HEVC|\\bDS4K\\b)).*$", "type": "textbox", "advanced": false, "privacy": "normal", @@ -14837,8 +14837,8 @@ }, { "name": "WEB", - "implementation": "ReleaseTitleSpecification", - "implementationName": "Release Title", + "implementation": "SourceSpecification", + "implementationName": "Source", "infoLink": "https://wiki.servarr.com/radarr/settings#custom-formats-2", "negate": false, "required": true, @@ -14846,11 +14846,72 @@ { "order": 0, "name": "value", - "label": "Regular Expression", - "helpText": "Custom Format RegEx is Case Insensitive", - "value": "WEB", - "type": "textbox", + "label": "Source", + "value": 7, + "type": "select", "advanced": false, + "selectOptions": [ + { + "value": 0, + "name": "UNKNOWN", + "order": 0, + "dividerAfter": false + }, + { + "value": 1, + "name": "CAM", + "order": 1, + "dividerAfter": false + }, + { + "value": 2, + "name": "TELESYNC", + "order": 2, + "dividerAfter": false + }, + { + "value": 3, + "name": "TELECINE", + "order": 3, + "dividerAfter": false + }, + { + "value": 4, + "name": "WORKPRINT", + "order": 4, + "dividerAfter": false + }, + { + "value": 5, + "name": "DVD", + "order": 5, + "dividerAfter": false + }, + { + "value": 6, + "name": "TV", + "order": 6, + "dividerAfter": false + }, + { + "value": 7, + "name": "WEBDL", + "order": 7, + "dividerAfter": false + }, + { + "value": 8, + "name": "WEBRIP", + "order": 8, + "dividerAfter": false + }, + { + "value": 9, + "name": "BLURAY", + "order": 9, + "dividerAfter": false + } + ], "privacy": "normal", "isFloat": false } diff --git a/imports/custom_formats/sonarr/custom formats (sonarr - master).json b/imports/custom_formats/sonarr/custom formats (sonarr - master).json index d1f7377..07fc46f 100644 --- a/imports/custom_formats/sonarr/custom formats (sonarr - master).json +++ b/imports/custom_formats/sonarr/custom formats (sonarr - master).json @@ -11628,7 +11628,7 @@ "name": "value", "label": "Regular Expression", "helpText": "Custom Format RegEx is Case Insensitive", - "value": "^(?!.*(?i:remux)).*([x]\\s?(\\.?265))", + "value": "^(?!.*(?i:remux))(?=.*(\\b[x]\\s?(\\.?265)\\b|HEVC|\\bDS4K\\b)).*$", "type": "textbox", "advanced": false, "privacy": "normal", @@ -11680,8 +11680,8 @@ }, { "name": "WEB", - "implementation": "ReleaseTitleSpecification", - "implementationName": "Release Title", + "implementation": "SourceSpecification", + "implementationName": "Source", "infoLink": "https://wiki.servarr.com/sonarr/settings#custom-formats-2", "negate": false, "required": true, @@ -11689,11 +11689,52 @@ { "order": 0, "name": "value", - "label": "Regular Expression", - "helpText": "Custom Format RegEx is Case Insensitive", - "value": "WEB", - "type": "textbox", + "label": "Source", + "value": 3, + "type": "select", "advanced": false, + "selectOptions": [ + { + "value": 0, + "name": "Unknown", + "order": 0 + }, + { + "value": 1, + "name": "Television", + "order": 1 + }, + { + "value": 2, + "name": "TelevisionRaw", + "order": 2 + }, + { + "value": 3, + "name": "Web", + "order": 3 + }, + { + "value": 4, + "name": "WebRip", + "order": 4 + }, + { + "value": 5, + "name": "DVD", + "order": 5 + }, + { + "value": 6, + "name": "Bluray", + "order": 6 + }, + { + "value": 7, + "name": "BlurayRaw", + "order": 7 + } + ], "privacy": "normal", "isFloat": false } diff --git a/tests/regex.py b/tests/regex.py index 2b97b72..1cd7608 100644 --- a/tests/regex.py +++ b/tests/regex.py @@ -2,6 +2,7 @@ import sys from roku import roku from h265verify import h265 from qxr import qxr +from x265web import x265WEB from taoe import taoe from ralphy import Ralphy from av1 import AV1 @@ -19,6 +20,7 @@ def run_tests(): ("ROKU", roku), ("h265 Verified Groups", h265), ("QxR Groups", qxr), + ("x265 (Web)", x265WEB), ("TAoE Groups", taoe), ("Ralphy", Ralphy), ("AV1", AV1), diff --git a/tests/x265web.py b/tests/x265web.py new file mode 100644 index 0000000..01c8d46 --- /dev/null +++ b/tests/x265web.py @@ -0,0 +1,107 @@ +from extract import get_custom_format, get_regex +import re +import sys + +# ANSI escape codes for colors +GREEN = '\033[92m' +RED = '\033[91m' +RESET = '\033[0m' + +good_matches = [ + "Silo (2023) S01 1080p DS4K ATVP WEB-DL DDP 5 1 Atmos English - YELLO", + "Yuva (2024) Kannada (1080p DS4K WEBRip AMZN x265 HEVC 10bit DDP5.1 ESub M3GAN) [MCX]", + "Mrs. Davis 2023 S01 1080p DS4K PCOK WEB-DL DDP 5.1 x265 - YELLO", + "The New Look (2024) S01E01 Just You Wait and See (1080p DS4K ATVP WEBRip x265 10-bit SDR DDP Atmos 5 1 English - DarQ)", + "Baghead (2024) 1080p DS4K WEB-DL x265 DV HDR10+ DDP 5.1 English-SM737", + "Bosch.Legacy.2022.S02E03.1080p.DS4K.AMZN.WEB-DL.10bit.DDP5.1.x265-YELLO" +] + +bad_matches = [ + "Bird Box (2018) 1080p DS4K NF WEBRip AV1 Opus 5.1 [Retr0]", + "The Banshees of Inisherin (2022) 1080p DS4K MA WEBRip AV1 Opus 5.1 [Retr0]", + "Once Upon a Studio (2023) DS4K 1080p DSNP WEBRip AV1 Opus 5.1 [RAV1NE]", + "24 Jam Bersama Gaspar (2024) INDONESIAN DS4K 1080p NF WEBRip AV1 Opus 5.1 [RAV1NE]", +] + +def x265WEB(debug_level=0): + # Get the custom formats for "x265WEB" from both Radarr and Sonarr + x265WEB_radarr = get_custom_format("x265 (Web)", "radarr", debug_level) + x265WEB_sonarr = get_custom_format("x265 (Web)", "sonarr", debug_level) + + # Get the custom formats for "AV1" from both Radarr and Sonarr + AV1_radarr = get_custom_format("AV1", "radarr", debug_level) + AV1_sonarr = get_custom_format("AV1", "sonarr", debug_level) + + # Extract the regex values for both Radarr and Sonarr using get_regex + x265WEB_value_radarr = get_regex(x265WEB_radarr, "x265", debug_level) + x265WEB_value_sonarr = get_regex(x265WEB_sonarr, "x265", debug_level) + + # Extract the regex values for both Radarr and Sonarr using get_regex + AV1_value_radarr = get_regex(AV1_radarr, "AV1", debug_level) + AV1_value_sonarr = get_regex(AV1_sonarr, "AV1", debug_level) + + # Replace the negative lookbehind with a negative lookahead + x265WEB_value_radarr = x265WEB_value_radarr.replace(r"(?<=^|[\s.-])", r"(?:^|[\s.-])") + x265WEB_value_sonarr = x265WEB_value_sonarr.replace(r"(?<=^|[\s.-])", r"(?:^|[\s.-])") + + if debug_level > 0: + print(f"Testing with x265 regex: {x265WEB_value_radarr}") + print(f"Testing with AV1 regex: {AV1_value_radarr}") + + # Compare Radarr and Sonarr x265WEB regex values + if x265WEB_value_radarr != x265WEB_value_sonarr: + print("Test Failed: regex value not same.") + print(f"Radarr regex: {x265WEB_value_radarr}") + print(f"Sonarr regex: {x265WEB_value_sonarr}") + + # Compare Radarr and Sonarr AV1 regex values + if AV1_value_radarr != AV1_value_sonarr: + print("Test Failed: regex value not same.") + print(f"Radarr regex: {AV1_value_radarr}") + print(f"Sonarr regex: {AV1_value_sonarr}") + + good_matches_passed = [] + good_matches_failed = [] + bad_matches_passed = [] + bad_matches_failed = [] + + print("Checking good matches:") + # Test good matches + for release in good_matches: + if re.search(x265WEB_value_radarr, release, re.IGNORECASE): + good_matches_passed.append(release) + print(f" - {release}: {GREEN}Passed{RESET}") + else: + good_matches_failed.append(release) + print(f" - {release}: {RED}Failed{RESET}") + + print("\nChecking bad matches:") + # Test bad matches + for release in bad_matches: + if re.search(AV1_value_radarr, release, re.IGNORECASE): + bad_matches_passed.append(release) + print(f" - {release}: {GREEN}Passed{RESET}") + else: + bad_matches_failed.append(release) + print(f" - {release}: {RED}Failed{RESET}") + + # Reporting failed matches + print("\nFailed matches:") + for release in good_matches_failed + bad_matches_failed: + print(f" - {release}") + + total_matches = len(good_matches) + len(bad_matches) + passed_matches = len(good_matches_passed) + len(bad_matches_passed) + success_rate = (passed_matches / total_matches) * 100 + + print("\nStats:") + print(f"Total: {total_matches}") + print(f"Bad: {len(bad_matches_failed) + len(good_matches_failed)}") + print(f"Rate: {success_rate:.2f}%") + + if success_rate >= 99.8: + print("Test Passed") + return True + else: + print("Test Failed") + return False