From 97bacf602c20a2d6c54542c86701b858f49c484a Mon Sep 17 00:00:00 2001 From: sHa Date: Sun, 28 Dec 2025 07:33:37 +0000 Subject: [PATCH] feat: Bump version to 0.3.3, update special editions structure, and enhance filename extraction logic --- dist/renamer-0.3.3-py3-none-any.whl | Bin 0 -> 34249 bytes pyproject.toml | 2 +- renamer/constants.py | 100 ++++++++++++----------- renamer/extractors/filename_extractor.py | 33 ++++---- uv.lock | 2 +- 5 files changed, 72 insertions(+), 65 deletions(-) create mode 100644 dist/renamer-0.3.3-py3-none-any.whl diff --git a/dist/renamer-0.3.3-py3-none-any.whl b/dist/renamer-0.3.3-py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..d29ec26aba65b8ff86137867316745fc319cb4ca GIT binary patch literal 34249 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Ļ{+3&*`D7# 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 literal 0 HcmV?d00001 diff --git a/pyproject.toml b/pyproject.toml index ee8ffe1..96a7396 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "renamer" -version = "0.3.2" +version = "0.3.3" description = "Terminal-based media file renamer and metadata viewer" readme = "README.md" requires-python = ">=3.11" diff --git a/renamer/constants.py b/renamer/constants.py index 5904934..fe06a6c 100644 --- a/renamer/constants.py +++ b/renamer/constants.py @@ -133,50 +133,56 @@ MOVIE_DB_DICT = { }, } -SPECIAL_EDITIONS = [ - "Theatrical Cut", - "Director's Cut", - "Director Cut", - "Extended Edition", - "Ultimate Extended Edition", - "Special Edition", - "Collector's Edition", - "Criterion Collection", - "Fundamental Collection", - "Anniversary Edition", - "Redux", - "Final Cut", - "Alternate Cut", - "International Cut", - "Restored Version", - "Remastered", - "Unrated", - "Uncensored", - "Definitive Edition", - "Platinum Edition", - "Gold Edition", - "Diamond Edition", - "Steelbook Edition", - "Limited Edition", - "Deluxe Edition", - "Premium Edition", - "Complete Edition", - "Restored Edition", - "4K Restoration", - "HD Remaster", - "Director's Definitive Cut", - "Extended Director's Cut", - "Ultimate Director's Cut", - "Original Cut", - "Cinematic Cut", - "Roadshow Cut", - "Premiere Cut", - "Festival Cut", - "Workprint", - "Rough Cut", - "Special Assembly Cut", - "Amazon Edition", - "Amazon", - "Netflix Edition", - "HBO Edition", -] +SPECIAL_EDITIONS = { + "Theatrical Cut": ["Theatrical Cut"], + "Director's Cut": ["Director's Cut", "Director Cut"], + "Extended Edition": ["Extended Edition", "Ultimate Extended Edition"], + "Special Edition": ["Special Edition"], + "Collector's Edition": ["Collector's Edition"], + "Criterion Collection": ["Criterion Collection"], + "Anniversary Edition": ["Anniversary Edition"], + "Redux": ["Redux"], + "Final Cut": ["Final Cut"], + "Alternate Cut": ["Alternate Cut"], + "International Cut": ["International Cut"], + "Restored Edition": [ + "Restored Edition", + "Restored Version", + "4K Restoration", + "Restoration", + ], + "Remastered": ["Remastered", "Remaster", "HD Remaster"], + "Unrated": ["Unrated"], + "Uncensored": ["Uncensored"], + "Definitive Edition": ["Definitive Edition"], + "Platinum Edition": ["Platinum Edition"], + "Gold Edition": ["Gold Edition"], + "Diamond Edition": ["Diamond Edition"], + "Steelbook Edition": ["Steelbook Edition"], + "Limited Edition": ["Limited Edition"], + "Deluxe Edition": ["Deluxe Edition"], + "Premium Edition": ["Premium Edition"], + "Complete Edition": ["Complete Edition"], + "AI Remaster": ["AI Remaster", "AI Remastered"], + "Upscaled": [ + "AI Upscaled", + "AI Enhanced", + "AI Upscale", + "Upscaled", + "Upscale", + "Upscaling", + ], + "Director's Definitive Cut": ["Director's Definitive Cut"], + "Extended Director's Cut": ["Extended Director's Cut", "Ultimate Director's Cut"], + "Original Cut": ["Original Cut"], + "Cinematic Cut": ["Cinematic Cut"], + "Roadshow Cut": ["Roadshow Cut"], + "Premiere Cut": ["Premiere Cut"], + "Festival Cut": ["Festival Cut"], + "Workprint": ["Workprint"], + "Rough Cut": ["Rough Cut"], + "Special Assembly Cut": ["Special Assembly Cut"], + "Amazon Edition": ["Amazon Edition", "Amazon"], + "Netflix Edition": ["Netflix Edition"], + "HBO Edition": ["HBO Edition"], +} diff --git a/renamer/extractors/filename_extractor.py b/renamer/extractors/filename_extractor.py index f9302f0..e32c497 100644 --- a/renamer/extractors/filename_extractor.py +++ b/renamer/extractors/filename_extractor.py @@ -216,22 +216,23 @@ class FilenameExtractor: # Look for special edition indicators in brackets or as standalone text special_info = [] - for edition in SPECIAL_EDITIONS: - # Check in brackets: [Theatrical Cut], [Director's Cut], etc. - bracket_pattern = r'\[([^\]]+)\]' - brackets = re.findall(bracket_pattern, self.file_name) - for bracket in brackets: - # Check if bracket contains comma-separated items - items = [item.strip() for item in bracket.split(',')] - for item in items: - if edition.lower() == item.lower().strip(): - if edition not in special_info: - special_info.append(edition) - - # Check as standalone text (case-insensitive) - if re.search(r'\b' + re.escape(edition) + r'\b', self.file_name, re.IGNORECASE): - if edition not in special_info: - special_info.append(edition) + for canonical_edition, variants in SPECIAL_EDITIONS.items(): + for edition in variants: + # Check in brackets: [Theatrical Cut], [Director's Cut], etc. + bracket_pattern = r'\[([^\]]+)\]' + brackets = re.findall(bracket_pattern, self.file_name) + for bracket in brackets: + # Check if bracket contains comma-separated items + items = [item.strip() for item in bracket.split(',')] + for item in items: + if edition.lower() == item.lower().strip(): + if canonical_edition not in special_info: + special_info.append(canonical_edition) + + # Check as standalone text (case-insensitive) + if re.search(r'\b' + re.escape(edition) + r'\b', self.file_name, re.IGNORECASE): + if canonical_edition not in special_info: + special_info.append(canonical_edition) return special_info diff --git a/uv.lock b/uv.lock index 21a3abf..67476df 100644 --- a/uv.lock +++ b/uv.lock @@ -164,7 +164,7 @@ wheels = [ [[package]] name = "renamer" -version = "0.3.2" +version = "0.3.3" source = { editable = "." } dependencies = [ { name = "langcodes" },