scrobbler: Move to external extension

This commit is contained in:
Stein Magnus Jodal 2013-10-07 00:02:36 +02:00
parent fd6bb4ba43
commit 6400a45a0e
9 changed files with 26 additions and 179 deletions

View File

@ -50,4 +50,3 @@ Frontend implementations
* :mod:`mopidy.frontends.http`
* :mod:`mopidy.frontends.mpd`
* :mod:`mopidy.frontends.mpris`
* :mod:`mopidy.frontends.scrobbler`

View File

@ -7,6 +7,13 @@ This changelog is used to track all major changes to Mopidy.
v0.16.0 (UNRELEASED)
====================
**Extensions**
- The Last.fm scrobbler has been moved to its own external extension,
`Mopidy-Scrobbler <https://github.com/mopidy/mopidy-scrobbler>`. You'll need
to install it in addition to Mopidy if you want it to continue to work as it
used to.
**Audio**
- Added support for parsing and playback of playlists in GStreamer. What this

View File

@ -77,6 +77,21 @@ Issues:
https://github.com/mopidy/mopidy/issues
Mopidy-Scrobbler
----------------
Extension for scrobbling played tracks to Last.fm.
Author:
Stein Magnus Jodal
PyPI:
`Mopidy-Scrobbler <https://pypi.python.org/pypi/Mopidy-Scrobbler>`_
GitHub:
`mopidy/mopidy-scrobbler <https://github.com/mopidy/mopidy-scrobbler>`_
Issues:
https://github.com/mopidy/mopidy-scrobbler/issues
Mopidy-SomaFM
-------------

View File

@ -1,55 +0,0 @@
.. _ext-scrobbler:
****************
Mopidy-Scrobbler
****************
This extension scrobbles the music you play to your `Last.fm
<http://www.last.fm>`_ profile.
.. note::
This extension requires a free user account at Last.fm.
Dependencies
============
.. literalinclude:: ../../requirements/scrobbler.txt
Default configuration
=====================
.. literalinclude:: ../../mopidy/frontends/scrobbler/ext.conf
:language: ini
Configuration values
====================
.. confval:: scrobbler/enabled
If the scrobbler extension should be enabled or not.
.. confval:: scrobbler/username
Your Last.fm username.
.. confval:: scrobbler/password
Your Last.fm password.
Usage
=====
The extension is enabled by default if all dependencies are available. You just
need to add your Last.fm username and password to the
``~/.config/mopidy/mopidy.conf`` file:
.. code-block:: ini
[scrobbler]
username = myusername
password = mysecret

View File

@ -25,9 +25,9 @@ Glossary
frontend
A part of Mopidy *using* the :term:`core` API. Existing frontends
include the :ref:`MPD server <ext-mpd>`, the :ref:`MPRIS/D-Bus
integration <ext-mpris>`, the :ref:`Last.fm scrobbler <ext-scrobbler>`,
and the :ref:`HTTP server <ext-http>` with JavaScript API. See
:ref:`frontend-api` for details.
integration <ext-mpris>`, the Last.fm scrobbler, and the :ref:`HTTP
server <ext-http>` with JavaScript API. See :ref:`frontend-api` for
details.
mixer
A GStreamer element that controls audio volume.

View File

@ -1,33 +0,0 @@
from __future__ import unicode_literals
import os
import mopidy
from mopidy import config, exceptions, ext
class Extension(ext.Extension):
dist_name = 'Mopidy-Scrobbler'
ext_name = 'scrobbler'
version = mopidy.__version__
def get_default_config(self):
conf_file = os.path.join(os.path.dirname(__file__), 'ext.conf')
return config.read(conf_file)
def get_config_schema(self):
schema = super(Extension, self).get_config_schema()
schema['username'] = config.String()
schema['password'] = config.Secret()
return schema
def validate_environment(self):
try:
import pylast # noqa
except ImportError as e:
raise exceptions.ExtensionError('pylast library not found', e)
def get_frontend_classes(self):
from .actor import ScrobblerFrontend
return [ScrobblerFrontend]

View File

@ -1,81 +0,0 @@
from __future__ import unicode_literals
import logging
import time
import pykka
import pylast
from mopidy.core import CoreListener
logger = logging.getLogger('mopidy.frontends.scrobbler')
API_KEY = '2236babefa8ebb3d93ea467560d00d04'
API_SECRET = '94d9a09c0cd5be955c4afaeaffcaefcd'
class ScrobblerFrontend(pykka.ThreadingActor, CoreListener):
def __init__(self, config, core):
super(ScrobblerFrontend, self).__init__()
self.config = config
self.lastfm = None
self.last_start_time = None
def on_start(self):
try:
self.lastfm = pylast.LastFMNetwork(
api_key=API_KEY, api_secret=API_SECRET,
username=self.config['scrobbler']['username'],
password_hash=pylast.md5(self.config['scrobbler']['password']))
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 track_playback_started(self, tl_track):
track = tl_track.track
artists = ', '.join([a.name for a in track.artists])
duration = track.length and track.length // 1000 or 0
self.last_start_time = int(time.time())
logger.debug('Now playing track: %s - %s', artists, track.name)
try:
self.lastfm.update_now_playing(
artists,
(track.name or ''),
album=(track.album and track.album.name or ''),
duration=str(duration),
track_number=str(track.track_no),
mbid=(track.musicbrainz_id or ''))
except (pylast.ScrobblingError, pylast.NetworkError,
pylast.MalformedResponseError, pylast.WSError) as e:
logger.warning('Error submitting playing track to Last.fm: %s', e)
def track_playback_ended(self, tl_track, time_position):
track = tl_track.track
artists = ', '.join([a.name for a in track.artists])
duration = track.length and track.length // 1000 or 0
time_position = time_position // 1000
if duration < 30:
logger.debug('Track too short to scrobble. (30s)')
return
if time_position < duration // 2 and time_position < 240:
logger.debug(
'Track not played long enough to scrobble. (50% or 240s)')
return
if self.last_start_time is None:
self.last_start_time = int(time.time()) - duration
logger.debug('Scrobbling track: %s - %s', artists, track.name)
try:
self.lastfm.scrobble(
artists,
(track.name or ''),
str(self.last_start_time),
album=(track.album and track.album.name or ''),
track_number=str(track.track_no),
duration=str(duration),
mbid=(track.musicbrainz_id or ''))
except (pylast.ScrobblingError, pylast.NetworkError,
pylast.MalformedResponseError, pylast.WSError) as e:
logger.warning('Error submitting played track to Last.fm: %s', e)

View File

@ -1,4 +0,0 @@
[scrobbler]
enabled = true
username =
password =

View File

@ -29,7 +29,7 @@ setup(
],
extras_require={
'spotify': ['pyspotify >= 1.9, < 2'],
'scrobbler': ['pylast >= 0.5.7'],
'scrobbler': ['Mopidy-Scrobbler'],
'http': ['cherrypy >= 3.2.2', 'ws4py >= 0.2.3'],
},
test_suite='nose.collector',
@ -45,7 +45,6 @@ setup(
],
'mopidy.ext': [
'http = mopidy.frontends.http:Extension [http]',
'scrobbler = mopidy.frontends.scrobbler:Extension [scrobbler]',
'local = mopidy.backends.local:Extension',
'mpd = mopidy.frontends.mpd:Extension',
'mpris = mopidy.frontends.mpris:Extension',