[DEV] More OutputOption unit tests (#1082)
This commit is contained in:
parent
ed4a2814b9
commit
c0ba30b220
24 changed files with 663 additions and 297 deletions
|
|
@ -161,7 +161,7 @@ def _download_subscription_from_cli(
|
|||
extra_arguments=extra_args, config_options=config.config_options
|
||||
)
|
||||
subscription_args_dict = dl_args_parser.to_subscription_dict()
|
||||
subscription_name = f"cli-dl-{dl_args_parser.get_args_hash()}"
|
||||
subscription_name = dl_args_parser.get_dl_subscription_name()
|
||||
|
||||
subscription = Subscription.from_dict(
|
||||
config=config, preset_name=subscription_name, preset_dict=subscription_args_dict
|
||||
|
|
|
|||
|
|
@ -242,12 +242,13 @@ class DownloadArgsParser:
|
|||
|
||||
return subscription_dict
|
||||
|
||||
def get_args_hash(self) -> str:
|
||||
def get_dl_subscription_name(self) -> str:
|
||||
"""
|
||||
:return: Hash of the arguments provided
|
||||
Returns a deterministic name based on input args
|
||||
"""
|
||||
hash_string = str(sorted(self._unknown_arguments))
|
||||
return hashlib.sha256(hash_string.encode()).hexdigest()[-8:]
|
||||
to_hash = str(sorted(self._unknown_arguments))
|
||||
hash_str = hashlib.sha256(to_hash.encode()).hexdigest()[-8:]
|
||||
return f"cli-dl-{hash_str}"
|
||||
|
||||
@classmethod
|
||||
def from_dl_override(cls, override: str, config: ConfigFile) -> "DownloadArgsParser":
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@ import contextlib
|
|||
import json
|
||||
import logging
|
||||
import os
|
||||
import shlex
|
||||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
|
@ -18,8 +20,10 @@ from resources import copy_file_fixture
|
|||
from resources import file_fixture_path
|
||||
from yt_dlp.utils import sanitize_filename
|
||||
|
||||
from ytdl_sub.cli.entrypoint import main
|
||||
from ytdl_sub.config.config_file import ConfigFile
|
||||
from ytdl_sub.entries.script.custom_functions import CustomFunctions
|
||||
from ytdl_sub.subscriptions.subscription import Subscription
|
||||
from ytdl_sub.subscriptions.subscription_download import SubscriptionDownload
|
||||
from ytdl_sub.utils.file_handler import FileHandler
|
||||
from ytdl_sub.utils.logger import Logger
|
||||
|
|
@ -262,3 +266,9 @@ def default_config_path(default_config) -> str:
|
|||
@pytest.fixture()
|
||||
def music_subscriptions_path() -> Path:
|
||||
return Path("examples/music_subscriptions.yaml")
|
||||
|
||||
|
||||
def mock_run_from_cli(args: str) -> List[Subscription]:
|
||||
args_list = ["ytdl-sub"] + shlex.split(args)
|
||||
with patch.object(sys, "argv", args_list):
|
||||
return main()
|
||||
|
|
|
|||
|
|
@ -1,13 +1,7 @@
|
|||
import shlex
|
||||
import sys
|
||||
import tempfile
|
||||
from typing import List
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from ytdl_sub.cli.entrypoint import main
|
||||
from ytdl_sub.subscriptions.subscription import Subscription
|
||||
from ytdl_sub.utils.file_handler import FileHandler
|
||||
|
||||
|
||||
|
|
@ -31,9 +25,3 @@ def timestamps_file_path():
|
|||
yield tmp.name
|
||||
finally:
|
||||
FileHandler.delete(tmp.name)
|
||||
|
||||
|
||||
def mock_run_from_cli(args: str) -> List[Subscription]:
|
||||
args_list = ["ytdl-sub"] + shlex.split(args)
|
||||
with patch.object(sys, "argv", args_list):
|
||||
return main()
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
from typing import Optional
|
||||
|
||||
import pytest
|
||||
from e2e.conftest import mock_run_from_cli
|
||||
from conftest import mock_run_from_cli
|
||||
|
||||
from ytdl_sub.utils.file_handler import FileMetadata
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,13 @@
|
|||
from pathlib import Path
|
||||
from typing import Dict
|
||||
|
||||
import pytest
|
||||
from conftest import assert_logs
|
||||
from e2e.conftest import mock_run_from_cli
|
||||
from expected_download import assert_expected_downloads
|
||||
from expected_transaction_log import assert_transaction_log_matches
|
||||
from mergedeep import mergedeep
|
||||
|
||||
from ytdl_sub.config.config_file import ConfigFile
|
||||
from ytdl_sub.downloaders.ytdlp import YTDLP
|
||||
from ytdl_sub.subscriptions.subscription import Subscription
|
||||
from ytdl_sub.utils.system import IS_WINDOWS
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
|
@ -100,50 +96,6 @@ class TestPlaylist:
|
|||
files exist and have the expected md5 file hashes.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def _ensure_subscription_migrates(
|
||||
cls,
|
||||
config: ConfigFile,
|
||||
subscription_name: str,
|
||||
subscription_dict: Dict,
|
||||
output_directory: Path,
|
||||
):
|
||||
# Ensure download archive migrates
|
||||
mergedeep.merge(
|
||||
subscription_dict,
|
||||
{
|
||||
"output_options": {
|
||||
"migrated_download_archive_name": ".ytdl-sub-{tv_show_name_sanitized}-download-archive.json"
|
||||
}
|
||||
},
|
||||
)
|
||||
migrated_subscription = Subscription.from_dict(
|
||||
config=config,
|
||||
preset_name=subscription_name,
|
||||
preset_dict=subscription_dict,
|
||||
)
|
||||
transaction_log = migrated_subscription.download()
|
||||
|
||||
assert_transaction_log_matches(
|
||||
output_directory=output_directory,
|
||||
transaction_log=transaction_log,
|
||||
transaction_log_summary_file_name="youtube/test_playlist_archive_migrated.txt",
|
||||
)
|
||||
assert_expected_downloads(
|
||||
output_directory=output_directory,
|
||||
dry_run=False,
|
||||
expected_download_summary_file_name="youtube/test_playlist_archive_migrated.json",
|
||||
)
|
||||
|
||||
# Ensure no changes after migration
|
||||
transaction_log = migrated_subscription.download()
|
||||
assert transaction_log.is_empty
|
||||
assert_expected_downloads(
|
||||
output_directory=output_directory,
|
||||
dry_run=False,
|
||||
expected_download_summary_file_name="youtube/test_playlist_archive_migrated.json",
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize("dry_run", [True, False])
|
||||
def test_playlist_download(
|
||||
self,
|
||||
|
|
@ -186,86 +138,6 @@ class TestPlaylist:
|
|||
expected_download_summary_file_name="youtube/test_playlist.json",
|
||||
)
|
||||
|
||||
self._ensure_subscription_migrates(
|
||||
config=default_config,
|
||||
subscription_name="music_video_playlist_test",
|
||||
subscription_dict=playlist_preset_dict,
|
||||
output_directory=output_directory,
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize("dry_run", [True, False])
|
||||
def test_playlist_download_from_cli_sub_no_provided_config(
|
||||
self,
|
||||
preset_dict_to_subscription_yaml_generator,
|
||||
playlist_preset_dict,
|
||||
output_directory,
|
||||
dry_run,
|
||||
):
|
||||
# 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 = "--dry-run " if dry_run else ""
|
||||
args += f"sub '{subscription_path}'"
|
||||
subscriptions = mock_run_from_cli(args=args)
|
||||
|
||||
assert len(subscriptions) == 1
|
||||
transaction_log = subscriptions[0].transaction_log
|
||||
|
||||
assert_transaction_log_matches(
|
||||
output_directory=output_directory,
|
||||
transaction_log=transaction_log,
|
||||
transaction_log_summary_file_name="youtube/test_playlist.txt",
|
||||
)
|
||||
assert_expected_downloads(
|
||||
output_directory=output_directory,
|
||||
dry_run=dry_run,
|
||||
expected_download_summary_file_name="youtube/test_playlist.json",
|
||||
)
|
||||
|
||||
if not dry_run:
|
||||
# Ensure another invocation will hit ExistingVideoReached
|
||||
with assert_logs(
|
||||
logger=YTDLP.logger,
|
||||
expected_message="ExistingVideoReached, stopping additional downloads",
|
||||
log_level="debug",
|
||||
):
|
||||
transaction_log = mock_run_from_cli(args=args)[0].transaction_log
|
||||
|
||||
assert transaction_log.is_empty
|
||||
assert_expected_downloads(
|
||||
output_directory=output_directory,
|
||||
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
|
||||
|
||||
def test_tv_show_by_date_downloads_bilateral(
|
||||
self,
|
||||
tv_show_by_date_bilateral_dict: Dict,
|
||||
|
|
|
|||
|
|
@ -1,17 +1,9 @@
|
|||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
from conftest import preset_dict_to_dl_args
|
||||
from e2e.conftest import mock_run_from_cli
|
||||
from expected_download import assert_expected_downloads
|
||||
from expected_transaction_log import assert_transaction_log_matches
|
||||
|
||||
from ytdl_sub.downloaders.ytdlp import YTDLP
|
||||
from ytdl_sub.entries.entry import Entry
|
||||
from ytdl_sub.subscriptions.subscription import Subscription
|
||||
from ytdl_sub.utils.file_handler import FileHandler
|
||||
from ytdl_sub.utils.system import IS_WINDOWS
|
||||
from ytdl_sub.utils.thumbnail import try_convert_download_thumbnail
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
|
@ -69,72 +61,3 @@ class TestYoutubeVideo:
|
|||
dry_run=dry_run,
|
||||
expected_download_summary_file_name="youtube/test_video.json",
|
||||
)
|
||||
|
||||
def test_single_video_download_missing_thumbnail(
|
||||
self,
|
||||
default_config,
|
||||
single_video_preset_dict,
|
||||
working_directory,
|
||||
output_directory,
|
||||
):
|
||||
single_video_subscription = Subscription.from_dict(
|
||||
config=default_config,
|
||||
preset_name="music_video_single_video_test",
|
||||
preset_dict=single_video_preset_dict,
|
||||
)
|
||||
|
||||
def delete_entry_thumb(entry: Entry) -> None:
|
||||
FileHandler.delete(entry.get_download_thumbnail_path())
|
||||
try_convert_download_thumbnail(entry=entry)
|
||||
|
||||
# Pretend the thumbnail did not download via returning nothing for its downloaded path
|
||||
with (
|
||||
patch.object(YTDLP, "_EXTRACT_ENTRY_NUM_RETRIES", 1),
|
||||
patch.object(Entry, "try_get_ytdlp_download_thumbnail_path") as mock_ytdlp_path,
|
||||
patch(
|
||||
"ytdl_sub.downloaders.url.downloader.try_convert_download_thumbnail",
|
||||
side_effect=delete_entry_thumb,
|
||||
),
|
||||
):
|
||||
mock_ytdlp_path.return_value = None
|
||||
transaction_log = single_video_subscription.download(dry_run=False)
|
||||
|
||||
assert_transaction_log_matches(
|
||||
output_directory=output_directory,
|
||||
transaction_log=transaction_log,
|
||||
transaction_log_summary_file_name="youtube/test_video_missing_thumb.txt",
|
||||
)
|
||||
assert_expected_downloads(
|
||||
output_directory=output_directory,
|
||||
dry_run=False,
|
||||
expected_download_summary_file_name="youtube/test_video_missing_thumb.json",
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize("dry_run", [True, False])
|
||||
def test_single_video_download_from_cli_dl(
|
||||
self,
|
||||
default_config_path,
|
||||
single_video_preset_dict_dl_args,
|
||||
output_directory,
|
||||
dry_run,
|
||||
):
|
||||
# TODO: Fix CLI parsing on windows when dealing with spaces
|
||||
if IS_WINDOWS:
|
||||
return
|
||||
|
||||
args = "--dry-run " if dry_run else ""
|
||||
args += f"--config {default_config_path} "
|
||||
args += f"dl {single_video_preset_dict_dl_args}"
|
||||
subscriptions = mock_run_from_cli(args=args)
|
||||
|
||||
assert len(subscriptions) == 1
|
||||
assert_transaction_log_matches(
|
||||
output_directory=output_directory,
|
||||
transaction_log=subscriptions[0].transaction_log,
|
||||
transaction_log_summary_file_name="youtube/test_video_cli.txt",
|
||||
)
|
||||
assert_expected_downloads(
|
||||
output_directory=output_directory,
|
||||
dry_run=dry_run,
|
||||
expected_download_summary_file_name="youtube/test_video_cli.json",
|
||||
)
|
||||
|
|
|
|||
73
tests/integration/cli/test_dl.py
Normal file
73
tests/integration/cli/test_dl.py
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
from typing import Dict
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
from conftest import mock_run_from_cli
|
||||
from conftest import preset_dict_to_dl_args
|
||||
from expected_download import assert_expected_downloads
|
||||
from expected_transaction_log import assert_transaction_log_matches
|
||||
|
||||
from ytdl_sub.cli.parsers.dl import DownloadArgsParser
|
||||
from ytdl_sub.utils.system import IS_WINDOWS
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def dl_subscription_dict(output_directory) -> Dict:
|
||||
return {
|
||||
"preset": "Jellyfin Music Videos",
|
||||
"overrides": {
|
||||
"music_video_artist": "JMC",
|
||||
"music_video_directory": output_directory,
|
||||
"url": "https://your.name.here",
|
||||
},
|
||||
"nfo_tags": {"tags": {"custom_tag": "{%array_at( ['hi', 'mom'], 1 )}"}},
|
||||
}
|
||||
|
||||
|
||||
class TestCliDl:
|
||||
@pytest.mark.parametrize("config_provided", [True, False])
|
||||
@pytest.mark.parametrize("dry_run", [True, False])
|
||||
def test_cli_dl_command(
|
||||
self,
|
||||
default_config_path: str,
|
||||
subscription_name: str,
|
||||
dl_subscription_dict: Dict,
|
||||
output_directory: str,
|
||||
mock_download_collection_entries,
|
||||
config_provided: bool,
|
||||
dry_run: bool,
|
||||
):
|
||||
# Skip this combo to save time and to avoid mocking working dir
|
||||
if not config_provided and not dry_run:
|
||||
return
|
||||
|
||||
# TODO: Fix CLI parsing on windows when dealing with spaces
|
||||
if IS_WINDOWS:
|
||||
return
|
||||
|
||||
args = "--dry-run " if dry_run else ""
|
||||
args += f"--config {default_config_path} " if config_provided else ""
|
||||
args += f"dl {preset_dict_to_dl_args(dl_subscription_dict)} "
|
||||
|
||||
with (
|
||||
patch.object(DownloadArgsParser, "get_dl_subscription_name") as mock_subscription_name,
|
||||
mock_download_collection_entries(
|
||||
is_youtube_channel=False,
|
||||
num_urls=1,
|
||||
is_extracted_audio=False,
|
||||
is_dry_run=dry_run,
|
||||
),
|
||||
):
|
||||
mock_subscription_name.return_value = subscription_name
|
||||
subscriptions = mock_run_from_cli(args=args)
|
||||
|
||||
assert_transaction_log_matches(
|
||||
output_directory=output_directory,
|
||||
transaction_log=subscriptions[0].transaction_log,
|
||||
transaction_log_summary_file_name="dl/test_cli_dl_command.txt",
|
||||
)
|
||||
assert_expected_downloads(
|
||||
output_directory=output_directory,
|
||||
dry_run=dry_run,
|
||||
expected_download_summary_file_name="dl/test_cli_dl_command.json",
|
||||
)
|
||||
|
|
@ -145,6 +145,8 @@ def mock_download_collection_entries(
|
|||
# Second TV URL or second soundcloud URL, which downloads first
|
||||
is_second_url = "2" in kwargs["url"] or kwargs["url"].endswith("/albums")
|
||||
|
||||
if num_urls == 0:
|
||||
return []
|
||||
if num_urls == 1 or (is_second_url and num_urls > 1):
|
||||
return [
|
||||
mock_entry_dict_factory(
|
||||
|
|
|
|||
|
|
@ -1,11 +1,18 @@
|
|||
from pathlib import Path
|
||||
from typing import Dict
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
from expected_download import assert_expected_downloads
|
||||
from expected_transaction_log import assert_transaction_log_matches
|
||||
from mergedeep import mergedeep
|
||||
|
||||
from ytdl_sub.config.config_file import ConfigFile
|
||||
from ytdl_sub.downloaders.ytdlp import YTDLP
|
||||
from ytdl_sub.entries.entry import Entry
|
||||
from ytdl_sub.subscriptions.subscription import Subscription
|
||||
from ytdl_sub.utils.file_handler import FileHandler
|
||||
from ytdl_sub.utils.thumbnail import try_convert_download_thumbnail
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
|
@ -27,6 +34,110 @@ def output_options_subscription_dict(output_directory) -> Dict:
|
|||
|
||||
|
||||
class TestOutputOptions:
|
||||
|
||||
@classmethod
|
||||
def _ensure_subscription_migrates(
|
||||
cls,
|
||||
config: ConfigFile,
|
||||
subscription_name: str,
|
||||
subscription_dict: Dict,
|
||||
output_directory: Path,
|
||||
):
|
||||
# Ensure download archive migrates
|
||||
mergedeep.merge(
|
||||
subscription_dict,
|
||||
{
|
||||
"output_options": {
|
||||
"migrated_download_archive_name": ".ytdl-sub-{tv_show_name_sanitized}-download-archive.json"
|
||||
}
|
||||
},
|
||||
)
|
||||
migrated_subscription = Subscription.from_dict(
|
||||
config=config,
|
||||
preset_name=subscription_name,
|
||||
preset_dict=subscription_dict,
|
||||
)
|
||||
transaction_log = migrated_subscription.download()
|
||||
|
||||
assert_transaction_log_matches(
|
||||
output_directory=output_directory,
|
||||
transaction_log=transaction_log,
|
||||
transaction_log_summary_file_name="youtube/test_playlist_archive_migrated.txt",
|
||||
)
|
||||
assert_expected_downloads(
|
||||
output_directory=output_directory,
|
||||
dry_run=False,
|
||||
expected_download_summary_file_name="youtube/test_playlist_archive_migrated.json",
|
||||
)
|
||||
|
||||
# Ensure no changes after migration
|
||||
transaction_log = migrated_subscription.download()
|
||||
assert transaction_log.is_empty
|
||||
assert_expected_downloads(
|
||||
output_directory=output_directory,
|
||||
dry_run=False,
|
||||
expected_download_summary_file_name="youtube/test_playlist_archive_migrated.json",
|
||||
)
|
||||
|
||||
def test_download_archive_migration(
|
||||
self,
|
||||
config: ConfigFile,
|
||||
subscription_name: str,
|
||||
output_options_subscription_dict: Dict,
|
||||
output_directory: str,
|
||||
mock_download_collection_entries,
|
||||
):
|
||||
subscription = Subscription.from_dict(
|
||||
config=config,
|
||||
preset_name=subscription_name,
|
||||
preset_dict=output_options_subscription_dict,
|
||||
)
|
||||
|
||||
with mock_download_collection_entries(
|
||||
is_youtube_channel=False,
|
||||
num_urls=1,
|
||||
is_extracted_audio=False,
|
||||
is_dry_run=False,
|
||||
):
|
||||
transaction_log = subscription.download(dry_run=False)
|
||||
|
||||
assert_transaction_log_matches(
|
||||
output_directory=output_directory,
|
||||
transaction_log=transaction_log,
|
||||
transaction_log_summary_file_name="plugins/output_options/pre_migration.txt",
|
||||
)
|
||||
assert_expected_downloads(
|
||||
output_directory=output_directory,
|
||||
dry_run=False,
|
||||
expected_download_summary_file_name="plugins/output_options/pre_migration.json",
|
||||
)
|
||||
|
||||
output_options_subscription_dict["output_options"][
|
||||
"migrated_download_archive_name"
|
||||
] = ".ytdl-sub-{tv_show_name_sanitized}-migrated-download-archive.json"
|
||||
subscription = Subscription.from_dict(
|
||||
config=config,
|
||||
preset_name=subscription_name,
|
||||
preset_dict=output_options_subscription_dict,
|
||||
)
|
||||
|
||||
with mock_download_collection_entries(
|
||||
is_youtube_channel=False,
|
||||
num_urls=0,
|
||||
):
|
||||
transaction_log = subscription.download(dry_run=False)
|
||||
|
||||
assert_transaction_log_matches(
|
||||
output_directory=output_directory,
|
||||
transaction_log=transaction_log,
|
||||
transaction_log_summary_file_name="plugins/output_options/post_migration.txt",
|
||||
)
|
||||
assert_expected_downloads(
|
||||
output_directory=output_directory,
|
||||
dry_run=False,
|
||||
expected_download_summary_file_name="plugins/output_options/post_migration.json",
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize("dry_run", [True, False])
|
||||
def test_empty_info_json_and_thumb(
|
||||
self,
|
||||
|
|
@ -64,3 +175,51 @@ class TestOutputOptions:
|
|||
dry_run=dry_run,
|
||||
expected_download_summary_file_name="plugins/output_options/empty_info_json_thumb.json",
|
||||
)
|
||||
|
||||
def test_missing_thumbnail(
|
||||
self,
|
||||
config: ConfigFile,
|
||||
subscription_name: str,
|
||||
output_options_subscription_dict: Dict,
|
||||
working_directory,
|
||||
output_directory,
|
||||
mock_download_collection_entries,
|
||||
):
|
||||
single_video_subscription = Subscription.from_dict(
|
||||
config=config,
|
||||
preset_name=subscription_name,
|
||||
preset_dict=output_options_subscription_dict,
|
||||
)
|
||||
|
||||
def delete_entry_thumb(entry: Entry) -> None:
|
||||
FileHandler.delete(entry.get_download_thumbnail_path())
|
||||
try_convert_download_thumbnail(entry=entry)
|
||||
|
||||
# Pretend the thumbnail did not download via returning nothing for its downloaded path
|
||||
with (
|
||||
mock_download_collection_entries(
|
||||
is_youtube_channel=False,
|
||||
num_urls=1,
|
||||
is_extracted_audio=False,
|
||||
is_dry_run=False,
|
||||
),
|
||||
patch.object(YTDLP, "_EXTRACT_ENTRY_NUM_RETRIES", 1),
|
||||
patch.object(Entry, "try_get_ytdlp_download_thumbnail_path") as mock_ytdlp_path,
|
||||
patch(
|
||||
"ytdl_sub.downloaders.url.downloader.try_convert_download_thumbnail",
|
||||
side_effect=delete_entry_thumb,
|
||||
),
|
||||
):
|
||||
mock_ytdlp_path.return_value = None
|
||||
transaction_log = single_video_subscription.download(dry_run=False)
|
||||
|
||||
assert_transaction_log_matches(
|
||||
output_directory=output_directory,
|
||||
transaction_log=transaction_log,
|
||||
transaction_log_summary_file_name="plugins/output_options/test_missing_thumb.txt",
|
||||
)
|
||||
assert_expected_downloads(
|
||||
output_directory=output_directory,
|
||||
dry_run=False,
|
||||
expected_download_summary_file_name="plugins/output_options/test_missing_thumb.json",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
".ytdl-sub-subscription_test-download-archive.json": "76e202bd03ceef93daaffffee2cfa193",
|
||||
"JMC/Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"JMC/Mock Entry 20-1.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"JMC/Mock Entry 20-1.mp4": "dbaeb2a3bfd1de1c7e9615e8bdacb910",
|
||||
"JMC/Mock Entry 20-1.nfo": "5d001a105d2380844db181911d5df5c6",
|
||||
"JMC/Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"JMC/Mock Entry 20-2.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"JMC/Mock Entry 20-2.mp4": "76c2c70572489c684923a51cb1b50687",
|
||||
"JMC/Mock Entry 20-2.nfo": "dccdded1ca7ebb38d2c9a0e5130bea33",
|
||||
"JMC/Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"JMC/Mock Entry 20-3.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"JMC/Mock Entry 20-3.mp4": "7bb4f21d59a6fb91836537b27a24e776",
|
||||
"JMC/Mock Entry 20-3.nfo": "7b1eab48693161e83c21203b1308b64e",
|
||||
"JMC/Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"JMC/Mock Entry 21-1.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"JMC/Mock Entry 21-1.mp4": "7b008531ca5660b51fb8adc83c799084",
|
||||
"JMC/Mock Entry 21-1.nfo": "3b4b0e6820f80370d6738ce828f14a89"
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
".ytdl-sub-JMC-migrated-download-archive.json": "456d8882fc5e35d74f19b386d1d9a059",
|
||||
"Season 2020/s2020.e000001 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Season 2020/s2020.e000001 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Season 2020/s2020.e000001 - Mock Entry 20-3.mp4": "7d2ee7fe8003ea63ece37dd2a441c123",
|
||||
"Season 2020/s2020.e000001 - Mock Entry 20-3.nfo": "dbe61f2c8ae41041773f713ba5376726",
|
||||
"Season 2020/s2020.e000002 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Season 2020/s2020.e000002 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Season 2020/s2020.e000002 - Mock Entry 20-2.mp4": "699017cd1b67ae216eda769bef413415",
|
||||
"Season 2020/s2020.e000002 - Mock Entry 20-2.nfo": "0f071078c9fa2569bbcb998664d40681",
|
||||
"Season 2020/s2020.e000003 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Season 2020/s2020.e000003 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Season 2020/s2020.e000003 - Mock Entry 20-1.mp4": "a16741d4fbf657d1de4c50493db14062",
|
||||
"Season 2020/s2020.e000003 - Mock Entry 20-1.nfo": "837a61dca11bbe1874ea07cb8ef8a7c9",
|
||||
"Season 2021/s2021.e000004 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Season 2021/s2021.e000004 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Season 2021/s2021.e000004 - Mock Entry 21-1.mp4": "7433153952b069a5674e2a3ed529b49b",
|
||||
"Season 2021/s2021.e000004 - Mock Entry 21-1.nfo": "8ee3845c514a411425b7e9198666b61c",
|
||||
"tvshow.nfo": "cccca1086b41af04d8ea004b1aa250e8"
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
".ytdl-sub-subscription_test-download-archive.json": "456d8882fc5e35d74f19b386d1d9a059",
|
||||
"Season 2020/s2020.e000001 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Season 2020/s2020.e000001 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Season 2020/s2020.e000001 - Mock Entry 20-3.mp4": "7d2ee7fe8003ea63ece37dd2a441c123",
|
||||
"Season 2020/s2020.e000001 - Mock Entry 20-3.nfo": "dbe61f2c8ae41041773f713ba5376726",
|
||||
"Season 2020/s2020.e000002 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Season 2020/s2020.e000002 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Season 2020/s2020.e000002 - Mock Entry 20-2.mp4": "699017cd1b67ae216eda769bef413415",
|
||||
"Season 2020/s2020.e000002 - Mock Entry 20-2.nfo": "0f071078c9fa2569bbcb998664d40681",
|
||||
"Season 2020/s2020.e000003 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Season 2020/s2020.e000003 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Season 2020/s2020.e000003 - Mock Entry 20-1.mp4": "a16741d4fbf657d1de4c50493db14062",
|
||||
"Season 2020/s2020.e000003 - Mock Entry 20-1.nfo": "837a61dca11bbe1874ea07cb8ef8a7c9",
|
||||
"Season 2021/s2021.e000004 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Season 2021/s2021.e000004 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Season 2021/s2021.e000004 - Mock Entry 21-1.mp4": "7433153952b069a5674e2a3ed529b49b",
|
||||
"Season 2021/s2021.e000004 - Mock Entry 21-1.nfo": "8ee3845c514a411425b7e9198666b61c",
|
||||
"tvshow.nfo": "cccca1086b41af04d8ea004b1aa250e8"
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
".ytdl-sub-subscription_test-download-archive.json": "e049068ba7f5bdc27c474b18f4c6b402",
|
||||
"Season 2020/s2020.e000001 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Season 2020/s2020.e000001 - Mock Entry 20-3.mp4": "7d2ee7fe8003ea63ece37dd2a441c123",
|
||||
"Season 2020/s2020.e000001 - Mock Entry 20-3.nfo": "dbe61f2c8ae41041773f713ba5376726",
|
||||
"Season 2020/s2020.e000002 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Season 2020/s2020.e000002 - Mock Entry 20-2.mp4": "699017cd1b67ae216eda769bef413415",
|
||||
"Season 2020/s2020.e000002 - Mock Entry 20-2.nfo": "0f071078c9fa2569bbcb998664d40681",
|
||||
"Season 2020/s2020.e000003 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Season 2020/s2020.e000003 - Mock Entry 20-1.mp4": "a16741d4fbf657d1de4c50493db14062",
|
||||
"Season 2020/s2020.e000003 - Mock Entry 20-1.nfo": "837a61dca11bbe1874ea07cb8ef8a7c9",
|
||||
"Season 2021/s2021.e000004 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Season 2021/s2021.e000004 - Mock Entry 21-1.mp4": "7433153952b069a5674e2a3ed529b49b",
|
||||
"Season 2021/s2021.e000004 - Mock Entry 21-1.nfo": "8ee3845c514a411425b7e9198666b61c",
|
||||
"tvshow.nfo": "cccca1086b41af04d8ea004b1aa250e8"
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"JMC/.ytdl-sub-JMC-download-archive.json": "3fdab8d103e51aa70430b6da0ceb07e2",
|
||||
"JMC/Season 01/s01.e11020101 - Jesse's Minecraft Server [Trailer - Feb.1]-thumb.jpg": "b232d253df621aa770b780c1301d364d",
|
||||
"JMC/Season 01/s01.e11020101 - Jesse's Minecraft Server [Trailer - Feb.1].info.json": "INFO_JSON",
|
||||
"JMC/Season 01/s01.e11020101 - Jesse's Minecraft Server [Trailer - Feb.1].mp4": "7fa67dd3a895da12c17669b0fa2f3763",
|
||||
"JMC/Season 01/s01.e11020101 - Jesse's Minecraft Server [Trailer - Feb.1].nfo": "2a2997cbf16fb6b943d9933ad267331e",
|
||||
"JMC/Season 01/s01.e11022701 - Jesse's Minecraft Server [Trailer - Feb.27]-thumb.jpg": "d17c379ea8b362f5b97c6b213b0342cb",
|
||||
"JMC/Season 01/s01.e11022701 - Jesse's Minecraft Server [Trailer - Feb.27].info.json": "INFO_JSON",
|
||||
"JMC/Season 01/s01.e11022701 - Jesse's Minecraft Server [Trailer - Feb.27].mp4": "5a3ffa5cee2f58f5001502ab3823d130",
|
||||
"JMC/Season 01/s01.e11022701 - Jesse's Minecraft Server [Trailer - Feb.27].nfo": "da7645e8826586388ae0d8278ef6a1c1",
|
||||
"JMC/Season 01/s01.e11032101 - Jesse's Minecraft Server [Trailer - Mar.21]-thumb.jpg": "e7830aa8a64b0cde65ba3f7e5fc56530",
|
||||
"JMC/Season 01/s01.e11032101 - Jesse's Minecraft Server [Trailer - Mar.21].info.json": "INFO_JSON",
|
||||
"JMC/Season 01/s01.e11032101 - Jesse's Minecraft Server [Trailer - Mar.21].mp4": "91f22944f797513fcda9856e244dd3b3",
|
||||
"JMC/Season 01/s01.e11032101 - Jesse's Minecraft Server [Trailer - Mar.21].nfo": "c56083e2f3545fa2cafc4d67cbfdacf8",
|
||||
"JMC/fanart.jpg": "129c6639b47299bc48062f0365e670ee",
|
||||
"JMC/poster.jpg": "5de28eea5a921a041452ab3ce1041f73",
|
||||
"JMC/season01-poster.jpg": "e7830aa8a64b0cde65ba3f7e5fc56530",
|
||||
"JMC/tvshow.nfo": "e92e4a2c01522dd9a9c3423f0f9304dc"
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"JMC/Oblivion Mod "Falcor" p.1.info.json": "INFO_JSON",
|
||||
"JMC/Oblivion Mod "Falcor" p.1.jpg": "fb95b510681676e81c321171fc23143e",
|
||||
"JMC/Oblivion Mod "Falcor" p.1.mp4": "318faf3eb1d7666491553cdfd2a2e9fb",
|
||||
"JMC/Oblivion Mod "Falcor" p.1.nfo": "58c2be339869b5d071c1758d55c72ddb"
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"JMC/Oblivion Mod "Falcor" p.1.info.json": "INFO_JSON",
|
||||
"JMC/Oblivion Mod "Falcor" p.1.mp4": "d3bdda5ec6822ea3b4b4bd8908eb327a",
|
||||
"JMC/Oblivion Mod "Falcor" p.1.nfo": "58c2be339869b5d071c1758d55c72ddb"
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
Files created:
|
||||
----------------------------------------
|
||||
{output_directory}
|
||||
.ytdl-sub-subscription_test-download-archive.json
|
||||
{output_directory}/JMC
|
||||
Mock Entry 20-1.info.json
|
||||
Mock Entry 20-1.jpg
|
||||
Mock Entry 20-1.mp4
|
||||
Video Tags:
|
||||
album: Music Videos
|
||||
artist: JMC
|
||||
genre: ytdl-sub
|
||||
premiered: 2020-08-08
|
||||
title: Mock Entry 20-1
|
||||
year: 2020
|
||||
Mock Entry 20-1.nfo
|
||||
NFO tags:
|
||||
musicvideo:
|
||||
album: Music Videos
|
||||
artist: JMC
|
||||
custom_tag: mom
|
||||
genre: ytdl-sub
|
||||
premiered: 2020-08-08
|
||||
title: Mock Entry 20-1
|
||||
Mock Entry 20-2.info.json
|
||||
Mock Entry 20-2.jpg
|
||||
Mock Entry 20-2.mp4
|
||||
Video Tags:
|
||||
album: Music Videos
|
||||
artist: JMC
|
||||
genre: ytdl-sub
|
||||
premiered: 2020-08-08
|
||||
title: Mock Entry 20-2
|
||||
year: 2020
|
||||
Mock Entry 20-2.nfo
|
||||
NFO tags:
|
||||
musicvideo:
|
||||
album: Music Videos
|
||||
artist: JMC
|
||||
custom_tag: mom
|
||||
genre: ytdl-sub
|
||||
premiered: 2020-08-08
|
||||
title: Mock Entry 20-2
|
||||
Mock Entry 20-3.info.json
|
||||
Mock Entry 20-3.jpg
|
||||
Mock Entry 20-3.mp4
|
||||
Video Tags:
|
||||
album: Music Videos
|
||||
artist: JMC
|
||||
genre: ytdl-sub
|
||||
premiered: 2020-08-07
|
||||
title: Mock Entry 20-3
|
||||
year: 2020
|
||||
Mock Entry 20-3.nfo
|
||||
NFO tags:
|
||||
musicvideo:
|
||||
album: Music Videos
|
||||
artist: JMC
|
||||
custom_tag: mom
|
||||
genre: ytdl-sub
|
||||
premiered: 2020-08-07
|
||||
title: Mock Entry 20-3
|
||||
Mock Entry 21-1.info.json
|
||||
Mock Entry 21-1.jpg
|
||||
Mock Entry 21-1.mp4
|
||||
Video Tags:
|
||||
album: Music Videos
|
||||
artist: JMC
|
||||
genre: ytdl-sub
|
||||
premiered: 2021-08-08
|
||||
title: Mock Entry 21-1
|
||||
year: 2021
|
||||
Mock Entry 21-1.nfo
|
||||
NFO tags:
|
||||
musicvideo:
|
||||
album: Music Videos
|
||||
artist: JMC
|
||||
custom_tag: mom
|
||||
genre: ytdl-sub
|
||||
premiered: 2021-08-08
|
||||
title: Mock Entry 21-1
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
Files created:
|
||||
----------------------------------------
|
||||
{output_directory}
|
||||
.ytdl-sub-JMC-download-archive.json
|
||||
.ytdl-sub-JMC-migrated-download-archive.json
|
||||
|
||||
Files removed:
|
||||
----------------------------------------
|
||||
{output_directory}
|
||||
.ytdl-sub-music_video_playlist_test-download-archive.json
|
||||
.ytdl-sub-subscription_test-download-archive.json
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
Files created:
|
||||
----------------------------------------
|
||||
{output_directory}
|
||||
.ytdl-sub-subscription_test-download-archive.json
|
||||
tvshow.nfo
|
||||
NFO tags:
|
||||
tvshow:
|
||||
genre: ytdl-sub
|
||||
mpaa: TV-14
|
||||
title: JMC
|
||||
{output_directory}/Season 2020
|
||||
s2020.e000001 - Mock Entry 20-3-thumb.jpg
|
||||
s2020.e000001 - Mock Entry 20-3.info.json
|
||||
s2020.e000001 - Mock Entry 20-3.mp4
|
||||
Video Tags:
|
||||
contentRating: TV-14
|
||||
date: 2020-08-07
|
||||
episode_id: 1
|
||||
genre: ytdl-sub
|
||||
show: JMC
|
||||
synopsis:
|
||||
https://20-3.com
|
||||
|
||||
The Description
|
||||
title: 2020-08-07 - Mock Entry 20-3
|
||||
year: 2020
|
||||
s2020.e000001 - Mock Entry 20-3.nfo
|
||||
NFO tags:
|
||||
episodedetails:
|
||||
aired: 2020-08-07
|
||||
episode: 1
|
||||
genre: ytdl-sub
|
||||
mpaa: TV-14
|
||||
plot:
|
||||
https://20-3.com
|
||||
|
||||
The Description
|
||||
season: 2020
|
||||
title: 2020-08-07 - Mock Entry 20-3
|
||||
year: 2020
|
||||
s2020.e000002 - Mock Entry 20-2-thumb.jpg
|
||||
s2020.e000002 - Mock Entry 20-2.info.json
|
||||
s2020.e000002 - Mock Entry 20-2.mp4
|
||||
Video Tags:
|
||||
contentRating: TV-14
|
||||
date: 2020-08-08
|
||||
episode_id: 2
|
||||
genre: ytdl-sub
|
||||
show: JMC
|
||||
synopsis:
|
||||
https://20-2.com
|
||||
|
||||
The Description
|
||||
title: 2020-08-08 - Mock Entry 20-2
|
||||
year: 2020
|
||||
s2020.e000002 - Mock Entry 20-2.nfo
|
||||
NFO tags:
|
||||
episodedetails:
|
||||
aired: 2020-08-08
|
||||
episode: 2
|
||||
genre: ytdl-sub
|
||||
mpaa: TV-14
|
||||
plot:
|
||||
https://20-2.com
|
||||
|
||||
The Description
|
||||
season: 2020
|
||||
title: 2020-08-08 - Mock Entry 20-2
|
||||
year: 2020
|
||||
s2020.e000003 - Mock Entry 20-1-thumb.jpg
|
||||
s2020.e000003 - Mock Entry 20-1.info.json
|
||||
s2020.e000003 - Mock Entry 20-1.mp4
|
||||
Video Tags:
|
||||
contentRating: TV-14
|
||||
date: 2020-08-08
|
||||
episode_id: 3
|
||||
genre: ytdl-sub
|
||||
show: JMC
|
||||
synopsis:
|
||||
https://20-1.com
|
||||
|
||||
The Description
|
||||
title: 2020-08-08 - Mock Entry 20-1
|
||||
year: 2020
|
||||
s2020.e000003 - Mock Entry 20-1.nfo
|
||||
NFO tags:
|
||||
episodedetails:
|
||||
aired: 2020-08-08
|
||||
episode: 3
|
||||
genre: ytdl-sub
|
||||
mpaa: TV-14
|
||||
plot:
|
||||
https://20-1.com
|
||||
|
||||
The Description
|
||||
season: 2020
|
||||
title: 2020-08-08 - Mock Entry 20-1
|
||||
year: 2020
|
||||
{output_directory}/Season 2021
|
||||
s2021.e000004 - Mock Entry 21-1-thumb.jpg
|
||||
s2021.e000004 - Mock Entry 21-1.info.json
|
||||
s2021.e000004 - Mock Entry 21-1.mp4
|
||||
Video Tags:
|
||||
contentRating: TV-14
|
||||
date: 2021-08-08
|
||||
episode_id: 4
|
||||
genre: ytdl-sub
|
||||
show: JMC
|
||||
synopsis:
|
||||
https://21-1.com
|
||||
|
||||
The Description
|
||||
title: 2021-08-08 - Mock Entry 21-1
|
||||
year: 2021
|
||||
s2021.e000004 - Mock Entry 21-1.nfo
|
||||
NFO tags:
|
||||
episodedetails:
|
||||
aired: 2021-08-08
|
||||
episode: 4
|
||||
genre: ytdl-sub
|
||||
mpaa: TV-14
|
||||
plot:
|
||||
https://21-1.com
|
||||
|
||||
The Description
|
||||
season: 2021
|
||||
title: 2021-08-08 - Mock Entry 21-1
|
||||
year: 2021
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
Files created:
|
||||
----------------------------------------
|
||||
{output_directory}
|
||||
.ytdl-sub-subscription_test-download-archive.json
|
||||
tvshow.nfo
|
||||
NFO tags:
|
||||
tvshow:
|
||||
genre: ytdl-sub
|
||||
mpaa: TV-14
|
||||
title: JMC
|
||||
{output_directory}/Season 2020
|
||||
s2020.e000001 - Mock Entry 20-3.info.json
|
||||
s2020.e000001 - Mock Entry 20-3.mp4
|
||||
Video Tags:
|
||||
contentRating: TV-14
|
||||
date: 2020-08-07
|
||||
episode_id: 1
|
||||
genre: ytdl-sub
|
||||
show: JMC
|
||||
synopsis:
|
||||
https://20-3.com
|
||||
|
||||
The Description
|
||||
title: 2020-08-07 - Mock Entry 20-3
|
||||
year: 2020
|
||||
s2020.e000001 - Mock Entry 20-3.nfo
|
||||
NFO tags:
|
||||
episodedetails:
|
||||
aired: 2020-08-07
|
||||
episode: 1
|
||||
genre: ytdl-sub
|
||||
mpaa: TV-14
|
||||
plot:
|
||||
https://20-3.com
|
||||
|
||||
The Description
|
||||
season: 2020
|
||||
title: 2020-08-07 - Mock Entry 20-3
|
||||
year: 2020
|
||||
s2020.e000002 - Mock Entry 20-2.info.json
|
||||
s2020.e000002 - Mock Entry 20-2.mp4
|
||||
Video Tags:
|
||||
contentRating: TV-14
|
||||
date: 2020-08-08
|
||||
episode_id: 2
|
||||
genre: ytdl-sub
|
||||
show: JMC
|
||||
synopsis:
|
||||
https://20-2.com
|
||||
|
||||
The Description
|
||||
title: 2020-08-08 - Mock Entry 20-2
|
||||
year: 2020
|
||||
s2020.e000002 - Mock Entry 20-2.nfo
|
||||
NFO tags:
|
||||
episodedetails:
|
||||
aired: 2020-08-08
|
||||
episode: 2
|
||||
genre: ytdl-sub
|
||||
mpaa: TV-14
|
||||
plot:
|
||||
https://20-2.com
|
||||
|
||||
The Description
|
||||
season: 2020
|
||||
title: 2020-08-08 - Mock Entry 20-2
|
||||
year: 2020
|
||||
s2020.e000003 - Mock Entry 20-1.info.json
|
||||
s2020.e000003 - Mock Entry 20-1.mp4
|
||||
Video Tags:
|
||||
contentRating: TV-14
|
||||
date: 2020-08-08
|
||||
episode_id: 3
|
||||
genre: ytdl-sub
|
||||
show: JMC
|
||||
synopsis:
|
||||
https://20-1.com
|
||||
|
||||
The Description
|
||||
title: 2020-08-08 - Mock Entry 20-1
|
||||
year: 2020
|
||||
s2020.e000003 - Mock Entry 20-1.nfo
|
||||
NFO tags:
|
||||
episodedetails:
|
||||
aired: 2020-08-08
|
||||
episode: 3
|
||||
genre: ytdl-sub
|
||||
mpaa: TV-14
|
||||
plot:
|
||||
https://20-1.com
|
||||
|
||||
The Description
|
||||
season: 2020
|
||||
title: 2020-08-08 - Mock Entry 20-1
|
||||
year: 2020
|
||||
{output_directory}/Season 2021
|
||||
s2021.e000004 - Mock Entry 21-1.info.json
|
||||
s2021.e000004 - Mock Entry 21-1.mp4
|
||||
Video Tags:
|
||||
contentRating: TV-14
|
||||
date: 2021-08-08
|
||||
episode_id: 4
|
||||
genre: ytdl-sub
|
||||
show: JMC
|
||||
synopsis:
|
||||
https://21-1.com
|
||||
|
||||
The Description
|
||||
title: 2021-08-08 - Mock Entry 21-1
|
||||
year: 2021
|
||||
s2021.e000004 - Mock Entry 21-1.nfo
|
||||
NFO tags:
|
||||
episodedetails:
|
||||
aired: 2021-08-08
|
||||
episode: 4
|
||||
genre: ytdl-sub
|
||||
mpaa: TV-14
|
||||
plot:
|
||||
https://21-1.com
|
||||
|
||||
The Description
|
||||
season: 2021
|
||||
title: 2021-08-08 - Mock Entry 21-1
|
||||
year: 2021
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
Files created:
|
||||
----------------------------------------
|
||||
{output_directory}/JMC
|
||||
Oblivion Mod "Falcor" p.1.info.json
|
||||
Oblivion Mod "Falcor" p.1.jpg
|
||||
Oblivion Mod "Falcor" p.1.mp4
|
||||
Video Tags:
|
||||
album: Music Videos
|
||||
artist: JMC
|
||||
genre: ytdl-sub
|
||||
premiered: 2010-08-13
|
||||
title: Oblivion Mod "Falcor" p.1
|
||||
year: 2010
|
||||
Embedded thumbnail
|
||||
Oblivion Mod "Falcor" p.1.nfo
|
||||
NFO tags:
|
||||
musicvideo:
|
||||
album: Music Videos
|
||||
artist: JMC
|
||||
genre: ytdl-sub
|
||||
premiered: 2010-08-13
|
||||
title: Oblivion Mod "Falcor" p.1
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
Files created:
|
||||
----------------------------------------
|
||||
{output_directory}/JMC
|
||||
Oblivion Mod "Falcor" p.1.info.json
|
||||
Oblivion Mod "Falcor" p.1.mp4
|
||||
Video Tags:
|
||||
album: Music Videos
|
||||
artist: JMC
|
||||
genre: ytdl-sub
|
||||
premiered: 2010-08-13
|
||||
title: Oblivion Mod "Falcor" p.1
|
||||
year: 2010
|
||||
Oblivion Mod "Falcor" p.1.nfo
|
||||
NFO tags:
|
||||
musicvideo:
|
||||
album: Music Videos
|
||||
artist: JMC
|
||||
genre: ytdl-sub
|
||||
premiered: 2010-08-13
|
||||
title: Oblivion Mod "Falcor" p.1
|
||||
|
|
@ -186,6 +186,7 @@ def preset_with_subscription_overrides_map(
|
|||
"elem2",
|
||||
"elem3",
|
||||
],
|
||||
"custom_map": {"custom_map_key": ["custom_map_list_value"]},
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
@ -290,6 +291,7 @@ def test_subscription_overrides_map(
|
|||
"elem2",
|
||||
"elem3",
|
||||
],
|
||||
"custom_map": {"custom_map_key": ["custom_map_list_value"]},
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue