diff --git a/VERSION b/VERSION index 02b5a085..063614d5 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.18.0-develop39 +1.18.0-develop40 diff --git a/defaults/overlays/resolution.yml b/defaults/overlays/resolution.yml index 4e884e8f..e285bb9f 100644 --- a/defaults/overlays/resolution.yml +++ b/defaults/overlays/resolution.yml @@ -127,7 +127,6 @@ templates: - <> - <> ignore_blank_results: true - only_filter_missing: false plex_all: true filters: - edition: <> diff --git a/docs/conf.py b/docs/conf.py index ba07deb4..5c3da884 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -307,6 +307,8 @@ html_theme_options = { ("Templates", "metadata/templates"), ("Filters", "metadata/filters"), ("_menu", "Dynamic Collections", "metadata/dynamic", [ + ("Dynamic Collections", "metadata/dynamic"), + ("_divider", ), ("_menu", "TMDb Dynamic Collections", "metadata/dynamic", [ ("TMDb Collection", "metadata/dynamic", "#tmdb-collection"), ("TMDb Popular People", "metadata/dynamic", "#tmdb-popular-people"), @@ -324,6 +326,7 @@ html_theme_options = { ("Writer", "metadata/dynamic", "#writer"), ("Producer", "metadata/dynamic", "#producer"), ("Genre", "metadata/dynamic", "#genre"), + ("Album Genre", "metadata/dynamic", "#album-genre"), ("Content Rating", "metadata/dynamic", "#content-rating"), ("Year", "metadata/dynamic", "#year"), ("Decade", "metadata/dynamic", "#decade"), @@ -335,13 +338,15 @@ html_theme_options = { ("Edition", "metadata/dynamic", "#edition"), ("Network", "metadata/dynamic", "#network"), ("Mood", "metadata/dynamic", "#mood"), + ("Album Mood", "metadata/dynamic", "#album-mood"), + ("Track Mood", "metadata/dynamic", "#track-mood"), ("Style", "metadata/dynamic", "#style"), ("Album Style", "metadata/dynamic", "#album-style"), ]), ("Number", "metadata/dynamic", "#number"), ("Custom", "metadata/dynamic", "#custom"), ]), - ("_menu", "Editing Media Metadata", "#", [ + ("_menu", "Editing Media Metadata", "", [ ("Editing Movie Metadata", "metadata/metadata/movie"), ("Editing TV Metadata", "metadata/metadata/show"), ("Editing Music Metadata", "metadata/metadata/music"), diff --git a/docs/metadata/builders/plex.md b/docs/metadata/builders/plex.md index 86e32335..5342179b 100644 --- a/docs/metadata/builders/plex.md +++ b/docs/metadata/builders/plex.md @@ -247,7 +247,7 @@ Tag search can take multiple values as a **list or a comma-separated string**. | `album_source` | Uses the Album's Source attribute to match | ❌ | ❌ | ✅ | | `album_label` | Uses the Album's Label attribute to match | ❌ | ❌ | ✅ | | `track_mood` | Uses the Track's Mood attribute to match | ❌ | ❌ | ✅ | -| `track_source` | Uses the Track's Style attribute to match | ❌ | ❌ | ✅ | +| `track_source` | Uses the Track's Source attribute to match | ❌ | ❌ | ✅ | | `track_label` | Uses the Track's Label attribute to match | ❌ | ❌ | ✅ | 1 You can use `current_year` to have PMM use the current years value. This can be combined with a `-#` at the end to subtract that number of years. i.e. `current-2` diff --git a/docs/metadata/builders/smart.md b/docs/metadata/builders/smart.md index 279c763b..d2c0e4e9 100644 --- a/docs/metadata/builders/smart.md +++ b/docs/metadata/builders/smart.md @@ -181,7 +181,7 @@ Tag filter can take multiple values as a **list or a comma-separated string**. | `album_source` | Uses the Album's Source attribute to match | ❌ | ❌ | ✅ | | `album_label` | Uses the Album's Label attribute to match | ❌ | ❌ | ✅ | | `track_mood` | Uses the Track's Mood attribute to match | ❌ | ❌ | ✅ | -| `track_source` | Uses the Track's Style attribute to match | ❌ | ❌ | ✅ | +| `track_source` | Uses the Track's Source attribute to match | ❌ | ❌ | ✅ | | `track_label` | Uses the Track's Label attribute to match | ❌ | ❌ | ✅ | 1 You can use `current_year` to have PMM use the current years value. This can be combined with a `-#` at the end to subtract that number of years. i.e. `current-2` diff --git a/docs/metadata/dynamic.md b/docs/metadata/dynamic.md index c0572b62..c4e8ef07 100644 --- a/docs/metadata/dynamic.md +++ b/docs/metadata/dynamic.md @@ -120,6 +120,7 @@ Depending on the `type` of dynamic collection, `data` is used to specify the opt | [`writer`](#writer) | Create a collection for each writer found in the library | ✅ | ✅ | ❌ | ❌ | ❌ | | [`producer`](#producer) | Create a collection for each producer found in the library | ✅ | ✅ | ❌ | ❌ | ❌ | | [`genre`](#genre) | Create a collection for each genre found in the library | ❌ | ✅ | ✅ | ✅ | ✅ | +| [`album_genre`](#album-genre) | Create a collection for each album genre found in the library | ❌ | ❌ | ❌ | ✅ | ❌ | | [`content_rating`](#content-rating) | Create a collection for each content rating found in the library | ❌ | ✅ | ✅ | ❌ | ✅ | | [`year`](#year) | Create a collection for each year found in the library | ❌ | ✅ | ✅ | ❌ | ❌ | | [`decade`](#decade) | Create a collection for each decade found in the library | ❌ | ✅ | ✅ | ❌ | ❌ | @@ -130,7 +131,9 @@ Depending on the `type` of dynamic collection, `data` is used to specify the opt | [`studio`](#studio) | Create a collection for each studio found in the library | ❌ | ✅ | ✅ | ❌ | ❌ | | [`edition`](#edition) | Create a collection for each edition found in the library | ❌ | ✅ | ❌ | ❌ | ❌ | | [`network`](#network) | Create a collection for each network found in the library | ❌ | ❌ | ✅ | ❌ | ❌ | -| [`mood`](#mood) | Create a collection for each mood found in the library | ❌ | ❌ | ❌ | ✅ | ❌ | +| [`mood`](#mood) | Create a collection for each artist mood found in the library | ❌ | ❌ | ❌ | ✅ | ❌ | +| [`album_mood`](#album-mood) | Create a collection for each album mood found in the library | ❌ | ❌ | ❌ | ✅ | ❌ | +| [`track_mood`](#track-mood) | Create a collection for each track mood found in the library | ❌ | ❌ | ❌ | ✅ | ❌ | | [`style`](#style) | Create a collection for each artist style found in the library | ❌ | ❌ | ❌ | ✅ | ❌ | | [`album_style`](#album-style) | Create a collection for each album style found in the library | ❌ | ❌ | ❌ | ✅ | ❌ | | [`number`](#number) | Creates a collection for each number defined | ✅ | ✅ | ✅ | ✅ | ✅ | @@ -920,6 +923,72 @@ dynamic_collections: template: genre collection ``` +### Album Genre + +Create a collection for each album genre found in the library. + + + + + + + + + + + + + + + + + + + + + + + + + + +
type Optionalbum_genre
data ValueNot Used
KeysGenre
Key NamesGenre
Default title_formatTop <<key_name>> Albums
Default Template + +```yaml +default_template: + smart_filter: + limit: 50 + sort_by: plays.desc + any: + album_genre: <> +``` + +
+ +#### Example: + +* Create dynamic collections based on each Album genre found in the library +* Amend the template to increase the limit from 10 to 20 +* Exclude the "Pop" genre +* Name the collection "Top 20 [Genre] Albums" + +```yaml +templates: + genre collection: + smart_filter: + limit: 100 + sort_by: plays.desc + all: + album_genre: <> +dynamic_collections: + Genres: # mapping name does not matter just needs to be unique + type: album_genre + exclude: + - Pop + title_format: Top 20 <> <>s + template: genre collection +``` + ### Content Rating Create a collection for each content rating found in the library. @@ -1504,7 +1573,7 @@ dynamic_collections: ### Mood -Create a collection for each mood found in the library. +Create a collection for each artist mood found in the library. @@ -1534,7 +1603,7 @@ Create a collection for each mood found in the library. ```yaml default_template: smart_filter: - limit: 50 + limit: 10 sort_by: plays.desc any: artist_mood: <> @@ -1546,8 +1615,135 @@ default_template: #### Example: -* Create a collection for the top 100 items for each mood found in the Music library -* Name the collection "Top [Mood] Tracks" +* Create a collection for the top 20 artists for each mood found in the Music library +* Amend the template to increase the limit from 10 to 20 +* Name the collection "Top 20 [Mood] Artists" + +```yaml +templates: + mood collection: + smart_filter: + limit: 20 + sort_by: plays.desc + all: + artist_mood: <> +dynamic_collections: + Moods: # mapping name does not matter just needs to be unique + type: mood + title_format: Top 20 <> Artists + template: mood collection +``` + +### Album Mood + +Create a collection for each album mood found in the library. + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
type Optionalbum_mood
data ValueNot Used
KeysMood
Key NamesMood
Default title_formatMost Played <<value>> Albums
Default Template + +```yaml +default_template: + smart_filter: + limit: 10 + sort_by: plays.desc + any: + album_mood: <> +``` + +
+ +#### Example: + +* Create a collection for the top 20 albums for each mood found in the Music library +* Amend the template to increase the limit from 10 to 20 +* Name the collection "Top 20 [Mood] Albums" + +```yaml +templates: + mood collection: + smart_filter: + limit: 20 + sort_by: plays.desc + all: + album_mood: <> +dynamic_collections: + Moods: # mapping name does not matter just needs to be unique + type: album_mood + title_format: Top 20 <> Albums + template: mood collection +``` + +### Track Mood + +Create a collection for each track mood found in the library. + + + + + + + + + + + + + + + + + + + + + + + + + + +
type Optiontrack_mood
data ValueNot Used
KeysMood
Key NamesMood
Default title_formatMost Played <<value>> Tracks
Default Template + +```yaml +default_template: + smart_filter: + limit: 50 + sort_by: plays.desc + any: + track_mood: <> +``` + +
+ +#### Example: + +* Create a collection for the top 100 tracks for each mood found in the Music library +* Amend the template to increase the limit from 50 to 100 +* Name the collection "Top 100 [Mood] Tracks" ```yaml templates: @@ -1555,13 +1751,12 @@ templates: smart_filter: limit: 100 sort_by: plays.desc - type: tracks all: track_mood: <> dynamic_collections: Moods: # mapping name does not matter just needs to be unique - type: mood - title_format: Top <> Tracks + type: track_mood + title_format: Top 100 <> Tracks template: mood collection ``` @@ -1597,7 +1792,7 @@ Create a collection for each artist style found in the library. ```yaml default_template: smart_filter: - limit: 50 + limit: 10 sort_by: plays.desc any: artist_style: <> @@ -1659,7 +1854,7 @@ Create a collection for each album style found in the library. ```yaml default_template: smart_filter: - limit: 50 + limit: 10 sort_by: plays.desc any: album_style: <> diff --git a/modules/builder.py b/modules/builder.py index ae6ca239..db13b38f 100644 --- a/modules/builder.py +++ b/modules/builder.py @@ -849,7 +849,7 @@ class CollectionBuilder: elif method_name == "tvdb_description": self.summaries[method_name] = self.config.TVDb.get_list_description(method_data) elif method_name == "trakt_description": - self.summaries[method_name] = self.config.Trakt.list_description(self.config.Trakt.validate_list(method_data, self.library.is_movie)[0]) + self.summaries[method_name] = self.config.Trakt.list_description(self.config.Trakt.validate_list(method_data)[0]) elif method_name == "letterboxd_description": self.summaries[method_name] = self.config.Letterboxd.get_list_description(method_data, self.language) elif method_name == "icheckmovies_description": diff --git a/modules/meta.py b/modules/meta.py index 534e9bb7..ad602bc7 100644 --- a/modules/meta.py +++ b/modules/meta.py @@ -14,7 +14,7 @@ ms_auto = [ auto = { "Movie": ["tmdb_collection", "edition", "country", "director", "producer", "writer"] + all_auto + ms_auto, "Show": ["network", "origin_country"] + all_auto + ms_auto, - "Artist": ["mood", "style", "country"] + all_auto, + "Artist": ["mood", "style", "country", "album_genre", "album_mood", "album_style", "track_mood"] + all_auto, "Video": ["country", "content_rating"] + all_auto } dynamic_attributes = [ @@ -23,7 +23,7 @@ dynamic_attributes = [ ] auto_type_translation = { "content_rating": "contentRating", "subtitle_language": "subtitleLanguage", "audio_language": "audioLanguage", - "album_style": "album.style", "edition": "editionTitle" + "album_genre": "album.genre", "album_style": "album.style", "album_mood": "album.mood", "track_mood": "track.mood", "edition": "editionTitle" } default_templates = { "original_language": {"plex_all": True, "filters": {"original_language": "<>"}}, @@ -661,7 +661,7 @@ class MetadataFile(DataFile): auto_list = {str(k): f"{k}s" for k in addons if str(k) not in exclude and f"{k}s" not in exclude} default_template = {"smart_filter": {"limit": 50, "sort_by": "critic_rating.desc", "any": {"year": "<>"}}} default_title_format = "Best <>s of <>" - elif auto_type in ["genre", "mood", "style", "album_style", "country", "studio", "edition", "network", "year", "decade", "content_rating", "subtitle_language", "audio_language", "resolution"]: + elif auto_type in ["genre", "mood", "style", "album_genre", "album_mood", "album_style", "track_mood", "country", "studio", "edition", "network", "year", "decade", "content_rating", "subtitle_language", "audio_language", "resolution"]: search_tag = auto_type_translation[auto_type] if auto_type in auto_type_translation else auto_type if library.is_show and auto_type in ["resolution", "subtitle_language", "audio_language"]: tags = library.get_tags(f"episode.{search_tag}") @@ -682,11 +682,13 @@ class MetadataFile(DataFile): all_keys = {str(i.title): i.title for i in tags} auto_list = {str(i.title): i.title for i in tags if str(i.title) not in exclude} if library.is_music: - final_var = auto_type if auto_type.startswith("album") else f"artist_{auto_type}" - default_template = {"smart_filter": {"limit": 50, "sort_by": "plays.desc", "any": {final_var: "<>"}}} - if auto_type.startswith("album"): - default_template["builder_level"] = "album" - default_title_format = f"Most Played <> {'Albums' if auto_type.startswith('album') else '<>'}s" + final_var = auto_type if auto_type.startswith(("album", "track")) else f"artist_{auto_type}" + default_template = {"smart_filter": {"limit": 50 if auto_type.startswith("track") else 10, "sort_by": "plays.desc", "any": {final_var: "<>"}}} + music_type = "<>" + if auto_type.startswith(("album", "track")): + default_template["builder_level"] = "album" if auto_type.startswith("album") else "track" + music_type = "Album" if auto_type.startswith("album") else "Track" + default_title_format = f"Most Played <> {music_type}s" elif auto_type == "resolution": default_template = {"smart_filter": {"sort_by": "title.asc", "any": {auto_type: "<>"}}} default_title_format = "<> <>s"