diff --git a/unshackle/commands/dl.py b/unshackle/commands/dl.py index 72752fc..91300ca 100644 --- a/unshackle/commands/dl.py +++ b/unshackle/commands/dl.py @@ -1159,7 +1159,13 @@ class dl: final_filename = title.get_filename(media_info, show_service=not no_source) if not no_folder and isinstance(title, (Episode, Song)): - final_dir /= title.get_filename(media_info, show_service=not no_source, folder=True) + if isinstance(title, Episode): + # Create nested structure: {title}/Season {season:02}/{filename} + final_dir /= title.get_filename(media_info, show_service=not no_source, folder=True) + final_dir /= title.get_season_folder() + else: + # For Song, use existing logic + final_dir /= title.get_filename(media_info, show_service=not no_source, folder=True) final_dir.mkdir(parents=True, exist_ok=True) final_path = final_dir / f"{final_filename}{muxed_path.suffix}" diff --git a/unshackle/core/titles/episode.py b/unshackle/core/titles/episode.py index f66bcb7..ec69499 100644 --- a/unshackle/core/titles/episode.py +++ b/unshackle/core/titles/episode.py @@ -92,14 +92,14 @@ class Episode(Title): primary_audio_track = next(iter(media_info.audio_tracks), None) unique_audio_languages = len({x.language.split("-")[0] for x in media_info.audio_tracks if x.language}) - # Title [Year] SXXEXX Name (or Title [Year] SXX if folder) + # Title [Year] SXXEXX Name (or just Title for main folder) if folder: name = f"{self.title}" if self.year and config.series_year: - name += f" {self.year}" - name += f" S{self.season:02}" + name += f" ({self.year})" + return name else: - name = "{title}{year} S{season:02}E{number:02} {name}".format( + name = "{title}{year} S{season:02}E{number:02} - {name} -".format( title=self.title.replace("$", "S"), # e.g., Arli$$ year=f" {self.year}" if self.year and config.series_year else "", season=self.season, @@ -128,19 +128,19 @@ class Episode(Title): name += f" {resolution}p" # Service - if show_service: - name += f" {self.service.__name__}" + # if show_service: + # name += f" {self.service.__name__}" - # 'WEB-DL' - name += " WEB-DL" + # # 'WEB-DL' + # name += " WEB-DL" - # DUAL - if unique_audio_languages == 2: - name += " DUAL" + # # DUAL + # if unique_audio_languages == 2: + # name += " DUAL" - # MULTi - if unique_audio_languages > 2: - name += " MULTi" + # # MULTi + # if unique_audio_languages > 2: + # name += " MULTi" # Audio Codec + Channels (+ feature) if primary_audio_track: @@ -189,6 +189,12 @@ class Episode(Title): # Simple naming style without technical details - use spaces instead of dots return sanitize_filename(name, " ") + def get_season_folder(self) -> str: + """ + Get the season folder name in the format 'Season XX'. + """ + return f"Season {self.season:02d}" + class Series(SortedKeyList, ABC): def __init__(self, iterable: Optional[Iterable] = None): diff --git a/unshackle/unshackle.yaml b/unshackle/unshackle.yaml index a4c0e6d..cb719da 100644 --- a/unshackle/unshackle.yaml +++ b/unshackle/unshackle.yaml @@ -18,7 +18,7 @@ scene_naming: true # Whether to include the year in series names for episodes and folders (default: true) # true for style - Show Name (2023) S01E01 Episode Name # false for style - Show Name S01E01 Episode Name -series_year: true +series_year: false # Check for updates from GitHub repository on startup (default: true) update_checks: true