From d3295cef86ec4367996d1a258283f32549c9ee76 Mon Sep 17 00:00:00 2001 From: Jesse Bannon Date: Mon, 18 Nov 2024 00:22:20 -0800 Subject: [PATCH 1/9] [BUGFIX] Do not perform nested scripting on file path outputs (#1123) Fixes a bug where curly braces in file-names causes scripting to think its a variable that does not exist --- src/ytdl_sub/utils/file_path.py | 6 +++++ .../validators/file_path_validators.py | 24 ++++--------------- tests/e2e/test_debug_repro.py | 5 ++-- .../validators/test_file_path_validators.py | 10 ++++---- 4 files changed, 17 insertions(+), 28 deletions(-) diff --git a/src/ytdl_sub/utils/file_path.py b/src/ytdl_sub/utils/file_path.py index af8246f1..ff50c991 100644 --- a/src/ytdl_sub/utils/file_path.py +++ b/src/ytdl_sub/utils/file_path.py @@ -1,4 +1,5 @@ import os +import posixpath from pathlib import Path from typing import Tuple @@ -59,3 +60,8 @@ class FilePathTruncater: return str(Path(file_directory) / cls._truncate_file_name(file_name)) return str(file_path) + + @classmethod + def to_native_filepath(cls, file_path: str) -> str: + """Ensures file paths use the correct separator""" + return os.path.expanduser(file_path.replace(posixpath.sep, os.sep)) diff --git a/src/ytdl_sub/validators/file_path_validators.py b/src/ytdl_sub/validators/file_path_validators.py index c255ed1a..f5a69f61 100644 --- a/src/ytdl_sub/validators/file_path_validators.py +++ b/src/ytdl_sub/validators/file_path_validators.py @@ -2,7 +2,7 @@ import os from pathlib import Path from typing import Any -from ytdl_sub.script.script import Script +from ytdl_sub.utils.file_path import FilePathTruncater from ytdl_sub.validators.string_formatter_validators import OverridesStringFormatterValidator from ytdl_sub.validators.string_formatter_validators import StringFormatterValidator from ytdl_sub.validators.validators import StringValidator @@ -45,15 +45,8 @@ class StringFormatterFileNameValidator(StringFormatterValidator): _expected_value_type_name = "filepath" def post_process(self, resolved: str) -> str: - return ( - Script( - { - "tmp_var_1": resolved, - "tmp_var_2": "{%to_native_filepath(%truncate_filepath_if_too_long(tmp_var_1))}", - } - ) - .resolve() - .get_str("tmp_var_2") + return FilePathTruncater.to_native_filepath( + FilePathTruncater.maybe_truncate_file_path(resolved) ) @@ -61,13 +54,6 @@ class OverridesStringFormatterFilePathValidator(OverridesStringFormatterValidato _expected_value_type_name = "static filepath" def post_process(self, resolved: str) -> str: - return ( - Script( - { - "tmp_var_1": resolved, - "tmp_var_2": "{%to_native_filepath(%truncate_filepath_if_too_long(tmp_var_1))}", - } - ) - .resolve() - .get_str("tmp_var_2") + return FilePathTruncater.to_native_filepath( + FilePathTruncater.maybe_truncate_file_path(resolved) ) diff --git a/tests/e2e/test_debug_repro.py b/tests/e2e/test_debug_repro.py index b96f530b..8587dd5c 100644 --- a/tests/e2e/test_debug_repro.py +++ b/tests/e2e/test_debug_repro.py @@ -1,4 +1,3 @@ -import json from typing import Dict import pytest @@ -44,13 +43,13 @@ class TestReproduce: def test_debug_log_repro( self, default_config, - repro_preset_dict, + debug_log_rerpo, output_directory, ): sub = Subscription.from_dict( config=default_config, preset_name="repro", - preset_dict=repro_preset_dict, + preset_dict=debug_log_rerpo, ) transaction_log = sub.download(dry_run=False) diff --git a/tests/unit/validators/test_file_path_validators.py b/tests/unit/validators/test_file_path_validators.py index 7ff62143..467f7b80 100644 --- a/tests/unit/validators/test_file_path_validators.py +++ b/tests/unit/validators/test_file_path_validators.py @@ -54,19 +54,17 @@ class TestStringFormatterFilePathValidator: if "thumb" not in ext: # do not put . in front of -thumb ext = f".{ext}" # pytest args with . in the beginning act weird - base_file_name = "s2023.e031701 - 𝗪𝗔𝗥𝗡𝗜𝗡𝗚: LG Secretly Overhaul This OLED Feature on C3 & G3… Should You Buy C2 Instead?" + base_file_name = "s2023.e031701 - 𝗪𝗔𝗥𝗡𝗜𝗡𝗚: {LG} Secretly Overhaul This OLED Feature on C3 & G3… Should You Buy C2 Instead?" with tempfile.TemporaryDirectory() as temp_dir: file_path = str(Path(temp_dir) / f"{base_file_name}{ext}") - formatter = StringFormatterFileNameValidator(name="test", value=str(file_path)) - truncated_file_path = formatter.post_process( - Script({"file_name": formatter.format_string}).resolve().get_str("file_name") - ) + formatter = StringFormatterFileNameValidator(name="test", value="") + truncated_file_path = formatter.post_process(file_path) assert truncated_file_path == str( Path(temp_dir) - / f"s2023.e031701 - 𝗪𝗔𝗥𝗡𝗜𝗡𝗚: LG Secretly Overhaul This OLED Feature on C3 & G3… Should You Buy C2 Instead?{ext}" + / f"s2023.e031701 - 𝗪𝗔𝗥𝗡𝗜𝗡𝗚: {{LG}} Secretly Overhaul This OLED Feature on C3 & G3… Should You Buy C2 Instead?{ext}" ) # Ensure it can actually open the file From a6341971ffb2ea08c8b675d99dfced3c659f4af6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Nov 2024 18:06:52 -0800 Subject: [PATCH 2/9] [DEV] Update pytest-rerunfailures requirement from ~=14.0 to >=14,<16 (#1125) Updates the requirements on [pytest-rerunfailures](https://github.com/pytest-dev/pytest-rerunfailures) to permit the latest version. - [Changelog](https://github.com/pytest-dev/pytest-rerunfailures/blob/master/CHANGES.rst) - [Commits](https://github.com/pytest-dev/pytest-rerunfailures/compare/14.0...15.0) --- updated-dependencies: - dependency-name: pytest-rerunfailures dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index dd14f164..b18d7378 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,7 +44,7 @@ where = ["src"] test = [ "coverage[toml]>=6.3,<8.0", "pytest>=7.2,<9.0", - "pytest-rerunfailures~=14.0", + "pytest-rerunfailures>=14,<16", ] lint = [ "black==24.10.0", From 8c3f8528ad87d196f4d5cde8fb99f63e4dc78abd Mon Sep 17 00:00:00 2001 From: Jesse Bannon Date: Sun, 24 Nov 2024 15:28:36 -0800 Subject: [PATCH 3/9] [BACKEND] More media quality presets + docs (#1127) Adds common media quality prebuilt presets and documentation on how to use them --- docs/source/prebuilt_presets/helpers.rst | 31 +---------------- docs/source/prebuilt_presets/index.rst | 29 +++++++++++++--- .../source/prebuilt_presets/media_quality.rst | 29 ++++++++++++++++ .../helpers/media_quality.yaml | 34 ++++++++++++++++++- 4 files changed, 88 insertions(+), 35 deletions(-) create mode 100644 docs/source/prebuilt_presets/media_quality.rst diff --git a/docs/source/prebuilt_presets/helpers.rst b/docs/source/prebuilt_presets/helpers.rst index a4b141c6..7f70c243 100644 --- a/docs/source/prebuilt_presets/helpers.rst +++ b/docs/source/prebuilt_presets/helpers.rst @@ -4,21 +4,7 @@ Helper Presets .. hint:: - Apply presets to your subscriptions using pipes: - - .. code-block:: yaml - :caption: Pipes can separate presets and values to apply them to all subscriptions below them. - - Plex TV Show by Date | best_video_quality: - - = Documentaries | chunk_initial_download: - "NOVA PBS": "https://www.youtube.com/@novapbs" - "National Geographic": "https://www.youtube.com/@NatGeo" - - = Documentaries: - "Cosmos - What If": "https://www.youtube.com/playlist?list=PLZdXRHYAVxTJno6oFF9nLGuwXNGYHmE8U" - -Common presets are not usable by themselves- setting one of these as the sole preset of your subscription and attempting to download will not work. But you can add these presets to quickly modify an existing preset to better suit your needs. + See how to apply helper presets :doc:`here ` Only Recent ----------- @@ -42,21 +28,6 @@ upload date is outside of the range, or you hit max files, older videos will be To prevent deletion of files, use the preset ``Only Recent Archive`` instead. -Best A/V Quality ----------------- - -Add the following preset to download the best available video and audio quality, and remux it into an MP4 container: - -``best_video_quality`` - - -Max 1080p Video ---------------- - -Add the following preset to download the best available audio and video quality, with the video not greater than 1080p, and remux it into an MP4 container: - -``max_1080p`` - Filter Keywords --------------- diff --git a/docs/source/prebuilt_presets/index.rst b/docs/source/prebuilt_presets/index.rst index 744428ce..bb95ac0c 100644 --- a/docs/source/prebuilt_presets/index.rst +++ b/docs/source/prebuilt_presets/index.rst @@ -3,13 +3,34 @@ Prebuilt Presets ================ ``ytdl-sub`` offers a number of built-in presets using best practices for formatting -media in various players. For advanced users, you can review the prebuilt preset +media in various players. + +.. hint:: + + Apply multiple presets to your subscriptions using pipes. Pipes can define multiple presets and values + on the same line to apply to all subscriptions nested below them. + + .. code-block:: yaml + :caption: Applies Max Video Quality preset to all TV shows, and Chunk Downloads preset to some + + Plex TV Show by Date | Max Video Quality: + + = Documentaries | Chunk Downloads: + "NOVA PBS": "https://www.youtube.com/@novapbs" + "National Geographic": "https://www.youtube.com/@NatGeo" + + = Documentaries: + "Cosmos - What If": "https://www.youtube.com/playlist?list=PLZdXRHYAVxTJno6oFF9nLGuwXNGYHmE8U" + + +For advanced users, you can review the prebuilt preset definitions :doc:`here `. .. toctree:: :titlesonly: - - helpers + tv_shows music - music_videos \ No newline at end of file + music_videos + media_quality + helpers \ No newline at end of file diff --git a/docs/source/prebuilt_presets/media_quality.rst b/docs/source/prebuilt_presets/media_quality.rst new file mode 100644 index 00000000..ceb92479 --- /dev/null +++ b/docs/source/prebuilt_presets/media_quality.rst @@ -0,0 +1,29 @@ +====================== +Media Quality Presets +====================== + +.. hint:: + + See how to apply media quality presets :doc:`here ` + +Video +----- +The following presets set video quality specifications to yt-dlp. + +- ``Max Video Quality`` +- ``Max 2160p`` +- ``Max 1440p`` +- ``Max 1080p`` +- ``Max 720p`` +- ``Max 480p`` + +Audio +----- +The following presets set audio quality specifications to yt-dlp. +These assume you are only extracting audio (no video). + +- ``Max Audio Quality``, format is determined by the source +- ``Max MP3 Quality`` +- ``Max Opus Quality`` +- ``MP3 320k`` +- ``MP3 128k`` diff --git a/src/ytdl_sub/prebuilt_presets/helpers/media_quality.yaml b/src/ytdl_sub/prebuilt_presets/helpers/media_quality.yaml index a4c35dc9..78b99ca4 100644 --- a/src/ytdl_sub/prebuilt_presets/helpers/media_quality.yaml +++ b/src/ytdl_sub/prebuilt_presets/helpers/media_quality.yaml @@ -13,6 +13,10 @@ presets: preset: - best_video_quality + "Max Video Quality": + preset: + - best_video_quality + ############################################################################# # Max 2160p @@ -55,4 +59,32 @@ presets: "Max 480p": format: "(bv*[height<=480]+bestaudio/best[height<=480])" ytdl_options: - merge_output_format: "mp4" \ No newline at end of file + merge_output_format: "mp4" + + ############################################################################# + # Audio Quality Presets + + "Max Audio Quality": + audio_extract: + codec: "best" + quality: 0 + + "Max MP3 Quality": + audio_extract: + codec: "mp3" + quality: 0 + + "Max Opus Quality": + audio_extract: + codec: "opus" + quality: 0 + + "MP3 320k": + audio_extract: + codec: "mp3" + quality: 320 + + "MP3 128k": + audio_extract: + codec: "mp3" + quality: 128 From 53d84d8c1e2bb73403e7cbe5c713e3017b3e9e48 Mon Sep 17 00:00:00 2001 From: Jesse Bannon Date: Tue, 26 Nov 2024 08:20:42 -0800 Subject: [PATCH 4/9] [FEATURE] Toggleable keyword evaluation behavior (#1130) With the `Filter Keywords` prebuilt preset, can now set keyword evaluation to be either `ANY` or `ALL`. More info here: https://ytdl-sub.readthedocs.io/en/latest/prebuilt_presets/helpers.html#filter-keywords --- .../scripting/scripting_functions.rst | 7 ++ docs/source/prebuilt_presets/helpers.rst | 17 ++- .../prebuilt_presets/helpers/filtering.yaml | 34 ++++-- .../script/functions/string_functions.py | 14 +++ .../prebuilt_presets/test_filter_keywords.py | 100 +++++++++++++++++- .../script/functions/test_string_functions.py | 8 ++ 6 files changed, 166 insertions(+), 14 deletions(-) diff --git a/docs/source/config_reference/scripting/scripting_functions.rst b/docs/source/config_reference/scripting/scripting_functions.rst index a12b0ebd..cc42c52c 100644 --- a/docs/source/config_reference/scripting/scripting_functions.rst +++ b/docs/source/config_reference/scripting/scripting_functions.rst @@ -646,6 +646,13 @@ contains :description: Returns True if ``contains`` is in ``string``. False otherwise. +contains_all +~~~~~~~~~~~~ +:spec: ``contains_all(string: String, contains_array: Array) -> Boolean`` + +:description: + Returns true if all elements in ``contains_array`` are in ``string``. False otherwise. + contains_any ~~~~~~~~~~~~ :spec: ``contains_any(string: String, contains_array: Array) -> Boolean`` diff --git a/docs/source/prebuilt_presets/helpers.rst b/docs/source/prebuilt_presets/helpers.rst index 7f70c243..e8e37c31 100644 --- a/docs/source/prebuilt_presets/helpers.rst +++ b/docs/source/prebuilt_presets/helpers.rst @@ -33,12 +33,14 @@ Filter Keywords ``Filter Keywords`` can include or exclude media with any of the listed keywords. Both keywords and title/description are lower-cased before filtering. +Default behavior for Keyword evaluation is ANY, meaning the filter will succeed if any of the keywords are present. This can be set to ANY or ALL using the respective ``_eval`` variable. + Supports the following override variables: -* ``title_include_keywords`` -* ``title_exclude_keywords`` -* ``description_include_keywords`` -* ``description_exclude_keywords`` +* ``title_include_keywords``, ``title_include_eval`` +* ``title_exclude_keywords``, ``title_exclude_eval`` +* ``description_include_keywords``, ``title_exclude_eval`` +* ``description_exclude_keywords``, ``title_exclude_eval`` .. tip:: @@ -61,6 +63,13 @@ Supports the following override variables: title_include_keywords: - "To Catch a Smuggler" + = Sports: + "~Maple Leafs Highlights": + url: "https://www.youtube.com/@NHL" + title_include_eval: "ALL" + title_include_keywords: + - "maple leafs" + - "highlights" Chunk Downloads --------------- diff --git a/src/ytdl_sub/prebuilt_presets/helpers/filtering.yaml b/src/ytdl_sub/prebuilt_presets/helpers/filtering.yaml index b964cc8c..4d99e93e 100644 --- a/src/ytdl_sub/prebuilt_presets/helpers/filtering.yaml +++ b/src/ytdl_sub/prebuilt_presets/helpers/filtering.yaml @@ -12,6 +12,11 @@ presets: description_include_keywords: "{ [] }" description_exclude_keywords: "{ [] }" + title_include_eval: "ANY" + title_exclude_eval: "ANY" + description_include_eval: "ANY" + description_exclude_eval: "ANY" + "%ensure_string": >- { %assert_then( @@ -32,21 +37,36 @@ presets: ) } + # $0 - var to evaluate + # $1 - keyword list + # $2 - eval type + "%contains_keywords_inner": >- + { + %elif( + %eq(%ensure_string($2), 'any'), + %contains_any( $0, $1 ), + %eq(%ensure_string($2), 'all'), + %contains_all( $0, $1 ), + %throw('Keyword eval must be either ANY or ALL') + ) + } + # $0 - var to evaluate # $1 - keyword list # $2 - variable name for error messages - # $3 - default return if keyword list is empty + # $3 - keyword eval + # $4 - default return if keyword list is empty "%contains_keywords": >- { %if( %bool( $1 ), - %contains_any( %lower($0), %ensure_lower_array($1, $2) ), - $3 + %contains_keywords_inner( %lower($0), %ensure_lower_array($1, $2), $3 ), + $4 ) } 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 + - "{ %not( %contains_keywords(title, title_include_keywords, 'title_include_keywords', title_include_eval, true) ) }" + - "{ %not( %contains_keywords(description, description_include_keywords, 'description_include_keywords', description_include_eval, true) ) }" + - "{ %contains_keywords(title, title_exclude_keywords, 'title_exclude_keywords', title_exclude_eval, false) }" + - "{ %contains_keywords(description, description_exclude_keywords, 'description_exclude_keywords', description_exclude_eval, false) }" \ No newline at end of file diff --git a/src/ytdl_sub/script/functions/string_functions.py b/src/ytdl_sub/script/functions/string_functions.py index c2977db0..e9af7a54 100644 --- a/src/ytdl_sub/script/functions/string_functions.py +++ b/src/ytdl_sub/script/functions/string_functions.py @@ -40,6 +40,20 @@ class StringFunctions: ) ) + @staticmethod + def contains_all(string: String, contains_array: Array) -> Boolean: + """ + :description: + Returns true if all elements in ``contains_array`` are in ``string``. False otherwise. + """ + return Boolean( + all( + str(val) in string.value + for val in contains_array.value + if isinstance(val, (String, Integer, Boolean, Float)) + ) + ) + @staticmethod def slice(string: String, start: Integer, end: Optional[Integer] = None) -> String: """ diff --git a/tests/integration/prebuilt_presets/test_filter_keywords.py b/tests/integration/prebuilt_presets/test_filter_keywords.py index 41761b03..733f27b6 100644 --- a/tests/integration/prebuilt_presets/test_filter_keywords.py +++ b/tests/integration/prebuilt_presets/test_filter_keywords.py @@ -1,11 +1,8 @@ -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 @pytest.fixture @@ -77,6 +74,39 @@ class TestFilterKeywords: transaction_log_summary_file_name=f"integration/prebuilt_presets/title_filter_keywords_{filter_mode}.txt", ) + @pytest.mark.parametrize("filter_mode", ["include", "exclude"]) + def test_title_all( + self, + config, + filter_subscription_dict, + output_directory, + subscription_name, + mock_download_collection_entries, + filter_mode: str, + ): + filter_subscription_dict["overrides"][f"title_{filter_mode}_eval"] = "all" + filter_subscription_dict["overrides"][f"title_{filter_mode}_keywords"] = [ + "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/title_filter_keywords_{filter_mode}.txt", + ) + @pytest.mark.parametrize("filter_mode", ["include", "exclude"]) def test_description( self, @@ -108,6 +138,38 @@ class TestFilterKeywords: transaction_log_summary_file_name=f"integration/prebuilt_presets/description_filter_keywords_{filter_mode}.txt", ) + @pytest.mark.parametrize("filter_mode", ["include", "exclude"]) + def test_description_all( + self, + config, + filter_subscription_dict, + output_directory, + subscription_name, + mock_download_collection_entries, + filter_mode: str, + ): + filter_subscription_dict["overrides"][f"description_{filter_mode}_eval"] = "ALL" + filter_subscription_dict["overrides"][f"description_{filter_mode}_keywords"] = [ + "descr", + "iption", + ] + 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/description_filter_keywords_{filter_mode}.txt", + ) + @pytest.mark.parametrize( "keyword_variable", [ @@ -169,3 +231,35 @@ class TestFilterKeywords: pytest.raises(UserThrownRuntimeError, match="filter keywords must be strings"), ): _ = subscription.download(dry_run=True) + + @pytest.mark.parametrize( + "keyword_variable", + [ + "title_include", + "title_exclude", + "description_include", + "description_exclude", + ], + ) + def test_error_not_correct_eval( + self, + config, + filter_subscription_dict, + output_directory, + subscription_name, + mock_download_collection_entries, + keyword_variable, + ): + filter_subscription_dict["overrides"][f"{keyword_variable}_keywords"] = ["hmm"] + filter_subscription_dict["overrides"][f"{keyword_variable}_eval"] = "LOL" + 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="Keyword eval must be either ANY or ALL"), + ): + _ = subscription.download(dry_run=True) diff --git a/tests/unit/script/functions/test_string_functions.py b/tests/unit/script/functions/test_string_functions.py index a5a2961d..f5c85741 100644 --- a/tests/unit/script/functions/test_string_functions.py +++ b/tests/unit/script/functions/test_string_functions.py @@ -126,6 +126,14 @@ class TestNumericFunctions: output = single_variable_output(f"{{%contains_any('a brown dog', {value})}}") assert output == expected_output + @pytest.mark.parametrize( + "value, expected_output", + [("['a', 'b', 'c']", False), ("['nope', [], {}]", False), ("['a', 'dog']", True)], + ) + def test_contains_all(self, value, expected_output): + output = single_variable_output(f"{{%contains_all('a brown dog', {value})}}") + assert output == expected_output + @pytest.mark.parametrize( "input_string, split, max_split, expected_output", [ From 3bf31a5e079c432725fa6a5612176a5ce3b0f488 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 23:18:33 -0800 Subject: [PATCH 5/9] [DEV] Bump pylint from 3.3.1 to 3.3.2 (#1132) Bumps [pylint](https://github.com/pylint-dev/pylint) from 3.3.1 to 3.3.2. - [Release notes](https://github.com/pylint-dev/pylint/releases) - [Commits](https://github.com/pylint-dev/pylint/compare/v3.3.1...v3.3.2) --- updated-dependencies: - dependency-name: pylint dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index b18d7378..da745545 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -49,7 +49,7 @@ test = [ lint = [ "black==24.10.0", "isort==5.13.2", - "pylint==3.3.1", + "pylint==3.3.2", ] docs = [ "sphinx>=7,<9", From d83523ffe539a3958a429f284d8da5bb1b061a04 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 23:18:49 -0800 Subject: [PATCH 6/9] [DEV] Update twine requirement from ~=5.0 to >=5,<7 (#1133) Updates the requirements on [twine](https://github.com/pypa/twine) to permit the latest version. - [Release notes](https://github.com/pypa/twine/releases) - [Changelog](https://github.com/pypa/twine/blob/main/docs/changelog.rst) - [Commits](https://github.com/pypa/twine/compare/5.0.0...6.0.1) --- updated-dependencies: - dependency-name: twine dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index da745545..6117cd5d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -60,7 +60,7 @@ docs = [ ] build = [ "build~=1.2", - "twine~=5.0", + "twine>=5,<7", "pyinstaller~=6.5", ] [project.scripts] From d84310a13cdea3259e2450fa6b12a5aa818231e4 Mon Sep 17 00:00:00 2001 From: Jesse Bannon Date: Tue, 3 Dec 2024 18:16:51 -0800 Subject: [PATCH 7/9] [BACKEND] Update yt-dlp to 2024.12.3 (#1135) --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 6117cd5d..6a917d19 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,7 +15,7 @@ classifiers = [ "Programming Language :: Python :: 3.11", ] dependencies = [ - "yt-dlp[default]==2024.11.4", + "yt-dlp[default]==2024.12.3", "colorama~=0.4", "mergedeep~=1.3", "mediafile~=0.12", From d06ad079162c9e108779d3ffed96fd22e39d1525 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 Dec 2024 08:50:58 -0800 Subject: [PATCH 8/9] [BACKEND] Bump yt-dlp[default] from 2024.12.3 to 2024.12.6 (#1136) Bumps [yt-dlp[default]](https://github.com/yt-dlp/yt-dlp) from 2024.12.3 to 2024.12.6. - [Release notes](https://github.com/yt-dlp/yt-dlp/releases) - [Changelog](https://github.com/yt-dlp/yt-dlp/blob/master/Changelog.md) - [Commits](https://github.com/yt-dlp/yt-dlp/compare/2024.12.03...2024.12.06) --- updated-dependencies: - dependency-name: yt-dlp[default] dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 6a917d19..63f9279d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,7 +15,7 @@ classifiers = [ "Programming Language :: Python :: 3.11", ] dependencies = [ - "yt-dlp[default]==2024.12.3", + "yt-dlp[default]==2024.12.6", "colorama~=0.4", "mergedeep~=1.3", "mediafile~=0.12", From ebe99083616c7b3ec3a1490b1c3c789c625c77cd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Dec 2024 21:35:00 -0800 Subject: [PATCH 9/9] Bump yt-dlp[default] from 2024.12.6 to 2024.12.13 (#1138) Bumps [yt-dlp[default]](https://github.com/yt-dlp/yt-dlp) from 2024.12.6 to 2024.12.13. - [Release notes](https://github.com/yt-dlp/yt-dlp/releases) - [Changelog](https://github.com/yt-dlp/yt-dlp/blob/master/Changelog.md) - [Commits](https://github.com/yt-dlp/yt-dlp/compare/2024.12.06...2024.12.13) --- updated-dependencies: - dependency-name: yt-dlp[default] dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 63f9279d..8ad1494a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,7 +15,7 @@ classifiers = [ "Programming Language :: Python :: 3.11", ] dependencies = [ - "yt-dlp[default]==2024.12.6", + "yt-dlp[default]==2024.12.13", "colorama~=0.4", "mergedeep~=1.3", "mediafile~=0.12",