Last active
December 4, 2015 01:08
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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