[FEATURE] Arg to shuffle subscriptions (#1263)

Closes https://github.com/jmbannon/ytdl-sub/issues/1234

Adds `--shuffle` support which shuffles the order of subscriptions when downloading.
This commit is contained in:
Jesse Bannon 2026-02-02 10:23:08 -08:00 committed by GitHub
parent c163f9766a
commit ced547b14a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 59 additions and 0 deletions

View file

@ -1,5 +1,6 @@
import gc
import os
import random
import sys
from datetime import datetime
from pathlib import Path
@ -75,6 +76,7 @@ def _download_subscriptions_from_yaml_files(
subscription_override_dict: Dict,
update_with_info_json: bool,
dry_run: bool,
shuffle: bool,
) -> List[Subscription]:
"""
Downloads all subscriptions from one or many subscription yaml files.
@ -91,6 +93,8 @@ def _download_subscriptions_from_yaml_files(
Whether to actually download or update using existing info json
dry_run
Whether to dry run or not
shuffle
Whether to shuffle the subscription download order
Returns
-------
@ -112,6 +116,10 @@ def _download_subscriptions_from_yaml_files(
subscription_override_dict=subscription_override_dict,
)
if shuffle:
logger.info("Shuffling subscriptions")
random.shuffle(subscriptions)
for subscription in subscriptions:
with subscription.exception_handling():
logger.info(
@ -253,6 +261,7 @@ def main() -> List[Subscription]:
subscription_override_dict=subscription_override_dict,
update_with_info_json=args.update_with_info_json,
dry_run=args.dry_run,
shuffle=args.shuffle,
)
# One-off download

View file

@ -172,6 +172,10 @@ class SubArguments:
short="-o",
long="--dl-override",
)
SHUFFLE = CLIArgument(
short="-sh",
long="--shuffle",
)
subscription_parser = subparsers.add_parser("sub")
@ -197,6 +201,13 @@ subscription_parser.add_argument(
help="override all subscription config values using `dl` syntax, "
"i.e. --dl-override='--ytdl_options.max_downloads 3'",
)
subscription_parser.add_argument(
SubArguments.SHUFFLE.short,
SubArguments.SHUFFLE.long,
action="store_true",
help="shuffle subscription order when downloading",
default=False,
)
###################################################################################################
# DOWNLOAD PARSER

View file

@ -9,6 +9,7 @@ import pytest
from ytdl_sub.cli.entrypoint import _download_subscriptions_from_yaml_files
from ytdl_sub.cli.entrypoint import main
from ytdl_sub.config.config_file import ConfigFile
from ytdl_sub.subscriptions.subscription import Subscription
from ytdl_sub.utils.exceptions import ExperimentalFeatureNotEnabled
@ -59,6 +60,7 @@ def test_subscription_logs_write_to_file(
subscription_override_dict={},
update_with_info_json=False,
dry_run=dry_run,
shuffle=False,
)
except ValueError:
assert not mock_success_output
@ -120,3 +122,40 @@ def test_update_with_info_json_requires_experimental_flag(
pytest.raises(ExperimentalFeatureNotEnabled),
):
_ = main()
def test_subscription_shuffle(
default_config: ConfigFile,
mock_subscription_download_factory: Callable,
music_video_subscription_path: Path,
):
subscription_paths = [str(music_video_subscription_path)]
with (
patch.object(
Subscription,
"download",
new=mock_subscription_download_factory(mock_success_output=True),
),
):
out1 = _download_subscriptions_from_yaml_files(
config=default_config,
subscription_paths=subscription_paths,
subscription_matches=[],
subscription_override_dict={},
update_with_info_json=False,
dry_run=True,
shuffle=True,
)
out2 = _download_subscriptions_from_yaml_files(
config=default_config,
subscription_paths=subscription_paths,
subscription_matches=[],
subscription_override_dict={},
update_with_info_json=False,
dry_run=True,
shuffle=True,
)
assert [sub.name for sub in out1] != [sub.name for sub in out2]