From b94890a1c77f2e1f3c3a3bdf785c000137678207 Mon Sep 17 00:00:00 2001 From: Thomas Adamcik Date: Mon, 15 Apr 2013 00:29:52 +0200 Subject: [PATCH 1/6] config: Start work on mopidy-convert-config --- mopidy/config/convert.py | 98 ++++++++++++++++++++++++++++++++++++++++ setup.py | 1 + 2 files changed, 99 insertions(+) create mode 100644 mopidy/config/convert.py diff --git a/mopidy/config/convert.py b/mopidy/config/convert.py new file mode 100644 index 00000000..5fb4a733 --- /dev/null +++ b/mopidy/config/convert.py @@ -0,0 +1,98 @@ +from __future__ import unicode_literals + +from mopidy.utils import path + + +def load(): + settings_file = path.expand_path('$XDG_CONFIG_DIR/mopidy/settings.py') + print 'Checking %s' % settings_file + + setting_globals = {} + try: + execfile(settings_file, setting_globals) + except Exception as e: + print 'Problem loading settings: %s' % e + return setting_globals + + +def convert(settings): + config = {} + + def helper(confval, setting_name): + if settings.get(setting_name) is not None: + section, key = confval.split('/') + config.setdefault(section, {})[key] = settings[setting_name] + + # Perform all the simple mappings using our helper: + + helper('logging/console_format', 'CONSOLE_LOG_FORMAT') + helper('logging/debug_format', 'DEBUG_LOG_FORMAT') + helper('logging/debug_file', 'DEBUG_LOG_FILENAME') + + helper('audio/mixer', 'MIXER') + helper('audio/mixer_track', 'MIXER_TRACK') + helper('audio/output', 'OUTPUT') + + helper('proxy/hostname', 'SPOTIFY_PROXY_HOST') + helper('proxy/username', 'SPOTIFY_PROXY_USERNAME') + helper('proxy/password', 'SPOTIFY_PROXY_PASSWORD') + + helper('local/media_dir', 'LOCAL_MUSIC_PATH') + helper('local/playlists_dir', 'LOCAL_PLAYLIST_PATH') + helper('local/tag_cache_file', 'LOCAL_TAG_CACHE_FILE') + + helper('spotify/username', 'SPOTIFY_USERNAME') + helper('spotify/password', 'SPOTIFY_PASSWORD') + helper('spotify/bitrate', 'SPOTIFY_BITRATE') + helper('spotify/timeout', 'SPOTIFY_TIMEOUT') + helper('spotify/cache_dir', 'SPOTIFY_CACHE_PATH') + + helper('stream/protocols', 'STREAM_PROTOCOLS') + + helper('http/hostname', 'HTTP_SERVER_HOSTNAME') + helper('http/port', 'HTTP_SERVER_PORT') + helper('http/static_dir', 'HTTP_SERVER_STATIC_DIR') + + helper('mpd/hostname', 'MPD_SERVER_HOSTNAME') + helper('mpd/port', 'MPD_SERVER_PORT') + helper('mpd/password', 'MPD_SERVER_PASSWORD') + helper('mpd/max_connections', 'MPD_SERVER_MAX_CONNECTIONS') + helper('mpd/connection_timeout', 'MPD_SERVER_CONNECTION_TIMEOUT') + + helper('mpris/desktop_file', 'DESKTOP_FILE') + + helper('scrobbler/username', 'LASTFM_USERNAME') + helper('scrobbler/password', 'LASTFM_PASSWORD') + + # Assume FRONTENDS/BACKENDS = None implies all enabled, otherwise disable + # if our module path is missing from the setting. + + frontends = settings.get('FRONTENDS') + if frontends is not None: + if 'mopidy.frontends.http.HttpFrontend' not in frontends: + config.setdefault('http', {})['enabled'] = False + if 'mopidy.frontends.mpd.MpdFrontend' not in frontends: + config.setdefault('mpd', {})['enabled'] = False + if 'mopidy.frontends.lastfm.LastfmFrontend' not in frontends: + config.setdefault('scrobbler', {})['enabled'] = False + if 'mopidy.frontends.mpris.MprisFrontend' not in frontends: + config.setdefault('mpris', {})['enabled'] = False + + backends = settings.get('BACKENDS') + if backends is not None: + if 'mopidy.backends.local.LocalBackend' not in backends: + config.setdefault('local', {})['enabled'] = False + if 'mopidy.backends.spotify.SpotifyBackend' not in backends: + config.setdefault('spotify', {})['enabled'] = False + if 'mopidy.backends.stream.StreamBackend' not in backends: + config.setdefault('stream', {})['enabled'] = False + + return config + + +def main(): + settings = load() + if not settings: + return + + config = convert(settings) diff --git a/setup.py b/setup.py index 6b7b2a6f..bd1a5f75 100644 --- a/setup.py +++ b/setup.py @@ -42,6 +42,7 @@ setup( 'console_scripts': [ 'mopidy = mopidy.__main__:main', 'mopidy-scan = mopidy.scanner:main', + 'mopidy-convert-config = mopidy.config.convert:main', ], 'mopidy.ext': [ 'http = mopidy.frontends.http:Extension [http]', From 14a09643a01bba237560ffc2af3244e0fb999ded Mon Sep 17 00:00:00 2001 From: Thomas Adamcik Date: Tue, 16 Apr 2013 23:29:56 +0200 Subject: [PATCH 2/6] config: Avoid adding empty sections --- mopidy/config/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mopidy/config/__init__.py b/mopidy/config/__init__.py index 6438f975..c836e906 100644 --- a/mopidy/config/__init__.py +++ b/mopidy/config/__init__.py @@ -111,6 +111,8 @@ def _format(config, comments, schemas, display): output = [] for schema in schemas: serialized = schema.serialize(config.get(schema.name, {}), display=display) + if not serialized: + continue output.append(b'[%s]' % schema.name) for key, value in serialized.items(): comment = comments.get(schema.name, {}).get(key, b'') From df9d635db868cc891b54a888ea42302d4e474240 Mon Sep 17 00:00:00 2001 From: Thomas Adamcik Date: Tue, 16 Apr 2013 23:32:01 +0200 Subject: [PATCH 3/6] config: Print converted settings --- mopidy/config/convert.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mopidy/config/convert.py b/mopidy/config/convert.py index 5fb4a733..90297dc8 100644 --- a/mopidy/config/convert.py +++ b/mopidy/config/convert.py @@ -1,5 +1,6 @@ from __future__ import unicode_literals +from mopidy import config as config_lib, ext from mopidy.utils import path @@ -96,3 +97,10 @@ def main(): return config = convert(settings) + + known = [ + 'spotify', 'scrobbler', 'mpd', 'mpris', 'local', 'stream', 'http'] + extensions = [e for e in ext.load_extensions() if e.ext_name in known] + + print b'Converted config:\n' + print config_lib.format(config, extensions) From 10f06322393f8d88d87fd97d0996fde4e5e71362 Mon Sep 17 00:00:00 2001 From: Thomas Adamcik Date: Tue, 16 Apr 2013 23:50:48 +0200 Subject: [PATCH 4/6] config: Encode any unicode passwords if found --- mopidy/config/types.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mopidy/config/types.py b/mopidy/config/types.py index f8614efd..29c41ae2 100644 --- a/mopidy/config/types.py +++ b/mopidy/config/types.py @@ -100,6 +100,8 @@ class Secret(ConfigValue): return value def serialize(self, value, display=False): + if isinstance(value, unicode): + value = value.encode('utf-8') if value is None: return b'' elif display: From c35dfb3610b14c1b1240781fbff4ca6f996d98b9 Mon Sep 17 00:00:00 2001 From: Thomas Adamcik Date: Tue, 16 Apr 2013 23:51:21 +0200 Subject: [PATCH 5/6] config: Ensure format only produces bytes --- mopidy/config/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mopidy/config/__init__.py b/mopidy/config/__init__.py index c836e906..3cbc92b3 100644 --- a/mopidy/config/__init__.py +++ b/mopidy/config/__init__.py @@ -113,10 +113,10 @@ def _format(config, comments, schemas, display): serialized = schema.serialize(config.get(schema.name, {}), display=display) if not serialized: continue - output.append(b'[%s]' % schema.name) + output.append(b'[%s]' % bytes(schema.name)) for key, value in serialized.items(): - comment = comments.get(schema.name, {}).get(key, b'') - output.append(b'%s =' % key) + comment = bytes(comments.get(schema.name, {}).get(key, '')) + output.append(b'%s =' % bytes(key)) if value is not None: output[-1] += b' ' + value if comment: From b8b578e107e4100c974a38802afbdda19c360f97 Mon Sep 17 00:00:00 2001 From: Thomas Adamcik Date: Tue, 16 Apr 2013 23:51:52 +0200 Subject: [PATCH 6/6] config: Add basic saving to convert config --- mopidy/config/convert.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/mopidy/config/convert.py b/mopidy/config/convert.py index 90297dc8..f292e302 100644 --- a/mopidy/config/convert.py +++ b/mopidy/config/convert.py @@ -1,5 +1,9 @@ from __future__ import unicode_literals +import io +import os.path +import sys + from mopidy import config as config_lib, ext from mopidy.utils import path @@ -104,3 +108,18 @@ def main(): print b'Converted config:\n' print config_lib.format(config, extensions) + + conf_file = path.expand_path('$XDG_CONFIG_DIR/mopidy/mopidy.conf') + if os.path.exists(conf_file): + print '%s exists, exiting.' % conf_file + sys.exit(1) + + print 'Write new config to %s? [yN]' % conf_file, + if raw_input() != 'y': + print 'Not saving, exiting.' + sys.exit(0) + + serialized_config = config_lib.format(config, extensions, display=False) + with io.open(conf_file, 'wb') as filehandle: + filehandle.write(serialized_config) + print 'Done.'