This commit is contained in:
Jesse Bannon 2024-01-19 00:22:34 -08:00
parent 4a07b72293
commit 7a5ae6b778
4 changed files with 173 additions and 146 deletions

View file

@ -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) }"

View file

@ -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:

View file

@ -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):

View file

@ -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
):