Merge branch 'develop' into feature/use-new-config

This commit is contained in:
Stein Magnus Jodal 2013-04-08 09:59:36 +02:00
commit 638ea8cd27
7 changed files with 89 additions and 9 deletions

View File

@ -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):

View File

@ -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):

View File

@ -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()

View File

@ -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):

View File

@ -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):

View File

@ -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)

View File

@ -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()