def main(): # Gather required info. google_username = raw_input("Google username: "******"Google password: "******"Lastfm username: "******"Lastfm API key: ").strip() # Log in. api = gmusicapi.Mobileclient() if not api.login(google_username, google_password, gmusicapi.Mobileclient.FROM_MAC_ADDRESS): print "Login error" return # Get loved tracks. loved = [] page = 1 while True: url = "http://ws.audioscrobbler.com/2.0/?method=user.getlovedtracks&user=%s&api_key=%s&page=%d" % \ (lastfm_username, lastfm_key, page) print("Fetching: " + url) tree = parse(urllib2.urlopen(url)).getroot() tracks = tree.findall('lovedtracks/track') for track in tracks: title = track.find('name').text artist = track.find('artist/name').text loved.append((artist, title)) if len(tracks) < 50: break page += 1 print("Got " + str(len(loved)) + " loved tracks") if len(loved) == 0: print "Exiting" return # Creating new playlist playlist_id = api.create_playlist("Loved tracks") to_add = [] # Search for each song in all access. # This is quite a dirty way to do it, and the gmusicapi seems to be a little out of date # hence the catch-all. This found 529 out of the 787 loved songs I have which is not too bad. for target in loved: try: res = api.search_all_access(target[0] + " " + target[1], max_results=1) to_add.append(res["song_hits"][0]["track"]["nid"]) except: pass print("Got " + str(len(to_add)) + " songs so far out of " + str(len(loved))) print("Adding " + str(len(to_add)) + " songs to playlist") api.add_songs_to_playlist(playlist_id, to_add) print("Done! I hope.")
def __init__(self, all_access, api=None): self._all_access = all_access if api is None: self.api = gmusicapi.Mobileclient() self.api._authtype = "oauth" else: self.api = api
def login(self): self.g_api = gmusicapi.Mobileclient(debug_logging=False) self.load_config() if not isfile(CRED_FILE): from oauth2client.client import FlowExchangeError print("No local credentials file found.") print("TUIJam will now open a browser window so you can provide") print( "permission for TUIJam to access your Google Play Music account." ) input("Press enter to continue.") try: self.g_api.perform_oauth(CRED_FILE, open_browser=True) except FlowExchangeError: raise RuntimeError("Oauth authentication Failed.") self.g_api.oauth_login(self.g_api.FROM_MAC_ADDRESS, CRED_FILE) if self.lastfm_sk is not None: self.lastfm = LastFMAPI(self.lastfm_sk) # TODO handle if sk is invalid from apiclient.discovery import build developer_key, = lookup_keys("GOOGLE_DEVELOPER_KEY") self.youtube = build("youtube", "v3", developerKey=developer_key)
def init_gpm_api(new_login): gpm_oauth_credentials_path = 'gpm_oauth_credentials.cred' Mobileclient = gmusicapi.Mobileclient() if new_login: Mobileclient.perform_oauth(storage_filepath=gpm_oauth_credentials_path) if not Path(gpm_oauth_credentials_path).is_file(): sys.exit('Not logged in.') logged_in = Mobileclient.oauth_login(Mobileclient.FROM_MAC_ADDRESS, oauth_credentials=gpm_oauth_credentials_path) if logged_in == False or not Mobileclient.is_authenticated: sys.exit("Not logged in.") return Mobileclient
def login_check(user, passw): if internet_connection(): api.login(user, passw, gmusicapi.Mobileclient().FROM_MAC_ADDRESS) if api.is_authenticated(): return True else: return False else: return True
def __init__(self, session, token=None, max_in_flight=1): self.token = token self.session = session self._loop = asyncio.get_event_loop() self._sync_gmapi = gmusicapi.Mobileclient() self.limiter = asyncio.Semaphore(value=max_in_flight) self.is_not_limited = asyncio.Event() self.is_not_limited.set()
def __init__(self, context): """ :param context: execution context :type context: gmusiccache.service.context.ExecutionContext """ self.__context = context self.__gmusic_client = self.__gmusic_client = gmusicapi.Mobileclient() self.__song_cache = {}
def get_gmusic_client(self): try: return self.GMUSIC_INSTANCES[self.server.id] except KeyError: pass instance = gmusicapi.Mobileclient(debug_logging=False) if not instance.login(self.username, self.password, gmusicapi.Mobileclient.FROM_MAC_ADDRESS): instance = None self.GMUSIC_INSTANCES[self.server.id] = instance return instance
def import_playlist(username, password, public, playlist): gmusic = gmusicapi.Mobileclient() gmusic.login(username, password, gmusicapi.Mobileclient.FROM_MAC_ADDRESS) # Delete an existing playlist if it already exists. This is a bit easier # than trying to de-dup tracks. playlist_name = pathlib.Path(playlist).stem.replace('_', ' ') existing_playlists = { p['name']: p['id'] for p in gmusic.get_all_playlists() } if playlist_name in existing_playlists: click.confirm( 'Playlist already exists; continuing will delete it and start over. OK?', abort=True) gmusic.delete_playlist(existing_playlists[playlist_name]) playlist_track_ids = [] # Technique for finding tracks: # 1. search for "{artist} {track}" # 2. for each song hit, calcuate a "score" based on how many fields # (track name, artist name, album name, track number) match. # 3. choose the highest score with click.progressbar(list(csv.DictReader(open(playlist))), label="Finding tracks") as tracks: for track in tracks: search_results = gmusic.search_all_access( '{Artist} {Name}'.format(**track))['song_hits'] candidates = [r['track'] for r in search_results] scored_candidates = [] for candidate in candidates: score = sum([ normalize(candidate['album']) == normalize(track['Album']), normalize(candidate['artist']) == normalize( track['Artist']), normalize(candidate['title']) == normalize(track['Name']), str(candidate['trackNumber']) == track['Track Number'], ]) # Don't include tracks with a score of 0. if score: scored_candidates.append((score, candidate)) if not scored_candidates: click.secho("Can't find: {Artist} - {Name}".format(**track), fg='yellow') continue match = max(scored_candidates)[1] playlist_track_ids.append(match['storeId']) playlist_id = gmusic.create_playlist(playlist_name, public=public) gmusic.add_songs_to_playlist(playlist_id, playlist_track_ids)
def login(arg_email, arg_password): api = gmusicapi.Mobileclient() while True: email = arg_email if arg_email else raw_input('Email: ') password = arg_password if arg_password else getpass.getpass( 'Password: '******'Invalid email/password combination.' if arg_email and arg_password: exit()
def gmusic_login(): """ Interactive login for gmusicapi :return: Returns a Mobileclient session """ #What do I need to load gmusic? username = input("Google Username: "******"Password (or app-specific password): ") session = gmusicapi.Mobileclient() login_result = session.login(username, password, session.FROM_MAC_ADDRESS) if login_result: return session else: raise LoginError(username)
def connect(username, password, verbose=True, quiet=False): source = gmusicapi.Mobileclient() #print(help(source)) try: burn = 1 / 0 # It appears google changed some backend stuff, so this forces it to use an android device source.login(username, password, source.FROM_MAC_ADDRESS, "en_US") if not source.is_authenticated(): print("MAC adress was not authenticated") raise Exception if verbose: if not quiet: print("MAC address worked") return source except Exception as e: #Sometimes gmusicapi is weird, and because I don't want to have to modify it, I can manually control certain aspects because python has no proper encapsulation. #Basically, I'm "stealing" a device id from gmusicapi. import uuid #raise e if source.session.login( username, password, gmusicapi.utils.utils.create_mac_string( uuid.getnode()).replace(":", "")): devices = source.get_registered_devices() if not quiet: print(devices) source.logout() for option in devices: if option["type"] == "ANDROID": if not quiet: print(option["type"]) if source.login( username, password, option['id'][2:] if option['id'].startswith('0x') else option['id'].replace(':', '')): if verbose: if not quiet: print(option["id"]) return source for option in devices: if source.login( username, password, option['id'][2:] if option['id'].startswith('0x') else option['id'].replace(':', '')): if verbose: if not quiet: print(option["id"]) break return source else: print("FAILED LOGIN") from gmusicapi.utils import utils print(utils.log_filepath)
def main(): gmusic = gmusicapi.Mobileclient() gmusic.login(USERNAME, PASSWORD, gmusicapi.Mobileclient.FROM_MAC_ADDRESS) here = pathlib.Path(__file__).parent collection_db_file = here / 'collection.sqlite3' if not collection_db_file.exists(): click.secho("collection.sqlite3 doesn't exist, run rdio_export_to_sqlite3.py first", fg='red') return db = sqlite3.connect(str(collection_db_file)) cursor = db.cursor() cursor.execute('''SELECT artist, album FROM collection WHERE skip = 0 AND complete = 0 AND track_count > 5 ORDER BY track_count DESC''') all_albums = cursor.fetchall() for i, (artist, album) in enumerate(all_albums): print_header(artist, album, i, len(all_albums)) results = gmusic.search_all_access(artist + ' ' + album)['album_hits'] if not results: click.secho("Can't find it, fixup please.", fg='yellow') fixed_artist = click.prompt('Artist'.format(artist), default=artist) fixed_album = click.prompt('Album'.format(album), default=album) results = gmusic.search_all_access(fixed_artist + ' ' + fixed_album)['album_hits'] if not results: handle_not_found(db, artist, album) continue # swizzle results into a slightly more usable form results = [r['album'] for r in results] try: album_object = select_album(artist, album, results, i, len(all_albums)) except SkipAlbum: handle_not_found(db, artist, album, prompt=False) continue if album_object: add_to_gmusic(db, gmusic, album_object, artist, album) else: handle_not_found(db, artist, album) db.close()
def main(): parser = argparse.ArgumentParser( description="""Command line tool to download metadata from Google Play Music""") parser.add_argument('-V', '--version', action='version', version='%(prog)s {}'.format( escapeorangebox.__version__)) parser.add_argument('user', metavar='<google-username>', help="""The google account username to pull sing information from.""") parser.add_argument('-o', '--output', metavar='<file>', type=argparse.FileType('w'), default=sys.stdout, help="""Output file. (default: stdout)""") parser.add_argument('-t', '--timeout', metavar='<timeout>', type=float, default=0.1, help="""Average timeout to wait between requests to avoid rate limiting. (default: %(default)g)""") args = parser.parse_args() client = gmusicapi.Mobileclient(False, True, True) if not client.login( args.user, getpass.getpass('Google password for {}: '.format(args.user)), client.FROM_MAC_ADDRESS): sys.stderr.write('Authentication failed') # TODO Make log message sys.exit(1) if args.timeout > 0: def tfunc(): return random.expovariate(1 / args.timeout) else: def tfunc(): return 0 output = download_song_info(client, True, tfunc) json.dump(output, args.output, separators=(',', ':')) args.output.write('\n')
def __init__(self): GObject.threads_init() Gst.init(None) self.loop = GObject.MainLoop() self.dbus = SessionBus() self.playbin = Gst.ElementFactory.make("playbin", "player") self.bus = self.playbin.get_bus() self.bus.add_signal_watch() self.bus.connect("message::error", self.on_error) self.bus.connect("message::eos", self.on_eos) self.playbin.connect("about-to-finish", self.next_song) self.shuffle = 'alltracks' with open("conf.yml", 'r') as y: self.conf = yaml.load(y) self.client = gmusicapi.Mobileclient() self.cache_dir = os.path.expanduser(self.conf['cache_dir']) os.makedirs(self.cache_dir, exist_ok=True) if not self.client.is_authenticated(): self.client.login(self.conf['email'], self.conf['pass'], self.conf['deviceid']) self.songs = self.client.get_all_songs() with open("{}/metadata.json".format(self.cache_dir), 'w') as fd: json.dump(self.songs, fd) for song in self.songs: if song['albumArtist'] == "": song['albumArtist'] = song['artist'] self.songs.sort(key=itemgetter('albumArtist', 'year', 'album', 'discNumber', 'trackNumber')) s = 0 for song in self.songs: song['num'] = s s += 1
def __init__( self, device_id, mobile_credentials=None, uploader_id=None, uploader_name=None, manager_credentials=None, ): self.device_id = device_id self.mobile_credentials = mobile_credentials self.uploader_id = uploader_id self.uploader_name = uploader_name self.manager_credentials = manager_credentials self.mobile_client = gmusicapi.Mobileclient() self.music_manager = gmusicapi.Musicmanager() self._login()
self.songs[(file_info['title'], file_info['artist'])] = file_info self.size += 1 if (self.size % 100 == 0): print self.size, " songs found" for folder in folders: self.add_folder(os.path.join(path, folder)) def song_exists(self, title, artist=''): return (title, artist) in self.songs music_dict = build_dict() print "Songs found: ", music_dict.size google_music = gmusicapi.Mobileclient() google_music.login(sys.argv[1], getpass.getpass(), google_music.FROM_MAC_ADDRESS) google_songs = google_music.get_all_songs() delete_songs = [] print "Removing music from google play that does not exist on computer." for song in google_songs: if not music_dict.song_exists(song["title"], song["artist"]): print "Deleting " + song["title"] + " by " + song[ "artist"] + " remotely" delete_songs.append(song["id"]) try: # print delete_songs response = raw_input("Do you want to delete these songs? (y/n): ") if (response != "n"):
__author__ = 'Lewis England' # Libraries import os import json import shutil import socket import gmusicapi import os.path # Local Libraries import DataFarmer api = gmusicapi.Mobileclient() # Local vars REMOTE_SERVER = "www.google.com" CACHE_FILE = '.gmusiccache' OFFLINE_MODE = False def set_offline_mode(mode): global OFFLINE_MODE OFFLINE_MODE = mode def in_offline_mode(): global OFFLINE_MODE return OFFLINE_MODE def internet_connection():
def setup(force=False): is_setup = True if ADDON.getSetting('is_setup') == 'true' else False if is_setup and not force: return True dialog = xbmcgui.Dialog() username = dialog.input(utils.translate(30075), type=xbmcgui.INPUT_ALPHANUM) if not username: return False # If 2-Factor Authentication is used is_two_factor = dialog.yesno(utils.translate(30071), utils.translate(30072)) if is_two_factor: if not dialog.ok(utils.translate(30071), utils.translate(30073), utils.translate(30074)): return False password = dialog.input(utils.translate(30076), type=xbmcgui.INPUT_ALPHANUM, option=xbmcgui.ALPHANUM_HIDE_INPUT) if not password: return False device_id = None if is_two_factor: # If Android Device available if dialog.yesno(utils.translate(30077), utils.translate(30078)): if not dialog.ok(utils.translate(30079), utils.translate(30081)): return False device_id = dialog.input(utils.translate(30084), type=xbmcgui.INPUT_ALPHANUM) if not device_id: return False else: # If using MAC-Address if dialog.yesno(utils.translate(30082), utils.translate(30083)): device_id = gmusicapi.Mobileclient.FROM_MAC_ADDRESS else: return False else: web = gmusicapi.Webclient() if not web.login(username, password): # If re-run setup due to login failed if dialog.yesno(utils.translate(30048), utils.translate(30085)): return setup(force=True) else: return False try: devices = web.get_registered_devices() if not devices: raise dev_list = [] for dev in devices: # Not an Android Device so we skip as streaming would not work if dev['deviceType'] != 2: continue if 'id' in dev and dev['id']: dev_list.append('%s - %s' % ( dev.get('carrier', '').strip(' '), dev.get('model', '').strip(' '), )) dev_list = sorted(dev_list) if len(dev_list) <= 0: raise elif len(dev_list) == 1: device_id = devices[0]['id'].lstrip('0x') else: selection = dialog.select(utils.translate(30042), dev_list, 0) if selection >= 0: device_id = devices[selection]['id'].lstrip('0x') else: return False except Exception: # If use MAC-Address instead due to no devices found if not dialog.yesno(utils.translate(30079), utils.translate(30097)): return False device_id = gmusicapi.Mobileclient.FROM_MAC_ADDRESS # Test login mobile = gmusicapi.Mobileclient() if mobile.login(username, password, device_id): # Test if this is an all-access account if not mobile.get_all_stations(): dialog.ok(utils.translate(30091), utils.translate(30092)) return False ADDON.setSetting('username', username) ADDON.setSetting('password', password) ADDON.setSetting('authtoken', mobile.session._authtoken) if device_id == gmusicapi.Mobileclient.FROM_MAC_ADDRESS: mac_address = ''.join(re.findall('..', '%012x' % uuid.getnode())) ADDON.setSetting('device_id', mac_address) else: ADDON.setSetting('device_id', device_id) ADDON.setSetting('is_setup', 'true') utils.notify(utils.translate(30086), utils.translate(30087)) return True else: # If re-run setup if dialog.yesno(utils.translate(30048), utils.translate(30085)): return setup(force=True) return False
def auth(oauth_credentials): client = gmusicapi.Mobileclient() if not os.path.exists(oauth_credentials): client.perform_oauth(oauth_credentials, open_browser=True) client.oauth_login(gmusicapi.Mobileclient.FROM_MAC_ADDRESS, oauth_credentials=oauth_credentials) return client
def __init__(self, device_id): self.user = None self.logged_in = False self.api = gmusicapi.Mobileclient() self.device_id = device_id
def login(): # Loads config JSON to global variable config_json global config_json if os.path.exists(CONFIG_FILENAME): if os.access(pathlib.Path(__file__).parent.absolute(), os.R_OK): with open(CONFIG_FILENAME, "r") as config_file: config_json = json.load(config_file) else: exit( "No read access for the config file. Please check permissions." ) else: exit( "Config file does not exist. Please run \"python playlistrandomizer.py createconfig\" and fill in the appropriate login information." ) # If already have OAuth credentials if os.path.exists(config_json["oauth_file"]): # Check read access if os.access(pathlib.Path(__file__).parent.absolute(), os.R_OK): device_id = "" api = gmusicapi.Mobileclient(debug_logging=False) # Log in with dummy device ID in order to get the list of valid device IDs try: api.oauth_login(device_id="ABCDEF1234567890", oauth_credentials=config_json["oauth_file"]) except gmusicapi.exceptions.InvalidDeviceId as err: # Make sure there is at least one device ID returned if len(err.valid_device_ids) > 0: device_id = err.valid_device_ids[0] # Log in a second time with valid device ID try: logged_in = api.oauth_login( device_id=device_id, oauth_credentials=config_json["oauth_file"]) except gmusicapi.exceptions.InvalidDeviceId as err: print("Second login failed.") else: print("Unable to read OAuth credentials. Check permissions.") # If OAuth file can't be found, perform OAuth login for first time else: print("OAuth credentials were not found.") # Get filepath to store credentials in is_valid_location = False file_path = "" while not is_valid_location: answer = input( "Enter path to store credentials. Default is the same location as the Python script. Leave blank for default:" ) if answer == '': is_valid_location = os.access( pathlib.Path(__file__).parent.absolute(), os.W_OK) file_path = os.path.join( pathlib.Path(__file__).parent.absolute(), OAUTH_FILENAME) else: is_valid_location = os.access(answer, os.W_OK) if not is_valid_location: print("Location doesn't exist, or write access denied") else: file_path = os.path.join(answer, OAUTH_FILENAME) # Write oauth_file location to config if os.path.exists(CONFIG_FILENAME): if os.access(pathlib.Path(__file__).parent.absolute(), os.R_OK): config_json["oauth_file"] = file_path with open(CONFIG_FILENAME, "w") as config_file: json.dump(config_json, config_file, indent=4, sort_keys=True) else: exit( "No read access for the config file. Please check permissions." ) else: exit( "Config file does not exist. Please run \"python playlistrandomizer.py createconfig\" and fill in the appropriate login information." ) # Generate OAuth token api = gmusicapi.Mobileclient(debug_logging=False) api.perform_oauth(config_json["oauth_file"], open_browser=True) # Log in using new OAuth credentials device_id = "" # Log in with dummy device ID in order to get the list of valid device IDs try: api.oauth_login(device_id="ABCDEF1234567890", oauth_credentials=file_path) except gmusicapi.exceptions.InvalidDeviceId as err: # Make sure there is at least one device ID returned if len(err.valid_device_ids) > 0: device_id = err.valid_device_ids[0] # Log in a second time with valid device ID try: logged_in = api.oauth_login(device_id=device_id, oauth_credentials=file_path) except gmusicapi.exceptions.InvalidDeviceId as err: print("Second login failed.") if not logged_in: exit("Unable to login with the provided credentials.") else: return api
def __init__(self, all_access, api=None): self.all_access = all_access if api is None: self.api = gmusicapi.Mobileclient() else: self.api = api