Last active
February 16, 2026 17:47
-
-
Save rubenhortas/d0ccd46750dd009d0f3fbedec5a4ecc9 to your computer and use it in GitHub Desktop.
Utility to normalize TV show filenames
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3 | |
| """ | |
| TV Show Renamer: A utility to normalize TV show filenames. | |
| This script automates the tedious process of renaming video files from messy | |
| tracker formats (e.g., 'Show.Name.S01E01.720p.x264-Group.mkv') into a clean, | |
| standardized structure (e.g., 'Show Name S01E01.mkv'). | |
| KEY FEATURES: | |
| * Format Normalization: Converts multiple episode formats (S01E01, 1x01, | |
| [Cap.101]) into a single consistent output style (English or Spanish). | |
| * Intelligent Cleanup: Automatically removes over 100+ common metadata | |
| tags, including video quality (4K, 1080p), codecs (x264, HEVC), | |
| platforms (NF, AMZN), and release group names. | |
| * Recursive Processing: Can scan entire directory trees to find and | |
| process video files (.mp4, .mkv, .avi). | |
| * Safety First: Includes a 'Test Mode' (-t) to preview changes without | |
| modifying any files, and prevents overwriting existing files. | |
| * Clean Typography: Corrects capitalization and removes redundant | |
| periods, underscores, and dashes from titles. | |
| USAGE: | |
| usage: tv_show_renamer.py [-h] [-t] [-of {en,es}] [-sf {en,es}] [-ts TITLE_SEPARATOR] [paths ...] | |
| TV Show Renamer (Normalize 'S01E01' and '1x01' formats) | |
| positional arguments: | |
| paths Directories to process | |
| options: | |
| -h, --help show this help message and exit | |
| -t, --test Test mode (no changes) | |
| -of, --output-format {en,es} | |
| Format: 'en' (S01E01) or 'es' (01x01). Default: 'en' | |
| -sf, --skip-format {en,es} | |
| Skip files that already have this format | |
| -ts, --title-separator TITLE_SEPARATOR | |
| Separating character between the episode and the title, e.g.: '-' | |
| """ | |
| import argparse | |
| import re | |
| import signal | |
| import sys | |
| from pathlib import Path | |
| # Keywords to strip (Case insensitive) | |
| # Don't add '[]' | |
| _ACRONYMS = [ | |
| # Video qualities | |
| "CAM", | |
| "CAMRIP", | |
| "HDCAM", | |
| "BDSCR", | |
| "DDC", | |
| "DVDSCR", | |
| "DVDSCREENER", | |
| "SCR", | |
| "SCREENER", | |
| "WEBSCREENER", | |
| "HDTC", | |
| "TC", | |
| "TELECINE", | |
| "HDTS", | |
| "TELESYNC", | |
| "TS", | |
| "TVRIP", | |
| "VHSRIP", | |
| "WP", | |
| "WORKPRINT", | |
| "BD5", | |
| "BD9", | |
| "BD25", | |
| "BD50", | |
| "BD66", | |
| "BD100", | |
| "BDISO", | |
| "BDMV", | |
| "BDR", | |
| "BDRIP", | |
| "DISC", | |
| "BLU RAY", | |
| "BLU RAY RIP", | |
| "BLURAY", | |
| "BRIP", | |
| "BRRIP", | |
| "COMPLETE.BLURAY", | |
| "REMUX", | |
| "PDTV", | |
| "DVDMUX", | |
| "DVDR", | |
| "DVDRIP", | |
| "DVD-5", | |
| "DVD-9", | |
| "DVD-FULL", | |
| "FULL-RIP", | |
| "ISO RIP", | |
| "ISOLESS RIP", | |
| "P_REDVDRIP", | |
| "UNTOUCHED RIP", | |
| "HD", | |
| "HDRIP", | |
| "HDTV", | |
| "HDTVRIP", | |
| "PPV", | |
| "PPVRIP", | |
| "WEB", | |
| "WEB DL", | |
| "WEB RIP", | |
| "WEB (SCENE)", | |
| "WEBDL", | |
| "WEBRIP", | |
| "WEB-DL", | |
| "WEB-DLRIP", | |
| "WEB-RIP", | |
| # 4K | |
| "DS4k", | |
| "RM4K", | |
| # Video resolutions | |
| "m-720p", | |
| "mini 720p", | |
| "720p", | |
| "m-1080p", | |
| "mini 1080p", | |
| "1080", | |
| "1080p", | |
| "m1080p", | |
| "mHD", | |
| "mini HD", | |
| "μHD", | |
| "micro HD", | |
| # Video Codecs | |
| "XVid", | |
| "AV1", | |
| "x264", | |
| "AVC", | |
| "h264", | |
| "H.264", | |
| "H-264", | |
| "H 264", | |
| "x265", | |
| "h265", | |
| "H.265", | |
| "H 265", | |
| "HEVC", | |
| "10bit", | |
| # Video bit rates | |
| "CBR", | |
| "VBR", | |
| # Video dynamic range | |
| "SDR", | |
| "HDR", | |
| # Audio languages | |
| "Dual", | |
| "MULTI", | |
| "AA3", | |
| "AAc", | |
| "AAC2 0", | |
| "AC3", | |
| # Audio qualities | |
| "2.0", | |
| "2Ch", | |
| "5.1", | |
| "7.1", | |
| "2 0", | |
| "5 1", | |
| "7 1", | |
| # Audio Codecs | |
| "AA3", | |
| "AC3", | |
| "DDP", | |
| "DDP2.0", | |
| "DDP2 0", | |
| "DDP5.1", | |
| "DDP5 1", | |
| # Corrected versions | |
| "(Proper)", | |
| "(Repack)", | |
| "PROPER", | |
| "REPACK", | |
| # Subtitles | |
| "+Subs", | |
| "HC", | |
| "MULTISUBS", | |
| "Subs", | |
| "SUBTITLES", | |
| # Platforfms | |
| "A3P", | |
| "ABC", | |
| "ALL4", | |
| "AMZ", | |
| "AMZN", | |
| "ARD", | |
| "ATVP", | |
| "APTV", | |
| "BBC", | |
| "CBC", | |
| "CBS", | |
| "CR", | |
| "DSNP", | |
| "DISNEY", | |
| "HBO", | |
| "HBOM", | |
| "HMax", | |
| "HULU", | |
| "NBC", | |
| "NF", | |
| "NFLX", | |
| "PARA", | |
| "PMNT", | |
| "PCOK", | |
| "PCKL", | |
| "SHOW", | |
| "STZ", | |
| # Groups and sites | |
| "AFG", | |
| "EZTV.to", | |
| "EZTVx.to", | |
| "eztv.re", | |
| "www.AtomixHQ.com", | |
| "www.AtomixHQ.link", | |
| "www.AtomoHD.BEER", | |
| "www.AtomoHD.CASA", | |
| "www.AtomoHD.cloud", | |
| "www.AtomoHD.FUTBOL", | |
| "www.AtomoHD.LOVE", | |
| "www.AtomoHD.ninja", | |
| "www.AtomoHD.PLUS", | |
| "www.descargas2020.com", | |
| "www.descargas2020.org", | |
| "www.maxitorrent.com", | |
| "www.PCTmix.com", | |
| "www.pctnew.com", | |
| "www.newpct1.com", | |
| "(wolfmax4k.com)", | |
| "BONE", | |
| "CBFM", | |
| "DiRT", | |
| "EDITH", | |
| "ETHEL", | |
| "FENiX", | |
| "FLUX", | |
| "FREQUENCY", | |
| "GalaxyTV", | |
| "glhf", | |
| "ggwp", | |
| "GRACE", | |
| "HiggsBoson", | |
| "ION10", | |
| "JFF", | |
| "lazycunts", | |
| "MeGusta", | |
| "MGHW", | |
| "NTb", | |
| "RAWR", | |
| "STAN", | |
| "STC", | |
| "successfulcrab", | |
| "SYNCOPY", | |
| "TORRENTGALAXY", | |
| "TRUFFLE", | |
| # Languages | |
| "Cast", | |
| "Castellano", | |
| ] | |
| _VIDEO_EXTENSIONS = {".mp4", ".avi", ".mkv"} | |
| _RE_EPISODE = re.compile( | |
| r""" | |
| (?P<show_name>.*?) | |
| (?: | |
| s(?P<s_en>\d{1,2})e(?P<e_en>\d{2}) | # s01e01 | |
| (?P<s_es>\d{1,2})x(?P<e_es>\d{2}) | # 1x01 | |
| \[Cap.(?P<se_es>\d+)\] # [Cap.101] | |
| ) | |
| [\s\.\-]*(?P<title>.*)$ | |
| """, | |
| re.IGNORECASE | re.VERBOSE, | |
| ) | |
| _RE_CLEANUP_TAGS = re.compile(r"\s*\[.*?\]\s*") | |
| _RE_ACRONYMS_CLEANUP = re.compile( | |
| r"(?:[\s\.\-]+|^)(" | |
| + "|".join(map(re.escape, sorted(_ACRONYMS, key=len, reverse=True))) | |
| + r")(?=[\s\.\-]|$)", | |
| re.IGNORECASE, | |
| ) | |
| _RE_SPACES_CLEANUP = re.compile(r"[\s\.]+") | |
| # ANSI colors | |
| _RED = "\033[91m" | |
| _GREEN = "\033[92m" | |
| _RESET = "\033[0m" | |
| class Video: | |
| __slots__ = [ | |
| "original_name", | |
| "new_name", | |
| "_path", | |
| "_output_format", | |
| "_skip_format", | |
| "_title_separator", | |
| "_extension", | |
| "_language", | |
| ] | |
| def __init__( | |
| self, | |
| file_path: Path, | |
| output_format: str, | |
| skip_format: str | None, | |
| title_separator: str, | |
| ): | |
| self.original_name = file_path.name | |
| self.new_name = None | |
| self._path = file_path | |
| self._output_format = output_format | |
| self._skip_format = skip_format | |
| self._title_separator = title_separator | |
| self._extension = file_path.suffix | |
| self._language = None | |
| self._parse() | |
| def _parse(self) -> None: | |
| match = _RE_EPISODE.search(self._path.stem) | |
| if not match: | |
| return | |
| s_en, e_en = match.group("s_en"), match.group("e_en") | |
| s_es, e_es = match.group("s_es"), match.group("e_es") | |
| se_es = match.group("se_es") | |
| if s_en and e_en: | |
| season, episode, self._language = s_en, e_en, "en" | |
| elif s_es and e_es: | |
| season, episode, self._language = s_es, e_es, "es" | |
| elif se_es: | |
| season = se_es[:-2] if len(se_es) > 2 else "01" | |
| episode = se_es[-2:].zfill(2) | |
| self._language = "es" | |
| else: | |
| return | |
| if self._skip_format == self._language: | |
| return | |
| show_name = self._clean_text(match.group("show_name")) | |
| show_name = " ".join(word.capitalize() for word in show_name.split()) | |
| ep_title = self._clean_text(match.group("title")) | |
| season_int = int(season) | |
| if self._output_format == "en": | |
| formatted_id = f"S{season_int:02d}E{episode}" | |
| else: | |
| formatted_id = f"{season_int:02d}x{episode}" | |
| parts = [show_name, formatted_id] | |
| if ep_title: | |
| if self._title_separator.strip(): | |
| parts.append(self._title_separator) | |
| parts.append(ep_title) | |
| self.new_name = " ".join(parts) + self._extension | |
| def _clean_text(self, text: str) -> str: | |
| if not text: | |
| return "" | |
| clean_text = _RE_CLEANUP_TAGS.sub("", text) | |
| clean_text = _RE_ACRONYMS_CLEANUP.sub(" ", clean_text) | |
| clean_text = _RE_SPACES_CLEANUP.sub(" ", clean_text).strip(" .-_") | |
| return clean_text | |
| def _rename_videos( | |
| directory: Path, | |
| output_format: str, | |
| skip_format: str, | |
| title_separator: str, | |
| testing: bool, | |
| ) -> None: | |
| videos = 0 | |
| renamed = 0 | |
| print( | |
| f"\n{_GREEN + '(TEST) ' + _RESET if testing else ''}Processing: {_GREEN}{directory}{_RESET}" | |
| ) | |
| video_files = ( | |
| f | |
| for f in directory.rglob("*") | |
| if f.suffix.lower() in _VIDEO_EXTENSIONS and f.is_file() | |
| ) | |
| for video_file in sorted(video_files, key=lambda x: x.name): | |
| videos += 1 | |
| video = Video(video_file, output_format, skip_format, title_separator) | |
| if video.new_name and video.new_name != video.original_name: | |
| target = video_file.with_name(video.new_name) | |
| print(f"{video.original_name} -> {_GREEN}{video.new_name}{_RESET}") | |
| if not testing: | |
| if target.exists(): | |
| print(f"{_RED}Skip{_RESET}: '{target}' already exists") | |
| continue | |
| try: | |
| video_file.rename(target) | |
| renamed += 1 | |
| except Exception as e: | |
| print(f"{_RED}Error{_RESET}: {e}") | |
| print(f"\nRenamed {_GREEN}{renamed}{_RESET}/{videos} videos") | |
| def _main(argv: list[str] | None = None) -> int: | |
| parser = argparse.ArgumentParser( | |
| description="TV Show Renamer (Normalize 'S01E01' and '1x01' formats)" | |
| ) | |
| parser.add_argument("paths", nargs="*", help="Directories to process") | |
| parser.add_argument( | |
| "-t", "--test", action="store_true", help="Test mode (no changes)" | |
| ) | |
| parser.add_argument( | |
| "-of", | |
| "--output-format", | |
| choices=["en", "es"], | |
| default="en", | |
| help="Format: 'en' (S01E01) or 'es' (01x01). Default: 'en'", | |
| ) | |
| parser.add_argument( | |
| "-sf", | |
| "--skip-format", | |
| choices=["en", "es"], | |
| help="Skip files that already have this format", | |
| ) | |
| parser.add_argument( | |
| "-ts", | |
| "--title-separator", | |
| default="", | |
| help="Separating character between the episode and the title, e.g.: '-'", | |
| ) | |
| args = parser.parse_args(argv) | |
| if not args.paths: | |
| parser.print_help() | |
| return 0 | |
| try: | |
| title_separator = args.title_separator | |
| if title_separator: | |
| if len(title_separator) > 1 and Path(title_separator).exists(): | |
| print( | |
| f"Warning: The separator '{title_separator}' looks like a filename." | |
| ) | |
| print('If you wanted to use "*", please use quotes: -ts "*"') | |
| for p in args.paths: | |
| path_obj = Path(p).resolve() | |
| if path_obj.is_dir(): | |
| _rename_videos( | |
| directory=path_obj, | |
| output_format=args.output_format, | |
| skip_format=args.skip_format, | |
| title_separator=title_separator, | |
| testing=args.test, | |
| ) | |
| else: | |
| print(f"{_RED}Error{_RESET}: '{p}' is not a directory") | |
| return 0 | |
| except Exception as e: | |
| print(f"{_RED}Error{_RESET}: {e}") | |
| return 1 | |
| if __name__ == "__main__": | |
| signal.signal(signal.SIGINT, lambda sig, frame: sys.exit(0)) | |
| sys.exit(_main(sys.argv[1:])) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #https://www.softzone.es/noticias/open-source/sistema-operativo-linux-kolibrios-1-4-mb/!/usr/bin/env python3 | |
| # Run from cli: | |
| # python3 -m unittest nombre_de_tu_archivo.TvShowRenamerTest.test_name | |
| import unittest | |
| from tv_show_renamer import Video | |
| class FakePath: | |
| def __init__(self, filename: str): | |
| self.name = filename | |
| if '.' in filename: | |
| self.stem = filename.rsplit('.', 1)[0] | |
| self.suffix = f".{filename.rsplit('.', 1)[1]}" | |
| else: | |
| self.stem = filename | |
| self.suffix = "" | |
| def __repr__(self): | |
| return f"FakePath('{self.name}')" | |
| class TvShowRenamerTest(unittest.TestCase): | |
| def setUp(self): | |
| self.separator = '' | |
| self.test_separator = f" {self.separator} " if self.separator.strip() else ' ' | |
| self.filenames = [ | |
| # ES Ok | |
| 'Test 1x02.mkv', | |
| 'Test 01x02.mkv', | |
| 'Test 1x02 - episode title.mkv', | |
| 'Test 33 1x02.mkv', | |
| 'Test 33 1x02 - episode title', | |
| 'Test (testing) 1x02.mkv', | |
| 'Test (testing) 1x02 - episode title.mkv', | |
| 'NotAshow.mkv', | |
| 'Crime 1x02 testing.mkv', | |
| 'Casting 1x02 testing.mkv', | |
| # ES to format | |
| 'Test [HDTV 720p][Cap.102].mkv', | |
| 'Test 1x02 episode title [NF 1080p WEBDL AVC Dual DDP 5.1 + Subs].mkv', | |
| 'Test 1x02 episode title [NF 1080p WEBDL AVC Dual DDP 5.1 + Subs].mkv', | |
| 'Test.[Cap102].episode.title.mkv', | |
| 'Test.testing.1x02.mkv', | |
| 'Test.testing.01x02.mkv', | |
| 'T3st.testing.1x02.mkv', | |
| 'T3st.testing.01x02.mkv', | |
| 'T3st!.testing.1x02.mkv', | |
| 'T3st!.testing.01x02.mkv', | |
| 'Tests 1x02 testing[TS].mkv', | |
| 'Test 1x02 [remove this text.-].mkv', | |
| # EN Ok | |
| 'Test s01e02.mkv', | |
| 'Test s01e02 - episode title.mkv', | |
| 'Test s02e02 episode title.mkv', | |
| # EN to format | |
| 'Test.s01e02.1080p.WEB.h264-EDITH[EZTVx.to].mkv', | |
| 'Test.s01e02.720p.WEB.h264-EDITH[EZTVx.to].mkv', | |
| 'Test.s01e05.1to1.mkv', | |
| 'Test.2025.s01e02.Part1.1080p.AMZN.WEB-DL.DDP5.1.H-264-Ntb.mkv', | |
| 'Test s01e02 episode title 1080p HMax WEB-DL DDP2 0 H 264-STC[EZTVx.to].mkv' | |
| ] | |
| def rename(self, of: str, sf: str|None, expected_results: list): | |
| print('-'*130) | |
| print(f"output format: '{of}' - skip format: '{sf}' - separator: '{self.test_separator}'") | |
| print('-'*130) | |
| for t in zip(self.filenames, expected_results): | |
| fake_file = FakePath(t[0]) | |
| video = Video(fake_file, output_format=of, skip_format=sf, title_separator=self.separator) | |
| new_name = video.new_name if video.new_name else video.original_name | |
| if new_name: | |
| print(f"* {t[0]} -> {new_name}") | |
| self.assertEqual(new_name, t[1]) | |
| print() | |
| def test_en_none(self): | |
| of = 'en' | |
| sf = None | |
| expected_results = [ | |
| # ES Ok | |
| 'Test S01E02.mkv', | |
| 'Test S01E02.mkv', | |
| f"Test S01E02{self.test_separator}episode title.mkv", | |
| 'Test 33 S01E02.mkv', | |
| f"Test 33 S01E02{self.test_separator}episode title", | |
| 'Test (testing) S01E02.mkv', | |
| f"Test (testing) S01E02{self.test_separator}episode title.mkv", | |
| 'NotAshow.mkv', | |
| f"Crime S01E02{self.test_separator}testing.mkv", | |
| f"Casting S01E02{self.test_separator}testing.mkv", | |
| # ES to format | |
| 'Test S01E02.mkv', | |
| f"Test S01E02{self.test_separator}episode title.mkv", | |
| f"Test S01E02{self.test_separator}episode title.mkv", | |
| f"Test S01E02{self.test_separator}episode title.mkv", | |
| 'Test Testing S01E02.mkv', | |
| 'Test Testing S01E02.mkv', | |
| 'T3st Testing S01E02.mkv', | |
| 'T3st Testing S01E02.mkv', | |
| 'T3st! Testing S01E02.mkv', | |
| 'T3st! Testing S01E02.mkv', | |
| f"Tests S01E02{self.test_separator}testing.mkv", | |
| 'Test S01E02.mkv', | |
| # EN Ok | |
| 'Test S01E02.mkv', | |
| f"Test S01E02{self.test_separator}episode title.mkv", | |
| f"Test S02E02{self.test_separator}episode title.mkv", | |
| # EN to format | |
| 'Test S01E02.mkv', | |
| 'Test S01E02.mkv', | |
| f"Test S01E05{self.test_separator}1to1.mkv", | |
| f"Test 2025 S01E02{self.test_separator}Part1.mkv", | |
| f"Test S01E02{self.test_separator}episode title.mkv" | |
| ] | |
| self.rename(of, sf, expected_results) | |
| def test_en_es(self): | |
| of = 'en' | |
| sf = 'es' | |
| expected_results = [ | |
| # ES Ok | |
| 'Test 1x02.mkv', | |
| 'Test 01x02.mkv', | |
| 'Test 1x02 - episode title.mkv', | |
| 'Test 33 1x02.mkv', | |
| 'Test 33 1x02 - episode title', | |
| 'Test (testing) 1x02.mkv', | |
| 'Test (testing) 1x02 - episode title.mkv', | |
| 'NotAshow.mkv', | |
| 'Crime 1x02 testing.mkv', | |
| 'Casting 1x02 testing.mkv', | |
| # ES to format | |
| 'Test [HDTV 720p][Cap.102].mkv', | |
| 'Test 1x02 episode title [NF 1080p WEBDL AVC Dual DDP 5.1 + Subs].mkv', | |
| 'Test 1x02 episode title [NF 1080p WEBDL AVC Dual DDP 5.1 + Subs].mkv', | |
| 'Test.[Cap102].episode.title.mkv', | |
| 'Test.testing.1x02.mkv', | |
| 'Test.testing.01x02.mkv', | |
| 'T3st.testing.1x02.mkv', | |
| 'T3st.testing.01x02.mkv', | |
| 'T3st!.testing.1x02.mkv', | |
| 'T3st!.testing.01x02.mkv', | |
| 'Tests 1x02 testing[TS].mkv', | |
| 'Test 1x02 [remove this text.-].mkv', | |
| # EN Ok | |
| 'Test S01E02.mkv', | |
| f"Test S01E02{self.test_separator}episode title.mkv", | |
| f"Test S02E02{self.test_separator}episode title.mkv", | |
| # EN to format | |
| 'Test S01E02.mkv', | |
| 'Test S01E02.mkv', | |
| f"Test S01E05{self.test_separator}1to1.mkv", | |
| f"Test 2025 S01E02{self.test_separator}Part1.mkv", | |
| f"Test S01E02{self.test_separator}episode title.mkv" | |
| ] | |
| self.rename(of, sf, expected_results) | |
| def test_en_en(self): | |
| of = 'en' | |
| sf = 'en' | |
| expected_results = [ | |
| # ES Ok | |
| 'Test S01E02.mkv', | |
| 'Test S01E02.mkv', | |
| f"Test S01E02{self.test_separator}episode title.mkv", | |
| 'Test 33 S01E02.mkv', | |
| f"Test 33 S01E02{self.test_separator}episode title", | |
| 'Test (testing) S01E02.mkv', | |
| f"Test (testing) S01E02{self.test_separator}episode title.mkv", | |
| 'NotAshow.mkv', | |
| f"Crime S01E02{self.test_separator}testing.mkv", | |
| f"Casting S01E02{self.test_separator}testing.mkv", | |
| # ES to format | |
| 'Test S01E02.mkv', | |
| f"Test S01E02{self.test_separator}episode title.mkv", | |
| f"Test S01E02{self.test_separator}episode title.mkv", | |
| f"Test S01E02{self.test_separator}episode title.mkv", | |
| 'Test Testing S01E02.mkv', | |
| 'Test Testing S01E02.mkv', | |
| 'T3st Testing S01E02.mkv', | |
| 'T3st Testing S01E02.mkv', | |
| 'T3st! Testing S01E02.mkv', | |
| 'T3st! Testing S01E02.mkv', | |
| f"Tests S01E02{self.test_separator}testing.mkv", | |
| 'Test S01E02.mkv', | |
| # EN Ok | |
| 'Test s01e02.mkv', | |
| 'Test s01e02 - episode title.mkv', | |
| 'Test s02e02 episode title.mkv', | |
| # EN to format | |
| 'Test.s01e02.1080p.WEB.h264-EDITH[EZTVx.to].mkv', | |
| 'Test.s01e02.720p.WEB.h264-EDITH[EZTVx.to].mkv', | |
| 'Test.s01e05.1to1.mkv', | |
| 'Test.2025.s01e02.Part1.1080p.AMZN.WEB-DL.DDP5.1.H-264-Ntb.mkv', | |
| 'Test s01e02 episode title 1080p HMax WEB-DL DDP2 0 H 264-STC[EZTVx.to].mkv' | |
| ] | |
| self.rename(of, sf, expected_results) | |
| def test_es_none(self): | |
| of = 'es' | |
| sf = None | |
| expected_results = [ | |
| # ES Ok | |
| 'Test 01x02.mkv', | |
| 'Test 01x02.mkv', | |
| f"Test 01x02{self.test_separator}episode title.mkv", | |
| 'Test 33 01x02.mkv', | |
| f"Test 33 01x02{self.test_separator}episode title", | |
| 'Test (testing) 01x02.mkv', | |
| f"Test (testing) 01x02{self.test_separator}episode title.mkv", | |
| 'NotAshow.mkv', | |
| f"Crime 01x02{self.test_separator}testing.mkv", | |
| f"Casting 01x02{self.test_separator}testing.mkv", | |
| # ES to format | |
| 'Test 01x02.mkv', | |
| f"Test 01x02{self.test_separator}episode title.mkv", | |
| f"Test 01x02{self.test_separator}episode title.mkv", | |
| f"Test 01x02{self.test_separator}episode title.mkv", | |
| 'Test Testing 01x02.mkv', | |
| 'Test Testing 01x02.mkv', | |
| 'T3st Testing 01x02.mkv', | |
| 'T3st Testing 01x02.mkv', | |
| 'T3st! Testing 01x02.mkv', | |
| 'T3st! Testing 01x02.mkv', | |
| f"Tests 01x02{self.test_separator}testing.mkv", | |
| 'Test 01x02.mkv', | |
| # EN Ok | |
| 'Test 01x02.mkv', | |
| f"Test 01x02{self.test_separator}episode title.mkv", | |
| f"Test 02x02{self.test_separator}episode title.mkv", | |
| # EN to format | |
| 'Test 01x02.mkv', | |
| 'Test 01x02.mkv', | |
| f"Test 01x05{self.test_separator}1to1.mkv", | |
| f"Test 2025 01x02{self.test_separator}Part1.mkv", | |
| f"Test 01x02{self.test_separator}episode title.mkv" | |
| ] | |
| self.rename(of, sf, expected_results) | |
| def test_es_en(self): | |
| of = 'es' | |
| sf = 'en' | |
| expected_results = [ | |
| # ES Ok | |
| 'Test 01x02.mkv', | |
| 'Test 01x02.mkv', | |
| f"Test 01x02{self.test_separator}episode title.mkv", | |
| 'Test 33 01x02.mkv', | |
| f"Test 33 01x02{self.test_separator}episode title", | |
| 'Test (testing) 01x02.mkv', | |
| f"Test (testing) 01x02{self.test_separator}episode title.mkv", | |
| 'NotAshow.mkv', | |
| f"Crime 01x02{self.test_separator}testing.mkv", | |
| f"Casting 01x02{self.test_separator}testing.mkv", | |
| # ES to format | |
| 'Test 01x02.mkv', | |
| f"Test 01x02{self.test_separator}episode title.mkv", | |
| f"Test 01x02{self.test_separator}episode title.mkv", | |
| f"Test 01x02{self.test_separator}episode title.mkv", | |
| 'Test Testing 01x02.mkv', | |
| 'Test Testing 01x02.mkv', | |
| 'T3st Testing 01x02.mkv', | |
| 'T3st Testing 01x02.mkv', | |
| 'T3st! Testing 01x02.mkv', | |
| 'T3st! Testing 01x02.mkv', | |
| f"Tests 01x02{self.test_separator}testing.mkv", | |
| 'Test 01x02.mkv', | |
| # EN Ok | |
| 'Test s01e02.mkv', | |
| 'Test s01e02 - episode title.mkv', | |
| 'Test s02e02 episode title.mkv', | |
| # EN to format | |
| 'Test.s01e02.1080p.WEB.h264-EDITH[EZTVx.to].mkv', | |
| 'Test.s01e02.720p.WEB.h264-EDITH[EZTVx.to].mkv', | |
| 'Test.s01e05.1to1.mkv', | |
| 'Test.2025.s01e02.Part1.1080p.AMZN.WEB-DL.DDP5.1.H-264-Ntb.mkv', | |
| 'Test s01e02 episode title 1080p HMax WEB-DL DDP2 0 H 264-STC[EZTVx.to].mkv' | |
| ] | |
| self.rename(of, sf, expected_results) | |
| def test_es_es(self): | |
| of = 'es' | |
| sf = 'es' | |
| expected_results = [ | |
| # ES Ok | |
| 'Test 1x02.mkv', | |
| 'Test 01x02.mkv', | |
| 'Test 1x02 - episode title.mkv', | |
| 'Test 33 1x02.mkv', | |
| 'Test 33 1x02 - episode title', | |
| 'Test (testing) 1x02.mkv', | |
| 'Test (testing) 1x02 - episode title.mkv', | |
| 'NotAshow.mkv', | |
| 'Crime 1x02 testing.mkv', | |
| 'Casting 1x02 testing.mkv', | |
| # ES to format | |
| 'Test [HDTV 720p][Cap.102].mkv', | |
| 'Test 1x02 episode title [NF 1080p WEBDL AVC Dual DDP 5.1 + Subs].mkv', | |
| 'Test 1x02 episode title [NF 1080p WEBDL AVC Dual DDP 5.1 + Subs].mkv', | |
| 'Test.[Cap102].episode.title.mkv', | |
| 'Test.testing.1x02.mkv', | |
| 'Test.testing.01x02.mkv', | |
| 'T3st.testing.1x02.mkv', | |
| 'T3st.testing.01x02.mkv', | |
| 'T3st!.testing.1x02.mkv', | |
| 'T3st!.testing.01x02.mkv', | |
| 'Tests 1x02 testing[TS].mkv', | |
| 'Test 1x02 [remove this text.-].mkv', | |
| # EN Ok | |
| 'Test 01x02.mkv', | |
| f"Test 01x02{self.test_separator}episode title.mkv", | |
| f"Test 02x02{self.test_separator}episode title.mkv", | |
| # EN to format | |
| 'Test 01x02.mkv', | |
| 'Test 01x02.mkv', | |
| f"Test 01x05{self.test_separator}1to1.mkv", | |
| f"Test 2025 01x02{self.test_separator}Part1.mkv", | |
| f"Test 01x02{self.test_separator}episode title.mkv" | |
| ] | |
| self.rename(of, sf, expected_results) | |
| if __name__ == '__main__': | |
| unittest.main() | |
| # Run one test | |
| # suite = unittest.TestSuite() | |
| # suite.addTest('test_name')) | |
| # runner = unittest.TextTestRunner() | |
| # runner.run(suite) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment