kill soundcloud downloader

This commit is contained in:
Jesse Bannon 2022-09-12 14:19:38 -07:00
parent a6052160bf
commit a16fca5fde
3 changed files with 34 additions and 103 deletions

View file

@ -1,65 +0,0 @@
from abc import ABC
from typing import Generic
from typing import TypeVar
from ytdl_sub.downloaders.downloader import Downloader
from ytdl_sub.downloaders.downloader import DownloaderValidator
from ytdl_sub.entries.soundcloud import SoundcloudTrack
from ytdl_sub.validators.validators import BoolValidator
class SoundcloudDownloaderOptions(DownloaderValidator, ABC):
"""
Abstract source validator for all soundcloud sources.
"""
_optional_keys = {"skip_premiere_tracks"}
def __init__(self, name: str, value: dict):
super().__init__(name=name, value=value)
self._skip_premiere_tracks = self._validate_key(
"skip_premiere_tracks", BoolValidator, default=True
)
@property
def skip_premiere_tracks(self) -> bool:
"""
Optional. True to skip tracks that require purchasing. False otherwise. Defaults to True.
"""
return self._skip_premiere_tracks.value
SoundcloudDownloaderOptionsT = TypeVar(
"SoundcloudDownloaderOptionsT", bound=SoundcloudDownloaderOptions
)
class SoundcloudDownloader(
Downloader[SoundcloudDownloaderOptionsT, SoundcloudTrack],
Generic[SoundcloudDownloaderOptionsT],
ABC,
):
"""
Class that handles downloading soundcloud entries via ytdl and converting them into
SoundcloudTrack / SoundcloudAlbumTrack objects
"""
downloader_entry_type = SoundcloudTrack
@classmethod
def artist_albums_url(cls, artist_url: str) -> str:
"""
Returns
-------
Full artist album url
"""
return f"{artist_url}/albums"
@classmethod
def artist_tracks_url(cls, artist_url: str) -> str:
"""
Returns
-------
Full artist tracks url
"""
return f"{artist_url}/tracks"

View file

@ -1,15 +1,17 @@
from typing import Dict
from typing import Generator
from ytdl_sub.downloaders.downloader import Downloader
from ytdl_sub.downloaders.downloader import DownloaderValidator
from ytdl_sub.downloaders.generic.collection import CollectionDownloader
from ytdl_sub.downloaders.generic.collection import CollectionDownloadOptions
from ytdl_sub.downloaders.soundcloud.abc import SoundcloudDownloader
from ytdl_sub.downloaders.soundcloud.abc import SoundcloudDownloaderOptions
from ytdl_sub.entries.entry import Entry
from ytdl_sub.entries.soundcloud import SoundcloudTrack
from ytdl_sub.validators.url_validator import SoundcloudUsernameUrlValidator
from ytdl_sub.validators.validators import BoolValidator
class SoundcloudAlbumsAndSinglesDownloadOptions(SoundcloudDownloaderOptions):
class SoundcloudAlbumsAndSinglesDownloadOptions(DownloaderValidator):
"""
Downloads a soundcloud user's entire discography. Groups together album tracks and considers
any track not in an album as a single. Also includes any collaboration tracks.
@ -30,12 +32,16 @@ class SoundcloudAlbumsAndSinglesDownloadOptions(SoundcloudDownloaderOptions):
"""
_required_keys = {"url"}
_optional_keys = {"skip_premiere_tracks"}
def __init__(self, name, value):
super().__init__(name, value)
self._url = self._validate_key(
key="url", validator=SoundcloudUsernameUrlValidator
).username_url
self._skip_premiere_tracks = self._validate_key(
"skip_premiere_tracks", BoolValidator, default=True
)
self.collection_validator = CollectionDownloadOptions(
name=self._name,
@ -67,6 +73,13 @@ class SoundcloudAlbumsAndSinglesDownloadOptions(SoundcloudDownloaderOptions):
},
)
@property
def skip_premiere_tracks(self) -> bool:
"""
Optional. True to skip tracks that require purchasing. False otherwise. Defaults to True.
"""
return self._skip_premiere_tracks.value
@property
def url(self) -> str:
"""
@ -76,9 +89,11 @@ class SoundcloudAlbumsAndSinglesDownloadOptions(SoundcloudDownloaderOptions):
class SoundcloudAlbumsAndSinglesDownloader(
SoundcloudDownloader[SoundcloudAlbumsAndSinglesDownloadOptions]
Downloader[SoundcloudAlbumsAndSinglesDownloadOptions, SoundcloudTrack]
):
downloader_options_type = SoundcloudAlbumsAndSinglesDownloadOptions
downloader_entry_type = SoundcloudTrack
supports_subtitles = False
supports_chapters = False
@ -100,6 +115,16 @@ class SoundcloudAlbumsAndSinglesDownloader(
},
)
def _should_skip(self, entry: Entry) -> bool:
if not self.download_options.skip_premiere_tracks:
return False
for url in [entry.kwargs_get("url", ""), entry.webpage_url]:
if "/preview/" in url:
return True
return False
def download(self) -> Generator[SoundcloudTrack, None, None]:
"""
Soundcloud subscription to download albums and tracks as singles.
@ -112,4 +137,7 @@ class SoundcloudAlbumsAndSinglesDownloader(
)
for entry in downloader.download():
if self._should_skip(entry):
continue
yield entry

View file

@ -1,6 +1,8 @@
from ytdl_sub.entries.entry import Entry
from ytdl_sub.entries.variables.soundcloud_variables import SoundcloudVariables
# TODO: Delete since not used
class SoundcloudTrack(SoundcloudVariables, Entry):
"""
@ -9,37 +11,3 @@ class SoundcloudTrack(SoundcloudVariables, Entry):
"""
entry_extractor = "soundcloud"
def is_premiere(self) -> bool:
"""
Returns whether the entry is a premier track. Check this by seeing if the track's url is
a preview.
"""
return "/preview/" in self.kwargs("url")
class SoundcloudAlbumTrack(SoundcloudTrack):
"""
Entry object to represent a Soundcloud track yt-dlp that belongs to an album.
"""
@property
def track_number(self) -> int:
"""Returns the entry's track number"""
return self.kwargs("playlist_index")
@property
def track_count(self) -> int:
"""Returns the entry's total tracks in album"""
return self.kwargs("playlist_count")
@property
def album(self) -> str:
"""Returns the entry's album name, fetched from its internal album"""
return self.kwargs("playlist")
@property
def album_year(self) -> int:
"""Returns the entry's album year, fetched from its internal album"""
# added from parent entry
return self._additional_variables["playlist_max_upload_year"]