[REFACTOR] Rename source/collection to url/multi_url (#310)

This commit is contained in:
Jesse Bannon 2022-11-06 17:00:26 -08:00 committed by GitHub
parent da22c9a608
commit 255805c871
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 63 additions and 67 deletions

View file

@ -3,8 +3,8 @@ from typing import List
from typing import Type from typing import Type
from ytdl_sub.downloaders.downloader import Downloader from ytdl_sub.downloaders.downloader import Downloader
from ytdl_sub.downloaders.generic.collection import CollectionDownloader from ytdl_sub.downloaders.generic.multi_url import MultiUrlDownloader
from ytdl_sub.downloaders.generic.source import SourceDownloader from ytdl_sub.downloaders.generic.url import UrlDownloader
from ytdl_sub.downloaders.soundcloud.albums_and_singles import SoundcloudAlbumsAndSinglesDownloader from ytdl_sub.downloaders.soundcloud.albums_and_singles import SoundcloudAlbumsAndSinglesDownloader
from ytdl_sub.downloaders.youtube.channel import YoutubeChannelDownloader from ytdl_sub.downloaders.youtube.channel import YoutubeChannelDownloader
from ytdl_sub.downloaders.youtube.merge_playlist import YoutubeMergePlaylistDownloader from ytdl_sub.downloaders.youtube.merge_playlist import YoutubeMergePlaylistDownloader
@ -40,8 +40,8 @@ class DownloadStrategyMapping:
"albums_and_singles": SoundcloudAlbumsAndSinglesDownloader, "albums_and_singles": SoundcloudAlbumsAndSinglesDownloader,
}, },
"download": { "download": {
"collection": CollectionDownloader, "multi_url": MultiUrlDownloader,
"source": SourceDownloader, "url": UrlDownloader,
}, },
} }

View file

