From d28ff08a69bf650a23a81041a0f21406ca1e9459 Mon Sep 17 00:00:00 2001 From: Rutger Rauws Date: Tue, 11 Jul 2017 19:44:56 +0200 Subject: [PATCH] Use a Spotify song's title instead of a YouTube video's title (#99) * Use a Spotify song's title instead of a YouTube video's title * Added fallback to YouTube title if song's metadata cannot be fetched from Spotify * Removed duplicate generation of metadata * Fix test cases that use download_song(..) and generate_filename(..) * Fix conflicting function * Fix conflict in check_exists() * Fix filenames for non spotify songs * Fix some bugs * Some documentation changes * Remove unnecessary determine_filename() --- core/misc.py | 6 +++--- spotdl.py | 31 ++++++++++++++++++------------- test/test_single.py | 35 +++++++++++++++++++++++------------ 3 files changed, 44 insertions(+), 28 deletions(-) diff --git a/core/misc.py b/core/misc.py index 58f1d48..a9d523c 100755 --- a/core/misc.py +++ b/core/misc.py @@ -77,13 +77,13 @@ def is_spotify(raw_song): return False -def generate_filename(title): +def sanitize_title(title): """Generate filename of the song to be downloaded.""" title = title.replace(' ', '_') # slugify removes any special characters - filename = slugify(title, ok='-_()[]{}', lower=False) - return filename + title = slugify(title, ok='-_()[]{}', lower=False) + return title def generate_token(): diff --git a/spotdl.py b/spotdl.py index b0699e3..f036a97 100755 --- a/spotdl.py +++ b/spotdl.py @@ -16,8 +16,11 @@ import os def generate_songname(raw_song): """Generate a string of the format '[artist] - [song]' for the given song.""" - if misc.is_spotify(raw_song): - tags = generate_metadata(raw_song) + tags = generate_metadata(raw_song) + if tags is None: + content = go_pafy(raw_song) + raw_song = get_youtube_title(content) + else: raw_song = u'{0} - {1}'.format(tags['artists'][0]['name'], tags['name']) return raw_song @@ -160,8 +163,7 @@ def feed_playlist(username): else: break - -def download_song(content): +def download_song(file_name, content): """Download the audio file from YouTube.""" if args.input_ext == '.webm': link = content.getbestaudio(preftype='webm') @@ -173,9 +175,8 @@ def download_song(content): if link is None: return False else: - music_file = misc.generate_filename(content.title) link.download( - filepath='{0}{1}'.format(os.path.join(args.folder, music_file), args.input_ext)) + filepath='{0}{1}'.format(os.path.join(args.folder, file_name), args.input_ext)) return True @@ -187,8 +188,8 @@ def check_exists(music_file, raw_song, islist=True): os.remove(os.path.join(args.folder, song)) continue # check if any song with similar name is already present in the given folder - umfile = misc.generate_filename(music_file) - if song.startswith(umfile): + file_name = misc.sanitize_title(music_file) + if song.startswith(file_name): # check if the already downloaded song has correct metadata already_tagged = metadata.compare(os.path.join(args.folder, song), generate_metadata(raw_song)) @@ -268,17 +269,21 @@ def grab_single(raw_song, number=None): print(get_youtube_title(content, number)) # generate file name of the song to download - music_file = misc.generate_filename(content.title) - if not check_exists(music_file, raw_song, islist=islist): - if download_song(content): + meta_tags = generate_metadata(raw_song) + songname = generate_songname(raw_song) + file_name = misc.sanitize_title(songname) + + if not check_exists(file_name, raw_song, islist=islist): + if download_song(file_name, content): print('') - input_song = music_file + args.input_ext - output_song = music_file + args.output_ext + input_song = file_name + args.input_ext + output_song = file_name + args.output_ext convert.song(input_song, output_song, args.folder, avconv=args.avconv, verbose=args.verbose) if not args.input_ext == args.output_ext: os.remove(os.path.join(args.folder, input_song)) meta_tags = generate_metadata(raw_song) + if not args.no_metadata: metadata.embed(os.path.join(args.folder, output_song), meta_tags) else: diff --git a/test/test_single.py b/test/test_single.py index 8259f93..c015c0f 100644 --- a/test/test_single.py +++ b/test/test_single.py @@ -30,47 +30,58 @@ def test_youtube_title(): def test_check_exists(): expect_check = False + # prerequisites for determining filename content = spotdl.go_pafy(raw_song) - music_file = spotdl.misc.generate_filename(content.title) - check = spotdl.check_exists(music_file, raw_song, islist=True) + songname = spotdl.generate_songname(raw_song) + file_name = spotdl.misc.sanitize_title(songname) + check = spotdl.check_exists(file_name, raw_song, islist=True) assert check == expect_check def test_download(): expect_download = True + # prerequisites for determining filename content = spotdl.go_pafy(raw_song) - download = spotdl.download_song(content) + songname = spotdl.generate_songname(raw_song) + file_name = spotdl.misc.sanitize_title(songname) + download = spotdl.download_song(file_name, content) assert download == expect_download def test_convert(): # exit code 0 = success expect_convert = 0 + # prerequisites for determining filename content = spotdl.go_pafy(raw_song) - music_file = spotdl.misc.generate_filename(content.title) - input_song = music_file + spotdl.args.input_ext - output_song = music_file + spotdl.args.output_ext + songname = spotdl.generate_songname(raw_song) + file_name = spotdl.misc.sanitize_title(songname) + input_song = file_name + spotdl.args.input_ext + output_song = file_name + spotdl.args.output_ext convert = spotdl.convert.song(input_song, output_song, spotdl.args.folder) assert convert == expect_convert def test_metadata(): expect_metadata = True + # prerequisites for determining filename content = spotdl.go_pafy(raw_song) - music_file = spotdl.misc.generate_filename(content.title) + songname = spotdl.generate_songname(raw_song) meta_tags = spotdl.generate_metadata(raw_song) - output_song = music_file + spotdl.args.output_ext + file_name = spotdl.misc.sanitize_title(songname) + output_song = file_name + spotdl.args.output_ext metadata_output = spotdl.metadata.embed(os.path.join(spotdl.args.folder, output_song), meta_tags) - input_song = music_file + spotdl.args.input_ext + input_song = file_name + spotdl.args.input_ext metadata_input = spotdl.metadata.embed(os.path.join(spotdl.args.folder, input_song), meta_tags) assert metadata_output == (metadata_input == expect_metadata) def test_check_exists2(): expect_check = True + # prerequisites for determining filename content = spotdl.go_pafy(raw_song) - music_file = spotdl.misc.generate_filename(content.title) - input_song = music_file + spotdl.args.input_ext + songname = spotdl.generate_songname(raw_song) + file_name = spotdl.misc.sanitize_title(songname) + input_song = file_name + spotdl.args.input_ext os.remove(os.path.join(spotdl.args.folder, input_song)) - check = spotdl.check_exists(music_file, raw_song, islist=True) + check = spotdl.check_exists(file_name, raw_song, islist=True) assert check == expect_check