ext: Add basic global registry and switch to Extension.setup()

This commit is contained in:
Thomas Adamcik 2013-12-07 01:00:55 +01:00
parent 0d7fea0a43
commit decce4ccf6
4 changed files with 59 additions and 38 deletions

View File

@ -84,7 +84,6 @@ def main():
enabled_extensions.append(extension)
log_extension_info(installed_extensions, enabled_extensions)
ext.register_gstreamer_elements(enabled_extensions)
# Config and deps commands are simply special cased for now.
if args.command == config_cmd:
@ -108,16 +107,13 @@ def main():
args.extension.ext_name)
return 1
registry = {'backends': [], 'frontends': [], 'local:library': []}
for extension in enabled_extensions:
registry['backends'].extend(extension.get_backend_classes())
registry['frontends'].extend(extension.get_frontend_classes())
registry['local:library'].extend(extension.get_library_updaters())
extension.setup()
# Anything that wants to exit after this point must use
# mopidy.utils.process.exit_process as actors can have been started.
try:
return args.command.run(args, proxied_config, registry)
return args.command.run(args, proxied_config)
except NotImplementedError:
print root_cmd.format_help()
return 1

View File

@ -4,7 +4,7 @@ import logging
import os
import time
from mopidy import commands, exceptions
from mopidy import commands, exceptions, ext
from mopidy.audio import scan
from mopidy.utils import path
@ -22,14 +22,15 @@ class LocalCommand(commands.Command):
class ScanCommand(commands.Command):
help = "Scan local media files and populate the local library."
def run(self, args, config, registry):
def run(self, args, config):
media_dir = config['local']['media_dir']
scan_timeout = config['local']['scan_timeout']
excluded_file_extensions = config['local']['excluded_file_extensions']
excluded_file_extensions = set(
ext.lower() for ext in config['local']['excluded_file_extensions'])
file_ext.lower() for file_ext in excluded_file_extensions)
# TODO: select updater / library to use by name
updaters = registry['local:library']
updaters = ext.registry['local:library']
if not updaters:
logger.error('No usable library updaters found.')
return 1

View File

@ -9,7 +9,7 @@ import sys
import glib
import gobject
from mopidy import config as config_lib
from mopidy import config as config_lib, ext
from mopidy.audio import Audio
from mopidy.core import Core
from mopidy.utils import deps, process, versioning
@ -257,22 +257,26 @@ class RootCommand(Command):
type=config_override_type, metavar='OPTIONS',
help='`section/key=value` values to override config options')
def run(self, args, config, registry):
def run(self, args, config):
loop = gobject.MainLoop()
backend_classes = ext.registry['backend']
frontend_classes = ext.registry['frontend']
try:
audio = self.start_audio(config)
backends = self.start_backends(config, registry, audio)
backends = self.start_backends(config, backend_classes, audio)
core = self.start_core(audio, backends)
self.start_frontends(config, registry, core)
self.start_frontends(config, frontend_classes, core)
loop.run()
except KeyboardInterrupt:
logger.info('Interrupted. Exiting...')
return
finally:
loop.quit()
self.stop_frontends(registry)
self.stop_frontends(frontend_classes)
self.stop_core()
self.stop_backends(registry)
self.stop_backends(backend_classes)
self.stop_audio()
process.stop_remaining_actors()
@ -280,9 +284,7 @@ class RootCommand(Command):
logger.info('Starting Mopidy audio')
return Audio.start(config=config).proxy()
def start_backends(self, config, registry, audio):
backend_classes = registry['backends']
def start_backends(self, config, backend_classes, audio):
logger.info(
'Starting Mopidy backends: %s',
', '.join(b.__name__ for b in backend_classes) or 'none')
@ -298,9 +300,7 @@ class RootCommand(Command):
logger.info('Starting Mopidy core')
return Core.start(audio=audio, backends=backends).proxy()
def start_frontends(self, config, registry, core):
frontend_classes = registry['frontends']
def start_frontends(self, config, frontend_classes, core):
logger.info(
'Starting Mopidy frontends: %s',
', '.join(f.__name__ for f in frontend_classes) or 'none')
@ -308,18 +308,18 @@ class RootCommand(Command):
for frontend_class in frontend_classes:
frontend_class.start(config=config, core=core)
def stop_frontends(self, registry):
def stop_frontends(self, frontend_classes):
logger.info('Stopping Mopidy frontends')
for frontend_class in registry['frontends']:
for frontend_class in frontend_classes:
process.stop_actors_by_class(frontend_class)
def stop_core(self):
logger.info('Stopping Mopidy core')
process.stop_actors_by_class(Core)
def stop_backends(self, registry):
def stop_backends(self, backend_classes):
logger.info('Stopping Mopidy backends')
for backend_class in registry['backends']:
for backend_class in backend_classes:
process.stop_actors_by_class(backend_class)
def stop_audio(self):

View File

@ -1,5 +1,6 @@
from __future__ import unicode_literals
import collections
import logging
import pkg_resources
@ -61,6 +62,18 @@ class Extension(object):
"""
pass
def setup(self):
for backend_class in self.get_backend_classes():
registry.add('backend', backend_class)
for frontend_class in self.get_frontend_classes():
registry.add('frontend', frontend_class)
for library_updater in self.get_library_updaters():
registry.add('local:library', library_updater)
self.register_gstreamer_elements()
def get_frontend_classes(self):
"""List of frontend actor classes
@ -112,6 +125,29 @@ class Extension(object):
pass
class _Registry(collections.Mapping):
def __init__(self):
self._registry = collections.defaultdict(list)
def add(self, name, cls):
self._registry[name].append(cls)
def __getitem__(self, name):
return self._registry[name]
def __iter__(self):
return iter(self._registry)
def __len__(self):
return len(self._registry)
# TODO: document the registry
# TODO: consider if we should avoid having this as a global and pass an
# instance from __main__ around instead?
registry = _Registry()
def load_extensions():
"""Find all installed extensions.
@ -166,15 +202,3 @@ def validate_extension(extension):
return False
return True
def register_gstreamer_elements(enabled_extensions):
"""Registers custom GStreamer elements from extensions.
:param enabled_extensions: list of enabled extensions
"""
for extension in enabled_extensions:
logger.debug(
'Registering GStreamer elements for: %s', extension.ext_name)
extension.register_gstreamer_elements()