ytdl-sub/src/ytdl_sub/downloaders/youtube/playlist.py
2022-09-28 00:17:18 -07:00

104 lines
3.3 KiB
Python

from typing import Dict
from typing import List
from typing import Optional
from ytdl_sub.downloaders.downloader import Downloader
from ytdl_sub.downloaders.downloader import DownloaderValidator
from ytdl_sub.downloaders.generic.collection_validator import CollectionValidator
from ytdl_sub.utils.thumbnail import ThumbnailTypes
from ytdl_sub.validators.string_formatter_validators import OverridesStringFormatterValidator
from ytdl_sub.validators.url_validator import YoutubePlaylistUrlValidator
class YoutubePlaylistDownloaderOptions(DownloaderValidator):
"""
Downloads all videos from a youtube playlist.
Usage:
.. code-block:: yaml
presets:
my_example_preset:
youtube:
# required
download_strategy: "playlist"
playlist_url: "https://www.youtube.com/playlist?list=UCsvn_Po0SmunchJYtttWpOxMg"
# optional
playlist_thumbnail_name: "poster.jpg"
"""
_required_keys = {"playlist_url"}
_optional_keys = {"playlist_thumbnail_name"}
def __init__(self, name, value):
super().__init__(name, value)
self._playlist_url = self._validate_key(
"playlist_url", YoutubePlaylistUrlValidator
).playlist_url
self._playlist_thumbnail_name = self._validate_key_if_present(
"playlist_thumbnail_name", OverridesStringFormatterValidator
)
@property
def collection_validator(self) -> CollectionValidator:
"""Downloads the playlist url"""
playlist_thumbnails: List[Dict] = []
if self.playlist_thumbnail_name:
playlist_thumbnails.append(
{
"name": self.playlist_thumbnail_name.format_string,
"uid": ThumbnailTypes.LATEST_ENTRY,
}
)
return CollectionValidator(
name=self._name,
value={
"urls": [
{
"url": self.playlist_url,
"playlist_thumbnails": playlist_thumbnails,
"variables": {"playlist_size": "{playlist_count}"},
}
]
},
)
@property
def playlist_url(self) -> str:
"""
Required. The playlist's url, i.e.
``https://www.youtube.com/playlist?list=UCsvn_Po0SmunchJYtttWpOxMg``.
"""
return self._playlist_url
@property
def playlist_thumbnail_name(self) -> Optional[OverridesStringFormatterValidator]:
"""
Optional. Path to store the playlist's thumbnail
"""
return self._playlist_thumbnail_name
class YoutubePlaylistDownloader(Downloader[YoutubePlaylistDownloaderOptions]):
downloader_options_type = YoutubePlaylistDownloaderOptions
# pylint: disable=line-too-long
@classmethod
def ytdl_option_defaults(cls) -> Dict:
"""
Default `ytdl_options`_ for ``playlist``
.. code-block:: yaml
ytdl_options:
ignoreerrors: True # ignore errors like hidden videos, age restriction, etc
break_on_existing: True # stop downloads (newest to oldest) if a video is already downloaded
"""
return dict(
super().ytdl_option_defaults(),
**{"break_on_existing": True},
)
# pylint: enable=line-too-long