From b0033e4e570f083241b22794f8f4c9ad5536961d Mon Sep 17 00:00:00 2001 From: Jesse Bannon Date: Sat, 28 Oct 2023 15:45:24 -0700 Subject: [PATCH] fix tests, re-update youtube channel test --- examples/advanced/music_video_config.yaml | 76 +++++++++++++++++++ examples/advanced/tv_show_config.yaml | 16 ++-- tests/conftest.py | 11 ++- tests/e2e/plugins/test_date_range.py | 14 ++-- tests/e2e/youtube/test_channel.py | 6 +- tests/e2e/youtube/test_video.py | 4 +- .../youtube/test_channel_full.json | 2 +- .../youtube/test_channel_full.txt | 1 + tests/unit/config/test_subscription.py | 10 +-- tests/unit/main/test_main.py | 10 +-- 10 files changed, 115 insertions(+), 35 deletions(-) create mode 100644 examples/advanced/music_video_config.yaml diff --git a/examples/advanced/music_video_config.yaml b/examples/advanced/music_video_config.yaml new file mode 100644 index 00000000..64a7d4a1 --- /dev/null +++ b/examples/advanced/music_video_config.yaml @@ -0,0 +1,76 @@ +############################################################################### +# Top-level configurations to apply umask and persist error logs +configuration: + umask: "002" + persist_logs: + logs_directory: './logs' + keep_successful_logs: False + +presets: + + ############################################################################### + # Try to capture music video metadata using regex + regex_capture_metadata: + regex: + from: + # Try to capture the artist and title of the track from the + # video title. Default to channel and video title. + title: + match: + - "(.*) - (.*) \\[O" # artist - song [Official ... + - "(.*) - (.*) \\(O" # artist - song (Official ... + - "(.*) - \"(.*)\" \\[O" # artist - "song" [Official ... + - "(.*) - \"(.*)\" \\(O" # artist - "song" (Official ... + - "(.*): (.*) \\[O" # artist: song [Official ... + - "(.*): (.*) \\(O" # artist: song (Official ... + - "(.*) - \"(.*)\".*" # artist - "song" + - "(.*) - '(.*)'.*" # artist - 'song' + - "(.*) - (.*).*" # artist - song + exclude: + - ".*[Aa][Uu][Dd][Ii][Oo].*" # Exclude audio vids + - ".*[Ll][Yy][Rr][Ii][Cc].*" # Exclude lyric vids + capture_group_names: + - "captured_artist" + - "captured_title" + capture_group_defaults: + - "{channel}" + - "{title}" + + # Try to capture the year the music video premiered. + # Default to upload year + description: + match: + - ".*(19\\d{2}).*" # first 19XX digit value as year + - ".*(20\\d{2}).*" # first 20XX digit value as year + capture_group_names: + - "captured_year" + capture_group_defaults: + - "{upload_year}" + + overrides: + music_video_directory: "/music_videos" + music_video_title: "{music_video_year} - {captured_title}" + music_video_artist: "{subscription_name}" + music_video_album: "Music Videos" + music_video_year: "{captured_year}" + music_video_file_name: "{music_video_artist_sanitized}/{music_video_title_sanitized}" + + ####################################################### + + regex_capture_artist: + overrides: + music_video_artist: "{captured_artist}" + + ####################################################### + + concert: + preset: "music_video" + + overrides: + music_video_album: "Concerts" + + ####################################################### + + year_as_upload_date: + overrides: + music_video_year: "{upload_year}" diff --git a/examples/advanced/tv_show_config.yaml b/examples/advanced/tv_show_config.yaml index cd90d478..f19a5283 100644 --- a/examples/advanced/tv_show_config.yaml +++ b/examples/advanced/tv_show_config.yaml @@ -8,6 +8,12 @@ configuration: presets: + ############################################################################### + # Set tv_show_directory here instead of in the subscriptions file + tv_show_paths: + overrides: + tv_show_directory: "/tv_shows" + ############################################################################### # Filter out any YouTube shorts no_shorts: @@ -34,7 +40,7 @@ presets: # Wait 2 days before downloading in hopes to get more accurate sponsorblock sponsorblock_wait: # Import the sponsorblock preset defined above - presets: + preset: - "sponsorblock" date_range: @@ -47,6 +53,7 @@ presets: preset: - "Kodi TV Show by Date" # Set intended player - "best_video_quality" # prebuilt preset to get best quality + - "tv_show_paths" # Embed chapters into video files chapters: @@ -62,7 +69,7 @@ presets: # ytdl_options lets you pass any arg into yt-dlp's Python API ytdl_options: # Set the cookie file - cookiefile: "/config/youtube_cookies.txt" + # cookiefile: "/config/youtube_cookies.txt" # For YouTube, get English metadata if multiple languages are present extractor_args: @@ -70,11 +77,6 @@ presets: lang: - "en" - # Set tv_show_directory in the preset - # instead of in the subscriptions file - overrides: - tv_show_directory: "/youtube" - ############################################################################### # Custom preset to archive an entire channel TV Show Full Archive: diff --git a/tests/conftest.py b/tests/conftest.py index 3b88c827..d3426a57 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -169,10 +169,13 @@ def music_video_subscription_path() -> Path: @pytest.fixture() -def channel_as_tv_show_config(working_directory) -> ConfigFile: - return _load_config( - config_path=Path("examples/tv_show_config.yaml"), working_directory=working_directory - ) +def tv_show_config_path() -> str: + return "examples/advanced/tv_show_config.yaml" + + +@pytest.fixture() +def tv_show_config(working_directory, tv_show_config_path) -> ConfigFile: + return _load_config(config_path=Path(tv_show_config_path), working_directory=working_directory) @pytest.fixture() diff --git a/tests/e2e/plugins/test_date_range.py b/tests/e2e/plugins/test_date_range.py index 6d0dd483..4196d567 100644 --- a/tests/e2e/plugins/test_date_range.py +++ b/tests/e2e/plugins/test_date_range.py @@ -43,12 +43,12 @@ class TestDateRange: def test_recent_channel_download( self, recent_preset_dict, - channel_as_tv_show_config, + tv_show_config, output_directory, dry_run, ): recent_channel_subscription = Subscription.from_dict( - config=channel_as_tv_show_config, + config=tv_show_config, preset_name="recent", preset_dict=recent_preset_dict, ) @@ -86,7 +86,7 @@ class TestDateRange: @pytest.mark.parametrize("dry_run", [True, False]) def test_recent_channel_download__no_vids_in_range( self, - channel_as_tv_show_config, + tv_show_config, recent_preset_dict, output_directory, dry_run, @@ -94,7 +94,7 @@ class TestDateRange: recent_preset_dict["date_range"]["after"] = "21000101" recent_channel_no_vids_in_range_subscription = Subscription.from_dict( - config=channel_as_tv_show_config, + config=tv_show_config, preset_name="recent", preset_dict=recent_preset_dict, ) @@ -118,19 +118,19 @@ class TestDateRange: @pytest.mark.parametrize("dry_run", [True, False]) def test_rolling_recent_channel_download( self, - channel_as_tv_show_config, + tv_show_config, recent_preset_dict, rolling_recent_channel_preset_dict, output_directory, dry_run, ): recent_channel_subscription = Subscription.from_dict( - config=channel_as_tv_show_config, + config=tv_show_config, preset_name="recent", preset_dict=recent_preset_dict, ) rolling_recent_channel_subscription = Subscription.from_dict( - config=channel_as_tv_show_config, + config=tv_show_config, preset_name="recent", preset_dict=rolling_recent_channel_preset_dict, ) diff --git a/tests/e2e/youtube/test_channel.py b/tests/e2e/youtube/test_channel.py index 8910ea65..585abaa4 100644 --- a/tests/e2e/youtube/test_channel.py +++ b/tests/e2e/youtube/test_channel.py @@ -43,16 +43,16 @@ class TestChannel: expected md5 file hashes. """ - @pytest.mark.parametrize("dry_run", [False]) + @pytest.mark.parametrize("dry_run", [True, False]) def test_full_channel_download( self, - channel_as_tv_show_config, + tv_show_config, channel_preset_dict, output_directory, dry_run, ): full_channel_subscription = Subscription.from_dict( - config=channel_as_tv_show_config, preset_name="pz", preset_dict=channel_preset_dict + config=tv_show_config, preset_name="pz", preset_dict=channel_preset_dict ) transaction_log = full_channel_subscription.download(dry_run=dry_run) assert_transaction_log_matches( diff --git a/tests/e2e/youtube/test_video.py b/tests/e2e/youtube/test_video.py index e2f23970..2b63d6db 100644 --- a/tests/e2e/youtube/test_video.py +++ b/tests/e2e/youtube/test_video.py @@ -208,12 +208,12 @@ class TestYoutubeVideo: def test_single_video_nulled_values( self, - channel_as_tv_show_config, + tv_show_config, single_tv_show_video_nulled_values_preset_dict, output_directory, ): single_video_subscription = Subscription.from_dict( - config=channel_as_tv_show_config, + config=tv_show_config, preset_name="tv_video_nulled_values", preset_dict=single_tv_show_video_nulled_values_preset_dict, ) diff --git a/tests/resources/expected_downloads_summaries/youtube/test_channel_full.json b/tests/resources/expected_downloads_summaries/youtube/test_channel_full.json index 852adc14..8350d840 100644 --- a/tests/resources/expected_downloads_summaries/youtube/test_channel_full.json +++ b/tests/resources/expected_downloads_summaries/youtube/test_channel_full.json @@ -47,7 +47,7 @@ "Project ⧸ Zombie/Season 2018/s2018.e110201 - Jesse's Minecraft Server | IP mc.jesse.id-thumb.jpg": "28d852ede73b879b9ebf9a061cfc7d46", "Project ⧸ Zombie/Season 2018/s2018.e110201 - Jesse's Minecraft Server | IP mc.jesse.id.en.srt": "3d2c4e7f65d2ca5e96da38ce7eecfc4e", "Project ⧸ Zombie/Season 2018/s2018.e110201 - Jesse's Minecraft Server | IP mc.jesse.id.info.json": "INFO_JSON", - "Project ⧸ Zombie/Season 2018/s2018.e110201 - Jesse's Minecraft Server | IP mc.jesse.id.mp4": "77aca1c8f8ef32c282a8a871d80bec10", + "Project ⧸ Zombie/Season 2018/s2018.e110201 - Jesse's Minecraft Server | IP mc.jesse.id.mp4": "3725eaeaae4a400599070a56a1dccf9d", "Project ⧸ Zombie/Season 2018/s2018.e110201 - Jesse's Minecraft Server | IP mc.jesse.id.nfo": "a9b7ac3cacbda7fed9d12b0519945292", "Project ⧸ Zombie/fanart.jpg": "129c6639b47299bc48062f0365e670ee", "Project ⧸ Zombie/poster.jpg": "5de28eea5a921a041452ab3ce1041f73", diff --git a/tests/resources/transaction_log_summaries/youtube/test_channel_full.txt b/tests/resources/transaction_log_summaries/youtube/test_channel_full.txt index 04baa854..9c48de45 100644 --- a/tests/resources/transaction_log_summaries/youtube/test_channel_full.txt +++ b/tests/resources/transaction_log_summaries/youtube/test_channel_full.txt @@ -579,6 +579,7 @@ Files created: s2018.e110201 - Jesse's Minecraft Server | IP mc.jesse.id.en.srt s2018.e110201 - Jesse's Minecraft Server | IP mc.jesse.id.info.json s2018.e110201 - Jesse's Minecraft Server | IP mc.jesse.id.mp4 + Embedded subtitles with lang(s) en Video Tags: contentRating: TV-14 date: 2018-11-02 diff --git a/tests/unit/config/test_subscription.py b/tests/unit/config/test_subscription.py index 097e738c..0fafa4ad 100644 --- a/tests/unit/config/test_subscription.py +++ b/tests/unit/config/test_subscription.py @@ -351,16 +351,14 @@ def test_subscription_file_invalid_form(config_file: ConfigFile): _ = Subscription.from_file_path(config=config_file, subscription_path="mocked") -def test_tv_show_subscriptions( - channel_as_tv_show_config: ConfigFile, tv_show_subscriptions_path: Path -): +def test_tv_show_subscriptions(tv_show_config: ConfigFile, tv_show_subscriptions_path: Path): subs = Subscription.from_file_path( - config=channel_as_tv_show_config, subscription_path=tv_show_subscriptions_path + config=tv_show_config, subscription_path=tv_show_subscriptions_path ) assert len(subs) == 5 - assert subs[2].name == "Jake Trains" - jake_train_overrides = subs[2].overrides.dict_with_format_strings + assert subs[3].name == "Jake Trains" + jake_train_overrides = subs[3].overrides.dict_with_format_strings assert jake_train_overrides["subscription_name"] == "Jake Trains" assert jake_train_overrides["subscription_value"] == "https://www.youtube.com/@JakeTrains" diff --git a/tests/unit/main/test_main.py b/tests/unit/main/test_main.py index 5f4b2d5a..a42e21a5 100644 --- a/tests/unit/main/test_main.py +++ b/tests/unit/main/test_main.py @@ -96,17 +96,17 @@ def test_main_permission_error(capsys, mock_sys_exit, expected_uncaught_error_me assert mock_error.call_args.args[1] == "test" -def test_args_after_sub_work(mock_sys_exit): +def test_args_after_sub_work(mock_sys_exit, tv_show_config_path): with mock_sys_exit(expected_exit_code=0), patch.object( sys, "argv", - ["ytdl-sub", "-c", "examples/tv_show_config.yaml", "sub", "--log-level", "verbose"], + ["ytdl-sub", "-c", tv_show_config_path, "sub", "--log-level", "verbose"], ), patch("ytdl_sub.cli.entrypoint._download_subscriptions_from_yaml_files") as mock_sub: main() assert mock_sub.call_count == 1 assert mock_sub.call_args.kwargs["subscription_paths"] == ["subscriptions.yaml"] - assert mock_sub.call_args.kwargs["config"]._name == "examples/tv_show_config.yaml" + assert mock_sub.call_args.kwargs["config"]._name == tv_show_config_path assert Logger._LOGGER_LEVEL == LoggerLevels.VERBOSE @@ -151,11 +151,11 @@ def test_uses_default_config_if_present(mock_sys_exit): FileHandler.delete(DEFAULT_CONFIG_FILE_NAME) -def test_no_positional_arg_command(mock_sys_exit): +def test_no_positional_arg_command(mock_sys_exit, tv_show_config_path): with mock_sys_exit(expected_exit_code=1), patch.object( sys, "argv", - ["ytdl-sub", "-c", "examples/tv_show_config.yaml", "--log-level", "verbose"], + ["ytdl-sub", "-c", tv_show_config_path, "--log-level", "verbose"], ), patch.object(logging.Logger, "error") as mock_error: main()