more docs
This commit is contained in:
parent
b37a138f65
commit
a3ea217a5e
4 changed files with 90 additions and 13 deletions
|
|
@ -1,7 +1,37 @@
|
||||||
Configuration
|
Configuration
|
||||||
=============
|
=============
|
||||||
|
|
||||||
Hello, WIP
|
|
||||||
|
Source and Download Strategy
|
||||||
|
----------------------------
|
||||||
|
Download strategies dictate what exactly is getting downloaded from which
|
||||||
|
source. By having separate strategies, we can define strategy-dependent
|
||||||
|
parameters to better fine-tune how we download things.
|
||||||
|
|
||||||
|
youtube: channel
|
||||||
|
^^^^^^^^^^^^^^^^
|
||||||
|
.. autoclass:: ytdl_sub.downloaders.youtube_downloader.YoutubeChannelDownloaderOptions()
|
||||||
|
:members:
|
||||||
|
:inherited-members:
|
||||||
|
:exclude-members: get_date_range
|
||||||
|
|
||||||
|
youtube: playlist
|
||||||
|
^^^^^^^^^^^^^^^^^
|
||||||
|
.. autoclass:: ytdl_sub.downloaders.youtube_downloader.YoutubePlaylistDownloaderOptions()
|
||||||
|
:members:
|
||||||
|
:inherited-members:
|
||||||
|
|
||||||
|
youtube: video
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
.. autoclass:: ytdl_sub.downloaders.youtube_downloader.YoutubeVideoDownloaderOptions()
|
||||||
|
:members:
|
||||||
|
:inherited-members:
|
||||||
|
|
||||||
|
soundcloud: albums_and_singles
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
.. autoclass:: ytdl_sub.downloaders.soundcloud_downloader.SoundcloudAlbumsAndSinglesDownloadOptions()
|
||||||
|
:members:
|
||||||
|
:inherited-members:
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:titlesonly:
|
:titlesonly:
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,17 @@ class SoundcloudDownloaderOptions(DownloaderValidator, ABC):
|
||||||
|
|
||||||
def __init__(self, name: str, value: dict):
|
def __init__(self, name: str, value: dict):
|
||||||
super().__init__(name=name, value=value)
|
super().__init__(name=name, value=value)
|
||||||
self.skip_premiere_tracks = self._validate_key(
|
self._skip_premiere_tracks = self._validate_key(
|
||||||
"skip_premiere_tracks", BoolValidator, default=True
|
"skip_premiere_tracks", BoolValidator, default=True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def skip_premiere_tracks(self) -> bool:
|
||||||
|
"""
|
||||||
|
True to skip tracks that require purchasing. False otherwise.
|
||||||
|
"""
|
||||||
|
return self._skip_premiere_tracks.value
|
||||||
|
|
||||||
|
|
||||||
SoundcloudDownloaderOptionsT = TypeVar(
|
SoundcloudDownloaderOptionsT = TypeVar(
|
||||||
"SoundcloudDownloaderOptionsT", bound=SoundcloudDownloaderOptions
|
"SoundcloudDownloaderOptionsT", bound=SoundcloudDownloaderOptions
|
||||||
|
|
@ -68,7 +75,14 @@ class SoundcloudAlbumsAndSinglesDownloadOptions(SoundcloudDownloaderOptions):
|
||||||
|
|
||||||
def __init__(self, name, value):
|
def __init__(self, name, value):
|
||||||
super().__init__(name, value)
|
super().__init__(name, value)
|
||||||
self.username = self._validate_key(key="username", validator=StringValidator)
|
self._username = self._validate_key(key="username", validator=StringValidator)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def username(self) -> str:
|
||||||
|
"""
|
||||||
|
The Soundcloud username
|
||||||
|
"""
|
||||||
|
return self._username.value
|
||||||
|
|
||||||
|
|
||||||
class SoundcloudAlbumsAndSinglesDownloader(
|
class SoundcloudAlbumsAndSinglesDownloader(
|
||||||
|
|
@ -132,7 +146,7 @@ class SoundcloudAlbumsAndSinglesDownloader(
|
||||||
"""
|
"""
|
||||||
Soundcloud subscription to download albums and tracks as singles.
|
Soundcloud subscription to download albums and tracks as singles.
|
||||||
"""
|
"""
|
||||||
artist_url = self.artist_url(artist_name=self.download_options.username.value)
|
artist_url = self.artist_url(artist_name=self.download_options.username)
|
||||||
entry_dicts = self.extract_info_via_info_json(url=artist_url)
|
entry_dicts = self.extract_info_via_info_json(url=artist_url)
|
||||||
|
|
||||||
# Get all of the artist's albums
|
# Get all of the artist's albums
|
||||||
|
|
@ -146,7 +160,7 @@ class SoundcloudAlbumsAndSinglesDownloader(
|
||||||
tracks += album.album_tracks()
|
tracks += album.album_tracks()
|
||||||
|
|
||||||
# Filter any premiere tracks if specified
|
# Filter any premiere tracks if specified
|
||||||
if self.download_options.skip_premiere_tracks.value:
|
if self.download_options.skip_premiere_tracks:
|
||||||
tracks = [track for track in tracks if not track.is_premiere()]
|
tracks = [track for track in tracks if not track.is_premiere()]
|
||||||
|
|
||||||
return tracks
|
return tracks
|
||||||
|
|
|
||||||
|
|
@ -134,14 +134,37 @@ class YoutubeChannelDownloaderOptions(YoutubeDownloaderOptions, DateRangeValidat
|
||||||
def __init__(self, name, value):
|
def __init__(self, name, value):
|
||||||
YoutubeDownloaderOptions.__init__(self, name, value)
|
YoutubeDownloaderOptions.__init__(self, name, value)
|
||||||
DateRangeValidator.__init__(self, name, value)
|
DateRangeValidator.__init__(self, name, value)
|
||||||
self.channel_id = self._validate_key("channel_id", StringValidator)
|
self._channel_id = self._validate_key("channel_id", StringValidator)
|
||||||
self.channel_avatar_path = self._validate_key_if_present(
|
self._channel_avatar_path = self._validate_key_if_present(
|
||||||
"channel_avatar_path", OverridesStringFormatterValidator
|
"channel_avatar_path", OverridesStringFormatterValidator
|
||||||
)
|
)
|
||||||
self.channel_banner_path = self._validate_key_if_present(
|
self._channel_banner_path = self._validate_key_if_present(
|
||||||
"channel_banner_path", OverridesStringFormatterValidator
|
"channel_banner_path", OverridesStringFormatterValidator
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def channel_id(self) -> str:
|
||||||
|
"""
|
||||||
|
The channel's ID. Not to be confused with the username. It should look something like
|
||||||
|
`UCsvn_Po0SmunchJYOWpOxMg`. You can get this by opening a video and clicking on the
|
||||||
|
channel's avatar image to take you to their channel, then check the url.
|
||||||
|
"""
|
||||||
|
return self.channel_id
|
||||||
|
|
||||||
|
@property
|
||||||
|
def channel_avatar_path(self) -> Optional[OverridesStringFormatterValidator]:
|
||||||
|
"""
|
||||||
|
Optional. Path to store the channel's avatar thumbnail image to.
|
||||||
|
"""
|
||||||
|
return self._channel_avatar_path
|
||||||
|
|
||||||
|
@property
|
||||||
|
def channel_banner_path(self) -> Optional[OverridesStringFormatterValidator]:
|
||||||
|
"""
|
||||||
|
Optional. Path to store the channel's banner image to.
|
||||||
|
"""
|
||||||
|
return self._channel_banner_path
|
||||||
|
|
||||||
|
|
||||||
class YoutubeChannelDownloader(YoutubeDownloader[YoutubeChannelDownloaderOptions, YoutubeVideo]):
|
class YoutubeChannelDownloader(YoutubeDownloader[YoutubeChannelDownloaderOptions, YoutubeVideo]):
|
||||||
downloader_options_type = YoutubeChannelDownloaderOptions
|
downloader_options_type = YoutubeChannelDownloaderOptions
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,18 @@ class DateRangeValidator(StrictDictValidator):
|
||||||
|
|
||||||
def __init__(self, name, value):
|
def __init__(self, name, value):
|
||||||
super().__init__(name, value)
|
super().__init__(name, value)
|
||||||
self.before = self._validate_key_if_present("before", StringDatetimeValidator)
|
self._before = self._validate_key_if_present("before", StringDatetimeValidator)
|
||||||
self.after = self._validate_key_if_present("after", StringDatetimeValidator)
|
self._after = self._validate_key_if_present("after", StringDatetimeValidator)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def before(self) -> Optional[StringDatetimeValidator]:
|
||||||
|
"""Optional. Only download videos before this datetime."""
|
||||||
|
return self._before
|
||||||
|
|
||||||
|
@property
|
||||||
|
def after(self) -> Optional[StringDatetimeValidator]:
|
||||||
|
"""Optional. Only download videos after this datetime."""
|
||||||
|
return self._after
|
||||||
|
|
||||||
def get_date_range(self) -> Optional[DateRange]:
|
def get_date_range(self) -> Optional[DateRange]:
|
||||||
"""
|
"""
|
||||||
|
|
@ -20,9 +30,9 @@ class DateRangeValidator(StrictDictValidator):
|
||||||
-------
|
-------
|
||||||
Date range if the 'before' or 'after' is defined. None otherwise.
|
Date range if the 'before' or 'after' is defined. None otherwise.
|
||||||
"""
|
"""
|
||||||
if self.before or self.after:
|
if self._before or self._after:
|
||||||
return DateRange(
|
return DateRange(
|
||||||
start=self.after.datetime_str if self.after else None,
|
start=self._after.datetime_str if self._after else None,
|
||||||
end=self.before.datetime_str if self.before else None,
|
end=self._before.datetime_str if self._before else None,
|
||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue