mirror of
https://github.com/KevinMidboe/spotify-downloader.git
synced 2025-10-29 18:00:15 +00:00
Merge branch 'release-v1.1.1'
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
2
setup.py
2
setup.py
@@ -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
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
__version__ = "1.1.0"
|
__version__ = "1.1.1"
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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":
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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 = [
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user