mirror of
				https://github.com/KevinMidboe/spotify-downloader.git
				synced 2025-10-29 18:00:15 +00:00 
			
		
		
		
	Update spotdl.py
This commit is contained in:
		
							
								
								
									
										490
									
								
								spotdl.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										490
									
								
								spotdl.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,490 @@
 | 
			
		||||
#!/usr/bin/env python
 | 
			
		||||
# -*- coding: UTF-8 -*-
 | 
			
		||||
 | 
			
		||||
# Usual import stuff
 | 
			
		||||
from bs4 import BeautifulSoup
 | 
			
		||||
from shutil import copyfileobj
 | 
			
		||||
from sys import path, version_info
 | 
			
		||||
from slugify import slugify
 | 
			
		||||
from titlecase import titlecase
 | 
			
		||||
from mutagen.mp4 import MP4, MP4Cover
 | 
			
		||||
import spotipy
 | 
			
		||||
import spotipy.oauth2 as oauth2
 | 
			
		||||
import eyed3
 | 
			
		||||
import requests
 | 
			
		||||
import pafy
 | 
			
		||||
import os
 | 
			
		||||
import argparse
 | 
			
		||||
import urllib
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def getInputLink(links):
 | 
			
		||||
    #for i in range(len(links)):
 | 
			
		||||
    #    links[i] = str(i + 1) + '. ' + links[i]
 | 
			
		||||
    while True:
 | 
			
		||||
        try:
 | 
			
		||||
            the_chosen_one = int(raw_input('>> Choose your number: '))
 | 
			
		||||
            if the_chosen_one >= 1 and the_chosen_one <= len(links):
 | 
			
		||||
                return links[the_chosen_one - 1]
 | 
			
		||||
            elif the_chosen_one == 0:
 | 
			
		||||
                return None
 | 
			
		||||
            else:
 | 
			
		||||
                print('Choose a valid number!')
 | 
			
		||||
        except ValueError:
 | 
			
		||||
            print('Choose a valid number!')
 | 
			
		||||
 | 
			
		||||
# Check if input song is Spotify URL or just a song name
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def isSpotify(raw_song):
 | 
			
		||||
    if (len(raw_song) == 22 and raw_song.replace(" ", "%20") == raw_song) or (raw_song.find('spotify') > -1):
 | 
			
		||||
        return True
 | 
			
		||||
    else:
 | 
			
		||||
        return False
 | 
			
		||||
 | 
			
		||||