@ -26,9 +26,9 @@ from yt_dlp.utils import RejectedVideoReached
from ytdl_sub.config.preset_options import AddsVariablesMixin from ytdl_sub.config.preset_options import AddsVariablesMixin
from ytdl_sub.config.preset_options import Overrides from ytdl_sub.config.preset_options import Overrides
from ytdl_sub.downloaders.generic.collection_validator import CollectionThumbnailListValidator from ytdl_sub.downloaders.generic.validators import MultiUrlValidator
from ytdl_sub.downloaders.generic.collection_validator import CollectionUrlValidator from ytdl_sub.downloaders.generic.validators import UrlThumbnailListValidator
from ytdl_sub.downloaders.generic.collection_validator import CollectionValidator from ytdl_sub.downloaders.generic.validators import UrlValidator
from ytdl_sub.downloaders.ytdl_options_builder import YTDLOptionsBuilder from ytdl_sub.downloaders.ytdl_options_builder import YTDLOptionsBuilder
from ytdl_sub.entries.base_entry import BaseEntry from ytdl_sub.entries.base_entry import BaseEntry
from ytdl_sub.entries.entry import Entry from ytdl_sub.entries.entry import Entry
@ -63,11 +63,11 @@ class DownloaderValidator(StrictDictValidator, AddsVariablesMixin, ABC):
@property @property
@abc.abstractmethod @abc.abstractmethod
def collection_validator(self) -> CollectionValidator: def collection_validator(self) -> MultiUrlValidator:
""" """
Returns Returns
------- -------
CollectionValidator MultiUrlValidator
To determine how the entries are downloaded To determine how the entries are downloaded
""" """
@ -380,7 +380,7 @@ class Downloader(DownloadArchiver, Generic[DownloaderOptionsT], ABC):
self.downloaded_entries[_entry_key(entry)] = entry self.downloaded_entries[_entry_key(entry)] = entry
@property @property
def collection(self) -> CollectionValidator: def collection(self) -> MultiUrlValidator:
"""Return the download options collection""" """Return the download options collection"""
return self.download_options.collection_validator return self.download_options.collection_validator
@ -480,9 +480,7 @@ class Downloader(DownloadArchiver, Generic[DownloaderOptionsT], ABC):
for entry_child in self._download_parent_entry(parent=parent_child): for entry_child in self._download_parent_entry(parent=parent_child):
yield entry_child yield entry_child
def _set_collection_variables( def _set_collection_variables(self, collection_url: UrlValidator, entry: Entry | EntryParent):
self, collection_url: CollectionUrlValidator, entry: Entry | EntryParent
):
if isinstance(entry, EntryParent): if isinstance(entry, EntryParent):
for child in entry.parent_children(): for child in entry.parent_children():
self._set_collection_variables(collection_url, child) self._set_collection_variables(collection_url, child)
@ -495,7 +493,7 @@ class Downloader(DownloadArchiver, Generic[DownloaderOptionsT], ABC):
entry.add_variables(variables_to_add=collection_url.variables.dict_with_format_strings) entry.add_variables(variables_to_add=collection_url.variables.dict_with_format_strings)
def _download_url_metadata( def _download_url_metadata(
self, collection_url: CollectionUrlValidator self, collection_url: UrlValidator
) -> Tuple[List[EntryParent], List[Entry]]: ) -> Tuple[List[EntryParent], List[Entry]]:
""" """
Downloads only info.json files and forms EntryParent trees Downloads only info.json files and forms EntryParent trees
@ -594,7 +592,7 @@ class Downloader(DownloadArchiver, Generic[DownloaderOptionsT], ABC):
def _download_parent_thumbnails( def _download_parent_thumbnails(
self, self,
thumbnails_downloaded: Set[str], thumbnails_downloaded: Set[str],
thumbnail_list_info: CollectionThumbnailListValidator, thumbnail_list_info: UrlThumbnailListValidator,
entry: Entry, entry: Entry,
is_last_entry: bool, is_last_entry: bool,
parent: EntryParent, parent: EntryParent,
@ -637,9 +635,7 @@ class Downloader(DownloadArchiver, Generic[DownloaderOptionsT], ABC):
return thumbnails_downloaded return thumbnails_downloaded
def _download_url_thumbnails( def _download_url_thumbnails(self, collection_url: UrlValidator, entries: List[Entry]):
self, collection_url: CollectionUrlValidator, entries: List[Entry]
):
""" """
After all media entries have been downloaded, post processed, and moved to the output After all media entries have been downloaded, post processed, and moved to the output
directory, run this function. This lets the downloader add any extra files directly to the directory, run this function. This lets the downloader add any extra files directly to the

View file

@ -1,9 +1,9 @@
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.downloaders.generic.collection_validator import CollectionValidator from ytdl_sub.downloaders.generic.validators import MultiUrlValidator
class CollectionDownloadOptions(CollectionValidator, DownloaderValidator): class MultiUrlDownloadOptions(MultiUrlValidator, DownloaderValidator):
""" """
Downloads from multiple URLs. If an entry is returned from more than one URL, it will Downloads from multiple URLs. If an entry is returned from more than one URL, it will
resolve to the bottom-most URL settings. resolve to the bottom-most URL settings.
@ -16,7 +16,7 @@ class CollectionDownloadOptions(CollectionValidator, DownloaderValidator):
my_example_preset: my_example_preset:
download: download:
# required # required
download_strategy: "collection" download_strategy: "multi_url"
urls: urls:
- url: "youtube.com/channel/UCsvn_Po0SmunchJYtttWpOxMg" - url: "youtube.com/channel/UCsvn_Po0SmunchJYtttWpOxMg"
variables: variables:
@ -39,10 +39,10 @@ class CollectionDownloadOptions(CollectionValidator, DownloaderValidator):
""" """
@property @property
def collection_validator(self) -> CollectionValidator: def collection_validator(self) -> MultiUrlValidator:
"""Returns itself!""" """Returns itself!"""
return self return self
class CollectionDownloader(Downloader[CollectionDownloadOptions]): class MultiUrlDownloader(Downloader[MultiUrlDownloadOptions]):
downloader_options_type = CollectionDownloadOptions downloader_options_type = MultiUrlDownloadOptions

View file

@ -1,10 +1,10 @@
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.downloaders.generic.collection_validator import CollectionUrlValidator from ytdl_sub.downloaders.generic.validators import MultiUrlValidator
from ytdl_sub.downloaders.generic.collection_validator import CollectionValidator from ytdl_sub.downloaders.generic.validators import UrlValidator
class SourceDownloadOptions(CollectionUrlValidator, DownloaderValidator): class UrlDownloadOptions(UrlValidator, DownloaderValidator):
""" """
Downloads from a single URL supported by yt-dlp. Downloads from a single URL supported by yt-dlp.
@ -27,13 +27,13 @@ class SourceDownloadOptions(CollectionUrlValidator, DownloaderValidator):
""" """
@property @property
def collection_validator(self) -> CollectionValidator: def collection_validator(self) -> MultiUrlValidator:
"""Returns itself!""" """Returns itself!"""
return CollectionValidator( return MultiUrlValidator(
name=self._name, name=self._name,
value={"urls": [self._value]}, value={"urls": [self._value]},
) )
class SourceDownloader(Downloader[SourceDownloadOptions]): class UrlDownloader(Downloader[UrlDownloadOptions]):
downloader_options_type = SourceDownloadOptions downloader_options_type = UrlDownloadOptions

View file

@ -11,7 +11,7 @@ from ytdl_sub.validators.string_formatter_validators import StringFormatterValid
from ytdl_sub.validators.validators import ListValidator from ytdl_sub.validators.validators import ListValidator
class CollectionThumbnailValidator(StrictDictValidator): class UrlThumbnailValidator(StrictDictValidator):
_required_keys = {"name", "uid"} _required_keys = {"name", "uid"}
def __init__(self, name, value): def __init__(self, name, value):
@ -35,11 +35,11 @@ class CollectionThumbnailValidator(StrictDictValidator):
return self._uid return self._uid
class CollectionThumbnailListValidator(ListValidator[CollectionThumbnailValidator]): class UrlThumbnailListValidator(ListValidator[UrlThumbnailValidator]):
_inner_list_type = CollectionThumbnailValidator _inner_list_type = UrlThumbnailValidator
class CollectionUrlValidator(StrictDictValidator): class UrlValidator(StrictDictValidator):
_required_keys = {"url"} _required_keys = {"url"}
_optional_keys = {"variables", "source_thumbnails", "playlist_thumbnails"} _optional_keys = {"variables", "source_thumbnails", "playlist_thumbnails"}
@ -62,10 +62,10 @@ class CollectionUrlValidator(StrictDictValidator):
) )
self._source_thumbnails = self._validate_key_if_present( self._source_thumbnails = self._validate_key_if_present(
key="source_thumbnails", validator=CollectionThumbnailListValidator, default=[] key="source_thumbnails", validator=UrlThumbnailListValidator, default=[]
) )
self._playlist_thumbnails = self._validate_key_if_present( self._playlist_thumbnails = self._validate_key_if_present(
key="playlist_thumbnails", validator=CollectionThumbnailListValidator, default=[] key="playlist_thumbnails", validator=UrlThumbnailListValidator, default=[]
) )
@property @property
@ -86,7 +86,7 @@ class CollectionUrlValidator(StrictDictValidator):
return self._variables return self._variables
@property @property
def source_thumbnails(self) -> Optional[CollectionThumbnailListValidator]: def source_thumbnails(self) -> Optional[UrlThumbnailListValidator]:
""" """
Thumbnails to download from the source, if any exist. The hierarchy is defined as Thumbnails to download from the source, if any exist. The hierarchy is defined as
source -> playlist -> entry. source -> playlist -> entry.
@ -105,7 +105,7 @@ class CollectionUrlValidator(StrictDictValidator):
return self._source_thumbnails return self._source_thumbnails
@property @property
def playlist_thumbnails(self) -> Optional[CollectionThumbnailListValidator]: def playlist_thumbnails(self) -> Optional[UrlThumbnailListValidator]:
""" """
Thumbnails to download from the source, if any exist. The hierarchy is defined as Thumbnails to download from the source, if any exist. The hierarchy is defined as
source -> playlist -> entry. source -> playlist -> entry.
@ -124,8 +124,8 @@ class CollectionUrlValidator(StrictDictValidator):
return self._playlist_thumbnails return self._playlist_thumbnails
class CollectionUrlListValidator(ListValidator[CollectionUrlValidator]): class UrlListValidator(ListValidator[UrlValidator]):
_inner_list_type = CollectionUrlValidator _inner_list_type = UrlValidator
_expected_value_type_name = "collection url list" _expected_value_type_name = "collection url list"
def __init__(self, name, value): def __init__(self, name, value):
@ -151,7 +151,7 @@ class CollectionUrlListValidator(ListValidator[CollectionUrlValidator]):
collection_variables[var] = added_variables[var] collection_variables[var] = added_variables[var]
class CollectionValidator(StrictDictValidator, AddsVariablesMixin): class MultiUrlValidator(StrictDictValidator, AddsVariablesMixin):
""" """
Downloads from multiple URLs. If an entry is returned from more than one URL, it will Downloads from multiple URLs. If an entry is returned from more than one URL, it will
resolve to the bottom-most URL settings. resolve to the bottom-most URL settings.
@ -170,10 +170,10 @@ class CollectionValidator(StrictDictValidator, AddsVariablesMixin):
def __init__(self, name, value): def __init__(self, name, value):
super().__init__(name, value) super().__init__(name, value)
self._urls = self._validate_key(key="urls", validator=CollectionUrlListValidator) self._urls = self._validate_key(key="urls", validator=UrlListValidator)
@property @property
def collection_urls(self) -> CollectionUrlListValidator: def collection_urls(self) -> UrlListValidator:
""" """
Required. The Soundcloud user's url, i.e. ``soundcloud.com/the_username`` Required. The Soundcloud user's url, i.e. ``soundcloud.com/the_username``
""" """

