discography test

This commit is contained in:
jbannon 2022-05-30 07:03:40 +00:00
parent 70b78047ba
commit 517709b8a4
5 changed files with 142 additions and 16 deletions

View file

@ -65,6 +65,24 @@ class SoundcloudDownloader(
"""Returns full artist url""" """Returns full artist url"""
return f"https://soundcloud.com/{artist_name}" return f"https://soundcloud.com/{artist_name}"
@classmethod
def artist_albums_url(cls, artist_name: str) -> str:
"""
Returns
-------
Full artist album url
"""
return cls.artist_url(artist_name) + "/albums"
@classmethod
def artist_tracks_url(cls, artist_name: str) -> str:
"""
Returns
-------
Full artist tracks url
"""
return cls.artist_url(artist_name) + "/tracks"
############################################################################### ###############################################################################
# Soundcloud albums and singles downloader + options # Soundcloud albums and singles downloader + options
@ -139,21 +157,15 @@ class SoundcloudAlbumsAndSinglesDownloader(
return list(albums.values()) return list(albums.values())
def _get_singles(self, entry_dicts: List[Dict]) -> List[SoundcloudTrack]: def _get_singles(
artist_id = None self, entry_dicts: List[Dict], albums: List[SoundcloudAlbum]
) -> List[SoundcloudTrack]:
tracks: List[SoundcloudTrack] = [] tracks: List[SoundcloudTrack] = []
# First, get the artist entry. All single tracks that do not belong to an album will belong # Get all tracks that are not part of an album
# to the 'artist' playlist
for entry_dict in entry_dicts: for entry_dict in entry_dicts:
if entry_dict.get("extractor") == "soundcloud:user": if entry_dict.get("extractor") == "soundcloud" and not any(
artist_id = entry_dict["id"] entry_dict in album for album in albums
# Then, get all singles that belong to the 'artist' playlist
for entry_dict in entry_dicts:
if (
entry_dict.get("extractor") == "soundcloud"
and entry_dict.get("playlist_id") == artist_id
): ):
tracks.append( tracks.append(
SoundcloudTrack(entry_dict=entry_dict, working_directory=self.working_directory) SoundcloudTrack(entry_dict=entry_dict, working_directory=self.working_directory)
@ -165,14 +177,17 @@ 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) artist_albums_url = self.artist_albums_url(artist_name=self.download_options.username)
entry_dicts = self.extract_info_via_info_json(url=artist_url) artist_tracks_url = self.artist_tracks_url(artist_name=self.download_options.username)
album_entry_dicts = self.extract_info_via_info_json(url=artist_albums_url)
tracks_entry_dicts = self.extract_info_via_info_json(url=artist_tracks_url)
# Get all of the artist's albums # Get all of the artist's albums
albums = self._get_albums(entry_dicts=entry_dicts) albums = self._get_albums(entry_dicts=album_entry_dicts)
# Then, get all singles # Then, get all singles
tracks = self._get_singles(entry_dicts=entry_dicts) tracks = self._get_singles(entry_dicts=tracks_entry_dicts, albums=albums)
# Append all album tracks as SoundcloudAlbumTrack classes to the singles # Append all album tracks as SoundcloudAlbumTrack classes to the singles
for album in albums: for album in albums:

View file

@ -134,3 +134,13 @@ class SoundcloudAlbum(Entry):
Number of tracks in the album (technically a playlist) Number of tracks in the album (technically a playlist)
""" """
return self.kwargs("playlist_count") return self.kwargs("playlist_count")
def __contains__(self, item):
"""
Returns
-------
True if the the item (entry_dict) has the same id as one of the tracks. False otherwise.
"""
if isinstance(item, dict):
return any(item.get("id") == track.uid for track in self.tracks)
return False

View file

View file

@ -0,0 +1,101 @@
from pathlib import Path
import pytest
from e2e.expected_download import ExpectedDownload
from ytdl_sub.config.config_file import ConfigFile
from ytdl_sub.config.preset import Preset
from ytdl_sub.subscriptions.subscription import Subscription
@pytest.fixture
def config_path():
return "examples/soundcloud_discography_config.yaml"
@pytest.fixture
def subscription_name():
return "jb"
@pytest.fixture
def config(config_path):
return ConfigFile.from_file_path(config_path=config_path)
@pytest.fixture
def subscription_dict(output_directory, subscription_name):
return {
"preset": "sc_discography",
"soundcloud": {"username": "jessebannon"},
# override the output directory with our fixture-generated dir
"output_options": {"output_directory": output_directory + "/{artist_sanitized}"},
# download the worst format so it is fast
"ytdl_options": {
"format": "worst[ext=mp3]",
},
"overrides": {"artist": "j_b"},
}
@pytest.fixture
def discography_subscription(config, subscription_name, subscription_dict):
discography_preset = Preset.from_dict(
config=config,
preset_name=subscription_name,
preset_dict=subscription_dict,
)
return Subscription.from_preset(
preset=discography_preset,
config=config,
)
@pytest.fixture
def expected_discography_download():
# turn off black formatter here for readability
# fmt: off
return ExpectedDownload(
expected_md5_file_hashes={
# Download mapping
Path("j_b/.ytdl-sub-jb-download-archive.json"): "7d7615294db4be55a75f644d30ff2de1",
# Entry files (singles)
Path("j_b/[2021] Baby Santana's Dorian Groove/01 - Baby Santana's Dorian Groove.mp3"): "bffbd558e12c6a9e029dc136a88342c4",
Path("j_b/[2021] Baby Santana's Dorian Groove/folder.jpg"): "511c43d7e939c70953cf2cd3cd437072",
Path("j_b/[2021] Purple Clouds/01 - Purple Clouds.mp3"): "038db58aebe2ba875b733932b42a94d6",
Path("j_b/[2021] Purple Clouds/folder.jpg"): "511c43d7e939c70953cf2cd3cd437072",
# Entry files (albums)
Path("j_b/[2022] Acoustic Treats/01 - 20160426 184214.mp3"): "e145f0a2f6012768280c38655ca58065",
Path("j_b/[2022] Acoustic Treats/02 - 20160502 123150.mp3"): "60c8b8817a197a13e4bb90903af612c5",
Path("j_b/[2022] Acoustic Treats/03 - 20160504 143832.mp3"): "8265b7e4f79878af877bc6ecd9757efe",
Path("j_b/[2022] Acoustic Treats/04 - 20160601 221234.mp3"): "accf46b76891d2954b893d0f91d82816",
Path("j_b/[2022] Acoustic Treats/05 - 20160601 222440.mp3"): "e1f584f523336160d5c1104a61de77f3",
Path("j_b/[2022] Acoustic Treats/06 - 20170604 190236.mp3"): "f6885b25901177f0357649afe97328cc",
Path("j_b/[2022] Acoustic Treats/07 - 20170612 193646.mp3"): "fa057f221cbe4cf2442cd2fdb960743e",
Path("j_b/[2022] Acoustic Treats/08 - 20170628 215206.mp3"): "7794ae812c64580e2ac8fc457d5cc85f",
Path("j_b/[2022] Acoustic Treats/09 - Finding Home.mp3"): "adbf02eddb2090c008eb497d13ff84b9",
Path("j_b/[2022] Acoustic Treats/10 - Shallow Water WIP.mp3"): "65bb10c84366c71498161734f953e93d",
Path("j_b/[2022] Acoustic Treats/11 - Untold History.mp3"): "6904b2918e5dc38d9a9f72d967eb74bf",
Path("j_b/[2022] Acoustic Treats/folder.jpg"): "511c43d7e939c70953cf2cd3cd437072",
}
)
# fmt: on
class TestSoundcloudDiscography:
"""
Downloads my (bad) SC recordings I made. Ensure the above files exist and have the
expected md5 file hashes.
"""
def test_discography_download(
self, discography_subscription, expected_discography_download, output_directory
):
discography_subscription.download()
expected_discography_download.assert_files_exist(relative_directory=output_directory)