# [Artist] - [Song Name]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def generateSongName(raw_song):
 | 
			
		||||
    if isSpotify(raw_song):
 | 
			
		||||
        tags = generateMetaTags(raw_song)
 | 
			
		||||
        raw_song = tags['artists'][0]['name'] + ' - ' + tags['name']
 | 
			
		||||
    return raw_song
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def generateMetaTags(raw_song):
 | 
			
		||||
    try:
 | 
			
		||||
        if isSpotify(raw_song):
 | 
			
		||||
            return spotify.track(raw_song)
 | 
			
		||||
        else:
 | 
			
		||||
            return spotify.search(raw_song, limit=1)['tracks']['items'][0]
 | 
			
		||||
    except BaseException:
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def generateSearchURL(song):
 | 
			
		||||
    URL = "https://www.youtube.com/results?sp=EgIQAQ%253D%253D&q=" + \
 | 
			
		||||
        urllib.quote(song)
 | 
			
		||||
    return URL
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def generateYouTubeURL(raw_song):
 | 
			
		||||
    song = generateSongName(raw_song)
 | 
			
		||||
    searchURL = generateSearchURL(song)
 | 
			
		||||
    items = requests.get(searchURL).text
 | 
			
		||||
    items_parse = BeautifulSoup(items, "html.parser")
 | 
			
		||||
    check = 1
 | 
			
		||||
    if args.manual:
 | 
			
		||||
        links = []
 | 
			
		||||
        print(song)
 | 
			
		||||
        print('')
 | 
			
		||||
        print('0. Skip downloading this song')
 | 
			
		||||
        for x in items_parse.find_all('h3', {'class': 'yt-lockup-title'}):
 | 
			
		||||
            if not x.find('channel') == -1 or not x.find('googleads') == -1:
 | 
			
		||||
                print(str(check) + '. ' + x.get_text())
 | 
			
		||||
                links.append(x.find('a')['href'])
 | 
			
		||||
                check += 1
 | 
			
		||||
        print('')
 | 
			
		||||
        result = getInputLink(links)
 | 
			
		||||
        if result is None:
 | 
			
		||||
            return None
 | 
			
		||||
    else:
 | 
			
		||||
        result = items_parse.find_all(
 | 
			
		||||
            attrs={'class': 'yt-uix-tile-link'})[0]['href']
 | 
			
		||||
        while not result.find('channel') == - \
 | 
			
		||||
                1 or not result.find('googleads') == -1:
 | 
			
		||||
            result = items_parse.find_all(
 | 
			
		||||
                attrs={'class': 'yt-uix-tile-link'})[check]['href']
 | 
			
		||||
            check += 1
 | 
			
		||||
    full_link = "youtube.com" + result
 | 
			
		||||
    return full_link
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def goPafy(raw_song):
 | 
			
		||||
    trackURL = generateYouTubeURL(raw_song)
 | 
			
		||||
    if trackURL is None:
 | 
			
		||||
        return None
 | 
			
		||||
    else:
 | 
			
		||||
        return pafy.new(trackURL)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def getYouTubeTitle(content, number):
 | 
			
		||||
    title = content.title
 | 
			
		||||
    if number is None:
 | 
			
		||||
        return title
 | 
			
		||||
    else:
 | 
			
		||||
        return str(number) + '. ' + title
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def feedTracks(file, tracks):
 | 
			
		||||
    with open(file, 'a') as fout:
 | 
			
		||||
        for item in tracks['items']:
 | 
			
		||||
            track = item['track']
 | 
			
		||||
            try:
 | 
			
		||||
                fout.write(track['external_urls']['spotify'] + '\n')
 | 
			
		||||
            except KeyError:
 | 
			
		||||
                pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def feedPlaylist(username):
 | 
			
		||||
    playlists = spotify.user_playlists(username)
 | 
			
		||||
    links = []
 | 
			
		||||
    check = 1
 | 
			
		||||
    for playlist in playlists['items']:
 | 
			
		||||
        print(str(check) + '. ' + fixEncoding(playlist['name']) + ' (' + str(playlist['tracks']['total']) + ' tracks)')
 | 
			
		||||
        links.append(playlist)
 | 
			
		||||
        check += 1
 | 
			
		||||
    print('')
 | 
			
		||||
    playlist = getInputLink(links)
 | 
			
		||||
    results = spotify.user_playlist(playlist['owner']['id'], playlist['id'], fields="tracks,next")
 | 
			
		||||
    print('')
 | 
			
		||||
    file = slugify(playlist['name'], ok='-_()[]{}') + '.txt'
 | 
			
		||||
    print('Feeding ' + str(playlist['tracks']['total']) + ' tracks to ' + file)
 | 
			
		||||
    tracks = results['tracks']
 | 
			
		||||
    feedTracks(file, tracks)
 | 
			
		||||
    while tracks['next']:
 | 
			
		||||
        tracks = spotify.next(tracks)
 | 
			
		||||
        feedTracks(file, tracks)
 | 
			
		||||
 | 
			
		||||
