From 37ef14cc179a97b25fa54f76f07cc27886ebf920 Mon Sep 17 00:00:00 2001 From: Jesse Bannon Date: Fri, 4 Oct 2024 23:15:24 -0700 Subject: [PATCH 1/5] need to have conditionals not execute all branches --- .../prebuilt_presets/common.rst | 5 + docs/source/prebuilt_presets/helpers.rst | 28 ++++ .../prebuilt_presets/helpers/filtering.yaml | 52 +++++++ .../prebuilt_presets/test_filter_keywords.py | 130 ++++++++++++++++++ tests/resources.py | 2 +- .../filter_keywords_empty.txt | 66 +++++++++ .../filter_keywords_exclude.txt | 66 +++++++++ .../filter_keywords_include.txt | 1 + 8 files changed, 349 insertions(+), 1 deletion(-) create mode 100644 src/ytdl_sub/prebuilt_presets/helpers/filtering.yaml create mode 100644 tests/integration/prebuilt_presets/test_filter_keywords.py create mode 100644 tests/resources/transaction_log_summaries/integration/prebuilt_presets/filter_keywords_empty.txt create mode 100644 tests/resources/transaction_log_summaries/integration/prebuilt_presets/filter_keywords_exclude.txt create mode 100644 tests/resources/transaction_log_summaries/integration/prebuilt_presets/filter_keywords_include.txt diff --git a/docs/source/config_reference/prebuilt_presets/common.rst b/docs/source/config_reference/prebuilt_presets/common.rst index 0a6c8e8a0..ab1fd5453 100644 --- a/docs/source/config_reference/prebuilt_presets/common.rst +++ b/docs/source/config_reference/prebuilt_presets/common.rst @@ -4,6 +4,11 @@ Common .. highlight:: yaml +Filtering +------------- + +.. literalinclude:: /../../src/ytdl_sub/prebuilt_presets/helpers/filtering.yaml + Media Quality ------------- diff --git a/docs/source/prebuilt_presets/helpers.rst b/docs/source/prebuilt_presets/helpers.rst index 745cdb97f..6f67693f2 100644 --- a/docs/source/prebuilt_presets/helpers.rst +++ b/docs/source/prebuilt_presets/helpers.rst @@ -35,6 +35,34 @@ Add the following preset to download the best available audio and video quality, ``max_1080p`` +Filter Keywords +--------------- + +Include or exclude media with any of the listed keywords in their titles. Both keywords and title/description are lower-cased before filtering. + +``Filter Keywords`` + +.. tip:: + + Use the `~` tilda subscription mode to set a subscription's list override variables. + Tilda mode allows override variables to be set directly underneath it. + + .. code-block:: yaml + Plex TV Show by Date: + + = Documentaries: + "~NOVA PBS": + url: "https://www.youtube.com/@novapbs" + title_exclude_keywords: + - "preview" + - "trailer" + + "~To Catch a Smuggler": + url: "https://www.youtube.com/@NatGeo" + title_include_keywords: + - "To Catch a Smuggler" + + Chunk Initial Download ---------------------- diff --git a/src/ytdl_sub/prebuilt_presets/helpers/filtering.yaml b/src/ytdl_sub/prebuilt_presets/helpers/filtering.yaml new file mode 100644 index 000000000..b964cc8c3 --- /dev/null +++ b/src/ytdl_sub/prebuilt_presets/helpers/filtering.yaml @@ -0,0 +1,52 @@ +presets: + + ############################################################################# + # Include Keywords + # Include or exclude media with any of the listed keywords in their titles + # Keywords will check a lower-cased title or description + Filter Keywords: + overrides: + # default filter lists to be empty + title_include_keywords: "{ [] }" + title_exclude_keywords: "{ [] }" + description_include_keywords: "{ [] }" + description_exclude_keywords: "{ [] }" + + "%ensure_string": >- + { + %assert_then( + %is_string($0), + %lower($0), + "filter keywords must be strings" + ) + } + "%ensure_lower_array": >- + { + %assert_then( + %is_array($0), + %array_apply( + $0, + %ensure_string + ), + %concat($1," must be an array") + ) + } + + # $0 - var to evaluate + # $1 - keyword list + # $2 - variable name for error messages + # $3 - default return if keyword list is empty + "%contains_keywords": >- + { + %if( + %bool( $1 ), + %contains_any( %lower($0), %ensure_lower_array($1, $2) ), + $3 + ) + } + + filter_exclude: + - "{ %not( %contains_keywords(title, title_include_keywords, 'title_include_keywords', true) ) }" + - "{ %not( %contains_keywords(description, description_include_keywords, 'description_include_keywords', true) ) }" + - "{ %contains_keywords(title, title_exclude_keywords, 'title_exclude_keywords', false) }" + - "{ %contains_keywords(description, description_exclude_keywords, 'description_exclude_keywords',false) }" \ No newline at end of file diff --git a/tests/integration/prebuilt_presets/test_filter_keywords.py b/tests/integration/prebuilt_presets/test_filter_keywords.py new file mode 100644 index 000000000..5c68cbf57 --- /dev/null +++ b/tests/integration/prebuilt_presets/test_filter_keywords.py @@ -0,0 +1,130 @@ +import re + +import pytest + +from expected_transaction_log import assert_transaction_log_matches +from ytdl_sub.subscriptions.subscription import Subscription +from ytdl_sub.utils.exceptions import ValidationException + + +@pytest.fixture +def filter_subscription_dict(output_directory): + return { + "preset": [ + "Plex TV Show by Date", + "Filter Keywords", + ], + "overrides": { + "url": "https://your.name.here", + "tv_show_directory": output_directory + } + } + +class TestFilterKeywords: + + def test_no_overrides( + self, + config, + filter_subscription_dict, + output_directory, + subscription_name, + mock_download_collection_entries, + ): + subscription = Subscription.from_dict( + config=config, + preset_name=subscription_name, + preset_dict=filter_subscription_dict, + ) + + with mock_download_collection_entries( + is_youtube_channel=False, num_urls=1, is_dry_run=True + ): + transaction_log = subscription.download(dry_run=True) + + assert_transaction_log_matches( + output_directory=output_directory, + transaction_log=transaction_log, + transaction_log_summary_file_name=f"integration/prebuilt_presets/filter_keywords_empty.txt", + ) + + @pytest.mark.parametrize("filter_mode", ["include", "exclude"]) + def test_title( + self, + config, + filter_subscription_dict, + output_directory, + subscription_name, + mock_download_collection_entries, + filter_mode: str, + ): + filter_subscription_dict["overrides"][f"title_{filter_mode}_keywords"] = [ + "not included", + "MOCK ENTRY 20-3" + ] + subscription = Subscription.from_dict( + config=config, + preset_name=subscription_name, + preset_dict=filter_subscription_dict, + ) + + with mock_download_collection_entries( + is_youtube_channel=False, num_urls=1, is_dry_run=True + ): + transaction_log = subscription.download(dry_run=True) + + assert_transaction_log_matches( + output_directory=output_directory, + transaction_log=transaction_log, + transaction_log_summary_file_name=f"integration/prebuilt_presets/filter_keywords_{filter_mode}.txt", + ) + + @pytest.mark.parametrize("filter_mode", ["include", "exclude"]) + def test_description( + self, + config, + filter_subscription_dict, + output_directory, + subscription_name, + mock_download_collection_entries, + filter_mode: str, + ): + filter_subscription_dict["overrides"][f"description_{filter_mode}_keywords"] = [ + "not included", + "MOCK ENTRY 20-3" + ] + subscription = Subscription.from_dict( + config=config, + preset_name=subscription_name, + preset_dict=filter_subscription_dict, + ) + + with mock_download_collection_entries( + is_youtube_channel=False, num_urls=1, is_dry_run=True + ): + transaction_log = subscription.download(dry_run=True) + + assert_transaction_log_matches( + output_directory=output_directory, + transaction_log=transaction_log, + transaction_log_summary_file_name=f"integration/prebuilt_presets/filter_keywords_{filter_mode}.txt", + ) + + def test_error_not_list_type( + self, + config, + filter_subscription_dict, + output_directory, + subscription_name, + mock_download_collection_entries, + ): + filter_subscription_dict["overrides"][f"description_include_keywords"] = "not list" + subscription = Subscription.from_dict( + config=config, + preset_name=subscription_name, + preset_dict=filter_subscription_dict, + ) + + with mock_download_collection_entries( + is_youtube_channel=False, num_urls=1, is_dry_run=True + ): + transaction_log = subscription.download(dry_run=True) \ No newline at end of file diff --git a/tests/resources.py b/tests/resources.py index 8a426c9e2..bb9808fda 100644 --- a/tests/resources.py +++ b/tests/resources.py @@ -2,7 +2,7 @@ import shutil from pathlib import Path -REGENERATE_FIXTURES: bool = False +REGENERATE_FIXTURES: bool = True RESOURCE_PATH: Path = Path("tests") / "resources" _FILE_FIXTURE_PATH: Path = RESOURCE_PATH / "file_fixtures" diff --git a/tests/resources/transaction_log_summaries/integration/prebuilt_presets/filter_keywords_empty.txt b/tests/resources/transaction_log_summaries/integration/prebuilt_presets/filter_keywords_empty.txt new file mode 100644 index 000000000..8c3ebf9a3 --- /dev/null +++ b/tests/resources/transaction_log_summaries/integration/prebuilt_presets/filter_keywords_empty.txt @@ -0,0 +1,66 @@ +Files created: +---------------------------------------- +{output_directory} + .ytdl-sub-subscription_test-download-archive.json +{output_directory}/Season 2020 + s2020.e080701 - Mock Entry 20-3-thumb.jpg + s2020.e080701 - Mock Entry 20-3.info.json + s2020.e080701 - Mock Entry 20-3.mp4 + Video Tags: + contentRating: TV-14 + date: 2020-08-07 + episode_id: 80701 + genre: ytdl-sub + show: subscription_test + synopsis: + https://20-3.com + + The Description + title: 2020-08-07 - Mock Entry 20-3 + year: 2020 + s2020.e080801 - Mock Entry 20-2-thumb.jpg + s2020.e080801 - Mock Entry 20-2.info.json + s2020.e080801 - Mock Entry 20-2.mp4 + Video Tags: + contentRating: TV-14 + date: 2020-08-08 + episode_id: 80801 + genre: ytdl-sub + show: subscription_test + synopsis: + https://20-2.com + + The Description + title: 2020-08-08 - Mock Entry 20-2 + year: 2020 + s2020.e080802 - Mock Entry 20-1-thumb.jpg + s2020.e080802 - Mock Entry 20-1.info.json + s2020.e080802 - Mock Entry 20-1.mp4 + Video Tags: + contentRating: TV-14 + date: 2020-08-08 + episode_id: 80802 + genre: ytdl-sub + show: subscription_test + synopsis: + https://20-1.com + + The Description + title: 2020-08-08 - Mock Entry 20-1 + year: 2020 +{output_directory}/Season 2021 + s2021.e080801 - Mock Entry 21-1-thumb.jpg + s2021.e080801 - Mock Entry 21-1.info.json + s2021.e080801 - Mock Entry 21-1.mp4 + Video Tags: + contentRating: TV-14 + date: 2021-08-08 + episode_id: 80801 + genre: ytdl-sub + show: subscription_test + synopsis: + https://21-1.com + + The Description + title: 2021-08-08 - Mock Entry 21-1 + year: 2021 \ No newline at end of file diff --git a/tests/resources/transaction_log_summaries/integration/prebuilt_presets/filter_keywords_exclude.txt b/tests/resources/transaction_log_summaries/integration/prebuilt_presets/filter_keywords_exclude.txt new file mode 100644 index 000000000..8c3ebf9a3 --- /dev/null +++ b/tests/resources/transaction_log_summaries/integration/prebuilt_presets/filter_keywords_exclude.txt @@ -0,0 +1,66 @@ +Files created: +---------------------------------------- +{output_directory} + .ytdl-sub-subscription_test-download-archive.json +{output_directory}/Season 2020 + s2020.e080701 - Mock Entry 20-3-thumb.jpg + s2020.e080701 - Mock Entry 20-3.info.json + s2020.e080701 - Mock Entry 20-3.mp4 + Video Tags: + contentRating: TV-14 + date: 2020-08-07 + episode_id: 80701 + genre: ytdl-sub + show: subscription_test + synopsis: + https://20-3.com + + The Description + title: 2020-08-07 - Mock Entry 20-3 + year: 2020 + s2020.e080801 - Mock Entry 20-2-thumb.jpg + s2020.e080801 - Mock Entry 20-2.info.json + s2020.e080801 - Mock Entry 20-2.mp4 + Video Tags: + contentRating: TV-14 + date: 2020-08-08 + episode_id: 80801 + genre: ytdl-sub + show: subscription_test + synopsis: + https://20-2.com + + The Description + title: 2020-08-08 - Mock Entry 20-2 + year: 2020 + s2020.e080802 - Mock Entry 20-1-thumb.jpg + s2020.e080802 - Mock Entry 20-1.info.json + s2020.e080802 - Mock Entry 20-1.mp4 + Video Tags: + contentRating: TV-14 + date: 2020-08-08 + episode_id: 80802 + genre: ytdl-sub + show: subscription_test + synopsis: + https://20-1.com + + The Description + title: 2020-08-08 - Mock Entry 20-1 + year: 2020 +{output_directory}/Season 2021 + s2021.e080801 - Mock Entry 21-1-thumb.jpg + s2021.e080801 - Mock Entry 21-1.info.json + s2021.e080801 - Mock Entry 21-1.mp4 + Video Tags: + contentRating: TV-14 + date: 2021-08-08 + episode_id: 80801 + genre: ytdl-sub + show: subscription_test + synopsis: + https://21-1.com + + The Description + title: 2021-08-08 - Mock Entry 21-1 + year: 2021 \ No newline at end of file diff --git a/tests/resources/transaction_log_summaries/integration/prebuilt_presets/filter_keywords_include.txt b/tests/resources/transaction_log_summaries/integration/prebuilt_presets/filter_keywords_include.txt new file mode 100644 index 000000000..7192b6c7a --- /dev/null +++ b/tests/resources/transaction_log_summaries/integration/prebuilt_presets/filter_keywords_include.txt @@ -0,0 +1 @@ +No new, modified, or removed files in '{output_directory}' \ No newline at end of file From ecdc786e1ce17773b31aaee379b42aebdcdeef4e Mon Sep 17 00:00:00 2001 From: Jesse Bannon Date: Sat, 5 Oct 2024 00:21:40 -0700 Subject: [PATCH 2/5] [FEATURE] `Filter Keywords` prebuilt preset --- .../script/functions/error_functions.py | 17 ++-- src/ytdl_sub/script/types/function.py | 2 +- src/ytdl_sub/script/utils/type_checking.py | 4 + .../prebuilt_presets/test_filter_keywords.py | 87 ++++++++++++++----- tests/resources.py | 2 +- ...> description_filter_keywords_exclude.txt} | 0 ...> description_filter_keywords_include.txt} | 0 .../title_filter_keywords_exclude.txt | 51 +++++++++++ .../title_filter_keywords_include.txt | 20 +++++ 9 files changed, 151 insertions(+), 32 deletions(-) rename tests/resources/transaction_log_summaries/integration/prebuilt_presets/{filter_keywords_include.txt => description_filter_keywords_exclude.txt} (100%) rename tests/resources/transaction_log_summaries/integration/prebuilt_presets/{filter_keywords_exclude.txt => description_filter_keywords_include.txt} (100%) create mode 100644 tests/resources/transaction_log_summaries/integration/prebuilt_presets/title_filter_keywords_exclude.txt create mode 100644 tests/resources/transaction_log_summaries/integration/prebuilt_presets/title_filter_keywords_include.txt diff --git a/src/ytdl_sub/script/functions/error_functions.py b/src/ytdl_sub/script/functions/error_functions.py index 3a1be9f50..34b92a742 100644 --- a/src/ytdl_sub/script/functions/error_functions.py +++ b/src/ytdl_sub/script/functions/error_functions.py @@ -20,9 +20,10 @@ def assert_(value: ReturnableArgument, assert_message: String) -> ReturnableArgu Explicitly throw an error with the provided assert message if ``value`` evaluates to False. If it evaluates to True, it will return ``value``. """ - if not bool(value.value): + evaluated_val = value.value() + if not bool(evaluated_val.value): raise UserThrownRuntimeError(assert_message) - return value + return evaluated_val @staticmethod def assert_then( @@ -35,7 +36,7 @@ def assert_then( """ if not bool(value.value): raise UserThrownRuntimeError(assert_message) - return ret + return ret.value() @staticmethod def assert_eq( @@ -46,9 +47,10 @@ def assert_eq( Explicitly throw an error with the provided assert message if ``value`` does not equal ``equals``. If they do equal, then return ``value``. """ - if not value.value == equals.value: + evaluated_val = value.value() + if not evaluated_val.value == equals.value: raise UserThrownRuntimeError(assert_message) - return value + return evaluated_val @staticmethod def assert_ne( @@ -59,6 +61,7 @@ def assert_ne( Explicitly throw an error with the provided assert message if ``value`` equals ``equals``. If they do equal, then return ``value``. """ - if value.value == equals.value: + evaluated_value = value.value() + if evaluated_value.value == equals.value: raise UserThrownRuntimeError(assert_message) - return value + return evaluated_value diff --git a/src/ytdl_sub/script/types/function.py b/src/ytdl_sub/script/types/function.py index a61fc7d46..7ecd19995 100644 --- a/src/ytdl_sub/script/types/function.py +++ b/src/ytdl_sub/script/types/function.py @@ -259,7 +259,7 @@ def resolve( resolved_variables: Dict[Variable, Resolvable], custom_functions: Dict[str, "VariableDependency"], ) -> Resolvable: - # TODO: Make conditionals not execute all branches!!! + # Ensure conditionals do not execute all branches conditional_return_args = self.function_spec.conditional_arg_indices( num_input_args=len(self.args) ) diff --git a/src/ytdl_sub/script/utils/type_checking.py b/src/ytdl_sub/script/utils/type_checking.py index 2489760b1..e8a8bc79e 100644 --- a/src/ytdl_sub/script/utils/type_checking.py +++ b/src/ytdl_sub/script/utils/type_checking.py @@ -208,6 +208,10 @@ def conditional_arg_indices(self, num_input_args: int) -> List[int]: return list(range(1, num_input_args, 2)) + [num_input_args - 1] if self.function_name == "if_passthrough": return [0, 1] # true-passthrough, false-passthrough + if self.function_name in ("assert", "assert_eq", "assert_ne"): + return [0] + if self.function_name == "assert_then": + return [1] return [] @property diff --git a/tests/integration/prebuilt_presets/test_filter_keywords.py b/tests/integration/prebuilt_presets/test_filter_keywords.py index 5c68cbf57..41761b031 100644 --- a/tests/integration/prebuilt_presets/test_filter_keywords.py +++ b/tests/integration/prebuilt_presets/test_filter_keywords.py @@ -1,8 +1,9 @@ import re import pytest - from expected_transaction_log import assert_transaction_log_matches + +from ytdl_sub.script.utils.exceptions import UserThrownRuntimeError from ytdl_sub.subscriptions.subscription import Subscription from ytdl_sub.utils.exceptions import ValidationException @@ -14,12 +15,10 @@ def filter_subscription_dict(output_directory): "Plex TV Show by Date", "Filter Keywords", ], - "overrides": { - "url": "https://your.name.here", - "tv_show_directory": output_directory - } + "overrides": {"url": "https://your.name.here", "tv_show_directory": output_directory}, } + class TestFilterKeywords: def test_no_overrides( @@ -36,7 +35,7 @@ def test_no_overrides( preset_dict=filter_subscription_dict, ) - with mock_download_collection_entries( + with mock_download_collection_entries( is_youtube_channel=False, num_urls=1, is_dry_run=True ): transaction_log = subscription.download(dry_run=True) @@ -59,7 +58,7 @@ def test_title( ): filter_subscription_dict["overrides"][f"title_{filter_mode}_keywords"] = [ "not included", - "MOCK ENTRY 20-3" + "MOCK ENTRY 20-3", ] subscription = Subscription.from_dict( config=config, @@ -67,7 +66,7 @@ def test_title( preset_dict=filter_subscription_dict, ) - with mock_download_collection_entries( + with mock_download_collection_entries( is_youtube_channel=False, num_urls=1, is_dry_run=True ): transaction_log = subscription.download(dry_run=True) @@ -75,7 +74,7 @@ def test_title( assert_transaction_log_matches( output_directory=output_directory, transaction_log=transaction_log, - transaction_log_summary_file_name=f"integration/prebuilt_presets/filter_keywords_{filter_mode}.txt", + transaction_log_summary_file_name=f"integration/prebuilt_presets/title_filter_keywords_{filter_mode}.txt", ) @pytest.mark.parametrize("filter_mode", ["include", "exclude"]) @@ -89,8 +88,8 @@ def test_description( filter_mode: str, ): filter_subscription_dict["overrides"][f"description_{filter_mode}_keywords"] = [ - "not included", - "MOCK ENTRY 20-3" + "no filter here", + "description", ] subscription = Subscription.from_dict( config=config, @@ -98,7 +97,7 @@ def test_description( preset_dict=filter_subscription_dict, ) - with mock_download_collection_entries( + with mock_download_collection_entries( is_youtube_channel=False, num_urls=1, is_dry_run=True ): transaction_log = subscription.download(dry_run=True) @@ -106,25 +105,67 @@ def test_description( assert_transaction_log_matches( output_directory=output_directory, transaction_log=transaction_log, - transaction_log_summary_file_name=f"integration/prebuilt_presets/filter_keywords_{filter_mode}.txt", + transaction_log_summary_file_name=f"integration/prebuilt_presets/description_filter_keywords_{filter_mode}.txt", ) + @pytest.mark.parametrize( + "keyword_variable", + [ + "title_include_keywords", + "title_exclude_keywords", + "description_include_keywords", + "description_exclude_keywords", + ], + ) def test_error_not_list_type( - self, - config, - filter_subscription_dict, - output_directory, - subscription_name, - mock_download_collection_entries, + self, + config, + filter_subscription_dict, + output_directory, + subscription_name, + mock_download_collection_entries, + keyword_variable, ): - filter_subscription_dict["overrides"][f"description_include_keywords"] = "not list" + filter_subscription_dict["overrides"][keyword_variable] = "not array" subscription = Subscription.from_dict( config=config, preset_name=subscription_name, preset_dict=filter_subscription_dict, ) - with mock_download_collection_entries( - is_youtube_channel=False, num_urls=1, is_dry_run=True + with ( + mock_download_collection_entries(is_youtube_channel=False, num_urls=1, is_dry_run=True), + pytest.raises(UserThrownRuntimeError, match=f"{keyword_variable} must be an array"), + ): + _ = subscription.download(dry_run=True) + + @pytest.mark.parametrize( + "keyword_variable", + [ + "title_include_keywords", + "title_exclude_keywords", + "description_include_keywords", + "description_exclude_keywords", + ], + ) + def test_error_not_string_keyword( + self, + config, + filter_subscription_dict, + output_directory, + subscription_name, + mock_download_collection_entries, + keyword_variable, + ): + filter_subscription_dict["overrides"][keyword_variable] = "{['str', ['nested array not']]}" + subscription = Subscription.from_dict( + config=config, + preset_name=subscription_name, + preset_dict=filter_subscription_dict, + ) + + with ( + mock_download_collection_entries(is_youtube_channel=False, num_urls=1, is_dry_run=True), + pytest.raises(UserThrownRuntimeError, match="filter keywords must be strings"), ): - transaction_log = subscription.download(dry_run=True) \ No newline at end of file + _ = subscription.download(dry_run=True) diff --git a/tests/resources.py b/tests/resources.py index bb9808fda..8a426c9e2 100644 --- a/tests/resources.py +++ b/tests/resources.py @@ -2,7 +2,7 @@ import shutil from pathlib import Path -REGENERATE_FIXTURES: bool = True +REGENERATE_FIXTURES: bool = False RESOURCE_PATH: Path = Path("tests") / "resources" _FILE_FIXTURE_PATH: Path = RESOURCE_PATH / "file_fixtures" diff --git a/tests/resources/transaction_log_summaries/integration/prebuilt_presets/filter_keywords_include.txt b/tests/resources/transaction_log_summaries/integration/prebuilt_presets/description_filter_keywords_exclude.txt similarity index 100% rename from tests/resources/transaction_log_summaries/integration/prebuilt_presets/filter_keywords_include.txt rename to tests/resources/transaction_log_summaries/integration/prebuilt_presets/description_filter_keywords_exclude.txt diff --git a/tests/resources/transaction_log_summaries/integration/prebuilt_presets/filter_keywords_exclude.txt b/tests/resources/transaction_log_summaries/integration/prebuilt_presets/description_filter_keywords_include.txt similarity index 100% rename from tests/resources/transaction_log_summaries/integration/prebuilt_presets/filter_keywords_exclude.txt rename to tests/resources/transaction_log_summaries/integration/prebuilt_presets/description_filter_keywords_include.txt diff --git a/tests/resources/transaction_log_summaries/integration/prebuilt_presets/title_filter_keywords_exclude.txt b/tests/resources/transaction_log_summaries/integration/prebuilt_presets/title_filter_keywords_exclude.txt new file mode 100644 index 000000000..36d8f389a --- /dev/null +++ b/tests/resources/transaction_log_summaries/integration/prebuilt_presets/title_filter_keywords_exclude.txt @@ -0,0 +1,51 @@ +Files created: +---------------------------------------- +{output_directory} + .ytdl-sub-subscription_test-download-archive.json +{output_directory}/Season 2020 + s2020.e080801 - Mock Entry 20-2-thumb.jpg + s2020.e080801 - Mock Entry 20-2.info.json + s2020.e080801 - Mock Entry 20-2.mp4 + Video Tags: + contentRating: TV-14 + date: 2020-08-08 + episode_id: 80801 + genre: ytdl-sub + show: subscription_test + synopsis: + https://20-2.com + + The Description + title: 2020-08-08 - Mock Entry 20-2 + year: 2020 + s2020.e080802 - Mock Entry 20-1-thumb.jpg + s2020.e080802 - Mock Entry 20-1.info.json + s2020.e080802 - Mock Entry 20-1.mp4 + Video Tags: + contentRating: TV-14 + date: 2020-08-08 + episode_id: 80802 + genre: ytdl-sub + show: subscription_test + synopsis: + https://20-1.com + + The Description + title: 2020-08-08 - Mock Entry 20-1 + year: 2020 +{output_directory}/Season 2021 + s2021.e080801 - Mock Entry 21-1-thumb.jpg + s2021.e080801 - Mock Entry 21-1.info.json + s2021.e080801 - Mock Entry 21-1.mp4 + Video Tags: + contentRating: TV-14 + date: 2021-08-08 + episode_id: 80801 + genre: ytdl-sub + show: subscription_test + synopsis: + https://21-1.com + + The Description + title: 2021-08-08 - Mock Entry 21-1 + year: 2021 \ No newline at end of file diff --git a/tests/resources/transaction_log_summaries/integration/prebuilt_presets/title_filter_keywords_include.txt b/tests/resources/transaction_log_summaries/integration/prebuilt_presets/title_filter_keywords_include.txt new file mode 100644 index 000000000..cf4f5275b --- /dev/null +++ b/tests/resources/transaction_log_summaries/integration/prebuilt_presets/title_filter_keywords_include.txt @@ -0,0 +1,20 @@ +Files created: +---------------------------------------- +{output_directory} + .ytdl-sub-subscription_test-download-archive.json +{output_directory}/Season 2020 + s2020.e080701 - Mock Entry 20-3-thumb.jpg + s2020.e080701 - Mock Entry 20-3.info.json + s2020.e080701 - Mock Entry 20-3.mp4 + Video Tags: + contentRating: TV-14 + date: 2020-08-07 + episode_id: 80701 + genre: ytdl-sub + show: subscription_test + synopsis: + https://20-3.com + + The Description + title: 2020-08-07 - Mock Entry 20-3 + year: 2020 \ No newline at end of file From 5581183aec8f5b937e8ad6a092e8cb378c35e431 Mon Sep 17 00:00:00 2001 From: Jesse Bannon Date: Sat, 5 Oct 2024 00:28:47 -0700 Subject: [PATCH 3/5] better docs --- docs/source/faq/index.rst | 7 ++++++- docs/source/prebuilt_presets/helpers.rst | 25 ++++++++++++------------ 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/docs/source/faq/index.rst b/docs/source/faq/index.rst index 1822194f3..f8ae66532 100644 --- a/docs/source/faq/index.rst +++ b/docs/source/faq/index.rst @@ -55,7 +55,12 @@ See `yt-dl's recommended way ` +See the prebuilt preset :doc:`chunk_initial_download `. + +...filter to include or exclude based on certain keywords? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +See the prebuilt preset :doc:`Filter Keywords `. There is a bug where... ----------------------- diff --git a/docs/source/prebuilt_presets/helpers.rst b/docs/source/prebuilt_presets/helpers.rst index 6f67693f2..80c76ef10 100644 --- a/docs/source/prebuilt_presets/helpers.rst +++ b/docs/source/prebuilt_presets/helpers.rst @@ -48,19 +48,20 @@ Include or exclude media with any of the listed keywords in their titles. Both k Tilda mode allows override variables to be set directly underneath it. .. code-block:: yaml - Plex TV Show by Date: - = Documentaries: - "~NOVA PBS": - url: "https://www.youtube.com/@novapbs" - title_exclude_keywords: - - "preview" - - "trailer" - - "~To Catch a Smuggler": - url: "https://www.youtube.com/@NatGeo" - title_include_keywords: - - "To Catch a Smuggler" + Plex TV Show by Date | Filter Keywords: + + = Documentaries: + "~NOVA PBS": + url: "https://www.youtube.com/@novapbs" + title_exclude_keywords: + - "preview" + - "trailer" + + "~To Catch a Smuggler": + url: "https://www.youtube.com/@NatGeo" + title_include_keywords: + - "To Catch a Smuggler" Chunk Initial Download From a746cbd7bc3febecd64aaaa6df7d50f623f88fdd Mon Sep 17 00:00:00 2001 From: Jesse Bannon Date: Sat, 5 Oct 2024 00:44:57 -0700 Subject: [PATCH 4/5] docs --- docs/source/prebuilt_presets/helpers.rst | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/source/prebuilt_presets/helpers.rst b/docs/source/prebuilt_presets/helpers.rst index 80c76ef10..c4a36f055 100644 --- a/docs/source/prebuilt_presets/helpers.rst +++ b/docs/source/prebuilt_presets/helpers.rst @@ -38,9 +38,14 @@ Add the following preset to download the best available audio and video quality, Filter Keywords --------------- -Include or exclude media with any of the listed keywords in their titles. Both keywords and title/description are lower-cased before filtering. +``Filter Keywords`` can include or exclude media with any of the listed keywords in their titles. Both keywords and title/description are lower-cased before filtering. -``Filter Keywords`` +Supports the following override variables: + +* ``title_include_keywords`` +* ``title_exclude_keywords`` +* ``description_include_keywords`` +* ``description_exclude_keywords`` .. tip:: From 37db996f5915d94a0eaf4a6f931de50f1ab1721a Mon Sep 17 00:00:00 2001 From: Jesse Bannon Date: Sat, 5 Oct 2024 00:46:03 -0700 Subject: [PATCH 5/5] docs --- docs/source/prebuilt_presets/helpers.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/prebuilt_presets/helpers.rst b/docs/source/prebuilt_presets/helpers.rst index c4a36f055..fa6d25f9f 100644 --- a/docs/source/prebuilt_presets/helpers.rst +++ b/docs/source/prebuilt_presets/helpers.rst @@ -38,7 +38,7 @@ Add the following preset to download the best available audio and video quality, Filter Keywords --------------- -``Filter Keywords`` can include or exclude media with any of the listed keywords in their titles. Both keywords and title/description are lower-cased before filtering. +``Filter Keywords`` can include or exclude media with any of the listed keywords. Both keywords and title/description are lower-cased before filtering. Supports the following override variables: