def session(network, key_file): if not os.path.exists(key_file): skg = pylast.SessionKeyGenerator(network) url = skg.get_web_auth_url() logger.info( "Please authorize the scrobbler " "to scrobble to your account: %s\n" % url ) import webbrowser webbrowser.open(url) while True: try: session_key = skg.get_web_auth_session_key(url) fp = open(key_file, "w") fp.write(session_key) fp.close() break except pylast.WSError: time.sleep(1) else: session_key = open(key_file).read() network.session_key = session_key
def clicked(self, *ignore): if self.auth_url: def err(e): logging.error(e) self.set_button_text() get_worker().send(self.sg.get_web_auth_session_key, (self.auth_url, ), self.setkey, err) self.button.set_label("Checking...") self.button.set_sensitive(False) self.auth_url = False elif self.enabled: self.setkey(False) else: self.network = pylast.get_lastfm_network(api_key=API_KEY, api_secret=API_SECRET) self.sg = pylast.SessionKeyGenerator(self.network) def callback(url): self.auth_url = url self.set_button_text() open_browser(self.auth_url) get_worker().send(self.sg.get_web_auth_url, (), callback) self.button.set_label("Connecting...") self.button.set_sensitive(False)
def authorize() -> pylast.LastFMNetwork: network = pylast.LastFMNetwork(api_key=API_KEY, api_secret=API_SECRET) lastfm_session = pylast.SessionKeyGenerator(network) if not SESSION_KEY_FILE.exists(): auth_url = lastfm_session.get_web_auth_url() print(f'Open your browser and authorize application: {auth_url}') while True: try: session_key = lastfm_session.get_web_auth_session_key(auth_url) SESSION_KEY_FILE.write_text(session_key) print(f'Session key has been saved to {SESSION_KEY_FILE}') break except pylast.WSError: time.sleep(1) else: print( f'You are already authorized with session key: {get_session_key()}' ) print(f'Session key file location: {SESSION_KEY_FILE}') network.session_key = get_session_key() return network
def __init__(self): self.apiKey = 'eb1f248f2a3dd23c0d321448d1b74c8a' self.secret = 'bfd72e05278afbd59b4b27e62036a115' self.getInfo() self.network = pylast.LastFMNetwork(api_key = self.apiKey, api_secret = self.secret, username = self.username, password_hash = self.password) sg = pylast.SessionKeyGenerator(self.network) self.scrobbler = self.network.get_scrobbler('tst', '1.0')
def request_authentication(self, callback): """ Instigates first of Last.fm's two-stage authentication. Returns a URL for the participant to confirm access to their profile by this application. :param callback: PRISONER's authentication flow URL. The participant must go here after authenticating with Last.fm to continue the flow :type callback: str """ self.session_manager = pylast.SessionKeyGenerator(self.network) return self.session_manager.get_web_flow(callback)
def login(self, query): form = self._deserialize(query) storage = harkfm.Storage() api_key = harkfm.Engine.config['apis']['last.fm']['key'] api_secret = harkfm.Engine.config['apis']['last.fm']['secret'] try: network = pylast.get_lastfm_network(api_key, api_secret) session_key = pylast.SessionKeyGenerator(network).get_session_key(form['username'], pylast.md5(form['password'])) storage.config_set('apis/last.fm/session_key', session_key) interface = harkfm.Interface() interface.index() except Exception as e: harkfm.Interface.logger.error('%s %s', type(e), e)
def check(self, the_session_key, lastfm_token): """ Depending on the existence of a session key or lastfm_token tell the app if the user is logged in or not :param the_session_key: A session key derived by pylast.SessionKeyGenerator :param lastfm_token: A token derived by calling the last.fm API as on http://www.last.fm/api/webauth :return: True (user is logged in) | False (user not logged in) """ # Derive secret API key and API secret form yaml file doc = get_secret_dict() # If a session_key is there if the_session_key is not None: # try to connect at last.fm try: network = pylast.LastFMNetwork(api_key=doc["api_key"], api_secret=doc["api_secret"], session_key=the_session_key) logged_in = True except: logged_in = False return logged_in else: # If a token was provided if lastfm_token is not None: network = pylast.LastFMNetwork(api_key=doc["api_key"], api_secret=doc["api_secret"], username=doc["username"]) # Create a session key by using pylast try: sk_gen = pylast.SessionKeyGenerator(network) session_key = sk_gen.get_web_auth_session_key( url=None, token=lastfm_token) except WSError: return False session["session_key"] = session_key return True else: return False
def retrieve_librefm_session(self): ''' Opens a Web browser to create a session key file if none exists yet. Else, it is loaded from disk. Returns True on success. ''' if not os.path.exists(LIBREFM_SESSION_KEY_FILE): import webbrowser logger.warning('The Libre.fm session key does not exist. A Web ' 'browser will open an authentication URL. Confirm ' 'access using your username and password. This ' 'has to be done only once.') session_keygen = pylast.SessionKeyGenerator(self.librefm) auth_url = session_keygen.get_web_auth_url() webbrowser.open(auth_url) logger.info( 'A Web browser may not be opened if you run Mopidy ' 'as a different user. In this case, you will have ' 'to manually open the link "{url}".'.format(url=auth_url)) remainingTime = 30 # approximately 30 seconds before timeout while remainingTime: try: session_key = session_keygen \ .get_web_auth_session_key(auth_url) # if the file was created in the meantime, it will # be blindly overwritten: with open(LIBREFM_SESSION_KEY_FILE, 'w') as f: f.write(session_key) logger.debug('Libre.fm session key retrieved and written ' 'to disk.') break except pylast.WSError: remainingTime -= 1 time.sleep(1) except IOError: logger.error( 'Cannot write to session key file "{path}"'.format( path=LIBREFM_SESSION_KEY_FILE)) return False if not remainingTime: logger.error('Authenticating to Libre.fm timed out. Did you ' 'allow access in your Web browser?') return False else: session_key = open(LIBREFM_SESSION_KEY_FILE).read() self.librefm.session_key = session_key return True
def on_start(self): try: self.lastfm = pylast.LastFMNetwork(api_key=API_KEY, api_secret=API_SECRET) if self.config.get('proxy'): self.lastfm.enable_proxy(self.config['proxy']['hostname'], self.config['proxy']['port']) self.lastfm.username = self.config['scrobbler']['username'] self.lastfm.password_hash = pylast.md5( self.config['scrobbler']['password']) sk_gen = pylast.SessionKeyGenerator(self.lastfm) self.lastfm.session_key = sk_gen.get_session_key( self.lastfm.username, self.lastfm.password_hash) logger.info('Scrobbler connected to Last.fm') except (pylast.NetworkError, pylast.MalformedResponseError, pylast.WSError) as e: logger.error('Error during Last.fm setup: %s', e) self.stop()
def fmlogin(word, word_eol, userdata): # Need one argument (the username) if not len(word) > 1: hexchat.command("help fmlogin") return hexchat.EAT_ALL else: # If there's no session key if not os.path.exists(SESSION_KEY_FILE): skg = pylast.SessionKeyGenerator(network) url = skg.get_web_auth_url() hexchat.prnt("Please authorise the scrobbler: %s" % url) import webbrowser webbrowser.open(url) while True: try: session_key = skg.get_web_auth_session_key(url) fp = open(SESSION_KEY_FILE, "w") fp.write(session_key) fp.close() break except pylast.WSError: time.sleep(1) else: session_key = open(SESSION_KEY_FILE).read() # Whether's a username file already or not, we replace it fp = open(USERNAME_FILE, "w") fp.write(word[1]) fp.close() # Now we have a key and a username network.session_key = session_key return hexchat.EAT_ALL
def config_wizard(): ''' Text User Interface to generate initial lastcast.toml config. ''' config = {'chromecast': {}} if click.confirm('Set up last.fm account?', default=True): click.echo(''' You'll need to create a last.fm API application first. Do so here: http://www.last.fm/api/account/create What you fill in doesn't matter at all, just make sure to save the API Key and Shared Secret. ''') config['lastfm'] = { key: click.prompt(key, type=str, hide_input=hidden) for (key, hidden) in [('user_name', False), ('password', True), ('api_key', False), ('api_secret', True)] } if click.confirm('Set up Libre.fm account?'): libre_conf = { key: click.prompt(key, type=str, hide_input=hidden) for (key, hidden) in [('user_name', False), ('password', True)] } libre = pylast.LibreFMNetwork( username=libre_conf['user_name'], password_hash=pylast.md5(libre_conf['password'])) skg = pylast.SessionKeyGenerator(libre) url = skg.get_web_auth_url() click.echo('''Please grant lastcast access to your Libre.fm account: %s ''' % url) click.echo('Hit enter when ready') click.getchar() libre_conf['session_key'] = skg.get_web_auth_session_key(url) config['librefm'] = libre_conf available = [ cc.device.friendly_name for cc in pychromecast.get_chromecasts() ] if len(available) == 1: config['chromecast']['devices'] = [available[0]] if len(available) > 1 or click.confirm('Manually specify cast device?', default=True): click.echo('\n\nAvailable cast devices: %s' % ', '.join(available)) device_names = click.prompt('Which device(s) should be used? (comma separated)') device_names = [d.strip() for d in device_names.split(',') if d.strip != ''] config['chromecast']['devices'] = device_names click.echo('\n\nDefault chromecast apps to scrobble from: %s' % ', '.join(APP_WHITELIST)) apps = click.prompt('Comma separated apps [blank for default]', default='', show_default=False) apps = [app.strip() for app in apps.split(',') if app.strip() != ''] if apps: config['chromecast']['app_whitelist'] = apps generated = toml.dumps(config) click.echo('Generated config:\n\n%s' % generated) if click.confirm('Write to ~/.lastcast.toml?', default=True): with open(os.path.expanduser('~/.lastcast.toml'), 'w') as fp: fp.write(generated)
def duration(track): return int(track.track.get_duration()) / 1000 if __name__ == "__main__": parser = argparse.ArgumentParser( description="Loopy thing to show what a Last.fm user is now playing.", formatter_class=argparse.ArgumentDefaultsHelpFormatter, ) parser.add_argument("user", nargs="?", default="hvk", help="User to check") args = parser.parse_args() network = pylast.LastFMNetwork(API_KEY, API_SECRET) if not os.path.exists(SESSION_KEY_FILE): skg = pylast.SessionKeyGenerator(network) url = skg.get_web_auth_url() print(f"Please authorize the scrobbler to scrobble to your account: {url}\n") import webbrowser webbrowser.open(url) while True: try: session_key = skg.get_web_auth_session_key(url) fp = open(SESSION_KEY_FILE, "w") fp.write(session_key) fp.close() break except pylast.WSError:
def get_session(token): network = pylast.LastFMNetwork(api_key=API_KEY, api_secret=API_SECRET) sg = pylast.SessionKeyGenerator(network) session_key = sg.get_web_auth_session_key(token) return session_key
def main(): global playing_station parser = argparse.ArgumentParser( description="BBC Radio scrobbler. " "On Mac: scrobbles BBC from iTunes if it's running, " "or the station of your choice if --ignore-itunes. " "On Windows: scrobbles BBC from Winamp if it's running, " "or the station of your choice if --ignore-winamp.", formatter_class=argparse.ArgumentDefaultsHelpFormatter, ) parser.add_argument( "-i", "--ignore-media-player", action="store_true", help= "Shortcut for --ignore-itunes on Mac or --ignore-winamp on Windows", ) parser.add_argument( "--ignore-itunes", action="store_true", help="Mac only: Ignore whatever iTunes is doing and scrobble the " "station. For example, use this if listening via web or a real " "radio.", ) parser.add_argument( "--ignore-winamp", action="store_true", help="Windows only: Ignore whatever Winamp is doing and scrobble the " "station. For example, use this if listening via web or a real " "radio.", ) parser.add_argument( "station", nargs="?", default="bbc6music", choices=("bbc6music", "bbcradio1", "bbcradio2", "bbc1xtra"), help="BBC station to scrobble", ) parser.add_argument("-s", "--say", action="store_true", help="Mac only: Announcertron 4000") args = parser.parse_args() atexit.register(restore_terminal_title) if args.ignore_media_player: if _platform == "darwin": args.ignore_itunes = True elif _platform == "win32": args.ignore_winamp = True network = pylast.LastFMNetwork(API_KEY, API_SECRET) if not os.path.exists(SESSION_KEY_FILE): skg = pylast.SessionKeyGenerator(network) url = skg.get_web_auth_url() print( "Please authorize the scrobbler to scrobble to your account: %s\n" % url) import webbrowser webbrowser.open(url) while True: try: session_key = skg.get_web_auth_session_key(url) fp = open(SESSION_KEY_FILE, "w") fp.write(session_key) fp.close() break except pylast.WSError: time.sleep(1) else: session_key = open(SESSION_KEY_FILE).read() network.session_key = session_key last_station = None last_scrobbled = None playing_track = None np_time = None scrobble_me_next = None playing_station = args.station try: while True: if not check_media_player(args.ignore_itunes, args.ignore_winamp): last_station = None last_scrobbled = None playing_track = None np_time = None scrobble_me_next = None else: if last_station != playing_station: last_station = playing_station out = f"Tuned in to {playing_station}" output(out + "\n" + "-" * len(out)) if args.say: say(playing_station) try: # Get now playing track realtime = bbcrealtime.nowplaying(playing_station) if realtime: new_track = pylast.Track(realtime["artist"], realtime["title"], network) new_track.start = realtime["start"] new_track.end = realtime["end"] else: new_track = None if (new_track and (time.time() - new_track.end) > ONE_HOUR_IN_SECONDS): print("Last track over an hour ago, don't scrobble") raise Escape # A new, different track if new_track != playing_track: if scrobble_me_next: scrobble(network, scrobble_me_next) scrobble_me_next = None last_scrobbled = scrobble_me_next playing_track = new_track update_now_playing(network, playing_track, args.say) np_time = int(time.time()) # Scrobblable if 30 seconds has gone by else: now = int(time.time()) if (playing_track and playing_track != last_scrobbled and now - np_time >= 30): scrobble_me_next = playing_track except Escape: pass except ( KeyError, pylast.NetworkError, pylast.MalformedResponseError, ) as e: output("Error: {}".format(repr(e)), "error") time.sleep(15) except KeyboardInterrupt: if scrobble_me_next: scrobble(network, scrobble_me_next) print("exit")