diff --git a/docs/source/config_reference/scripting/static_variables.rst b/docs/source/config_reference/scripting/static_variables.rst index 2825edba..9a90e761 100644 --- a/docs/source/config_reference/scripting/static_variables.rst +++ b/docs/source/config_reference/scripting/static_variables.rst @@ -5,6 +5,18 @@ Static Variables Subscription Variables ---------------------- +subscription_array +~~~~~~~~~~~~~~~~~~ +For subscriptions in the form of + +.. code-block:: yaml + + "Subscription Name": + - "https://url1.com/..." + - "https://url2.com/..." + +Store all values into an array named ``subscription_array``. + subscription_has_download_archive ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Returns True if the subscription has any entries recorded in a download archive. False diff --git a/examples/music_video_subscriptions.yaml b/examples/music_video_subscriptions.yaml index 330d1ef9..fb600b69 100644 --- a/examples/music_video_subscriptions.yaml +++ b/examples/music_video_subscriptions.yaml @@ -14,12 +14,32 @@ __preset__: overrides: music_video_directory: "/music_videos" -# Choose between Jellyfin/Kodi/Plex Music Videos -# "Jellyfin Music Videos": -# "Kodi Music Videos": +# Choose between Jellyfin/Kodi/Plex Music Videos preset: +# - Plex Music Videos: +# - Jellyfin Music Videos: +# - Kodi Music Videos: "Plex Music Videos": + = Pop: # Sets genre tag to "Pop" "Rick Astley": "https://www.youtube.com/playlist?list=PLlaN88a7y2_plecYoJxvRFTLHVbIVAOoc" "Michael Jackson": "https://www.youtube.com/playlist?list=OLAK5uy_mnY03zP6abNWH929q2XhGzWD_2uKJ_n8E" + = Blues: "Eric Clapton": "https://www.youtube.com/playlist?list=PLABGggHhsbEeaRtdzqnxYoEINsJE_4GF4" + + = Rock: + # Prefixing with '+' puts the subscription into 'map-mode'. + # Music video presets in map-mode support grouping videos into different + # categories, which get set on the album field. + # + # URLs can either be strings, or maps that can overload title, year, date + "+ Guns N' Roses": + Music Videos: + - "https://www.youtube.com/playlist?list=PLOTK54q5K4INNXaHKtmXYr6J7CajWjqeJ" + Concerts: + - title: "Live at The Ritz - New York City" + year: "1988" + url: "https://www.youtube.com/watch?v=OldpIhHPsbs" + - title: "Live at The Hollywood Bowl" + date: "2023-01-11" + url: "https://www.youtube.com/watch?v=Z7hutGlvq9I" \ No newline at end of file diff --git a/src/ytdl_sub/entries/variables/override_variables.py b/src/ytdl_sub/entries/variables/override_variables.py index 68ec72d4..42bb4498 100644 --- a/src/ytdl_sub/entries/variables/override_variables.py +++ b/src/ytdl_sub/entries/variables/override_variables.py @@ -3,6 +3,7 @@ from typing import Set from ytdl_sub.entries.script.function_scripts import CUSTOM_FUNCTION_SCRIPTS from ytdl_sub.entries.script.variable_definitions import VARIABLE_SCRIPTS +from ytdl_sub.entries.script.variable_types import ArrayVariable from ytdl_sub.entries.script.variable_types import BooleanVariable from ytdl_sub.entries.script.variable_types import MapVariable from ytdl_sub.entries.script.variable_types import StringVariable @@ -36,6 +37,21 @@ class SubscriptionVariables: """ return StringVariable(variable_name="subscription_value", definition="{ %string('') }") + @staticmethod + def subscription_array() -> ArrayVariable: + """ + For subscriptions in the form of + + .. code-block:: yaml + + "Subscription Name": + - "https://url1.com/..." + - "https://url2.com/..." + + Store all values into an array named ``subscription_array``. + """ + return ArrayVariable(variable_name="subscription_array", definition="{ [] }") + @staticmethod def subscription_indent_i(index: int) -> StringVariable: """ diff --git a/src/ytdl_sub/prebuilt_presets/helpers/url.yaml b/src/ytdl_sub/prebuilt_presets/helpers/url.yaml index 3a9726dd..7fc1d9ad 100644 --- a/src/ytdl_sub/prebuilt_presets/helpers/url.yaml +++ b/src/ytdl_sub/prebuilt_presets/helpers/url.yaml @@ -129,6 +129,7 @@ presets: avatar_uncropped_thumbnail_file_name: "" banner_uncropped_thumbnail_file_name: "" + subscription_array: "{ [] }" subscription_value: "" subscription_value_2: "" subscription_value_3: "" diff --git a/src/ytdl_sub/prebuilt_presets/helpers/url_categorized.yaml b/src/ytdl_sub/prebuilt_presets/helpers/url_categorized.yaml new file mode 100644 index 00000000..b212f640 --- /dev/null +++ b/src/ytdl_sub/prebuilt_presets/helpers/url_categorized.yaml @@ -0,0 +1,210 @@ +presets: + # Preset for categorizing URls like so + # + # subscription_name: + # category_1: + # - https://...1 + # - https://...2 + # category_2: + # - url: https://...1 + # metadata_field_1: 2011 + # metadata_field_2: 'abc" + # ... + # + # Metadata field of `url` must exist, other ones can be anything. + # Only supports a single level of nesting. + _url_categorized: + preset: + - "_multi_url_bilateral" + + overrides: + # Parameters: + # $0: url string or map containing url + metadata fields + # $1: category key + # + # Output: + # Map containing { url: ..., category: ..., metadata_field_1: ... } + "%flat_array__url_to_map_format": >- + { + %elif( + %is_map($0), + %map_extend( $0, { "category": $1 } ), + %is_string($0), + { "url": $0, "category": $1 }, + %throw("If using album categories, each URL must be either a string or map with metadata fields") + ) + } + + # Parameters: + # $0: category key + # $1: array of URLs in either string or map form + # + # Output: + # Array containing [{ url: ..., category: ... }, ... ] + "%flat_array__category_to_map_format": >- + { + %array_apply_fixed( + %assert_then( + %is_array( $1 ), + $1, + "If using album categories, each category must map to an array" + ), + $0, + %flat_array__url_to_map_format + ) + } + + # Parameters: + # $0: map containing fields { url: , category: ... } + # + # Output: + # Nested map containing { : { url: , category: ... } } + "%flat_array__url_keyed_map_format": >- + { { %map_get($0, "url"): $0 } } + + # Creates an array in the form of [ { url: ..., category: ..., metadata_field_1: ... }, ... ] + category_url_array: >- + { %array_flatten( %map_apply( subscription_map, %flat_array__category_to_map_format ) ) } + + # Creates a map in the form of { : { category: ..., metadata_field_1: ... }, ... } + category_url_map: >- + { + %array_reduce( + %array_apply( category_url_array, %flat_array__url_keyed_map_format ), + %map_extend + ) + } + + # Parameters: + # $0: metadata field to fetch for the current url + # $1: default value + # + # Output: + # Metadata field value if it exists. Otherwise, return default value + "%get_url_field": >- + { %map_get( %map( %map_get( category_url_map, ytdl_sub_input_url, {} ) ), $0, $1 ) } + + # Parameters: + # $0: metadata field to fetch for the current url + # + # Output: + # True if field is specified. False otherwise. + "%contains_url_field": >- + { %not( %is_null( %get_url_field( $0, null ) ) ) } + + + # Parameters: + # $0: integer to fetch the i'th url using 1-based indexing + # + # Output: + # i'th url in the category map + "%get_url_i": >- + { + %map_get( + %map( %array_at( category_url_array, %int( %sub($0, 1) ), {} ) ), + "url", + %array_at(subscription_array, %int( %sub($0, 1) ), null) + ) + } + + subscription_map: "{ {} }" + url: "{ %get_url_i(1) }" + url2: "{ %get_url_i(2) }" + url3: "{ %get_url_i(3) }" + url4: "{ %get_url_i(4) }" + url5: "{ %get_url_i(5) }" + url6: "{ %get_url_i(6) }" + url7: "{ %get_url_i(7) }" + url8: "{ %get_url_i(8) }" + url9: "{ %get_url_i(9) }" + url10: "{ %get_url_i(10) }" + url11: "{ %get_url_i(11) }" + url12: "{ %get_url_i(12) }" + url13: "{ %get_url_i(13) }" + url14: "{ %get_url_i(14) }" + url15: "{ %get_url_i(15) }" + url16: "{ %get_url_i(16) }" + url17: "{ %get_url_i(17) }" + url18: "{ %get_url_i(18) }" + url19: "{ %get_url_i(19) }" + url20: "{ %get_url_i(20) }" + url21: "{ %get_url_i(21) }" + url22: "{ %get_url_i(22) }" + url23: "{ %get_url_i(23) }" + url24: "{ %get_url_i(24) }" + url25: "{ %get_url_i(25) }" + url26: "{ %get_url_i(26) }" + url27: "{ %get_url_i(27) }" + url28: "{ %get_url_i(28) }" + url29: "{ %get_url_i(29) }" + url30: "{ %get_url_i(30) }" + url31: "{ %get_url_i(31) }" + url32: "{ %get_url_i(32) }" + url33: "{ %get_url_i(33) }" + url34: "{ %get_url_i(34) }" + url35: "{ %get_url_i(35) }" + url36: "{ %get_url_i(36) }" + url37: "{ %get_url_i(37) }" + url38: "{ %get_url_i(38) }" + url39: "{ %get_url_i(39) }" + url40: "{ %get_url_i(40) }" + url41: "{ %get_url_i(41) }" + url42: "{ %get_url_i(42) }" + url43: "{ %get_url_i(43) }" + url44: "{ %get_url_i(44) }" + url45: "{ %get_url_i(45) }" + url46: "{ %get_url_i(46) }" + url47: "{ %get_url_i(47) }" + url48: "{ %get_url_i(48) }" + url49: "{ %get_url_i(49) }" + url50: "{ %get_url_i(50) }" + url51: "{ %get_url_i(51) }" + url52: "{ %get_url_i(52) }" + url53: "{ %get_url_i(53) }" + url54: "{ %get_url_i(54) }" + url55: "{ %get_url_i(55) }" + url56: "{ %get_url_i(56) }" + url57: "{ %get_url_i(57) }" + url58: "{ %get_url_i(58) }" + url59: "{ %get_url_i(59) }" + url60: "{ %get_url_i(60) }" + url61: "{ %get_url_i(61) }" + url62: "{ %get_url_i(62) }" + url63: "{ %get_url_i(63) }" + url64: "{ %get_url_i(64) }" + url65: "{ %get_url_i(65) }" + url66: "{ %get_url_i(66) }" + url67: "{ %get_url_i(67) }" + url68: "{ %get_url_i(68) }" + url69: "{ %get_url_i(69) }" + url70: "{ %get_url_i(70) }" + url71: "{ %get_url_i(71) }" + url72: "{ %get_url_i(72) }" + url73: "{ %get_url_i(73) }" + url74: "{ %get_url_i(74) }" + url75: "{ %get_url_i(75) }" + url76: "{ %get_url_i(76) }" + url77: "{ %get_url_i(77) }" + url78: "{ %get_url_i(78) }" + url79: "{ %get_url_i(79) }" + url80: "{ %get_url_i(80) }" + url81: "{ %get_url_i(81) }" + url82: "{ %get_url_i(82) }" + url83: "{ %get_url_i(83) }" + url84: "{ %get_url_i(84) }" + url85: "{ %get_url_i(85) }" + url86: "{ %get_url_i(86) }" + url87: "{ %get_url_i(87) }" + url88: "{ %get_url_i(88) }" + url89: "{ %get_url_i(89) }" + url90: "{ %get_url_i(90) }" + url91: "{ %get_url_i(91) }" + url92: "{ %get_url_i(92) }" + url93: "{ %get_url_i(93) }" + url94: "{ %get_url_i(94) }" + url95: "{ %get_url_i(95) }" + url96: "{ %get_url_i(96) }" + url97: "{ %get_url_i(97) }" + url98: "{ %get_url_i(98) }" + url99: "{ %get_url_i(99) }" + url100: "{ %get_url_i(100) }" \ No newline at end of file diff --git a/src/ytdl_sub/prebuilt_presets/music_videos/__init__.py b/src/ytdl_sub/prebuilt_presets/music_videos/__init__.py index 7338b591..ae128998 100644 --- a/src/ytdl_sub/prebuilt_presets/music_videos/__init__.py +++ b/src/ytdl_sub/prebuilt_presets/music_videos/__init__.py @@ -10,3 +10,11 @@ class MusicVideoPresets(PrebuiltPresets): "Jellyfin Music Videos", "Plex Music Videos", } + + +class MusicVideoExtrasPresets(PrebuiltPresets): + preset_names = { + "Kodi Music Videos with Extras", + "Jellyfin Music Videos with Extras", + "Plex Music Videos with Extras", + } diff --git a/src/ytdl_sub/prebuilt_presets/music_videos/music_video_base.yaml b/src/ytdl_sub/prebuilt_presets/music_videos/music_video_base.yaml index ac810745..25b97697 100644 --- a/src/ytdl_sub/prebuilt_presets/music_videos/music_video_base.yaml +++ b/src/ytdl_sub/prebuilt_presets/music_videos/music_video_base.yaml @@ -1,7 +1,8 @@ presets: _music_video_base: + preset: - - "_multi_url" + - "_url_categorized" output_options: output_directory: "{music_video_directory}" @@ -25,12 +26,38 @@ presets: subscription_indent_1: "{music_video_genre_default}" # Music Video Overrides - music_video_title: "{title}" - music_video_album: "{music_video_album_default}" music_video_artist: "{subscription_name}" - music_video_year: "{upload_year}" - music_video_date: "{upload_date_standardized}" music_video_genre: "{subscription_indent_1}" + music_video_album: >- + { %get_url_field("category", music_video_album_default) } + music_video_title: >- + { %get_url_field("title", title) } + music_video_date: >- + { + %elif( + %contains_url_field("date"), + %get_url_field("date", upload_date_standardized), + + %contains_url_field("year"), + %concat( %get_url_field("date", upload_year), "-01-01"), + + upload_date_standardized + ) + } + music_video_year: >- + { + %int(%elif( + %contains_url_field("date"), + %slice( %get_url_field("date", upload_date_standardized), 0, 4 ), + + %contains_url_field("year"), + %get_url_field("date", upload_year), + + upload_year + )) + } + # Directory Overrides - music_video_file_name: "{music_video_artist_sanitized}/{music_video_title_sanitized}" \ No newline at end of file + music_video_file_name_suffix: "" + music_video_file_name: "{music_video_artist_sanitized}/{music_video_title_sanitized}{music_video_file_name_suffix}" 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 new file mode 100644 index 00000000..e292deea --- /dev/null +++ b/src/ytdl_sub/prebuilt_presets/music_videos/music_video_extras.yaml @@ -0,0 +1,58 @@ +# +# 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: + _music_video_extras_base: + preset: + - "_url_categorized" + - "_music_video_base" + + overrides: + music_video_album: >- + { %get_url_field("category", music_video_album_default) } + music_video_title: >- + { %get_url_field("title", title) } + + "Jellyfin Music Videos with Extras": + preset: + - "_base" + - "_music_video_extras_base" + - "_music_video_nfo" + - "_music_video_tags" + + "Kodi Music Videos with Extras": + preset: + - "_kodi_base" + - "_music_video_extras_base" + - "_music_video_nfo" + - "_music_video_tags" + + "Plex Music Videos with Extras": + preset: + - "_plex_video_base" + - "_music_video_extras_base" + - "_music_video_tags" + +# overrides: +# metadata_verify_plex_suffix: "{url_metadata}" +# music_video_file_name_suffix: "-{music_video_album}" \ No newline at end of file diff --git a/src/ytdl_sub/subscriptions/subscription_validators.py b/src/ytdl_sub/subscriptions/subscription_validators.py index 5994c218..35bbbcb7 100644 --- a/src/ytdl_sub/subscriptions/subscription_validators.py +++ b/src/ytdl_sub/subscriptions/subscription_validators.py @@ -143,10 +143,21 @@ class SubscriptionValueValidator(SubscriptionLeafValidator, StringValidator): presets=presets, indent_overrides=indent_overrides, ) + # subscription_value self._overrides_to_add[SubscriptionVariables.subscription_value().variable_name] = ( self.value ) + # subscription_value_0 + self._overrides_to_add[ + SubscriptionVariables.subscription_value_i(index=0).variable_name + ] = self.value + + # And the array variable + self._overrides_to_add[SubscriptionVariables.subscription_array().variable_name] = ( + ScriptUtils.to_script([self.value]) + ) + class SubscriptionListValuesValidator(SubscriptionLeafValidator, StringListValidator): def __init__( @@ -167,6 +178,7 @@ class SubscriptionListValuesValidator(SubscriptionLeafValidator, StringListValid indent_overrides=indent_overrides, ) + # Add indexed variables for idx, list_value in enumerate(self.list): # Write the first list value into subscription_value as well if idx == 0: @@ -178,6 +190,11 @@ class SubscriptionListValuesValidator(SubscriptionLeafValidator, StringListValid SubscriptionVariables.subscription_value_i(index=idx).variable_name ] = list_value.value + # And the array variable + self._overrides_to_add[SubscriptionVariables.subscription_array().variable_name] = ( + ScriptUtils.to_script([list_value.value for list_value in self.list]) + ) + class SubscriptionWithOverridesValidator(SubscriptionLeafValidator, DictFormatterValidator): def __init__( @@ -220,7 +237,7 @@ class SubscriptionMapValidator(SubscriptionLeafValidator, LiteralDictValidator): indent_overrides=indent_overrides, ) self._overrides_to_add[SubscriptionVariables.subscription_map().variable_name] = ( - ScriptUtils.to_script(self.dict) + ScriptUtils.to_script(self.dict, sort_keys=False) ) diff --git a/src/ytdl_sub/utils/script.py b/src/ytdl_sub/utils/script.py index fba88a35..e3a17b2f 100644 --- a/src/ytdl_sub/utils/script.py +++ b/src/ytdl_sub/utils/script.py @@ -35,7 +35,7 @@ class ScriptUtils: return dict(variables, **sanitized_variables) @classmethod - def to_script(cls, value: Any) -> str: + def to_script(cls, value: Any, sort_keys: bool = True) -> str: """ Converts a python value to a script value """ @@ -50,7 +50,7 @@ class ScriptUtils: elif isinstance(value, float): out = f"{{%float({value})}}" else: - dumped_json = json.dumps(value, ensure_ascii=False, sort_keys=True) + dumped_json = json.dumps(value, ensure_ascii=False, sort_keys=sort_keys) # Remove triple-single-quotes from JSON to avoid parsing issues dumped_json = re.sub("'{3,}", "'", dumped_json) diff --git a/tests/resources/expected_downloads_summaries/unit/music_videos/Jellyfin Music Videos Categorized/multi_url_False.json b/tests/resources/expected_downloads_summaries/unit/music_videos/Jellyfin Music Videos Categorized/multi_url_False.json new file mode 100644 index 00000000..72e4fbce --- /dev/null +++ b/tests/resources/expected_downloads_summaries/unit/music_videos/Jellyfin Music Videos Categorized/multi_url_False.json @@ -0,0 +1,19 @@ +{ + ".ytdl-sub-subscription_test-download-archive.json": "b98a30417f259daeec888e1a5047b9ed", + "subscription_test/Mock Entry 20-1.info.json": "INFO_JSON", + "subscription_test/Mock Entry 20-1.jpg": "e80c508c4818454300133fe1dc1a9cd7", + "subscription_test/Mock Entry 20-1.mp4": "34916dc26e723c3464adcc4687898ca8", + "subscription_test/Mock Entry 20-1.nfo": "68a6a9e51a12e75d4c68e6e644b409d1", + "subscription_test/Mock Entry 20-2.info.json": "INFO_JSON", + "subscription_test/Mock Entry 20-2.jpg": "e80c508c4818454300133fe1dc1a9cd7", + "subscription_test/Mock Entry 20-2.mp4": "01a910b7a023325aa9d4ad3a013a1e02", + "subscription_test/Mock Entry 20-2.nfo": "1cbe51945c1a7a9ced0eb1222e9d2405", + "subscription_test/Mock Entry 20-3.info.json": "INFO_JSON", + "subscription_test/Mock Entry 20-3.jpg": "e80c508c4818454300133fe1dc1a9cd7", + "subscription_test/Mock Entry 20-3.mp4": "812b6db9ff08bf1822e99e43d371400d", + "subscription_test/Mock Entry 20-3.nfo": "ef07f30d3e882de3f7cb3ad675125352", + "subscription_test/Mock Entry 21-1.info.json": "INFO_JSON", + "subscription_test/Mock Entry 21-1.jpg": "e80c508c4818454300133fe1dc1a9cd7", + "subscription_test/Mock Entry 21-1.mp4": "079832b6e49b283d80be402c9c928b90", + "subscription_test/Mock Entry 21-1.nfo": "dc714fd9f3c3729f74927ad245b50d9d" +} \ No newline at end of file diff --git a/tests/resources/expected_downloads_summaries/unit/music_videos/Jellyfin Music Videos Categorized/multi_url_True.json b/tests/resources/expected_downloads_summaries/unit/music_videos/Jellyfin Music Videos Categorized/multi_url_True.json new file mode 100644 index 00000000..ced3db94 --- /dev/null +++ b/tests/resources/expected_downloads_summaries/unit/music_videos/Jellyfin Music Videos Categorized/multi_url_True.json @@ -0,0 +1,23 @@ +{ + ".ytdl-sub-subscription_test-download-archive.json": "bcb2e8e8139f5bf589e027f841aa9449", + "subscription_test/Custom Title.info.json": "INFO_JSON", + "subscription_test/Custom Title.jpg": "e80c508c4818454300133fe1dc1a9cd7", + "subscription_test/Custom Title.mp4": "d7c2b8e961a8fcb612bd0d69c96bf0f3", + "subscription_test/Custom Title.nfo": "996f3993b2ba8a0614bef294492dde65", + "subscription_test/Mock Entry 20-4.info.json": "INFO_JSON", + "subscription_test/Mock Entry 20-4.jpg": "e80c508c4818454300133fe1dc1a9cd7", + "subscription_test/Mock Entry 20-4.mp4": "10f239edf916f8fb9eb461f24a821578", + "subscription_test/Mock Entry 20-4.nfo": "1e7cb1a09c15f155623f6cd796e874ff", + "subscription_test/Mock Entry 20-5.info.json": "INFO_JSON", + "subscription_test/Mock Entry 20-5.jpg": "e80c508c4818454300133fe1dc1a9cd7", + "subscription_test/Mock Entry 20-5.mp4": "046878a073fb269ec61401cdeb834707", + "subscription_test/Mock Entry 20-5.nfo": "f6100f194ae3c3b24211ff515d97ccdf", + "subscription_test/Mock Entry 20-6.info.json": "INFO_JSON", + "subscription_test/Mock Entry 20-6.jpg": "e80c508c4818454300133fe1dc1a9cd7", + "subscription_test/Mock Entry 20-6.mp4": "a50ead5d08456f0bcb907f1912caefcf", + "subscription_test/Mock Entry 20-6.nfo": "f51ae05104f5b98531535e75d623f941", + "subscription_test/Mock Entry 20-7.info.json": "INFO_JSON", + "subscription_test/Mock Entry 20-7.jpg": "e80c508c4818454300133fe1dc1a9cd7", + "subscription_test/Mock Entry 20-7.mp4": "5b35f04254c38c33ba056274b6c3af9f", + "subscription_test/Mock Entry 20-7.nfo": "852c02ea3ab196d808854ee94a9313d2" +} \ No newline at end of file diff --git a/tests/resources/expected_downloads_summaries/unit/music_videos/Kodi Music Videos Categorized/multi_url_False.json b/tests/resources/expected_downloads_summaries/unit/music_videos/Kodi Music Videos Categorized/multi_url_False.json new file mode 100644 index 00000000..72e4fbce --- /dev/null +++ b/tests/resources/expected_downloads_summaries/unit/music_videos/Kodi Music Videos Categorized/multi_url_False.json @@ -0,0 +1,19 @@ +{ + ".ytdl-sub-subscription_test-download-archive.json": "b98a30417f259daeec888e1a5047b9ed", + "subscription_test/Mock Entry 20-1.info.json": "INFO_JSON", + "subscription_test/Mock Entry 20-1.jpg": "e80c508c4818454300133fe1dc1a9cd7", + "subscription_test/Mock Entry 20-1.mp4": "34916dc26e723c3464adcc4687898ca8", + "subscription_test/Mock Entry 20-1.nfo": "68a6a9e51a12e75d4c68e6e644b409d1", + "subscription_test/Mock Entry 20-2.info.json": "INFO_JSON", + "subscription_test/Mock Entry 20-2.jpg": "e80c508c4818454300133fe1dc1a9cd7", + "subscription_test/Mock Entry 20-2.mp4": "01a910b7a023325aa9d4ad3a013a1e02", + "subscription_test/Mock Entry 20-2.nfo": "1cbe51945c1a7a9ced0eb1222e9d2405", + "subscription_test/Mock Entry 20-3.info.json": "INFO_JSON", + "subscription_test/Mock Entry 20-3.jpg": "e80c508c4818454300133fe1dc1a9cd7", + "subscription_test/Mock Entry 20-3.mp4": "812b6db9ff08bf1822e99e43d371400d", + "subscription_test/Mock Entry 20-3.nfo": "ef07f30d3e882de3f7cb3ad675125352", + "subscription_test/Mock Entry 21-1.info.json": "INFO_JSON", + "subscription_test/Mock Entry 21-1.jpg": "e80c508c4818454300133fe1dc1a9cd7", + "subscription_test/Mock Entry 21-1.mp4": "079832b6e49b283d80be402c9c928b90", + "subscription_test/Mock Entry 21-1.nfo": "dc714fd9f3c3729f74927ad245b50d9d" +} \ No newline at end of file diff --git a/tests/resources/expected_downloads_summaries/unit/music_videos/Kodi Music Videos Categorized/multi_url_True.json b/tests/resources/expected_downloads_summaries/unit/music_videos/Kodi Music Videos Categorized/multi_url_True.json new file mode 100644 index 00000000..ced3db94 --- /dev/null +++ b/tests/resources/expected_downloads_summaries/unit/music_videos/Kodi Music Videos Categorized/multi_url_True.json @@ -0,0 +1,23 @@ +{ + ".ytdl-sub-subscription_test-download-archive.json": "bcb2e8e8139f5bf589e027f841aa9449", + "subscription_test/Custom Title.info.json": "INFO_JSON", + "subscription_test/Custom Title.jpg": "e80c508c4818454300133fe1dc1a9cd7", + "subscription_test/Custom Title.mp4": "d7c2b8e961a8fcb612bd0d69c96bf0f3", + "subscription_test/Custom Title.nfo": "996f3993b2ba8a0614bef294492dde65", + "subscription_test/Mock Entry 20-4.info.json": "INFO_JSON", + "subscription_test/Mock Entry 20-4.jpg": "e80c508c4818454300133fe1dc1a9cd7", + "subscription_test/Mock Entry 20-4.mp4": "10f239edf916f8fb9eb461f24a821578", + "subscription_test/Mock Entry 20-4.nfo": "1e7cb1a09c15f155623f6cd796e874ff", + "subscription_test/Mock Entry 20-5.info.json": "INFO_JSON", + "subscription_test/Mock Entry 20-5.jpg": "e80c508c4818454300133fe1dc1a9cd7", + "subscription_test/Mock Entry 20-5.mp4": "046878a073fb269ec61401cdeb834707", + "subscription_test/Mock Entry 20-5.nfo": "f6100f194ae3c3b24211ff515d97ccdf", + "subscription_test/Mock Entry 20-6.info.json": "INFO_JSON", + "subscription_test/Mock Entry 20-6.jpg": "e80c508c4818454300133fe1dc1a9cd7", + "subscription_test/Mock Entry 20-6.mp4": "a50ead5d08456f0bcb907f1912caefcf", + "subscription_test/Mock Entry 20-6.nfo": "f51ae05104f5b98531535e75d623f941", + "subscription_test/Mock Entry 20-7.info.json": "INFO_JSON", + "subscription_test/Mock Entry 20-7.jpg": "e80c508c4818454300133fe1dc1a9cd7", + "subscription_test/Mock Entry 20-7.mp4": "5b35f04254c38c33ba056274b6c3af9f", + "subscription_test/Mock Entry 20-7.nfo": "852c02ea3ab196d808854ee94a9313d2" +} \ No newline at end of file diff --git a/tests/resources/expected_downloads_summaries/unit/music_videos/Plex Music Videos Categorized/multi_url_False.json b/tests/resources/expected_downloads_summaries/unit/music_videos/Plex Music Videos Categorized/multi_url_False.json new file mode 100644 index 00000000..78727e67 --- /dev/null +++ b/tests/resources/expected_downloads_summaries/unit/music_videos/Plex Music Videos Categorized/multi_url_False.json @@ -0,0 +1,15 @@ +{ + ".ytdl-sub-subscription_test-download-archive.json": "6cb47203ec56d8318a0d428b5b4efa5d", + "subscription_test/Mock Entry 20-1.info.json": "INFO_JSON", + "subscription_test/Mock Entry 20-1.jpg": "e80c508c4818454300133fe1dc1a9cd7", + "subscription_test/Mock Entry 20-1.mp4": "34916dc26e723c3464adcc4687898ca8", + "subscription_test/Mock Entry 20-2.info.json": "INFO_JSON", + "subscription_test/Mock Entry 20-2.jpg": "e80c508c4818454300133fe1dc1a9cd7", + "subscription_test/Mock Entry 20-2.mp4": "01a910b7a023325aa9d4ad3a013a1e02", + "subscription_test/Mock Entry 20-3.info.json": "INFO_JSON", + "subscription_test/Mock Entry 20-3.jpg": "e80c508c4818454300133fe1dc1a9cd7", + "subscription_test/Mock Entry 20-3.mp4": "812b6db9ff08bf1822e99e43d371400d", + "subscription_test/Mock Entry 21-1.info.json": "INFO_JSON", + "subscription_test/Mock Entry 21-1.jpg": "e80c508c4818454300133fe1dc1a9cd7", + "subscription_test/Mock Entry 21-1.mp4": "079832b6e49b283d80be402c9c928b90" +} \ No newline at end of file diff --git a/tests/resources/expected_downloads_summaries/unit/music_videos/Plex Music Videos Categorized/multi_url_True.json b/tests/resources/expected_downloads_summaries/unit/music_videos/Plex Music Videos Categorized/multi_url_True.json new file mode 100644 index 00000000..5f236acf --- /dev/null +++ b/tests/resources/expected_downloads_summaries/unit/music_videos/Plex Music Videos Categorized/multi_url_True.json @@ -0,0 +1,18 @@ +{ + ".ytdl-sub-subscription_test-download-archive.json": "69a9960ce69e3813269412fa7cb1bd33", + "subscription_test/Custom Title.info.json": "INFO_JSON", + "subscription_test/Custom Title.jpg": "e80c508c4818454300133fe1dc1a9cd7", + "subscription_test/Custom Title.mp4": "d7c2b8e961a8fcb612bd0d69c96bf0f3", + "subscription_test/Mock Entry 20-4.info.json": "INFO_JSON", + "subscription_test/Mock Entry 20-4.jpg": "e80c508c4818454300133fe1dc1a9cd7", + "subscription_test/Mock Entry 20-4.mp4": "10f239edf916f8fb9eb461f24a821578", + "subscription_test/Mock Entry 20-5.info.json": "INFO_JSON", + "subscription_test/Mock Entry 20-5.jpg": "e80c508c4818454300133fe1dc1a9cd7", + "subscription_test/Mock Entry 20-5.mp4": "046878a073fb269ec61401cdeb834707", + "subscription_test/Mock Entry 20-6.info.json": "INFO_JSON", + "subscription_test/Mock Entry 20-6.jpg": "e80c508c4818454300133fe1dc1a9cd7", + "subscription_test/Mock Entry 20-6.mp4": "a50ead5d08456f0bcb907f1912caefcf", + "subscription_test/Mock Entry 20-7.info.json": "INFO_JSON", + "subscription_test/Mock Entry 20-7.jpg": "e80c508c4818454300133fe1dc1a9cd7", + "subscription_test/Mock Entry 20-7.mp4": "5b35f04254c38c33ba056274b6c3af9f" +} \ No newline at end of file diff --git a/tests/resources/transaction_log_summaries/unit/music_videos/Jellyfin Music Videos Categorized/multi_url_False.txt b/tests/resources/transaction_log_summaries/unit/music_videos/Jellyfin Music Videos Categorized/multi_url_False.txt new file mode 100644 index 00000000..52e2c27d --- /dev/null +++ b/tests/resources/transaction_log_summaries/unit/music_videos/Jellyfin Music Videos Categorized/multi_url_False.txt @@ -0,0 +1,77 @@ +Files created: +---------------------------------------- +{output_directory} + .ytdl-sub-subscription_test-download-archive.json +{output_directory}/subscription_test + Mock Entry 20-1.info.json + Mock Entry 20-1.jpg + Mock Entry 20-1.mp4 + Video Tags: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-08-08 + title: Mock Entry 20-1 + year: 2020 + Mock Entry 20-1.nfo + NFO tags: + musicvideo: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-08-08 + title: Mock Entry 20-1 + Mock Entry 20-2.info.json + Mock Entry 20-2.jpg + Mock Entry 20-2.mp4 + Video Tags: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-08-08 + title: Mock Entry 20-2 + year: 2020 + Mock Entry 20-2.nfo + NFO tags: + musicvideo: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-08-08 + title: Mock Entry 20-2 + Mock Entry 20-3.info.json + Mock Entry 20-3.jpg + Mock Entry 20-3.mp4 + Video Tags: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-08-07 + title: Mock Entry 20-3 + year: 2020 + Mock Entry 20-3.nfo + NFO tags: + musicvideo: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-08-07 + title: Mock Entry 20-3 + Mock Entry 21-1.info.json + Mock Entry 21-1.jpg + Mock Entry 21-1.mp4 + Video Tags: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2021-08-08 + title: Mock Entry 21-1 + year: 2021 + Mock Entry 21-1.nfo + NFO tags: + musicvideo: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2021-08-08 + title: Mock Entry 21-1 \ No newline at end of file diff --git a/tests/resources/transaction_log_summaries/unit/music_videos/Jellyfin Music Videos Categorized/multi_url_True.txt b/tests/resources/transaction_log_summaries/unit/music_videos/Jellyfin Music Videos Categorized/multi_url_True.txt new file mode 100644 index 00000000..49e609e1 --- /dev/null +++ b/tests/resources/transaction_log_summaries/unit/music_videos/Jellyfin Music Videos Categorized/multi_url_True.txt @@ -0,0 +1,95 @@ +Files created: +---------------------------------------- +{output_directory} + .ytdl-sub-subscription_test-download-archive.json +{output_directory}/subscription_test + Custom Title.info.json + Custom Title.jpg + Custom Title.mp4 + Video Tags: + album: Concerts + artist: subscription_test + genre: ytdl-sub + premiered: 2021-08-08 + title: Custom Title + year: 2021 + Custom Title.nfo + NFO tags: + musicvideo: + album: Concerts + artist: subscription_test + genre: ytdl-sub + premiered: 2021-08-08 + title: Custom Title + Mock Entry 20-4.info.json + Mock Entry 20-4.jpg + Mock Entry 20-4.mp4 + Video Tags: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-08-06 + title: Mock Entry 20-4 + year: 2020 + Mock Entry 20-4.nfo + NFO tags: + musicvideo: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-08-06 + title: Mock Entry 20-4 + Mock Entry 20-5.info.json + Mock Entry 20-5.jpg + Mock Entry 20-5.mp4 + Video Tags: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-07-06 + title: Mock Entry 20-5 + year: 2020 + Mock Entry 20-5.nfo + NFO tags: + musicvideo: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-07-06 + title: Mock Entry 20-5 + Mock Entry 20-6.info.json + Mock Entry 20-6.jpg + Mock Entry 20-6.mp4 + Video Tags: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-07-06 + title: Mock Entry 20-6 + year: 2020 + Mock Entry 20-6.nfo + NFO tags: + musicvideo: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-07-06 + title: Mock Entry 20-6 + Mock Entry 20-7.info.json + Mock Entry 20-7.jpg + Mock Entry 20-7.mp4 + Video Tags: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-06-06 + title: Mock Entry 20-7 + year: 2020 + Mock Entry 20-7.nfo + NFO tags: + musicvideo: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-06-06 + title: Mock Entry 20-7 \ No newline at end of file diff --git a/tests/resources/transaction_log_summaries/unit/music_videos/Kodi Music Videos Categorized/multi_url_False.txt b/tests/resources/transaction_log_summaries/unit/music_videos/Kodi Music Videos Categorized/multi_url_False.txt new file mode 100644 index 00000000..52e2c27d --- /dev/null +++ b/tests/resources/transaction_log_summaries/unit/music_videos/Kodi Music Videos Categorized/multi_url_False.txt @@ -0,0 +1,77 @@ +Files created: +---------------------------------------- +{output_directory} + .ytdl-sub-subscription_test-download-archive.json +{output_directory}/subscription_test + Mock Entry 20-1.info.json + Mock Entry 20-1.jpg + Mock Entry 20-1.mp4 + Video Tags: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-08-08 + title: Mock Entry 20-1 + year: 2020 + Mock Entry 20-1.nfo + NFO tags: + musicvideo: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-08-08 + title: Mock Entry 20-1 + Mock Entry 20-2.info.json + Mock Entry 20-2.jpg + Mock Entry 20-2.mp4 + Video Tags: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-08-08 + title: Mock Entry 20-2 + year: 2020 + Mock Entry 20-2.nfo + NFO tags: + musicvideo: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-08-08 + title: Mock Entry 20-2 + Mock Entry 20-3.info.json + Mock Entry 20-3.jpg + Mock Entry 20-3.mp4 + Video Tags: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-08-07 + title: Mock Entry 20-3 + year: 2020 + Mock Entry 20-3.nfo + NFO tags: + musicvideo: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-08-07 + title: Mock Entry 20-3 + Mock Entry 21-1.info.json + Mock Entry 21-1.jpg + Mock Entry 21-1.mp4 + Video Tags: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2021-08-08 + title: Mock Entry 21-1 + year: 2021 + Mock Entry 21-1.nfo + NFO tags: + musicvideo: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2021-08-08 + title: Mock Entry 21-1 \ No newline at end of file diff --git a/tests/resources/transaction_log_summaries/unit/music_videos/Kodi Music Videos Categorized/multi_url_True.txt b/tests/resources/transaction_log_summaries/unit/music_videos/Kodi Music Videos Categorized/multi_url_True.txt new file mode 100644 index 00000000..49e609e1 --- /dev/null +++ b/tests/resources/transaction_log_summaries/unit/music_videos/Kodi Music Videos Categorized/multi_url_True.txt @@ -0,0 +1,95 @@ +Files created: +---------------------------------------- +{output_directory} + .ytdl-sub-subscription_test-download-archive.json +{output_directory}/subscription_test + Custom Title.info.json + Custom Title.jpg + Custom Title.mp4 + Video Tags: + album: Concerts + artist: subscription_test + genre: ytdl-sub + premiered: 2021-08-08 + title: Custom Title + year: 2021 + Custom Title.nfo + NFO tags: + musicvideo: + album: Concerts + artist: subscription_test + genre: ytdl-sub + premiered: 2021-08-08 + title: Custom Title + Mock Entry 20-4.info.json + Mock Entry 20-4.jpg + Mock Entry 20-4.mp4 + Video Tags: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-08-06 + title: Mock Entry 20-4 + year: 2020 + Mock Entry 20-4.nfo + NFO tags: + musicvideo: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-08-06 + title: Mock Entry 20-4 + Mock Entry 20-5.info.json + Mock Entry 20-5.jpg + Mock Entry 20-5.mp4 + Video Tags: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-07-06 + title: Mock Entry 20-5 + year: 2020 + Mock Entry 20-5.nfo + NFO tags: + musicvideo: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-07-06 + title: Mock Entry 20-5 + Mock Entry 20-6.info.json + Mock Entry 20-6.jpg + Mock Entry 20-6.mp4 + Video Tags: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-07-06 + title: Mock Entry 20-6 + year: 2020 + Mock Entry 20-6.nfo + NFO tags: + musicvideo: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-07-06 + title: Mock Entry 20-6 + Mock Entry 20-7.info.json + Mock Entry 20-7.jpg + Mock Entry 20-7.mp4 + Video Tags: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-06-06 + title: Mock Entry 20-7 + year: 2020 + Mock Entry 20-7.nfo + NFO tags: + musicvideo: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-06-06 + title: Mock Entry 20-7 \ No newline at end of file diff --git a/tests/resources/transaction_log_summaries/unit/music_videos/Plex Music Videos Categorized/multi_url_False.txt b/tests/resources/transaction_log_summaries/unit/music_videos/Plex Music Videos Categorized/multi_url_False.txt new file mode 100644 index 00000000..520d916d --- /dev/null +++ b/tests/resources/transaction_log_summaries/unit/music_videos/Plex Music Videos Categorized/multi_url_False.txt @@ -0,0 +1,45 @@ +Files created: +---------------------------------------- +{output_directory} + .ytdl-sub-subscription_test-download-archive.json +{output_directory}/subscription_test + Mock Entry 20-1.info.json + Mock Entry 20-1.jpg + Mock Entry 20-1.mp4 + Video Tags: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-08-08 + title: Mock Entry 20-1 + year: 2020 + Mock Entry 20-2.info.json + Mock Entry 20-2.jpg + Mock Entry 20-2.mp4 + Video Tags: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-08-08 + title: Mock Entry 20-2 + year: 2020 + Mock Entry 20-3.info.json + Mock Entry 20-3.jpg + Mock Entry 20-3.mp4 + Video Tags: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-08-07 + title: Mock Entry 20-3 + year: 2020 + Mock Entry 21-1.info.json + Mock Entry 21-1.jpg + Mock Entry 21-1.mp4 + Video Tags: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2021-08-08 + title: Mock Entry 21-1 + year: 2021 \ No newline at end of file diff --git a/tests/resources/transaction_log_summaries/unit/music_videos/Plex Music Videos Categorized/multi_url_True.txt b/tests/resources/transaction_log_summaries/unit/music_videos/Plex Music Videos Categorized/multi_url_True.txt new file mode 100644 index 00000000..1b97b19d --- /dev/null +++ b/tests/resources/transaction_log_summaries/unit/music_videos/Plex Music Videos Categorized/multi_url_True.txt @@ -0,0 +1,55 @@ +Files created: +---------------------------------------- +{output_directory} + .ytdl-sub-subscription_test-download-archive.json +{output_directory}/subscription_test + Custom Title.info.json + Custom Title.jpg + Custom Title.mp4 + Video Tags: + album: Concerts + artist: subscription_test + genre: ytdl-sub + premiered: 2021-08-08 + title: Custom Title + year: 2021 + Mock Entry 20-4.info.json + Mock Entry 20-4.jpg + Mock Entry 20-4.mp4 + Video Tags: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-08-06 + title: Mock Entry 20-4 + year: 2020 + Mock Entry 20-5.info.json + Mock Entry 20-5.jpg + Mock Entry 20-5.mp4 + Video Tags: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-07-06 + title: Mock Entry 20-5 + year: 2020 + Mock Entry 20-6.info.json + Mock Entry 20-6.jpg + Mock Entry 20-6.mp4 + Video Tags: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-07-06 + title: Mock Entry 20-6 + year: 2020 + Mock Entry 20-7.info.json + Mock Entry 20-7.jpg + Mock Entry 20-7.mp4 + Video Tags: + album: Music Videos + artist: subscription_test + genre: ytdl-sub + premiered: 2020-06-06 + title: Mock Entry 20-7 + year: 2020 \ No newline at end of file diff --git a/tests/unit/cli/test_entrypoint.py b/tests/unit/cli/test_entrypoint.py index d7a472cc..084df414 100644 --- a/tests/unit/cli/test_entrypoint.py +++ b/tests/unit/cli/test_entrypoint.py @@ -34,7 +34,7 @@ def test_subscription_logs_write_to_file( keep_successful_logs: bool, match: List[str], ): - subscription_names = ["Rick Astley", "Michael Jackson", "Eric Clapton"] + subscription_names = ["Rick Astley", "Michael Jackson", "Eric Clapton", "Guns N' Roses"] if match: subscription_names = ["Rick Astley", "Michael Jackson"] num_runs = 2 diff --git a/tests/unit/config/test_subscription.py b/tests/unit/config/test_subscription.py index e01525b7..ff9feb93 100644 --- a/tests/unit/config/test_subscription.py +++ b/tests/unit/config/test_subscription.py @@ -1,3 +1,4 @@ +import json import re from contextlib import contextmanager from pathlib import Path @@ -470,6 +471,15 @@ def test_advanced_tv_show_subscriptions( == "https://www.youtube.com/playlist?list=PLi8V8UemxeG6lo5if5H5g5EbsteELcb0_" ) + assert overrides.apply_formatter(overrides.dict["subscription_array"]) == json.dumps( + [ + "https://www.youtube.com/@gardeningwithciscoe4430", + "https://www.youtube.com/playlist?list=PLi8V8UemxeG6lo5if5H5g5EbsteELcb0_", + "https://www.youtube.com/playlist?list=PLsJlQSR-KjmaQqqJ9jq18cF6XXXAR4kyn", + "https://www.youtube.com/watch?v=2vq-vPubS5I", + ] + ) + def test_music_subscriptions(default_config: ConfigFile, music_subscriptions_path: Path): subs = Subscription.from_file_path( @@ -493,16 +503,31 @@ def test_music_video_subscriptions(default_config: ConfigFile, music_video_subsc config=default_config, subscription_path=music_video_subscription_path ) - assert len(subs) == 3 + assert len(subs) == 4 assert subs[1].name == "Michael Jackson" - monk = subs[1].overrides.script + jackson = subs[1].overrides.script - assert monk.get("subscription_name").native == "Michael Jackson" + assert jackson.get("subscription_name").native == "Michael Jackson" assert ( - monk.get("subscription_value").native + jackson.get("subscription_value").native == "https://www.youtube.com/playlist?list=OLAK5uy_mnY03zP6abNWH929q2XhGzWD_2uKJ_n8E" ) - assert monk.get("subscription_indent_1").native == "Pop" + assert jackson.get("subscription_indent_1").native == "Pop" + assert ( + jackson.get("url").native + == "https://www.youtube.com/playlist?list=OLAK5uy_mnY03zP6abNWH929q2XhGzWD_2uKJ_n8E" + ) + + assert subs[3].name == "Guns N' Roses" + gnr = subs[3].overrides.script + + assert gnr.get("subscription_name").native == "Guns N' Roses" + assert ( + gnr.get("url").native + == "https://www.youtube.com/playlist?list=PLOTK54q5K4INNXaHKtmXYr6J7CajWjqeJ" + ) + assert gnr.get("subscription_indent_1").native == "Rock" + assert gnr.get("url2").native == "https://www.youtube.com/watch?v=OldpIhHPsbs" def test_default_docker_config_and_subscriptions(): diff --git a/tests/unit/prebuilt_presets/test_prebuilt_presets.py b/tests/unit/prebuilt_presets/test_prebuilt_presets.py index 0f7cf5a2..a92a05c2 100644 --- a/tests/unit/prebuilt_presets/test_prebuilt_presets.py +++ b/tests/unit/prebuilt_presets/test_prebuilt_presets.py @@ -1,4 +1,5 @@ import copy +from pathlib import Path from typing import Dict from typing import List from typing import Optional @@ -9,6 +10,7 @@ from expected_download import assert_expected_downloads from expected_transaction_log import assert_transaction_log_matches from ytdl_sub.prebuilt_presets.music import MusicPresets +from ytdl_sub.prebuilt_presets.music_videos import MusicVideoExtrasPresets from ytdl_sub.prebuilt_presets.music_videos import MusicVideoPresets from ytdl_sub.prebuilt_presets.tv_show import TvShowByDateEpisodeFormattingPresets from ytdl_sub.prebuilt_presets.tv_show import TvShowByDateOldPresets @@ -16,6 +18,7 @@ from ytdl_sub.prebuilt_presets.tv_show import TvShowCollectionEpisodeFormattingP from ytdl_sub.prebuilt_presets.tv_show import TvShowCollectionPresets from ytdl_sub.prebuilt_presets.tv_show import TvShowCollectionSeasonPresets from ytdl_sub.subscriptions.subscription import Subscription +from ytdl_sub.utils.exceptions import RegexNoMatchException from ytdl_sub.utils.exceptions import ValidationException @@ -530,3 +533,91 @@ class TestPrebuiltMusicVideoPresets: dry_run=False, expected_download_summary_file_name=f"{expected_summary_name}.json", ) + + +@pytest.mark.parametrize("music_video_preset", MusicVideoPresets.preset_names) +@pytest.mark.parametrize("multi_url", [True, False]) +class TestPrebuiltMusicVideoPresetsWithCategories: + + def _preset_dict( + self, + output_directory: Path, + music_video_preset: str, + multi_url: bool, + ) -> Dict: + subscription_dict = {"Music Videos": ["https://your.name.here"]} + + if multi_url: + subscription_dict["Concerts"] = [ + {"url": "https://your.name.here2", "title": "Custom Title"} + ] + + preset_dict = { + "preset": [ + music_video_preset, + ], + "overrides": { + "music_video_directory": output_directory, + "subscription_map": subscription_dict, + }, + } + + return preset_dict + + def test_compilation( + self, + config, + output_directory: Path, + music_video_preset: str, + multi_url: bool, + ): + preset_dict = self._preset_dict( + output_directory=output_directory, + music_video_preset=music_video_preset, + multi_url=multi_url, + ) + + _ = Subscription.from_dict( + config=config, preset_name="preset_test", preset_dict=preset_dict + ) + + def test_presets_run( + self, + config, + subscription_name, + output_directory, + mock_download_collection_entries, + music_video_preset: str, + multi_url: bool, + ): + expected_summary_name = ( + f"unit/music_videos/{music_video_preset} Categorized/multi_url_{multi_url}" + ) + + preset_dict = self._preset_dict( + output_directory=output_directory, + music_video_preset=music_video_preset, + multi_url=multi_url, + ) + + subscription = Subscription.from_dict( + config=config, + preset_name=subscription_name, + preset_dict=preset_dict, + ) + + with mock_download_collection_entries( + is_youtube_channel=False, num_urls=2 if multi_url else 1, is_extracted_audio=False + ): + transaction_log = subscription.download(dry_run=False) + + assert_transaction_log_matches( + output_directory=output_directory, + transaction_log=transaction_log, + transaction_log_summary_file_name=f"{expected_summary_name}.txt", + ) + assert_expected_downloads( + output_directory=output_directory, + dry_run=False, + expected_download_summary_file_name=f"{expected_summary_name}.json", + )