def __sync_song_ratings(self, apim, songs): apim = Mobileclient() apim.login(self.email, self.password) """ Sync ratings to Google Music """ apim.change_song_metadata(songs)
def lastfm_to_google_music(lastfm_user, lastfm_apikey, gmusic_email, gmusic_password): lastfm_client = LastFMClient() gmusic_client = Mobileclient() gmusic_client.login(gmusic_email, gmusic_password) tracks= defaultdict(list) # get gmusic all songs gmusic_load = gmusic_client.get_all_songs() for element in gmusic_load : rp_artist = element["artist"].encode('utf8').lower() rp_title = element["title"].encode('utf8').lower() tracks["gmusic"].append((rp_artist,rp_title)) # get lastfm loves lastfm_likes = lastfm_client.liked_tracks(lastfm_user, lastfm_apikey) json_string = json.loads(lastfm_likes) for element in json_string["lovedtracks"]["track"]: rp_artist = element["artist"]["name"].encode('utf8').lower() rp_title = element["name"].encode('utf8').lower() tracks["lastfm"].append((rp_artist,rp_title)) match = set(tracks["lastfm"]) & set(tracks["gmusic"]) print "gmusic total" print sum(len(x) for x in tracks["gmusic"]) print "Lastfm likes total" lastfm_like_count = sum(len(x) for x in tracks["lastfm"]) print lastfm_like_count print "matched with gmusic" print sum(len(x) for x in match) print "not matched" print list(set(tracks["lastfm"]) - set(match)) for element in gmusic_load: rp_artist = element["artist"].encode('utf8').lower() rp_title = element["title"].encode('utf8').lower() for element2 in match: if element2 == (rp_artist,rp_title): element['rating'] = '5' gmusic_client.change_song_metadata(element)
class GPMClient(object): """ Google Play Music client. """ all_songs_album_title = "All Songs" thumbs_up_playlist_name = "Thumbs Up" #------------------------------------------------------------------------------ def __init__(self, email, password, device_id): self.__api = Mobileclient() self.logged_in = False self.__device_id = device_id attempts = 0 while not self.logged_in and attempts < 3: self.logged_in = self.__api.login(email, password, device_id) attempts += 1 self.all_tracks = dict() self.playlists = dict() self.library = dict() #------------------------------------------------------------------------------ def logout(self): self.__api.logout() #------------------------------------------------------------------------------ def update_local_lib(self): songs = self.__api.get_all_songs() self.playlists[self.thumbs_up_playlist_name] = list() # Get main library song_map = dict() for song in songs: if "rating" in song and song["rating"] == "5": self.playlists[self.thumbs_up_playlist_name].append(song) song_id = song["id"] song_artist = song["artist"] song_album = song["album"] song_map[song_id] = song if song_artist == "": song_artist = "Unknown Artist" if song_album == "": song_album = "Unknown Album" if song_artist not in self.library: self.library[song_artist] = dict() self.library[song_artist][self.all_songs_album_title] = list() if song_album not in self.library[song_artist]: self.library[song_artist][song_album] = list() self.library[song_artist][song_album].append(song) self.library[song_artist][self.all_songs_album_title].append(song) # Sort albums by track number for artist in self.library.keys(): for album in self.library[artist].keys(): if album == self.all_songs_album_title: sorted_album = sorted(self.library[artist][album], key=lambda k: k['title']) else: sorted_album = sorted(self.library[artist][album], key=lambda k: k.get('trackNumber', 0)) self.library[artist][album] = sorted_album # Get all playlists plists = self.__api.get_all_user_playlist_contents() for plist in plists: plist_name = plist["name"] self.playlists[plist_name] = list() for track in plist["tracks"]: if track["trackId"] not in song_map: song = song_map[track["trackId"]] = track["track"] song["id"] = track["trackId"] else: song = song_map[track["trackId"]] self.playlists[plist_name].append(song) #------------------------------------------------------------------------------ def get_stream_url(self, song): return self.__api.get_stream_url(song["id"], self.__device_id) #------------------------------------------------------------------------------ def rate_song(self, song, rating): try: song["rating"] = rating song_list = [song] self.__api.change_song_metadata(song_list) print "Gave a Thumbs Up to {0} by {1} on Google Play.".format( song["title"].encode("utf-8"), song["artist"].encode("utf-8")) except RuntimeError: print "Error giving a Thumbs Up on Google Play."
continue new_track['rating'] = track_rating new_track_artist = new_track.get('artist') new_track_title = new_track.get('title') if track_artist != new_track_artist: log.warning('Track artists do not match (' + track_artist + ' != ' + new_track_artist + ')') if track_title != new_track_title: log.warning('Track titles do not match (' + track_title + ' != ' + new_track_title + ')') if not simulate: try: import_api.change_song_metadata(new_track) except CallFailure as e: log.error('Failed to set rating on track ' + new_track_artist + ' - ' + new_track_title) log.debug('ID of failed track is ' + track_id) continue # import all playlists if migration_type == 'all' or migration_type == 'playlists': log.info('Importing ' + str(len(playlists)) + ' playlists to ' + import_username) for i, playlist in enumerate(playlists, start=1): if i % 10 == 0: log.info('Creating playlist ' + str(i) + ' of ' + str(len(playlists)))
class GPMClient(object): """ Google Play Music client. """ all_songs_album_title = "All Songs" thumbs_up_playlist_name = "Thumbs Up" #------------------------------------------------------------------------------ def __init__(self, email, password, device_id): self.__api = Mobileclient() self.logged_in = False self.__device_id = device_id attempts = 0 while not self.logged_in and attempts < 3: self.logged_in = self.__api.login(email, password, device_id) attempts += 1 self.all_tracks = dict() self.playlists = dict() self.library = dict() #------------------------------------------------------------------------------ def logout(self): self.__api.logout() #------------------------------------------------------------------------------ def update_local_lib(self): songs = self.__api.get_all_songs() self.playlists[self.thumbs_up_playlist_name] = list() # Get main library song_map = dict() for song in songs: if "rating" in song and song["rating"] == "5": self.playlists[self.thumbs_up_playlist_name].append(song) song_id = song["id"] song_artist = song["artist"] song_album = song["album"] song_map[song_id] = song if song_artist == "": song_artist = "Unknown Artist" if song_album == "": song_album = "Unknown Album" if song_artist not in self.library: self.library[song_artist] = dict() self.library[song_artist][self.all_songs_album_title] = list() if song_album not in self.library[song_artist]: self.library[song_artist][song_album] = list() self.library[song_artist][song_album].append(song) self.library[song_artist][self.all_songs_album_title].append(song) # Sort albums by track number for artist in self.library.keys(): for album in self.library[artist].keys(): if album == self.all_songs_album_title: sorted_album = sorted(self.library[artist][album], key=lambda k: k['title']) else: sorted_album = sorted( self.library[artist][album], key=lambda k: k.get('trackNumber', 0)) self.library[artist][album] = sorted_album # Get all playlists plists = self.__api.get_all_user_playlist_contents() for plist in plists: plist_name = plist["name"] self.playlists[plist_name] = list() for track in plist["tracks"]: if track["trackId"] not in song_map: song = song_map[track["trackId"]] = track["track"] song["id"] = track["trackId"] else: song = song_map[track["trackId"]] self.playlists[plist_name].append(song) #------------------------------------------------------------------------------ def get_stream_url(self, song): return self.__api.get_stream_url(song["id"], self.__device_id) #------------------------------------------------------------------------------ def rate_song(self, song, rating): try: song["rating"] = rating song_list = [song] self.__api.change_song_metadata(song_list) print "Gave a Thumbs Up to {0} by {1} on Google Play.".format( song["title"].encode("utf-8"), song["artist"].encode("utf-8")) except RuntimeError: print "Error giving a Thumbs Up on Google Play."
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import json,re from gmusicapi import Mobileclient from pathlib import Path from collections import Counter,deque mc = Mobileclient() mc.login('*****@*****.**', 'LiAlSi8O20', Mobileclient.FROM_MAC_ADDRESS) """ songs = mc.get_all_songs() with Path("songs.json").open("w") as f: f.write(json.dumps(songs)) """ with Path("songs.json").open("r") as f: songs = json.loads(f.read()) for song in deque(songs,1000): if re.search(u'ラルク|(?=.*arc)(?=.*en)(?=.*ciel)',song["artist"].lower()) and song["artist"] != 'L\'Arc~en~Ciel' and song["albumArtist"] != "Various": #print(song["title"],song["artist"],song["albumArtist"]) song["artist"] = 'L\'Arc~en~Ciel' song["albumArtist"] = 'L\'Arc~en~Ciel' print(song) print( mc.change_song_metadata(song) )
log.error('Failed to retrieve data for track ' + track_artist + ' - ' + track_title) log.debug('ID of failed track is ' + track_id) continue new_track['rating'] = track_rating new_track_artist = new_track.get('artist') new_track_title = new_track.get('title') if track_artist != new_track_artist: log.warning('Track artists do not match (' + track_artist + ' != ' + new_track_artist + ')') if track_title != new_track_title: log.warning('Track titles do not match (' + track_title + ' != ' + new_track_title + ')') if not simulate: try: import_api.change_song_metadata(new_track) except CallFailure as e: log.error('Failed to set rating on track ' + new_track_artist + ' - ' + new_track_title) log.debug('ID of failed track is ' + track_id) continue # import all playlists if migration_type == 'all' or migration_type == 'playlists': log.info('Importing ' + str(len(playlists)) + ' playlists to ' + import_username) for i, playlist in enumerate(playlists, start=1): if i % 10 == 0: log.info('Creating playlist ' + str(i) + ' of ' + str(len(playlists))) playlist_name = playlist.get('name') playlist_description = playlist.get('description')
def main(): log.setLevel(logging.INFO) logging.getLogger('gmusicapi').setLevel(logging.INFO) cred_path = os.path.join(os.path.expanduser('~'), '.gmusic-sync') if not os.path.isfile(cred_path): raise NoCredentialException( 'No username/password was specified. No config file could ' 'be found either. Try creating %s and specifying your ' 'username/password there. Make sure to chmod 600.' % cred_path) if not oct(os.stat(cred_path)[os.path.stat.ST_MODE]).endswith('00'): raise NoCredentialException( 'Config file is not protected. Please run: ' 'chmod 600 %s' % cred_path) config = ConfigParser.ConfigParser() config.read(cred_path) src_user = config.get('src','username') src_pass = config.get('src','password') src_device = config.get('src','deviceid') dst_user = config.get('dst','username') dst_pass = config.get('dst','password') dst_device = config.get('dst','deviceid') if not src_user or not src_pass or not dst_user or not dst_pass: raise NoCredentialException( 'No username/password could be read from config file' ': %s' % cred_path) if not src_device or not dst_device: raise NoCredentialException( 'No deviceId could be read from config file' ': %s' % cred_path) parser = argparse.ArgumentParser(description='gmusic-sync', add_help=False) parser.add_argument('-d', '--dst', help='Perform operation on the dst account', action='store_true', dest='dst') parser.add_argument('-l', '--list', help='List playlists on the src account', action='store_true', dest='lst') parser.add_argument('-p', '--playlist', help='Playlist ID from src account to transfer', dest='playlist') args = parser.parse_args() api = Mobileclient() if args.dst: api.login(dst_user, dst_pass, dst_device) else: api.login(src_user, src_pass, src_device) playlists = api.get_all_playlists() if args.lst: for playlist in playlists: print playlist['name'] + ' (' + playlist['id'] + ') ' exit() library = api.get_all_songs() if args.playlist is None: print 'Error: no playlist selected' all_playlist_entries = api.get_all_user_playlist_contents() selected_playlist_entries = [] for entry in all_playlist_entries: if entry['id'] == args.playlist: selected_playlist_entries = entry['tracks'] playlist_tracks = [] for ptrack in selected_playlist_entries: track_found = False for track in library: if ptrack['trackId'] == track['id']: playlist_tracks.append(track) track_found = True break try: if ptrack['trackId'] == track['storeId']: playlist_tracks.append(track) track_found = True break except: pass if not track_found: print 'ERROR: could not find playlist entry ' + str(ptrack) api.add_aa_track(ptrack['trackId']) if len(playlist_tracks) != len(selected_playlist_entries): print 'Error: could not locate all playlist tracks in src library' exit() failed_tracks = [] playlist_tracks_reversed = [] for track in playlist_tracks: playlist_tracks_reversed.insert(0, track) for track in playlist_tracks_reversed: track['rating'] = '5' res = api.change_song_metadata(track) if len(res) != 1: raise Exception('Could not change track metadata!') time.sleep(1)