# Generate name for the song to be downloaded
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def generateFileName(content):
 | 
			
		||||
    title = (content.title).replace(' ', '_')
 | 
			
		||||
    title = slugify(title, ok='-_()[]{}', lower=False)
 | 
			
		||||
    return fixEncoding(title)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def downloadSong(content):
 | 
			
		||||
    music_file = generateFileName(content)
 | 
			
		||||
    if input_ext == '.webm':
 | 
			
		||||
        link = content.getbestaudio(preftype='webm')
 | 
			
		||||
        if link is not None:
 | 
			
		||||
            link.download(filepath='Music/' + music_file + input_ext)
 | 
			
		||||
    else:
 | 
			
		||||
        link = content.getbestaudio(preftype="m4a")
 | 
			
		||||
        if link is not None:
 | 
			
		||||
            link.download(filepath='Music/' + music_file + input_ext)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def convertWithAvconv(music_file):
 | 
			
		||||
    if os.name == 'nt':
 | 
			
		||||
        avconv_path = 'Scripts\\avconv.exe'
 | 
			
		||||
    else:
 | 
			
		||||
        avconv_path = 'avconv'
 | 
			
		||||
    os.system(
 | 
			
		||||
        avconv_path + ' -loglevel 0 -i "' +
 | 
			
		||||
        'Music/' +
 | 
			
		||||
        music_file +
 | 
			
		||||
        '.m4a" -ab 192k "' +
 | 
			
		||||
        'Music/' +
 | 
			
		||||
        music_file +
 | 
			
		||||
        '.mp3"')
 | 
			
		||||
    os.remove('Music/' + music_file + '.m4a')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def convertWithFfmpeg(music_file):
 | 
			
		||||
    # What are the differences and similarities between ffmpeg, libav, and avconv?
 | 
			
		||||
    # https://stackoverflow.com/questions/9477115
 | 
			
		||||
    # ffmeg encoders high to lower quality
 | 
			
		||||
    # libopus > libvorbis >= libfdk_aac > aac > libmp3lame
 | 
			
		||||
    # libfdk_aac due to copyrights needs to be compiled by end user
 | 
			
		||||
    # on MacOS brew install ffmpeg --with-fdk-aac will do just that. Other OS?
 | 
			
		||||
    # https://trac.ffmpeg.org/wiki/Encode/AAC
 | 
			
		||||
    #
 | 
			
		||||
    if args.verbose:
 | 
			
		||||
        ffmpeg_pre = 'ffmpeg -y '
 | 
			
		||||
    else:
 | 
			
		||||
        ffmpeg_pre = 'ffmpeg -hide_banner -nostats -v panic -y '
 | 
			
		||||
 | 
			
		||||
    if input_ext == '.m4a':
 | 
			
		||||
        if output_ext == '.mp3':
 | 
			
		||||
            ffmpeg_params = '-codec:v copy -codec:a libmp3lame -q:a 2 '
 | 
			
		||||
        elif output_ext == '.webm':
 | 
			
		||||
            ffmpeg_params = '-c:a libopus -vbr on -b:a 192k -vn '
 | 
			
		||||
        else:
 | 
			
		||||
            return
 | 
			
		||||
    elif input_ext == '.webm':
 | 
			
		||||
        if output_ext == '.mp3':
 | 
			
		||||
            ffmpeg_params = '-ab 192k -ar 44100 -vn '
 | 
			
		||||
        elif output_ext == '.m4a':
 | 
			
		||||
            ffmpeg_params = '-cutoff 20000 -c:a libfdk_aac -b:a 256k -vn '
 | 
			
		||||
        else:
 | 
			
		||||
            return
 | 
			
		||||
    else:
 | 
			
		||||
        print('Unknown formats. Unable to convert.', input_ext, output_ext)
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    if args.verbose:
 | 
			
		||||
        print(ffmpeg_pre +
 | 
			
		||||
              '-i "Music/' + music_file + input_ext + '" ' +
 | 
			
		||||
              ffmpeg_params +
 | 
			
		||||
              '"Music/' + music_file + output_ext + '" ')
 | 
			
		||||
 | 
			
		||||
    os.system(
 | 
			
		||||
        ffmpeg_pre +
 | 
			
		||||
        '-i "Music/' + music_file + input_ext + '" ' +
 | 
			
		||||
        ffmpeg_params +
 | 
			
		||||
        '"Music/' + music_file + output_ext + '" ')
 | 
			
		||||
    os.remove('Music/' + music_file + input_ext)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def checkExists(music_file, raw_song, islist):
 | 
			
		||||
    if os.path.exists("Music/" + music_file + input_ext + ".temp"):
 | 
			
		||||
        os.remove("Music/" + music_file + input_ext + ".temp")
 | 
			
		||||
    if args.no_convert:
 | 
			
		||||
        extension = input_ext
 | 
			
		||||
    else:
 | 
			
		||||
        extension = output_ext
 | 
			
		||||
    if os.path.isfile("Music/" + music_file + extension):
 | 
			
		||||
        if extension == '.mp3':
 | 
			
		||||
            audiofile = eyed3.load("Music/" + music_file + extension)
 | 
			
		||||
            if isSpotify(raw_song) and not audiofile.tag.title == (
 | 
			
		||||
                    generateMetaTags(raw_song))['name']:
 | 
			
		||||
                os.remove("Music/" + music_file + extension)
 | 
			
		||||
                return False
 | 
			
		||||
        if islist:
 | 
			
		||||
            return True
 | 
			
		||||
        else:
 | 
			
		||||
            prompt = raw_input(
 | 
			
		||||
                'Song with same name has already been downloaded. Re-download? (y/n): ').lower()
 | 
			
		||||
            if prompt == "y":
 | 
			
		||||
                os.remove("Music/" + music_file + extension)
 | 
			
		||||
                return False
 | 
			
		||||
            else:
 | 
			
		||||
                return True
 | 
			
		||||
 | 
			
		||||
# Remove song from file once downloaded
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def trimSong(file):
 | 
			
		||||
    with open(file, 'r') as fin:
 | 
			
		||||
        data = fin.read().splitlines(True)
 | 
			
		||||
    with open(file, 'w') as fout:
 | 
			
		||||
        fout.writelines(data[1:])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def fixSongMP3(music_file, meta_tags):
 | 
			
		||||
    audiofile = eyed3.load("Music/" + music_file + '.mp3')
 | 
			
		||||
    audiofile.tag.artist = meta_tags['artists'][0]['name']
 | 
			
		||||
    audiofile.tag.album_artist = meta_tags['artists'][0]['name']
 | 
			
		||||
    audiofile.tag.album = meta_tags['album']['name']
 | 
			
		||||
    audiofile.tag.title = meta_tags['name']
 | 
			
		||||
    artist = spotify.artist(meta_tags['artists'][0]['id'])
 | 
			
		||||
    try:
 | 
			
		||||
        audiofile.tag.genre = titlecase(artist['genres'][0])
 | 
			
		||||
    except IndexError:
 | 
			
		||||
        pass
 | 
			
		||||
    audiofile.tag.track_num = meta_tags['track_number']
 | 
			
		||||
    audiofile.tag.disc_num = meta_tags['disc_number']
 | 
			
		||||
    audiofile.tag.release_date = spotify.album(
 | 
			
		||||
        meta_tags['album']['id'])['release_date']
 | 
			
		||||
    albumart = (
 | 
			
		||||
        requests.get(
 | 
			
		||||
            meta_tags['album']['images'][0]['url'],
 | 
			
		||||
            stream=True)).raw
 | 
			
		||||
    with open('last_albumart.jpg', 'wb') as out_file:
 | 
			
		||||
        copyfileobj(albumart, out_file)
 | 
			
		||||
    albumart = open("last_albumart.jpg", "rb").read()
 | 
			
		||||
    audiofile.tag.images.set(3, albumart, "image/jpeg")
 | 
			
		||||
    audiofile.tag.save(version=(2, 3, 0))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def fixSongM4A(music_file, meta_tags):
 | 
			
		||||
    # eyed serves only mp3 not aac so using mutagen
 | 
			
		||||
    # Apple has specific tags - see mutagen docs -
 | 
			
		||||
    # http://mutagen.readthedocs.io/en/latest/api/mp4.html
 | 
			
		||||
    tags = {'album': '\xa9alb',
 | 
			
		||||
            'artist': '\xa9ART',
 | 
			
		||||
            'year': '\xa9day',
 | 
			
		||||
            'title': '\xa9nam',
 | 
			
		||||
            'comment': '\xa9cmt',
 | 
			
		||||
            'group': '\xa9grp',
 | 
			
		||||
            'writer': '\xa9wrt',
 | 
			
		||||
            'genre': '\xa9gen',
 | 
			
		||||
            'track': 'trkn',
 | 
			
		||||
            'aart': 'aART',
 | 
			
		||||
            'disk': 'disk',
 | 
			
		||||
            'cpil': 'cpil',
 | 
			
		||||
            'tempo': 'tmpo'}
 | 
			
		||||
    audiofile = MP4('Music/' + music_file + output_ext)
 | 
			
		||||
    audiofile[tags['artist']] = meta_tags['artists'][0]['name']
 | 
			
		||||
    audiofile[tags['album']] = meta_tags['album']['name']
 | 
			
		||||
    audiofile[tags['title']] = meta_tags['name']
 | 
			
		||||
    artist = spotify.artist(meta_tags['artists'][0]['id'])
 | 
			
		||||
    try:
 | 
			
		||||
        audiofile[tags['genre']] = titlecase(artist['genres'][0])
 | 
			
		||||
    except IndexError:
 | 
			
		||||
        pass
 | 
			
		||||
    album = spotify.album(meta_tags['album']['id'])
 | 
			
		||||
    audiofile[tags['year']] = album['release_date']
 | 
			
		||||
    audiofile[tags['track']] = [(meta_tags['track_number'], 0)]
 | 
			
		||||
    audiofile[tags['disk']] = [(meta_tags['disc_number'], 0)]
 | 
			
		||||
    albumart = (
 | 
			
		||||
        requests.get(meta_tags['album']['images'][0]['url'], stream=True)).raw
 | 
			
		||||
    with open('last_albumart.jpg', 'wb') as out_file:
 | 
			
		||||
        copyfileobj(albumart, out_file)
 | 
			
		||||
    with open("last_albumart.jpg", "rb") as f:
 | 
			
		||||
        audiofile["covr"] = [
 | 
			
		||||
            MP4Cover(
 | 
			
		||||
                f.read(),
 | 
			
		||||
                imageformat=MP4Cover.FORMAT_JPEG)]
 | 
			
		||||
    audiofile.save()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def convertSong(music_file):
 | 
			
		||||
    print('Converting ' + music_file + input_ext + ' to ' + output_ext[1:])
 | 
			
		||||
    if args.ffmpeg:
 | 
			
		||||
        convertWithFfmpeg(music_file)
 | 
			
		||||
    else:
 | 
			
		||||
        convertWithAvconv(music_file)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def fixSong(music_file, meta_tags):
 | 
			
		||||
    if meta_tags is None:
 | 
			
		||||
        print('Could not find meta-tags')
 | 
			
		||||
    elif output_ext == '.m4a':
 | 
			
		||||
        print('Fixing meta-tags')
 | 
			
		||||
        fixSongM4A(music_file, meta_tags)
 | 
			
		||||
    elif output_ext == '.mp3':
 | 
			
		||||
        print('Fixing meta-tags')
 | 
			
		||||
        fixSongMP3(music_file, meta_tags)
 | 
			
		||||
    else:
 | 
			
		||||
         print('Cannot embed meta-tags into given output extension')
 | 
			
		||||
 | 
			
		||||
# Logic behind preparing the song to download to finishing meta-tags
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def grabSingle(raw_song, number=None):
 | 
			
		||||
    if number:
 | 
			
		||||
        islist = True
 | 
			
		||||
    else:
 | 
			
		||||
        islist = False
 | 
			
		||||
    content = goPafy(raw_song)
 | 
			
		||||
    if content is None:
 | 
			
		||||
        return
 | 
			
		||||
    print(getYouTubeTitle(content, number))
 | 
			
		||||
    music_file = generateFileName(content)
 | 
			
		||||
    if not checkExists(music_file, raw_song, islist=islist):
 | 
			
		||||
        downloadSong(content)
 | 
			
		||||
        print('')
 | 
			
		||||
        if not args.no_convert:
 | 
			
		||||
            convertSong(music_file)
 | 
			
		||||
            meta_tags = generateMetaTags(raw_song)
 | 
			
		||||
            fixSong(music_file, meta_tags)
 | 
			
		||||
 | 
			
		||||
# Fix python2 encoding issues
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def fixEncoding(query):
 | 
			
		||||
    if version_info > (3, 0):
 | 
			
		||||
        return query
 | 
			
		||||
    else:
 | 
			
		||||
        return query.encode('utf-8')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def grabList(file):
 | 
			
		||||
    lines = open(file, 'r').read()
 | 
			
		||||
    lines = lines.splitlines()
 | 
			
		||||
    # Ignore blank lines in file (if any)
 | 
			
		||||
    try:
 | 
			
		||||
        lines.remove('')
 | 
			
		||||
    except ValueError:
 | 
			
		||||
        pass
 | 
			
		||||
    print('Total songs in list = ' + str(len(lines)) + ' songs')
 | 
			
		||||
    print('')
 | 
			
		||||
    # Count the number of song being downloaded
 | 
			
		||||
    number = 1
 | 
			
		||||
    for raw_song in lines:
 | 
			
		||||
        try:
 | 
			
		||||
            grabSingle(raw_song, number=number)
 | 
			
		||||
            trimSong(file)
 | 
			
		||||
            number += 1
 | 
			
		||||
            print('')
 | 
			
		||||
        except KeyboardInterrupt:
 | 
			
		||||
            graceQuit()
 | 
			
		||||
        except requests.exceptions.ConnectionError:
 | 
			
		||||
            lines.append(raw_song)
 | 
			
		||||
            trimSong(file)
 | 
			
		||||
            with open(file, 'a') as myfile:
 | 
			
		||||
                myfile.write(raw_song)
 | 
			
		||||
            print('Failed to download song. Will retry after other songs.')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def getArgs(argv=None):
 | 
			
		||||
    parser = argparse.ArgumentParser(description='Download and convert songs \
 | 
			
		||||
                    from Spotify, Youtube etc.',
 | 
			
		||||
                                     formatter_class=argparse.ArgumentDefaultsHelpFormatter)
 | 
			
		||||
    group = parser.add_mutually_exclusive_group(required=True)
 | 
			
		||||
 | 
			
		||||
    group.add_argument('-s', '--song',
 | 
			
		||||
                        help='download song by spotify link or name')
 | 
			
		||||
    group.add_argument('-l', '--list',
 | 
			
		||||
                        help='download songs from a file')
 | 
			
		||||
    group.add_argument('-u', '--username',
 | 
			
		||||
                        help="load user's playlists into <playlist_name>.txt")
 | 
			
		||||
 | 
			
		||||
    parser.add_argument('-n', '--no-convert', default=False,
 | 
			
		||||
                        help='skip the conversion process and meta-tags', action='store_true')
 | 
			
		||||
    parser.add_argument('-m', '--manual', default=False,
 | 
			
		||||
                        help='choose the song to download manually', action='store_true')
 | 
			
		||||
    parser.add_argument('-f', '--ffmpeg', default=False,
 | 
			
		||||
                        help='Use ffmpeg instead of libav for conversion. If not set defaults to libav',
 | 
			
		||||
                        action='store_true')
 | 
			
		||||
    parser.add_argument('-v', '--verbose', default=False,
 | 
			
		||||
                        help='show debug output', action='store_true')
 | 
			
		||||
    parser.add_argument('-i', '--input_ext', default='.m4a',
 | 
			
		||||
                        help='prefered input format .m4a or .webm (Opus)')
 | 
			
		||||
    parser.add_argument('-o', '--output_ext', default='.mp3',
 | 
			
		||||
                        help='prefered output extension .mp3 or .m4a (AAC)')
 | 
			
		||||
 | 
			
		||||
    return parser.parse_args(argv)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def graceQuit():
 | 
			
		||||
    print('')
 | 
			
		||||
    print('')
 | 
			
		||||
    print('Exitting..')
 | 
			
		||||
    exit()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
 | 
			
		||||
    # Python 3 compatibility
 | 
			
		||||
    if version_info > (3, 0):
 | 
			
		||||
        raw_input = input
 | 
			
		||||
 | 
			
		||||
    os.chdir(path[0])
 | 
			
		||||
    if not os.path.exists("Music"):
 | 
			
		||||
        os.makedirs("Music")
 | 
			
		||||
 | 
			
		||||
    for temp in os.listdir('Music/'):
 | 
			
		||||
        if temp.endswith('.m4a.temp'):
 | 
			
		||||
            os.remove('Music/' + temp)
 | 
			
		||||
 | 
			
		||||
    # Please respect this user token :)
 | 
			
		||||
    oauth2 = oauth2.SpotifyClientCredentials(
 | 
			
		||||
        client_id='4fe3fecfe5334023a1472516cc99d805',
 | 
			
		||||
        client_secret='0f02b7c483c04257984695007a4a8d5c')
 | 
			
		||||
    token = oauth2.get_access_token()
 | 
			
		||||
    spotify = spotipy.Spotify(auth=token)
 | 
			
		||||
 | 
			
		||||
    # Set up arguments
 | 
			
		||||
    args = getArgs()
 | 
			
		||||
 | 
			
		||||
    if not args.verbose:
 | 
			
		||||
        eyed3.log.setLevel("ERROR")
 | 
			
		||||
 | 
			
		||||
    if args.ffmpeg:
 | 
			
		||||
        input_ext = args.input_ext
 | 
			
		||||
        output_ext = args.output_ext
 | 
			
		||||
    else:
 | 
			
		||||
        input_ext = '.m4a'
 | 
			
		||||
        output_ext = '.mp3'
 | 
			
		||||
 | 
			
		||||
    if args.song:
 | 
			
		||||
        grabSingle(raw_song=args.song)
 | 
			
		||||
    elif args.list:
 | 
			
		||||
        grabList(file=args.list)
 | 
			
		||||
    elif args.username:
 | 
			
		||||
        feedPlaylist(username=args.username)
 | 
			
		||||
		Reference in New Issue
	
	Block a user