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
Beispiel #2
0
    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)
Beispiel #3
0
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
Beispiel #4
0
 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')
Beispiel #5
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)
Beispiel #6
0
 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)
Beispiel #7
0
    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
Beispiel #8
0
    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
Beispiel #9
0
 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()
Beispiel #10
0
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
Beispiel #11
0
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)
Beispiel #12
0
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:
Beispiel #13
0
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
Beispiel #14
0
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")