mirror of
				https://github.com/KevinMidboe/spotify-downloader.git
				synced 2025-10-29 18:00:15 +00:00 
			
		
		
		
	Rename to functions to snakecase
This commit is contained in:
		
							
								
								
									
										16
									
								
								core/misc.py
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								core/misc.py
									
									
									
									
									
								
							| @@ -2,7 +2,7 @@ import argparse | |||||||
| import sys | import sys | ||||||
| import os | import os | ||||||
|  |  | ||||||
| def getInputLink(links): | def input_link(links): | ||||||
|     while True: |     while True: | ||||||
|         try: |         try: | ||||||
|             the_chosen_one = int(raw_input('>> Choose your number: ')) |             the_chosen_one = int(raw_input('>> Choose your number: ')) | ||||||
| @@ -15,13 +15,13 @@ def getInputLink(links): | |||||||
|         except ValueError: |         except ValueError: | ||||||
|             print('Choose a valid number!') |             print('Choose a valid number!') | ||||||
|  |  | ||||||
| def trimSong(file): | def trim_song(file): | ||||||
|     with open(file, 'r') as fin: |     with open(file, 'r') as fin: | ||||||
|         data = fin.read().splitlines(True) |         data = fin.read().splitlines(True) | ||||||
|     with open(file, 'w') as fout: |     with open(file, 'w') as fout: | ||||||
|         fout.writelines(data[1:]) |         fout.writelines(data[1:]) | ||||||
|  |  | ||||||
| def getArgs(): | def get_arguments(): | ||||||
|     parser = argparse.ArgumentParser(description='Download and convert songs \ |     parser = argparse.ArgumentParser(description='Download and convert songs \ | ||||||
|                     from Spotify, Youtube etc.', |                     from Spotify, Youtube etc.', | ||||||
|                                      formatter_class=argparse.ArgumentDefaultsHelpFormatter) |                                      formatter_class=argparse.ArgumentDefaultsHelpFormatter) | ||||||
| @@ -33,7 +33,6 @@ def getArgs(): | |||||||
|                         help='download songs from a file') |                         help='download songs from a file') | ||||||
|     group.add_argument('-u', '--username', |     group.add_argument('-u', '--username', | ||||||
|                         help="load user's playlists into <playlist_name>.txt") |                         help="load user's playlists into <playlist_name>.txt") | ||||||
|  |  | ||||||
|     parser.add_argument('-n', '--no-convert', default=False, |     parser.add_argument('-n', '--no-convert', default=False, | ||||||
|                         help='skip the conversion process and meta-tags', action='store_true') |                         help='skip the conversion process and meta-tags', action='store_true') | ||||||
|     parser.add_argument('-m', '--manual', default=False, |     parser.add_argument('-m', '--manual', default=False, | ||||||
| @@ -50,25 +49,24 @@ def getArgs(): | |||||||
|  |  | ||||||
|     return parser.parse_args() |     return parser.parse_args() | ||||||
|  |  | ||||||
|  | def is_spotify(raw_song): | ||||||
| def isSpotify(raw_song): |  | ||||||
|     if (len(raw_song) == 22 and raw_song.replace(" ", "%20") == raw_song) or (raw_song.find('spotify') > -1): |     if (len(raw_song) == 22 and raw_song.replace(" ", "%20") == raw_song) or (raw_song.find('spotify') > -1): | ||||||
|         return True |         return True | ||||||
|     else: |     else: | ||||||
|         return False |         return False | ||||||
|  |  | ||||||
| def generateSearchURL(song): | def generate_search_URL(song): | ||||||
|     URL = "https://www.youtube.com/results?sp=EgIQAQ%253D%253D&q=" + \ |     URL = "https://www.youtube.com/results?sp=EgIQAQ%253D%253D&q=" + \ | ||||||
|         song.replace(" ", "%20") |         song.replace(" ", "%20") | ||||||
|     return URL |     return URL | ||||||
|  |  | ||||||
| def fixEncoding(query): | def fix_encoding(query): | ||||||
|     if sys.version_info > (3, 0): |     if sys.version_info > (3, 0): | ||||||
|         return query |         return query | ||||||
|     else: |     else: | ||||||
|         return query.encode('utf-8') |         return query.encode('utf-8') | ||||||
|  |  | ||||||
| def graceQuit(): | def grace_quit(): | ||||||
|     print('') |     print('') | ||||||
|     print('') |     print('') | ||||||
|     print('Exitting..') |     print('Exitting..') | ||||||
|   | |||||||
							
								
								
									
										121
									
								
								spotdl.py
									
									
									
									
									
								
							
							
						
						
									
										121
									
								
								spotdl.py
									
									
									
									
									
								
							| @@ -1,15 +1,14 @@ | |||||||
| #!/usr/bin/env python | #!/usr/bin/env python | ||||||
| # -*- coding: UTF-8 -*- | # -*- coding: UTF-8 -*- | ||||||
|  |  | ||||||
| from core.misc import getInputLink | from core.misc import input_link | ||||||
| from core.misc import trimSong | from core.misc import trim_song | ||||||
| from core.misc import getArgs | from core.misc import get_arguments | ||||||
| from core.misc import isSpotify | from core.misc import is_spotify | ||||||
| from core.misc import generateSearchURL | from core.misc import generate_search_URL | ||||||
| from core.misc import fixEncoding | from core.misc import fix_encoding | ||||||
| from core.misc import graceQuit | from core.misc import grace_quit | ||||||
| from bs4 import BeautifulSoup | from bs4 import BeautifulSoup | ||||||
| from shutil import copyfileobj |  | ||||||
| import sys | import sys | ||||||
| from slugify import slugify | from slugify import slugify | ||||||
| from titlecase import titlecase | from titlecase import titlecase | ||||||
| @@ -22,15 +21,15 @@ import urllib2 | |||||||
| import pafy | import pafy | ||||||
| import os | import os | ||||||
|  |  | ||||||
| def generateSongName(raw_song): | def generate_song_name(raw_song): | ||||||
|     if isSpotify(raw_song): |     if is_spotify(raw_song): | ||||||
|         tags = generateMetaTags(raw_song) |         tags = generate_metadata(raw_song) | ||||||
|         raw_song = tags['artists'][0]['name'] + ' - ' + tags['name'] |         raw_song = tags['artists'][0]['name'] + ' - ' + tags['name'] | ||||||
|     return raw_song |     return raw_song | ||||||
|  |  | ||||||
| def generateMetaTags(raw_song): | def generate_metadata(raw_song): | ||||||
|     try: |     try: | ||||||
|         if isSpotify(raw_song): |         if is_spotify(raw_song): | ||||||
|             meta_tags = spotify.track(raw_song) |             meta_tags = spotify.track(raw_song) | ||||||
|         else: |         else: | ||||||
|             meta_tags = spotify.search(raw_song, limit=1)['tracks']['items'][0] |             meta_tags = spotify.search(raw_song, limit=1)['tracks']['items'][0] | ||||||
| @@ -47,9 +46,9 @@ def generateMetaTags(raw_song): | |||||||
|     except BaseException: |     except BaseException: | ||||||
|         return None |         return None | ||||||
|  |  | ||||||
| def generateYouTubeURL(raw_song): | def generate_YouTube_URL(raw_song): | ||||||
|     song = generateSongName(raw_song) |     song = generate_song_name(raw_song) | ||||||
|     searchURL = generateSearchURL(song) |     searchURL = generate_search_URL(song) | ||||||
|     item = urllib2.urlopen(searchURL).read() |     item = urllib2.urlopen(searchURL).read() | ||||||
|     items_parse = BeautifulSoup(item, "html.parser") |     items_parse = BeautifulSoup(item, "html.parser") | ||||||
|     check = 1 |     check = 1 | ||||||
| @@ -64,7 +63,7 @@ def generateYouTubeURL(raw_song): | |||||||
|                 links.append(x.find('a')['href']) |                 links.append(x.find('a')['href']) | ||||||
|                 check += 1 |                 check += 1 | ||||||
|         print('') |         print('') | ||||||
|         result = getInputLink(links) |         result = input_link(links) | ||||||
|         if result is None: |         if result is None: | ||||||
|             return None |             return None | ||||||
|     else: |     else: | ||||||
| @@ -78,21 +77,21 @@ def generateYouTubeURL(raw_song): | |||||||
|     full_link = "youtube.com" + result |     full_link = "youtube.com" + result | ||||||
|     return full_link |     return full_link | ||||||
|  |  | ||||||
| def goPafy(raw_song): | def go_pafy(raw_song): | ||||||
|     trackURL = generateYouTubeURL(raw_song) |     trackURL = generate_YouTube_URL(raw_song) | ||||||
|     if trackURL is None: |     if trackURL is None: | ||||||
|         return None |         return None | ||||||
|     else: |     else: | ||||||
|         return pafy.new(trackURL) |         return pafy.new(trackURL) | ||||||
|  |  | ||||||
| def getYouTubeTitle(content, number): | def get_YouTube_title(content, number): | ||||||
|     title = content.title |     title = content.title | ||||||
|     if number is None: |     if number is None: | ||||||
|         return title |         return title | ||||||
|     else: |     else: | ||||||
|         return str(number) + '. ' + title |         return str(number) + '. ' + title | ||||||
|  |  | ||||||
| def feedTracks(file, tracks): | def feed_tracks(file, tracks): | ||||||
|     with open(file, 'a') as fout: |     with open(file, 'a') as fout: | ||||||
|         for item in tracks['items']: |         for item in tracks['items']: | ||||||
|             track = item['track'] |             track = item['track'] | ||||||
| @@ -101,34 +100,34 @@ def feedTracks(file, tracks): | |||||||
|             except KeyError: |             except KeyError: | ||||||
|                 pass |                 pass | ||||||
|  |  | ||||||
| def feedPlaylist(username): | def feed_playlist(username): | ||||||
|     playlists = spotify.user_playlists(username) |     playlists = spotify.user_playlists(username) | ||||||
|     links = [] |     links = [] | ||||||
|     check = 1 |     check = 1 | ||||||
|     for playlist in playlists['items']: |     for playlist in playlists['items']: | ||||||
|         print(str(check) + '. ' + fixEncoding(playlist['name']) + ' (' + str(playlist['tracks']['total']) + ' tracks)') |         print(str(check) + '. ' + fix_encoding(playlist['name']) + ' (' + str(playlist['tracks']['total']) + ' tracks)') | ||||||
|         links.append(playlist) |         links.append(playlist) | ||||||
|         check += 1 |         check += 1 | ||||||
|     print('') |     print('') | ||||||
|     playlist = getInputLink(links) |     playlist = input_link(links) | ||||||
|     results = spotify.user_playlist(playlist['owner']['id'], playlist['id'], fields="tracks,next") |     results = spotify.user_playlist(playlist['owner']['id'], playlist['id'], fields="tracks,next") | ||||||
|     print('') |     print('') | ||||||
|     file = slugify(playlist['name'], ok='-_()[]{}') + '.txt' |     file = slugify(playlist['name'], ok='-_()[]{}') + '.txt' | ||||||
|     print('Feeding ' + str(playlist['tracks']['total']) + ' tracks to ' + file) |     print('Feeding ' + str(playlist['tracks']['total']) + ' tracks to ' + file) | ||||||
|     tracks = results['tracks'] |     tracks = results['tracks'] | ||||||
|     feedTracks(file, tracks) |     feed_tracks(file, tracks) | ||||||
|     while tracks['next']: |     while tracks['next']: | ||||||
|         tracks = spotify.next(tracks) |         tracks = spotify.next(tracks) | ||||||
|         feedTracks(file, tracks) |         feed_tracks(file, tracks) | ||||||
|  |  | ||||||
| # Generate name for the song to be downloaded | # Generate name for the song to be downloaded | ||||||
| def generateFileName(content): | def generate_filename(content): | ||||||
|     title = (content.title).replace(' ', '_') |     title = (content.title).replace(' ', '_') | ||||||
|     title = slugify(title, ok='-_()[]{}', lower=False) |     title = slugify(title, ok='-_()[]{}', lower=False) | ||||||
|     return fixEncoding(title) |     return fix_encoding(title) | ||||||
|  |  | ||||||
| def downloadSong(content, input_ext): | def download_song(content, input_ext): | ||||||
|     music_file = generateFileName(content) |     music_file = generate_filename(content) | ||||||
|     if input_ext == '.webm': |     if input_ext == '.webm': | ||||||
|         link = content.getbestaudio(preftype='webm') |         link = content.getbestaudio(preftype='webm') | ||||||
|         if link is not None: |         if link is not None: | ||||||
| @@ -138,7 +137,7 @@ def downloadSong(content, input_ext): | |||||||
|         if link is not None: |         if link is not None: | ||||||
|             link.download(filepath='Music/' + music_file + input_ext) |             link.download(filepath='Music/' + music_file + input_ext) | ||||||
|  |  | ||||||
| def convertWithAvconv(music_file, input_ext, output_ext, verbose): | def convert_with_avconv(music_file, input_ext, output_ext, verbose): | ||||||
|     if os.name == 'nt': |     if os.name == 'nt': | ||||||
|         avconv_path = 'Scripts\\avconv.exe' |         avconv_path = 'Scripts\\avconv.exe' | ||||||
|     else: |     else: | ||||||
| @@ -153,7 +152,7 @@ def convertWithAvconv(music_file, input_ext, output_ext, verbose): | |||||||
|         output_ext + '"') |         output_ext + '"') | ||||||
|     os.remove('Music/' + music_file + input_ext) |     os.remove('Music/' + music_file + input_ext) | ||||||
|  |  | ||||||
| def convertWithFfmpeg(music_file, input_ext, output_ext, verbose): | def convert_with_FFmpeg(music_file, input_ext, output_ext, verbose): | ||||||
|     # What are the differences and similarities between ffmpeg, libav, and avconv? |     # What are the differences and similarities between ffmpeg, libav, and avconv? | ||||||
|     # https://stackoverflow.com/questions/9477115 |     # https://stackoverflow.com/questions/9477115 | ||||||
|     # ffmeg encoders high to lower quality |     # ffmeg encoders high to lower quality | ||||||
| @@ -199,7 +198,7 @@ def convertWithFfmpeg(music_file, input_ext, output_ext, verbose): | |||||||
|         '"Music/' + music_file + output_ext + '" ') |         '"Music/' + music_file + output_ext + '" ') | ||||||
|     os.remove('Music/' + music_file + input_ext) |     os.remove('Music/' + music_file + input_ext) | ||||||
|  |  | ||||||
| def checkExists(music_file, raw_song, islist): | def check_exists(music_file, raw_song, islist): | ||||||
|     files = os.listdir("Music") |     files = os.listdir("Music") | ||||||
|     for file in files: |     for file in files: | ||||||
|         if file.endswith(".temp"): |         if file.endswith(".temp"): | ||||||
| @@ -209,8 +208,8 @@ def checkExists(music_file, raw_song, islist): | |||||||
|         if file.startswith(music_file): |         if file.startswith(music_file): | ||||||
|             # FIXME |             # FIXME | ||||||
|             #audiofile = mutagen.load("Music/" + music_file + output_ext) |             #audiofile = mutagen.load("Music/" + music_file + output_ext) | ||||||
|             #if isSpotify(raw_song) and not audiofile.tag.title == ( |             #if is_spotify(raw_song) and not audiofile.tag.title == ( | ||||||
|             #        generateMetaTags(raw_song))['name']: |             #        generate_metadata(raw_song))['name']: | ||||||
|             #    os.remove("Music/" + music_file + output_ext) |             #    os.remove("Music/" + music_file + output_ext) | ||||||
|             #    return False |             #    return False | ||||||
|             os.remove("Music/" + file) |             os.remove("Music/" + file) | ||||||
| @@ -227,19 +226,19 @@ def checkExists(music_file, raw_song, islist): | |||||||
|                 return True |                 return True | ||||||
|  |  | ||||||
| # Remove song from file once downloaded | # Remove song from file once downloaded | ||||||
| def fixSong(music_file, meta_tags, output_ext): | def fix_metadata(music_file, meta_tags, output_ext): | ||||||
|     if meta_tags is None: |     if meta_tags is None: | ||||||
|         print('Could not find meta-tags') |         print('Could not find meta-tags') | ||||||
|     elif output_ext == '.m4a': |     elif output_ext == '.m4a': | ||||||
|         print('Fixing meta-tags') |         print('Fixing meta-tags') | ||||||
|         fixSongM4A(music_file, meta_tags, output_ext) |         fix_metadata_m4a(music_file, meta_tags, output_ext) | ||||||
|     elif output_ext == '.mp3': |     elif output_ext == '.mp3': | ||||||
|         print('Fixing meta-tags') |         print('Fixing meta-tags') | ||||||
|         fixSongMP3(music_file, meta_tags, output_ext) |         fix_metadata_mp3(music_file, meta_tags, output_ext) | ||||||
|     else: |     else: | ||||||
|          print('Cannot embed meta-tags into given output extension') |          print('Cannot embed meta-tags into given output extension') | ||||||
|  |  | ||||||
| def fixSongMP3(music_file, meta_tags, output_ext): | def fix_metadata_mp3(music_file, meta_tags, output_ext): | ||||||
|     audiofile = EasyID3('Music/' + music_file + output_ext) |     audiofile = EasyID3('Music/' + music_file + output_ext) | ||||||
|     audiofile['artist'] = meta_tags['artists'][0]['name'] |     audiofile['artist'] = meta_tags['artists'][0]['name'] | ||||||
|     audiofile['albumartist'] = meta_tags['artists'][0]['name'] |     audiofile['albumartist'] = meta_tags['artists'][0]['name'] | ||||||
| @@ -257,7 +256,7 @@ def fixSongMP3(music_file, meta_tags, output_ext): | |||||||
|     albumart.close() |     albumart.close() | ||||||
|     audiofile.save(v2_version=3) |     audiofile.save(v2_version=3) | ||||||
|  |  | ||||||
| def fixSongM4A(music_file, meta_tags, output_ext): | def fix_metadata_m4a(music_file, meta_tags, output_ext): | ||||||
|     # eyed serves only mp3 not aac so using mutagen |     # eyed serves only mp3 not aac so using mutagen | ||||||
|     # 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 | ||||||
| @@ -289,39 +288,39 @@ def fixSongM4A(music_file, meta_tags, output_ext): | |||||||
|     albumart.close() |     albumart.close() | ||||||
|     audiofile.save() |     audiofile.save() | ||||||
|  |  | ||||||
| def convertSong(music_file, input_ext, output_ext, ffmpeg, verbose): | def convert_song(music_file, input_ext, output_ext, ffmpeg, verbose): | ||||||
|     print(music_file, input_ext, output_ext, ffmpeg, verbose) |     print(music_file, input_ext, output_ext, ffmpeg, verbose) | ||||||
|     if not input_ext == output_ext: |     if not input_ext == output_ext: | ||||||
|         print('Converting ' + music_file + input_ext + ' to ' + output_ext[1:]) |         print('Converting ' + music_file + input_ext + ' to ' + output_ext[1:]) | ||||||
|         if ffmpeg: |         if ffmpeg: | ||||||
|             convertWithFfmpeg(music_file, input_ext, output_ext, verbose) |             convert_with_FFmpeg(music_file, input_ext, output_ext, verbose) | ||||||
|         else: |         else: | ||||||
|             convertWithAvconv(music_file, input_ext, output_ext, verbose) |             convert_with_avconv(music_file, input_ext, output_ext, verbose) | ||||||
|     else: |     else: | ||||||
|         print('Skipping conversion since input_ext = output_ext') |         print('Skipping conversion since input_ext = output_ext') | ||||||
|  |  | ||||||
|  |  | ||||||
| # Logic behind preparing the song to download to finishing meta-tags | # Logic behind preparing the song to download to finishing meta-tags | ||||||
| def grabSingle(raw_song, number=None): | def grab_single(raw_song, number=None): | ||||||
|     if number: |     if number: | ||||||
|         islist = True |         islist = True | ||||||
|     else: |     else: | ||||||
|         islist = False |         islist = False | ||||||
|     content = goPafy(raw_song) |     content = go_pafy(raw_song) | ||||||
|     if content is None: |     if content is None: | ||||||
|         return |         return | ||||||
|     print(getYouTubeTitle(content, number)) |     print(get_YouTube_title(content, number)) | ||||||
|     music_file = generateFileName(content) |     music_file = generate_filename(content) | ||||||
|     if not checkExists(music_file, raw_song, islist=islist): |     if not check_exists(music_file, raw_song, islist=islist): | ||||||
|         downloadSong(content, args.input_ext) |         download_song(content, args.input_ext) | ||||||
|         print('') |         print('') | ||||||
|         if not args.no_convert: |         if not args.no_convert: | ||||||
|             convertSong(music_file, args.input_ext, args.output_ext, args.ffmpeg, args.verbose) |             convert_song(music_file, args.input_ext, args.output_ext, args.ffmpeg, args.verbose) | ||||||
|             meta_tags = generateMetaTags(raw_song) |             meta_tags = generate_metadata(raw_song) | ||||||
|             fixSong(music_file, meta_tags, args.output_ext) |             fix_metadata(music_file, meta_tags, args.output_ext) | ||||||
|  |  | ||||||
| # Fix python2 encoding issues | # Fix python2 encoding issues | ||||||
| def grabList(file): | def grab_list(file): | ||||||
|     lines = open(file, 'r').read() |     lines = open(file, 'r').read() | ||||||
|     lines = lines.splitlines() |     lines = lines.splitlines() | ||||||
|     # Ignore blank lines in file (if any) |     # Ignore blank lines in file (if any) | ||||||
| @@ -335,15 +334,15 @@ def grabList(file): | |||||||
|     number = 1 |     number = 1 | ||||||
|     for raw_song in lines: |     for raw_song in lines: | ||||||
|         try: |         try: | ||||||
|             grabSingle(raw_song, number=number) |             grab_single(raw_song, number=number) | ||||||
|             trimSong(file) |             trim_song(file) | ||||||
|             number += 1 |             number += 1 | ||||||
|             print('') |             print('') | ||||||
|         except KeyboardInterrupt: |         except KeyboardInterrupt: | ||||||
|             graceQuit() |             grace_quit() | ||||||
|         except ConnectionError: |         except ConnectionError: | ||||||
|             lines.append(raw_song) |             lines.append(raw_song) | ||||||
|             trimSong(file) |             trim_song(file) | ||||||
|             with open(file, 'a') as myfile: |             with open(file, 'a') as myfile: | ||||||
|                 myfile.write(raw_song) |                 myfile.write(raw_song) | ||||||
|             print('Failed to download song. Will retry after other songs.') |             print('Failed to download song. Will retry after other songs.') | ||||||
| @@ -367,7 +366,7 @@ if __name__ == '__main__': | |||||||
|     spotify = spotipy.Spotify(auth=token) |     spotify = spotipy.Spotify(auth=token) | ||||||
|  |  | ||||||
|     # Set up arguments |     # Set up arguments | ||||||
|     args = getArgs() |     args = get_arguments() | ||||||
|     print(args) |     print(args) | ||||||
|  |  | ||||||
|     #if args.ffmpeg: |     #if args.ffmpeg: | ||||||
| @@ -378,8 +377,8 @@ if __name__ == '__main__': | |||||||
|     #    output_ext = '.mp3' |     #    output_ext = '.mp3' | ||||||
|  |  | ||||||
|     if args.song: |     if args.song: | ||||||
|         grabSingle(raw_song=args.song) |         grab_single(raw_song=args.song) | ||||||
|     elif args.list: |     elif args.list: | ||||||
|         grabList(file=args.list) |         grab_list(file=args.list) | ||||||
|     elif args.username: |     elif args.username: | ||||||
|         feedPlaylist(username=args.username) |         feed_playlist(username=args.username) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user