[FEATURE] Add --dl-override to pass dl arg overrides to all subscriptions (#882)
With both `--match` and `--dl-override`, it is now possible to more easily experiment with subscriptions without needing to create a separate file. For example, suppose you are changing some values in your subscription "Rick A" and want to test them out. You can now run: ``` ytdl-sub sub --dry-run --match Rick --dl-override '--ytdl-options.max_downloads 3' ``` This will 1. Dry-run 2. Only run for the subscription "Rick A" 3. Apply setting max_downloads to 3
This commit is contained in:
parent
9382be5c42
commit
78cdcce464
6 changed files with 75 additions and 2 deletions
|
|
@ -3,6 +3,7 @@ import os
|
|||
import sys
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import Dict
|
||||
from typing import List
|
||||
from typing import Optional
|
||||
|
||||
|
|
@ -70,6 +71,7 @@ def _download_subscriptions_from_yaml_files(
|
|||
config: ConfigFile,
|
||||
subscription_paths: List[str],
|
||||
subscription_matches: List[str],
|
||||
subscription_override_dict: Dict,
|
||||
update_with_info_json: bool,
|
||||
dry_run: bool,
|
||||
) -> List[Subscription]:
|
||||
|
|
@ -102,7 +104,11 @@ def _download_subscriptions_from_yaml_files(
|
|||
|
||||
# Load all the subscriptions first to perform all validation before downloading
|
||||
for path in subscription_paths:
|
||||
subscriptions += Subscription.from_file_path(config=config, subscription_path=path)
|
||||
subscriptions += Subscription.from_file_path(
|
||||
config=config,
|
||||
subscription_path=path,
|
||||
subscription_override_dict=subscription_override_dict,
|
||||
)
|
||||
|
||||
if subscriptions and subscription_matches:
|
||||
logger.info("Filtering subscriptions by name based on --match arguments")
|
||||
|
|
@ -233,11 +239,18 @@ def main() -> List[Subscription]:
|
|||
"full backup before usage. You have been warned!",
|
||||
)
|
||||
|
||||
subscription_override_dict = {}
|
||||
if args.dl_override:
|
||||
subscription_override_dict = DownloadArgsParser.from_dl_override(
|
||||
override=args.dl_override, config=config
|
||||
).to_subscription_dict()
|
||||
|
||||
logger.info("Validating subscriptions...")
|
||||
subscriptions = _download_subscriptions_from_yaml_files(
|
||||
config=config,
|
||||
subscription_paths=args.subscription_paths,
|
||||
subscription_matches=args.match,
|
||||
subscription_override_dict=subscription_override_dict,
|
||||
update_with_info_json=args.update_with_info_json,
|
||||
dry_run=args.dry_run,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ from typing import Tuple
|
|||
from mergedeep import mergedeep
|
||||
|
||||
from ytdl_sub.cli.parsers.main import MainArguments
|
||||
from ytdl_sub.config.config_file import ConfigFile
|
||||
from ytdl_sub.config.config_validator import ConfigOptions
|
||||
from ytdl_sub.utils.exceptions import InvalidDlArguments
|
||||
|
||||
|
|
@ -247,3 +248,12 @@ class DownloadArgsParser:
|
|||
"""
|
||||
hash_string = str(sorted(self._unknown_arguments))
|
||||
return hashlib.sha256(hash_string.encode()).hexdigest()[-8:]
|
||||
|
||||
@classmethod
|
||||
def from_dl_override(cls, override: str, config: ConfigFile) -> "DownloadArgsParser":
|
||||
"""
|
||||
Create a DownloadArgsParser from a sub --override argument value
|
||||
"""
|
||||
return DownloadArgsParser(
|
||||
extra_arguments=override.split(), config_options=config.config_options
|
||||
)
|
||||
|
|
|
|||
|
|
@ -157,6 +157,10 @@ class SubArguments:
|
|||
short="-u",
|
||||
long="--update-with-info-json",
|
||||
)
|
||||
OVERRIDE = CLIArgument(
|
||||
short="-o",
|
||||
long="--dl-override",
|
||||
)
|
||||
|
||||
|
||||
subscription_parser = subparsers.add_parser("sub")
|
||||
|
|
@ -175,6 +179,13 @@ subscription_parser.add_argument(
|
|||
help="update all subscriptions with the current config using info.json files",
|
||||
default=False,
|
||||
)
|
||||
subscription_parser.add_argument(
|
||||
SubArguments.OVERRIDE.short,
|
||||
SubArguments.OVERRIDE.long,
|
||||
type=str,
|
||||
help="override all subscription config values using `dl` syntax, "
|
||||
"i.e. --dl-override='--ytdl_options.max_downloads 3'",
|
||||
)
|
||||
|
||||
###################################################################################################
|
||||
# DOWNLOAD PARSER
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@ from pathlib import Path
|
|||
from typing import Any
|
||||
from typing import Dict
|
||||
from typing import List
|
||||
from typing import Optional
|
||||
|
||||
from mergedeep import mergedeep
|
||||
|
||||
from ytdl_sub.config.config_file import ConfigFile
|
||||
from ytdl_sub.config.preset import Preset
|
||||
|
|
@ -69,7 +72,10 @@ class Subscription(SubscriptionDownload):
|
|||
|
||||
@classmethod
|
||||
def from_file_path(
|
||||
cls, config: ConfigFile, subscription_path: str | Path
|
||||
cls,
|
||||
config: ConfigFile,
|
||||
subscription_path: str | Path,
|
||||
subscription_override_dict: Optional[Dict] = None,
|
||||
) -> List["Subscription"]:
|
||||
"""
|
||||
Loads subscriptions from a file.
|
||||
|
|
@ -80,6 +86,8 @@ class Subscription(SubscriptionDownload):
|
|||
Validated instance of the config
|
||||
subscription_path:
|
||||
File path to the subscription yaml file
|
||||
subscription_override_dict:
|
||||
Optional dict containing overrides to every subscription
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
|
@ -122,6 +130,13 @@ class Subscription(SubscriptionDownload):
|
|||
)
|
||||
|
||||
for subscription_key, subscription_object in subscriptions_dicts.items():
|
||||
# Hard-override subscriptions here
|
||||
mergedeep.merge(
|
||||
subscription_object,
|
||||
subscription_override_dict or {},
|
||||
strategy=mergedeep.Strategy.ADDITIVE,
|
||||
)
|
||||
|
||||
subscriptions.append(
|
||||
cls.from_dict(
|
||||
config=config,
|
||||
|
|
|
|||
|
|
@ -199,3 +199,26 @@ class TestPlaylist:
|
|||
dry_run=dry_run,
|
||||
expected_download_summary_file_name="youtube/test_playlist.json",
|
||||
)
|
||||
|
||||
def test_playlist_download_from_cli_sub_with_override_arg(
|
||||
self,
|
||||
preset_dict_to_subscription_yaml_generator,
|
||||
playlist_preset_dict,
|
||||
output_directory,
|
||||
):
|
||||
# TODO: Fix CLI parsing on windows when dealing with spaces
|
||||
if IS_WINDOWS:
|
||||
return
|
||||
|
||||
# No config needed when using only prebuilt presets
|
||||
with preset_dict_to_subscription_yaml_generator(
|
||||
subscription_name="music_video_playlist_test", preset_dict=playlist_preset_dict
|
||||
) as subscription_path:
|
||||
args = (
|
||||
f"--dry-run sub '{subscription_path}' --dl-override '--date_range.after 20240101'"
|
||||
)
|
||||
|
||||
subscriptions = mock_run_from_cli(args=args)
|
||||
|
||||
assert len(subscriptions) == 1
|
||||
assert subscriptions[0].transaction_log.is_empty
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ def test_subscription_logs_write_to_file(
|
|||
config=config,
|
||||
subscription_paths=subscription_paths,
|
||||
subscription_matches=match,
|
||||
subscription_override_dict={},
|
||||
update_with_info_json=False,
|
||||
dry_run=dry_run,
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue