From d5090d1a9f5a2cececcaa2ea322b7370f67dfcff Mon Sep 17 00:00:00 2001 From: Sam Chau Date: Sat, 1 Jun 2024 23:46:35 +0930 Subject: [PATCH] Feature/Automated Testing (#1) (#2) * addition: custom formats imported from dev * feat. Added scripts to conduct automate testing * feat. Added CODEOWNERS file for reviews * feat. Added workflow for automated testing on PR * change. test script now exits on fail * fix. Use py3 for running regex script * fix. Adjusted sys exits on failed tests * addition. Added placeholder json files from profilarr --- .github/CODEOWNERS | 1 + .github/workflows/test.yml | 27 + db/custom_formats/audio/ATMOS (Missing).json | 69 + db/custom_formats/audio/ATMOS.json | 27 + db/custom_formats/audio/DD+.json | 132 ++ db/custom_formats/audio/DD.json | 153 ++ db/custom_formats/audio/DTS-HD MA.json | 195 ++ db/custom_formats/audio/DTS-X.json | 174 ++ db/custom_formats/audio/DTS.json | 216 +++ db/custom_formats/audio/FLAC.json | 153 ++ db/custom_formats/audio/PCM.json | 153 ++ db/custom_formats/audio/TrueHD (Missing).json | 202 ++ db/custom_formats/audio/TrueHD.json | 111 ++ db/custom_formats/codec/2160p x265.json | 111 ++ db/custom_formats/codec/AV1.json | 27 + db/custom_formats/codec/Blu-Ray (Remux).json | 109 ++ db/custom_formats/codec/DVD REMUX .json | 109 ++ db/custom_formats/codec/REMUX.json | 109 ++ db/custom_formats/codec/VVC.json | 27 + db/custom_formats/codec/WEBRip.json | 109 ++ db/custom_formats/codec/Xvid.json | 27 + db/custom_formats/codec/h265 (4k).json | 200 ++ db/custom_formats/codec/h265.json | 242 +++ db/custom_formats/codec/x264.json | 172 ++ db/custom_formats/codec/x265 (Missing).json | 109 ++ db/custom_formats/codec/x265 (Web).json | 151 ++ db/custom_formats/codec/x265.json | 151 ++ db/custom_formats/flag/Freeleech100.json | 82 + db/custom_formats/flag/Freeleech25.json | 82 + db/custom_formats/flag/Freeleech50.json | 82 + db/custom_formats/flag/Freeleech75.json | 82 + .../flag/Golden Popcorn 1080p.json | 152 ++ .../flag/Golden Popcorn 720p.json | 152 ++ db/custom_formats/flag/Golden Popcorn SD.json | 222 +++ db/custom_formats/flag/HDBits Internal.json | 1636 ++++++++++++++++ db/custom_formats/group/3L.json | 27 + db/custom_formats/group/AnoZu.json | 27 + .../group/BHDStudio (1080p x265).json | 48 + db/custom_formats/group/BHDStudio.json | 27 + db/custom_formats/group/BLURANiUM.json | 27 + db/custom_formats/group/BMF.json | 27 + db/custom_formats/group/BV.json | 27 + db/custom_formats/group/BeyondHD.json | 27 + db/custom_formats/group/CRX.json | 27 + db/custom_formats/group/CRiSC.json | 27 + db/custom_formats/group/Chivaman.json | 27 + db/custom_formats/group/Chotab.json | 27 + db/custom_formats/group/CtrlHD.json | 27 + db/custom_formats/group/D-Z0N3.json | 27 + db/custom_formats/group/DON.json | 109 ++ db/custom_formats/group/Dariush .json | 109 ++ db/custom_formats/group/Dariush SD.json | 109 ++ db/custom_formats/group/E.N.D.json | 27 + db/custom_formats/group/E1.json | 27 + db/custom_formats/group/EA.json | 27 + db/custom_formats/group/EDPH.json | 27 + db/custom_formats/group/EPSiLON.json | 27 + db/custom_formats/group/ESiR.json | 27 + db/custom_formats/group/EXCiSiON.json | 27 + db/custom_formats/group/EbP.json | 27 + db/custom_formats/group/FTW-HD.json | 27 + db/custom_formats/group/FoRM.json | 27 + db/custom_formats/group/FraMeSToR.json | 48 + db/custom_formats/group/GALAXY.json | 27 + db/custom_formats/group/GRiMM.json | 109 ++ db/custom_formats/group/GS88.json | 27 + db/custom_formats/group/Geek.json | 27 + db/custom_formats/group/GutS.json | 27 + db/custom_formats/group/HANDJOB SD.json | 109 ++ db/custom_formats/group/HANDJOB.json | 109 ++ db/custom_formats/group/HDMaNiAcS.json | 27 + db/custom_formats/group/HONE.json | 109 ++ db/custom_formats/group/HiDt.json | 27 + db/custom_formats/group/HiFi.json | 27 + db/custom_formats/group/HiP.json | 27 + db/custom_formats/group/IDE.json | 27 + db/custom_formats/group/KASHMiR.json | 27 + db/custom_formats/group/LEGi0N (x265).json | 48 + db/custom_formats/group/LEGi0N.json | 27 + db/custom_formats/group/LSt.json | 27 + db/custom_formats/group/LoRD.json | 27 + db/custom_formats/group/LolHD.json | 27 + db/custom_formats/group/MTeam.json | 27 + db/custom_formats/group/MainFrame.json | 27 + db/custom_formats/group/NAN0.json | 27 + db/custom_formats/group/NCmt.json | 27 + db/custom_formats/group/NTb.json | 109 ++ db/custom_formats/group/NyHD.json | 27 + db/custom_formats/group/ORiGEN.json | 27 + db/custom_formats/group/PTer.json | 27 + db/custom_formats/group/Penumbra.json | 27 + db/custom_formats/group/PmP.json | 27 + db/custom_formats/group/Positive.json | 27 + db/custom_formats/group/QxR.json | 132 ++ db/custom_formats/group/R1GY3B B3YG1R.json | 27 + db/custom_formats/group/Ralphy.json | 48 + db/custom_formats/group/RightSIZE.json | 27 + db/custom_formats/group/SA89.json | 27 + db/custom_formats/group/SEV.json | 111 ++ db/custom_formats/group/SaNcTi.json | 27 + db/custom_formats/group/SbR.json | 27 + db/custom_formats/group/Scene.json | 256 +++ db/custom_formats/group/SiMPLE.json | 27 + db/custom_formats/group/TAoE.json | 69 + db/custom_formats/group/TBB SD.json | 109 ++ db/custom_formats/group/TBB.json | 109 ++ db/custom_formats/group/TDD.json | 27 + db/custom_formats/group/TRiToN.json | 27 + db/custom_formats/group/TayTo.json | 27 + db/custom_formats/group/ThD.json | 27 + db/custom_formats/group/TimeDistortion.json | 27 + .../group/Unwanted x265 Groups.json | 27 + db/custom_formats/group/VietHD.json | 27 + db/custom_formats/group/Vyndros.json | 27 + db/custom_formats/group/W4NK3R.json | 27 + db/custom_formats/group/WMING.json | 27 + db/custom_formats/group/WiLDCAT.json | 27 + db/custom_formats/group/ZIMBO.json | 27 + db/custom_formats/group/ZQ.json | 27 + db/custom_formats/group/c0ke.json | 27 + db/custom_formats/group/de[42].json | 27 + db/custom_formats/group/decibeL.json | 27 + db/custom_formats/group/dkore.json | 27 + db/custom_formats/group/edge2020.json | 27 + db/custom_formats/group/iFT.json | 27 + db/custom_formats/group/jennaortegaUHD.json | 27 + db/custom_formats/group/luvBB.json | 27 + db/custom_formats/group/mHD.json | 27 + db/custom_formats/group/nmd.json | 27 + db/custom_formats/group/playBD.json | 27 + db/custom_formats/group/playHD.json | 27 + db/custom_formats/group/xander.json | 27 + .../hdr/Dolby Vision wout Fallback.json | 27 + db/custom_formats/hdr/Dolby Vision.json | 69 + .../hdr/HDR10 (Missing) (x265 HDR only).json | 132 ++ db/custom_formats/hdr/HDR10 (Missing).json | 160 ++ db/custom_formats/hdr/HDR10+.json | 90 + db/custom_formats/hdr/HDR10.json | 111 ++ db/custom_formats/other/3D.json | 69 + db/custom_formats/other/Black and White.json | 27 + db/custom_formats/other/DVD.json | 109 ++ db/custom_formats/other/Disc .json | 48 + db/custom_formats/other/Extras.json | 27 + db/custom_formats/other/IMAX.json | 48 + db/custom_formats/other/LQ.json | 1707 +++++++++++++++++ db/custom_formats/other/Stream Optimised.json | 27 + db/custom_formats/other/UHDBits.json | 27 + db/custom_formats/other/Upscaled.json | 27 + db/custom_formats/resolution/1080p.json | 90 + db/custom_formats/resolution/2160p.json | 90 + db/custom_formats/resolution/480p.json | 146 ++ db/custom_formats/resolution/720p.json | 90 + db/custom_formats/resolution/Unwanted.json | 368 ++++ db/custom_formats/source/Blu-Ray.json | 109 ++ db/custom_formats/source/UHD Bluray.json | 48 + db/custom_formats/streaming/7PLUS.json | 112 ++ db/custom_formats/streaming/Amazon Prime.json | 109 ++ db/custom_formats/streaming/Apple TV+.json | 109 ++ db/custom_formats/streaming/Disney+.json | 109 ++ db/custom_formats/streaming/HBO Max.json | 109 ++ db/custom_formats/streaming/Hulu.json | 109 ++ db/custom_formats/streaming/MAX.json | 191 ++ .../streaming/Movies Anywhere.json | 130 ++ db/custom_formats/streaming/Netflix.json | 109 ++ db/custom_formats/streaming/Paramount+.json | 109 ++ db/custom_formats/streaming/Peacock TV.json | 109 ++ db/custom_formats/streaming/ROKU.json | 109 ++ .../streaming/iTunes (Missing).json | 422 ++++ db/custom_formats/streaming/iTunes.json | 191 ++ db/quality_profiles/1080p Transparent.json | 0 scripts/split.sh | 46 + tests/regex.py | 152 ++ 172 files changed, 15610 insertions(+) create mode 100644 .github/CODEOWNERS create mode 100644 .github/workflows/test.yml create mode 100644 db/custom_formats/audio/ATMOS (Missing).json create mode 100644 db/custom_formats/audio/ATMOS.json create mode 100644 db/custom_formats/audio/DD+.json create mode 100644 db/custom_formats/audio/DD.json create mode 100644 db/custom_formats/audio/DTS-HD MA.json create mode 100644 db/custom_formats/audio/DTS-X.json create mode 100644 db/custom_formats/audio/DTS.json create mode 100644 db/custom_formats/audio/FLAC.json create mode 100644 db/custom_formats/audio/PCM.json create mode 100644 db/custom_formats/audio/TrueHD (Missing).json create mode 100644 db/custom_formats/audio/TrueHD.json create mode 100644 db/custom_formats/codec/2160p x265.json create mode 100644 db/custom_formats/codec/AV1.json create mode 100644 db/custom_formats/codec/Blu-Ray (Remux).json create mode 100644 db/custom_formats/codec/DVD REMUX .json create mode 100644 db/custom_formats/codec/REMUX.json create mode 100644 db/custom_formats/codec/VVC.json create mode 100644 db/custom_formats/codec/WEBRip.json create mode 100644 db/custom_formats/codec/Xvid.json create mode 100644 db/custom_formats/codec/h265 (4k).json create mode 100644 db/custom_formats/codec/h265.json create mode 100644 db/custom_formats/codec/x264.json create mode 100644 db/custom_formats/codec/x265 (Missing).json create mode 100644 db/custom_formats/codec/x265 (Web).json create mode 100644 db/custom_formats/codec/x265.json create mode 100644 db/custom_formats/flag/Freeleech100.json create mode 100644 db/custom_formats/flag/Freeleech25.json create mode 100644 db/custom_formats/flag/Freeleech50.json create mode 100644 db/custom_formats/flag/Freeleech75.json create mode 100644 db/custom_formats/flag/Golden Popcorn 1080p.json create mode 100644 db/custom_formats/flag/Golden Popcorn 720p.json create mode 100644 db/custom_formats/flag/Golden Popcorn SD.json create mode 100644 db/custom_formats/flag/HDBits Internal.json create mode 100644 db/custom_formats/group/3L.json create mode 100644 db/custom_formats/group/AnoZu.json create mode 100644 db/custom_formats/group/BHDStudio (1080p x265).json create mode 100644 db/custom_formats/group/BHDStudio.json create mode 100644 db/custom_formats/group/BLURANiUM.json create mode 100644 db/custom_formats/group/BMF.json create mode 100644 db/custom_formats/group/BV.json create mode 100644 db/custom_formats/group/BeyondHD.json create mode 100644 db/custom_formats/group/CRX.json create mode 100644 db/custom_formats/group/CRiSC.json create mode 100644 db/custom_formats/group/Chivaman.json create mode 100644 db/custom_formats/group/Chotab.json create mode 100644 db/custom_formats/group/CtrlHD.json create mode 100644 db/custom_formats/group/D-Z0N3.json create mode 100644 db/custom_formats/group/DON.json create mode 100644 db/custom_formats/group/Dariush .json create mode 100644 db/custom_formats/group/Dariush SD.json create mode 100644 db/custom_formats/group/E.N.D.json create mode 100644 db/custom_formats/group/E1.json create mode 100644 db/custom_formats/group/EA.json create mode 100644 db/custom_formats/group/EDPH.json create mode 100644 db/custom_formats/group/EPSiLON.json create mode 100644 db/custom_formats/group/ESiR.json create mode 100644 db/custom_formats/group/EXCiSiON.json create mode 100644 db/custom_formats/group/EbP.json create mode 100644 db/custom_formats/group/FTW-HD.json create mode 100644 db/custom_formats/group/FoRM.json create mode 100644 db/custom_formats/group/FraMeSToR.json create mode 100644 db/custom_formats/group/GALAXY.json create mode 100644 db/custom_formats/group/GRiMM.json create mode 100644 db/custom_formats/group/GS88.json create mode 100644 db/custom_formats/group/Geek.json create mode 100644 db/custom_formats/group/GutS.json create mode 100644 db/custom_formats/group/HANDJOB SD.json create mode 100644 db/custom_formats/group/HANDJOB.json create mode 100644 db/custom_formats/group/HDMaNiAcS.json create mode 100644 db/custom_formats/group/HONE.json create mode 100644 db/custom_formats/group/HiDt.json create mode 100644 db/custom_formats/group/HiFi.json create mode 100644 db/custom_formats/group/HiP.json create mode 100644 db/custom_formats/group/IDE.json create mode 100644 db/custom_formats/group/KASHMiR.json create mode 100644 db/custom_formats/group/LEGi0N (x265).json create mode 100644 db/custom_formats/group/LEGi0N.json create mode 100644 db/custom_formats/group/LSt.json create mode 100644 db/custom_formats/group/LoRD.json create mode 100644 db/custom_formats/group/LolHD.json create mode 100644 db/custom_formats/group/MTeam.json create mode 100644 db/custom_formats/group/MainFrame.json create mode 100644 db/custom_formats/group/NAN0.json create mode 100644 db/custom_formats/group/NCmt.json create mode 100644 db/custom_formats/group/NTb.json create mode 100644 db/custom_formats/group/NyHD.json create mode 100644 db/custom_formats/group/ORiGEN.json create mode 100644 db/custom_formats/group/PTer.json create mode 100644 db/custom_formats/group/Penumbra.json create mode 100644 db/custom_formats/group/PmP.json create mode 100644 db/custom_formats/group/Positive.json create mode 100644 db/custom_formats/group/QxR.json create mode 100644 db/custom_formats/group/R1GY3B B3YG1R.json create mode 100644 db/custom_formats/group/Ralphy.json create mode 100644 db/custom_formats/group/RightSIZE.json create mode 100644 db/custom_formats/group/SA89.json create mode 100644 db/custom_formats/group/SEV.json create mode 100644 db/custom_formats/group/SaNcTi.json create mode 100644 db/custom_formats/group/SbR.json create mode 100644 db/custom_formats/group/Scene.json create mode 100644 db/custom_formats/group/SiMPLE.json create mode 100644 db/custom_formats/group/TAoE.json create mode 100644 db/custom_formats/group/TBB SD.json create mode 100644 db/custom_formats/group/TBB.json create mode 100644 db/custom_formats/group/TDD.json create mode 100644 db/custom_formats/group/TRiToN.json create mode 100644 db/custom_formats/group/TayTo.json create mode 100644 db/custom_formats/group/ThD.json create mode 100644 db/custom_formats/group/TimeDistortion.json create mode 100644 db/custom_formats/group/Unwanted x265 Groups.json create mode 100644 db/custom_formats/group/VietHD.json create mode 100644 db/custom_formats/group/Vyndros.json create mode 100644 db/custom_formats/group/W4NK3R.json create mode 100644 db/custom_formats/group/WMING.json create mode 100644 db/custom_formats/group/WiLDCAT.json create mode 100644 db/custom_formats/group/ZIMBO.json create mode 100644 db/custom_formats/group/ZQ.json create mode 100644 db/custom_formats/group/c0ke.json create mode 100644 db/custom_formats/group/de[42].json create mode 100644 db/custom_formats/group/decibeL.json create mode 100644 db/custom_formats/group/dkore.json create mode 100644 db/custom_formats/group/edge2020.json create mode 100644 db/custom_formats/group/iFT.json create mode 100644 db/custom_formats/group/jennaortegaUHD.json create mode 100644 db/custom_formats/group/luvBB.json create mode 100644 db/custom_formats/group/mHD.json create mode 100644 db/custom_formats/group/nmd.json create mode 100644 db/custom_formats/group/playBD.json create mode 100644 db/custom_formats/group/playHD.json create mode 100644 db/custom_formats/group/xander.json create mode 100644 db/custom_formats/hdr/Dolby Vision wout Fallback.json create mode 100644 db/custom_formats/hdr/Dolby Vision.json create mode 100644 db/custom_formats/hdr/HDR10 (Missing) (x265 HDR only).json create mode 100644 db/custom_formats/hdr/HDR10 (Missing).json create mode 100644 db/custom_formats/hdr/HDR10+.json create mode 100644 db/custom_formats/hdr/HDR10.json create mode 100644 db/custom_formats/other/3D.json create mode 100644 db/custom_formats/other/Black and White.json create mode 100644 db/custom_formats/other/DVD.json create mode 100644 db/custom_formats/other/Disc .json create mode 100644 db/custom_formats/other/Extras.json create mode 100644 db/custom_formats/other/IMAX.json create mode 100644 db/custom_formats/other/LQ.json create mode 100644 db/custom_formats/other/Stream Optimised.json create mode 100644 db/custom_formats/other/UHDBits.json create mode 100644 db/custom_formats/other/Upscaled.json create mode 100644 db/custom_formats/resolution/1080p.json create mode 100644 db/custom_formats/resolution/2160p.json create mode 100644 db/custom_formats/resolution/480p.json create mode 100644 db/custom_formats/resolution/720p.json create mode 100644 db/custom_formats/resolution/Unwanted.json create mode 100644 db/custom_formats/source/Blu-Ray.json create mode 100644 db/custom_formats/source/UHD Bluray.json create mode 100644 db/custom_formats/streaming/7PLUS.json create mode 100644 db/custom_formats/streaming/Amazon Prime.json create mode 100644 db/custom_formats/streaming/Apple TV+.json create mode 100644 db/custom_formats/streaming/Disney+.json create mode 100644 db/custom_formats/streaming/HBO Max.json create mode 100644 db/custom_formats/streaming/Hulu.json create mode 100644 db/custom_formats/streaming/MAX.json create mode 100644 db/custom_formats/streaming/Movies Anywhere.json create mode 100644 db/custom_formats/streaming/Netflix.json create mode 100644 db/custom_formats/streaming/Paramount+.json create mode 100644 db/custom_formats/streaming/Peacock TV.json create mode 100644 db/custom_formats/streaming/ROKU.json create mode 100644 db/custom_formats/streaming/iTunes (Missing).json create mode 100644 db/custom_formats/streaming/iTunes.json create mode 100644 db/quality_profiles/1080p Transparent.json create mode 100755 scripts/split.sh create mode 100755 tests/regex.py diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..bbd74e7 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @santiagosayshey \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..63cbe00 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,27 @@ +name: Run Tests + +on: + push: + branches: [dev] + pull_request: + branches: [dev] + +jobs: + run-tests: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.9 + + - name: Install dependencies + run: | + python3 -m pip install --upgrade pip + pip install colorama + + - name: Run regex tests + run: python3 tests/regex.py \ No newline at end of file diff --git a/db/custom_formats/audio/ATMOS (Missing).json b/db/custom_formats/audio/ATMOS (Missing).json new file mode 100644 index 0000000..5af24d0 --- /dev/null +++ b/db/custom_formats/audio/ATMOS (Missing).json @@ -0,0 +1,69 @@ +{ + "name": "ATMOS (Missing)", + "includeCustomFormatWhenRenaming": false, + "specifications": [ + { + "name": "TrueHD", + "implementation": "ReleaseTitleSpecification", + "implementationName": "Release Title", + "infoLink": "https://wiki.servarr.com/radarr/settings#custom-formats-2", + "negate": false, + "required": true, + "fields": [ + { + "order": 0, + "name": "value", + "label": "Regular Expression", + "helpText": "Custom Format RegEx is Case Insensitive", + "value": "True[ .-]?HD[ .-]?7\\.1", + "type": "textbox", + "advanced": false, + "privacy": "normal", + "isFloat": false + } + ] + }, + { + "name": "Atmos", + "implementation": "ReleaseTitleSpecification", + "implementationName": "Release Title", + "infoLink": "https://wiki.servarr.com/radarr/settings#custom-formats-2", + "negate": true, + "required": true, + "fields": [ + { + "order": 0, + "name": "value", + "label": "Regular Expression", + "helpText": "Custom Format RegEx is Case Insensitive", + "value": "\\bATMOS(\\b|\\d)", + "type": "textbox", + "advanced": false, + "privacy": "normal", + "isFloat": false + } + ] + }, + { + "name": "7.1", + "implementation": "ReleaseTitleSpecification", + "implementationName": "Release Title", + "infoLink": "https://wiki.servarr.com/radarr/settings#custom-formats-2", + "negate": false, + "required": true, + "fields": [ + { + "order": 0, + "name": "value", + "label": "Regular Expression", + "helpText": "Custom Format RegEx is Case Insensitive", + "value": "7.1", + "type": "textbox", + "advanced": false, + "privacy": "normal", + "isFloat": false + } + ] + } + ] +} diff --git a/db/custom_formats/audio/ATMOS.json b/db/custom_formats/audio/ATMOS.json new file mode 100644 index 0000000..2ecb3e3 --- /dev/null +++ b/db/custom_formats/audio/ATMOS.json @@ -0,0 +1,27 @@ +{ + "name": "ATMOS", + "includeCustomFormatWhenRenaming": true, + "specifications": [ + { + "name": "ATMOS", + "implementation": "ReleaseTitleSpecification", + "implementationName": "Release Title", + "infoLink": "https://wiki.servarr.com/radarr/settings#custom-formats-2", + "negate": false, + "required": true, + "fields": [ + { + "order": 0, + "name": "value", + "label": "Regular Expression", + "helpText": "Custom Format RegEx is Case Insensitive", + "value": "\\bATMOS(\\b|\\d)", + "type": "textbox", + "advanced": false, + "privacy": "normal", + "isFloat": false + } + ] + } + ] +} diff --git a/db/custom_formats/audio/DD+.json b/db/custom_formats/audio/DD+.json new file mode 100644 index 0000000..dabcc2d --- /dev/null +++ b/db/custom_formats/audio/DD+.json @@ -0,0 +1,132 @@ +{ + "name": "DD+", + "includeCustomFormatWhenRenaming": false, + "specifications": [ + { + "name": "Dolby Digital Plus", + "implementation": "ReleaseTitleSpecification", + "implementationName": "Release Title", + "infoLink": "https://wiki.servarr.com/radarr/settings#custom-formats-2", + "negate": false, + "required": true, + "fields": [ + { + "order": 0, + "name": "value", + "label": "Regular Expression", + "helpText": "Custom Format RegEx is Case Insensitive", + "value": "\\bDD[P+](?!A)|\\b(e[-_. ]?ac3)\\b", + "type": "textbox", + "advanced": false, + "privacy": "normal", + "isFloat": false + } + ] + }, + { + "name": "TrueHD", + "implementation": "ReleaseTitleSpecification", + "implementationName": "Release Title", + "infoLink": "https://wiki.servarr.com/radarr/settings#custom-formats-2", + "negate": true, + "required": true, + "fields": [ + { + "order": 0, + "name": "value", + "label": "Regular Expression", + "helpText": "Custom Format RegEx is Case Insensitive", + "value": "True[ .-]?HD", + "type": "textbox", + "advanced": false, + "privacy": "normal", + "isFloat": false + } + ] + }, + { + "name": "Not DTS", + "implementation": "ReleaseTitleSpecification", + "implementationName": "Release Title", + "infoLink": "https://wiki.servarr.com/radarr/settings#custom-formats-2", + "negate": true, + "required": true, + "fields": [ + { + "order": 0, + "name": "value", + "label": "Regular Expression", + "helpText": "Custom Format RegEx is Case Insensitive", + "value": "\\bDTS(\\b|\\d)", + "type": "textbox", + "advanced": false, + "privacy": "normal", + "isFloat": false + } + ] + }, + { + "name": "Not FLAC", + "implementation": "ReleaseTitleSpecification", + "implementationName": "Release Title", + "infoLink": "https://wiki.servarr.com/radarr/settings#custom-formats-2", + "negate": true, + "required": true, + "fields": [ + { + "order": 0, + "name": "value", + "label": "Regular Expression", + "helpText": "Custom Format RegEx is Case Insensitive", + "value": "\\bFLAC(\\b|\\d)", + "type": "textbox", + "advanced": false, + "privacy": "normal", + "isFloat": false + } + ] + }, + { + "name": "Not AAC", + "implementation": "ReleaseTitleSpecification", + "implementationName": "Release Title", + "infoLink": "https://wiki.servarr.com/radarr/settings#custom-formats-2", + "negate": true, + "required": true, + "fields": [ + { + "order": 0, + "name": "value", + "label": "Regular Expression", + "helpText": "Custom Format RegEx is Case Insensitive", + "value": "\\bAAC(\\b|\\d)", + "type": "textbox", + "advanced": false, + "privacy": "normal", + "isFloat": false + } + ] + }, + { + "name": "Not PCM", + "implementation": "ReleaseTitleSpecification", + "implementationName": "Release Title", + "infoLink": "https://wiki.servarr.com/radarr/settings#custom-formats-2", + "negate": true, + "required": true, + "fields": [ + { + "order": 0, + "name": "value", + "label": "Regular Expression", + "helpText": "Custom Format RegEx is Case Insensitive", + "value": "\\b(l?)PCM(\\b|\\d)", + "type": "textbox", + "advanced": false, + "privacy": "normal", + "isFloat": false + } + ] + } + ] +} diff --git a/db/custom_formats/audio/DD.json b/db/custom_formats/audio/DD.json new file mode 100644 index 0000000..768751b --- /dev/null +++ b/db/custom_formats/audio/DD.json @@ -0,0 +1,153 @@ +{ + "name": "DD", + "includeCustomFormatWhenRenaming": true, + "specifications": [ + { + "name": "Basic Dolby Digital", + "implementation": "ReleaseTitleSpecification", + "implementationName": "Release Title", + "infoLink": "https://wiki.servarr.com/radarr/settings#custom-formats-2", + "negate": false, + "required": true, + "fields": [ + { + "order": 0, + "name": "value", + "label": "Regular Expression", + "helpText": "Custom Format RegEx is Case Insensitive", + "value": "\\bDD[^a-z+]|(? /dev/null +then + echo "jq could not be found. Please install jq before running this script." + exit 1 +fi + +# Check if input file is provided as an argument +if [ "$#" -ne 1 ]; then + echo "Usage: $0 " + exit 1 +fi + +# Input JSON file +input_file="$1" + +# Check if the input file exists +if [[ ! -f "$input_file" ]]; then + echo "Input file not found: $input_file" + exit 1 +fi + +# Create output directory if it doesn't exist +output_dir="../output" +mkdir -p "$output_dir" + +# Function to sanitize filenames by removing slashes +sanitize_filename() { + echo "$1" | tr -d '/' +} + +# Read each object in the array and save to a separate JSON file +jq -c '.[]' "$input_file" | while read -r object; do + name=$(echo "$object" | jq -r '.name') + if [[ -n "$name" ]]; then + sanitized_name=$(sanitize_filename "$name") + echo "$object" | jq '.' > "$output_dir/$sanitized_name.json" + echo "Created file: $output_dir/$sanitized_name.json" + else + echo "Skipping object without a name field: $object" + fi +done + +echo "Finished processing JSON objects." diff --git a/tests/regex.py b/tests/regex.py new file mode 100755 index 0000000..f8244d7 --- /dev/null +++ b/tests/regex.py @@ -0,0 +1,152 @@ +import json +import subprocess +import time +import re +import os +import sys +from colorama import Fore, Style + +class RegexTester: + def __init__(self, max_retries=3, retry_delay=1): + self.max_retries = max_retries + self.retry_delay = retry_delay + + def get_latest_revision(self, unique_id): + url = f"https://regex101.com/api/regex/{unique_id}" + retries = 0 + while retries < self.max_retries: + try: + response = subprocess.check_output(["curl", "-s", url]) + data = json.loads(response.decode("utf-8")) + revisions = data["versions"] + latest_revision = revisions[-1] + return latest_revision + except (subprocess.CalledProcessError, json.JSONDecodeError) as e: + print(f"{Fore.YELLOW}Warning: {str(e)}. Retrying in {self.retry_delay} second(s)...{Style.RESET_ALL}") + retries += 1 + time.sleep(self.retry_delay) + raise Exception("Failed to retrieve latest revision after multiple retries.") + + def get_regex_data(self, unique_id, revision): + url = f"https://regex101.com/api/regex/{unique_id}/{revision}" + retries = 0 + while retries < self.max_retries: + try: + response = subprocess.check_output(["curl", "-s", url]) + data = json.loads(response.decode("utf-8")) + regex_pattern = data["regex"] + unit_tests = data["unitTests"] + flavor = data["flavor"] + return regex_pattern, unit_tests, flavor + except (subprocess.CalledProcessError, json.JSONDecodeError) as e: + print(f"{Fore.YELLOW}Warning: {str(e)}. Retrying in {self.retry_delay} second(s)...{Style.RESET_ALL}") + retries += 1 + time.sleep(self.retry_delay) + raise Exception("Failed to retrieve regex data after multiple retries.") + + def run_unit_tests(self, regex_pattern, flavor, unit_tests): + success_count = 0 + failure_count = 0 + if flavor == "pcre2": + regex_flags = re.MULTILINE | re.IGNORECASE | re.DOTALL + else: + regex_flags = re.MULTILINE | re.IGNORECASE + + for test in unit_tests: + test_string = test["testString"] + criteria = test["criteria"] + target = test["target"] + + if target == "REGEX": + matches = re.finditer(regex_pattern, test_string, regex_flags) + match_found = bool(list(matches)) + + if criteria == "DOES_MATCH": + if match_found: + success_count += 1 + print(f"{Fore.GREEN}Passed test{Style.RESET_ALL}: '{test_string}'") + else: + failure_count += 1 + print(f"{Fore.RED}Should match{Style.RESET_ALL} '{test_string}'") + elif criteria == "DOES_NOT_MATCH": + if not match_found: + success_count += 1 + print(f"{Fore.GREEN}Passed test{Style.RESET_ALL}: '{test_string}'") + else: + failure_count += 1 + print(f"{Fore.RED}Shouldn't match{Style.RESET_ALL} '{test_string}'") + + return success_count, failure_count + +def extract_regex_ids(data): + regex_ids = {} + + def extract_ids(obj): + if isinstance(obj, dict): + if "fields" in obj: + for field in obj["fields"]: + if "regexID" in field: + regex_id = field["regexID"] + name = obj.get("name", "") + regex_ids[regex_id] = name + for value in obj.values(): + extract_ids(value) + elif isinstance(obj, list): + for item in obj: + extract_ids(item) + + extract_ids(data) + return regex_ids + +def main(): + tester = RegexTester() + regex_dir = "./db/custom_formats" + tested_ids = set() + any_test_failed = False + + for root, dirs, files in os.walk(regex_dir): + for filename in files: + if filename.endswith(".json"): + filepath = os.path.join(root, filename) + with open(filepath, "r") as f: + data = json.load(f) + + regex_ids = extract_regex_ids(data) + + for regex_id, name in regex_ids.items(): + if regex_id not in tested_ids: + tested_ids.add(regex_id) + try: + latest_revision = tester.get_latest_revision(regex_id) + regex_pattern, unit_tests, flavor = tester.get_regex_data(regex_id, latest_revision) + print(f"====================") + print(f"Running Test: {Fore.YELLOW}{name}{Style.RESET_ALL}") + print(f"Regex: {Fore.YELLOW}{regex_pattern}{Style.RESET_ALL}") + print(f"Link: {Fore.BLUE}https://regex101.com/r/{regex_id}{Style.RESET_ALL}") + print(f"====================") + print() + + total_tests = len(unit_tests) + passed_tests, failed_tests = tester.run_unit_tests(regex_pattern, flavor, unit_tests) + + score_color = Fore.GREEN if passed_tests == total_tests else Fore.RED + status_text = "PASS" if failed_tests == 0 else "FAIL" + status_color = Fore.GREEN if status_text == "PASS" else Fore.RED + + print() + print(f"====================") + print(f"Score: {score_color}{passed_tests} / {total_tests}{Style.RESET_ALL}") + print(f"Status: {status_color}{status_text}{Style.RESET_ALL}") + print(f"====================") + print() + + if failed_tests > 0: + sys.exit(1) + except Exception as e: + print(f"{Fore.RED}Error processing regex {regex_id}: {str(e)}{Style.RESET_ALL}") + print() + sys.exit(1) + sys.exit(0) + +if __name__ == "__main__": + main() \ No newline at end of file