diff --git a/spotify_dl/spotify_dl.py b/spotify_dl/spotify_dl.py index 998b2744..cc3f3e92 100755 --- a/spotify_dl/spotify_dl.py +++ b/spotify_dl/spotify_dl.py @@ -35,6 +35,9 @@ def spotify_dl(): help='Don\'t convert downloaded songs to mp3') parser.add_argument('-s', '--scrape', action="store", help="Use HTML Scraper for YouTube Search", default=True) + parser.add_argument('-w', '--no-overwrites', action='store_true', + help="Whether we should avoid overwriting the target audio file if it already exists", + default=False) parser.add_argument('-V', '--verbose', action='store_true', help='Show more information on what''s happening.') parser.add_argument('-v', '--version', action='store_true', @@ -88,7 +91,8 @@ def spotify_dl(): if args.keep_playlist_order: file_name_f = playlist_num_filename - download_songs(songs, save_path, args.format_str, args.skip_mp3, args.keep_playlist_order, file_name_f) + download_songs(songs, save_path, args.format_str, args.skip_mp3, args.keep_playlist_order, args.no_overwrites, + file_name_f) if __name__ == '__main__': diff --git a/spotify_dl/youtube.py b/spotify_dl/youtube.py index 84cc5a9b..3efc1d77 100644 --- a/spotify_dl/youtube.py +++ b/spotify_dl/youtube.py @@ -20,7 +20,7 @@ def playlist_num_filename(song): def download_songs(songs, download_directory, format_string, skip_mp3, - keep_playlist_order=False, file_name_f=default_filename): + keep_playlist_order=False, no_overwrites=False, file_name_f=default_filename): """ Downloads songs from the YouTube URL passed to either current directory or download_directory, is it is passed. :param songs: Dictionary of songs and associated artist @@ -28,8 +28,10 @@ def download_songs(songs, download_directory, format_string, skip_mp3, :param format_string: format string for the file conversion :param skip_mp3: Whether to skip conversion to MP3 :param keep_playlist_order: Whether to keep original playlist ordering. Also, prefixes songs files with playlist num + :param no_overwrites: Whether we should avoid overwriting the song if it already exists :param file_name_f: optional func(song) -> str that returns a filename for the download (without extension) """ + overwrites = not no_overwrites log.debug(f"Downloading to {download_directory}") for song in songs: query = f"{song.get('artist')} - {song.get('name')} Lyrics".replace(":", "").replace("\"", "") @@ -66,25 +68,36 @@ def download_songs(songs, download_directory, format_string, skip_mp3, continue if not skip_mp3: - try: - song_file = MP3(path.join(f"{file_path}.mp3"), ID3=EasyID3) - except mutagen.MutagenError as e: - log.debug(e) - print('Failed to download: {}, please ensure YouTubeDL is up-to-date. '.format(query)) - continue - song_file['date'] = song.get('year') - if keep_playlist_order: - song_file['tracknumber'] = str(song.get('playlist_num')) + mp3filename = f"{file_path}.mp3" + mp3file_path = path.join(mp3filename) + if overwrites or not path.exists(mp3file_path): + try: + song_file = MP3(mp3file_path, ID3=EasyID3) + except mutagen.MutagenError as e: + log.debug(e) + print('Failed to download: {}, please ensure YouTubeDL is up-to-date. '.format(query)) + continue + song_file['date'] = song.get('year') + if keep_playlist_order: + song_file['tracknumber'] = str(song.get('playlist_num')) + else: + song_file['tracknumber'] = str(song.get('num')) + '/' + str(song.get('num_tracks')) + song_file['genre'] = song.get('genre') + song_file.save() + song_file = MP3(mp3filename, ID3=ID3) + cover = song.get('cover') + if cover is not None: + if cover.lower().startswith('http'): + req = urllib.request.Request(cover) + else: + raise ValueError from None + with urllib.request.urlopen(req) as resp: # nosec + song_file.tags['APIC'] = APIC( + encoding=3, + mime='image/jpeg', + type=3, desc=u'Cover', + data=resp.read() + ) + song_file.save() else: - song_file['tracknumber'] = str(song.get('num')) + '/' + str(song.get('num_tracks')) - song_file['genre'] = song.get('genre') - song_file.save() - song_file = MP3(f"{file_path}.mp3", ID3=ID3) - if song.get('cover') is not None: - song_file.tags['APIC'] = APIC( - encoding=3, - mime='image/jpeg', - type=3, desc=u'Cover', - data=urllib.request.urlopen(song.get('cover')).read() - ) - song_file.save() + print('File {} already exists, we do not overwrite it '.format(mp3filename))