def google_playlists(x): api = Mobileclient() api.login('*****@*****.**', 'rtqjkpidxwxddpur', Mobileclient.FROM_MAC_ADDRESS) all_playlists = api.get_all_playlists(incremental=False, include_deleted=False) dj_list = list(set(x['host'])) for k, dj in enumerate(dj_list): # pull out subset of a given Dj subset = x.loc[x['host']==(dj)] print("\n Analyzing "+dj+" Playlists...\n") # pull out subset of dj subset for a given month for i in np.arange(1, 12, 1): print('Now loading Month: '+str(i)) artists = np.load(dj+'/'+'2015-'+str(i)+'-artists.npy') if len(artists) == 0: break titles = np.load(dj+'/'+'2015-'+str(i)+'-titles.npy') # playlist_exists = False # playlist_name = 'KCRW DJ '+host+', Tracks of 2015-'+str(i) # print("Searching for playlist named: " + playlist_name) # for playlist in all_playlists: # if playlist['name'] == playlist_name: # playlist_exists = True # playlist_id = playlist['id'] # print("Playlist exists, adding new songs to playlist: "+playlist_name) # if not playlist_exists: # playlist_id = api.create_playlist(playlist_name, description=None, public=False) # print("Playlist is new, creating playlist and adding new songs to: "+playlist_name) search_google(api, artists, titles)
def search(self, lib, opts, args): password = config['gmusic']['password'] email = config['gmusic']['email'] password.redact = True email.redact = True # Since Musicmanager doesn't support library management # we need to use mobileclient interface mobile = Mobileclient() try: mobile.login(email.as_str(), password.as_str(), Mobileclient.FROM_MAC_ADDRESS) files = mobile.get_all_songs() except NotLoggedIn: ui.print_( u'Authentication error. Please check your email and password.' ) return if not args: for i, file in enumerate(files, start=1): print(i, ui.colorize('blue', file['artist']), file['title'], ui.colorize('red', file['album'])) else: if opts.track: self.match(files, args, 'title') else: self.match(files, args, 'artist')
def login_to_google_music(user): api = Mobileclient() # Try to read the username and password from a file # This is useful for 2-step authentication # Don't store your regular password in plain text! try: creds_file = open(CREDS_FILE) creds = json.load(creds_file) except IOError: creds = {} try: user = creds["username"] except KeyError: if not user: user = raw_input("Google username/email: ") try: password = creds["password"] except KeyError: password = getpass() print "\nLogging in..." if api.login(user, password, Mobileclient.FROM_MAC_ADDRESS): return api else: print "Login failed. Giving up." exit(1)
def start(self): """ Start the sync """ api = Webclient() apim = Mobileclient() apim.login(self.email, self.password) try: api.login(self.email, self.password) xml_file = open('self.xml_file', 'r').read() print "Parsing songs from iTunes XML file..." itunes_song_list = self.__get_itunes_song_list(xml_file) print "iTunes XML file parsing complete" print "Retrieving songs from Google Music..." gmusic_song_list = self.__get_gmusic_song_list(apim) print "Google Music song retrieval complete" print "Computing the intersection of the song lists..." song_list = self.__get_intersection(gmusic_songs=gmusic_song_list, itunes_songs=itunes_song_list, only_no_rating=self.only_no_rating) print "Song list intersection computed" print "Syncing song ratings..." self.__sync_song_ratings(api, song_list) print "Song ratings sync complete!" except CallFailure: print "Error: Couldn't log in to Google Music!" except IOError: print "Error: iTunes XML file not found"
class GoogleMusic(Source): def __init__(self, library, username, password): Source.__init__(self, library, SourceType.GOOGLE) self.GOOGLE_DEVICE_ID = None print username print password self.client = Mobileclient() logged_in = self.client.login(username, password, Mobileclient.FROM_MAC_ADDRESS) print "Google logged in:", logged_in DList = self.client.get_registered_devices() self.GOOGLE_DEVICE_ID = DList[0]["id"] if self.GOOGLE_DEVICE_ID[:2] == '0x': self.GOOGLE_DEVICE_ID = self.GOOGLE_DEVICE_ID[2:] print self.GOOGLE_DEVICE_ID #>testing # self.get_stream_URL("47b9d52c-9d66-3ff2-94d4-3ae55c0d2acc") def get_stream_URL(self, song_id): return self.client.get_stream_url(song_id, self.GOOGLE_DEVICE_ID) def sync(self): gmusic_tracks = self.client.get_all_songs() for track in gmusic_tracks: art = '' try: art = track['albumArtRef'][0]['url'] except KeyError: art = '' self.library.insert_track(track['title'], track['album'], track['artist'], self._source, str(track['id']), track['trackNumber'], art)
class gmObject: def __init__(self): self.mc = Mobileclient() self.wc = Webclient() self.mm = Musicmanager() def login(self, username, password): error.e = 0 if not self.mc.login(username, password): gmtPrintV("gmObject.login: Wrong username or password (or no internet connection)") error.e = error.LOGIN_FAILED return if not self.wc.login(username, password): gmtPrintV("gmObject.login: Wrong username or password (or no internet connection)") error.e = error.LOGIN_FAILED return if not self.mm.login(config.cred_path): gmtPrintV("gmObject.login: Wrong credentials (or no internet connection)") error.e = error.LOGIN_FAILED return def logout(self): error.e = 0 try: self.mc.logout() self.wc.logout() self.mm.logout() except: gmtPrintV("gmObject.logout: Logout failed") error.e = error.LOGOUT_FAILED
def login_to_google_music(user): api = Mobileclient() attempts = 0 while attempts < 3: if user == None: user = raw_input("Google username or email: ") # Try to read the password from a file # If file doesn't exist, ask for password # This is useful for 2-step authentication only # Don't store your regular password in plain text! try: pw_file = open("pass.txt") password = pw_file.readline() print "Reading password from pass.txt." except IOError: password = getpass() print "\nLogging in..." if api.login(user, password): return api else: print "Login failed." # Set the username to none so it is prompted to be re-entered on the next loop iteration user = None attempts += 1 print str(attempts) + " failed login attempts. Giving up." exit(0)
def ask_for_credentials(): """Make an instance of the api and attempts to login with it. Returns the authenticated api. """ # We're not going to upload anything, so the Mobileclient is what we want. api = Mobileclient(debug_logging=False) logged_in = False attempts = 0 #try: # logged_in = api.login("mail", "pass", Mobileclient.FROM_MAC_ADDRESS) #except: # print(Fore.YELLOW + "Error logging you in!") while not logged_in and attempts < 3: print("Please log in into your Google Play account.") email = input('Email: ') password = getpass() logged_in = api.login(email, password, Mobileclient.FROM_MAC_ADDRESS) attempts += 1 return api
def __init__(self, fileName): ''' Initializes the API with user credentials :param: fileName Reference to the file with authentication information :return: Reference to the API ''' api = Mobileclient() # read in the auth file cntr = 0 for line in open(fileName): if (cntr == 0): user = line.strip() if (cntr == 1): app_pwd = line.strip() cntr += 1 # bail before potential exception if (cntr != 2): print("ERROR: Improperly formatted auth file.", file=sys.stderr) exit(1) # TODO improve MAC id logged_in = api.login(user, app_pwd, Mobileclient.FROM_MAC_ADDRESS) # error handling for auth if not(logged_in): print("ERROR: Unable to log in.", file=sys.stderr) exit(1) return api
def main(): api = Mobileclient() if not api.login(credentials.email, credentials.password): print "Couldn't log in :(" return check_playlists(api)
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 main(): api = Mobileclient() if not api.login(credentials.email, credentials.password): print "Couldn't log in :(" return regen_playlist(api, 'All') regen_playlist(api, 'Programming')
def setup_mobile_api(): global mobile_api mobile_api = Mobileclient() mobile_logged_in = mobile_api.login(username, password) if not mobile_logged_in: print "Failed to log in to the mobile API, ensure your details are correct and try again." sys.exit(0)
def test_google_login(self): google_username = os.environ['INFRADIO_TEST_GOOGLE_USERNAME'] google_password = os.environ['INFRADIO_TEST_GOOGLE_PASSWORD'] from gmusicapi import Mobileclient api = Mobileclient() self.assertTrue(api.login(google_username, google_password, Mobileclient.FROM_MAC_ADDRESS))
def login(self): if self.api is not None: return self.api debug("logging in as {}", self.config["email"]) api = Mobileclient(debug_logging=DEBUG) api.login(self.config["email"], self.config["password"], Mobileclient.FROM_MAC_ADDRESS) self.api = api return api
class GMusicWS: def __init__(self, user, password, playlistName): self.playlistName = playlistName self.api = Mobileclient() print ("Logging into MobileClient API") self.api.login(user, password,"android_id") #insert unique android_id here def mapUnknownTracks(self, db): playlist = db.unmappedTracks() for track in playlist: searchstr = track.artist + " " + track.song print ("Searching for %s" % (searchstr)) try: result = self.api.search_all_access(searchstr, max_results=1) print ("Found " + result['song_hits'][0]['track']['artist'] + " - " + result['song_hits'][0]['track']['title']) nid = result['song_hits'][0]['track']['nid'] db.storemapping(track.song, track.artist, nid) except: print ("Error parsing result: " + str(result)) time.sleep(1) def maintain(self, tracks): print ("Searching for playlist %s" % (self.playlistName)) found = False searchres = self.api.get_all_playlists() for list in searchres: if list['name'] == self.playlistName: found = True pid = list['id'] if not found: print ("Not found - creating") pid = self.api.create_playlist(self.playlistName) print ("Playlist id is %s" % (pid)) print ("Getting current contents") playlists = self.api.get_all_user_playlist_contents() currentEntries = [] for playlist in playlists: if playlist['name'] == self.playlistName: for entry in playlist['tracks']: currentEntries.append(entry['id']) print ("Removing songs") self.api.remove_entries_from_playlist(currentEntries) print ("Adding songs") self.api.add_songs_to_playlist(pid, tracks)
def _get_global_tracks(api: gmusicapi.Mobileclient, artist_ids, album_ids): artist_ids = list(artist_ids) album_ids = list(album_ids) for artist_id in artist_ids: results = api.get_artist_info(artist_id) for album_stub in results['albums']: album_id = album_stub['albumId'] album_ids.append(album_id) for album_id in album_ids: album = api.get_album_info(album_id) yield from album['tracks']
def main(path): api = Mobileclient() logged_in = api.login(EMAIL, PASSWORD) if logged_in: print("Succesfully logged in, retrieving all songs and running check...") all_songs = api.get_all_songs() tracks = remove_dups(all_songs) results = find_in_lib(path, tracks) print("saving file to %s" % os.path.join(os.getcwd(), "output.json")) with open("output.json", "w+") as f: f.write(json.dumps(results)) f.close()
def open_api(): global api log('Logging into google music...') api = Mobileclient() if not api.oauth_login(Mobileclient.FROM_MAC_ADDRESS): log('ERROR unable to login') time.sleep(3) exit() password = None log('Login Successful.') dlog(u'Available track details: '+str(get_google_track_details())) return api
def login(): # get the password each time so that it isn't stored in plain text password = getpass.getpass(username + '\'s password: '******'ERROR unable to login' time.sleep(3) exit() password = None return api
def init_gmusic(): """Request credentials, authenticate and connect to Google Music. Return authenticated MobileClient instance. """ username = raw_input("Please enter your Google username: "******"Please enter password for user %s: " % username) gmusic = Mobileclient() logged_in = gmusic.login(username, password, Mobileclient.FROM_MAC_ADDRESS) if not logged_in: raise Exception("Failed to authenticate google music account") sys.exit(2) return gmusic
def __init__(self, email, password, device_id): self.__gmusic = Mobileclient() self.__email = email self.__device_id = device_id self.logged_in = False self.queue = list() self.queue_index = -1 self.play_queue_order = list() self.play_modes = TizEnumeration(["NORMAL", "SHUFFLE"]) self.current_play_mode = self.play_modes.NORMAL self.now_playing_song = None userdir = os.path.expanduser('~') tizconfig = os.path.join(userdir, ".config/tizonia/." + email + ".auth_token") auth_token = "" if os.path.isfile(tizconfig): with open(tizconfig, "r") as f: auth_token = pickle.load(f) if auth_token: # 'Keep track of the auth token' workaround. See: # https://github.com/diraimondo/gmusicproxy/issues/34#issuecomment-147359198 print_msg("[Google Play Music] [Authenticating] : " \ "'with cached auth token'") self.__gmusic.android_id = device_id self.__gmusic.session._authtoken = auth_token self.__gmusic.session.is_authenticated = True try: self.__gmusic.get_registered_devices() except CallFailure: # The token has expired. Reset the client object print_wrn("[Google Play Music] [Authenticating] : " \ "'auth token expired'") self.__gmusic = Mobileclient() auth_token = "" if not auth_token: attempts = 0 print_nfo("[Google Play Music] [Authenticating] : " \ "'with user credentials'") while not self.logged_in and attempts < 3: self.logged_in = self.__gmusic.login(email, password, device_id) attempts += 1 with open(tizconfig, "a+") as f: f.truncate() pickle.dump(self.__gmusic.session._authtoken, f) self.library = CaseInsensitiveDict() self.song_map = CaseInsensitiveDict() self.playlists = CaseInsensitiveDict() self.stations = CaseInsensitiveDict()
class GMusicAPI(): def __init__(self, username=None, encrypted_pass=None): self._api = Mobileclient() self.logged_in = False if username and encrypted_pass: self.login(username, encrypted_pass) def login(self, username, encrypted_pass): self.logged_in = self._api.login(username, decrypt(encrypted_pass), Mobileclient.FROM_MAC_ADDRESS) def logout(self): self._api.logout() self.logged_in = False def clear_playlist(self, playlist_name): playlists = self._api.get_all_user_playlist_contents() playlist = [playlist for playlist in playlists if playlist['name'] == playlist_name][0] entry_ids = [entry['id'] for entry in playlist['tracks']] removed = self._api.remove_entries_from_playlist(entry_ids) return len(removed) def search(self, *args): """ Returns the best-fitting track dict for the given information. :param args: Strings which can be artist, song title, album etc. :return: """ query = sanitise_query(' '.join(args)) result = self._api.search(query) song_results = result['song_hits'] if not song_results: warnings.warn('Warning: query {} returned no song hits.'.format(query)) return None tracks = [song_result['track'] for song_result in song_results[:5]] for track in tracks: if not is_tribute(track, query): return track warnings.warn('Warning: query {} returned no non-tribute song hits.'.format(query)) return None def get_playlist_id(self, playlist_name): for playlist in self._api.get_all_playlists(): if playlist['name'] == playlist_name: return playlist['id'] raise ValueError("Playlist '{}' not found".format(playlist_name)) def add_songs(self, playlist_name, tracks): playlist_id = self.get_playlist_id(playlist_name) track_ids = [track['nid'] for track in tracks if track] self._api.add_songs_to_playlist(playlist_id, track_ids)
def open_api(): global api log('Logging into google music...') # get the password each time so that it isn't stored in plain text api = Mobileclient() if not api.login(username, password, Mobileclient.FROM_MAC_ADDRESS): log('ERROR unable to login') time.sleep(3) exit() log('Login Successful.') dlog(u'Available track details: '+str(get_google_track_details())) return api
def login_gpm(): #takes credentials and checks user login of Google username = raw_input("Enter your Google Play username: "******"Enter your Google Play password: "******"\nNot a valid login") exit() else: print("\nLogin success!") return gpm
def authenticate(self, email=None, password=None): # create the gmusicapi client and attempt to login # TODO: store the client somewhere so we can use it for music gmc = Mobileclient() valid = gmc.login(email, password) if valid: try: user = User.objects.get(username=username) except User.DoesNotExist: # Create a new user. We don't need to store the password user = User(username=username, password='******') # TODO: store some basic account info user.save() return user return None
def login(): config = ConfigParser.ConfigParser() config.read('config.ini') email = config.get('login', 'email') password = config.get('login', 'password') print "Logging into Google Play Music as", email api = Mobileclient() login = api.login(email, password, Mobileclient.FROM_MAC_ADDRESS) if not login: print "<< Couldn't login. >>" sys.exit() return api
def __init__(self, google_username, google_password): self.client = Mobileclient(validate=False) # generate a stable, unique android id h = hashlib.sha256() h.update(google_username) android_id = h.hexdigest()[:16] self.client.login(google_username, google_password, android_id)
def __init__(self): import requests from requests.packages.urllib3.exceptions import InsecureRequestWarning from requests.packages.urllib3.exceptions import InsecurePlatformWarning requests.packages.urllib3.disable_warnings(InsecureRequestWarning) requests.packages.urllib3.disable_warnings(InsecurePlatformWarning) self.gmusicapi = Mobileclient(debug_logging=False, validate=False, verify_ssl=False)
def __login_and_setup(self, username=None, password=None): # If credentials are not specified, get them from $HOME/.gmusicfs if not username or not password: cred_path = os.path.join(os.path.expanduser('~'), '.gmusicfs') 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) self.config = ConfigParser.ConfigParser() self.config.read(cred_path) username = self.config.get('credentials','username') password = self.config.get('credentials','password') global deviceId deviceId = self.config.get('credentials','deviceId') if not username or not password: raise NoCredentialException( 'No username/password could be read from config file' ': %s' % cred_path) if not deviceId: raise NoCredentialException( 'No deviceId could be read from config file' ': %s' % cred_path) self.api = GoogleMusicAPI(debug_logging=self.verbose) log.info('Logging in...') self.api.login(username, password) log.info('Login successful.')
#!/usr/bin/env python import vlc import os import json from gmusicapi import Mobileclient import os.path from youtube_search_engine import youtube_search from youtube_search_engine import youtube_stream_link import yaml with open('/home/pi/GassistPi/src/config.yaml','r') as conf: configuration = yaml.load(conf) api = Mobileclient() #If you are using two-step authentication, use app specific password. For guidelines, go through README logged_in = api.login(configuration['Gmusicapi']['email'],configuration['Gmusicapi']['password'] , configuration['Gmusicapi']['deviceid']) class vlcplayer(): def __init__(self): self.libvlc_Instance=vlc.Instance('--verbose 0') self.libvlc_player = self.libvlc_Instance.media_player_new() # self.libvlc_list_player = self.libvlc_Instance.media_list_player_new() # self.libvlc_Media_list = self.libvlc_Instance.media_list_new() # self.libvlc_list_player.set_media_player(self.libvlc_player) # self.libvlc_list_player.set_media_list(self.libvlc_Media_list) # self.libvlc_player_event_manager= self.libvlc_player.event_manager()
print "Please fill in the details in the .myrock_google_sync file in the current directory" exit(1) #print 'Loading' from gmusicapi import Mobileclient import datetime import re try: # For Python 3+ from urllib.request import urlopen except ImportError: # For Python 2 from urllib2 import urlopen api = Mobileclient() print 'Logging in to Google Play' logged_in = api.login(config['username'], config['password'], Mobileclient.FROM_MAC_ADDRESS) def findId(title, artist): if artist == 'Rammstein': # Rammstein is not available on Google Play only covers return None results = api.search(title + ', ' + artist) for song_hit in results['song_hits']: track = song_hit['track'] # print track #if cleanString(track['title']) == cleanString(title) and cleanString(track['albumArtist']) == cleanString(artist): # Trust google to find the right version return track['storeId']
class GMusicWrapper(object): def __init__(self, username, password, logger=None): self._api = Mobileclient() self.logger = logger success = self._api.login( username, password, environ.get('ANDROID_ID', Mobileclient.FROM_MAC_ADDRESS)) if not success: raise Exception("Unsuccessful login. Aborting!") # Populate our library self.library = {} self.indexing_thread = threading.Thread(target=self.index_library) self.indexing_thread.start() def _search(self, query_type, query): try: results = self._api.search(query) except CallFailure: return [] hits_key = "%s_hits" % query_type if hits_key not in results: return [] # Ugh, Google had to make this schema nonstandard... if query_type == 'song': query_type = 'track' return [x[query_type] for x in results[hits_key]] def is_indexing(self): return self.indexing_thread.is_alive() def index_library(self): """ Downloads the a list of every track in a user's library and populates self.library with storeIds -> track definitions """ self.logger.debug('Fetching library...') tracks = self.get_all_songs() for track in tracks: song_id = track['id'] self.library[song_id] = track self.logger.debug('Done! Discovered %d tracks.' % len(self.library)) def get_artist(self, name): """ Fetches information about an artist given its name """ search = self._search("artist", name) if len(search) == 0: return False return self._api.get_artist_info(search[0]['artistId'], max_top_tracks=100) def get_album(self, name, artist_name=None): if artist_name: name = "%s %s" % (name, artist_name) search = self._search("album", name) if len(search) == 0: return False return self._api.get_album_info(search[0]['albumId']) def get_latest_album(self, artist_name=None): search = self._search("artist", artist_name) if len(search) == 0: return False artist_info = self._api.get_artist_info(search[0]['artistId'], include_albums=True) album_info = artist_info['albums'] sorted_list = sorted(album_info.__iter__(), key=lambda s: s['year'], reverse=True) for index, val in enumerate(sorted_list): album_info = self._api.get_album_info( album_id=sorted_list[index]['albumId'], include_tracks=True) if len(album_info['tracks']) >= 5: return album_info return False def get_album_by_artist(self, artist_name, album_id=None): search = self._search("artist", artist_name) if len(search) == 0: return False artist_info = self._api.get_artist_info(search[0]['artistId'], include_albums=True) album_info = artist_info['albums'] random.shuffle(album_info) for index, val in enumerate(album_info): album = self._api.get_album_info( album_id=album_info[index]['albumId'], include_tracks=True) if album['albumId'] != album_id and len(album['tracks']) >= 5: return album return False def get_song(self, name, artist_name=None, album_name=None): if artist_name: name = "%s %s" % (artist_name, name) elif album_name: name = "%s %s" % (album_name, name) search = self._search("song", name) if len(search) == 0: return False if album_name: for i in range(0, len(search) - 1): if album_name in search[i]['album']: return search[i] return search[0] def get_station(self, title, track_id=None, artist_id=None, album_id=None): if artist_id is not None: if album_id is not None: if track_id is not None: return self._api.create_station(title, track_id=track_id) return self._api.create_station(title, album_id=album_id) return self._api.create_station(title, artist_id=artist_id) def get_station_tracks(self, station_id): return self._api.get_station_tracks(station_id) def get_google_stream_url(self, song_id): return self._api.get_stream_url(song_id) def get_stream_url(self, song_id): return "%s/alexa/stream/%s" % (environ['APP_URL'], song_id) def get_thumbnail(self, artist_art): return artist_art.replace("http://", "https://") def get_all_user_playlist_contents(self): return self._api.get_all_user_playlist_contents() def get_all_songs(self): return self._api.get_all_songs() def rate_song(self, song, rating): return self._api.rate_songs(song, rating) def extract_track_info(self, track): # When coming from a playlist, track info is nested under the "track" # key if 'track' in track: track = track['track'] if 'storeId' in track: return track, track['storeId'] elif 'trackId' in track: return self.library[track['trackId']], track['trackId'] else: return None, None def get_artist_album_list(self, artist_name): search = self._search("artist", artist_name) if len(search) == 0: return "Unable to find the artist you requested." artist_info = self._api.get_artist_info(search[0]['artistId'], include_albums=True) album_list_text = "Here's the album listing for %s: " % artist_name counter = 0 for index, val in enumerate(artist_info['albums']): if counter > 25: # alexa will time out after 10 seconds if the list takes too long to iterate through break album_info = self._api.get_album_info( album_id=artist_info['albums'][index]['albumId'], include_tracks=True) if len(album_info['tracks']) > 5: counter += 1 album_list_text += ( artist_info['albums'][index]['name']) + ", " return album_list_text def get_latest_artist_albums(self, artist_name): search = self._search("artist", artist_name) if len(search) == 0: return False artist_info = self._api.get_artist_info(search[0]['artistId'], include_albums=True) album_list = artist_info['albums'] sorted_list = sorted(album_list.__iter__(), key=lambda s: s['year'], reverse=True) speech_text = 'The latest albums by %s are ' % artist_name counter = 0 for index, val in enumerate(sorted_list): if counter > 5: break else: album_info = self._api.get_album_info( album_id=sorted_list[index]['albumId'], include_tracks=True) if len(album_info['tracks']) >= 5: counter += 1 album_name = sorted_list[index]['name'] album_year = sorted_list[index]['year'] speech_text += '%s, released in %d, ' % (album_name, album_year) return speech_text def closest_match(self, request_name, all_matches, artist_name='', minimum_score=70): # Give each match a score based on its similarity to the requested # name self.logger.debug("The artist name is " + str(artist_name)) request_name = request_name.lower() + artist_name.lower() scored_matches = [] for i, match in enumerate(all_matches): try: name = match['name'].lower() except (KeyError, TypeError): i = match name = all_matches[match]['title'].lower() if artist_name != "": name += all_matches[match]['artist'].lower() scored_matches.append({ 'index': i, 'name': name, 'score': fuzz.ratio(name, request_name) }) sorted_matches = sorted(scored_matches, key=lambda a: a['score'], reverse=True) top_scoring = sorted_matches[0] self.logger.debug("The top scoring match was: " + str(top_scoring)) best_match = all_matches[top_scoring['index']] # Make sure we have a decent match (the score is n where 0 <= n <= 100) if top_scoring['score'] < minimum_score: return None return best_match def get_genres(self, parent_genre_id=None): return self._api.get_genres(parent_genre_id) def increment_song_playcount(self, song_id, plays=1, playtime=None): return self._api.increment_song_playcount(song_id, plays, playtime) def get_song_data(self, song_id): return self._api.get_track_info(song_id) @classmethod def generate_api(cls, **kwargs): return cls(environ['GOOGLE_EMAIL'], environ['GOOGLE_PASSWORD'], **kwargs)
class GMusicHandler: """ GMusicHandler is the class handling the communication with the google music api. """ def __init__(self, user, password): self.user = user self.password = password self.api = Mobileclient() if not self.api.oauth_login(Mobileclient.FROM_MAC_ADDRESS): raise Exception('Failed to login...') self.tracks = {} self.playlists = {} def get_all_song(self): if len(self.tracks) == 0: songs = self.api.get_all_songs() for song in songs: track_id = song['id'] title = song['title'] artist = song['artist'] album = song['album'] track_number = song['trackNumber'] self.tracks[track_id] = Track(track_id, title, artist, album, track_number) return self.tracks def get_song(self, track_id): songs = self.get_all_song() return songs.get(track_id) def get_all_playlist(self): if len(self.playlists) == 0: playlists = self.api.get_all_user_playlist_contents() for pl in playlists: playlist = self._build_playlist(pl) self.playlists[playlist.id] = playlist return self.playlists def _build_playlist(self, data): playlist_id = data['id'] playlist_name = data['name'] p = Playlist(playlist_id, playlist_name) for track in data['tracks']: track_id = track['trackId'] source = track['source'] if source == '1': song = self.get_song(track_id) p.tracks[song.id] = song elif source == '2': song = self._create_track(track_id, track['track']) p.tracks[song.id] = song return p def _create_track(self, track_id, data): title = data['title'] artist = data['artist'] album = data['album'] track_number = data['trackNumber'] song = Track(track_id, title, artist, album, track_number) self.tracks[song.id] = song return song def get_playlist(self, playlist_name): playlists = self.get_all_playlist() return next( iter([p for p in playlists.values() if p.name == playlist_name]), None) def download_track(self, track_id): url = self.api.get_stream_url(track_id) file_path, headers = urllib.request.urlretrieve(url) return file_path def search(self, query): return self.api.search(query)
class GMusicSession(object): def __init__(self): super(GMusicSession, self).__init__() logger.info('Mopidy uses Google Music') self.api = Mobileclient() def login(self, username, password, deviceid): if self.api.is_authenticated(): self.api.logout() try: self.api.login(username, password) except CallFailure as error: logger.error(u'Failed to login as "%s": %s', username, error) if self.api.is_authenticated(): if deviceid is None: self.deviceid = self.get_deviceid(username, password) else: self.deviceid = deviceid else: return False def logout(self): if self.api.is_authenticated(): return self.api.logout() else: return True def get_all_songs(self): if self.api.is_authenticated(): return self.api.get_all_songs() else: return {} def get_stream_url(self, song_id): if self.api.is_authenticated(): try: return self.api.get_stream_url(song_id, self.deviceid) except CallFailure as error: logger.error(u'Failed to lookup "%s": %s', song_id, error) def get_all_user_playlist_contents(self): if self.api.is_authenticated(): return self.api.get_all_user_playlist_contents() else: return {} def get_shared_playlist_contents(self, shareToken): if self.api.is_authenticated(): return self.api.get_shared_playlist_contents(shareToken) else: return {} def get_all_playlists(self): if self.api.is_authenticated(): return self.api.get_all_playlists() else: return {} def get_deviceid(self, username, password): logger.warning(u'No mobile device ID configured. ' u'Trying to detect one.') webapi = Webclient(validate=False) webapi.login(username, password) devices = webapi.get_registered_devices() deviceid = None for device in devices: if device['type'] == 'PHONE' and device['id'][0:2] == u'0x': # Omit the '0x' prefix deviceid = device['id'][2:] break webapi.logout() if deviceid is None: logger.error(u'No valid mobile device ID found. ' u'Playing songs will not work.') else: logger.info(u'Using mobile device ID %s', deviceid) return deviceid def get_track_info(self, store_track_id): if self.api.is_authenticated(): try: return self.api.get_track_info(store_track_id) except CallFailure as error: logger.error(u'Failed to get All Access track info: %s', error) def get_album_info(self, albumid, include_tracks=True): if self.api.is_authenticated(): try: return self.api.get_album_info(albumid, include_tracks) except CallFailure as error: logger.error(u'Failed to get All Access album info: %s', error)
import sys from gmusicapi import Mobileclient if __name__ == "__main__": if sys.argv[1] == "1": mc = Mobileclient() success = mc.login(sys.argv[3], sys.argv[4]) if success == True: sresults = mc.search_all_access(sys.argv[2], 1) #2 = query song = sresults['song_hits'][0] sid = song['track']['nid'] sname = song['track']['title'] sartist = song['track']['artist'] sartistid = song['track']['artistId'][0] salbum = song['track']['album'] salbumart = song['track']['albumArtRef'][0]['url'] aresults = mc.get_artist_info(sartistid, False, 1, 1) artistart = aresults['artistArtRef'] print(sid) print(sname) print(sartist) print(salbum) print(salbumart) print(artistart) if sys.argv[1] == "2": print("Spotify is not yet supported.")
RATING_NO_RATING = '0' RATING_THUMBS_DOWN = '1' RATING_THUMBS_UP = '5' # API DOCS # http://unofficial-google-music-api.readthedocs.io/en/latest/reference/mobileclient.html # source code # https://github.com/simon-weber/gmusicapi/blob/develop/gmusicapi/clients/mobileclient.py def loadConfig(file="config.ini"): config = configparser.ConfigParser() config.read(file) return config api = Mobileclient() config = loadConfig() logged_in = api.login(config['Credentials']["username"], config['Credentials']["password"], 'f8:a9:d0:0c:9d:82') songs_list = api.get_all_songs() songs_to_delete = [] # following is just for debugging # wanted_keys = ['artist', 'title', 'id', 'rating'] for song in songs_list: if song['rating'] == RATING_THUMBS_DOWN: songs_to_delete.append(song) # songs_to_delete.append({k: song[k] for k in wanted_keys})
def allaccessimport(playlist=None, username=None, password=None, dry_run=False): """ Exports a Spotify playlist to stdout or csv. """ if not username or not password: raise CommandError( "Username and password must be provided as either command-line " + "argument or in the application configuration file.") playlist_name = playlist playlist_description = "" if playlist: playlist_name = os.path.basename(playlist_name) playlist_name = os.path.splitext(playlist_name)[0] logging.debug("Playlist name will be: {}".format(playlist_name)) api = Mobileclient(False, False) logged_in = api.login(username, password, Mobileclient.FROM_MAC_ADDRESS) if not logged_in: raise CommandError( 'Error. Unable to login to Google Music All Access.') playlist_ref = None currenttracks = None failed_tracks = list() songs_added = 0 total = 0 stream = open(playlist, "rb") if playlist else sys.stdin for input_line in stream: input_line = input_line.strip() # Lazily search the beginning of the file for a Playlist name if input_line.startswith("#"): data = input_line[1:] parts = [x.strip() for x in data.split(":", 1)] if len(parts) == 2: if parts[0] == "Playlist": playlist_name = parts[1] elif parts[0] == "Description": playlist_description = parts[1] continue if not playlist_ref: if not playlist_name: raise CommandError( "A playlist name was not given and it was not found " + "in the file either. Can't continue.") else: playlist_ref, currenttracks = get_playlist(api, playlist_name) if not playlist_ref and not dry_run: sys.stderr.write('Playlist not found. Creating new.\n') playlist_ref = api.create_playlist( playlist_name, description=playlist_description) yield 'Going to update playlist {0} ({1})\n'.format( playlist_name, playlist_ref) trackinfo = list(csv.reader([input_line], quoting=csv.QUOTE_ALL))[0] if trackinfo[0] == 'Track' and trackinfo[1] == 'Artist': yield 'Skipping header.' continue search_term = "{0} {1}".format(trackinfo[0], trackinfo[1]) total = total + 1 newtrackid, error_reason = search_track(api, search_term, currenttracks) if newtrackid: if not dry_run: #print("Add to {} song {}".format(playlist_ref, newtrackid)) api.add_songs_to_playlist(playlist_ref, [newtrackid]) songs_added = songs_added + 1 else: failed_tracks.append(trackinfo) sys.stderr.write("Searching {}...{}\n".format(search_term, error_reason)) yield "{0} songs added out of {1}. {2} Failed.".format( songs_added, total, total - songs_added) yield "Failed tracks:" for line in failed_tracks: print " ", line
self.album = album self.title = [] # list of titles of this album self.artist = [] # could be a sampler with... self.genre = [] # ...different artists and genres self.ID = [] # id is needed to remove a song def add(self, artist, genre, title, ID): # add a song to the album self.artist.append(artist) self.genre.append(genre) self.title.append(title) self.ID.append(ID) all_albums = {} # dict of albums, indexed by album name n = 0 # counts the songs api = Mobileclient() # Mobileclient is the simple gmusicapi interface if api.login(USER, PASS, Mobileclient.FROM_MAC_ADDRESS): songs = api.get_all_songs() for i in songs: # iterate across the songs if i['album'] == '': # no album title, artist, song title? invent one i['album'] = 'ALBUM-' + str(n) if i['artist'] == '': i['artist'] = 'ARTIST-' + str(n) if i['title'] == '': i['title'] = 'TITLE-' + str(n) try: # try to add song to existing album all_albums[i['album']].add(i['artist'], i['genre'], i['title'], i['id']) # print('>>> added', i['title'], 'to album', i['album']) except: # no album exists -> create it, then add song
class MusicPlayer: def __init__(self, device_id, token): # Gmusic API initialization print("initializing client") self.api = Mobileclient() print("logging in") self.api.oauth_login(device_id, token) print("loading all songs") self.all_songs = self.api.get_all_songs() print("loading playlists") self.all_playlists = self.api.get_all_user_playlist_contents() self.all_playlist_names = {} for playlist in self.all_playlists: self.all_playlist_names[playlist["name"]] = playlist["id"] # VLC initialization self.track_file = vlc.MediaPlayer() self.track_list = [] self.titles = [] self.track_number = 0 self.playlists = [] self.current_time = -1 self.max_time = -1 # Get playlists, songs from the first playlist, and load the first song self.get_playlists() self.get_songs_from_playlist(self.playlists[0]) self.song = self.track_list[self.track_number]["trackId"] self.load_track() # GUI initialization print("creating window") self.song = "" self.player_layout = [ [sg.Text("I love you Mom!", size=(15, 1), font=("Helvetica", 25))], [sg.Listbox(values=self.playlists, size=(30, 20), bind_return_key=True, key="_playlists_"), # sg.Image(), sg.Listbox(values=self.titles, size=(30, 20), bind_return_key=True, key="_Tracks_")], [sg.Text("Click Play or select song", key="_SongName_", enable_events=True)], [sg.Text("Volume:"), sg.Slider(range=(0, 100), orientation="h", size=(20, 15), default_value=self.track_file.audio_get_volume(), key="_volume_"), sg.Button("Play"), sg.Button("Pause"), sg.Button("Next")] ] self.title = "Music Player" self.window = sg.Window(self.title).Layout(self.player_layout) def get_playlists(self): data = self.api.get_all_playlists() self.playlists = [] for playlist in data: if not playlist['deleted']: self.playlists.append(playlist['name']) print(self.playlists) def change_playlists(self, name): for pos, title in enumerate(self.playlists): if title == name: self.get_songs_from_playlist(self.playlists[pos]) def get_songs_from_playlist(self, name): print("Obtaining track list") tracks = [] if name in self.all_playlist_names: for playlist in self.all_playlists: if playlist["name"] == name: for track in playlist["tracks"]: tracks.append(track) break self.track_list = tracks self.get_playlist_song_titles() def get_playlist_song_titles(self): print("Getting playlist song titles") titles = [] for song in self.track_list: if song["source"] == "2": titles.append(song["track"]["title"]) else: for track in self.all_songs: if track["id"] == song["trackId"]: print("match found") titles.append(track["title"]) else: print("No match found") print(titles) self.titles = titles def get_song_position_from_title(self, title): for pos, name in enumerate(self.titles): if name == title: return pos else: print("Couldn't find song in tracks") def download_song(self): print("downloading song") url = self.api.get_stream_url(self.song) doc = requests.get(url) with open("song.mp3", "wb") as f: f.write(doc.content) def load_track(self): self.track_file = vlc.MediaPlayer("song.mp3") print("Time:", self.track_file.get_length()) def play(self): self.track_file.play() self.window.FindElement("_SongName_").Update(value=self.titles[self.track_number]) def stop(self): self.track_file.stop() def pause(self): self.track_file.pause() def next(self): self.track_number += 1 self.song = self.track_list[self.track_number]["trackId"] self.window.FindElement("_Tracks_").SetValue(self.titles[self.track_number]) self.download_song() self.track_file.stop() self.load_track() self.track_file.play() self.max_time = self.track_file.get_time() def run(self): print("launching program") while True: self.current_time = self.track_file.get_time() if self.max_time == -1: self.max_time = self.track_file.get_length() elif self.max_time == 0: self.max_time = -1 else: current = timedelta(milliseconds=self.current_time) max = timedelta(milliseconds=self.max_time) # print("Current", current, "Max", max) # print(int((self.current_time / self.max_time) * 100)) if (self.current_time + 500) > self.max_time: self.next() event, values = self.window.Read(timeout=100) if event is not None: if event == "Play": self.play() elif event == "Stop": self.stop() elif event == "Pause": self.pause() elif event == "Next": self.next() elif event == "_Tracks_": self.track_number = self.get_song_position_from_title(values[event][0]) self.song = self.track_list[self.track_number]["trackId"] self.download_song() self.track_file.stop() self.load_track() self.play() elif event == "_playlists_": print(values[event][0]) self.change_playlists(values[event][0]) self.window.FindElement("_Tracks_").Update(self.titles) elif event == "_volume_": print("Volume", event, values) else: self.track_file.audio_set_volume(values["_volume_"]) if event == "Quit" or values is None: break
def __init__(self): self._gclient = Mobileclient() self._credentials = self._get_credentials()
def authenticate(username, password): api = Mobileclient() api.login(username, password, Mobileclient.FROM_MAC_ADDRESS) return api
from gmusicapi import Mobileclient from os import path credentials_filename = 'mobilecredentials.cred' gpm_mobileclient = Mobileclient() oauth_creds = credentials_filename if path.exists(credentials_filename) else \ gpm_mobileclient.perform_oauth('./mobilecredentials.cred', open_browser=True) gpm_mobileclient.oauth_login('3b98457227009a89', oauth_credentials=oauth_creds)
g_playlist_name = input('New playlist name (empty to keep name): ') s_playlist_url = input('Spotify playlist URL: ') # get spotify url params spotify_user_id = 0 spotify_playlist_id = '' path_data = s_playlist_url.split('/') for path_piece in range(len(path_data)): if path_data[path_piece] == 'user': spotify_user_id = path_data[path_piece + 1] if path_data[path_piece] == 'playlist': spotify_playlist_id = path_data[path_piece + 1] # authenticate gapi = Mobileclient() logged_in = gapi.login(g_username, g_password, Mobileclient.FROM_MAC_ADDRESS) client_credentials_manager = spotipy.oauth2.SpotifyClientCredentials( client_id=SPOTIFY_CLIENT_ID, client_secret=SPOTIFY_CLIENT_SECRET) sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager) # get playlist playlist = sp.user_playlist(spotify_user_id, spotify_playlist_id) track_response = playlist['tracks'] gplaylist = [] for song in track_response['items']: song_search_string = "%s - %s - %s" % (song['track']['artists'][0]['name'], song['track']['name'], song['track']['album']['name']) song_result = gapi.search(song_search_string)
import os from flask import Flask from flask_ask import Ask, statement from gmusicapi import Mobileclient app = Flask(__name__) email = os.environ.get('email', 17995) password = os.environ.get('password', 17995) android_id = os.environ.get('android_id', 17995) ask = Ask(app, '/alexa') client = Mobileclient() print('Logging in as:', email, 'with ANDROID_ID', android_id) if client.login(email, password, android_id): print('Login successful!') else: raise Exception('Login failed') from . import utils musicman = utils.musicmanager.MusicManager(client) music_queue = utils.queue.MusicQueue() from . import intents
from gmusicapi import Mobileclient from config import * # API api = Mobileclient() logged_in = api.login(gpm_username, gpm_password, '3a6a9d34f7e8237e') # Data artist_names = [] for song in api.get_all_songs(): artist = song['artist'] if not(any(artist[:5].lower() in n.lower() for n in artist_names)): artist_names.append(artist) artist_names.sort() file = open("artist.txt","w") for artist in artist_names: print(artist) file.write(artist + "\n") file.close()
def __init__(self): super(GMusicSession, self).__init__() logger.info('Mopidy uses Google Music') self.api = Mobileclient()
scope, client_id='YOUR CLIENT ID', client_secret='YOUR CLIENT SECRET', redirect_uri='YOUR REDIRECT URI') if token: sp = spotipy.Spotify(auth=token) # start and authorize spotipy tracks = get_playlist_tracks( username, playlist) # get track, artist, and album names else: print "Can't get token for", username # ******************** # Update GPM playlist: # ******************** gpm = Mobileclient() gpm_username = '******' gpm_password = '******' logged_in = gpm.login( gpm_username, gpm_password, Mobileclient.FROM_MAC_ADDRESS) # is true if log in successful if logged_in: gpm_song_ids, skipped_songs = get_song_ids(tracks) gpm_playlist_id = 'YOUR GPM PLAYLIST ID' #gpm.create_playlist('Export to GPM Test', description='Test playlist', public=False) for i in range(len(gpm_song_ids)): gpm.add_songs_to_playlist(gpm_playlist_id, gpm_song_ids[i]) outputf.write('Number of tracks not found: %s' % skipped_songs) write_list_to_file(skipped_songs) else:
def _delete_duplicates(self, api: Mobileclient) -> None: """Delete duplicates.""" self._combine_play_counts(api) discard_ids = [song["id"] for song in self.get_discard_songs()] api.delete_songs(discard_ids)
class MusicLibrary(object): """This class reads information about your Google Play Music library""" def __init__(self, username=None, password=None, true_file_size=False, scan=True, verbose=0): self.verbose = False if verbose > 1: self.verbose = True self.__login_and_setup(username, password) self.__artists = {} # 'artist name' -> {'album name' : Album(), ...} self.__albums = [] # [Album(), ...] self.__tracks = {} self.__playlists = {} if scan: self.rescan() self.true_file_size = true_file_size def rescan(self): """Scan the Google Play Music library""" self.__artists = {} # 'artist name' -> {'album name' : Album(), ...} self.__albums = [] # [Album(), ...] self.__tracks = {} self.__playlists = {} self.__aggregate_albums() def __login_and_setup(self, username=None, password=None): # If credentials are not specified, get them from $HOME/.gmusicfs if not username or not password: cred_path = os.path.join(os.path.expanduser('~'), '.gmusicfs') 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) self.config = ConfigParser.ConfigParser() self.config.read(cred_path) username = self.config.get('credentials', 'username') password = self.config.get('credentials', 'password') global deviceId deviceId = self.config.get('credentials', 'deviceId') if not username or not password: raise NoCredentialException( 'No username/password could be read from config file' ': %s' % cred_path) if not deviceId: raise NoCredentialException( 'No deviceId could be read from config file' ': %s' % cred_path) if deviceId.startswith("0x"): deviceId = deviceId[2:] self.api = GoogleMusicAPI(debug_logging=self.verbose) log.info('Logging in...') self.api.login(username, password, deviceId) log.info('Login successful.') def __aggregate_albums(self): """Get all the tracks and playlists in the library, parse into relevant dicts""" log.info('Gathering track information...') tracks = self.api.get_all_songs() for track in tracks: log.debug('track = %s' % pp.pformat(track)) # Prefer the album artist over the track artist if there is one artist_name = formatNames(track['albumArtist']) if artist_name.strip() == '': artist_name = formatNames(track['artist']) if artist_name.strip() == '': artist_name = 'Unknown' # Get the Artist object, or create one if it doesn't exist artist = self.__artists.get(artist_name.lower(), None) if not artist: artist = Artist(self, artist_name) self.__artists[artist_name.lower()] = artist # Get the Album object, or create one if it doesn't exist album = artist.get_album(formatNames(track['album'])) if not album: album = Album(self, track['album']) self.__albums.append( album) # NOTE: Current no purpose other than to count artist.add_album(album) # Add track to album album.add_track(track) # Add track to list of all tracks, indexable by track ID if 'id' in track: self.__tracks[track['id']] = track log.debug('%d tracks loaded.' % len(tracks)) log.debug('%d artists loaded.' % len(self.__artists)) log.debug('%d albums loaded.' % len(self.__albums)) # Add all playlists playlists = self.api.get_all_user_playlist_contents() for pldata in playlists: playlist = Playlist(self, pldata) self.__playlists[playlist.dirname.lower()] = playlist log.debug('%d playlists loaded.' % len(self.__playlists)) def get_artists(self): """Return list of all artists in the library""" return self.__artists.values() def get_artist(self, name): """Return the artist from the library with the specified name""" return self.__artists.get(name.lower(), None) def get_playlists(self): """Return list of all playlists in the library""" return self.__playlists.values() def get_playlist(self, name): """Return the playlist from the library with the specified name""" return self.__playlists.get(name.lower(), None) def get_track(self, trackid): """Return the track from the library with the specified track ID""" return self.__tracks.get(trackid, None) def cleanup(self): pass
class Session(object): def __init__(self): self.api = None self.user = None self.lib_albums = {} self.lib_artists = {} self.lib_tracks = {} self.lib_playlists = {} self.lib_updatetime = 0 self.sitdata = [] self.sitbyid = {} self.sitdataupdtime = 0 def dmpdata(self, who, data): uplog("%s: %s" % (who, json.dumps(data, indent=4))) # Look for an Android device id in the registered devices. def find_device_id(self, data): for entry in data: if "type" in entry and entry["type"] == u"ANDROID": # Get rid of 0x id = entry["id"][2:] uplog("Using deviceid %s" % id) return id return None def login(self, username, password, deviceid=None): self.api = Mobileclient(debug_logging=False) if deviceid is None: logged_in = self.api.login(username, password, Mobileclient.FROM_MAC_ADDRESS) if logged_in: # Try to re-login with a valid deviceid data = self.api.get_registered_devices() #self.dmpdata("registered devices", data) deviceid = self.find_device_id(data) if deviceid: logged_in = self.login(username, password, deviceid) else: logged_in = self.api.login(username, password, deviceid) isauth = self.api.is_authenticated() #uplog("login: Logged in: %s. Auth ok: %s" % (logged_in, isauth)) return logged_in def _get_user_library(self): now = time.time() if now - self.lib_updatetime < 300: return if self.lib_updatetime == 0: data = self.api.get_all_songs() #self.dmpdata("all_songs", data) else: data = self.api.get_all_songs(updated_after=datetime.datetime.fromtimestamp(self.lib_updatetime)) #self.dmpdata("all_songs_since_update", data) self.lib_updatetime = now tracks = [_parse_track(t) for t in data] self.lib_tracks.update(dict([(t.id, t) for t in tracks])) for track in tracks: # We would like to use the album id here, but gmusic # associates the tracks with any compilations after # uploading (does not use the metadata apparently), so # that we can't (we would end up with multiple # albums). OTOH, the album name is correct (so seems to # come from the metadata). What we should do is test the # album ids for one album with a matching title, but we're # not sure to succeed. So at this point, the album id we # end up storing could be for a different albums, and we # should have a special library-local get_album_tracks self.lib_albums[track.album.name] = track.album self.lib_artists[track.artist.id] = track.artist def get_user_albums(self): self._get_user_library() return self.lib_albums.values() def get_user_artists(self): self._get_user_library() return self.lib_artists.values() def get_user_playlists(self): pldata = self.api.get_all_playlists() #self.dmpdata("playlists", pldata) return [_parse_playlist(pl) for pl in pldata] def get_user_playlist_tracks(self, playlist_id): self._get_user_library() # Unfortunately gmusic does not offer incremental updates for # playlists. This means we must download all playlist data any # time we want an update. Playlists include track information # for gmusic songs, so if a user has a lot of playlists this # can take some time. # For now, we only load the playlists one time for performance purposes if len(self.lib_playlists) == 0: data = self.api.get_all_user_playlist_contents() self.lib_playlists = dict([(pl['id'], pl) for pl in data]) tracks = [] if playlist_id in self.lib_playlists: for entry in self.lib_playlists[playlist_id]['tracks']: if entry['deleted']: continue if entry['source'] == u'1': tracks.append(self.lib_tracks[entry['trackId']]) elif 'track' in entry: tracks.append(_parse_track(entry['track']) ) return tracks def create_station_for_genre(self, genre_id): id = self.api.create_station("station"+genre_id, genre_id=genre_id) return id def get_user_stations(self): data = self.api.get_all_stations() # parse_playlist works fine for stations stations = [_parse_playlist(d) for d in data] return stations def delete_user_station(self, id): self.api.delete_stations(id) # not working right now def listen_now(self): print("api.get_listen_now_items()", file=sys.stderr) ret = {'albums' : [], 'stations' : []} try: data = self.api.get_listen_now_items() except Exception as err: print("api.get_listen_now_items failed: %s" % err, file=sys.stderr) data = None # listen_now entries are not like normal albums or stations, # and need special parsing. I could not make obvious sense of # the station-like listen_now entries, so left them aside for # now. Maybe should use create_station on the artist id? if data: ret['albums'] = [_parse_ln_album(a['album']) \ for a in data if 'album' in a] #ret['stations'] = [_parse_ln_station(d['radio_station']) \ # for d in data if 'radio_station' in d] else: print("listen_now: no items returned !", file=sys.stderr) print("get_listen_now_items: returning %d albums and %d stations" %\ (len(ret['albums']), len(ret['stations'])), file=sys.stderr) return ret def get_situation_content(self, id = None): ret = {'situations' : [], 'stations' : []} now = time.time() if id is None and now - self.sitdataupdtime > 300: self.sitbyid = {} self.sitdata = self.api.get_listen_now_situations() self.sitdataupdtime = now # Root is special, it's a list of situations if id is None: ret['situations'] = [self._parse_situation(s) \ for s in self.sitdata] return ret # not root if id not in self.sitbyid: print("get_situation_content: %s unknown" % id, file=sys.stderr) return ret situation = self.sitbyid[id] #self.dmpdata("situation", situation) if 'situations' in situation: ret['situations'] = [self._parse_situation(s) \ for s in situation['situations']] if 'stations' in situation: ret['stations'] = [_parse_situation_station(s) \ for s in situation['stations']] return ret def _parse_situation(self, data): self.sitbyid[data['id']] = data return Playlist(id=data['id'], name=data['title']) def create_curated_and_get_tracks(self, id): sid = self.api.create_station("station"+id, curated_station_id=id) print("create_curated: sid %s"%sid, file=sys.stderr) tracks = [_parse_track(t) for t in self.api.get_station_tracks(sid)] #print("curated tracks: %s"%tracks, file=sys.stderr) self.api.delete_stations(sid) return tracks def get_station_tracks(self, id): return [_parse_track(t) for t in self.api.get_station_tracks(id)] def get_media_url(self, song_id, quality=u'med'): url = self.api.get_stream_url(song_id, quality=quality) print("get_media_url got: %s" % url, file=sys.stderr) return url def get_album_tracks(self, album_id): data = self.api.get_album_info(album_id, include_tracks=True) album = _parse_album(data) return [_parse_track(t, album) for t in data['tracks']] def get_promoted_tracks(self): data = self.api.get_promoted_songs() #self.dmpdata("promoted_tracks", data) return [_parse_track(t) for t in data] def get_genres(self, parent=None): data = self.api.get_genres(parent_genre_id=parent) return [_parse_genre(g) for g in data] def get_artist_info(self, artist_id, doRelated=False): ret = {"albums" : [], "toptracks" : [], "related" : []} # Happens,some library tracks have no artistId entry if artist_id is None or artist_id == 'None': uplog("get_artist_albums: artist_id is None") return ret else: uplog("get_artist_albums: artist_id %s" % artist_id) maxrel = 20 if doRelated else 0 maxtop = 0 if doRelated else 10 incalbs = False if doRelated else True data = self.api.get_artist_info(artist_id, include_albums=incalbs, max_top_tracks=maxtop, max_rel_artist=maxrel) #self.dmpdata("artist_info", data) if 'albums' in data: ret["albums"] = [_parse_album(alb) for alb in data['albums']] if 'topTracks' in data: ret["toptracks"] = [_parse_track(t) for t in data['topTracks']] if 'related_artists' in data: ret["related"] = [_parse_artist(a) for a in data['related_artists']] return ret def get_artist_related(self, artist_id): data = self.get_artist_info(artist_id, doRelated=True) return data["related"] def search(self, query): data = self.api.search(query, max_results=50) #self.dmpdata("Search", data) tr = [_parse_track(i['track']) for i in data['song_hits']] ar = [_parse_artist(i['artist']) for i in data['artist_hits']] al = [_parse_album(i['album']) for i in data['album_hits']] #self.dmpdata("Search playlists", data['playlist_hits']) try: pl = [_parse_splaylist(i) for i in data['playlist_hits']] except: pl = [] return SearchResult(artists=ar, albums=al, playlists=pl, tracks=tr)
def main(no_oauth, spotify_only): if settings.SPOTIPY_CLIENT_ID == "<your-spotify-client-id>": click.echo( click.style( "To use this CLI utility, you must have a client account setup with Spotify.\n" "Setup a developer client account at: " "https://developer.spotify.com/my-applications\n" "Then, specify the client_id and client_secret in 'settings.local.yaml'", bold=True, ) ) return # setup for Google Play Music if not spotify_only: mobile_client = Mobileclient() if not no_oauth: if not os.path.exists(f"{CWD}/{settings.TOKEN_PATH}"): os.makedirs(f"{CWD}/{settings.TOKEN_PATH}") mobile_client.perform_oauth(storage_filepath=f"{GPM_TOKEN}") # Make sure that login works device_id = settings.GOOGLE_DEVICE_ID or get_mac_address().replace(":", "").upper() try: assert mobile_client.oauth_login(device_id, oauth_credentials=GPM_TOKEN) except Exception: click.echo( click.style( "ERROR: login for Google Play Music hit an exception.", fg="red", bold=True ) ) raise click.echo(click.style("Success logging into Google Play Music!", fg="green", bold=True)) click.echo(f"Oauth file for GPM stored in: '{GPM_TOKEN}'") # setup for Spotify try: if not no_oauth: token = prompt_for_user_token( settings.SPOTIPY_CLIENT_USERNAME, client_id=settings.SPOTIPY_CLIENT_ID, client_secret=settings.SPOTIPY_CLIENT_SECRET, redirect_uri=settings.SPOTIPY_REDIRECT_URI, cache_path=f"{SPOTIFY_TOKEN}", scope=settings.SPOTIPY_SCOPE, ) else: token = spotipy.oauth2.SpotifyOAuth( username=settings.SPOTIPY_CLIENT_USERNAME, client_id=settings.SPOTIPY_CLIENT_ID, client_secret=settings.SPOTIPY_CLIENT_SECRET, redirect_uri=settings.SPOTIPY_REDIRECT_URI, cache_path=f"{SPOTIFY_TOKEN}", ).get_access_token()["access_token"] # verify that login works spotify = spotipy.Spotify(auth=token) assert bool(spotify.current_user()) except Exception: click.echo(click.style("ERROR: login for Spotify hit an exception.", fg="red", bold=True)) raise click.echo(click.style(f"Success logging into Spotify!", fg="green", bold=True)) click.echo(f"Oauth file for Spotify stored in: '{SPOTIFY_TOKEN}'")
'--merge', dest="merge", action='store_true', help='Merge playlist if name already exists. Crude implementation.') parser.add_argument( '--rm-feat', dest="rmfeat", action='store_false', help= 'Remove (feat artistname) from titles for google music. Messes up spotify search, default on.' ) config = parser.parse_args() spotify_username = config.spotify_user google_api = Mobileclient() google_api.login(config.g_user, config.g_password, Mobileclient.FROM_MAC_ADDRESS) token = util.prompt_for_user_token(spotify_username, scope='playlist-modify-public', client_id=config.spotify_client, client_secret=config.spotify_secret, redirect_uri=config.spotify_redirect) spotify_api = spotipy.Spotify(auth=token) playlists = google_api.get_all_user_playlist_contents() output = [ "[{}]: {}".format(i, name['name']) for i, name in enumerate(playlists) ]
from gmusicapi import Mobileclient import gMusicLogin from tqdm import tqdm import sys, os, time, requests from mutagen.easyid3 import EasyID3 from mutagen.mp3 import MP3 import mutagen.id3 EasyID3.RegisterTextKey("albumartist", "TPE2") EasyID3.RegisterTextKey("media", "TMED") r_albumID = 'Bmzku73mo3yicub2vnes43wv52y' api = Mobileclient() try: api.login(gMusicLogin.getUser(), gMusicLogin.getPass(), Mobileclient.FROM_MAC_ADDRESS) except: sys.exit("Login Failed") while api.is_authenticated() == False: time.sleep(.1) def removeNonASCII(text): return ''.join(i for i in text if ord(i) < 128) def runMainBody():
import sys from gmusicapi import Mobileclient from datetime import date import fileinput if len(sys.argv) > 1: pw = "" for line in fileinput.input(): pw = line api = Mobileclient() logged_in = api.login('*****@*****.**', pw, Mobileclient.FROM_MAC_ADDRESS) if logged_in: playlists = api.get_all_playlists() names = [] for playlist in playlists: names.append(playlist['name']) for name in sorted(names): print(name) api.logout() else: print( "Please include the path to a file containing a Google Music password."
new_search = re.sub(pat, '', track_title, re.IGNORECASE) log_file_arr.append( f'\tNOT FOUND | {artist} | {track_title} | SEARCHING FOR: {new_search}' ) track_title = new_search elif iters == 2: new_search = track['album_artist'] log_file_arr.append( f'\tNOT FOUND | {artist} | {track_title} | SEARCHING FOR: {new_search}' ) artist = new_search else: log_file_arr.append('\n') break return log_file_arr # playlist = spotify_object.user_playlist_create(username, name) # spotify_object.user_playlist_add_tracks(user=username, playlist_id=playlist['id'], tracks=spotify_song_ids) if __name__ == "__main__": mc = Mobileclient() mc.oauth_login('3b98457227009a89', oauth_credentials='./mobilecredentials.cred') playlists = pull_playlists(mc) log_file_arr = [] for playlist in playlists: log_file_arr += import_playlist(playlist, username, sp) with open('log_file_2.txt', 'w') as f: f.write('\n'.join(log_file_arr))
print "starting..." from gmusicapi import Mobileclient import sys import login_credentials api = Mobileclient() api.login(login_credentials.google_email, login_credentials.google_password, Mobileclient.FROM_MAC_ADDRESS) print "url: " + api.get_stream_url('59b55acc-09c2-3048-9463-40cf50d34d16') print "...stopping"
class MusicLibrary(object): 'Read information about your Google Music library' def __init__(self, username=None, password=None, true_file_size=False, scan=True, verbose=0): self.verbose = False if verbose > 1: self.verbose = True self.__login_and_setup(username, password) self.__artists = {} # 'artist name' -> {'album name' : Album(), ...} self.__albums = [] # [Album(), ...] if scan: self.rescan() self.true_file_size = true_file_size def rescan(self): self.__artists = {} # 'artist name' -> {'album name' : Album(), ...} self.__albums = [] # [Album(), ...] self.__aggregate_albums() def __login_and_setup(self, username=None, password=None): # If credentials are not specified, get them from $HOME/.gmusicfs if not username or not password: cred_path = os.path.join(os.path.expanduser('~'), '.gmusicfs') 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) self.config = ConfigParser.ConfigParser() self.config.read(cred_path) username = self.config.get('credentials', 'username') password = self.config.get('credentials', 'password') global deviceId deviceId = self.config.get('credentials', 'deviceId') if not username or not password: raise NoCredentialException( 'No username/password could be read from config file' ': %s' % cred_path) if not deviceId: raise NoCredentialException( 'No deviceId could be read from config file' ': %s' % cred_path) self.api = GoogleMusicAPI(debug_logging=self.verbose) log.info('Logging in...') self.api.login(username, password) log.info('Login successful.') def __aggregate_albums(self): 'Get all the tracks in the library, parse into artist and album dicts' all_artist_albums = {} # 'Artist|||Album' -> Album() log.info('Gathering track information...') tracks = self.api.get_all_songs() for track in tracks: # Prefer the album artist over the track artist if there is one: artist = formatNames(track['albumArtist'].lower()) if artist.strip() == '': artist = formatNames(track['artist'].lower()) # Get the Album object if it already exists: key = '%s|||%s' % (formatNames(artist), formatNames(track['album'].lower())) album = all_artist_albums.get(key, None) if not album: # New Album if artist == '': artist = 'unknown' album = all_artist_albums[key] = Album( self, formatNames(track['album'].lower())) self.__albums.append(album) artist_albums = self.__artists.get(artist, None) if artist_albums: artist_albums[formatNames(album.normtitle)] = album else: self.__artists[artist] = {album.normtitle: album} artist_albums = self.__artists[artist] album.add_track(track) log.debug('%d tracks loaded.' % len(tracks)) log.debug('%d artists loaded.' % len(self.__artists)) log.debug('%d albums loaded.' % len(self.__albums)) def get_artists(self): return self.__artists def get_albums(self): return self.__albums def get_artist_albums(self, artist): log.debug(artist) return self.__artists[artist] def cleanup(self): pass
def __init__(self): self.session = Mobileclient() self.device_id = gmusic_device_id self.cred_path = gmusic_cred_path self.playlist_id = gmusic_playlist_id
def reverseplaylist(playlist_name='', repeat=False, quick=False): mc = Mobileclient() mc.__init__() # Find location of this script dir_path = os.path.dirname(os.path.realpath(__file__)) # Check whether this is the first time the program has been run by searching the directory for the log file file_list = os.listdir(dir_path) # No log file means not run if '.gmusiclog.txt' not in file_list: print( '\n' + 'This is the first time this program has been run in this folder.' + '\n' + 'performing initial authentication.' + '\n') # Autorepeat cannot be true without logfile, override if true repeat = False # Start with a bogus device ID to determine real id from error message devID = 'ffffffff' mc.perform_oauth() try: mc.oauth_login(devID) except Exception as e: error = str(e) IDpos = error.find('*') nextIDpos = error.find('\n', IDpos + 1, len(error)) devID = error[IDpos + 2:nextIDpos] # Perform login mc.oauth_login(devID) # Write authentication stuff to logfile with open(dir_path + '/.gmusiclog.txt', 'w') as log: log.write(devID + '\n') x = datetime.datetime.now() timeString = (str(x.day) + '/' + str(x.month) + '/' + str(x.year) + ' ' + str(x.hour) + ':' + str(x.minute) + ':' + str(x.second) + '.' + str(x.microsecond)) log.write('Initial authentication performed at ' + timeString + '\n') # Log file exists, we will check whether the user has requested autorepeat else: print( '\n' + 'This is not the first time this program has been run in this folder' + '\n' + 'performing login.' + '\n') # Open the logfile to read device id and previous playlists with open(dir_path + '/.gmusiclog.txt', 'r') as log: # Get device ID devID = log.readline().strip() # Look for the playlist name from the bottom of the list contents = log.read() # Perform login mc.oauth_login(devID) playlistLocation = contents.rfind('PLAYLIST') if playlistLocation != -1: # Define end of playlist to make defining desired playlist a little cleaner endOfPlaylist = contents.find('\n', playlistLocation, len(contents)) desired_playlist = contents[playlistLocation + 10:endOfPlaylist] with open(dir_path + '/.gmusiclog.txt', 'a+') as log: # Write authentication stuff to logfile x = datetime.datetime.now() timeString = (str(x.day) + '/' + str(x.month) + '/' + str(x.year) + ' ' + str(x.hour) + ':' + str(x.minute) + ':' + str(x.second) + '.' + str(x.microsecond)) log.write('Login performed at ' + timeString + '\n') # Get user input for desired playlist if autorepeat is not enabled if repeat == False and playlist_name == '': desired_playlist = input( 'Name of the playlist being reversed (case sensetive): ') elif playlist_name != '': # If a name is given this overrides all else desired_playlist = playlist_name else: print('Autorepeat enabled, reversing playlist: ' + desired_playlist + '\n') # Establish the name of the reversed playlist reversed_playlist = desired_playlist + 'REVERSED' # Check to see whether the desired and reversed playlists exist yet allPlaylists = mc.get_all_playlists() desired_playlist_index = -1 reversed_playlist_index = -1 for n in allPlaylists: if n['name'] == reversed_playlist: reversed_playlist_index = n reversedID = n['id'] elif n['name'] == desired_playlist: desired_playlist_index = n desiredID = n['id'] # Desired playlist exists, so we check to see if it has also been reversed if desired_playlist_index != -1: # We cache the playlist name so that it can be automatically re-reversed next time with open(dir_path + '/.gmusiclog.txt', 'a+') as log: log.write('PLAYLIST: ' + desired_playlist + '\n') # Desired playlist has been reversed, we can either delete the old one before proceeding # or perform a quick update if reversed_playlist_index != -1: print('The ' + desired_playlist + ' playlist has been reversed.') # Determine whether to do a quick update or not if quick == True: print('performing quick update') quick_update(mc, desiredID, reversedID) return else: print('Performing full update\n' + 'Deleting the old playlist...\n') mc.delete_playlist(reversedID) # Desired playlist has not been reversed, create the reverse else: print('The ' + desired_playlist + ' playlist has not been reversed, creating the reverse now.') # If we have got this far, the reversed playlist doesn't exist print('Generating reversed song list...') reversedID, id_list = create_new(mc, desired_playlist) print('Adding songs to the playlist...') mc.add_songs_to_playlist(reversedID, id_list) print('Done!') # No such playlist exists else: print( 'No playlist by the name of ' + desired_playlist + ' found. Did you spell it correctly? A reminder here that the playlist name is case sensetive.' )