diff --git a/docs/source/guides/development/index.rst b/docs/source/guides/development/index.rst index bf6b2c12..d0750e65 100644 --- a/docs/source/guides/development/index.rst +++ b/docs/source/guides/development/index.rst @@ -62,3 +62,19 @@ is highly recommended. TODO: screenshots of configuration +Debugging +--------- + +Debug Logs +^^^^^^^^^^^^^^^ +Run with ``--log-level debug`` to show all debug logs when running ytdl-sub. + + +Reproducing a Failing Subscription +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Subscriptions will dump their entire *compiled* yaml at the beginning of exeuction +when using ``--log-level debug``. This can be copy-pasted into the file +``resources/file_fixtures/repro.yaml``. + +Running the test ``e2e.test_debug_repro.TestReproduce.test_debug_log_repro`` +will fully reproduce that subscription in order to debug it. \ No newline at end of file diff --git a/tests/e2e/test_debug_repro.py b/tests/e2e/test_debug_repro.py new file mode 100644 index 00000000..b96f530b --- /dev/null +++ b/tests/e2e/test_debug_repro.py @@ -0,0 +1,69 @@ +import json +from typing import Dict + +import pytest +import yaml +from resources import file_fixture_path + +from ytdl_sub.subscriptions.subscription import Subscription + + +def debug_yaml_to_preset_dict(debug_subscription_dict: Dict, output_directory: str) -> Dict: + presets_level = debug_subscription_dict["presets"] + assert isinstance(presets_level, dict) and len(presets_level) == 1 + subscription = list(presets_level.values())[0] + del subscription["preset"] + subscription["output_options"]["output_directory"] = output_directory + return subscription + + +@pytest.fixture +def debug_log_rerpo(output_directory): + with open(file_fixture_path("repro.yaml"), "r", encoding="utf-8") as yaml_file: + yaml_dict = yaml.safe_load(yaml_file) + return debug_yaml_to_preset_dict( + debug_subscription_dict=yaml_dict, + output_directory=output_directory, + ) + + +@pytest.fixture +def subscription_yaml_preset(default_config, output_directory): + subscriptions = Subscription.from_file_path( + config=default_config, subscription_path=file_fixture_path("repro.yaml") + ) + subscription_dict = yaml.safe_load(subscriptions[0].as_yaml()) + return debug_yaml_to_preset_dict( + debug_subscription_dict=subscription_dict, + output_directory=output_directory, + ) + + +@pytest.mark.skipif(True, reason="Always skip repro, for local testing only") +class TestReproduce: + def test_debug_log_repro( + self, + default_config, + repro_preset_dict, + output_directory, + ): + sub = Subscription.from_dict( + config=default_config, + preset_name="repro", + preset_dict=repro_preset_dict, + ) + + transaction_log = sub.download(dry_run=False) + assert not transaction_log.is_empty + + def test_subscription_yaml_repro( + self, default_config, subscription_yaml_preset, output_directory + ): + sub = Subscription.from_dict( + config=default_config, + preset_name="repro", + preset_dict=subscription_yaml_preset, + ) + + transaction_log = sub.download(dry_run=False) + assert not transaction_log.is_empty diff --git a/tests/resources/file_fixtures/repro.yaml b/tests/resources/file_fixtures/repro.yaml new file mode 100644 index 00000000..17ca0b07 --- /dev/null +++ b/tests/resources/file_fixtures/repro.yaml @@ -0,0 +1,42 @@ +__preset__: + overrides: + music_directory: "hi" + +YouTube Full Albums: + + = Eastern Bloc: + "Eastern Bloc": + output_options: + migrated_download_archive_name: ".Eastern Bloc-download-archive.json" + ytdl_options: + max_downloads: 3 + overrides: + title_capture_regex_array: + - "^(.*) - (.*) \\|\\|.*" # Captures artist, album from 'artist - album ||...' + - "^(.*) - (.*) \\[.*" # Captures artist, ablum from 'artist - album [...' + - "^(.*) - (.*)" # Captures artist, ablum from 'artist - album' + title_capture: >- + { + %regex_capture_many( title, title_capture_regex_array ) + } + + description_capture_regex_array: + - '{%unescape("Genre:\s*(.*)\s*\n(?:Rec.+|Year):\s*.*(\d\{4\})\s*\n")}' # Captures genre and recorded year + description_capture: >- + { + %regex_capture_many( description, description_capture_regex_array) + } + + chapter_title_regex_array: + - "^(?:\\d+\\.\\s*|)(.*)" # Captures title from '1. title' + chapter_title_capture: >- + { + %regex_capture_many( chapter_title, chapter_title_regex_array, [chapter_title] ) + } + + url: "https://www.youtube.com/@heavymetalofeasternbloc" + track_artist: "{%array_at(title_capture, 1)}" + track_album: "{%array_at(title_capture, 2)}" + track_title: "{%array_at(chapter_title_capture, 1)}" + track_year: "{%array_at(description_capture, 1)}" +