diff --git a/docs/extensiondev.rst b/docs/extensiondev.rst index 43b0b723..8e636b1e 100644 --- a/docs/extensiondev.rst +++ b/docs/extensiondev.rst @@ -219,13 +219,19 @@ meaningful defaults blank, like ``username`` and ``password``. import gst import gobject - from mopidy import exceptions - from mopidy import ext + from mopidy import exceptions, ext from mopidy.utils import config __version__ = '0.1' + default_config = """ + [ext.soundspot] + enabled = true + username = + password = + """ + class Extension(ext.Extension): @@ -233,12 +239,7 @@ meaningful defaults blank, like ``username`` and ``password``. version = __version__ def get_default_config(self): - return """ - [ext.soundspot] - enabled = true - username = - password = - """ + return default_config def get_config_schema(self): schema = config.ExtensionConfigSchema() @@ -269,7 +270,6 @@ meaningful defaults blank, like ``username`` and ``password``. def register_gstreamer_elements(self): from .mixer import SoundspotMixer - gobject.type_register(SoundspotMixer) gst.element_register( SoundspotMixer, 'soundspotmixer', gst.RANK_MARGINAL) diff --git a/mopidy/audio/mixers/auto.py b/mopidy/audio/mixers/auto.py index bd61445e..96359da1 100644 --- a/mopidy/audio/mixers/auto.py +++ b/mopidy/audio/mixers/auto.py @@ -2,14 +2,14 @@ This is Mopidy's default mixer. -**Dependencies:** +**Dependencies** -- None +None -**Settings:** +**Settings** -- If this wasn't the default, you would set :attr:`mopidy.settings.MIXER` - to ``autoaudiomixer`` to use this mixer. +If this wasn't the default, you would set :attr:`mopidy.settings.MIXER` to +``autoaudiomixer`` to use this mixer. """ from __future__ import unicode_literals diff --git a/mopidy/audio/mixers/fake.py b/mopidy/audio/mixers/fake.py index 948ab82e..738491b5 100644 --- a/mopidy/audio/mixers/fake.py +++ b/mopidy/audio/mixers/fake.py @@ -1,12 +1,12 @@ """Fake mixer for use in tests. -**Dependencies:** +**Dependencies** -- None +None -**Settings:** +**Settings** -- Set :attr:`mopidy.settings.MIXER` to ``fakemixer`` to use this mixer. +Set :attr:`mopidy.settings.MIXER` to ``fakemixer`` to use this mixer. """ from __future__ import unicode_literals diff --git a/mopidy/audio/mixers/nad.py b/mopidy/audio/mixers/nad.py index 52ab4757..8481de55 100644 --- a/mopidy/audio/mixers/nad.py +++ b/mopidy/audio/mixers/nad.py @@ -3,14 +3,14 @@ The NAD amplifier must be connected to the machine running Mopidy using a serial cable. -**Dependencies:** +**Dependencies** .. literalinclude:: ../../../../requirements/external_mixers.txt -**Settings:** +**Settings** -- Set :attr:`mopidy.settings.MIXER` to ``nadmixer`` to use it. You probably - also needs to add some properties to the ``MIXER`` setting. +Set :attr:`mopidy.settings.MIXER` to ``nadmixer`` to use it. You probably also +needs to add some properties to the ``MIXER`` setting. Supported properties includes: diff --git a/mopidy/backends/dummy.py b/mopidy/backends/dummy.py index c6997b12..dd021445 100644 --- a/mopidy/backends/dummy.py +++ b/mopidy/backends/dummy.py @@ -5,13 +5,13 @@ used in tests of the frontends. The backend handles URIs starting with ``dummy:``. -**Dependencies:** +**Dependencies** -- None +None -**Settings:** +**Default config** -- None +None """ from __future__ import unicode_literals diff --git a/mopidy/backends/local/__init__.py b/mopidy/backends/local/__init__.py index c2001da5..42477b53 100644 --- a/mopidy/backends/local/__init__.py +++ b/mopidy/backends/local/__init__.py @@ -2,8 +2,25 @@ from __future__ import unicode_literals import mopidy from mopidy import ext +from mopidy.utils import config, formatting +default_config = """ +[ext.local] + +# If the local extension should be enabled or not +enabled = true + +# Path to folder with local music +music_path = $XDG_MUSIC_DIR + +# Path to playlist folder with m3u files for local music +playlist_path = $XDG_DATA_DIR/mopidy/playlists + +# Path to tag cache for local music +tag_cache_file = $XDG_DATA_DIR/mopidy/tag_cache +""" + __doc__ = """A backend for playing music from a local music archive. This backend handles URIs starting with ``file:``. @@ -11,20 +28,20 @@ This backend handles URIs starting with ``file:``. See :ref:`music-from-local-storage` for further instructions on using this backend. -**Issues:** +**Issues** https://github.com/mopidy/mopidy/issues?labels=Local+backend -**Dependencies:** +**Dependencies** -- None +None -**Settings:** +**Default config** -- :attr:`mopidy.settings.LOCAL_MUSIC_PATH` -- :attr:`mopidy.settings.LOCAL_PLAYLIST_PATH` -- :attr:`mopidy.settings.LOCAL_TAG_CACHE_FILE` -""" +.. code-block:: ini + +%(config)s +""" % {'config': formatting.indent(default_config)} class Extension(ext.Extension): @@ -33,10 +50,14 @@ class Extension(ext.Extension): version = mopidy.__version__ def get_default_config(self): - return '[ext.local]' + return default_config - def validate_config(self, config): - pass + def get_config_schema(self): + schema = config.ExtensionConfigSchema() + schema['music_path'] = config.String() + schema['playlist_path'] = config.String() + schema['tag_cache_file'] = config.String() + return schema def validate_environment(self): pass diff --git a/mopidy/backends/spotify/__init__.py b/mopidy/backends/spotify/__init__.py index 503d9eb6..4c3b67fe 100644 --- a/mopidy/backends/spotify/__init__.py +++ b/mopidy/backends/spotify/__init__.py @@ -3,10 +3,10 @@ from __future__ import unicode_literals import mopidy from mopidy import ext from mopidy.exceptions import ExtensionError -from mopidy.utils.formatting import indent +from mopidy.utils import config, formatting -config = """ +default_config = """ [ext.spotify] # If the Spotify extension should be enabled or not @@ -49,20 +49,20 @@ See :ref:`music-from-spotify` for further instructions on using this backend. otherwise approved in any way by Spotify. Spotify is the registered trade mark of the Spotify Group. -**Issues:** +**Issues** https://github.com/mopidy/mopidy/issues?labels=Spotify+backend -**Dependencies:** +**Dependencies** .. literalinclude:: ../../../requirements/spotify.txt -**Default config:** +**Default config** .. code-block:: ini %(config)s -""" % {'config': indent(config)} +""" % {'config': formatting.indent(default_config)} class Extension(ext.Extension): @@ -71,15 +71,19 @@ class Extension(ext.Extension): version = mopidy.__version__ def get_default_config(self): - return config + return default_config - def validate_config(self, config): - if not config.getboolean('spotify', 'enabled'): - return - if not config.get('spotify', 'username'): - raise ExtensionError('Config spotify.username not set') - if not config.get('spotify', 'password'): - raise ExtensionError('Config spotify.password not set') + def get_config_schema(self): + schema = config.ExtensionConfigSchema() + schema['username'] = config.String() + schema['password'] = config.String(secret=True) + schema['bitrate'] = config.Integer(choices=(96, 160, 320)) + schema['timeout'] = config.Integer(minimum=0) + schema['cache_path'] = config.String() + schema['proxy_host'] = config.Hostname(optional=True) + schema['proxy_username'] = config.String(optional=True) + schema['proxy_password'] = config.String(optional=True, secret=True) + return schema def validate_environment(self): try: diff --git a/mopidy/backends/stream/__init__.py b/mopidy/backends/stream/__init__.py index 4096476e..097efc45 100644 --- a/mopidy/backends/stream/__init__.py +++ b/mopidy/backends/stream/__init__.py @@ -2,26 +2,45 @@ from __future__ import unicode_literals import mopidy from mopidy import ext +from mopidy.utils import config, formatting +default_config = """ +[ext.stream] + +# If the stream extension should be enabled or not +enabled = true + +# Whitelist of URI schemas to support streaming from +protocols = + http + https + mms + rtmp + rtmps + rtsp +""" + __doc__ = """A backend for playing music for streaming music. This backend will handle streaming of URIs in :attr:`mopidy.settings.STREAM_PROTOCOLS` assuming the right plugins are installed. -**Issues:** +**Issues** https://github.com/mopidy/mopidy/issues?labels=Stream+backend -**Dependencies:** +**Dependencies** -- None +None -**Settings:** +**Default config** -- :attr:`mopidy.settings.STREAM_PROTOCOLS` -""" +.. code-block:: ini + +%(config)s +""" % {'config': formatting.indent(default_config)} class Extension(ext.Extension): @@ -30,10 +49,12 @@ class Extension(ext.Extension): version = mopidy.__version__ def get_default_config(self): - return '[ext.stream]' + return default_config - def validate_config(self, config): - pass + def get_config_schema(self): + schema = config.ExtensionConfigSchema() + schema['protocols'] = config.List() + return schema def validate_environment(self): pass diff --git a/mopidy/frontends/http/__init__.py b/mopidy/frontends/http/__init__.py index 7b99efd0..6160d47c 100644 --- a/mopidy/frontends/http/__init__.py +++ b/mopidy/frontends/http/__init__.py @@ -1,25 +1,56 @@ from __future__ import unicode_literals import mopidy -from mopidy import ext -from mopidy.exceptions import ExtensionError +from mopidy import exceptions, ext +from mopidy.utils import config, formatting +default_config = """ +[ext.http] + +# If the HTTP extension should be enabled or not +enabled = true + +# Which address the HTTP server should bind to +# +# 127.0.0.1 +# Listens only on the IPv4 loopback interface +# ::1 +# Listens only on the IPv6 loopback interface +# 0.0.0.0 +# Listens on all IPv4 interfaces +# :: +# Listens on all interfaces, both IPv4 and IPv6 +hostname = 127.0.0.1 + +# Which TCP port the HTTP server should listen to +port = 6680 + +# Which directory the HTTP server should serve at "/" +# +# Change this to have Mopidy serve e.g. files for your JavaScript client. +# "/mopidy" will continue to work as usual even if you change this setting. +# +static_dir = +""" + __doc__ = """ The HTTP frontends lets you control Mopidy through HTTP and WebSockets, e.g. from a web based client. +**Issues** + +https://github.com/mopidy/mopidy/issues?labels=HTTP+frontend + **Dependencies** .. literalinclude:: ../../../requirements/http.txt -**Settings** +**Default config** -- :attr:`mopidy.settings.HTTP_SERVER_HOSTNAME` +.. code-block:: ini -- :attr:`mopidy.settings.HTTP_SERVER_PORT` - -- :attr:`mopidy.settings.HTTP_SERVER_STATIC_DIR` +%(config)s Setup @@ -483,7 +514,7 @@ Example to get started with 9. The web page should now queue and play your first playlist every time your load it. See the browser's console for output from the function, any errors, and all events that are emitted. -""" +""" % {'config': formatting.indent(default_config)} class Extension(ext.Extension): @@ -492,21 +523,25 @@ class Extension(ext.Extension): version = mopidy.__version__ def get_default_config(self): - return '[ext.http]' + return default_config - def validate_config(self, config): - pass + def get_config_schema(self): + schema = config.ExtensionConfigSchema() + schema['hostname'] = config.Hostname() + schema['port'] = config.Port() + schema['static_dir'] = config.String(optional=True) + return schema def validate_environment(self): try: import cherrypy # noqa except ImportError as e: - raise ExtensionError('Library cherrypy not found', e) + raise exceptions.ExtensionError('cherrypy library not found', e) try: import ws4py # noqa except ImportError as e: - raise ExtensionError('Library ws4py not found', e) + raise exceptions.ExtensionError('ws4py library not found', e) def get_frontend_classes(self): from .actor import HttpFrontend diff --git a/mopidy/frontends/lastfm/__init__.py b/mopidy/frontends/lastfm/__init__.py index 439ada50..f24e8f81 100644 --- a/mopidy/frontends/lastfm/__init__.py +++ b/mopidy/frontends/lastfm/__init__.py @@ -1,10 +1,23 @@ from __future__ import unicode_literals import mopidy -from mopidy import ext -from mopidy.exceptions import ExtensionError +from mopidy import exceptions, ext +from mopidy.utils import config, formatting +default_config = """ +[ext.lastfm] + +# If the Last.fm extension should be enabled or not +enabled = true + +# Your Last.fm username +username = + +# Your Last.fm password +password = +""" + __doc__ = """ Frontend which scrobbles the music you play to your `Last.fm `_ profile. @@ -13,19 +26,20 @@ Frontend which scrobbles the music you play to your `Last.fm This frontend requires a free user account at Last.fm. -**Dependencies:** +**Dependencies** .. literalinclude:: ../../../requirements/lastfm.txt -**Settings:** +**Default config** -- :attr:`mopidy.settings.LASTFM_USERNAME` -- :attr:`mopidy.settings.LASTFM_PASSWORD` +.. code-block:: ini -**Usage:** +%(config)s + +**Usage** The frontend is enabled by default if all dependencies are available. -""" +""" % {'config': formatting.indent(default_config)} class Extension(ext.Extension): @@ -34,16 +48,19 @@ class Extension(ext.Extension): version = mopidy.__version__ def get_default_config(self): - return '[ext.lastfm]' + return default_config - def validate_config(self, config): - pass + def get_config_schema(self): + schema = config.ExtensionConfigSchema() + schema['username'] = config.String() + schema['password'] = config.String(secret=True) + return schema def validate_environment(self): try: import pylast # noqa except ImportError as e: - raise ExtensionError('pylast library not found', e) + raise exceptions.ExtensionError('pylast library not found', e) def get_frontend_classes(self): from .actor import LastfmFrontend diff --git a/mopidy/frontends/mpd/__init__.py b/mopidy/frontends/mpd/__init__.py index 5cb8b8c0..dacbf69e 100644 --- a/mopidy/frontends/mpd/__init__.py +++ b/mopidy/frontends/mpd/__init__.py @@ -2,23 +2,60 @@ from __future__ import unicode_literals import mopidy from mopidy import ext +from mopidy.utils import config, formatting +default_config = """ +[ext.mpd] + +# If the MPD extension should be enabled or not +enabled = true + +# Which address the MPD server should bind to +# +# 127.0.0.1 +# Listens only on the IPv4 loopback interface +# ::1 +# Listens only on the IPv6 loopback interface +# 0.0.0.0 +# Listens on all IPv4 interfaces +# :: +# Listens on all interfaces, both IPv4 and IPv6 +hostname = 127.0.0.1 + +# Which TCP port the MPD server should listen to +port = 6600 + +# The password required for connecting to the MPD server +password = + +# The maximum number of concurrent connections the MPD server will accept +max_connections = 20 + +# Number of seconds an MPD client can stay inactive before the connection is +# closed by the server +connection_timeout = 60 +""" + __doc__ = """The MPD server frontend. MPD stands for Music Player Daemon. MPD is an independent project and server. Mopidy implements the MPD protocol, and is thus compatible with clients for the original MPD server. -**Dependencies:** +**Issues** -- None +https://github.com/mopidy/mopidy/issues?labels=MPD+frontend -**Settings:** +**Dependencies** -- :attr:`mopidy.settings.MPD_SERVER_HOSTNAME` -- :attr:`mopidy.settings.MPD_SERVER_PORT` -- :attr:`mopidy.settings.MPD_SERVER_PASSWORD` +None + +**Default config** + +.. code-block:: ini + +%(config)s **Usage:** @@ -46,7 +83,7 @@ near future: - ``tagtypes`` is not supported - Browsing the file system is not supported - Live update of the music database is not supported -""" +""" % {'config': formatting.indent(default_config)} class Extension(ext.Extension): @@ -55,10 +92,16 @@ class Extension(ext.Extension): version = mopidy.__version__ def get_default_config(self): - return '[ext.mpd]' + return default_config - def validate_config(self, config): - pass + def get_config_schema(self): + schema = config.ExtensionConfigSchema() + schema['hostname'] = config.Hostname() + schema['port'] = config.Port() + schema['password'] = config.String(optional=True, secret=True) + schema['max_connections'] = config.Integer(minimum=1) + schema['connection_timeout'] = config.Integer(minimum=1) + return schema def validate_environment(self): pass diff --git a/mopidy/frontends/mpris/__init__.py b/mopidy/frontends/mpris/__init__.py index 940c4210..407d4800 100644 --- a/mopidy/frontends/mpris/__init__.py +++ b/mopidy/frontends/mpris/__init__.py @@ -1,10 +1,20 @@ from __future__ import unicode_literals import mopidy -from mopidy import ext -from mopidy.exceptions import ExtensionError +from mopidy import exceptions, ext +from mopidy.utils import formatting, config +default_config = """ +[ext.mpris] + +# If the MPRIS extension should be enabled or not +enabled = true + +# Location of the Mopidy .desktop file +desktop_file = /usr/share/applications/mopidy.desktop +""" + __doc__ = """ Frontend which lets you control Mopidy through the Media Player Remote Interfacing Specification (`MPRIS `_) D-Bus @@ -13,7 +23,7 @@ interface. An example of an MPRIS client is the `Ubuntu Sound Menu `_. -**Dependencies:** +**Dependencies** - D-Bus Python bindings. The package is named ``python-dbus`` in Ubuntu/Debian. @@ -26,11 +36,13 @@ An example of an MPRIS client is the `Ubuntu Sound Menu :attr:`mopidy.settings.DESKTOP_FILE`. See :ref:`install-desktop-file` for details. -**Settings:** +**Default config** -- :attr:`mopidy.settings.DESKTOP_FILE` +.. code-block:: ini -**Usage:** +%(config)s + +**Usage** The frontend is enabled by default if all dependencies are available. @@ -53,7 +65,7 @@ Now you can control Mopidy through the player object. Examples: - To quit Mopidy through D-Bus, run:: player.Quit(dbus_interface='org.mpris.MediaPlayer2') -""" +""" % {'config': formatting.indent(default_config)} class Extension(ext.Extension): @@ -62,16 +74,18 @@ class Extension(ext.Extension): version = mopidy.__version__ def get_default_config(self): - return '[ext.mpris]' + return default_config - def validate_config(self, config): - pass + def get_config_schema(self): + schema = config.ExtensionConfigSchema() + schema['desktop_file'] = config.String() + return schema def validate_environment(self): try: import dbus # noqa except ImportError as e: - raise ExtensionError('Library dbus not found', e) + raise exceptions.ExtensionError('dbus library not found', e) def get_frontend_classes(self): from .actor import MprisFrontend