Merge options -f and -ff into -f

This commit is contained in:
Ritiek Malhotra
2020-04-23 14:55:52 +05:30
parent 7ddc5c6348
commit 300f17e5cd
8 changed files with 83 additions and 72 deletions

View File

@@ -8,7 +8,10 @@ def match_arguments(arguments):
for track in arguments.tracks: for track in arguments.tracks:
if track == "-": if track == "-":
for line in sys.stdin: for line in sys.stdin:
command_line.helpers.download_track(line, arguments) command_line.helpers.download_track(
line,
arguments
)
else: else:
command_line.helpers.download_track(track, arguments) command_line.helpers.download_track(track, arguments)
elif arguments.list: elif arguments.list:

View File

@@ -136,12 +136,6 @@ def get_arguments(argv=None, to_merge=True):
choices={"ffmpeg", "avconv", "null"}, choices={"ffmpeg", "avconv", "null"},
help="use this encoder for conversion", help="use this encoder for conversion",
) )
parser.add_argument(
"-f",
"--directory",
default=os.path.abspath(config["directory"]),
help="path to directory where downloaded tracks will be stored in",
)
parser.add_argument( parser.add_argument(
"--overwrite", "--overwrite",
default=config["overwrite"], default=config["overwrite"],
@@ -175,11 +169,11 @@ def get_arguments(argv=None, to_merge=True):
help="write tracks from Spotify playlist, album, etc. to this file", help="write tracks from Spotify playlist, album, etc. to this file",
) )
parser.add_argument( parser.add_argument(
"-ff", "-f",
"--file-format", "--output-file",
default=config["file-format"], default=config["output-file"],
help="file format to save the downloaded track with, each tag " help="path where to write the downloaded track to, special tags "
"is surrounded by curly braces. Possible formats: " "are to be surrounded by curly braces. Possible tags: "
# "{}".format([spotdl.util.formats[x] for x in spotdl.util.formats]), # "{}".format([spotdl.util.formats[x] for x in spotdl.util.formats]),
) )
parser.add_argument( parser.add_argument(
@@ -192,8 +186,8 @@ def get_arguments(argv=None, to_merge=True):
"-sf", "-sf",
"--search-format", "--search-format",
default=config["search-format"], default=config["search-format"],
help="search format to search for on YouTube, each tag " help="search format to search for on YouTube, special tags "
"is surrounded by curly braces. Possible formats: " "are to be surrounded by curly braces. Possible tags: "
# "{}".format([spotdl.util.formats[x] for x in spotdl.util.formats]), # "{}".format([spotdl.util.formats[x] for x in spotdl.util.formats]),
) )
parser.add_argument( parser.add_argument(
@@ -289,10 +283,10 @@ def get_arguments(argv=None, 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)
return run_errands(parser, parsed) return run_errands(parser, parsed, config)
def run_errands(parser, parsed): def run_errands(parser, parsed, config):
if (parsed.list if (parsed.list
and not mimetypes.MimeTypes().guess_type(parsed.list)[0] == "text/plain" and not mimetypes.MimeTypes().guess_type(parsed.list)[0] == "text/plain"
): ):
@@ -334,12 +328,23 @@ def run_errands(parser, parsed):
setattr(parsed, "tracks", parsed.song) setattr(parsed, "tracks", parsed.song)
del parsed.song del parsed.song
if parsed.file_format == "-" and parsed.no_metadata is False: if parsed.output_file == "-" and parsed.no_metadata is False:
# log.warn( # log.warn(
# "Cannot write metadata when target file is STDOUT. Pass " # "Cannot write metadata when target file is STDOUT. Pass "
# "--no-metadata explicitly to hide this warning." # "--no-metadata explicitly to hide this warning."
# ) # )
parsed.no_metadata = True parsed.no_metadata = True
elif os.path.isdir(parsed.output_file):
adjusted_output_file = os.path.join(
parsed.output_file,
config["output-file"]
)
# log.warn(
# "Specified output file is a directory. Will write the filename as in
# "default file format. Pass --output-file={} to hide this warning".format(
# adjusted_output_file
# )
parsed.output_file = adjusted_output_file
parsed.log_level = log_leveller(parsed.log_level) parsed.log_level = log_leveller(parsed.log_level)

View File

@@ -3,6 +3,7 @@ from spotdl.metadata.providers import ProviderYouTube
from spotdl.metadata.providers import YouTubeSearch from spotdl.metadata.providers import YouTubeSearch
from spotdl.metadata.embedders import EmbedderDefault from spotdl.metadata.embedders import EmbedderDefault
from spotdl.metadata.exceptions import SpotifyMetadataNotFoundError from spotdl.metadata.exceptions import SpotifyMetadataNotFoundError
import spotdl.metadata
from spotdl.encode.encoders import EncoderFFmpeg from spotdl.encode.encoders import EncoderFFmpeg
from spotdl.encode.encoders import EncoderAvconv from spotdl.encode.encoders import EncoderAvconv
@@ -46,17 +47,16 @@ def search_metadata(track, search_format="{artist} - {track-name} lyrics", manua
if spotdl.util.is_spotify(track): if spotdl.util.is_spotify(track):
spotify = ProviderSpotify() spotify = ProviderSpotify()
spotify_metadata = spotify.from_url(track) spotify_metadata = spotify.from_url(track)
lyric_query = spotdl.util.format_string( lyric_query = spotdl.metadata.format_string(
"{artist} - {track-name}", "{artist} - {track-name}",
spotify_metadata, spotify_metadata,
) )
search_query = spotdl.util.format_string(search_format, spotify_metadata) search_query = spotdl.metadata.format_string(search_format, spotify_metadata)
youtube_urls = youtube_searcher.search(search_query) youtube_urls = youtube_searcher.search(search_query)
if not youtube_urls: if not youtube_urls:
# raise NoYouTubeVideoError( raise NoYouTubeVideoError(
# 'No videos found for the search query: "{}"'.format(search_query) 'No videos found for the search query: "{}"'.format(search_query)
# ) )
return
if manual: if manual:
pass pass
else: else:
@@ -69,7 +69,7 @@ def search_metadata(track, search_format="{artist} - {track-name} lyrics", manua
elif spotdl.util.is_youtube(track): elif spotdl.util.is_youtube(track):
metadata = youtube.from_url(track) metadata = youtube.from_url(track)
lyric_query = spotdl.util.format_string( lyric_query = spotdl.metadata.format_string(
"{artist} - {track-name}", "{artist} - {track-name}",
metadata, metadata,
) )
@@ -107,11 +107,14 @@ def search_metadata(track, search_format="{artist} - {track-name} lyrics", manua
def download_track(track, arguments): def download_track(track, arguments):
track_splits = track.split(":")
if len(track_splits) == 2:
youtube_track, spotify_track = track_splits
metadata = search_metadata(track, search_format=arguments.search_format) metadata = search_metadata(track, search_format=arguments.search_format)
log_fmt = spotdl.util.format_string( log_fmt = spotdl.metadata.format_string(
arguments.file_format, arguments.output_file,
metadata, metadata,
output_extension=arguments.output_ext output_extension=arguments.output_ext,
) )
# log.info(log_fmt) # log.info(log_fmt)
download_track_from_metadata(metadata, arguments) download_track_from_metadata(metadata, arguments)
@@ -119,7 +122,6 @@ def download_track(track, arguments):
def download_track_from_metadata(metadata, arguments): def download_track_from_metadata(metadata, arguments):
# TODO: Add `-m` flag # TODO: Add `-m` flag
track = Track(metadata, cache_albumart=(not arguments.no_metadata)) track = Track(metadata, cache_albumart=(not arguments.no_metadata))
print(metadata["name"]) print(metadata["name"])
@@ -139,11 +141,15 @@ def download_track_from_metadata(metadata, arguments):
else: else:
output_extension = arguments.output_ext output_extension = arguments.output_ext
filename = spotdl.util.format_string( filename = spotdl.metadata.format_string(
arguments.file_format, arguments.output_file,
metadata, metadata,
output_extension=output_extension output_extension=output_extension,
sanitizer=lambda s: spotdl.util.sanitize(
s, spaces_to_underscores=arguments.no_spaces
)
) )
print(filename)
# log.info(filename) # log.info(filename)
to_skip = arguments.dry_run to_skip = arguments.dry_run

View File

@@ -11,7 +11,6 @@ DEFAULT_CONFIGURATION = {
"no-fallback-metadata": False, "no-fallback-metadata": False,
"avconv": False, "avconv": False,
"encoder": "ffmpeg", "encoder": "ffmpeg",
"directory": spotdl.util.get_music_dir(),
"overwrite": "prompt", "overwrite": "prompt",
"quality": "best", "quality": "best",
"input-ext": "automatic", "input-ext": "automatic",
@@ -23,7 +22,7 @@ DEFAULT_CONFIGURATION = {
"music-videos-only": False, "music-videos-only": False,
"no-spaces": False, "no-spaces": False,
"processor": "synchronous", "processor": "synchronous",
"file-format": "{artist} - {track-name}.{output-ext}", "output-file": "{artist} - {track-name}.{output-ext}",
"search-format": "{artist} - {track-name} lyrics", "search-format": "{artist} - {track-name} lyrics",
"youtube-api-key": None, "youtube-api-key": None,
"skip": None, "skip": None,

View File

@@ -7,3 +7,5 @@ from spotdl.metadata.exceptions import YouTubeMetadataNotFoundError
from spotdl.metadata.embedder_base import EmbedderBase from spotdl.metadata.embedder_base import EmbedderBase
from spotdl.metadata.formatter import format_string

View File

@@ -0,0 +1,24 @@
def format_string(string, metadata, output_extension="", sanitizer=lambda s: s):
formats = {
"{track-name}" : metadata["name"],
"{artist}" : metadata["artists"][0]["name"],
"{album}" : metadata["album"]["name"],
"{album-artist}" : metadata["artists"][0]["name"],
"{genre}" : metadata["genre"],
"{disc-number}" : metadata["disc_number"],
"{duration}" : metadata["duration"],
"{year}" : metadata["year"],
"{original-date}": metadata["release_date"],
"{track-number}" : metadata["track_number"],
"{total-tracks}" : metadata["total_tracks"],
"{isrc}" : metadata["external_ids"]["isrc"],
# TODO: Call `str.zfill` fill on track-id
"{track-id}" : metadata.get("id", ""),
"{output-ext}" : output_extension,
}
for key, value in formats.items():
string = string.replace(key, sanitizer(str(value)))
return string

View File

@@ -21,7 +21,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")), "filter_this_folder") dir_path = os.path.join(str(tmpdir_factory.mktemp("tmpdir")), "filter_this_directory")
return dir_path return dir_path

View File

@@ -80,43 +80,15 @@ def is_youtube(raw_song):
return status return status
def format_string(string, metadata, output_extension=""): def sanitize(string, ok="-_()[]{}", spaces_to_underscores=False):
formats = {
"{track-name}" : metadata["name"],
"{artist}" : metadata["artists"][0]["name"],
"{album}" : metadata["album"]["name"],
"{album-artist}" : metadata["artists"][0]["name"],
"{genre}" : metadata["genre"],
"{disc-number}" : metadata["disc_number"],
"{duration}" : metadata["duration"],
"{year}" : metadata["year"],
"{original-date}": metadata["release_date"],
"{track-number}" : metadata["track_number"],
"{total-tracks}" : metadata["total_tracks"],
"{isrc}" : metadata["external_ids"]["isrc"],
# TODO: Call `str.zfill` fill on track-id
"{track-id}" : metadata.get("id", ""),
"{output-ext}" : output_extension,
}
for key, value in formats.items():
string = string.replace(key, str(value))
return string
def sanitize_title(title, ok="-_()[]{}"):
""" Generate filename of the song to be downloaded. """ """ Generate filename of the song to be downloaded. """
if spaces_to_underscores:
if const.args.no_spaces: string = string.replace(" ", "_")
title = title.replace(" ", "_") # replace slashes with "-" to avoid directory creation errors
string = string.replace("/", "-").replace("\\", "-")
# replace slashes with "-" to avoid folder creation errors
title = title.replace("/", "-").replace("\\", "-")
# slugify removes any special characters # slugify removes any special characters
title = slugify(title, ok=ok, lower=False, spaces=True) string = slugify(string, ok=ok, lower=False, spaces=True)
return title return string
def filter_path(path): def filter_path(path):
@@ -162,7 +134,7 @@ def get_sec(time_str):
def get_music_dir(): def get_music_dir():
home = os.path.expanduser("~") home = os.path.expanduser("~")
# On Linux, the localized folder names are the actual ones. # On Linux, the localized directory names are the actual ones.
# It's a freedesktop standard though. # It's a freedesktop standard though.
if sys.platform.startswith("linux"): if sys.platform.startswith("linux"):
for file_item in (".config/user-dirs.dirs", "user-dirs.dirs"): for file_item in (".config/user-dirs.dirs", "user-dirs.dirs"):
@@ -176,7 +148,7 @@ def get_music_dir():
) )
# Windows / Cygwin # Windows / Cygwin
# Queries registry for 'My Music' folder path (as this can be changed) # Queries registry for 'My Music' directory path (as this can be changed)
if "win" in sys.platform: if "win" in sys.platform:
try: try:
key = winreg.OpenKey( key = winreg.OpenKey(
@@ -189,7 +161,7 @@ def get_music_dir():
except (FileNotFoundError, NameError): except (FileNotFoundError, NameError):
pass pass
# On both Windows and macOS, the localized folder names you see in # On both Windows and macOS, the localized directory names you see in
# Explorer and Finder are actually in English on the file system. # Explorer and Finder are actually in English on the file system.
# So, defaulting to C:\Users\<user>\Music or /Users/<user>/Music # So, defaulting to C:\Users\<user>\Music or /Users/<user>/Music
# respectively is sufficient. # respectively is sufficient.