Merge branch 'release-v1.1.1'

This commit is contained in:
Ritiek Malhotra
2019-01-03 00:43:55 +05:30
14 changed files with 129 additions and 72 deletions

View File

@@ -6,6 +6,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## [Unreleased] ## [Unreleased]
## [1.1.1] - 2018-12-29
### Added ### Added
- Output informative message in case of no result found in YouTube search ([@Amit-L](https://github.com/Amit-L)) (#452) - Output informative message in case of no result found in YouTube search ([@Amit-L](https://github.com/Amit-L)) (#452)
- Ability to pass multiple tracks with `-s` option ([@ritiek](https://github.com/ritiek)) (#442) - Ability to pass multiple tracks with `-s` option ([@ritiek](https://github.com/ritiek)) (#442)

View File

@@ -1,6 +1,6 @@
from setuptools import setup from setuptools import setup
with open("README.md", "r") as f: with open("README.md", "r", encoding="utf-8") as f:
long_description = f.read() long_description = f.read()
import spotdl import spotdl

View File

@@ -1 +1 @@
__version__ = "1.1.0" __version__ = "1.1.1"

View File

@@ -2,13 +2,16 @@ import logzero
_log_format = "%(color)s%(levelname)s:%(end_color)s %(message)s" _log_format = "%(color)s%(levelname)s:%(end_color)s %(message)s"
_formatter = logzero.LogFormatter(fmt=_log_format) _formatter = logzero.LogFormatter(fmt=_log_format)
_log_level = 0
# Set up a temporary logger with default log level so that # Set up a temporary logger with default log level so that
# it can be used before log level argument is determined # it can be used before log level argument is determined
logzero.setup_default_logger(formatter=_formatter) logzero.setup_default_logger(formatter=_formatter, level=_log_level)
# options # Options
args = None # Initialize an empty object which can be assigned attributes
# (useful when using spotdl as a library)
args = type('', (), {})()
# Apple has specific tags - see mutagen docs - # Apple has specific tags - see mutagen docs -
# http://mutagen.readthedocs.io/en/latest/api/mp4.html # http://mutagen.readthedocs.io/en/latest/api/mp4.html

View File

@@ -28,8 +28,7 @@ class CheckExists:
for song in songs: for song in songs:
# check if a song with the same name is already present in the given folder # check if a song with the same name is already present in the given folder
if self._match_filenames(song): if self._match_filenames(song):
if internals.is_spotify(raw_song) and \ if internals.is_spotify(raw_song) and not self._has_metadata(song):
not self._has_metadata(song):
return False return False
log.warning('"{}" already exists'.format(song)) log.warning('"{}" already exists'.format(song))
@@ -53,9 +52,7 @@ class CheckExists:
already_tagged = metadata.compare( already_tagged = metadata.compare(
os.path.join(const.args.folder, song), self.meta_tags os.path.join(const.args.folder, song), self.meta_tags
) )
log.debug( log.debug("Checking if it is already tagged correctly? {}", already_tagged)
"Checking if it is already tagged correctly? {}", already_tagged
)
if not already_tagged: if not already_tagged:
os.remove(os.path.join(const.args.folder, song)) os.remove(os.path.join(const.args.folder, song))
return False return False
@@ -64,8 +61,7 @@ class CheckExists:
def _prompt_song(self, song): def _prompt_song(self, song):
log.info( log.info(
'"{}" has already been downloaded. ' '"{}" has already been downloaded. ' "Re-download? (y/N): ".format(song)
"Re-download? (y/N): ".format(song)
) )
prompt = input("> ") prompt = input("> ")
if prompt.lower() == "y": if prompt.lower() == "y":

View File

@@ -99,10 +99,7 @@ def get_arguments(raw_args=None, to_group=True, to_merge=True):
group = parser.add_mutually_exclusive_group(required=True) group = parser.add_mutually_exclusive_group(required=True)
group.add_argument( group.add_argument(
"-s", "-s", "--song", nargs="+", help="download track by spotify link or name"
"--song",
nargs='+',
help="download track by spotify link or name"
) )
group.add_argument("-l", "--list", help="download tracks from a file") group.add_argument("-l", "--list", help="download tracks from a file")
group.add_argument( group.add_argument(
@@ -116,7 +113,7 @@ def get_arguments(raw_args=None, to_group=True, to_merge=True):
group.add_argument( group.add_argument(
"-ab", "-ab",
"--all-albums", "--all-albums",
help="load all tracks from artist URL into <artist_name>.txt" help="load all tracks from artist URL into <artist_name>.txt",
) )
group.add_argument( group.add_argument(
"-u", "-u",
@@ -128,10 +125,10 @@ def get_arguments(raw_args=None, to_group=True, to_merge=True):
) )
parser.add_argument( parser.add_argument(
'--write-m3u', "--write-m3u",
help="generate an .m3u playlist file with youtube links given " help="generate an .m3u playlist file with youtube links given "
"a text file containing tracks", "a text file containing tracks",
action='store_true' action="store_true",
) )
parser.add_argument( parser.add_argument(
"-m", "-m",
@@ -266,12 +263,19 @@ def get_arguments(raw_args=None, to_group=True, to_merge=True):
if parsed.config is not None and to_merge: if parsed.config is not None and to_merge:
parsed = override_config(parsed.config, parser) parsed = override_config(parsed.config, parser)
if to_group and parsed.list and \ if (
not mimetypes.MimeTypes().guess_type(parsed.list)[0] == "text/plain": to_group
parser.error("{0} is not of a valid argument to --list, argument must be plain text file".format(parsed.list)) and parsed.list
and not mimetypes.MimeTypes().guess_type(parsed.list)[0] == "text/plain"
):
parser.error(
"{0} is not of a valid argument to --list, argument must be plain text file".format(
parsed.list
)
)
if parsed.write_m3u and not parsed.list: if parsed.write_m3u and not parsed.list:
parser.error('--write-m3u can only be used with --list') parser.error("--write-m3u can only be used with --list")
if parsed.avconv and parsed.trim_silence: if parsed.avconv and parsed.trim_silence:
parser.error("--trim-silence can only be used with FFmpeg") parser.error("--trim-silence can only be used with FFmpeg")

View File

@@ -27,6 +27,7 @@ def refresh_token():
new_token = generate_token() new_token = generate_token()
spotify = spotipy.Spotify(auth=new_token) spotify = spotipy.Spotify(auth=new_token)
# token is mandatory when using Spotify's API # token is mandatory when using Spotify's API
# https://developer.spotify.com/news-stories/2017/01/27/removing-unauthenticated-calls-to-the-web-api/ # https://developer.spotify.com/news-stories/2017/01/27/removing-unauthenticated-calls-to-the-web-api/
_token = generate_token() _token = generate_token()

View File

@@ -53,7 +53,7 @@ def match_video_and_metadata(track, force_pafy=True):
# Let it generate metadata, youtube doesn't know spotify slang # Let it generate metadata, youtube doesn't know spotify slang
if not const.args.no_metadata or internals.is_spotify(track): if not const.args.no_metadata or internals.is_spotify(track):
meta_tags = spotify_tools.generate_metadata(track) meta_tags = spotify_tools.generate_metadata(track)
if force_pafy: if force_pafy:
content = go_pafy(track, meta_tags) content = go_pafy(track, meta_tags)
else: else:

View File

@@ -8,7 +8,6 @@ import pytest
def load_defaults(): def load_defaults():
const.args = handle.get_arguments(raw_args="", to_group=False, to_merge=False) const.args = handle.get_arguments(raw_args="", to_group=False, to_merge=False)
const.args.overwrite = "skip" const.args.overwrite = "skip"
const.args.log_level = 10
spotdl.args = const.args spotdl.args = const.args
spotdl.log = const.logzero.setup_logger( spotdl.log = const.logzero.setup_logger(

View File

@@ -60,13 +60,21 @@ def monkeypatch_youtube_search_page(*args, **kwargs):
def test_youtube_url(metadata_fixture, monkeypatch): def test_youtube_url(metadata_fixture, monkeypatch):
monkeypatch.setattr(youtube_tools.GenerateYouTubeURL, "_fetch_response", monkeypatch_youtube_search_page) monkeypatch.setattr(
youtube_tools.GenerateYouTubeURL,
"_fetch_response",
monkeypatch_youtube_search_page,
)
url = youtube_tools.generate_youtube_url(SPOTIFY_TRACK_URL, metadata_fixture) url = youtube_tools.generate_youtube_url(SPOTIFY_TRACK_URL, metadata_fixture)
assert url == EXPECTED_YOUTUBE_URL assert url == EXPECTED_YOUTUBE_URL
def test_youtube_title(metadata_fixture, monkeypatch): def test_youtube_title(metadata_fixture, monkeypatch):
monkeypatch.setattr(youtube_tools.GenerateYouTubeURL, "_fetch_response", monkeypatch_youtube_search_page) monkeypatch.setattr(
youtube_tools.GenerateYouTubeURL,
"_fetch_response",
monkeypatch_youtube_search_page,
)
content = youtube_tools.go_pafy(SPOTIFY_TRACK_URL, metadata_fixture) content = youtube_tools.go_pafy(SPOTIFY_TRACK_URL, metadata_fixture)
pytest.content_fixture = content pytest.content_fixture = content
title = youtube_tools.get_youtube_title(content) title = youtube_tools.get_youtube_title(content)
@@ -99,60 +107,78 @@ class TestDownload:
def test_m4a(self, monkeypatch, filename_fixture): def test_m4a(self, monkeypatch, filename_fixture):
expect_download = True expect_download = True
monkeypatch.setattr("pafy.backend_shared.BaseStream.download", self.blank_audio_generator) monkeypatch.setattr(
download = youtube_tools.download_song(filename_fixture + ".m4a", pytest.content_fixture) "pafy.backend_shared.BaseStream.download", self.blank_audio_generator
)
download = youtube_tools.download_song(
filename_fixture + ".m4a", pytest.content_fixture
)
assert download == expect_download assert download == expect_download
def test_webm(self, monkeypatch, filename_fixture): def test_webm(self, monkeypatch, filename_fixture):
expect_download = True expect_download = True
monkeypatch.setattr("pafy.backend_shared.BaseStream.download", self.blank_audio_generator) monkeypatch.setattr(
download = youtube_tools.download_song(filename_fixture + ".webm", pytest.content_fixture) "pafy.backend_shared.BaseStream.download", self.blank_audio_generator
)
download = youtube_tools.download_song(
filename_fixture + ".webm", pytest.content_fixture
)
assert download == expect_download assert download == expect_download
class TestFFmpeg: class TestFFmpeg:
def test_convert_from_webm_to_mp3(self, filename_fixture, monkeypatch): def test_convert_from_webm_to_mp3(self, filename_fixture, monkeypatch):
expect_command = "ffmpeg -y -hide_banner -nostats -v panic -i {0}.webm -codec:a libmp3lame -ar 44100 -b:a 192k -vn {0}.mp3".format(
os.path.join(const.args.folder, filename_fixture)
)
monkeypatch.setattr("os.remove", lambda x: None) monkeypatch.setattr("os.remove", lambda x: None)
expect_command = "ffmpeg -y -i {0}.webm -codec:a libmp3lame -ar 44100 -b:a 192k -vn {0}.mp3".format(os.path.join(const.args.folder, filename_fixture))
_, command = convert.song( _, command = convert.song(
filename_fixture + ".webm", filename_fixture + ".mp3", const.args.folder filename_fixture + ".webm", filename_fixture + ".mp3", const.args.folder
) )
assert ' '.join(command) == expect_command assert " ".join(command) == expect_command
def test_convert_from_webm_to_m4a(self, filename_fixture, monkeypatch): def test_convert_from_webm_to_m4a(self, filename_fixture, monkeypatch):
expect_command = "ffmpeg -y -hide_banner -nostats -v panic -i {0}.webm -cutoff 20000 -codec:a aac -ar 44100 -b:a 192k -vn {0}.m4a".format(
os.path.join(const.args.folder, filename_fixture)
)
monkeypatch.setattr("os.remove", lambda x: None) monkeypatch.setattr("os.remove", lambda x: None)
expect_command = "ffmpeg -y -i {0}.webm -cutoff 20000 -codec:a aac -ar 44100 -b:a 192k -vn {0}.m4a".format(os.path.join(const.args.folder, filename_fixture))
_, command = convert.song( _, command = convert.song(
filename_fixture + ".webm", filename_fixture + ".m4a", const.args.folder filename_fixture + ".webm", filename_fixture + ".m4a", const.args.folder
) )
assert ' '.join(command) == expect_command assert " ".join(command) == expect_command
def test_convert_from_m4a_to_mp3(self, filename_fixture, monkeypatch): def test_convert_from_m4a_to_mp3(self, filename_fixture, monkeypatch):
expect_command = "ffmpeg -y -hide_banner -nostats -v panic -i {0}.m4a -codec:v copy -codec:a libmp3lame -ar 44100 -b:a 192k -vn {0}.mp3".format(
os.path.join(const.args.folder, filename_fixture)
)
monkeypatch.setattr("os.remove", lambda x: None) monkeypatch.setattr("os.remove", lambda x: None)
expect_command = "ffmpeg -y -i {0}.m4a -codec:v copy -codec:a libmp3lame -ar 44100 -b:a 192k -vn {0}.mp3".format(os.path.join(const.args.folder, filename_fixture))
_, command = convert.song( _, command = convert.song(
filename_fixture + ".m4a", filename_fixture + ".mp3", const.args.folder filename_fixture + ".m4a", filename_fixture + ".mp3", const.args.folder
) )
assert ' '.join(command) == expect_command assert " ".join(command) == expect_command
def test_convert_from_m4a_to_webm(self, filename_fixture, monkeypatch): def test_convert_from_m4a_to_webm(self, filename_fixture, monkeypatch):
expect_command = "ffmpeg -y -hide_banner -nostats -v panic -i {0}.m4a -codec:a libopus -vbr on -b:a 192k -vn {0}.webm".format(
os.path.join(const.args.folder, filename_fixture)
)
monkeypatch.setattr("os.remove", lambda x: None) monkeypatch.setattr("os.remove", lambda x: None)
expect_command = "ffmpeg -y -i {0}.m4a -codec:a libopus -vbr on -b:a 192k -vn {0}.webm".format(os.path.join(const.args.folder, filename_fixture))
_, command = convert.song( _, command = convert.song(
filename_fixture + ".m4a", filename_fixture + ".webm", const.args.folder filename_fixture + ".m4a", filename_fixture + ".webm", const.args.folder
) )
assert ' '.join(command) == expect_command assert " ".join(command) == expect_command
def test_convert_from_m4a_to_flac(self, filename_fixture, monkeypatch): def test_convert_from_m4a_to_flac(self, filename_fixture, monkeypatch):
expect_command = "ffmpeg -y -hide_banner -nostats -v panic -i {0}.m4a -codec:a flac -ar 44100 -b:a 192k -vn {0}.flac".format(
os.path.join(const.args.folder, filename_fixture)
)
monkeypatch.setattr("os.remove", lambda x: None) monkeypatch.setattr("os.remove", lambda x: None)
expect_command = "ffmpeg -y -i {0}.m4a -codec:a flac -ar 44100 -b:a 192k -vn {0}.flac".format(os.path.join(const.args.folder, filename_fixture))
_, command = convert.song( _, command = convert.song(
filename_fixture + ".m4a", filename_fixture + ".flac", const.args.folder filename_fixture + ".m4a", filename_fixture + ".flac", const.args.folder
) )
assert ' '.join(command) == expect_command assert " ".join(command) == expect_command
def test_correct_container_for_m4a(self, filename_fixture, monkeypatch): def test_correct_container_for_m4a(self, filename_fixture, monkeypatch):
expect_command = "ffmpeg -y -i {0}.m4a.temp -acodec copy -b:a 192k -vn {0}.m4a".format(os.path.join(const.args.folder, filename_fixture)) expect_command = "ffmpeg -y -hide_banner -nostats -v panic -i {0}.m4a.temp -acodec copy -b:a 192k -vn {0}.m4a".format(os.path.join(const.args.folder, filename_fixture))
_, command = convert.song( _, command = convert.song(
filename_fixture + ".m4a", filename_fixture + ".m4a", const.args.folder filename_fixture + ".m4a", filename_fixture + ".m4a", const.args.folder
) )
@@ -162,11 +188,15 @@ class TestFFmpeg:
class TestAvconv: class TestAvconv:
def test_convert_from_m4a_to_mp3(self, filename_fixture, monkeypatch): def test_convert_from_m4a_to_mp3(self, filename_fixture, monkeypatch):
monkeypatch.setattr("os.remove", lambda x: None) monkeypatch.setattr("os.remove", lambda x: None)
expect_command = "avconv -loglevel debug -i {0}.m4a -ab 192k {0}.mp3 -y".format(os.path.join(const.args.folder, filename_fixture)) expect_command = "avconv -loglevel 0 -i {0}.m4a -ab 192k {0}.mp3 -y".format(
os.path.join(const.args.folder, filename_fixture))
_, command = convert.song( _, command = convert.song(
filename_fixture + ".m4a", filename_fixture + ".mp3", const.args.folder, avconv=True filename_fixture + ".m4a",
filename_fixture + ".mp3",
const.args.folder,
avconv=True,
) )
assert ' '.join(command) == expect_command assert " ".join(command) == expect_command
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
@@ -200,7 +230,9 @@ class TestEmbedMetadata:
assert embed == expect_embed assert embed == expect_embed
def test_check_track_exists_after_download(metadata_fixture, filename_fixture, trackpath_fixture): def test_check_track_exists_after_download(
metadata_fixture, filename_fixture, trackpath_fixture
):
expect_check = True expect_check = True
track_existence = downloader.CheckExists(filename_fixture, metadata_fixture) track_existence = downloader.CheckExists(filename_fixture, metadata_fixture)
check = track_existence.already_exists(SPOTIFY_TRACK_URL) check = track_existence.already_exists(SPOTIFY_TRACK_URL)

View File

@@ -10,13 +10,11 @@ import yaml
def test_error_m3u_without_list(): def test_error_m3u_without_list():
with pytest.raises(SystemExit): with pytest.raises(SystemExit):
handle.get_arguments(raw_args=('-s cool song', '--write-m3u',), handle.get_arguments(raw_args=("-s cool song", "--write-m3u"), to_group=True)
to_group=True)
def test_m3u_with_list(): def test_m3u_with_list():
handle.get_arguments(raw_args=('-l cool_list.txt', '--write-m3u',), handle.get_arguments(raw_args=("-l cool_list.txt", "--write-m3u"), to_group=True)
to_group=True)
def test_log_str_to_int(): def test_log_str_to_int():
@@ -27,8 +25,7 @@ def test_log_str_to_int():
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def config_path_fixture(tmpdir_factory): def config_path_fixture(tmpdir_factory):
config_path = os.path.join(str(tmpdir_factory.mktemp("config")), config_path = os.path.join(str(tmpdir_factory.mktemp("config")), "config.yml")
"config.yml")
return config_path return config_path
@@ -53,9 +50,12 @@ class TestConfig:
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
with open(config_path_fixture, "w") as config_file: with open(config_path_fixture, "w") as config_file:
yaml.dump(modified_config_fixture, config_file, default_flow_style=False) yaml.dump(modified_config_fixture, config_file, default_flow_style=False)
overridden_config = handle.override_config(config_path_fixture, parser, raw_args="") overridden_config = handle.override_config(
config_path_fixture, parser, raw_args=""
)
modified_values = [ modified_values = [
str(value) for value in modified_config_fixture["spotify-downloader"].values() str(value)
for value in modified_config_fixture["spotify-downloader"].values()
] ]
overridden_config.folder = os.path.realpath(overridden_config.folder) overridden_config.folder = os.path.realpath(overridden_config.folder)
overridden_values = [ overridden_values = [

View File

@@ -86,7 +86,7 @@ FROM_SECONDS_TEST_TABLE = [
(158, "2:38"), (158, "2:38"),
(263, "4:23"), (263, "4:23"),
(4562, "1:16:02"), (4562, "1:16:02"),
(26762, "7:26:02") (26762, "7:26:02"),
] ]
@@ -114,8 +114,7 @@ def test_default_music_directory():
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def directory_fixture(tmpdir_factory): def directory_fixture(tmpdir_factory):
dir_path = os.path.join(str(tmpdir_factory.mktemp("tmpdir")), dir_path = os.path.join(str(tmpdir_factory.mktemp("tmpdir")), "filter_this_folder")
"filter_this_folder")
return dir_path return dir_path

View File

@@ -36,12 +36,16 @@ class TestGenerateMetadata:
def test_get_playlists(): def test_get_playlists():
expect_playlist_ids = [ "34gWCK8gVeYDPKcctB6BQJ", expect_playlist_ids = [
"04wTU2c2WNQG9XE5oSLYfj", "34gWCK8gVeYDPKcctB6BQJ",
"0fWBMhGh38y0wsYWwmM9Kt" ] "04wTU2c2WNQG9XE5oSLYfj",
"0fWBMhGh38y0wsYWwmM9Kt",
]
expect_playlists = [ "https://open.spotify.com/playlist/" + playlist_id expect_playlists = [
for playlist_id in expect_playlist_ids ] "https://open.spotify.com/playlist/" + playlist_id
for playlist_id in expect_playlist_ids
]
playlists = spotify_tools.get_playlists("uqlakumu7wslkoen46s5bulq0") playlists = spotify_tools.get_playlists("uqlakumu7wslkoen46s5bulq0")
assert playlists == expect_playlists assert playlists == expect_playlists
@@ -60,7 +64,9 @@ def test_write_user_playlist(tmpdir, monkeypatch):
class TestFetchPlaylist: class TestFetchPlaylist:
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def playlist_fixture(self): def playlist_fixture(self):
playlist = spotify_tools.fetch_playlist("https://open.spotify.com/playlist/0fWBMhGh38y0wsYWwmM9Kt") playlist = spotify_tools.fetch_playlist(
"https://open.spotify.com/playlist/0fWBMhGh38y0wsYWwmM9Kt"
)
return playlist return playlist
def test_name(self, playlist_fixture): def test_name(self, playlist_fixture):
@@ -73,7 +79,9 @@ class TestFetchPlaylist:
def test_write_playlist(tmpdir): 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_tools.write_playlist("https://open.spotify.com/playlist/0fWBMhGh38y0wsYWwmM9Kt", text_file) spotify_tools.write_playlist(
"https://open.spotify.com/playlist/0fWBMhGh38y0wsYWwmM9Kt", 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
@@ -83,7 +91,9 @@ def test_write_playlist(tmpdir):
class TestFetchAlbum: class TestFetchAlbum:
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def album_fixture(self): def album_fixture(self):
album = spotify_tools.fetch_album("https://open.spotify.com/album/499J8bIsEnU7DSrosFDJJg") album = spotify_tools.fetch_album(
"https://open.spotify.com/album/499J8bIsEnU7DSrosFDJJg"
)
return album return album
def test_name(self, album_fixture): def test_name(self, album_fixture):
@@ -97,7 +107,9 @@ class TestFetchAlbum:
class TestFetchAlbumsFromArtist: class TestFetchAlbumsFromArtist:
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def albums_from_artist_fixture(self): def albums_from_artist_fixture(self):
albums = spotify_tools.fetch_albums_from_artist("https://open.spotify.com/artist/7oPftvlwr6VrsViSDV7fJY") albums = spotify_tools.fetch_albums_from_artist(
"https://open.spotify.com/artist/7oPftvlwr6VrsViSDV7fJY"
)
return albums return albums
def test_len(self, albums_from_artist_fixture): def test_len(self, albums_from_artist_fixture):
@@ -122,7 +134,9 @@ def test_write_all_albums_from_artist(tmpdir):
# in US market only # in US market only
expect_tracks = 49 expect_tracks = 49
text_file = os.path.join(str(tmpdir), "test_ab.txt") text_file = os.path.join(str(tmpdir), "test_ab.txt")
spotify_tools.write_all_albums_from_artist("https://open.spotify.com/artist/4dpARuHxo51G3z768sgnrY", text_file) spotify_tools.write_all_albums_from_artist(
"https://open.spotify.com/artist/4dpARuHxo51G3z768sgnrY", 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
@@ -131,7 +145,9 @@ def test_write_all_albums_from_artist(tmpdir):
def test_write_album(tmpdir): 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_tools.write_album("https://open.spotify.com/album/499J8bIsEnU7DSrosFDJJg", text_file) spotify_tools.write_album(
"https://open.spotify.com/album/499J8bIsEnU7DSrosFDJJg", 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

View File

@@ -111,7 +111,9 @@ class TestYouTubeTitle:
youtube_tools.set_api_key() youtube_tools.set_api_key()
assert title_fixture == EXPECTED_TITLE assert title_fixture == EXPECTED_TITLE
def test_download_from_list_without_youtube_api(self, metadata_fixture, content_fixture): def test_download_from_list_without_youtube_api(
self, metadata_fixture, content_fixture
):
const.args.youtube_api_key = None const.args.youtube_api_key = None
youtube_tools.set_api_key() youtube_tools.set_api_key()
content_fixture = youtube_tools.go_pafy(TRACK_SEARCH, metadata_fixture) content_fixture = youtube_tools.go_pafy(TRACK_SEARCH, metadata_fixture)
@@ -139,11 +141,15 @@ class TestDownload:
# content_fixture does not have any .webm audiostream # content_fixture does not have any .webm audiostream
expect_download = False expect_download = False
monkeypatch.setattr("pafy.backend_shared.BaseStream.download", lambda x: None) monkeypatch.setattr("pafy.backend_shared.BaseStream.download", lambda x: None)
download = youtube_tools.download_song(filename_fixture + ".webm", content_fixture) download = youtube_tools.download_song(
filename_fixture + ".webm", content_fixture
)
assert download == expect_download assert download == expect_download
def test_other(self, content_fixture, filename_fixture, monkeypatch): def test_other(self, content_fixture, filename_fixture, monkeypatch):
expect_download = False expect_download = False
monkeypatch.setattr("pafy.backend_shared.BaseStream.download", lambda x: None) monkeypatch.setattr("pafy.backend_shared.BaseStream.download", lambda x: None)
download = youtube_tools.download_song(filename_fixture + ".fake_extension", content_fixture) download = youtube_tools.download_song(
filename_fixture + ".fake_extension", content_fixture
)
assert download == expect_download assert download == expect_download