diff --git a/src/ytdl_sub/__init__.py b/src/ytdl_sub/__init__.py
index a1ae89f9..abab4d89 100644
--- a/src/ytdl_sub/__init__.py
+++ b/src/ytdl_sub/__init__.py
@@ -1,2 +1,2 @@
-__pypi_version__ = "2023.10.22.post3"
-__local_version__ = "2023.10.22+bfba4f0"
+__pypi_version__ = "2025.01.09"
+__local_version__ = "2025.01.09+57c5d3c"
diff --git a/src/ytdl_sub/config/plugin/plugin_mapping.py b/src/ytdl_sub/config/plugin/plugin_mapping.py
index 316096b2..58ab2787 100644
--- a/src/ytdl_sub/config/plugin/plugin_mapping.py
+++ b/src/ytdl_sub/config/plugin/plugin_mapping.py
@@ -23,6 +23,7 @@ from ytdl_sub.plugins.match_filters import MatchFiltersPlugin
from ytdl_sub.plugins.music_tags import MusicTagsPlugin
from ytdl_sub.plugins.nfo_tags import NfoTagsPlugin
from ytdl_sub.plugins.output_directory_nfo_tags import OutputDirectoryNfoTagsPlugin
+from ytdl_sub.plugins.season_nfo_tags import SeasonNfoTagsPlugin
from ytdl_sub.plugins.split_by_chapters import SplitByChaptersPlugin
from ytdl_sub.plugins.subtitles import SubtitlesPlugin
from ytdl_sub.plugins.throttle_protection import ThrottleProtectionPlugin
@@ -46,6 +47,7 @@ class PluginMapping:
"video_tags": VideoTagsPlugin,
"nfo_tags": NfoTagsPlugin,
"output_directory_nfo_tags": OutputDirectoryNfoTagsPlugin,
+ "season_nfo_tags": SeasonNfoTagsPlugin,
"subtitles": SubtitlesPlugin,
"chapters": ChaptersPlugin,
"split_by_chapters": SplitByChaptersPlugin,
@@ -83,6 +85,7 @@ class PluginMapping:
MusicTagsPlugin,
VideoTagsPlugin,
NfoTagsPlugin,
+ SeasonNfoTagsPlugin,
EmbedThumbnailPlugin,
]
diff --git a/src/ytdl_sub/plugins/season_nfo_tags.py b/src/ytdl_sub/plugins/season_nfo_tags.py
new file mode 100644
index 00000000..0aedea24
--- /dev/null
+++ b/src/ytdl_sub/plugins/season_nfo_tags.py
@@ -0,0 +1,90 @@
+from ytdl_sub.config.overrides import Overrides
+from ytdl_sub.entries.entry import Entry
+from ytdl_sub.plugins.nfo_tags import NfoTagsValidator
+from ytdl_sub.plugins.nfo_tags import SharedNfoTagsOptions
+from ytdl_sub.plugins.nfo_tags import SharedNfoTagsPlugin
+from ytdl_sub.validators.string_formatter_validators import StringFormatterValidator
+from ytdl_sub.ytdl_additions.enhanced_download_archive import EnhancedDownloadArchive
+
+
+class SeasonNfoTagsOptions(SharedNfoTagsOptions):
+ """
+ Adds a single NFO file in the season directory. An NFO file is simply an XML file with a
+ ``.nfo`` extension. It uses the last entry's source variables which can change per download
+ invocation. Be cautious of which variables you use.
+
+ Usage:
+
+ .. code-block:: yaml
+
+ presets:
+ my_example_preset:
+ season_nfo_tags:
+ # required
+ nfo_name: "season.nfo"
+ nfo_root: "season"
+ tags:
+ title: "My custom season name!"
+ # optional
+ kodi_safe: False
+ """
+
+ # Hack to make it so collection named seasons do not error
+ # when adding output_directory_nfo info for plex
+ _required_keys = set()
+ _optional_keys = {"enable", "kodi_safe", "nfo_name", "nfo_root", "tags"}
+
+ @property
+ def nfo_root(self) -> StringFormatterValidator:
+ """
+ :expected type: EntryFormatter
+ :description:
+ The root tag of the NFO's XML. In the usage above, it would look like
+
+ .. code-block:: xml
+
+
+
+
+ """
+ return self._nfo_root
+
+ @property
+ def tags(self) -> NfoTagsValidator:
+ """
+ :expected type: NfoTags
+ :description:
+ Tags within the nfo_root tag. In the usage above, it would look like
+
+ .. code-block:: xml
+
+
+
+ My custom season name!
+
+ """
+ return self._tags
+
+
+class SeasonNfoTagsPlugin(SharedNfoTagsPlugin):
+ plugin_options_type = SeasonNfoTagsOptions
+
+ def __init__(
+ self,
+ options: SeasonNfoTagsOptions,
+ overrides: Overrides,
+ enhanced_download_archive: EnhancedDownloadArchive,
+ ):
+ super().__init__(options, overrides, enhanced_download_archive)
+ self._created_output_nfo = False
+
+ def post_process_entry(self, entry: Entry) -> None:
+ """
+ Creates an season NFO file using values defined by the season collection name
+ """
+ if (
+ self.plugin_options.nfo_name is not None
+ and self.plugin_options.nfo_root is not None
+ ):
+ self._create_nfo(entry=entry, save_to_entry=False)
+ self._created_output_nfo = True
diff --git a/src/ytdl_sub/prebuilt_presets/tv_show/season.yaml b/src/ytdl_sub/prebuilt_presets/tv_show/season.yaml
new file mode 100644
index 00000000..25353edf
--- /dev/null
+++ b/src/ytdl_sub/prebuilt_presets/tv_show/season.yaml
@@ -0,0 +1,13 @@
+presets:
+
+####################################################################################################
+
+ _season_nfo_tags:
+ season_nfo_tags:
+ # required
+ nfo_name: "{season_directory_name_sanitized}/season.nfo"
+ nfo_root: "season"
+ tags:
+ title: "{collection_season_name}"
+ # optional
+ kodi_safe: False
\ No newline at end of file
diff --git a/src/ytdl_sub/prebuilt_presets/tv_show/tv_show_collection.yaml b/src/ytdl_sub/prebuilt_presets/tv_show/tv_show_collection.yaml
index 888068d1..a36a89e2 100644
--- a/src/ytdl_sub/prebuilt_presets/tv_show/tv_show_collection.yaml
+++ b/src/ytdl_sub/prebuilt_presets/tv_show/tv_show_collection.yaml
@@ -12,6 +12,8 @@ presets:
preset:
- "jellyfin_tv_show_collection"
- "season_by_collection__episode_by_year_month_day"
+ # Jellyfin/Emby currently do not support reading the namedseason tag from tvshow.nfo and insted rely on a per-folder season.nfo
+ - "_season_nfo_tags"
"Plex TV Show Collection":
preset: