From 7a5ae6b778140be0855660802006bdd7d5834423 Mon Sep 17 00:00:00 2001 From: Jesse Bannon Date: Fri, 19 Jan 2024 00:22:34 -0800 Subject: [PATCH] simplify --- .../prebuilt_presets/helpers/keyed_url.yaml | 134 ++++++++++++++++++ .../music_videos/music_video_extras.yaml | 107 ++------------ src/ytdl_sub/script/utils/type_checking.py | 20 ++- .../prebuilt_presets/test_prebuilt_presets.py | 58 +++----- 4 files changed, 173 insertions(+), 146 deletions(-) create mode 100644 src/ytdl_sub/prebuilt_presets/helpers/keyed_url.yaml diff --git a/src/ytdl_sub/prebuilt_presets/helpers/keyed_url.yaml b/src/ytdl_sub/prebuilt_presets/helpers/keyed_url.yaml new file mode 100644 index 00000000..bb8ebb0c --- /dev/null +++ b/src/ytdl_sub/prebuilt_presets/helpers/keyed_url.yaml @@ -0,0 +1,134 @@ +# +# Kodi Music Videos with Extras: +# + Rick Astley: +# Music Videos: +# - url1 +# - url2 +# ... +# Concerts: +# - url: asfasdfasdf +# year: 2023 +# title: sdfasff +# exclude: asdffsdf +# - url4 +# Extras: +# - url5 +# - url6 +# Behind The Scenes: +# - ... +# Live: +# - ... +# Lyrics: +# - ... + +presets: + _keyed_url: + + overrides: + + # Takes a value and standardizes it to a dict, i.e. + # + # Concerts: + # - https://url1 -> { "url": "https://url1" } + # - url: https://url2 + # title: custom title -> { "url": "https://url2", "title": "custom title" } + "%standardize_value_to_dict": >- + { + %if( + %is_string($0), + { "url": $0 }, + $0 + ) + } + + # Takes a Subscription Dict in the form of + # + # Concerts: + # - https://url1 + # - url: https://url2 + # title: custom title + # Another: + # - https://url3 + # + # and standardizes it to + # + # [ + # { "key": "Concerts", "url": "https://url1" }, + # { "key": "Concerts", "url": "https://url2", "title": "custom title" }, + # { "key": "Another", "url": "https://url3" } + # ] + "%subscription_dict_to_list__inner": >- + { + %map_extend( + { "key": $0 }, + %assert_then( + %if( + %is_dict( %standardize_value_to_dict( $1 ) ), + %map_contains( %standardize_value_to_dict( $1 ), "url" ), + False + ), + %standardize_value_to_dict( $1 ), + "Value must be either a string or a Map with the key 'url'" + ) + ) + } + + # The actual variable that holds the subscription list of maps + subscription_map_list: >- + { + %map_apply( subscription_dict, %subscription_dict_to_list__inner ) + } + + # Helper function to get the i'th map in the subscription list. + # Returns an empty map if it does not exist. + "%get_subscription_map_i": >- + { + %array_at( subscription_map_list, $0, {} ) + } + + # Helper function to get the i'th map's url in the subscription list. + # Returns null if it does not exist. + "%get_subscription_map_i_url": >- + { + %map_get( + %get_subscription_map_i( $0 ), + "url", + null + ) + } + + + download: + - url: "{ %get_subscription_map_i_url(0) }" + playlist_thumbnails: + - name: "{avatar_uncropped_thumbnail_file_name}" + uid: "avatar_uncropped" + - name: "{banner_uncropped_thumbnail_file_name}" + uid: "banner_uncropped" + variables: + keyed_metadata: "{ %get_subscription_map_i(0) }" + - url: "{ %get_url_by_idx(1) }" + variables: + keyed_metadata: "{ %get_subscription_map_i(1) }" + - url: "{ %get_url_by_idx(2) }" + variables: + keyed_metadata: "{ %get_subscription_map_i(2) }" + - url: "{ %get_url_by_idx(3) }" + variables: + keyed_metadata: "{ %get_subscription_map_i(3) }" + - url: "{ %get_url_by_idx(4) }" + variables: + keyed_metadata: "{ %get_subscription_map_i(4) }" + - url: "{ %get_url_by_idx(5) }" + variables: + keyed_metadata: "{ %get_subscription_map_i(5) }" + - url: "{ %get_url_by_idx(6) }" + variables: + keyed_metadata: "{ %get_subscription_map_i(6) }" + - url: "{ %get_url_by_idx(7) }" + variables: + keyed_metadata: "{ %get_subscription_map_i(7) }" + - url: "{ %get_url_by_idx(8) }" + variables: + keyed_metadata: "{ %get_subscription_map_i(8) }" + diff --git a/src/ytdl_sub/prebuilt_presets/music_videos/music_video_extras.yaml b/src/ytdl_sub/prebuilt_presets/music_videos/music_video_extras.yaml index 252ae027..9cc72d82 100644 --- a/src/ytdl_sub/prebuilt_presets/music_videos/music_video_extras.yaml +++ b/src/ytdl_sub/prebuilt_presets/music_videos/music_video_extras.yaml @@ -6,7 +6,10 @@ # - url2 # ... # Concerts: -# - "Custom Title | 2013 | url3" +# - url: asfasdfasdf +# year: 2023 +# title: sdfasff +# exclude: asdffsdf # - url4 # Extras: # - url5 @@ -21,106 +24,14 @@ presets: _music_video_extras_base: preset: + - "_keyed_url" - "_music_video_base" overrides: - - # Splits metadata values from (TODO: allow any whitespace between | ) - # Key: - # - metadata_0 | url - # - metadata_0 | metadata_1 | url - "%get_value_split": >- - { %split($0, " | ") } - - # Gets the size of the metadata split - "%get_value_size": >- - { %array_size( %get_value_split($0) ) } - - # Gets the URL from the metadata, will always be the last one - "%get_value_url": >- - { %array_at( %get_value_split($0), -1 ) } - - # gets metadata_i if present, otherwise returns null - "%get_value_metadata_i": >- - { - %if( - %gt( %get_value_size($0) , %add($1, 1) ), - %array_at( %get_value_split($0), $1 ), - null - ) - } - - # For each value under a key, build this map allowing up to 5 metadata values - "%get_value_metadata_map": >- - { - { - "key": $1, - "url": %get_value_url($0), - 0: %get_value_metadata_i($0, 0), - 1: %get_value_metadata_i($0, 1), - 2: %get_value_metadata_i($0, 2), - 3: %get_value_metadata_i($0, 3), - 4: %get_value_metadata_i($0, 4) - } - } - - # TODO: Have this support single-string values - "%get_value_metadata_map_outer": >- - { %array_apply_fixed( $1, $0, %get_value_metadata_map ) } - - # Build an array of metadata maps from every key in the subscription_map - subscription_list_of_maps: >- - { - %array_flatten( - %map_apply( subscription_map, %get_value_metadata_map_outer ) - ) - } - - "%get_list_metadata_field_by_idx": >- - { - %map_get( - %array_at( subscription_list_of_maps, $0, {} ), - $1, - $2 - ) - } - - "%get_url_by_idx": >- - { %get_list_metadata_field_by_idx($0, "url", null) } - "%get_key_by_idx": >- - { %get_list_metadata_field_by_idx($0, "key", null) } - "%get_metadata_i_by_idx": >- - { %get_list_metadata_field_by_idx($0, $1, $2) } - - metadata_0_default: "{ %string(null) }" - metadata_1_default: "{ %string(null) }" - metadata_2_default: "{ %string(null) }" - metadata_3_default: "{ %string(null) }" - metadata_4_default: "{ %string(null) }" - - - download: - - url: "{ %get_url_by_idx(0) }" - playlist_thumbnails: - - name: "{avatar_uncropped_thumbnail_file_name}" - uid: "avatar_uncropped" - - name: "{banner_uncropped_thumbnail_file_name}" - uid: "banner_uncropped" - variables: - metadata_key: "{ %get_key_by_idx(0) }" - metadata_0: "{ %get_metadata_i_by_idx(0, 0, metadata_0_default) }" - metadata_1: "{ %get_metadata_i_by_idx(0, 1, metadata_1_default) }" - metadata_2: "{ %get_metadata_i_by_idx(0, 2, metadata_2_default) }" - metadata_3: "{ %get_metadata_i_by_idx(0, 3, metadata_3_default) }" - metadata_4: "{ %get_metadata_i_by_idx(0, 4, metadata_4_default) }" - - url: "{ %get_url_by_idx(1) }" - variables: - metadata_key: "{ %get_key_by_idx(1) }" - metadata_0: "{ %get_metadata_i_by_idx(0, 0, metadata_0_default) }" - metadata_1: "{ %get_metadata_i_by_idx(0, 1, metadata_1_default) }" - metadata_2: "{ %get_metadata_i_by_idx(0, 2, metadata_2_default) }" - metadata_3: "{ %get_metadata_i_by_idx(0, 3, metadata_3_default) }" - metadata_4: "{ %get_metadata_i_by_idx(0, 4, metadata_4_default) }" + music_video_album: >- + { %map_get( %map(keyed_metadata), "key" ) } + music_video_title: >- + { %map_get( keyed_metadata, "title", title ) } "Jellyfin Music Videos with Extras": preset: diff --git a/src/ytdl_sub/script/utils/type_checking.py b/src/ytdl_sub/script/utils/type_checking.py index 2170c3e0..ef7c02de 100644 --- a/src/ytdl_sub/script/utils/type_checking.py +++ b/src/ytdl_sub/script/utils/type_checking.py @@ -63,21 +63,19 @@ def _is_type_compatible( True if arg is compatible with expected_arg_type. False otherwise. """ if is_union(expected_arg_type): - # See if the arg is a valid against the union - valid_type = False + if issubclass(arg_type, (NamedCustomFunction, Variable)): + return True # custom-function/variable can be anything, so pass for now # if the input arg is a union, do a direct comparison if is_union(arg_type): - valid_type = arg_type == expected_arg_type - # otherwise, iterate the union to see if it's compatible - else: - for union_type in expected_arg_type.__args__: - if issubclass(arg_type, union_type): - valid_type = True - break + return arg_type == expected_arg_type - if not valid_type: - return False + # otherwise, iterate the union to see if it's compatible + for union_type in expected_arg_type.__args__: + if issubclass(arg_type, union_type): + return True + + return False # If the input is a union and the expected type is not, see if # each possible union input is compatible with the expected type elif is_union(arg_type): diff --git a/tests/unit/prebuilt_presets/test_prebuilt_presets.py b/tests/unit/prebuilt_presets/test_prebuilt_presets.py index 1a891640..d7bcf2f4 100644 --- a/tests/unit/prebuilt_presets/test_prebuilt_presets.py +++ b/tests/unit/prebuilt_presets/test_prebuilt_presets.py @@ -542,18 +542,6 @@ class TestPrebuiltMusicVideoPresets: ) @pytest.mark.parametrize("multi_url", [True, False]) class TestPrebuiltMusicVideoPresets: - def _will_succeed(self, music_video_extras_preset: str, album_metadata: str) -> bool: - if "Plex" not in music_video_extras_preset: - return True - - return album_metadata in [ - "behindthescenes", - "concert", - "interview", - "live", - "lyrics", - "video", - ] def _preset_dict( self, @@ -561,17 +549,25 @@ class TestPrebuiltMusicVideoPresets: music_video_extras_preset: str, album_metadata: str, multi_url: bool, - ) -> Tuple[Dict, bool]: - """Dict, whether it will succeed or not""" - - subscription_indent_1 = album_metadata - subscription_indent_2 = "https://your.name.here" - subscription_indent_3 = "" - subscription_indent_4 = "" + ) -> Dict: + subscription_dict = f"""{{ + {{ + {album_metadata}: "https://your.name.here" + }} + }}""" if multi_url: - subscription_indent_3 = subscription_indent_1 + " | Custom Title" - subscription_indent_4 = "https://your.name.here2" + subscription_dict = f"""{{ + {{ + {album_metadata}: [ + "https://your.name.here", + {{ + "url": "https://your.name.here2", + "title": "Custom Title" + }} + ] + }} + }}""" preset_dict = { "preset": [ @@ -579,16 +575,11 @@ class TestPrebuiltMusicVideoPresets: ], "overrides": { "music_video_directory": output_directory, - "subscription_value_1": subscription_indent_1, - "subscription_value_2": subscription_indent_2, - "subscription_value_3": subscription_indent_3, - "subscription_value_4": subscription_indent_4, + "subscription_dict": subscription_dict, }, } - return preset_dict, self._will_succeed( - music_video_extras_preset=music_video_extras_preset, album_metadata=album_metadata - ) + return preset_dict def test_compilation( self, @@ -598,7 +589,7 @@ class TestPrebuiltMusicVideoPresets: album_metadata: str, multi_url: bool, ): - preset_dict, _ = self._preset_dict( + preset_dict = self._preset_dict( output_directory=output_directory, music_video_extras_preset=music_video_extras_preset, album_metadata=album_metadata, @@ -623,7 +614,7 @@ class TestPrebuiltMusicVideoPresets: f"unit/music_videos/{music_video_extras_preset}/{album_metadata}/multi_url_{multi_url}" ) - preset_dict, will_succeed = self._preset_dict( + preset_dict = self._preset_dict( output_directory=output_directory, music_video_extras_preset=music_video_extras_preset, album_metadata=album_metadata, @@ -636,13 +627,6 @@ class TestPrebuiltMusicVideoPresets: preset_dict=preset_dict, ) - if not will_succeed: - with pytest.raises(RegexNoMatchException), mock_download_collection_entries( - is_youtube_channel=False, num_urls=2 if multi_url else 1, is_extracted_audio=False - ): - subscription.download(dry_run=False) - return - with mock_download_collection_entries( is_youtube_channel=False, num_urls=2 if multi_url else 1, is_extracted_audio=False ):