Add comprehensive tests for formatter classes, services, and utilities

- Introduced tests for various formatter classes including TextFormatter, DurationFormatter, SizeFormatter, DateFormatter, and more to ensure correct formatting behavior.
- Added tests for service classes such as FileTreeService, MetadataService, and RenameService, covering directory validation, metadata extraction, and file renaming functionalities.
- Implemented utility tests for LanguageCodeExtractor, PatternExtractor, and FrameClassMatcher to validate their extraction and matching capabilities.
- Updated test cases to use datasets for better maintainability and clarity.
- Enhanced error handling tests to ensure robustness against missing or invalid data.
This commit is contained in:
sha
2025-12-31 14:04:33 +00:00
parent c5fbd367fc
commit 262c0a7b7d
45 changed files with 3346 additions and 1057 deletions
+45
View File
@@ -0,0 +1,45 @@
"""Constants package for Renamer.
This package contains constants split into logical modules:
- media_constants.py: Media type definitions (MEDIA_TYPES)
- source_constants.py: Video source types (SOURCE_DICT)
- frame_constants.py: Resolution/frame classes (FRAME_CLASSES)
- moviedb_constants.py: Movie database identifiers (MOVIE_DB_DICT)
- edition_constants.py: Special edition types (SPECIAL_EDITIONS)
- lang_constants.py: Language-related constants (SKIP_WORDS)
- year_constants.py: Year validation (CURRENT_YEAR, MIN_VALID_YEAR, etc.)
- cyrillic_constants.py: Cyrillic character normalization (CYRILLIC_TO_ENGLISH)
"""
# Import from all constant modules
from .media_constants import MEDIA_TYPES
from .source_constants import SOURCE_DICT
from .frame_constants import FRAME_CLASSES, NON_STANDARD_QUALITY_INDICATORS
from .moviedb_constants import MOVIE_DB_DICT
from .edition_constants import SPECIAL_EDITIONS
from .lang_constants import SKIP_WORDS
from .year_constants import CURRENT_YEAR, MIN_VALID_YEAR, YEAR_FUTURE_BUFFER, is_valid_year
from .cyrillic_constants import CYRILLIC_TO_ENGLISH
__all__ = [
# Media types
'MEDIA_TYPES',
# Source types
'SOURCE_DICT',
# Frame classes
'FRAME_CLASSES',
'NON_STANDARD_QUALITY_INDICATORS',
# Movie databases
'MOVIE_DB_DICT',
# Special editions
'SPECIAL_EDITIONS',
# Language constants
'SKIP_WORDS',
# Year validation
'CURRENT_YEAR',
'MIN_VALID_YEAR',
'YEAR_FUTURE_BUFFER',
'is_valid_year',
# Cyrillic normalization
'CYRILLIC_TO_ENGLISH',
]
+21
View File
@@ -0,0 +1,21 @@
"""Cyrillic character normalization constants.
This module contains mappings for normalizing Cyrillic characters to their
English equivalents for parsing filenames.
"""
# Cyrillic to English character mappings
# Used for normalizing Cyrillic characters that look like English letters
CYRILLIC_TO_ENGLISH = {
'р': 'p', # Cyrillic 'er' looks like Latin 'p'
'і': 'i', # Cyrillic 'i' looks like Latin 'i'
'о': 'o', # Cyrillic 'o' looks like Latin 'o'
'с': 'c', # Cyrillic 'es' looks like Latin 'c'
'е': 'e', # Cyrillic 'ie' looks like Latin 'e'
'а': 'a', # Cyrillic 'a' looks like Latin 'a'
'т': 't', # Cyrillic 'te' looks like Latin 't'
'у': 'y', # Cyrillic 'u' looks like Latin 'y'
'к': 'k', # Cyrillic 'ka' looks like Latin 'k'
'х': 'x', # Cyrillic 'ha' looks like Latin 'x
# Add more mappings as needed
}
+59
View File
@@ -0,0 +1,59 @@
"""Special edition constants.
This module defines special edition types (Director's Cut, Extended Edition, etc.)
and their aliases for detection in filenames.
"""
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", "AMZN"],
"Netflix Edition": ["Netflix Edition"],
"HBO Edition": ["HBO Edition"],
}
+74
View File
@@ -0,0 +1,74 @@
"""Frame class and resolution constants.
This module defines video resolution frame classes (480p, 720p, 1080p, 4K, 8K, etc.)
and their nominal heights and typical widths.
Also includes non-standard quality indicators that appear in filenames but don't
represent specific resolutions.
"""
# Non-standard quality indicators that don't have specific resolution values
# These are used in filenames to indicate quality but aren't proper frame classes
# When found, we return None instead of trying to classify them
# Note: We have specific frame classes like "2160p" (4K) and "4320p" (8K),
# but when files use just "4K" or "8K" without the "p" suffix, we can't determine
# the exact resolution, so we treat them as non-standard indicators
NON_STANDARD_QUALITY_INDICATORS = ['SD', 'LQ', 'HD', 'QHD', 'FHD', 'FullHD', '4K', '8K']
FRAME_CLASSES = {
"480p": {
"nominal_height": 480,
"typical_widths": [640, 704, 720],
"description": "Standard Definition (SD) - DVD quality",
},
"480i": {
"nominal_height": 480,
"typical_widths": [640, 704, 720],
"description": "Standard Definition (SD) interlaced - NTSC quality",
},
"360p": {
"nominal_height": 360,
"typical_widths": [480, 640],
"description": "Low Definition (LD) - 360p",
},
"576p": {
"nominal_height": 576,
"typical_widths": [720, 768],
"description": "PAL Standard Definition (SD) - European DVD quality",
},
"576i": {
"nominal_height": 576,
"typical_widths": [720, 768],
"description": "PAL Standard Definition (SD) interlaced - European quality",
},
"720p": {
"nominal_height": 720,
"typical_widths": [1280],
"description": "High Definition (HD) - 720p HD",
},
"1080p": {
"nominal_height": 1080,
"typical_widths": [1920],
"description": "Full High Definition (FHD) - 1080p HD",
},
"1080i": {
"nominal_height": 1080,
"typical_widths": [1920],
"description": "Full High Definition (FHD) interlaced - 1080i HD",
},
"1440p": {
"nominal_height": 1440,
"typical_widths": [2560],
"description": "Quad High Definition (QHD) - 1440p 2K",
},
"2160p": {
"nominal_height": 2160,
"typical_widths": [3840],
"description": "Ultra High Definition (UHD) - 2160p 4K",
},
"4320p": {
"nominal_height": 4320,
"typical_widths": [7680],
"description": "Ultra High Definition (UHD) - 4320p 8K",
},
}
+31
View File
@@ -0,0 +1,31 @@
"""Language-related constants for filename parsing.
This module contains sets of words and patterns used to identify and skip
non-language codes when extracting language information from filenames.
"""
# Words to skip when looking for language codes in filenames
# These are common words, file extensions, or technical terms that might
# look like language codes but aren't
SKIP_WORDS = {
# Common English words that might look like language codes (2-3 letters)
'the', 'and', 'for', 'are', 'but', 'not', 'you', 'all', 'can', 'had',
'her', 'was', 'one', 'our', 'out', 'day', 'get', 'has', 'him', 'his',
'how', 'its', 'may', 'new', 'now', 'old', 'see', 'two', 'way', 'who',
'boy', 'did', 'let', 'put', 'say', 'she', 'too', 'use',
# File extensions (video)
'avi', 'mkv', 'mp4', 'mpg', 'mov', 'wmv', 'flv', 'webm', 'm4v', 'm2ts',
'ts', 'vob', 'iso', 'img',
# Quality/resolution indicators
'sd', 'hd', 'lq', 'qhd', 'uhd', 'p', 'i', 'hdr', 'sdr', '4k', '8k',
'2160p', '1080p', '720p', '480p', '360p', '240p', '144p',
# Source/codec indicators
'web', 'dl', 'rip', 'bluray', 'dvd', 'hdtv', 'bdrip', 'dvdrip', 'xvid',
'divx', 'h264', 'h265', 'x264', 'x265', 'hevc', 'avc',
# Audio codecs
'ma', 'atmos', 'dts', 'aac', 'ac3', 'mp3', 'flac', 'wav', 'wma', 'ogg', 'opus'
}
+46
View File
@@ -0,0 +1,46 @@
"""Media type constants for supported video formats.
This module defines all supported video container formats and their metadata.
"""
MEDIA_TYPES = {
"mkv": {
"description": "Matroska multimedia container",
"meta_type": "Matroska",
"mime": "video/x-matroska",
},
"mk3d": {
"description": "Matroska 3D multimedia container",
"meta_type": "Matroska",
"mime": "video/x-matroska",
},
"avi": {
"description": "Audio Video Interleave",
"meta_type": "AVI",
"mime": "video/x-msvideo",
},
"mov": {
"description": "QuickTime movie",
"meta_type": "QuickTime",
"mime": "video/quicktime",
},
"mp4": {
"description": "MPEG-4 video container",
"meta_type": "MP4",
"mime": "video/mp4",
},
"wmv": {
"description": "Windows Media Video",
"meta_type": "ASF",
"mime": "video/x-ms-wmv",
},
"flv": {"description": "Flash Video", "meta_type": "FLV", "mime": "video/x-flv"},
"webm": {
"description": "WebM multimedia",
"meta_type": "WebM",
"mime": "video/webm",
},
"m4v": {"description": "MPEG-4 video", "meta_type": "MP4", "mime": "video/mp4"},
"3gp": {"description": "3GPP multimedia", "meta_type": "MP4", "mime": "video/3gpp"},
"ogv": {"description": "Ogg Video", "meta_type": "Ogg", "mime": "video/ogg"},
}
+32
View File
@@ -0,0 +1,32 @@
"""Movie database identifier constants.
This module defines movie and TV database services (TMDB, IMDB, Trakt, TVDB)
and their identifier patterns.
"""
MOVIE_DB_DICT = {
"tmdb": {
"name": "The Movie Database (TMDb)",
"description": "Community built movie and TV database",
"url": "https://www.themoviedb.org/",
"patterns": ["tmdbid", "tmdb", "tmdbid-", "tmdb-"],
},
"imdb": {
"name": "Internet Movie Database (IMDb)",
"description": "Comprehensive movie, TV, and celebrity database",
"url": "https://www.imdb.com/",
"patterns": ["imdbid", "imdb", "imdbid-", "imdb-"],
},
"trakt": {
"name": "Trakt.tv",
"description": "Service that integrates with media centers for scrobbling",
"url": "https://trakt.tv/",
"patterns": ["traktid", "trakt", "traktid-", "trakt-"],
},
"tvdb": {
"name": "The TV Database (TVDB)",
"description": "Community driven TV database",
"url": "https://thetvdb.com/",
"patterns": ["tvdbid", "tvdb", "tvdbid-", "tvdb-"],
},
}
+23
View File
@@ -0,0 +1,23 @@
"""Video source type constants.
This module defines video source types (WEB-DL, BDRip, etc.) and their aliases.
"""
SOURCE_DICT = {
"WEB-DL": ["WEB-DL", "WEBRip", "WEB-Rip", "WEB", "WEB-DLRip"],
"BDRip": ["BDRip", "BD-Rip", "BDRIP"],
"BDRemux": ["BDRemux", "BD-Remux", "BDREMUX"],
"DVDRip": ["DVDRip", "DVD-Rip", "DVDRIP"],
"HDTVRip": ["HDTVRip", "HDTV"],
"BluRay": ["BluRay", "BLURAY", "Blu-ray"],
"SATRip": ["SATRip", "SAT-Rip", "SATRIP"],
"VHSRecord": [
"VHSRecord",
"VHS Record",
"VHS-Rip",
"VHSRip",
"VHS",
"VHS Tape",
"VHS-Tape",
],
}
+20
View File
@@ -0,0 +1,20 @@
"""Year validation constants for filename parsing.
This module contains constants used for validating years extracted from filenames.
"""
import datetime
# Current year for validation
CURRENT_YEAR = datetime.datetime.now().year
# Minimum valid year for movies/media (start of cinema era)
MIN_VALID_YEAR = 1900
# Allow years slightly into the future (for upcoming releases)
YEAR_FUTURE_BUFFER = 10
# Valid year range: MIN_VALID_YEAR to (CURRENT_YEAR + YEAR_FUTURE_BUFFER)
def is_valid_year(year: int) -> bool:
"""Check if a year is within the valid range for media files."""
return MIN_VALID_YEAR <= year <= CURRENT_YEAR + YEAR_FUTURE_BUFFER