new subtitle section. modularize ytdl_options in subscription
This commit is contained in:
parent
96c9c4b152
commit
a7f556b58f
7 changed files with 237 additions and 50 deletions
|
|
@ -14,6 +14,7 @@ from ytdl_sub.config.preset_class_mappings import DownloadStrategyMapping
|
||||||
from ytdl_sub.config.preset_class_mappings import PluginMapping
|
from ytdl_sub.config.preset_class_mappings import PluginMapping
|
||||||
from ytdl_sub.config.preset_options import OutputOptions
|
from ytdl_sub.config.preset_options import OutputOptions
|
||||||
from ytdl_sub.config.preset_options import Overrides
|
from ytdl_sub.config.preset_options import Overrides
|
||||||
|
from ytdl_sub.config.preset_options import SubtitleOptions
|
||||||
from ytdl_sub.config.preset_options import YTDLOptions
|
from ytdl_sub.config.preset_options import YTDLOptions
|
||||||
from ytdl_sub.downloaders.downloader import Downloader
|
from ytdl_sub.downloaders.downloader import Downloader
|
||||||
from ytdl_sub.downloaders.downloader import DownloaderValidator
|
from ytdl_sub.downloaders.downloader import DownloaderValidator
|
||||||
|
|
@ -32,6 +33,7 @@ from ytdl_sub.validators.validators import Validator
|
||||||
PRESET_KEYS = {
|
PRESET_KEYS = {
|
||||||
"preset",
|
"preset",
|
||||||
"output_options",
|
"output_options",
|
||||||
|
"subtitle_options",
|
||||||
"ytdl_options",
|
"ytdl_options",
|
||||||
"overrides",
|
"overrides",
|
||||||
*DownloadStrategyMapping.sources(),
|
*DownloadStrategyMapping.sources(),
|
||||||
|
|
@ -248,6 +250,10 @@ class Preset(StrictDictValidator):
|
||||||
validator=OutputOptions,
|
validator=OutputOptions,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.subtitle_options = self._validate_key(
|
||||||
|
key="subtitle_options", validator=SubtitleOptions, default={}
|
||||||
|
)
|
||||||
|
|
||||||
self.ytdl_options = self._validate_key(
|
self.ytdl_options = self._validate_key(
|
||||||
key="ytdl_options", validator=YTDLOptions, default={}
|
key="ytdl_options", validator=YTDLOptions, default={}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
from typing import List
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from yt_dlp.utils import DateRange
|
from yt_dlp.utils import DateRange
|
||||||
|
|
@ -9,8 +10,10 @@ from ytdl_sub.validators.string_datetime import StringDatetimeValidator
|
||||||
from ytdl_sub.validators.string_formatter_validators import DictFormatterValidator
|
from ytdl_sub.validators.string_formatter_validators import DictFormatterValidator
|
||||||
from ytdl_sub.validators.string_formatter_validators import OverridesStringFormatterValidator
|
from ytdl_sub.validators.string_formatter_validators import OverridesStringFormatterValidator
|
||||||
from ytdl_sub.validators.string_formatter_validators import StringFormatterValidator
|
from ytdl_sub.validators.string_formatter_validators import StringFormatterValidator
|
||||||
|
from ytdl_sub.validators.string_select_validator import StringSelectValidator
|
||||||
from ytdl_sub.validators.validators import BoolValidator
|
from ytdl_sub.validators.validators import BoolValidator
|
||||||
from ytdl_sub.validators.validators import LiteralDictValidator
|
from ytdl_sub.validators.validators import LiteralDictValidator
|
||||||
|
from ytdl_sub.validators.validators import StringListValidator
|
||||||
|
|
||||||
|
|
||||||
class YTDLOptions(LiteralDictValidator):
|
class YTDLOptions(LiteralDictValidator):
|
||||||
|
|
@ -132,9 +135,6 @@ class OutputOptions(StrictDictValidator):
|
||||||
self._thumbnail_name = self._validate_key_if_present(
|
self._thumbnail_name = self._validate_key_if_present(
|
||||||
key="thumbnail_name", validator=StringFormatterValidator
|
key="thumbnail_name", validator=StringFormatterValidator
|
||||||
)
|
)
|
||||||
self._subtitles_name = self._validate_key_if_present(
|
|
||||||
key="subtitles_name", validator=StringFormatterValidator
|
|
||||||
)
|
|
||||||
|
|
||||||
self._maintain_download_archive = self._validate_key_if_present(
|
self._maintain_download_archive = self._validate_key_if_present(
|
||||||
key="maintain_download_archive", validator=BoolValidator, default=False
|
key="maintain_download_archive", validator=BoolValidator, default=False
|
||||||
|
|
@ -178,15 +178,6 @@ class OutputOptions(StrictDictValidator):
|
||||||
"""
|
"""
|
||||||
return self._thumbnail_name
|
return self._thumbnail_name
|
||||||
|
|
||||||
@property
|
|
||||||
def subtitles_name(self) -> Optional[StringFormatterValidator]:
|
|
||||||
"""
|
|
||||||
Optional. The file name for the media's subtitles if they are present. This can include
|
|
||||||
directories such as ``"Season {upload_year}/{title}.{subtitle_ext}"``, and will be placed
|
|
||||||
in the output directory.
|
|
||||||
"""
|
|
||||||
return self._subtitles_name
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def maintain_download_archive(self) -> bool:
|
def maintain_download_archive(self) -> bool:
|
||||||
"""
|
"""
|
||||||
|
|
@ -234,3 +225,73 @@ class OutputOptions(StrictDictValidator):
|
||||||
end=self.keep_files_before.datetime_str if self.keep_files_before else None,
|
end=self.keep_files_before.datetime_str if self.keep_files_before else None,
|
||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
class SubtitlesTypeValidator(StringSelectValidator):
|
||||||
|
_expected_value_type_name = "subtitles type"
|
||||||
|
_select_values = {"srt", "vtt", "ass", "lrc"}
|
||||||
|
|
||||||
|
|
||||||
|
class SubtitleOptions(StrictDictValidator):
|
||||||
|
_optional_keys = {
|
||||||
|
"subtitles_name",
|
||||||
|
"subtitles_type",
|
||||||
|
"embed_subtitles",
|
||||||
|
"languages",
|
||||||
|
"allow_auto_generated_subtitles",
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self, name, value):
|
||||||
|
super().__init__(name, value)
|
||||||
|
self._subtitles_name = self._validate_key_if_present(
|
||||||
|
key="subtitles_name", validator=StringFormatterValidator
|
||||||
|
)
|
||||||
|
self._subtitles_type = self._validate_key_if_present(
|
||||||
|
key="subtitles_type", validator=SubtitlesTypeValidator, default="srt"
|
||||||
|
)
|
||||||
|
self._embed_subtitles = self._validate_key_if_present(
|
||||||
|
key="embed_subtitles", validator=BoolValidator
|
||||||
|
)
|
||||||
|
self._languages = self._validate_key_if_present(
|
||||||
|
key="languages", validator=StringListValidator, default=["en"]
|
||||||
|
).list
|
||||||
|
self._allow_auto_generated_subtitles = self._validate_key_if_present(
|
||||||
|
key="allow_auto_generated_subtitles", validator=BoolValidator, default=False
|
||||||
|
).value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def subtitles_name(self) -> Optional[StringFormatterValidator]:
|
||||||
|
"""
|
||||||
|
Optional. The file name for the media's subtitles if they are present. This can include
|
||||||
|
directories such as ``"Season {upload_year}/{title}.{subtitle_ext}"``, and will be placed
|
||||||
|
in the output directory.
|
||||||
|
"""
|
||||||
|
return self._subtitles_name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def subtitles_type(self) -> Optional[str]:
|
||||||
|
"""
|
||||||
|
Optional. The subtitles file format. Defaults to ``srt``
|
||||||
|
"""
|
||||||
|
return self._subtitles_type
|
||||||
|
|
||||||
|
@property
|
||||||
|
def embed_subtitles(self) -> Optional[bool]:
|
||||||
|
"""
|
||||||
|
Optional. Whether to embed the subtitles into the video file.
|
||||||
|
"""
|
||||||
|
return self._subtitles_type
|
||||||
|
|
||||||
|
@property
|
||||||
|
def languages(self) -> Optional[List[str]]:
|
||||||
|
"""
|
||||||
|
Optional. Language(s) to download for subtitles. Defaults to ``en``
|
||||||
|
"""
|
||||||
|
return [lang.value for lang in self._languages]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def allow_auto_generated_subtitles(self) -> Optional[bool]:
|
||||||
|
"""
|
||||||
|
Optional. Whether to allow auto generated subtitles. Defaults to False.
|
||||||
|
"""
|
||||||
|
return self._allow_auto_generated_subtitles
|
||||||
|
|
|
||||||
|
|
@ -60,11 +60,6 @@ class Downloader(DownloadArchiver, Generic[DownloaderOptionsT, DownloaderEntryT]
|
||||||
_extract_entry_num_retries: int = 5
|
_extract_entry_num_retries: int = 5
|
||||||
_extract_entry_retry_wait_sec: int = 3
|
_extract_entry_retry_wait_sec: int = 3
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def ytdl_option_overrides(cls) -> Dict:
|
|
||||||
"""Global overrides that even overwrite user input"""
|
|
||||||
return {}
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def ytdl_option_defaults(cls) -> Dict:
|
def ytdl_option_defaults(cls) -> Dict:
|
||||||
"""
|
"""
|
||||||
|
|
@ -78,7 +73,6 @@ class Downloader(DownloadArchiver, Generic[DownloaderOptionsT, DownloaderEntryT]
|
||||||
@classmethod
|
@classmethod
|
||||||
def _configure_ytdl_options(
|
def _configure_ytdl_options(
|
||||||
cls,
|
cls,
|
||||||
working_directory: str,
|
|
||||||
ytdl_options: Optional[Dict],
|
ytdl_options: Optional[Dict],
|
||||||
) -> Dict:
|
) -> Dict:
|
||||||
"""Configure the ytdl options for the downloader"""
|
"""Configure the ytdl options for the downloader"""
|
||||||
|
|
@ -88,12 +82,6 @@ class Downloader(DownloadArchiver, Generic[DownloaderOptionsT, DownloaderEntryT]
|
||||||
# Overwrite defaults with input
|
# Overwrite defaults with input
|
||||||
ytdl_options = dict(cls.ytdl_option_defaults(), **ytdl_options)
|
ytdl_options = dict(cls.ytdl_option_defaults(), **ytdl_options)
|
||||||
|
|
||||||
# Overwrite defaults + input with global options
|
|
||||||
ytdl_options = dict(ytdl_options, **cls.ytdl_option_overrides())
|
|
||||||
|
|
||||||
# Overwrite the output location with the specified working directory
|
|
||||||
ytdl_options["outtmpl"] = str(Path(working_directory) / "%(id)s.%(ext)s")
|
|
||||||
|
|
||||||
return ytdl_options
|
return ytdl_options
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
|
@ -116,7 +104,6 @@ class Downloader(DownloadArchiver, Generic[DownloaderOptionsT, DownloaderEntryT]
|
||||||
self.download_options = download_options
|
self.download_options = download_options
|
||||||
self.ytdl_options = self._configure_ytdl_options(
|
self.ytdl_options = self._configure_ytdl_options(
|
||||||
ytdl_options=ytdl_options,
|
ytdl_options=ytdl_options,
|
||||||
working_directory=self.working_directory,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import contextlib
|
import contextlib
|
||||||
import copy
|
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -14,12 +13,14 @@ from ytdl_sub.config.config_file import ConfigOptions
|
||||||
from ytdl_sub.config.preset import Preset
|
from ytdl_sub.config.preset import Preset
|
||||||
from ytdl_sub.config.preset_options import OutputOptions
|
from ytdl_sub.config.preset_options import OutputOptions
|
||||||
from ytdl_sub.config.preset_options import Overrides
|
from ytdl_sub.config.preset_options import Overrides
|
||||||
|
from ytdl_sub.config.preset_options import SubtitleOptions
|
||||||
from ytdl_sub.config.preset_options import YTDLOptions
|
from ytdl_sub.config.preset_options import YTDLOptions
|
||||||
from ytdl_sub.downloaders.downloader import Downloader
|
from ytdl_sub.downloaders.downloader import Downloader
|
||||||
from ytdl_sub.downloaders.downloader import DownloaderValidator
|
from ytdl_sub.downloaders.downloader import DownloaderValidator
|
||||||
from ytdl_sub.entries.entry import Entry
|
from ytdl_sub.entries.entry import Entry
|
||||||
from ytdl_sub.plugins.plugin import Plugin
|
from ytdl_sub.plugins.plugin import Plugin
|
||||||
from ytdl_sub.plugins.plugin import PluginOptions
|
from ytdl_sub.plugins.plugin import PluginOptions
|
||||||
|
from ytdl_sub.subscriptions.subscription_ytdl_options import SubscriptionYTDLOptions
|
||||||
from ytdl_sub.utils.file_handler import FileHandlerTransactionLog
|
from ytdl_sub.utils.file_handler import FileHandlerTransactionLog
|
||||||
from ytdl_sub.utils.file_handler import FileMetadata
|
from ytdl_sub.utils.file_handler import FileMetadata
|
||||||
from ytdl_sub.utils.thumbnail import convert_download_thumbnail
|
from ytdl_sub.utils.thumbnail import convert_download_thumbnail
|
||||||
|
|
@ -109,6 +110,15 @@ class Subscription:
|
||||||
"""
|
"""
|
||||||
return self.__preset_options.output_options
|
return self.__preset_options.output_options
|
||||||
|
|
||||||
|
@property
|
||||||
|
def subtitle_options(self) -> SubtitleOptions:
|
||||||
|
"""
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
The subtitle options defined for this subscription
|
||||||
|
"""
|
||||||
|
return self.__preset_options.subtitle_options
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def overrides(self) -> Overrides:
|
def overrides(self) -> Overrides:
|
||||||
"""
|
"""
|
||||||
|
|
@ -195,7 +205,9 @@ class Subscription:
|
||||||
)
|
)
|
||||||
|
|
||||||
# TODO: see if entry even has subtitles
|
# TODO: see if entry even has subtitles
|
||||||
if self.output_options.subtitles_name:
|
if self.output_options.subtitles_name and (
|
||||||
|
entry.kwargs_contains("subtitles") or entry.kwargs_contains("automatic_captions")
|
||||||
|
):
|
||||||
output_subtitles_name = self.overrides.apply_formatter(
|
output_subtitles_name = self.overrides.apply_formatter(
|
||||||
formatter=self.output_options.subtitles_name, entry=entry
|
formatter=self.output_options.subtitles_name, entry=entry
|
||||||
)
|
)
|
||||||
|
|
@ -275,29 +287,12 @@ class Subscription:
|
||||||
directory.
|
directory.
|
||||||
"""
|
"""
|
||||||
self._enhanced_download_archive.reinitialize(dry_run=dry_run)
|
self._enhanced_download_archive.reinitialize(dry_run=dry_run)
|
||||||
|
ytdl_options = SubscriptionYTDLOptions(
|
||||||
# TODO: Move this logic to separate function
|
preset=self.__preset_options,
|
||||||
# TODO: set id here as well
|
enhanced_download_archive=self._enhanced_download_archive,
|
||||||
ytdl_options = copy.deepcopy(self.ytdl_options.dict)
|
working_directory=self.working_directory,
|
||||||
|
dry_run=dry_run,
|
||||||
if self.output_options.thumbnail_name:
|
).to_dict()
|
||||||
ytdl_options["writethumbnail"] = True
|
|
||||||
if self.output_options.subtitles_name:
|
|
||||||
ytdl_options["writesubtitles"] = True
|
|
||||||
ytdl_options["subtitleslangs"] = ["en"]
|
|
||||||
ytdl_options["postprocessers"] = [
|
|
||||||
{"key": "FFmpegSubtitlesConvertorPP", "format": "srt"}
|
|
||||||
]
|
|
||||||
|
|
||||||
if dry_run:
|
|
||||||
ytdl_options["skip_download"] = True
|
|
||||||
ytdl_options["writethumbnail"] = False
|
|
||||||
ytdl_options["writesubtitles"] = False
|
|
||||||
|
|
||||||
if self.downloader_class.supports_download_archive and self.maintain_download_archive:
|
|
||||||
ytdl_options["download_archive"] = str(
|
|
||||||
Path(self.working_directory) / self._enhanced_download_archive.archive_file_name
|
|
||||||
)
|
|
||||||
|
|
||||||
plugins = self._initialize_plugins()
|
plugins = self._initialize_plugins()
|
||||||
with self._subscription_download_context_managers():
|
with self._subscription_download_context_managers():
|
||||||
|
|
|
||||||
104
src/ytdl_sub/subscriptions/subscription_ytdl_options.py
Normal file
104
src/ytdl_sub/subscriptions/subscription_ytdl_options.py
Normal file
|
|
@ -0,0 +1,104 @@
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Dict
|
||||||
|
|
||||||
|
import mergedeep
|
||||||
|
|
||||||
|
from ytdl_sub.config.preset import Preset
|
||||||
|
from ytdl_sub.ytdl_additions.enhanced_download_archive import EnhancedDownloadArchive
|
||||||
|
|
||||||
|
|
||||||
|
class SubscriptionYTDLOptions:
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
preset: Preset,
|
||||||
|
enhanced_download_archive: EnhancedDownloadArchive,
|
||||||
|
working_directory: str,
|
||||||
|
dry_run: bool,
|
||||||
|
):
|
||||||
|
self._preset = preset
|
||||||
|
self._enhanced_download_archive = enhanced_download_archive
|
||||||
|
self._working_directory = working_directory
|
||||||
|
self._dry_run = dry_run
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _global_options(self) -> Dict:
|
||||||
|
return {
|
||||||
|
# Download all files in the format of {id}.{ext}
|
||||||
|
"outtmpl": str(Path(self._working_directory) / "%(id)s.%(ext)s")
|
||||||
|
}
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _dry_run_options(self) -> Dict:
|
||||||
|
return {
|
||||||
|
"skip_download": True,
|
||||||
|
"writethumbnail": False,
|
||||||
|
"writesubtitles": False,
|
||||||
|
}
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _output_options(self) -> Dict:
|
||||||
|
ytdl_options = {}
|
||||||
|
output_options = self._preset.output_options
|
||||||
|
|
||||||
|
if output_options.thumbnail_name:
|
||||||
|
ytdl_options["writethumbnail"] = True
|
||||||
|
if (
|
||||||
|
self._preset.downloader.supports_download_archive
|
||||||
|
and output_options.maintain_download_archive
|
||||||
|
):
|
||||||
|
ytdl_options["download_archive"] = str(
|
||||||
|
Path(self._working_directory) / self._enhanced_download_archive.archive_file_name
|
||||||
|
)
|
||||||
|
|
||||||
|
return ytdl_options
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _subtitle_options(self) -> Dict:
|
||||||
|
ytdl_options: Dict = {}
|
||||||
|
subtitle_options = self._preset.subtitle_options
|
||||||
|
|
||||||
|
write_subtitle_file: bool = subtitle_options.subtitles_name is not None
|
||||||
|
if write_subtitle_file:
|
||||||
|
ytdl_options["writesubtitles"] = True
|
||||||
|
ytdl_options["postprocessors"] = [
|
||||||
|
{"key": "FFmpegSubtitlesConvertor", "format": subtitle_options.subtitles_type}
|
||||||
|
]
|
||||||
|
|
||||||
|
if subtitle_options.embed_subtitles:
|
||||||
|
ytdl_options["postprocessors"] = [
|
||||||
|
# already_have_subtitle=True means keep the subtitle files. False means delete
|
||||||
|
{"key": "FFmpegEmbedSubtitle", "already_have_subtitle": write_subtitle_file}
|
||||||
|
]
|
||||||
|
|
||||||
|
# If neither subtitles_name or embed_subtitles is set, do not set any other flags
|
||||||
|
if not ytdl_options:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
ytdl_options["writeautomaticsub"] = subtitle_options.allow_auto_generated_subtitles
|
||||||
|
ytdl_options["subtitleslangs"] = subtitle_options.languages
|
||||||
|
|
||||||
|
return ytdl_options
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _user_ytdl_options(self) -> Dict:
|
||||||
|
return self._preset.ytdl_options.dict
|
||||||
|
|
||||||
|
def to_dict(self) -> Dict:
|
||||||
|
ytdl_options = self._global_options
|
||||||
|
if self._dry_run:
|
||||||
|
mergedeep.merge(
|
||||||
|
ytdl_options,
|
||||||
|
self._dry_run_options,
|
||||||
|
self._user_ytdl_options,
|
||||||
|
strategy=mergedeep.Strategy.TYPESAFE_ADDITIVE,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
mergedeep.merge(
|
||||||
|
ytdl_options,
|
||||||
|
self._output_options,
|
||||||
|
self._subtitle_options,
|
||||||
|
self._user_ytdl_options,
|
||||||
|
strategy=mergedeep.Strategy.TYPESAFE_ADDITIVE,
|
||||||
|
)
|
||||||
|
|
||||||
|
return ytdl_options
|
||||||
|
|
@ -127,6 +127,11 @@ class ListValidator(Validator, ABC, Generic[ValidatorT]):
|
||||||
return self._list
|
return self._list
|
||||||
|
|
||||||
|
|
||||||
|
class StringListValidator(ListValidator[StringValidator]):
|
||||||
|
_expected_value_type_name = "string list"
|
||||||
|
_inner_list_type = StringValidator
|
||||||
|
|
||||||
|
|
||||||
class DictValidator(Validator):
|
class DictValidator(Validator):
|
||||||
"""
|
"""
|
||||||
Validates dictionary-based fields. Errors to them as 'object's since this could be validating
|
Validates dictionary-based fields. Errors to them as 'object's since this could be validating
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,35 @@ class TestYoutubeVideo:
|
||||||
if not dry_run:
|
if not dry_run:
|
||||||
expected_single_video_download.assert_files_exist(relative_directory=output_directory)
|
expected_single_video_download.assert_files_exist(relative_directory=output_directory)
|
||||||
|
|
||||||
|
# @pytest.mark.parametrize("dry_run", [True, False])
|
||||||
|
# def test_single_video_download_with_subtitles(
|
||||||
|
# self,
|
||||||
|
# music_video_config,
|
||||||
|
# single_video_preset_dict,
|
||||||
|
# expected_single_video_download,
|
||||||
|
# output_directory,
|
||||||
|
# dry_run,
|
||||||
|
# ):
|
||||||
|
# single_video_preset_dict["youtube"][
|
||||||
|
# "video_url"
|
||||||
|
# ] = "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
|
||||||
|
# single_video_preset_dict["subtitles"] = {}
|
||||||
|
# single_video_preset_dict["subtitles"]["subtitles_name"] = "{music_video_name}.srt"
|
||||||
|
# single_video_subscription = Subscription.from_dict(
|
||||||
|
# config=music_video_config,
|
||||||
|
# preset_name="music_video_single_video_test",
|
||||||
|
# preset_dict=single_video_preset_dict,
|
||||||
|
# )
|
||||||
|
#
|
||||||
|
# transaction_log = single_video_subscription.download(dry_run=dry_run)
|
||||||
|
# assert_transaction_log_matches(
|
||||||
|
# output_directory=output_directory,
|
||||||
|
# transaction_log=transaction_log,
|
||||||
|
# transaction_log_summary_file_name="youtube/test_video.txt",
|
||||||
|
# )
|
||||||
|
# if not dry_run:
|
||||||
|
# expected_single_video_download.assert_files_exist(relative_directory=output_directory)
|
||||||
|
|
||||||
@pytest.mark.parametrize("dry_run", [True, False])
|
@pytest.mark.parametrize("dry_run", [True, False])
|
||||||
def test_single_video_download_from_cli_dl(
|
def test_single_video_download_from_cli_dl(
|
||||||
self,
|
self,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue