From de80c33753bcd96804500748ae80865104ade8c4 Mon Sep 17 00:00:00 2001 From: Alexandre Petitjean Date: Mon, 29 Jul 2013 09:57:32 +0200 Subject: [PATCH 01/15] Add proxy/port to configuration --- mopidy/backends/spotify/session_manager.py | 7 ++++++- mopidy/config/__init__.py | 1 + mopidy/config/convert.py | 1 + mopidy/config/default.conf | 1 + mopidy/config/types.py | 8 ++++++-- 5 files changed, 15 insertions(+), 3 deletions(-) diff --git a/mopidy/backends/spotify/session_manager.py b/mopidy/backends/spotify/session_manager.py index 8f520896..3e8f1b67 100644 --- a/mopidy/backends/spotify/session_manager.py +++ b/mopidy/backends/spotify/session_manager.py @@ -33,9 +33,14 @@ class SpotifySessionManager(process.BaseThread, PyspotifySessionManager): self.cache_location = config['spotify']['cache_dir'] self.settings_location = config['spotify']['cache_dir'] + # Add proxy port only if available + full_proxy = config['proxy']['hostname'] + if 'port' in config['proxy']: + full_proxy = full_proxy + ':' + str(config['proxy']['port']) + PyspotifySessionManager.__init__( self, config['spotify']['username'], config['spotify']['password'], - proxy=config['proxy']['hostname'], + proxy=full_proxy, proxy_username=config['proxy']['username'], proxy_password=config['proxy']['password']) diff --git a/mopidy/config/__init__.py b/mopidy/config/__init__.py index e9ae7d86..7ccaa3f3 100644 --- a/mopidy/config/__init__.py +++ b/mopidy/config/__init__.py @@ -29,6 +29,7 @@ _proxy_schema = ConfigSchema('proxy') _proxy_schema['hostname'] = Hostname(optional=True) _proxy_schema['username'] = String(optional=True) _proxy_schema['password'] = Secret(optional=True) +_proxy_schema['port'] = Port(optional=True) # NOTE: if multiple outputs ever comes something like LogLevelConfigSchema #_outputs_schema = config.AudioOutputConfigSchema() diff --git a/mopidy/config/convert.py b/mopidy/config/convert.py index 6cb20fcd..3c3edb85 100644 --- a/mopidy/config/convert.py +++ b/mopidy/config/convert.py @@ -39,6 +39,7 @@ def convert(settings): helper('audio/output', 'OUTPUT') helper('proxy/hostname', 'SPOTIFY_PROXY_HOST') + helper('proxy/port', 'SPOTIFY_PROXY_PORT') helper('proxy/username', 'SPOTIFY_PROXY_USERNAME') helper('proxy/password', 'SPOTIFY_PROXY_PASSWORD') diff --git a/mopidy/config/default.conf b/mopidy/config/default.conf index b525ef47..204c789b 100644 --- a/mopidy/config/default.conf +++ b/mopidy/config/default.conf @@ -16,3 +16,4 @@ output = autoaudiosink hostname = username = password = +port = \ No newline at end of file diff --git a/mopidy/config/types.py b/mopidy/config/types.py index ec0be1de..3dff0908 100644 --- a/mopidy/config/types.py +++ b/mopidy/config/types.py @@ -117,7 +117,10 @@ class Integer(ConfigValue): self._choices = choices def deserialize(self, value): - value = int(value) + try: + value = int(value) + except: + value = 0 validators.validate_choice(value, self._choices) validators.validate_minimum(value, self._minimum) validators.validate_maximum(value, self._maximum) @@ -222,7 +225,8 @@ class Port(Integer): allocate a port for us. """ # TODO: consider probing if port is free or not? - def __init__(self, choices=None): + def __init__(self, choices=None, optional=False): + self._required = not optional super(Port, self).__init__( minimum=0, maximum=2 ** 16 - 1, choices=choices) From 05733cf844cb8f90eaf4174c05908eb6e6227daa Mon Sep 17 00:00:00 2001 From: Alexandre Petitjean Date: Mon, 29 Jul 2013 22:22:28 +0200 Subject: [PATCH 02/15] correct remarks from #481 --- mopidy/backends/spotify/session_manager.py | 10 ++++---- mopidy/config/__init__.py | 2 +- mopidy/config/default.conf | 2 +- mopidy/config/types.py | 27 +++++++++++++++++----- 4 files changed, 29 insertions(+), 12 deletions(-) diff --git a/mopidy/backends/spotify/session_manager.py b/mopidy/backends/spotify/session_manager.py index 3e8f1b67..dff29fad 100644 --- a/mopidy/backends/spotify/session_manager.py +++ b/mopidy/backends/spotify/session_manager.py @@ -33,10 +33,12 @@ class SpotifySessionManager(process.BaseThread, PyspotifySessionManager): self.cache_location = config['spotify']['cache_dir'] self.settings_location = config['spotify']['cache_dir'] - # Add proxy port only if available - full_proxy = config['proxy']['hostname'] - if 'port' in config['proxy']: - full_proxy = full_proxy + ':' + str(config['proxy']['port']) + full_proxy = '' + if config['proxy']['hostname']: + full_proxy = config['proxy']['hostname'] + # Add proxy port only if available + if config['proxy']['port']: + full_proxy = full_proxy + ':' + str(config['proxy']['port']) PyspotifySessionManager.__init__( self, config['spotify']['username'], config['spotify']['password'], diff --git a/mopidy/config/__init__.py b/mopidy/config/__init__.py index 7ccaa3f3..35a1d8e0 100644 --- a/mopidy/config/__init__.py +++ b/mopidy/config/__init__.py @@ -29,7 +29,7 @@ _proxy_schema = ConfigSchema('proxy') _proxy_schema['hostname'] = Hostname(optional=True) _proxy_schema['username'] = String(optional=True) _proxy_schema['password'] = Secret(optional=True) -_proxy_schema['port'] = Port(optional=True) +_proxy_schema['port'] = Port() # NOTE: if multiple outputs ever comes something like LogLevelConfigSchema #_outputs_schema = config.AudioOutputConfigSchema() diff --git a/mopidy/config/default.conf b/mopidy/config/default.conf index 204c789b..4a259c49 100644 --- a/mopidy/config/default.conf +++ b/mopidy/config/default.conf @@ -16,4 +16,4 @@ output = autoaudiosink hostname = username = password = -port = \ No newline at end of file +port = diff --git a/mopidy/config/types.py b/mopidy/config/types.py index 3dff0908..8309a591 100644 --- a/mopidy/config/types.py +++ b/mopidy/config/types.py @@ -117,10 +117,7 @@ class Integer(ConfigValue): self._choices = choices def deserialize(self, value): - try: - value = int(value) - except: - value = 0 + value = int(value) validators.validate_choice(value, self._choices) validators.validate_minimum(value, self._minimum) validators.validate_maximum(value, self._maximum) @@ -225,11 +222,29 @@ class Port(Integer): allocate a port for us. """ # TODO: consider probing if port is free or not? - def __init__(self, choices=None, optional=False): - self._required = not optional + def __init__(self, choices=None): super(Port, self).__init__( minimum=0, maximum=2 ** 16 - 1, choices=choices) + def deserialize(self, value): + # in case of no value is given, just return nothing + if not len(value): + return value + # now we can try to convert + try: + value = int(value) + except ValueError: + try: + value = socket.getservbyname(value, 'tcp') + except socket.error: + raise ValueError('must be a valid port number') + else: + validators.validate_choice(value, self._choices) + validators.validate_minimum(value, self._minimum) + validators.validate_maximum(value, self._maximum) + return value + + class Path(ConfigValue): """File system path From f9da3fe3e922a8a8df1f893769b8f645952d74c2 Mon Sep 17 00:00:00 2001 From: Alexandre Petitjean Date: Tue, 30 Jul 2013 08:17:10 +0200 Subject: [PATCH 03/15] implement remarks for #481, also add scheme as requested in #472 --- mopidy/backends/spotify/session_manager.py | 6 ++++-- mopidy/config/__init__.py | 4 +++- mopidy/config/default.conf | 3 ++- mopidy/config/types.py | 1 - 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/mopidy/backends/spotify/session_manager.py b/mopidy/backends/spotify/session_manager.py index dff29fad..130164fb 100644 --- a/mopidy/backends/spotify/session_manager.py +++ b/mopidy/backends/spotify/session_manager.py @@ -36,9 +36,11 @@ class SpotifySessionManager(process.BaseThread, PyspotifySessionManager): full_proxy = '' if config['proxy']['hostname']: full_proxy = config['proxy']['hostname'] - # Add proxy port only if available + # Add proxy port and scheme only if available if config['proxy']['port']: - full_proxy = full_proxy + ':' + str(config['proxy']['port']) + full_proxy += ':' + str(config['proxy']['port']) + if config['proxy']['scheme']: + full_proxy = config['proxy']['scheme'] + "://" + full_proxy PyspotifySessionManager.__init__( self, config['spotify']['username'], config['spotify']['password'], diff --git a/mopidy/config/__init__.py b/mopidy/config/__init__.py index 35a1d8e0..582a1a03 100644 --- a/mopidy/config/__init__.py +++ b/mopidy/config/__init__.py @@ -26,10 +26,12 @@ _audio_schema['mixer_track'] = String(optional=True) _audio_schema['output'] = String() _proxy_schema = ConfigSchema('proxy') +_proxy_schema['scheme'] = String(optional=True, + choices=['', 'https', 'socks4', 'socks5']) _proxy_schema['hostname'] = Hostname(optional=True) +_proxy_schema['port'] = Port() _proxy_schema['username'] = String(optional=True) _proxy_schema['password'] = Secret(optional=True) -_proxy_schema['port'] = Port() # NOTE: if multiple outputs ever comes something like LogLevelConfigSchema #_outputs_schema = config.AudioOutputConfigSchema() diff --git a/mopidy/config/default.conf b/mopidy/config/default.conf index 4a259c49..8d2101fb 100644 --- a/mopidy/config/default.conf +++ b/mopidy/config/default.conf @@ -13,7 +13,8 @@ mixer_track = output = autoaudiosink [proxy] +scheme = hostname = +port = username = password = -port = diff --git a/mopidy/config/types.py b/mopidy/config/types.py index 8309a591..ba8b8f2a 100644 --- a/mopidy/config/types.py +++ b/mopidy/config/types.py @@ -245,7 +245,6 @@ class Port(Integer): return value - class Path(ConfigValue): """File system path From bb3242d15aef348ddc3df2605c80bb136cfcd854 Mon Sep 17 00:00:00 2001 From: Alexandre Petitjean Date: Tue, 30 Jul 2013 08:37:24 +0200 Subject: [PATCH 04/15] correct default port config for proxy and deserialize function --- mopidy/config/default.conf | 2 +- mopidy/config/types.py | 12 ++++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/mopidy/config/default.conf b/mopidy/config/default.conf index 8d2101fb..d241323a 100644 --- a/mopidy/config/default.conf +++ b/mopidy/config/default.conf @@ -15,6 +15,6 @@ output = autoaudiosink [proxy] scheme = hostname = -port = +port = http username = password = diff --git a/mopidy/config/types.py b/mopidy/config/types.py index ba8b8f2a..8715c8da 100644 --- a/mopidy/config/types.py +++ b/mopidy/config/types.py @@ -227,10 +227,6 @@ class Port(Integer): minimum=0, maximum=2 ** 16 - 1, choices=choices) def deserialize(self, value): - # in case of no value is given, just return nothing - if not len(value): - return value - # now we can try to convert try: value = int(value) except ValueError: @@ -238,10 +234,10 @@ class Port(Integer): value = socket.getservbyname(value, 'tcp') except socket.error: raise ValueError('must be a valid port number') - else: - validators.validate_choice(value, self._choices) - validators.validate_minimum(value, self._minimum) - validators.validate_maximum(value, self._maximum) + + validators.validate_choice(value, self._choices) + validators.validate_minimum(value, self._minimum) + validators.validate_maximum(value, self._maximum) return value From 4f310f51fc7262317886921402a969de517293a2 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Tue, 30 Jul 2013 23:21:08 +0200 Subject: [PATCH 05/15] Change docs license to Apache License, Version 2.0 I've looked through all contributions to the docs. Any contributions not by Thomas Adamcik or myself are trivial (e.g. typo fixes) or have mostly been replaced by later changes. Thus I'm comfortable with changing the license with the agreement of Thomas Adamcik. By changing the documentation license to be the same as the source code license, we avoid ambiguities around the license of e.g. docstrings which are written as part of the source code but are included in the generated docs. --- docs/conf.py | 2 +- docs/index.rst | 2 +- docs/license.rst | 10 ++++++++++ docs/licenses.rst | 34 ---------------------------------- 4 files changed, 12 insertions(+), 36 deletions(-) create mode 100644 docs/license.rst delete mode 100644 docs/licenses.rst diff --git a/docs/conf.py b/docs/conf.py index c0dba916..f3e4166c 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -101,7 +101,7 @@ master_doc = 'index' # General information about the project. project = 'Mopidy' -copyright = '2010-2013, Stein Magnus Jodal and contributors' +copyright = '2009-2013, Stein Magnus Jodal and contributors' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the diff --git a/docs/index.rst b/docs/index.rst index fb91244d..ca40c96c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -48,7 +48,7 @@ About :maxdepth: 1 authors - licenses + license changelog versioning diff --git a/docs/license.rst b/docs/license.rst new file mode 100644 index 00000000..98928f63 --- /dev/null +++ b/docs/license.rst @@ -0,0 +1,10 @@ +******* +License +******* + +Mopidy is copyright 2009-2013 Stein Magnus Jodal and contributors. For a list +of contributors, see :doc:`authors`. For details on who have contributed what, +please refer to our git repository. + +Mopidy is licensed under the `Apache License, Version 2.0 +`_. diff --git a/docs/licenses.rst b/docs/licenses.rst deleted file mode 100644 index fc2530e5..00000000 --- a/docs/licenses.rst +++ /dev/null @@ -1,34 +0,0 @@ -******** -Licenses -******** - -For a list of contributors, see :doc:`authors`. For details on who have -contributed what, please refer to our git repository. - -Source code license -=================== - -Copyright 2009-2013 Stein Magnus Jodal and contributors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - - -Documentation license -===================== - -Copyright 2010-2013 Stein Magnus Jodal and contributors - -This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 -Unported License. To view a copy of this license, visit -http://creativecommons.org/licenses/by-sa/3.0/ or send a letter to Creative -Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA. From 786d7c1ae0adcc5b0e0652ab767256777393706d Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Tue, 30 Jul 2013 23:21:08 +0200 Subject: [PATCH 06/15] Change docs license to Apache License, Version 2.0 I've looked through all contributions to the docs. Any contributions not by Thomas Adamcik or myself are trivial (e.g. typo fixes) or have mostly been replaced by later changes. Thus I'm comfortable with changing the license with the agreement of Thomas Adamcik. By changing the documentation license to be the same as the source code license, we avoid ambiguities around the license of e.g. docstrings which are written as part of the source code but are included in the generated docs. --- docs/conf.py | 2 +- docs/index.rst | 2 +- docs/license.rst | 10 ++++++++++ docs/licenses.rst | 34 ---------------------------------- 4 files changed, 12 insertions(+), 36 deletions(-) create mode 100644 docs/license.rst delete mode 100644 docs/licenses.rst diff --git a/docs/conf.py b/docs/conf.py index c0dba916..f3e4166c 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -101,7 +101,7 @@ master_doc = 'index' # General information about the project. project = 'Mopidy' -copyright = '2010-2013, Stein Magnus Jodal and contributors' +copyright = '2009-2013, Stein Magnus Jodal and contributors' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the diff --git a/docs/index.rst b/docs/index.rst index fb91244d..ca40c96c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -48,7 +48,7 @@ About :maxdepth: 1 authors - licenses + license changelog versioning diff --git a/docs/license.rst b/docs/license.rst new file mode 100644 index 00000000..98928f63 --- /dev/null +++ b/docs/license.rst @@ -0,0 +1,10 @@ +******* +License +******* + +Mopidy is copyright 2009-2013 Stein Magnus Jodal and contributors. For a list +of contributors, see :doc:`authors`. For details on who have contributed what, +please refer to our git repository. + +Mopidy is licensed under the `Apache License, Version 2.0 +`_. diff --git a/docs/licenses.rst b/docs/licenses.rst deleted file mode 100644 index fc2530e5..00000000 --- a/docs/licenses.rst +++ /dev/null @@ -1,34 +0,0 @@ -******** -Licenses -******** - -For a list of contributors, see :doc:`authors`. For details on who have -contributed what, please refer to our git repository. - -Source code license -=================== - -Copyright 2009-2013 Stein Magnus Jodal and contributors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - - -Documentation license -===================== - -Copyright 2010-2013 Stein Magnus Jodal and contributors - -This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 -Unported License. To view a copy of this license, visit -http://creativecommons.org/licenses/by-sa/3.0/ or send a letter to Creative -Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA. From 97848bc1a2bf80896680ad45bac9933e3f782d83 Mon Sep 17 00:00:00 2001 From: Alexandre Petitjean Date: Wed, 31 Jul 2013 10:05:20 +0200 Subject: [PATCH 07/15] String config value can be optionnal AND have a choices list Integer value can be optionnal --- mopidy/backends/spotify/session_manager.py | 1 - mopidy/config/__init__.py | 4 ++-- mopidy/config/default.conf | 2 +- mopidy/config/types.py | 26 +++++++--------------- 4 files changed, 11 insertions(+), 22 deletions(-) diff --git a/mopidy/backends/spotify/session_manager.py b/mopidy/backends/spotify/session_manager.py index 130164fb..125b6ada 100644 --- a/mopidy/backends/spotify/session_manager.py +++ b/mopidy/backends/spotify/session_manager.py @@ -36,7 +36,6 @@ class SpotifySessionManager(process.BaseThread, PyspotifySessionManager): full_proxy = '' if config['proxy']['hostname']: full_proxy = config['proxy']['hostname'] - # Add proxy port and scheme only if available if config['proxy']['port']: full_proxy += ':' + str(config['proxy']['port']) if config['proxy']['scheme']: diff --git a/mopidy/config/__init__.py b/mopidy/config/__init__.py index 582a1a03..dfdae6a7 100644 --- a/mopidy/config/__init__.py +++ b/mopidy/config/__init__.py @@ -27,9 +27,9 @@ _audio_schema['output'] = String() _proxy_schema = ConfigSchema('proxy') _proxy_schema['scheme'] = String(optional=True, - choices=['', 'https', 'socks4', 'socks5']) + choices=['http', 'https', 'socks4', 'socks5']) _proxy_schema['hostname'] = Hostname(optional=True) -_proxy_schema['port'] = Port() +_proxy_schema['port'] = Port(optional=True) _proxy_schema['username'] = String(optional=True) _proxy_schema['password'] = Secret(optional=True) diff --git a/mopidy/config/default.conf b/mopidy/config/default.conf index d241323a..3899c2c5 100644 --- a/mopidy/config/default.conf +++ b/mopidy/config/default.conf @@ -15,6 +15,6 @@ output = autoaudiosink [proxy] scheme = hostname = -port = http +port = username = password = diff --git a/mopidy/config/types.py b/mopidy/config/types.py index 8715c8da..29651940 100644 --- a/mopidy/config/types.py +++ b/mopidy/config/types.py @@ -71,9 +71,9 @@ class String(ConfigValue): def deserialize(self, value): value = decode(value).strip() validators.validate_required(value, self._required) - validators.validate_choice(value, self._choices) if not value: return None + validators.validate_choice(value, self._choices) return value def serialize(self, value, display=False): @@ -111,12 +111,16 @@ class Secret(ConfigValue): class Integer(ConfigValue): """Integer value.""" - def __init__(self, minimum=None, maximum=None, choices=None): + def __init__(self, minimum=None, maximum=None, choices=None, optional=False): + self._required = not optional self._minimum = minimum self._maximum = maximum self._choices = choices def deserialize(self, value): + validators.validate_required(value, self._required) + if not value: + return None value = int(value) validators.validate_choice(value, self._choices) validators.validate_minimum(value, self._minimum) @@ -222,23 +226,9 @@ class Port(Integer): allocate a port for us. """ # TODO: consider probing if port is free or not? - def __init__(self, choices=None): + def __init__(self, choices=None, optional=False): super(Port, self).__init__( - minimum=0, maximum=2 ** 16 - 1, choices=choices) - - def deserialize(self, value): - try: - value = int(value) - except ValueError: - try: - value = socket.getservbyname(value, 'tcp') - except socket.error: - raise ValueError('must be a valid port number') - - validators.validate_choice(value, self._choices) - validators.validate_minimum(value, self._minimum) - validators.validate_maximum(value, self._maximum) - return value + minimum=0, maximum=2 ** 16 - 1, choices=choices, optional=optional) class Path(ConfigValue): From c66e2a5b0fce548a653bab26245da38f84c52da0 Mon Sep 17 00:00:00 2001 From: Alexandre Petitjean Date: Wed, 31 Jul 2013 23:11:29 +0200 Subject: [PATCH 08/15] add some tests about optionnal integer and optionnal+choices string --- tests/config/types_test.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/config/types_test.py b/tests/config/types_test.py index 88c8f067..d915b4f2 100644 --- a/tests/config/types_test.py +++ b/tests/config/types_test.py @@ -98,6 +98,11 @@ class StringTest(unittest.TestCase): self.assertIsInstance(result, bytes) self.assertEqual(b'', result) + def test_deserialize_enforces_choices_optionnal(self): + value = types.String(optional=True, choices=['foo', 'bar', 'baz']) + self.assertEqual(None, value.deserialize(b'')) + self.assertRaises(ValueError, value.deserialize, b'foobar') + class SecretTest(unittest.TestCase): def test_deserialize_passes_through(self): @@ -163,6 +168,10 @@ class IntegerTest(unittest.TestCase): self.assertEqual(5, value.deserialize('5')) self.assertRaises(ValueError, value.deserialize, '15') + def test_deserialize_respects_optional(self): + value = types.Integer(optional=True) + self.assertEqual(None, value.deserialize('')) + class BooleanTest(unittest.TestCase): def test_deserialize_conversion_success(self): From 20729eabe309083c05e78074d75a802f6c4efe47 Mon Sep 17 00:00:00 2001 From: Thomas Adamcik Date: Sun, 2 Jun 2013 15:56:25 +0200 Subject: [PATCH 09/15] audio: Add visualiser support and adjust playbin flags Sets up playbin to use just audio, soft_volume and downloading. --- mopidy/audio/actor.py | 34 +++++++++++++++++++++++++++++++--- mopidy/config/__init__.py | 1 + mopidy/config/default.conf | 1 + 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/mopidy/audio/actor.py b/mopidy/audio/actor.py index af0a0c68..d78df9b7 100644 --- a/mopidy/audio/actor.py +++ b/mopidy/audio/actor.py @@ -22,6 +22,22 @@ mixers.register_mixers() MB = 1 << 20 +# GST_PLAY_FLAG_VIDEO (1<<0) +# GST_PLAY_FLAG_AUDIO (1<<1) +# GST_PLAY_FLAG_TEXT (1<<2) +# GST_PLAY_FLAG_VIS (1<<3) +# GST_PLAY_FLAG_SOFT_VOLUME (1<<4) +# GST_PLAY_FLAG_NATIVE_AUDIO (1<<5) +# GST_PLAY_FLAG_NATIVE_VIDEO (1<<6) +# GST_PLAY_FLAG_DOWNLOAD (1<<7) +# GST_PLAY_FLAG_BUFFERING (1<<8) +# GST_PLAY_FLAG_DEINTERLACE (1<<9) +# GST_PLAY_FLAG_SOFT_COLORBALANCE (1<<10) + +# Default flags to use for playbin: AUDIO, SOFT_VOLUME, DOWNLOAD +PLAYBIN_FLAGS = (1<<1) | (1<<4) | (1<<7) +PLAYBIN_VIS_FLAGS = PLAYBIN_FLAGS | (1<<3) + class Audio(pykka.ThreadingActor): """ @@ -55,6 +71,7 @@ class Audio(pykka.ThreadingActor): try: self._setup_playbin() self._setup_output() + self._setup_visualizer() self._setup_mixer() self._setup_message_processor() except gobject.GError as ex: @@ -78,9 +95,7 @@ class Audio(pykka.ThreadingActor): def _setup_playbin(self): playbin = gst.element_factory_make('playbin2') - - fakesink = gst.element_factory_make('fakesink') - playbin.set_property('video-sink', fakesink) + playbin.set_property('flags', PLAYBIN_FLAGS) self._connect(playbin, 'about-to-finish', self._on_about_to_finish) self._connect(playbin, 'notify::source', self._on_new_source) @@ -149,6 +164,19 @@ class Audio(pykka.ThreadingActor): 'Failed to create audio output "%s": %s', output_desc, ex) process.exit_process() + def _setup_visualizer(self): + visualizer_element = self._config['audio']['visualizer'] + if not visualizer_element: + return + try: + visualizer = gst.element_factory_make(visualizer_element) + self._playbin.set_property('vis-plugin', visualizer) + self._playbin.set_property('flags', PLAYBIN_VIS_FLAGS) + logger.info('Audio visualizer set to "%s"', visualizer_element) + except gobject.GError as ex: + logger.error( + 'Failed to create audio visualizer "%s": %s', visualizer_element, ex) + def _setup_mixer(self): mixer_desc = self._config['audio']['mixer'] track_desc = self._config['audio']['mixer_track'] diff --git a/mopidy/config/__init__.py b/mopidy/config/__init__.py index e9ae7d86..60e8cb49 100644 --- a/mopidy/config/__init__.py +++ b/mopidy/config/__init__.py @@ -24,6 +24,7 @@ _audio_schema = ConfigSchema('audio') _audio_schema['mixer'] = String() _audio_schema['mixer_track'] = String(optional=True) _audio_schema['output'] = String() +_audio_schema['visualizer'] = String(optional=True) _proxy_schema = ConfigSchema('proxy') _proxy_schema['hostname'] = Hostname(optional=True) diff --git a/mopidy/config/default.conf b/mopidy/config/default.conf index b525ef47..d4bc0daf 100644 --- a/mopidy/config/default.conf +++ b/mopidy/config/default.conf @@ -11,6 +11,7 @@ pykka = info mixer = autoaudiomixer mixer_track = output = autoaudiosink +visualizer = [proxy] hostname = From a4d2f28ade7adfb0883878d88dc4c8387840f8eb Mon Sep 17 00:00:00 2001 From: Thomas Adamcik Date: Thu, 1 Aug 2013 01:09:01 +0200 Subject: [PATCH 10/15] audio: Fix tests with respect to visualizer support --- tests/audio/actor_test.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/audio/actor_test.py b/tests/audio/actor_test.py index c311bdc3..617131cc 100644 --- a/tests/audio/actor_test.py +++ b/tests/audio/actor_test.py @@ -21,6 +21,7 @@ class AudioTest(unittest.TestCase): 'mixer': 'fakemixer track_max_volume=65536', 'mixer_track': None, 'output': 'fakesink', + 'visualizer': None, } } self.song_uri = path_to_uri(path_to_data_dir('song1.wav')) @@ -70,6 +71,7 @@ class AudioTest(unittest.TestCase): 'mixer': 'fakemixer track_max_volume=40', 'mixer_track': None, 'output': 'fakesink', + 'visualizer': None, } } self.audio = audio.Audio.start(config=config).proxy() From c5c2d10455d924f7cb8130bb0f7c517e8df00dd1 Mon Sep 17 00:00:00 2001 From: Thomas Adamcik Date: Thu, 1 Aug 2013 01:53:07 +0200 Subject: [PATCH 11/15] audio: Update changelog and docs for visualizer. --- docs/changelog.rst | 5 +++++ docs/config.rst | 10 ++++++++++ 2 files changed, 15 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index a8c9dee6..8c88e8c1 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -33,6 +33,11 @@ v0.15.0 (UNRELEASED) hierarchy from your Spotify account is available in Mopidy. (Fixes: :issue:`62`) +**Audio** + +- Added support for viusalization. :confval:`audio/visualizer` can now be set + to GStreamer visualizers. + v0.14.2 (2013-07-01) ==================== diff --git a/docs/config.rst b/docs/config.rst index 9f997b23..6fd7579d 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -90,6 +90,16 @@ Core configuration values ``gst-inspect-0.10`` to see what output properties can be set on the sink. For example: ``gst-inspect-0.10 shout2send`` +.. confval:: audio/visualizer + + Visualizer to use. + + Can be left blank if no visualizer is desired. Otherwise this expects a + GStreamer visualizer. Typical values are ``monoscope``, ``goom``, + ``goom2k1`` or one of the `libvisual`_ visualizers. + +.. _libvisual: http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-plugin-libvisual.html + .. confval:: logging/console_format The log format used for informational logging. From da86015a2b400e2be0fb27838527faeb4d202ad9 Mon Sep 17 00:00:00 2001 From: AlexandreP2101 Date: Thu, 1 Aug 2013 08:47:22 +0200 Subject: [PATCH 12/15] Correct typo --- tests/config/types_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/config/types_test.py b/tests/config/types_test.py index d915b4f2..74e9672d 100644 --- a/tests/config/types_test.py +++ b/tests/config/types_test.py @@ -98,7 +98,7 @@ class StringTest(unittest.TestCase): self.assertIsInstance(result, bytes) self.assertEqual(b'', result) - def test_deserialize_enforces_choices_optionnal(self): + def test_deserialize_enforces_choices_optional(self): value = types.String(optional=True, choices=['foo', 'bar', 'baz']) self.assertEqual(None, value.deserialize(b'')) self.assertRaises(ValueError, value.deserialize, b'foobar') From e637eb90416154a3bf43cb05a8db9d0ec84ff452 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Fri, 2 Aug 2013 00:01:45 +0200 Subject: [PATCH 13/15] docs: Update changelog, authors --- .mailmap | 2 ++ AUTHORS | 1 + docs/changelog.rst | 3 +++ 3 files changed, 6 insertions(+) diff --git a/.mailmap b/.mailmap index b38c3f66..7098b6d4 100644 --- a/.mailmap +++ b/.mailmap @@ -5,3 +5,5 @@ Kristian Klette Johannes Knutsen Johannes Knutsen John Bäckstrand +Alexandre Petitjean +Alexandre Petitjean diff --git a/AUTHORS b/AUTHORS index 1e3faf0e..ddb1602e 100644 --- a/AUTHORS +++ b/AUTHORS @@ -22,3 +22,4 @@ - Janez Troha - Tobias Sauerwein - alzeih +- Alexandre Petitjean diff --git a/docs/changelog.rst b/docs/changelog.rst index a8c9dee6..c2c121d5 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -33,6 +33,9 @@ v0.15.0 (UNRELEASED) hierarchy from your Spotify account is available in Mopidy. (Fixes: :issue:`62`) +- Fix proxy config values that was broken with the config system change in + 0.14. (Fixes: :issue:`472`) + v0.14.2 (2013-07-01) ==================== From dc7289ba8303a3c759053d5f72dda986d3ae88fc Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Sun, 4 Aug 2013 11:22:36 +0200 Subject: [PATCH 14/15] docs: Fix formatting of code examples in lists --- js/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/js/README.md b/js/README.md index 0e5e17c9..793e9f9d 100644 --- a/js/README.md +++ b/js/README.md @@ -51,15 +51,15 @@ Building from source 1. Install [Node.js](http://nodejs.org/) and npm. There is a PPA if you're running Ubuntu: - sudo apt-get install python-software-properties - sudo add-apt-repository ppa:chris-lea/node.js - sudo apt-get update - sudo apt-get install nodejs npm + sudo apt-get install python-software-properties + sudo add-apt-repository ppa:chris-lea/node.js + sudo apt-get update + sudo apt-get install nodejs npm 2. Enter the `js/` in Mopidy's Git repo dir and install all dependencies: - cd js/ - npm install + cd js/ + npm install That's it. From 95c8077135a9b80cbbb291fe3c8cbe062b1a9b73 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Sun, 4 Aug 2013 11:24:00 +0200 Subject: [PATCH 15/15] docs: nodejs deb now includes npm --- js/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/README.md b/js/README.md index 793e9f9d..eddfa99f 100644 --- a/js/README.md +++ b/js/README.md @@ -54,7 +54,7 @@ Building from source sudo apt-get install python-software-properties sudo add-apt-repository ppa:chris-lea/node.js sudo apt-get update - sudo apt-get install nodejs npm + sudo apt-get install nodejs 2. Enter the `js/` in Mopidy's Git repo dir and install all dependencies: