diff --git a/unshackle/core/config.py b/unshackle/core/config.py index 153d7ce..957b3f2 100644 --- a/unshackle/core/config.py +++ b/unshackle/core/config.py @@ -97,6 +97,7 @@ class Config: self.dash_naming: bool = kwargs.get("dash_naming", False) self.series_year: bool = kwargs.get("series_year", True) self.unicode_filenames: bool = kwargs.get("unicode_filenames", False) + self.insert_episodename_into_filenames: bool = kwargs.get("insert_episodename_into_filenames", True) self.title_cache_time: int = kwargs.get("title_cache_time", 1800) # 30 minutes default self.title_cache_max_retention: int = kwargs.get("title_cache_max_retention", 86400) # 24 hours default diff --git a/unshackle/core/titles/episode.py b/unshackle/core/titles/episode.py index 5771def..869bfb8 100644 --- a/unshackle/core/titles/episode.py +++ b/unshackle/core/titles/episode.py @@ -105,22 +105,21 @@ class Episode(Title): def _get_resolution_token(track: Any) -> str: if not track or not getattr(track, "height", None): return "" - resolution = track.height + width = getattr(track, "width", track.height) + resolution = min(width, track.height) try: dar = getattr(track, "other_display_aspect_ratio", None) or [] if dar and dar[0]: aspect_ratio = [int(float(plane)) for plane in str(dar[0]).split(":")] if len(aspect_ratio) == 1: aspect_ratio.append(1) - if aspect_ratio[0] / aspect_ratio[1] not in (16 / 9, 4 / 3): - resolution = int(track.width * (9 / 16)) + ratio = aspect_ratio[0] / aspect_ratio[1] + if ratio not in (16 / 9, 4 / 3, 9 / 16, 3 / 4): + resolution = int(max(width, track.height) * (9 / 16)) except Exception: pass - scan_suffix = "p" - scan_type = getattr(track, "scan_type", None) - if scan_type and str(scan_type).lower() == "interlaced": - scan_suffix = "i" + scan_suffix = "i" if str(getattr(track, "scan_type", "")).lower() == "interlaced" else "p" return f"{resolution}{scan_suffix}" # Title [Year] SXXEXX Name (or Title [Year] SXX if folder) @@ -142,7 +141,7 @@ class Episode(Title): name += f" - S{self.season:02}E{self.number:02}" # Add episode name with dash separator - if self.name: + if self.name and config.insert_episodename_into_filenames: name += f" - {self.name}" name = name.strip() @@ -153,7 +152,7 @@ class Episode(Title): year=f" {self.year}" if self.year and config.series_year else "", season=self.season, number=self.number, - name=self.name or "", + name=self.name if self.name and config.insert_episodename_into_filenames else "", ).strip() if getattr(config, "repack", False): @@ -287,4 +286,4 @@ class Series(SortedKeyList, ABC): return tree -__all__ = ("Episode", "Series") +__all__ = ("Episode", "Series") \ No newline at end of file diff --git a/unshackle/core/titles/movie.py b/unshackle/core/titles/movie.py index d14df3e..3eb0b50 100644 --- a/unshackle/core/titles/movie.py +++ b/unshackle/core/titles/movie.py @@ -70,22 +70,21 @@ class Movie(Title): def _get_resolution_token(track: Any) -> str: if not track or not getattr(track, "height", None): return "" - resolution = track.height + width = getattr(track, "width", track.height) + resolution = min(width, track.height) try: dar = getattr(track, "other_display_aspect_ratio", None) or [] if dar and dar[0]: aspect_ratio = [int(float(plane)) for plane in str(dar[0]).split(":")] if len(aspect_ratio) == 1: aspect_ratio.append(1) - if aspect_ratio[0] / aspect_ratio[1] not in (16 / 9, 4 / 3): - resolution = int(track.width * (9 / 16)) + ratio = aspect_ratio[0] / aspect_ratio[1] + if ratio not in (16 / 9, 4 / 3, 9 / 16, 3 / 4): + resolution = int(max(width, track.height) * (9 / 16)) except Exception: pass - scan_suffix = "p" - scan_type = getattr(track, "scan_type", None) - if scan_type and str(scan_type).lower() == "interlaced": - scan_suffix = "i" + scan_suffix = "i" if str(getattr(track, "scan_type", "")).lower() == "interlaced" else "p" return f"{resolution}{scan_suffix}" # Name (Year) diff --git a/unshackle/unshackle-example.yaml b/unshackle/unshackle-example.yaml index 6363076..2a248c2 100644 --- a/unshackle/unshackle-example.yaml +++ b/unshackle/unshackle-example.yaml @@ -39,6 +39,10 @@ title_cache_enabled: true # Enable/disable title caching globally (default: true title_cache_time: 1800 # Cache duration in seconds (default: 1800 = 30 minutes) title_cache_max_retention: 86400 # Maximum cache retention for fallback when API fails (default: 86400 = 24 hours) +# Filename Configuration +unicode_filenames: false # optionally replace non-ASCII characters with ASCII equivalents +insert_episodename_into_filenames: true # optionally determines whether the specific name of an episode is automatically included within the filename for series content. + # Debug logging configuration # Comprehensive JSON-based debug logging for troubleshooting and service development debug: