class GoogleMusicHelper(object): def __init__(self, email=None, password=None): self.google_music_client = Mobileclient() if email and password: self.login(email, password) def login(self, email, password): if self.google_music_client.login(email, password, Mobileclient.FROM_MAC_ADDRESS): return "Logged in to Google" return "Error logging in" def add_song_by_name_to_google_library(self, song="", artist=""): results = self.google_music_client.search(query=song + " " + artist, max_results=1) if results: track = results["song_hits"][0]["track"] return self.google_music_client.add_store_tracks( track.get("storeId") or track.get("nid")) def list_playlists(self): return self.google_music_client.get_all_user_playlist_contents() def sync_playlists_with_library(self, password=None, username=None): if self.google_music_client.login(username, password, Mobileclient.FROM_MAC_ADDRESS): all_tracks = [] for playlist in self.google_music_client.get_all_user_playlist_contents( ): for track in playlist["tracks"]: all_tracks.append(track["track"]) playlist_store_ids = [track["storeId"] for track in all_tracks] all_songs = self.google_music_client.get_all_songs( incremental=False) print all_songs[0] added_store_ids = [] for song in all_songs: store_id = None if song.get("nid"): store_id = song["nid"] elif song.get("storeId"): store_id = song["storeId"] added_store_ids.append(store_id) new_store_ids = set(playlist_store_ids) - set(added_store_ids) new_tracks = [ track for track in all_tracks if track["storeId"] not in added_store_ids ] for storeId in new_store_ids: for track in new_tracks: if track["storeId"] == storeId: break print track['title'] + " by " + track["artist"] print self.google_music_client.add_store_tracks(storeId)
def addTracksGPM(trackList, api): #List of Song id's idList = [] #Searches store for each track id and adds it too list for i in range(len(trackList)): tracks = Mobileclient.search(api, trackList[i], 50)['song_hits'][0]['track'] idList.append(tracks['storeId']) #Add tracks to user library if (len(idList) > 0): Mobileclient.add_store_tracks(api, idList) else: print("All Google Play Music tracks are already added") return None
) > 0 and title == song_title and artist == artist_name and album_artist == artist_name and explicit_agree( explicit, args.explicit): #If the length indicates we're working with a real song, then go ahead and cautiously grab the information we think we need. Not all tracks have all this information. try: store_id = track["storeId"] except: print("No Store ID for Query") try: artist_id = track["artistId"] except: print("No Artist ID for Query") try: #Add the song to Play Music library mc.add_store_tracks([store_id]) mc.add_songs_to_playlist(playlist_id, store_id) print("Added song: \"" + title + "\" by " + artist + " to playlist: " + playlist_name) print("Song artist: " + artist + ", album_artist: " + album_artist) #Break out of the loop cause we don't need to check any of the other results break except: print("Unable to add song: \"" + title + "\" by " + artist + " to playlist: " + playlist_name) #Don't break out of the loop if we were unable to add this song, since then we can keep going through the rest of the songs in the list in case we find one we CAN add else: print("No results found, moving to next search query")
# import tracks if migration_type == 'all' or migration_type == 'tracks': log.info('Importing ' + str(len(all_tracks)) + ' All Access tracks to ' + import_username) for i, track in enumerate(all_tracks, start=1): track_id = get_aa_id(track) track_artist = track.get('artist') track_title = track.get('title') if i % 100 == 0: log.info('Importing track ' + str(i) + ' of ' + str(len(all_tracks))) if not simulate: try: import_api.add_store_tracks(track_id) except CallFailure as e: log.error('Add failed for track ' + track_artist + ' - ' + track_title) log.debug('ID of failed track is ' + track_id) continue # create consolidated list of library and thumbs up tracks with a rating if migration_type == 'all' or migration_type == 'ratings': merged_tracks = merge_track_lists(all_tracks, thumbs_up_tracks) rated_tracks = [t for t in merged_tracks if t.get('rating', 0) > 0] log.info('Importing ' + str(len(rated_tracks)) + ' track ratings to ' + import_username) # set rating on tracks
class Music: isRunning = True def __init__(self): self.token = self.getToken() self.getCred() self.readFile() def chunks(self, l, n): for i in range(0, len(l), n): yield l[i:i + n] def getToken(self): data = {"grant_type": "client_credentials"} auth = b"Basic OGExNTNkNjYxNjliNDBmYmJmNGEzYzAwNDMxMDA4Mzg6ZjRjNWY4NWQ0ZTE2NDI2MDg2NTYzM2FkOTY5MWI4NWI=" result = requests.post("https://accounts.spotify.com/api/token", data=dict(grant_type="client_credentials"), headers={"Authorization": auth}) result = json.loads(result.content) return result["access_token"] def readFile(self): tracks = [] with open("spotify.txt") as f: for line in f: trackId = line[31:].rstrip() tracks.append(trackId) self.count = len(tracks) print("Found", self.count, "songs") self.getInfo(list(self.chunks(tracks, 30))) def getInfo(self, data): print("Getting info from Spotify") songs = [] auth = "Bearer " + self.token for item in data: tracks = ",".join(item) url = "https://api.spotify.com/v1/tracks?ids=" + tracks resp = requests.get(url, headers={"Authorization": auth}) data = json.loads(resp.text) for track in data["tracks"]: song = track["name"] + " " + track["artists"][0]["name"] songs.append(song) self.searchSongs(songs) def getCred(self): with open('credentials.json', 'r+') as data: cred = json.load(data) if cred["username"] == None: cred["username"] = input("Your Google Email please: ") cred["password"] = getpass.getpass( prompt='And Your Password: '******'==============') command = input("Add, Playlist Name or Quit?\n>>> ") print('==============') if command == "Add" or command == "add": self.addMusic(songs) elif command == "Quit" or command == "quit": self.isRunning = False else: self.addToPlaylist(songs, command) print("\u001b[38;5;76mDone!\u001b[0m") self.isRunning = False def addMusic(self, songs): self.api.add_store_tracks(songs) def addToPlaylist(self, songs, name): user_playlists = self.api.get_all_playlists() temp = list(filter(lambda d: d['name'] in name, user_playlists)) if temp: playlist = temp[0]["id"] else: playlist = self.api.create_playlist(name) data = self.api.add_songs_to_playlist(playlist, songs)
# Search for each of the band names, recording the store id of the top song result in each # set of search results. store_track_ids = [] for band in bands: results = mc.search(band) if 'song_hits' not in results or len(results['song_hits']) == 0: logging.error("No song results for query '%s'", band) continue song = results['song_hits'][0] logging.info("For band '%s', got song %s", band, song) store_track_ids.append(song['track']['storeId']) # Add each of those songs to the library, so that we can transform the store song ids into # song ids. Why doesn't the search result return song ids? Who knows. logging.info("Adding store tracks to library") track_ids = mc.add_store_tracks(store_track_ids) # Create a new playlist. logging.info("Creating new playlist") playlist_id = mc.create_playlist( "Iceland Airwaves 2017 - %s" % unicode(datetime.datetime.now()), "The top song result for each band name in the Iceland Airwaves lineup", public=True) logging.info("Created playlist with id %s", playlist_id) # Add all of the song ids to the newly-created playlist. logging.info("Adding song ids to playlist") mc.add_songs_to_playlist(playlist_id, track_ids)
# Iterates through all the user playlists and adds them to the library from gmusicapi import Mobileclient import getpass api = Mobileclient() email = getpass.getpass(prompt='What is your email?') password = getpass.getpass(prompt='What is your password?') api.login(email, password, Mobileclient.FROM_MAC_ADDRESS) email = None password = None allPlaylists = api.get_all_user_playlist_contents() for playlist in allPlaylists: for track in playlist['tracks']: if 'track' in track and 'storeId' in track['track']: api.add_store_tracks(track['track']['storeId']) else: print 'Track not added: {}'.format(track)
else: fails.append({'query': track, 'resp': queRES['song_hits']}) if counter < 50: counter += 1 else: total += 50 counter = 0 print(total) print(str(len(songIDs)) + ' ' + str(len(fails)) + '\n') with shelve.open('outcomeFile') as outcome: outcome['good'] = songIDs outcome['bad'] = fails mc.add_store_tracks(songIDs) #ask user if they want to include potential matches that failed earlier checks. If yes it will add these songs to playlists titled "Potential Matches #" where the # indicates the number of the playlist # Due to a potential issue with playlist length playlists are capped at 500 songs addLoose = input("Would you like to add possible matches to playlists for later review (Y/N)?") if addLoose == 'Y': #get the store IDs of fails failIds = [] for query in fails: if query["resp"] != []: songID = query["resp"][0]["track"]["storeId"] failIds.append(songID) with shelve.open("failIds") as failed: failed["fails"] = failIds #create playlists to put the songs in playCount = 0
#Logging into new account print("Log into the Play Music account that you want to transfer songs to") while 1: login(mc) if not mc.is_subscribed: print("This account is not subscribed") print("Please log in with a subscribed account\n") mc.logout() continue break #Adding songs if songs: mc.add_store_tracks(list(i['storeId'] for i in songs)) #Adding playlists if playlists: already_created_playlists = [ i['name'] for i in mc.get_all_user_playlist_contents() ] for i in playlists: name = i['name'] suffix = "" num = 0 while ((name + suffix) in already_created_playlists): num += 1 suffix = " (" + str(num) + ")" name = name + suffix mc.add_songs_to_playlist(mc.create_playlist(name, i['description']),
class Gpm: def __init__(self): self.client = Mobileclient() # self.client.perform_oauth() self.client.oauth_login(Mobileclient.FROM_MAC_ADDRESS) def fetchCollection(self): songs = self.__makeSongSet(self.client.get_all_songs()) playlists = list() for playlistData in self.client.get_all_user_playlist_contents(): playlist = self.__makePlaylist(playlistData) if playlist is not None: playlists.append(playlist) return Collection(songs, playlists, self) def __makePlaylist(self, playlistData): if playlistData["deleted"] == "True": return None title = playlistData["name"] description = playlistData[ "description"] if "description" in playlistData else None serviceId = playlistData["id"] songs = self.__makeSongSet(playlistData["tracks"]) return Playlist(title, description, songs, serviceId) def __makeSongSet(self, songSetData): songs = list() for songData in songSetData: song = self.__makeSong(songData) if song is not None: songs.append(song) return SongSet(songs) def __makeSong(self, songData): if songData["kind"] == "sj#playlistEntry": if songData["deleted"] == "True" or not "track" in songData: return None songData = songData["track"] isDeleted = songData["deleted"] if "deleted" in songData else False if isDeleted: return None title = songData["title"] artist = songData["artist"] album = songData["album"] rating = int(songData["rating"]) if "rating" in songData else 0 serviceId = songData["id"] if "id" in songData else songData["storeId"] return Song(title, artist, album, rating, serviceId) @staticmethod def loadTakeoutExport(exportPath): songsPath = os.path.join(exportPath, "Tracks") songs = Gpm.loadTakeoutSongSet(songsPath) playlists = list() playlistsPath = os.path.join(exportPath, "Playlists") for playlistFileName in sorted(os.listdir(playlistsPath)): if playlistFileName != "Thumbs Up": playlist = Gpm.loadTakeoutPlaylist( os.path.join(playlistsPath, playlistFileName)) if playlist is not None: playlists.append(playlist) return Collection(songs, playlists, NullService()) @staticmethod def loadTakeoutPlaylist(exportPath): title = os.path.basename(exportPath) description = "" isDeleted = False metadataPath = os.path.join(exportPath, "Metadata.csv") with open(metadataPath) as metadataFile: metadata = next(csv.DictReader(metadataFile)) title = metadata["Title"] description = metadata["Description"] isDeleted = (metadata["Deleted"] == "Yes") if isDeleted: return None songs = Gpm.loadTakeoutSongSet(os.path.join(exportPath, "Tracks")) return Playlist(title, description, songs, None) @staticmethod def loadTakeoutSongSet(exportPath): songs = list() for songFileName in sorted(os.listdir(exportPath)): song = Gpm.loadTakeoutSong(os.path.join(exportPath, songFileName)) if song is not None: songs.append(song) return SongSet(songs) @staticmethod def loadTakeoutSong(exportPath): with open(exportPath) as songFile: metadata = next(csv.DictReader(songFile)) title = html.unescape(metadata["Title"].strip(" ")) artist = html.unescape(metadata["Artist"].strip(" ")) album = html.unescape(metadata["Album"].strip(" ")) rating = int(metadata["Rating"]) isDeleted = (metadata["Removed"] == "Yes") if isDeleted or (title == "" and artist == "" and album == ""): return None return Song(title, artist, album, rating, None) def addPlaylist(self, title, description): playlistId = self.client.create_playlist(title, description) return Playlist(title, description, list(), playlistId) def addSongFromSearchResults(self, song): trackId = self.client.add_store_tracks([song.serviceId]) return Song(song.title, song.artist, song.album, song.rating, trackId) def addSongToPlaylist(self, song, playlist): self.client.add_songs_to_playlist(playlist.serviceId, song.serviceId) def likeSong(self, song): self.client.rate_songs({"id": song.serviceId}, "5") def search(self, query): matches = list() searchResults = self.client.search(query) for songHit in searchResults["song_hits"]: song = self.__makeSong(songHit["track"]) matches.append(song) return matches