Skip to content

Instantly share code, notes, and snippets.

@tangerilli
Last active December 4, 2015 01:08
Show Gist options
  • Save tangerilli/cff42cacee5f809d6d60 to your computer and use it in GitHub Desktop.
Save tangerilli/cff42cacee5f809d6d60 to your computer and use it in GitHub Desktop.
Lists the albums in your Rdio collection, and tries to find the same albums in Google Music and Spotify
import time
import getpass
import requests
from gmusicapi import Mobileclient
import spotipy
key = '3qetuttqnjhwfbv2usagog6cca'
secret = '2q0buOGtQNaNih7kyorJxA'
device_url = 'https://services.rdio.com/oauth2/device/code/generate'
token_url = 'https://services.rdio.com/oauth2/token'
root_url = 'https://services.rdio.com/api/1/'
def authorize_rdio():
r = requests.post(device_url, data={'client_id': key})
if r.status_code != 200:
raise Exception("Error fetching device code")
device_code = r.json()['device_code']
url = r.json()['verification_url']
print "Visit https://{} and enter the code {}".format(url, device_code)
while True:
print "Waiting for authorization..."
r = requests.post(token_url, data={'client_id': key, 'client_secret': secret, 'grant_type': 'device_code', 'device_code': device_code})
if r.status_code == 200:
return r.json()['access_token']
time.sleep(5)
def call_rdio_api(rdio_access_token, method, arguments=None):
data = {
'method': method
}
if arguments:
data.update(arguments)
headers = {'Authorization': "Bearer {}".format(rdio_access_token)}
response = requests.post(root_url, data=data, headers=headers)
response.raise_for_status()
return response
def get_rdio_albums(rdio_access_token):
r = call_rdio_api(rdio_access_token, 'currentUser')
user_key = r.json()['result']['key']
print "Finding rdio albums in the collection of user id {}".format(user_key)
r = call_rdio_api(rdio_access_token, 'getAlbumsInCollection', {'user': user_key})
albums = r.json()['result']
print "Found {} albums".format(len(albums))
return albums
class MusicService(object):
def _normalize(self, name):
return name.lower().strip()
def _compare(self, album1, artist1, album2, artist2):
normalized_album1 = self._normalize(album1)
normalized_album2 = self._normalize(album2)
normalized_artist1 = self._normalize(artist1)
normalized_artist2 = self._normalize(artist2)
if normalized_album1 not in normalized_album2 and normalized_album2 not in normalized_album1:
return False
if normalized_artist1 not in normalized_artist2 and normalized_artist2 not in normalized_artist1:
return False
return True
class GoogleMusic(MusicService):
name = "Google Play Music"
def __init__(self):
self.google_api = Mobileclient()
username = raw_input("Enter your Google email address: ")
password = getpass.getpass("Enter your Google password: ")
self.google_api.login(username, password, Mobileclient.FROM_MAC_ADDRESS)
print "Logged into {}".format(self.name)
def find_album(self, artist, album_name):
query = u"{} {}".format(artist, album_name)
for album in self.google_api.search_all_access(query).get('album_hits', []):
album_data = album['album']
if self._compare(album_data['artist'], album_data['name'], artist, album_name):
return album
return None
class Spotify(MusicService):
name = "Spotify"
def __init__(self):
self.sp = spotipy.Spotify()
def find_album(self, artist_name, album_name):
query = u"{} {}".format(artist_name, album_name)
results = self.sp.search(q=query, type='album', limit=20)
for album_summary in results['albums']['items']:
album_id = album_summary['id']
album = self.sp.album(album_id)
for artist in album['artists']:
if self._compare(album['name'], artist['name'], album_name, artist_name):
return album
return None
if __name__ == '__main__':
rdio_access_token = authorize_rdio()
print "Authorized. Access token is {}".format(rdio_access_token)
albums = get_rdio_albums(rdio_access_token)
print "Found the following albums in your Rdio collection: "
for album in albums:
print u"{}: {}".format(album['artist'], album['name'])
print "---------------------------------------------------"
print ""
for service_class in (GoogleMusic, Spotify):
print "Looking for albums on {}".format(service_class.name)
service = service_class()
found_albums = []
not_found_albums = []
for album in albums:
other_album = service.find_album(album['artist'], album['name'])
if other_album:
found_albums.append(other_album)
else:
album_name = album['name']
artist_name = album['artist']
print u"Did not find {}: {}".format(artist_name, album_name)
not_found_albums.append(album)
print "Found {}/{} albums on {}".format(len(found_albums), len(albums), service.name)
print "-----------------------------"
print ""
spotipy==2.3.7
requests==2.8.1
gmusicapi==7.0.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment