Skip to content

Instantly share code, notes, and snippets.

@KillerGoldFisch
Created October 7, 2014 15:17
Show Gist options
  • Select an option

  • Save KillerGoldFisch/574c5502c6f54587e422 to your computer and use it in GitHub Desktop.

Select an option

Save KillerGoldFisch/574c5502c6f54587e422 to your computer and use it in GitHub Desktop.
Spotify playlist downloader
#!/usr/bin/env python
import groove
import urllib2
import argparse
from bs4 import BeautifulSoup
import difflib
def get_soup(url):
page = urllib2.urlopen(url)
return BeautifulSoup(page)
def spotify_parse(url):
soup = get_soup(url)
title = soup.find("strong", { "class" : "tl-name-name" }).get_text()
artist = soup.find("div", { "class" : "tl-name-more text-muted" }).get_text().strip()
album = soup.find("h1", { "class" : "h-title" }).get_text().strip()
return title, artist, album
def get_distance(a, b):
return difflib.SequenceMatcher(None, a.upper(), b.upper()).ratio()
def get_distance_track(a_album, a_artist, a_track, b_album, b_artist, b_track):
d_album = get_distance(a_album, b_album)
d_artist = get_distance(a_artist, b_artist)
d_track = get_distance(a_track, b_track)
return (1.0*d_album + 7.0*d_artist + 4.0*d_track)/12.0
def get_best_match(a_album, a_artist, a_track, s):
best = None
best_score = 0.0
for m,l in enumerate(s):
b_album = l["AlbumName"]
b_artist = l["ArtistName"]
b_track = l["SongName"]
score = get_distance_track(a_album, a_artist, a_track, b_album, b_artist, b_track)
if score > best_score:
best_score = score
best = s[m]
return best_score, best
def main():
parser = argparse.ArgumentParser(description = 'Export Spotify playlist to MP3.')
parser.add_argument('-f', '--filename', help='File holding list of HTTP spotify URIs.', required = True)
args = vars(parser.parse_args())
groove.getToken()
with open( args['filename'], 'rb') as input:
for line in input:
meta = spotify_parse(line)
name = "%s - %s"%(meta[1], meta[2])
filename = name+".mp3"
print "Album=%s Artist=%s Track=%s"%meta
print name
s = groove.getResultsFromSearch(name)
if len(s) == 0:
print "No results"
continue
match = get_best_match(meta[0], meta[1], meta[2], s)
print "match: Score=%0.2f%% | %s - %s"%(match[0]*100, unicode(match[1]["ArtistName"]).encode( "utf-8" ), unicode(match[1]["SongName"]).encode( "utf-8" )) #Print the results
if match[0] > 0.8: groove.downloadSong(s[0], filename, groove.chunk_report)
print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment