[BACKEND] Remove individual_download parameter from youtube channel + playlist (#119)

This commit is contained in:
Jesse Bannon 2022-07-22 08:46:05 -07:00 committed by GitHub
parent 72442ab846
commit d292ab0510
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 19 additions and 71 deletions

View file

@ -15,7 +15,6 @@ from ytdl_sub.utils.thumbnail import convert_url_thumbnail
from ytdl_sub.validators.date_range_validator import DateRangeValidator
from ytdl_sub.validators.string_formatter_validators import OverridesStringFormatterValidator
from ytdl_sub.validators.url_validator import YoutubeChannelUrlValidator
from ytdl_sub.validators.validators import BoolValidator
from ytdl_sub.ytdl_additions.enhanced_download_archive import EnhancedDownloadArchive
logger = Logger.get()
@ -49,7 +48,6 @@ class YoutubeChannelDownloaderOptions(YoutubeDownloaderOptions, DateRangeValidat
"after",
"channel_avatar_path",
"channel_banner_path",
"download_individually",
}
def __init__(self, name, value):
@ -64,9 +62,6 @@ class YoutubeChannelDownloaderOptions(YoutubeDownloaderOptions, DateRangeValidat
self._channel_banner_path = self._validate_key_if_present(
"channel_banner_path", OverridesStringFormatterValidator
)
self._download_individually = self._validate_key_if_present(
"download_individually", BoolValidator, default=True
)
@property
def channel_url(self) -> str:
@ -91,15 +86,6 @@ class YoutubeChannelDownloaderOptions(YoutubeDownloaderOptions, DateRangeValidat
"""
return self._channel_banner_path
@property
def download_individually(self) -> Optional[bool]:
"""
Optional. Downloads files from the channel individually instead of in bulk. Setting to True
is safer when downloading large amounts of videos in case an error occurs. Downloading by
bulk (by setting to False) can increase speeds. Defaults to True.
"""
return self._download_individually.value
class YoutubeChannelDownloader(YoutubeDownloader[YoutubeChannelDownloaderOptions, YoutubeVideo]):
downloader_options_type = YoutubeChannelDownloaderOptions
@ -155,26 +141,26 @@ class YoutubeChannelDownloader(YoutubeDownloader[YoutubeChannelDownloaderOptions
"""
ytdl_options_overrides = {}
# If downloading individually, dry-run the entire channel download first, this will get the
# videos that will be downloaded. Afterwards, download each video one-by-one
if self.download_options.download_individually:
ytdl_options_overrides["skip_download"] = True
ytdl_options_overrides["writethumbnail"] = False
# If a date range is specified when download a YT channel, add it into the ytdl options
source_date_range = self.download_options.get_date_range()
if source_date_range:
ytdl_options_overrides["daterange"] = source_date_range
# dry-run the entire channel download first, this will get the
# videos that will be downloaded. Afterwards, download each video one-by-one
entry_dicts = self.extract_info_via_info_json(
ytdl_options_overrides=ytdl_options_overrides, url=self.download_options.channel_url
ytdl_options_overrides=dict(
{"skip_download": True, "write_thumbnail": False}, **ytdl_options_overrides
),
url=self.download_options.channel_url,
)
self.channel = self._get_channel_from_entry_dicts(entry_dicts=entry_dicts)
for entry_dict in entry_dicts:
if entry_dict.get("extractor") == "youtube":
# Only do the individual download if it is not dry-run and downloading individually
if not self.is_dry_run and self.download_options.download_individually:
# Only do the individual download if it is not dry-run
# TODO: Respect the Reject/Exist exceptions
if not self.is_dry_run:
ytdl_options_overrides["playlist_items"] = str(entry_dict.get("playlist_index"))
_ = self.extract_info(
ytdl_options_overrides={

View file

@ -1,12 +1,10 @@
from typing import Dict
from typing import Generator
from typing import Optional
from ytdl_sub.downloaders.youtube.abc import YoutubeDownloader
from ytdl_sub.downloaders.youtube.abc import YoutubeDownloaderOptions
from ytdl_sub.entries.youtube import YoutubePlaylistVideo
from ytdl_sub.validators.url_validator import YoutubePlaylistUrlValidator
from ytdl_sub.validators.validators import BoolValidator
class YoutubePlaylistDownloaderOptions(YoutubeDownloaderOptions):
@ -28,16 +26,12 @@ class YoutubePlaylistDownloaderOptions(YoutubeDownloaderOptions):
"""
_required_keys = {"playlist_url"}
_optional_keys = {"download_individually"}
def __init__(self, name, value):
super().__init__(name, value)
self._playlist_url = self._validate_key(
"playlist_url", YoutubePlaylistUrlValidator
).playlist_url
self._download_individually = self._validate_key_if_present(
"download_individually", BoolValidator, default=True
)
@property
def playlist_url(self) -> str:
@ -47,15 +41,6 @@ class YoutubePlaylistDownloaderOptions(YoutubeDownloaderOptions):
"""
return self._playlist_url
@property
def download_individually(self) -> Optional[bool]:
"""
Optional. Downloads files from the playlist individually instead of in bulk. Setting to True
is safer when downloading large amounts of videos in case an error occurs. Downloading by
bulk (by setting to False) can increase speeds. Defaults to True.
"""
return self._download_individually.value
class YoutubePlaylistDownloader(
YoutubeDownloader[YoutubePlaylistDownloaderOptions, YoutubePlaylistVideo]
@ -84,25 +69,24 @@ class YoutubePlaylistDownloader(
def download(self) -> Generator[YoutubePlaylistVideo, None, None]:
"""
Downloads all videos in a Youtube playlist
Downloads all videos in a Youtube playlist.
Dry-run the entire playlist download first. This will get the videos that will be
downloaded. Afterwards, download each video one-by-one
"""
ytdl_options_overrides = {}
# If downloading individually, dry-run the entire channel download first, this will get the
# videos that will be downloaded. Afterwards, download each video one-by-one
if self.download_options.download_individually:
ytdl_options_overrides["skip_download"] = True
ytdl_options_overrides["writethumbnail"] = False
entry_dicts = self.extract_info_via_info_json(
ytdl_options_overrides=ytdl_options_overrides, url=self.download_options.playlist_url
ytdl_options_overrides={
"skip_download": True,
"writethumbnail": False,
},
url=self.download_options.playlist_url,
)
for entry_dict in entry_dicts:
if entry_dict.get("extractor") == "youtube":
# Only do the individual download if it is not dry-run and downloading individually
if not self.is_dry_run and self.download_options.download_individually:
if not self.is_dry_run:
_ = self.extract_info(
ytdl_options_overrides={
"playlist_items": str(entry_dict.get("playlist_index")),

View file

@ -225,7 +225,6 @@ class TestChannelAsKodiTvShow:
"""
@pytest.mark.parametrize("dry_run", [True, False])
@pytest.mark.parametrize("download_individually", [True, False])
def test_full_channel_download(
self,
channel_subscription_generator,
@ -233,10 +232,7 @@ class TestChannelAsKodiTvShow:
expected_full_channel_download,
output_directory,
dry_run,
download_individually,
):
channel_preset_dict["youtube"]["download_individually"] = download_individually
full_channel_subscription = channel_subscription_generator(preset_dict=channel_preset_dict)
transaction_log = full_channel_subscription.download(dry_run=dry_run)
assert_transaction_log_matches(
@ -248,7 +244,6 @@ class TestChannelAsKodiTvShow:
expected_full_channel_download.assert_files_exist(relative_directory=output_directory)
@pytest.mark.parametrize("dry_run", [True, False])
@pytest.mark.parametrize("download_individually", [True, False])
def test_recent_channel_download(
self,
channel_subscription_generator,
@ -256,10 +251,7 @@ class TestChannelAsKodiTvShow:
expected_recent_channel_download,
output_directory,
dry_run,
download_individually,
):
recent_channel_preset_dict["youtube"]["download_individually"] = download_individually
recent_channel_subscription = channel_subscription_generator(
preset_dict=recent_channel_preset_dict
)
@ -291,7 +283,6 @@ class TestChannelAsKodiTvShow:
)
@pytest.mark.parametrize("dry_run", [True, False])
@pytest.mark.parametrize("download_individually", [True, False])
def test_recent_channel_download__no_vids_in_range(
self,
channel_subscription_generator,
@ -299,9 +290,7 @@ class TestChannelAsKodiTvShow:
expected_recent_channel_no_vids_in_range_download,
output_directory,
dry_run,
download_individually,
):
recent_channel_preset_dict["youtube"]["download_individually"] = download_individually
recent_channel_preset_dict["youtube"]["after"] = "21000101"
recent_channel_no_vids_in_range_subscription = channel_subscription_generator(
@ -321,7 +310,6 @@ class TestChannelAsKodiTvShow:
)
@pytest.mark.parametrize("dry_run", [True, False])
@pytest.mark.parametrize("download_individually", [True, False])
def test_rolling_recent_channel_download(
self,
channel_subscription_generator,
@ -331,13 +319,7 @@ class TestChannelAsKodiTvShow:
expected_rolling_recent_channel_download,
output_directory,
dry_run,
download_individually,
):
recent_channel_preset_dict["youtube"]["download_individually"] = download_individually
rolling_recent_channel_preset_dict["youtube"][
"download_individually"
] = download_individually
recent_channel_subscription = channel_subscription_generator(
preset_dict=recent_channel_preset_dict
)

View file

@ -92,7 +92,6 @@ class TestPlaylistAsKodiMusicVideo:
"""
@pytest.mark.parametrize("dry_run", [True, False])
@pytest.mark.parametrize("download_individually", [True, False])
def test_playlist_download(
self,
music_video_config,
@ -100,10 +99,7 @@ class TestPlaylistAsKodiMusicVideo:
expected_playlist_download,
output_directory,
dry_run,
download_individually,
):
playlist_preset_dict["youtube"]["download_individually"] = download_individually
playlist_subscription = Subscription.from_dict(
config=music_video_config,
preset_name="music_video_playlist_test",