From a3ea217a5e8fe612cf9bb8254a9dcad4fffa0287 Mon Sep 17 00:00:00 2001 From: jbannon Date: Wed, 4 May 2022 06:32:24 +0000 Subject: [PATCH] more docs --- docs/config/index.rst | 32 ++++++++++++++++++- .../downloaders/soundcloud_downloader.py | 22 ++++++++++--- .../downloaders/youtube_downloader.py | 29 +++++++++++++++-- .../validators/date_range_validator.py | 20 +++++++++--- 4 files changed, 90 insertions(+), 13 deletions(-) diff --git a/docs/config/index.rst b/docs/config/index.rst index d0dc34f0..36094e27 100644 --- a/docs/config/index.rst +++ b/docs/config/index.rst @@ -1,7 +1,37 @@ 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:: :titlesonly: diff --git a/src/ytdl_sub/downloaders/soundcloud_downloader.py b/src/ytdl_sub/downloaders/soundcloud_downloader.py index 8b0509d9..af55b8d6 100644 --- a/src/ytdl_sub/downloaders/soundcloud_downloader.py +++ b/src/ytdl_sub/downloaders/soundcloud_downloader.py @@ -24,10 +24,17 @@ class SoundcloudDownloaderOptions(DownloaderValidator, ABC): def __init__(self, name: str, value: dict): 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 ) + @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", bound=SoundcloudDownloaderOptions @@ -68,7 +75,14 @@ class SoundcloudAlbumsAndSinglesDownloadOptions(SoundcloudDownloaderOptions): def __init__(self, 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( @@ -132,7 +146,7 @@ class SoundcloudAlbumsAndSinglesDownloader( """ 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) # Get all of the artist's albums @@ -146,7 +160,7 @@ class SoundcloudAlbumsAndSinglesDownloader( tracks += album.album_tracks() # 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()] return tracks diff --git a/src/ytdl_sub/downloaders/youtube_downloader.py b/src/ytdl_sub/downloaders/youtube_downloader.py index 8f4ed770..4d82059f 100644 --- a/src/ytdl_sub/downloaders/youtube_downloader.py +++ b/src/ytdl_sub/downloaders/youtube_downloader.py @@ -134,14 +134,37 @@ class YoutubeChannelDownloaderOptions(YoutubeDownloaderOptions, DateRangeValidat def __init__(self, name, value): YoutubeDownloaderOptions.__init__(self, name, value) DateRangeValidator.__init__(self, name, value) - self.channel_id = self._validate_key("channel_id", StringValidator) - self.channel_avatar_path = self._validate_key_if_present( + self._channel_id = self._validate_key("channel_id", StringValidator) + self._channel_avatar_path = self._validate_key_if_present( "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 ) + @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]): downloader_options_type = YoutubeChannelDownloaderOptions diff --git a/src/ytdl_sub/validators/date_range_validator.py b/src/ytdl_sub/validators/date_range_validator.py index d69a06ac..aa0268bd 100644 --- a/src/ytdl_sub/validators/date_range_validator.py +++ b/src/ytdl_sub/validators/date_range_validator.py @@ -11,8 +11,18 @@ class DateRangeValidator(StrictDictValidator): def __init__(self, name, value): super().__init__(name, value) - self.before = self._validate_key_if_present("before", StringDatetimeValidator) - self.after = self._validate_key_if_present("after", StringDatetimeValidator) + self._before = self._validate_key_if_present("before", 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]: """ @@ -20,9 +30,9 @@ class DateRangeValidator(StrictDictValidator): ------- 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( - start=self.after.datetime_str if self.after else None, - end=self.before.datetime_str if self.before else None, + start=self._after.datetime_str if self._after else None, + end=self._before.datetime_str if self._before else None, ) return None