View file

@ -4,7 +4,7 @@ from typing import Generator
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.downloaders.generic.collection_validator import CollectionValidator from ytdl_sub.downloaders.generic.validators import MultiUrlValidator
from ytdl_sub.entries.entry import Entry from ytdl_sub.entries.entry import Entry
from ytdl_sub.validators.url_validator import SoundcloudUsernameUrlValidator from ytdl_sub.validators.url_validator import SoundcloudUsernameUrlValidator
from ytdl_sub.validators.validators import BoolValidator from ytdl_sub.validators.validators import BoolValidator
@ -52,9 +52,9 @@ class SoundcloudAlbumsAndSinglesDownloadOptions(DownloaderValidator):
) )
@property @property
def collection_validator(self) -> CollectionValidator: def collection_validator(self) -> MultiUrlValidator:
"""Downloads the album tracks first, then the tracks""" """Downloads the album tracks first, then the tracks"""
return CollectionValidator( return MultiUrlValidator(
name=self._name, name=self._name,
value={ value={
"urls": [ "urls": [

View file

@ -5,7 +5,7 @@ from typing import Optional
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.downloaders.generic.collection_validator import CollectionValidator from ytdl_sub.downloaders.generic.validators import MultiUrlValidator
from ytdl_sub.validators.string_formatter_validators import OverridesStringFormatterValidator from ytdl_sub.validators.string_formatter_validators import OverridesStringFormatterValidator
from ytdl_sub.validators.url_validator import YoutubeChannelUrlValidator from ytdl_sub.validators.url_validator import YoutubeChannelUrlValidator
@ -59,7 +59,7 @@ class YoutubeChannelDownloaderOptions(DownloaderValidator):
) )
@property @property
def collection_validator(self) -> CollectionValidator: def collection_validator(self) -> MultiUrlValidator:
"""Download from the channel url""" """Download from the channel url"""
playlist_thumbnails: List[Dict] = [] playlist_thumbnails: List[Dict] = []
if self._channel_avatar_path: if self._channel_avatar_path:
@ -77,7 +77,7 @@ class YoutubeChannelDownloaderOptions(DownloaderValidator):
} }
) )
return CollectionValidator( return MultiUrlValidator(
name=self._name, name=self._name,
value={ value={
"urls": [ "urls": [

View file

@ -5,7 +5,7 @@ from typing import Optional
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.downloaders.generic.collection_validator import CollectionValidator from ytdl_sub.downloaders.generic.validators import MultiUrlValidator
from ytdl_sub.utils.thumbnail import ThumbnailTypes from ytdl_sub.utils.thumbnail import ThumbnailTypes
from ytdl_sub.validators.string_formatter_validators import OverridesStringFormatterValidator from ytdl_sub.validators.string_formatter_validators import OverridesStringFormatterValidator
from ytdl_sub.validators.url_validator import YoutubePlaylistUrlValidator from ytdl_sub.validators.url_validator import YoutubePlaylistUrlValidator
@ -53,7 +53,7 @@ class YoutubePlaylistDownloaderOptions(DownloaderValidator):
) )
@property @property
def collection_validator(self) -> CollectionValidator: def collection_validator(self) -> MultiUrlValidator:
"""Downloads the playlist url""" """Downloads the playlist url"""
playlist_thumbnails: List[Dict] = [] playlist_thumbnails: List[Dict] = []
if self.playlist_thumbnail_name: if self.playlist_thumbnail_name:
@ -64,7 +64,7 @@ class YoutubePlaylistDownloaderOptions(DownloaderValidator):
} }
) )
return CollectionValidator( return MultiUrlValidator(
name=self._name, name=self._name,
value={ value={
"urls": [ "urls": [

View file

@ -3,8 +3,8 @@ from typing import Dict
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.downloaders.generic.collection_validator import CollectionValidator from ytdl_sub.downloaders.generic.url import UrlDownloadOptions
from ytdl_sub.downloaders.generic.source import SourceDownloadOptions from ytdl_sub.downloaders.generic.validators import MultiUrlValidator
from ytdl_sub.validators.url_validator import YoutubeVideoUrlValidator from ytdl_sub.validators.url_validator import YoutubeVideoUrlValidator
@ -47,9 +47,9 @@ class YoutubeVideoDownloaderOptions(DownloaderValidator):
self._video_url = self._validate_key("video_url", YoutubeVideoUrlValidator).video_url self._video_url = self._validate_key("video_url", YoutubeVideoUrlValidator).video_url
@property @property
def collection_validator(self) -> CollectionValidator: def collection_validator(self) -> MultiUrlValidator:
"""Downloads the video url""" """Downloads the video url"""
return SourceDownloadOptions( return UrlDownloadOptions(
name=self._name, value={"url": self.video_url} name=self._name, value={"url": self.video_url}
).collection_validator ).collection_validator

View file

@ -2,7 +2,7 @@ presets:
kodi_music_video: kodi_music_video:
download: download:
download_strategy: "source" download_strategy: "url"
url: "{music_video_url}" url: "{music_video_url}"
output_options: output_options:

View file

@ -29,7 +29,7 @@ presets:
# TV show from any single source. Uses latest entry's thumbnail as tv show poster # TV show from any single source. Uses latest entry's thumbnail as tv show poster
_tv_show_by_date: _tv_show_by_date:
download: download:
download_strategy: "source" download_strategy: "url"
url: "{url}" url: "{url}"
playlist_thumbnails: playlist_thumbnails:
- name: "{tv_show_poster_file_name}" - name: "{tv_show_poster_file_name}"
@ -43,7 +43,7 @@ presets:
# addition. Each season sets its own `collection_season_number/_padded` # addition. Each season sets its own `collection_season_number/_padded`
_tv_show_collection: _tv_show_collection:
download: download:
download_strategy: "collection" download_strategy: "multi_url"
overrides: overrides:
season_number: "{collection_season_number}" season_number: "{collection_season_number}"

View file

@ -18,7 +18,7 @@ presets:
collection_season_1: collection_season_1:
download: download:
download_strategy: "collection" download_strategy: "multi_url"
urls: urls:
- url: "{collection_season_1_url}" - url: "{collection_season_1_url}"
variables: variables:
@ -43,7 +43,7 @@ presets:
collection_season_2: collection_season_2:
download: download:
download_strategy: "collection" download_strategy: "multi_url"
urls: urls:
- url: "{collection_season_2_url}" - url: "{collection_season_2_url}"
variables: variables:
@ -62,7 +62,7 @@ presets:
collection_season_3: collection_season_3:
download: download:
download_strategy: "collection" download_strategy: "multi_url"
urls: urls:
- url: "{collection_season_3_url}" - url: "{collection_season_3_url}"
variables: variables:
@ -81,7 +81,7 @@ presets:
collection_season_4: collection_season_4:
download: download:
download_strategy: "collection" download_strategy: "multi_url"
urls: urls:
- url: "{collection_season_4_url}" - url: "{collection_season_4_url}"
variables: variables:
@ -100,7 +100,7 @@ presets:
collection_season_5: collection_season_5:
download: download:
download_strategy: "collection" download_strategy: "multi_url"
urls: urls:
- url: "{collection_season_5_url}" - url: "{collection_season_5_url}"
variables: variables:

View file

@ -85,12 +85,12 @@ class TestConfigFilePartiallyValidatesPresets:
preset_dict={"download": {"download_strategy": "fail"}}, preset_dict={"download": {"download_strategy": "fail"}},
expected_error_message="Validation error in partial_preset.download: " expected_error_message="Validation error in partial_preset.download: "
"Tried to use download strategy 'fail' with source 'download', " "Tried to use download strategy 'fail' with source 'download', "
"which does not exist. Available download strategies: collection, source", "which does not exist. Available download strategies: multi_url, url",
) )
def test_error__bad_download_strategy_args(self): def test_error__bad_download_strategy_args(self):
self._partial_validate( self._partial_validate(
preset_dict={"download": {"download_strategy": "collection", "bad_key": "nope"}}, preset_dict={"download": {"download_strategy": "multi_url", "bad_key": "nope"}},
expected_error_message="Validation error in partial_preset.download: " expected_error_message="Validation error in partial_preset.download: "
"'partial_preset.download' contains the field 'bad_key' which is not allowed. " "'partial_preset.download' contains the field 'bad_key' which is not allowed. "
"Allowed fields: urls", "Allowed fields: urls",