Ejemplo n.º 1
0
    def __init__(self, config, cast_name, available_devices=None):
        self.cast_name = cast_name
        self.cast_config = config.get('chromecast', {})
        self.app_whitelist = self.cast_config.get('app_whitelist', APP_WHITELIST)

        self.last_scrobbled = {}
        self.current_track = {}
        self.current_time = 0
        self.last_poll = time.time()

        self._connect_chromecast(available_devices)

        if not self.cast:
            raise ChromecastNotFoundException()

        self.scrobblers = []

        if 'lastfm' in config:
            self.scrobblers.append(pylast.LastFMNetwork(
                api_key=config['lastfm']['api_key'],
                api_secret=config['lastfm']['api_secret'],
                username=config['lastfm']['user_name'],
                password_hash=pylast.md5(config['lastfm']['password'])))

        if 'librefm' in config:
            self.scrobblers.append(pylast.LibreFMNetwork(
                session_key=config['librefm']['session_key'],
                username=config['librefm']['user_name'],
                password_hash=pylast.md5(config['librefm']['password'])
            ))

        self.estimate_spotify_timestamp = self.cast_config.get(
            'estimate_spotify_timestamp', True)
Ejemplo n.º 2
0
    def __init__(self,
                 API_KEY,
                 API_SECRET,
                 lastfm_username,
                 lastfm_password,
                 lastfm_password_hash=None,
                 network="lastfm"):
        if lastfm_password_hash is None:
            lastfm_password_hash = pylast.md5(lastfm_password)

        network = network.lower()

        if network == "lastfm":
            self.network = pylast.LastFMNetwork(
                api_key=API_KEY,
                api_secret=API_SECRET,
                username=lastfm_username,
                password_hash=lastfm_password_hash)
        elif network == "librefm":
            self.network = pylast.LibreFMNetwork(
                api_key=API_KEY,
                api_secret=API_SECRET,
                username=lastfm_username,
                password_hash=lastfm_password_hash)
        else:
            raise RuntimeError("Network {} unknown".format(network))
Ejemplo n.º 3
0
    def _main(self):
        """
        get's automatically called from Memacs class
        """

        options = {
            'api_secret': self._get_config_option('api_secret'),
            'api_key': self._get_config_option('api_key'),
            'password_hash': pylast.md5(self._get_config_option('password')),
            'username': self._get_config_option('username')
        }

        try:

            if 'lastfm' in self._get_config_option('network'):
                network = pylast.LastFMNetwork(**options)

            if 'librefm' in self._get_config_option('network'):
                network = pylast.LibreFMNetwork(**options)

            user = network.get_user(options['username'])

            self._handle_recent_tracks(user.get_recent_tracks(limit=100))

        except pylast.WSError as e:
            logging.error('an issue with the network web service occured: %s' %
                          e)
            sys.exit(1)
Ejemplo n.º 4
0
def librefmconnect():
    config = configparser.ConfigParser()
    config.read("config.ini")
    username = config["librefm"]["username"]
    password = pylast.md5(config["librefm"]["password"])

    librefm = pylast.LibreFMNetwork(username=username, password_hash=password)
    return librefm
Ejemplo n.º 5
0
    def test_repr(self):
        # Arrange
        secrets = load_secrets()
        username = secrets["username"]
        password_hash = secrets["password_hash"]
        network = pylast.LibreFMNetwork(password_hash=password_hash, username=username)

        # Act
        representation = repr(network)

        # Assert
        self.assert_startswith(representation, "pylast.LibreFMNetwork(")
Ejemplo n.º 6
0
    def test_libre_fm(self):
        # Arrange
        secrets = load_secrets()
        username = secrets["username"]
        password_hash = secrets["password_hash"]

        # Act
        network = pylast.LibreFMNetwork(password_hash=password_hash, username=username)
        artist = network.get_artist("Radiohead")
        name = artist.get_name()

        # Assert
        self.assertEqual(name, "Radiohead")
Ejemplo n.º 7
0
    def connect_to_librefm(self):
        ''' Connect to Libre.fm and return True on success. '''
        librefm_username = self.config['scrobbler']['librefm_username']
        librefm_password = self.config['scrobbler']['librefm_password']

        try:
            if librefm_username and librefm_password:
                self.librefm = pylast.LibreFMNetwork(
                    username=librefm_username,
                    password_hash=pylast.md5(librefm_password))

                if self.retrieve_librefm_session():
                    self.networks['Libre.fm'] = self.librefm
                    logger.info('Scrobbler connected to Libre.fm')
                    return True
                else:
                    return False
        except (pylast.NetworkError, pylast.MalformedResponseError,
                pylast.WSError) as e:
            logger.error('Error while connecting to Libre.fm: %s', e)

        return False
Ejemplo n.º 8
0
    def get_network(self):
        if self.network is not None:
            return self.network

        if self.networkname == "lastfm":
            self.network = pylast.LastFMNetwork(
                api_key=self.api_key,
                api_secret=self.api_secret,
                username=self.username,
                password_hash=self.password_hash)
        elif self.netnetworkname == "librefm":
            self.network = pylast.LibreFMNetwork(
                api_key=self.api_key,
                api_secret=self.api_secret,
                username=self.username,
                password_hash=self.password_hash)
        else:
            raise RuntimeError("Network {} unknown".format(self.networkname))

        if self.network is not None:
            self.network.enable_caching()

        return self.network
Ejemplo n.º 9
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)
Ejemplo n.º 10
0
# -*- coding: utf-8 -*-
"""Takes the last 1000 songs from Listenbrainz and scrobbles it on Libre.fm"""
import os

import pylast
import pylistenbrainz
from dotenv import load_dotenv

load_dotenv()

# Set up the LibreFM client
libre_fm = pylast.LibreFMNetwork(
    api_key="Max-----------------------------",  # This can be anything
    api_secret=os.getenv("LIBRE_FM_PASSWORD"),
    username=os.getenv("LIBRE_FM_USERNAME"),
    password_hash=pylast.md5(os.getenv("LIBRE_FM_PASSWORD")),
)

# Authenticate with Listenbrainz
listenbrainz = pylistenbrainz.ListenBrainz()
listenbrainz.set_auth_token(os.getenv("LISTENBRAINZ_AUTH_TOKEN"))

# Get last 1000 listens - scrobbling the same thing multiple times has no effect
listens = listenbrainz.get_listens("aspiringmax", count=1000)

# Populate the tracks
scrobbles = []
for listen in listens:
    data = {
        "artist": listen.artist_name,
        "title": listen.track_name,