mirror of
https://github.com/KevinMidboe/spotify-downloader.git
synced 2025-10-29 18:00:15 +00:00
Replace class SpotifyAuthorize with @must_be_authorized (#506)
* @must_be_authorized decorator for functions in spotify_tools.py * We don't need this * Add tests * Update CHANGELOG.md
This commit is contained in:
@@ -13,7 +13,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||||||
-
|
-
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
-
|
- Fix writing playlist tracks to file ([@ritiek](https://github.com/ritiek)) (#506)
|
||||||
|
|
||||||
## [1.1.2] - 2019-02-10
|
## [1.1.2] - 2019-02-10
|
||||||
### Changed
|
### Changed
|
||||||
|
|||||||
@@ -202,12 +202,8 @@ class ListDownloader:
|
|||||||
try:
|
try:
|
||||||
track_dl = Downloader(raw_song, number=number)
|
track_dl = Downloader(raw_song, number=number)
|
||||||
track_dl.download_single()
|
track_dl.download_single()
|
||||||
except spotipy.client.SpotifyException:
|
|
||||||
# token expires after 1 hour
|
|
||||||
self._regenerate_token()
|
|
||||||
track_dl.download_single()
|
|
||||||
# detect network problems
|
|
||||||
except (urllib.request.URLError, TypeError, IOError) as e:
|
except (urllib.request.URLError, TypeError, IOError) as e:
|
||||||
|
# detect network problems
|
||||||
self._cleanup(raw_song, e)
|
self._cleanup(raw_song, e)
|
||||||
# TODO: remove this sleep once #397 is fixed
|
# TODO: remove this sleep once #397 is fixed
|
||||||
# wait 0.5 sec to avoid infinite looping
|
# wait 0.5 sec to avoid infinite looping
|
||||||
@@ -233,11 +229,6 @@ class ListDownloader:
|
|||||||
with open(self.write_successful_file, "a") as f:
|
with open(self.write_successful_file, "a") as f:
|
||||||
f.write("\n" + raw_song)
|
f.write("\n" + raw_song)
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _regenerate_token():
|
|
||||||
log.debug("Token expired, generating new one and authorizing")
|
|
||||||
spotify_tools.refresh_token()
|
|
||||||
|
|
||||||
def _cleanup(self, raw_song, exception):
|
def _cleanup(self, raw_song, exception):
|
||||||
self.tracks.append(raw_song)
|
self.tracks.append(raw_song)
|
||||||
# remove the downloaded song from file
|
# remove the downloaded song from file
|
||||||
|
|||||||
@@ -51,7 +51,6 @@ def main():
|
|||||||
|
|
||||||
internals.filter_path(const.args.folder)
|
internals.filter_path(const.args.folder)
|
||||||
youtube_tools.set_api_key()
|
youtube_tools.set_api_key()
|
||||||
spotify = spotify_tools.SpotifyAuthorize()
|
|
||||||
|
|
||||||
logzero.setup_default_logger(formatter=const._formatter, level=const.args.log_level)
|
logzero.setup_default_logger(formatter=const._formatter, level=const.args.log_level)
|
||||||
|
|
||||||
|
|||||||
@@ -8,51 +8,53 @@ from logzero import logger as log
|
|||||||
import pprint
|
import pprint
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
import functools
|
||||||
|
|
||||||
from spotdl import const
|
from spotdl import const
|
||||||
from spotdl import internals
|
from spotdl import internals
|
||||||
|
|
||||||
# token = generate_token()
|
spotify = None
|
||||||
# spotify = spotipy.Spotify(auth=token)
|
|
||||||
|
|
||||||
|
|
||||||
class SpotifyAuthorize:
|
def generate_token():
|
||||||
""" Class to handle all interactions with spotipy instance. """
|
|
||||||
def __init__(self):
|
|
||||||
self.client_id = const.args.spotify_client_id
|
|
||||||
self.client_secret = const.args.spotify_client_secret
|
|
||||||
token = self.generate_token()
|
|
||||||
self.spotify = spotipy.Spotify(auth=token)
|
|
||||||
|
|
||||||
def generate_token(self):
|
|
||||||
""" Generate the token. """
|
""" Generate the token. """
|
||||||
credentials = oauth2.SpotifyClientCredentials(
|
credentials = oauth2.SpotifyClientCredentials(
|
||||||
client_id=self.client_id,
|
client_id=const.args.spotify_client_id,
|
||||||
client_secret=self.client_secret,
|
client_secret=const.args.spotify_client_secret,
|
||||||
)
|
)
|
||||||
token = credentials.get_access_token()
|
token = credentials.get_access_token()
|
||||||
return token
|
return token
|
||||||
|
|
||||||
def refresh_token(self):
|
|
||||||
""" Refresh expired token. """
|
|
||||||
new_token = self.generate_token()
|
|
||||||
self.spotify = spotipy.Spotify(auth=new_token)
|
|
||||||
|
|
||||||
def generate_metadata(self, raw_song):
|
def must_be_authorized(func, spotify=spotify):
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
global spotify
|
||||||
|
try:
|
||||||
|
assert spotify
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
except (AssertionError, spotipy.client.SpotifyException):
|
||||||
|
token = generate_token()
|
||||||
|
spotify = spotipy.Spotify(auth=token)
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
|
@must_be_authorized
|
||||||
|
def generate_metadata(raw_song):
|
||||||
""" Fetch a song's metadata from Spotify. """
|
""" Fetch a song's metadata from Spotify. """
|
||||||
if internals.is_spotify(raw_song):
|
if internals.is_spotify(raw_song):
|
||||||
# fetch track information directly if it is spotify link
|
# fetch track information directly if it is spotify link
|
||||||
log.debug("Fetching metadata for given track URL")
|
log.debug("Fetching metadata for given track URL")
|
||||||
meta_tags = self.spotify.track(raw_song)
|
meta_tags = spotify.track(raw_song)
|
||||||
else:
|
else:
|
||||||
# otherwise search on spotify and fetch information from first result
|
# otherwise search on spotify and fetch information from first result
|
||||||
log.debug('Searching for "{}" on Spotify'.format(raw_song))
|
log.debug('Searching for "{}" on Spotify'.format(raw_song))
|
||||||
try:
|
try:
|
||||||
meta_tags = self.spotify.search(raw_song, limit=1)["tracks"]["items"][0]
|
meta_tags = spotify.search(raw_song, limit=1)["tracks"]["items"][0]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
return None
|
return None
|
||||||
artist = self.spotify.artist(meta_tags["artists"][0]["id"])
|
artist = spotify.artist(meta_tags["artists"][0]["id"])
|
||||||
album = self.spotify.album(meta_tags["album"]["id"])
|
album = spotify.album(meta_tags["album"]["id"])
|
||||||
|
|
||||||
try:
|
try:
|
||||||
meta_tags[u"genre"] = titlecase(artist["genres"][0])
|
meta_tags[u"genre"] = titlecase(artist["genres"][0])
|
||||||
@@ -92,15 +94,19 @@ class SpotifyAuthorize:
|
|||||||
log.debug(pprint.pformat(meta_tags))
|
log.debug(pprint.pformat(meta_tags))
|
||||||
return meta_tags
|
return meta_tags
|
||||||
|
|
||||||
def write_user_playlist(self, username, text_file=None):
|
|
||||||
""" Write user playlists to text_file """
|
|
||||||
links = self.get_playlists(username=username)
|
|
||||||
playlist = internals.input_link(links)
|
|
||||||
return self.write_playlist(playlist, text_file)
|
|
||||||
|
|
||||||
def get_playlists(self, username):
|
@must_be_authorized
|
||||||
|
def write_user_playlist(username, text_file=None):
|
||||||
|
""" Write user playlists to text_file """
|
||||||
|
links = get_playlists(username=username)
|
||||||
|
playlist = internals.input_link(links)
|
||||||
|
return write_playlist(playlist, text_file)
|
||||||
|
|
||||||
|
|
||||||
|
@must_be_authorized
|
||||||
|
def get_playlists(username):
|
||||||
""" Fetch user playlists when using the -u option. """
|
""" Fetch user playlists when using the -u option. """
|
||||||
playlists = self.spotify.user_playlists(username)
|
playlists = spotify.user_playlists(username)
|
||||||
links = []
|
links = []
|
||||||
check = 1
|
check = 1
|
||||||
|
|
||||||
@@ -119,13 +125,15 @@ class SpotifyAuthorize:
|
|||||||
links.append(playlist_url)
|
links.append(playlist_url)
|
||||||
check += 1
|
check += 1
|
||||||
if playlists["next"]:
|
if playlists["next"]:
|
||||||
playlists = self.spotify.next(playlists)
|
playlists = spotify.next(playlists)
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|
||||||
return links
|
return links
|
||||||
|
|
||||||
def fetch_playlist(self, playlist):
|
|
||||||
|
@must_be_authorized
|
||||||
|
def fetch_playlist(playlist):
|
||||||
try:
|
try:
|
||||||
playlist_id = internals.extract_spotify_id(playlist)
|
playlist_id = internals.extract_spotify_id(playlist)
|
||||||
except IndexError:
|
except IndexError:
|
||||||
@@ -133,7 +141,7 @@ class SpotifyAuthorize:
|
|||||||
log.error("The provided playlist URL is not in a recognized format!")
|
log.error("The provided playlist URL is not in a recognized format!")
|
||||||
sys.exit(10)
|
sys.exit(10)
|
||||||
try:
|
try:
|
||||||
results = self.spotify.user_playlist(
|
results = spotify.user_playlist(
|
||||||
user=None, playlist_id=playlist_id, fields="tracks,next,name"
|
user=None, playlist_id=playlist_id, fields="tracks,next,name"
|
||||||
)
|
)
|
||||||
except spotipy.client.SpotifyException:
|
except spotipy.client.SpotifyException:
|
||||||
@@ -143,19 +151,25 @@ class SpotifyAuthorize:
|
|||||||
|
|
||||||
return results
|
return results
|
||||||
|
|
||||||
def write_playlist(self, playlist_url, text_file=None):
|
|
||||||
playlist = self.fetch_playlist(playlist_url)
|
@must_be_authorized
|
||||||
|
def write_playlist(playlist_url, text_file=None):
|
||||||
|
playlist = fetch_playlist(playlist_url)
|
||||||
tracks = playlist["tracks"]
|
tracks = playlist["tracks"]
|
||||||
if not text_file:
|
if not text_file:
|
||||||
text_file = u"{0}.txt".format(slugify(playlist["name"], ok="-_()[]{}"))
|
text_file = u"{0}.txt".format(slugify(playlist["name"], ok="-_()[]{}"))
|
||||||
return self.write_tracks(tracks, text_file)
|
return write_tracks(tracks, text_file)
|
||||||
|
|
||||||
def fetch_album(self, album):
|
|
||||||
|
@must_be_authorized
|
||||||
|
def fetch_album(album):
|
||||||
album_id = internals.extract_spotify_id(album)
|
album_id = internals.extract_spotify_id(album)
|
||||||
album = self.spotify.album(album_id)
|
album = spotify.album(album_id)
|
||||||
return album
|
return album
|
||||||
|
|
||||||
def fetch_albums_from_artist(self, artist_url, album_type=None):
|
|
||||||
|
@must_be_authorized
|
||||||
|
def fetch_albums_from_artist(artist_url, album_type=None):
|
||||||
"""
|
"""
|
||||||
This funcction returns all the albums from a give artist_url using the US
|
This funcction returns all the albums from a give artist_url using the US
|
||||||
market
|
market
|
||||||
@@ -168,19 +182,20 @@ class SpotifyAuthorize:
|
|||||||
# fetching artist's albums limitting the results to the US to avoid duplicate
|
# fetching artist's albums limitting the results to the US to avoid duplicate
|
||||||
# albums from multiple markets
|
# albums from multiple markets
|
||||||
artist_id = internals.extract_spotify_id(artist_url)
|
artist_id = internals.extract_spotify_id(artist_url)
|
||||||
results = self.spotify.artist_albums(artist_id, album_type=album_type, country="US")
|
results = spotify.artist_albums(artist_id, album_type=album_type, country="US")
|
||||||
|
|
||||||
albums = results["items"]
|
albums = results["items"]
|
||||||
|
|
||||||
# indexing all pages of results
|
# indexing all pages of results
|
||||||
while results["next"]:
|
while results["next"]:
|
||||||
results = self.spotify.next(results)
|
results = spotify.next(results)
|
||||||
albums.extend(results["items"])
|
albums.extend(results["items"])
|
||||||
|
|
||||||
return albums
|
return albums
|
||||||
|
|
||||||
|
|
||||||
def write_all_albums_from_artist(self, artist_url, text_file=None):
|
@must_be_authorized
|
||||||
|
def write_all_albums_from_artist(artist_url, text_file=None):
|
||||||
"""
|
"""
|
||||||
This function gets all albums from an artist and writes it to a file in the
|
This function gets all albums from an artist and writes it to a file in the
|
||||||
current working directory called [ARTIST].txt, where [ARTIST] is the artist
|
current working directory called [ARTIST].txt, where [ARTIST] is the artist
|
||||||
@@ -192,7 +207,7 @@ class SpotifyAuthorize:
|
|||||||
album_base_url = "https://open.spotify.com/album/"
|
album_base_url = "https://open.spotify.com/album/"
|
||||||
|
|
||||||
# fetching all default albums
|
# fetching all default albums
|
||||||
albums = self.fetch_albums_from_artist(artist_url, album_type=None)
|
albums = fetch_albums_from_artist(artist_url, album_type=None)
|
||||||
|
|
||||||
# if no file if given, the default save file is in the current working
|
# if no file if given, the default save file is in the current working
|
||||||
# directory with the name of the artist
|
# directory with the name of the artist
|
||||||
@@ -202,16 +217,20 @@ class SpotifyAuthorize:
|
|||||||
for album in albums:
|
for album in albums:
|
||||||
# logging album name
|
# logging album name
|
||||||
log.info("Fetching album: " + album["name"])
|
log.info("Fetching album: " + album["name"])
|
||||||
self.write_album(album_base_url + album["id"], text_file=text_file)
|
write_album(album_base_url + album["id"], text_file=text_file)
|
||||||
|
|
||||||
def write_album(self, album_url, text_file=None):
|
|
||||||
album = self.fetch_album(album_url)
|
@must_be_authorized
|
||||||
tracks = self.spotify.album_tracks(album["id"])
|
def write_album(album_url, text_file=None):
|
||||||
|
album = fetch_album(album_url)
|
||||||
|
tracks = spotify.album_tracks(album["id"])
|
||||||
if not text_file:
|
if not text_file:
|
||||||
text_file = u"{0}.txt".format(slugify(album["name"], ok="-_()[]{}"))
|
text_file = u"{0}.txt".format(slugify(album["name"], ok="-_()[]{}"))
|
||||||
return self.write_tracks(tracks, text_file)
|
return write_tracks(tracks, text_file)
|
||||||
|
|
||||||
def write_tracks(self, tracks, text_file):
|
|
||||||
|
@must_be_authorized
|
||||||
|
def write_tracks(tracks, text_file):
|
||||||
log.info(u"Writing {0} tracks to {1}".format(tracks["total"], text_file))
|
log.info(u"Writing {0} tracks to {1}".format(tracks["total"], text_file))
|
||||||
track_urls = []
|
track_urls = []
|
||||||
with open(text_file, "a") as file_out:
|
with open(text_file, "a") as file_out:
|
||||||
@@ -235,7 +254,7 @@ class SpotifyAuthorize:
|
|||||||
# 1 page = 50 results
|
# 1 page = 50 results
|
||||||
# check if there are more pages
|
# check if there are more pages
|
||||||
if tracks["next"]:
|
if tracks["next"]:
|
||||||
tracks = self.spotify.next(tracks)
|
tracks = spotify.next(tracks)
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
return track_urls
|
return track_urls
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ def go_pafy(raw_song, meta_tags=None):
|
|||||||
def match_video_and_metadata(track):
|
def match_video_and_metadata(track):
|
||||||
""" Get and match track data from YouTube and Spotify. """
|
""" Get and match track data from YouTube and Spotify. """
|
||||||
meta_tags = None
|
meta_tags = None
|
||||||
spotify = spotify_tools.SpotifyAuthorize()
|
|
||||||
|
|
||||||
|
|
||||||
def fallback_metadata(meta_tags):
|
def fallback_metadata(meta_tags):
|
||||||
@@ -68,13 +67,13 @@ def match_video_and_metadata(track):
|
|||||||
content = go_pafy(track, meta_tags=None)
|
content = go_pafy(track, meta_tags=None)
|
||||||
track = slugify(content.title).replace("-", " ")
|
track = slugify(content.title).replace("-", " ")
|
||||||
if not const.args.no_metadata:
|
if not const.args.no_metadata:
|
||||||
meta_tags = spotify.generate_metadata(track)
|
meta_tags = spotify_tools.generate_metadata(track)
|
||||||
meta_tags = fallback_metadata(meta_tags)
|
meta_tags = fallback_metadata(meta_tags)
|
||||||
|
|
||||||
elif internals.is_spotify(track):
|
elif internals.is_spotify(track):
|
||||||
log.debug("Input song is a Spotify URL")
|
log.debug("Input song is a Spotify URL")
|
||||||
# Let it generate metadata, YouTube doesn't know Spotify slang
|
# Let it generate metadata, YouTube doesn't know Spotify slang
|
||||||
meta_tags = spotify.generate_metadata(track)
|
meta_tags = spotify_tools.generate_metadata(track)
|
||||||
content = go_pafy(track, meta_tags)
|
content = go_pafy(track, meta_tags)
|
||||||
if const.args.no_metadata:
|
if const.args.no_metadata:
|
||||||
meta_tags = None
|
meta_tags = None
|
||||||
@@ -84,7 +83,7 @@ def match_video_and_metadata(track):
|
|||||||
if const.args.no_metadata:
|
if const.args.no_metadata:
|
||||||
content = go_pafy(track, meta_tags=None)
|
content = go_pafy(track, meta_tags=None)
|
||||||
else:
|
else:
|
||||||
meta_tags = spotify.generate_metadata(track)
|
meta_tags = spotify_tools.generate_metadata(track)
|
||||||
content = go_pafy(track, meta_tags=meta_tags)
|
content = go_pafy(track, meta_tags=meta_tags)
|
||||||
meta_tags = fallback_metadata(meta_tags)
|
meta_tags = fallback_metadata(meta_tags)
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ def pytest_namespace():
|
|||||||
|
|
||||||
@pytest.fixture(scope="module")
|
@pytest.fixture(scope="module")
|
||||||
def metadata_fixture():
|
def metadata_fixture():
|
||||||
meta_tags = spotify_tools.SpotifyAuthorize().generate_metadata(SPOTIFY_TRACK_URL)
|
meta_tags = spotify_tools.generate_metadata(SPOTIFY_TRACK_URL)
|
||||||
return meta_tags
|
return meta_tags
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
from spotdl import spotify_tools
|
from spotdl import spotify_tools
|
||||||
|
from spotdl import const
|
||||||
|
|
||||||
|
import spotipy
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import pytest
|
import pytest
|
||||||
@@ -6,26 +9,45 @@ import loader
|
|||||||
|
|
||||||
loader.load_defaults()
|
loader.load_defaults()
|
||||||
|
|
||||||
@pytest.fixture(scope="module")
|
|
||||||
def spotify():
|
|
||||||
return spotify_tools.SpotifyAuthorize()
|
|
||||||
|
|
||||||
def test_generate_token(spotify):
|
def test_generate_token():
|
||||||
token = spotify.generate_token()
|
token = spotify_tools.generate_token()
|
||||||
assert len(token) == 83
|
assert len(token) == 83
|
||||||
|
|
||||||
|
|
||||||
def test_refresh_token(spotify):
|
class TestMustBeAuthorizedDecorator:
|
||||||
old_instance = spotify.spotify
|
def test_spotify_instance_is_unset(self):
|
||||||
spotify.refresh_token()
|
spotify_tools.spotify = None
|
||||||
new_instance = spotify.spotify
|
|
||||||
assert not old_instance == new_instance
|
@spotify_tools.must_be_authorized
|
||||||
|
def sample_func():
|
||||||
|
return True
|
||||||
|
|
||||||
|
assert sample_func()
|
||||||
|
|
||||||
|
def test_spotify_instance_forces_assertion_error(self):
|
||||||
|
@spotify_tools.must_be_authorized
|
||||||
|
def sample_func():
|
||||||
|
raise AssertionError
|
||||||
|
|
||||||
|
with pytest.raises(AssertionError):
|
||||||
|
sample_func()
|
||||||
|
|
||||||
|
def test_fake_token_generator(self, monkeypatch):
|
||||||
|
spotify_tools.spotify = None
|
||||||
|
monkeypatch.setattr(spotify_tools, "generate_token", lambda: 123123)
|
||||||
|
|
||||||
|
with pytest.raises(spotipy.client.SpotifyException):
|
||||||
|
spotify_tools.generate_metadata("ncs - spectre")
|
||||||
|
|
||||||
|
def test_correct_token(self):
|
||||||
|
assert spotify_tools.generate_metadata("ncs - spectre")
|
||||||
|
|
||||||
|
|
||||||
class TestGenerateMetadata:
|
class TestGenerateMetadata:
|
||||||
@pytest.fixture(scope="module")
|
@pytest.fixture(scope="module")
|
||||||
def metadata_fixture(self, spotify):
|
def metadata_fixture(self):
|
||||||
metadata = spotify.generate_metadata("ncs - spectre")
|
metadata = spotify_tools.generate_metadata("ncs - spectre")
|
||||||
return metadata
|
return metadata
|
||||||
|
|
||||||
def test_len(self, metadata_fixture):
|
def test_len(self, metadata_fixture):
|
||||||
@@ -41,7 +63,7 @@ class TestGenerateMetadata:
|
|||||||
assert metadata_fixture["duration"] == 230.634
|
assert metadata_fixture["duration"] == 230.634
|
||||||
|
|
||||||
|
|
||||||
def test_get_playlists(spotify):
|
def test_get_playlists():
|
||||||
expect_playlist_ids = [
|
expect_playlist_ids = [
|
||||||
"34gWCK8gVeYDPKcctB6BQJ",
|
"34gWCK8gVeYDPKcctB6BQJ",
|
||||||
"04wTU2c2WNQG9XE5oSLYfj",
|
"04wTU2c2WNQG9XE5oSLYfj",
|
||||||
@@ -53,15 +75,15 @@ def test_get_playlists(spotify):
|
|||||||
for playlist_id in expect_playlist_ids
|
for playlist_id in expect_playlist_ids
|
||||||
]
|
]
|
||||||
|
|
||||||
playlists = spotify.get_playlists("uqlakumu7wslkoen46s5bulq0")
|
playlists = spotify_tools.get_playlists("uqlakumu7wslkoen46s5bulq0")
|
||||||
assert playlists == expect_playlists
|
assert playlists == expect_playlists
|
||||||
|
|
||||||
|
|
||||||
def test_write_user_playlist(tmpdir, spotify, monkeypatch):
|
def test_write_user_playlist(tmpdir, monkeypatch):
|
||||||
expect_tracks = 17
|
expect_tracks = 17
|
||||||
text_file = os.path.join(str(tmpdir), "test_us.txt")
|
text_file = os.path.join(str(tmpdir), "test_us.txt")
|
||||||
monkeypatch.setattr("builtins.input", lambda x: 1)
|
monkeypatch.setattr("builtins.input", lambda x: 1)
|
||||||
spotify.write_user_playlist("uqlakumu7wslkoen46s5bulq0", text_file)
|
spotify_tools.write_user_playlist("uqlakumu7wslkoen46s5bulq0", text_file)
|
||||||
with open(text_file, "r") as f:
|
with open(text_file, "r") as f:
|
||||||
tracks = len(f.readlines())
|
tracks = len(f.readlines())
|
||||||
assert tracks == expect_tracks
|
assert tracks == expect_tracks
|
||||||
@@ -69,8 +91,8 @@ def test_write_user_playlist(tmpdir, spotify, monkeypatch):
|
|||||||
|
|
||||||
class TestFetchPlaylist:
|
class TestFetchPlaylist:
|
||||||
@pytest.fixture(scope="module")
|
@pytest.fixture(scope="module")
|
||||||
def playlist_fixture(self, spotify):
|
def playlist_fixture(self):
|
||||||
playlist = spotify.fetch_playlist(
|
playlist = spotify_tools.fetch_playlist(
|
||||||
"https://open.spotify.com/playlist/0fWBMhGh38y0wsYWwmM9Kt"
|
"https://open.spotify.com/playlist/0fWBMhGh38y0wsYWwmM9Kt"
|
||||||
)
|
)
|
||||||
return playlist
|
return playlist
|
||||||
@@ -82,10 +104,10 @@ class TestFetchPlaylist:
|
|||||||
assert playlist_fixture["tracks"]["total"] == 14
|
assert playlist_fixture["tracks"]["total"] == 14
|
||||||
|
|
||||||
|
|
||||||
def test_write_playlist(tmpdir, spotify):
|
def test_write_playlist(tmpdir):
|
||||||
expect_tracks = 14
|
expect_tracks = 14
|
||||||
text_file = os.path.join(str(tmpdir), "test_pl.txt")
|
text_file = os.path.join(str(tmpdir), "test_pl.txt")
|
||||||
spotify.write_playlist(
|
spotify_tools.write_playlist(
|
||||||
"https://open.spotify.com/playlist/0fWBMhGh38y0wsYWwmM9Kt", text_file
|
"https://open.spotify.com/playlist/0fWBMhGh38y0wsYWwmM9Kt", text_file
|
||||||
)
|
)
|
||||||
with open(text_file, "r") as f:
|
with open(text_file, "r") as f:
|
||||||
@@ -96,8 +118,8 @@ def test_write_playlist(tmpdir, spotify):
|
|||||||
# XXX: Mock this test off if it fails in future
|
# XXX: Mock this test off if it fails in future
|
||||||
class TestFetchAlbum:
|
class TestFetchAlbum:
|
||||||
@pytest.fixture(scope="module")
|
@pytest.fixture(scope="module")
|
||||||
def album_fixture(self, spotify):
|
def album_fixture(self):
|
||||||
album = spotify.fetch_album(
|
album = spotify_tools.fetch_album(
|
||||||
"https://open.spotify.com/album/499J8bIsEnU7DSrosFDJJg"
|
"https://open.spotify.com/album/499J8bIsEnU7DSrosFDJJg"
|
||||||
)
|
)
|
||||||
return album
|
return album
|
||||||
@@ -112,8 +134,8 @@ class TestFetchAlbum:
|
|||||||
# XXX: Mock this test off if it fails in future
|
# XXX: Mock this test off if it fails in future
|
||||||
class TestFetchAlbumsFromArtist:
|
class TestFetchAlbumsFromArtist:
|
||||||
@pytest.fixture(scope="module")
|
@pytest.fixture(scope="module")
|
||||||
def albums_from_artist_fixture(self, spotify):
|
def albums_from_artist_fixture(self):
|
||||||
albums = spotify.fetch_albums_from_artist(
|
albums = spotify_tools.fetch_albums_from_artist(
|
||||||
"https://open.spotify.com/artist/7oPftvlwr6VrsViSDV7fJY"
|
"https://open.spotify.com/artist/7oPftvlwr6VrsViSDV7fJY"
|
||||||
)
|
)
|
||||||
return albums
|
return albums
|
||||||
@@ -134,10 +156,10 @@ class TestFetchAlbumsFromArtist:
|
|||||||
assert albums_from_artist_fixture[0]["total_tracks"] == 12
|
assert albums_from_artist_fixture[0]["total_tracks"] == 12
|
||||||
|
|
||||||
|
|
||||||
def test_write_all_albums_from_artist(tmpdir, spotify):
|
def test_write_all_albums_from_artist(tmpdir):
|
||||||
expect_tracks = 282
|
expect_tracks = 282
|
||||||
text_file = os.path.join(str(tmpdir), "test_ab.txt")
|
text_file = os.path.join(str(tmpdir), "test_ab.txt")
|
||||||
spotify.write_all_albums_from_artist(
|
spotify_tools.write_all_albums_from_artist(
|
||||||
"https://open.spotify.com/artist/4dpARuHxo51G3z768sgnrY", text_file
|
"https://open.spotify.com/artist/4dpARuHxo51G3z768sgnrY", text_file
|
||||||
)
|
)
|
||||||
with open(text_file, "r") as f:
|
with open(text_file, "r") as f:
|
||||||
@@ -145,10 +167,10 @@ def test_write_all_albums_from_artist(tmpdir, spotify):
|
|||||||
assert tracks == expect_tracks
|
assert tracks == expect_tracks
|
||||||
|
|
||||||
|
|
||||||
def test_write_album(tmpdir, spotify):
|
def test_write_album(tmpdir):
|
||||||
expect_tracks = 15
|
expect_tracks = 15
|
||||||
text_file = os.path.join(str(tmpdir), "test_al.txt")
|
text_file = os.path.join(str(tmpdir), "test_al.txt")
|
||||||
spotify.write_album(
|
spotify_tools.write_album(
|
||||||
"https://open.spotify.com/album/499J8bIsEnU7DSrosFDJJg", text_file
|
"https://open.spotify.com/album/499J8bIsEnU7DSrosFDJJg", text_file
|
||||||
)
|
)
|
||||||
with open(text_file, "r") as f:
|
with open(text_file, "r") as f:
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class TestYouTubeAPIKeys:
|
|||||||
|
|
||||||
@pytest.fixture(scope="module")
|
@pytest.fixture(scope="module")
|
||||||
def metadata_fixture():
|
def metadata_fixture():
|
||||||
metadata = spotify_tools.SpotifyAuthorize().generate_metadata(TRACK_SEARCH)
|
metadata = spotify_tools.generate_metadata(TRACK_SEARCH)
|
||||||
return metadata
|
return metadata
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user