Empty utils/__init__.py
This commit is contained in:
parent
bc531d987e
commit
5a0529b142
@ -29,10 +29,9 @@ sys.path.insert(
|
|||||||
|
|
||||||
|
|
||||||
import mopidy
|
import mopidy
|
||||||
from mopidy import audio, core, exceptions, settings, utils
|
from mopidy import audio, core, exceptions, settings
|
||||||
from mopidy.utils import log, path, process
|
from mopidy.utils import (
|
||||||
from mopidy.utils.deps import list_deps_optparse_callback
|
deps, importing, log, path, process, settings as settings_utils)
|
||||||
from mopidy.utils.settings import list_settings_optparse_callback
|
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger('mopidy.main')
|
logger = logging.getLogger('mopidy.main')
|
||||||
@ -90,11 +89,12 @@ def parse_options():
|
|||||||
help='save debug log to "./mopidy.log"')
|
help='save debug log to "./mopidy.log"')
|
||||||
parser.add_option(
|
parser.add_option(
|
||||||
'--list-settings',
|
'--list-settings',
|
||||||
action='callback', callback=list_settings_optparse_callback,
|
action='callback',
|
||||||
|
callback=settings_utils.list_settings_optparse_callback,
|
||||||
help='list current settings')
|
help='list current settings')
|
||||||
parser.add_option(
|
parser.add_option(
|
||||||
'--list-deps',
|
'--list-deps',
|
||||||
action='callback', callback=list_deps_optparse_callback,
|
action='callback', callback=deps.list_deps_optparse_callback,
|
||||||
help='list dependencies and their versions')
|
help='list dependencies and their versions')
|
||||||
return parser.parse_args(args=mopidy_args)[0]
|
return parser.parse_args(args=mopidy_args)[0]
|
||||||
|
|
||||||
@ -131,11 +131,11 @@ def stop_audio():
|
|||||||
|
|
||||||
|
|
||||||
def setup_backend(audio):
|
def setup_backend(audio):
|
||||||
return utils.get_class(settings.BACKENDS[0]).start(audio=audio).proxy()
|
return importing.get_class(settings.BACKENDS[0]).start(audio=audio).proxy()
|
||||||
|
|
||||||
|
|
||||||
def stop_backend():
|
def stop_backend():
|
||||||
process.stop_actors_by_class(utils.get_class(settings.BACKENDS[0]))
|
process.stop_actors_by_class(importing.get_class(settings.BACKENDS[0]))
|
||||||
|
|
||||||
|
|
||||||
def setup_core(audio, backend):
|
def setup_core(audio, backend):
|
||||||
@ -149,7 +149,7 @@ def stop_core():
|
|||||||
def setup_frontends(core):
|
def setup_frontends(core):
|
||||||
for frontend_class_name in settings.FRONTENDS:
|
for frontend_class_name in settings.FRONTENDS:
|
||||||
try:
|
try:
|
||||||
utils.get_class(frontend_class_name).start(core=core)
|
importing.get_class(frontend_class_name).start(core=core)
|
||||||
except exceptions.OptionalDependencyError as ex:
|
except exceptions.OptionalDependencyError as ex:
|
||||||
logger.info(u'Disabled: %s (%s)', frontend_class_name, ex)
|
logger.info(u'Disabled: %s (%s)', frontend_class_name, ex)
|
||||||
|
|
||||||
@ -157,7 +157,8 @@ def setup_frontends(core):
|
|||||||
def stop_frontends():
|
def stop_frontends():
|
||||||
for frontend_class_name in settings.FRONTENDS:
|
for frontend_class_name in settings.FRONTENDS:
|
||||||
try:
|
try:
|
||||||
process.stop_actors_by_class(utils.get_class(frontend_class_name))
|
frontend_class = importing.get_class(frontend_class_name)
|
||||||
|
process.stop_actors_by_class(frontend_class)
|
||||||
except exceptions.OptionalDependencyError:
|
except exceptions.OptionalDependencyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import logging
|
|||||||
|
|
||||||
from pykka.actor import ThreadingActor
|
from pykka.actor import ThreadingActor
|
||||||
|
|
||||||
from mopidy import settings, utils
|
from mopidy import settings
|
||||||
from mopidy.utils import process
|
from mopidy.utils import process
|
||||||
|
|
||||||
from . import mixers
|
from . import mixers
|
||||||
@ -320,7 +320,7 @@ class Audio(ThreadingActor):
|
|||||||
new_scale = (0, 100)
|
new_scale = (0, 100)
|
||||||
old_scale = (
|
old_scale = (
|
||||||
self._mixer_track.min_volume, self._mixer_track.max_volume)
|
self._mixer_track.min_volume, self._mixer_track.max_volume)
|
||||||
return utils.rescale(avg_volume, old=old_scale, new=new_scale)
|
return self._rescale(avg_volume, old=old_scale, new=new_scale)
|
||||||
|
|
||||||
def set_volume(self, volume):
|
def set_volume(self, volume):
|
||||||
"""
|
"""
|
||||||
@ -341,13 +341,20 @@ class Audio(ThreadingActor):
|
|||||||
new_scale = (
|
new_scale = (
|
||||||
self._mixer_track.min_volume, self._mixer_track.max_volume)
|
self._mixer_track.min_volume, self._mixer_track.max_volume)
|
||||||
|
|
||||||
volume = utils.rescale(volume, old=old_scale, new=new_scale)
|
volume = self._rescale(volume, old=old_scale, new=new_scale)
|
||||||
|
|
||||||
volumes = (volume,) * self._mixer_track.num_channels
|
volumes = (volume,) * self._mixer_track.num_channels
|
||||||
self._mixer.set_volume(self._mixer_track, volumes)
|
self._mixer.set_volume(self._mixer_track, volumes)
|
||||||
|
|
||||||
return self._mixer.get_volume(self._mixer_track) == volumes
|
return self._mixer.get_volume(self._mixer_track) == volumes
|
||||||
|
|
||||||
|
def _rescale(self, value, old=None, new=None):
|
||||||
|
"""Convert value between scales."""
|
||||||
|
new_min, new_max = new
|
||||||
|
old_min, old_max = old
|
||||||
|
scaling = float(new_max - new_min) / (old_max - old_min)
|
||||||
|
return round(scaling * (value - old_min) + new_min)
|
||||||
|
|
||||||
def set_metadata(self, track):
|
def set_metadata(self, track):
|
||||||
"""
|
"""
|
||||||
Set track metadata for currently playing song.
|
Set track metadata for currently playing song.
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import logging
|
|||||||
logger = logging.getLogger('mopidy.backends.local.translator')
|
logger = logging.getLogger('mopidy.backends.local.translator')
|
||||||
|
|
||||||
from mopidy.models import Track, Artist, Album
|
from mopidy.models import Track, Artist, Album
|
||||||
from mopidy.utils import locale_decode
|
from mopidy.utils.encoding import locale_decode
|
||||||
from mopidy.utils.path import path_to_uri
|
from mopidy.utils.path import path_to_uri
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@ from pykka import registry, actor
|
|||||||
|
|
||||||
from mopidy import core, settings
|
from mopidy import core, settings
|
||||||
from mopidy.frontends.mpd import session
|
from mopidy.frontends.mpd import session
|
||||||
from mopidy.utils import locale_decode, network, process
|
from mopidy.utils import encoding, network, process
|
||||||
|
|
||||||
logger = logging.getLogger('mopidy.frontends.mpd')
|
logger = logging.getLogger('mopidy.frontends.mpd')
|
||||||
|
|
||||||
@ -37,7 +37,8 @@ class MpdFrontend(actor.ThreadingActor, core.CoreListener):
|
|||||||
max_connections=settings.MPD_SERVER_MAX_CONNECTIONS)
|
max_connections=settings.MPD_SERVER_MAX_CONNECTIONS)
|
||||||
except IOError as error:
|
except IOError as error:
|
||||||
logger.error(
|
logger.error(
|
||||||
u'MPD server startup failed: %s', locale_decode(error))
|
u'MPD server startup failed: %s',
|
||||||
|
encoding.locale_decode(error))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
logger.info(u'MPD server running at [%s]:%s', hostname, port)
|
logger.info(u'MPD server running at [%s]:%s', hostname, port)
|
||||||
|
|||||||
@ -5,7 +5,6 @@ from pykka import ActorDeadError
|
|||||||
|
|
||||||
from mopidy import settings
|
from mopidy import settings
|
||||||
from mopidy.frontends.mpd import exceptions, protocol
|
from mopidy.frontends.mpd import exceptions, protocol
|
||||||
from mopidy.utils import flatten
|
|
||||||
|
|
||||||
logger = logging.getLogger('mopidy.frontends.mpd.dispatcher')
|
logger = logging.getLogger('mopidy.frontends.mpd.dispatcher')
|
||||||
|
|
||||||
@ -187,10 +186,19 @@ class MpdDispatcher(object):
|
|||||||
if result is None:
|
if result is None:
|
||||||
return []
|
return []
|
||||||
if isinstance(result, set):
|
if isinstance(result, set):
|
||||||
return flatten(list(result))
|
return self._flatten(list(result))
|
||||||
if not isinstance(result, list):
|
if not isinstance(result, list):
|
||||||
return [result]
|
return [result]
|
||||||
return flatten(result)
|
return self._flatten(result)
|
||||||
|
|
||||||
|
def _flatten(self, the_list):
|
||||||
|
result = []
|
||||||
|
for element in the_list:
|
||||||
|
if isinstance(element, list):
|
||||||
|
result.extend(self._flatten(element))
|
||||||
|
else:
|
||||||
|
result.append(element)
|
||||||
|
return result
|
||||||
|
|
||||||
def _format_lines(self, line):
|
def _format_lines(self, line):
|
||||||
if isinstance(line, dict):
|
if isinstance(line, dict):
|
||||||
|
|||||||
@ -1,52 +0,0 @@
|
|||||||
from __future__ import division
|
|
||||||
|
|
||||||
import locale
|
|
||||||
import logging
|
|
||||||
import sys
|
|
||||||
|
|
||||||
logger = logging.getLogger('mopidy.utils')
|
|
||||||
|
|
||||||
|
|
||||||
# TODO: use itertools.chain.from_iterable(the_list)?
|
|
||||||
def flatten(the_list):
|
|
||||||
result = []
|
|
||||||
for element in the_list:
|
|
||||||
if isinstance(element, list):
|
|
||||||
result.extend(flatten(element))
|
|
||||||
else:
|
|
||||||
result.append(element)
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def rescale(v, old=None, new=None):
|
|
||||||
"""Convert value between scales."""
|
|
||||||
new_min, new_max = new
|
|
||||||
old_min, old_max = old
|
|
||||||
scaling = float(new_max - new_min) / (old_max - old_min)
|
|
||||||
return round(scaling * (v - old_min) + new_min)
|
|
||||||
|
|
||||||
|
|
||||||
def import_module(name):
|
|
||||||
__import__(name)
|
|
||||||
return sys.modules[name]
|
|
||||||
|
|
||||||
|
|
||||||
def get_class(name):
|
|
||||||
logger.debug('Loading: %s', name)
|
|
||||||
if '.' not in name:
|
|
||||||
raise ImportError("Couldn't load: %s" % name)
|
|
||||||
module_name = name[:name.rindex('.')]
|
|
||||||
cls_name = name[name.rindex('.') + 1:]
|
|
||||||
try:
|
|
||||||
module = import_module(module_name)
|
|
||||||
cls = getattr(module, cls_name)
|
|
||||||
except (ImportError, AttributeError):
|
|
||||||
raise ImportError("Couldn't load: %s" % name)
|
|
||||||
return cls
|
|
||||||
|
|
||||||
|
|
||||||
def locale_decode(bytestr):
|
|
||||||
try:
|
|
||||||
return unicode(bytestr)
|
|
||||||
except UnicodeError:
|
|
||||||
return str(bytestr).decode(locale.getpreferredencoding())
|
|
||||||
8
mopidy/utils/encoding.py
Normal file
8
mopidy/utils/encoding.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import locale
|
||||||
|
|
||||||
|
|
||||||
|
def locale_decode(bytestr):
|
||||||
|
try:
|
||||||
|
return unicode(bytestr)
|
||||||
|
except UnicodeError:
|
||||||
|
return str(bytestr).decode(locale.getpreferredencoding())
|
||||||
23
mopidy/utils/importing.py
Normal file
23
mopidy/utils/importing.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import logging
|
||||||
|
import sys
|
||||||
|
|
||||||
|
logger = logging.getLogger('mopidy.utils')
|
||||||
|
|
||||||
|
|
||||||
|
def import_module(name):
|
||||||
|
__import__(name)
|
||||||
|
return sys.modules[name]
|
||||||
|
|
||||||
|
|
||||||
|
def get_class(name):
|
||||||
|
logger.debug('Loading: %s', name)
|
||||||
|
if '.' not in name:
|
||||||
|
raise ImportError("Couldn't load: %s" % name)
|
||||||
|
module_name = name[:name.rindex('.')]
|
||||||
|
cls_name = name[name.rindex('.') + 1:]
|
||||||
|
try:
|
||||||
|
module = import_module(module_name)
|
||||||
|
cls = getattr(module, cls_name)
|
||||||
|
except (ImportError, AttributeError):
|
||||||
|
raise ImportError("Couldn't load: %s" % name)
|
||||||
|
return cls
|
||||||
@ -9,7 +9,7 @@ from pykka import ActorDeadError
|
|||||||
from pykka.actor import ThreadingActor
|
from pykka.actor import ThreadingActor
|
||||||
from pykka.registry import ActorRegistry
|
from pykka.registry import ActorRegistry
|
||||||
|
|
||||||
from mopidy.utils import locale_decode
|
from mopidy.utils import encoding
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger('mopidy.utils.server')
|
logger = logging.getLogger('mopidy.utils.server')
|
||||||
@ -30,7 +30,7 @@ def try_ipv6_socket():
|
|||||||
logger.debug(
|
logger.debug(
|
||||||
u'Platform supports IPv6, but socket creation failed, '
|
u'Platform supports IPv6, but socket creation failed, '
|
||||||
u'disabling: %s',
|
u'disabling: %s',
|
||||||
locale_decode(error))
|
encoding.locale_decode(error))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import mock
|
import mock
|
||||||
|
|
||||||
from mopidy.utils import locale_decode
|
from mopidy.utils.encoding import locale_decode
|
||||||
|
|
||||||
from tests import unittest
|
from tests import unittest
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('mopidy.utils.locale.getpreferredencoding')
|
@mock.patch('mopidy.utils.encoding.locale.getpreferredencoding')
|
||||||
class LocaleDecodeTest(unittest.TestCase):
|
class LocaleDecodeTest(unittest.TestCase):
|
||||||
def test_can_decode_utf8_strings_with_french_content(self, mock):
|
def test_can_decode_utf8_strings_with_french_content(self, mock):
|
||||||
mock.return_value = 'UTF-8'
|
mock.return_value = 'UTF-8'
|
||||||
@ -1,4 +1,4 @@
|
|||||||
from mopidy import utils
|
from mopidy.utils import importing
|
||||||
|
|
||||||
from tests import unittest
|
from tests import unittest
|
||||||
|
|
||||||
@ -6,22 +6,22 @@ from tests import unittest
|
|||||||
class GetClassTest(unittest.TestCase):
|
class GetClassTest(unittest.TestCase):
|
||||||
def test_loading_module_that_does_not_exist(self):
|
def test_loading_module_that_does_not_exist(self):
|
||||||
with self.assertRaises(ImportError):
|
with self.assertRaises(ImportError):
|
||||||
utils.get_class('foo.bar.Baz')
|
importing.get_class('foo.bar.Baz')
|
||||||
|
|
||||||
def test_loading_class_that_does_not_exist(self):
|
def test_loading_class_that_does_not_exist(self):
|
||||||
with self.assertRaises(ImportError):
|
with self.assertRaises(ImportError):
|
||||||
utils.get_class('unittest.FooBarBaz')
|
importing.get_class('unittest.FooBarBaz')
|
||||||
|
|
||||||
def test_loading_incorrect_class_path(self):
|
def test_loading_incorrect_class_path(self):
|
||||||
with self.assertRaises(ImportError):
|
with self.assertRaises(ImportError):
|
||||||
utils.get_class('foobarbaz')
|
importing.get_class('foobarbaz')
|
||||||
|
|
||||||
def test_import_error_message_contains_complete_class_path(self):
|
def test_import_error_message_contains_complete_class_path(self):
|
||||||
try:
|
try:
|
||||||
utils.get_class('foo.bar.Baz')
|
importing.get_class('foo.bar.Baz')
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
self.assertIn('foo.bar.Baz', str(e))
|
self.assertIn('foo.bar.Baz', str(e))
|
||||||
|
|
||||||
def test_loading_existing_class(self):
|
def test_loading_existing_class(self):
|
||||||
cls = utils.get_class('unittest.TestCase')
|
cls = importing.get_class('unittest.TestCase')
|
||||||
self.assertEqual(cls.__name__, 'TestCase')
|
self.assertEqual(cls.__name__, 'TestCase')
|
||||||
Loading…
Reference in New Issue
Block a user