Merge branch 'develop' into feature/use-new-config
This commit is contained in:
commit
638ea8cd27
@ -55,9 +55,9 @@ class Extension(ext.Extension):
|
||||
|
||||
def get_config_schema(self):
|
||||
schema = config.ExtensionConfigSchema()
|
||||
schema['music_path'] = config.String()
|
||||
schema['playlist_path'] = config.String()
|
||||
schema['tag_cache_file'] = config.String()
|
||||
schema['music_path'] = config.Path()
|
||||
schema['playlist_path'] = config.Path()
|
||||
schema['tag_cache_file'] = config.Path()
|
||||
return schema
|
||||
|
||||
def validate_environment(self):
|
||||
|
||||
@ -75,7 +75,7 @@ class Extension(ext.Extension):
|
||||
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['cache_path'] = config.Path()
|
||||
return schema
|
||||
|
||||
def validate_environment(self):
|
||||
|
||||
@ -27,7 +27,7 @@ config_schemas = {} # TODO: use ordered dict?
|
||||
config_schemas['logging'] = config.ConfigSchema()
|
||||
config_schemas['logging']['console_format'] = config.String()
|
||||
config_schemas['logging']['debug_format'] = config.String()
|
||||
config_schemas['logging']['debug_file'] = config.String()
|
||||
config_schemas['logging']['debug_file'] = config.Path()
|
||||
|
||||
config_schemas['logging.levels'] = config.LogLevelConfigSchema()
|
||||
|
||||
|
||||
@ -31,7 +31,7 @@ port = 6680
|
||||
# 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 =
|
||||
static_path =
|
||||
|
||||
[logging.levels]
|
||||
cherrypy = warning
|
||||
@ -533,7 +533,7 @@ class Extension(ext.Extension):
|
||||
schema = config.ExtensionConfigSchema()
|
||||
schema['hostname'] = config.Hostname()
|
||||
schema['port'] = config.Port()
|
||||
schema['static_dir'] = config.String(optional=True)
|
||||
schema['static_path'] = config.Path(optional=True)
|
||||
return schema
|
||||
|
||||
def validate_environment(self):
|
||||
|
||||
@ -79,7 +79,7 @@ class Extension(ext.Extension):
|
||||
|
||||
def get_config_schema(self):
|
||||
schema = config.ExtensionConfigSchema()
|
||||
schema['desktop_file'] = config.String()
|
||||
schema['desktop_file'] = config.Path()
|
||||
return schema
|
||||
|
||||
def validate_environment(self):
|
||||
|
||||
@ -5,6 +5,7 @@ import re
|
||||
import socket
|
||||
|
||||
from mopidy import exceptions
|
||||
from mopidy.utils import path
|
||||
|
||||
|
||||
def validate_required(value, required):
|
||||
@ -126,7 +127,7 @@ class ConfigValue(object):
|
||||
class String(ConfigValue):
|
||||
"""String values.
|
||||
|
||||
Supports: optional choices and secret.
|
||||
Supports: optional, choices and secret.
|
||||
"""
|
||||
def deserialize(self, value):
|
||||
value = value.strip()
|
||||
@ -242,6 +243,34 @@ class Port(Integer):
|
||||
self.maximum = 2 ** 16 - 1
|
||||
|
||||
|
||||
class ExpandedPath(bytes):
|
||||
def __new__(self, value):
|
||||
expanded = path.expand_path(value)
|
||||
return super(ExpandedPath, self).__new__(self, expanded)
|
||||
|
||||
def __init__(self, value):
|
||||
self.original = value
|
||||
|
||||
|
||||
class Path(ConfigValue):
|
||||
"""File system path that will be expanded with mopidy.utils.path.expand_path
|
||||
|
||||
Supports: optional, choices and secret.
|
||||
"""
|
||||
def deserialize(self, value):
|
||||
value = value.strip()
|
||||
validate_required(value, not self.optional)
|
||||
validate_choice(value, self.choices)
|
||||
if not value:
|
||||
return None
|
||||
return ExpandedPath(value)
|
||||
|
||||
def serialize(self, value):
|
||||
if isinstance(value, ExpandedPath):
|
||||
return value.original
|
||||
return value
|
||||
|
||||
|
||||
class ConfigSchema(object):
|
||||
"""Logical group of config values that correspond to a config section.
|
||||
|
||||
@ -264,6 +293,8 @@ class ConfigSchema(object):
|
||||
return self._schema[key]
|
||||
|
||||
def format(self, name, values):
|
||||
# TODO: should the output be encoded utf-8 since we use that in
|
||||
# serialize for strings?
|
||||
lines = ['[%s]' % name]
|
||||
for key in self._order:
|
||||
value = values.get(key)
|
||||
|
||||
@ -298,6 +298,55 @@ class PortTest(unittest.TestCase):
|
||||
self.assertRaises(ValueError, value.deserialize, '')
|
||||
|
||||
|
||||
class ExpandedPathTest(unittest.TestCase):
|
||||
def test_is_bytes(self):
|
||||
self.assertIsInstance(config.ExpandedPath('/tmp'), bytes)
|
||||
|
||||
@mock.patch('mopidy.utils.path.expand_path')
|
||||
def test_defaults_to_expanded(self, expand_path_mock):
|
||||
expand_path_mock.return_value = 'expanded_path'
|
||||
self.assertEqual('expanded_path', config.ExpandedPath('~'))
|
||||
|
||||
@mock.patch('mopidy.utils.path.expand_path')
|
||||
def test_orginal_stores_unexpanded(self, expand_path_mock):
|
||||
self.assertEqual('~', config.ExpandedPath('~').original)
|
||||
|
||||
|
||||
class PathTest(unittest.TestCase):
|
||||
def test_deserialize_conversion_success(self):
|
||||
result = config.Path().deserialize('/foo')
|
||||
self.assertEqual('/foo', result)
|
||||
self.assertIsInstance(result, config.ExpandedPath)
|
||||
self.assertIsInstance(result, bytes)
|
||||
|
||||
def test_deserialize_enforces_choices(self):
|
||||
value = config.Path(choices=['/foo', '/bar', '/baz'])
|
||||
self.assertEqual('/foo', value.deserialize('/foo'))
|
||||
self.assertRaises(ValueError, value.deserialize, '/foobar')
|
||||
|
||||
def test_deserialize_enforces_required(self):
|
||||
value = config.Path()
|
||||
self.assertRaises(ValueError, value.deserialize, '')
|
||||
self.assertRaises(ValueError, value.deserialize, ' ')
|
||||
|
||||
def test_deserialize_respects_optional(self):
|
||||
value = config.Path(optional=True)
|
||||
self.assertIsNone(value.deserialize(''))
|
||||
self.assertIsNone(value.deserialize(' '))
|
||||
|
||||
@mock.patch('mopidy.utils.path.expand_path')
|
||||
def test_serialize_uses_original(self, expand_path_mock):
|
||||
expand_path_mock.return_value = 'expanded_path'
|
||||
path = config.ExpandedPath('original_path')
|
||||
value = config.Path()
|
||||
self.assertEqual('expanded_path', path)
|
||||
self.assertEqual('original_path', value.serialize(path))
|
||||
|
||||
def test_serialize_plain_string(self):
|
||||
value = config.Path()
|
||||
self.assertEqual('path', value.serialize('path'))
|
||||
|
||||
|
||||
class ConfigSchemaTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.schema = config.ConfigSchema()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user