diff --git a/platypush/__init__.py b/platypush/__init__.py index c3ca5a87..7b0c3b89 100644 --- a/platypush/__init__.py +++ b/platypush/__init__.py @@ -7,8 +7,9 @@ from threading import Thread from .bus import Bus from .config import Config +from .context import register_backends from .event.processor import EventProcessor -from .utils import get_or_load_plugin, init_backends, get_module_and_name_from_action +from .utils import get_or_load_plugin, get_module_and_name_from_action from .message.event import Event, StopEvent from .message.request import Request from .message.response import Response @@ -105,7 +106,7 @@ class Daemon(object): self.bus = Bus(on_message=self.on_message()) # Initialize the backends and link them to the bus - self.backends = init_backends(bus=self.bus) + self.backends = register_backends(bus=self.bus) # Start the backend threads for backend in self.backends.values(): diff --git a/platypush/backend/assistant/google/__init__.py b/platypush/backend/assistant/google/__init__.py index fcb2cd40..d8b43f50 100644 --- a/platypush/backend/assistant/google/__init__.py +++ b/platypush/backend/assistant/google/__init__.py @@ -47,6 +47,10 @@ class AssistantGoogleBackend(Backend): self.bus.post(SpeechRecognizedEvent(phrase=phrase)) + def stop_conversation(self): + if self.assistant: self.assistant.stop_conversation() + + def send_message(self, msg): # Can't send a message on an event source, ignoring # TODO Make a class for event sources like these. Event sources @@ -58,6 +62,7 @@ class AssistantGoogleBackend(Backend): super().run() with Assistant(self.credentials) as assistant: + self.assistant = assistant for event in assistant.start(): self._process_event(event) diff --git a/platypush/context/__init__.py b/platypush/context/__init__.py new file mode 100644 index 00000000..756f393a --- /dev/null +++ b/platypush/context/__init__.py @@ -0,0 +1,51 @@ +import importlib +import functools + +from ..config import Config + +# Map: backend_name -> backend_instance +backends = {} + +# Map: plugin_name -> plugin_instance +plugins = {} + +def register_backends(bus=None, **kwargs): + """ Initialize the backend objects based on the configuration and returns + a name -> backend_instance map. + Params: + bus -- If specific (it usually should), the messages processed by the + backends will be posted on this bus. + + kwargs -- Any additional key-value parameters required to initialize the backends + """ + + global backends + + for (name, cfg) in Config.get_backends().items(): + module = importlib.import_module('platypush.backend.' + name) + + # e.g. backend.pushbullet main class: PushbulletBackend + cls_name = functools.reduce( + lambda a,b: a.title() + b.title(), + (module.__name__.title().split('.')[2:]) + ) + 'Backend' + + try: + b = getattr(module, cls_name)(bus=bus, **cfg, **kwargs) + backends[name] = b + except AttributeError as e: + logging.warning('No such class in {}: {}'.format( + module.__name__, cls_name)) + raise RuntimeError(e) + + return backends + +def get_backend(name): + """ Returns the backend instance identified by name if it exists """ + + global backends + return backends[name] + + +# vim:sw=4:ts=4:et: + diff --git a/platypush/message/event/assistant/__init__.py b/platypush/message/event/assistant/__init__.py index c9613929..4d00ff46 100644 --- a/platypush/message/event/assistant/__init__.py +++ b/platypush/message/event/assistant/__init__.py @@ -1,5 +1,6 @@ import re +from platypush.context import get_backend from platypush.message.event import Event class AssistantEvent(Event): @@ -7,6 +8,7 @@ class AssistantEvent(Event): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + self._assistant = get_backend('assistant.google') class ConversationStartEvent(AssistantEvent): @@ -49,7 +51,10 @@ class SpeechRecognizedEvent(AssistantEvent): else: recognized_tokens.pop(0) - return [len(condition_tokens) == 0, parsed_args] + is_match = len(condition_tokens) == 0 + if is_match and self._assistant: self._assistant.stop_conversation() + + return [is_match, parsed_args] # vim:sw=4:ts=4:et: diff --git a/platypush/pusher/__init__.py b/platypush/pusher/__init__.py index f3cdbf03..0f62aaba 100644 --- a/platypush/pusher/__init__.py +++ b/platypush/pusher/__init__.py @@ -5,8 +5,8 @@ import sys from platypush.bus import Bus from platypush.config import Config +from platypush.context import register_backends from platypush.message.request import Request -from platypush.utils import init_backends class Pusher(object): @@ -97,7 +97,7 @@ class Pusher(object): def get_backend(self, name): # Lazy init if not self.backends: - self.backends = init_backends(bus=self.bus) + self.backends = register_backends(bus=self.bus) if name not in self.backends: raise RuntimeError('No such backend configured: {}'.format(name)) diff --git a/platypush/utils/__init__.py b/platypush/utils/__init__.py index b2f253f4..45683d8d 100644 --- a/platypush/utils/__init__.py +++ b/platypush/utils/__init__.py @@ -42,38 +42,6 @@ def get_or_load_plugin(plugin_name, reload=False): return plugin -def init_backends(bus=None, **kwargs): - """ Initialize the backend objects based on the configuration and returns - a name -> backend_instance map. - Params: - bus -- If specific (it usually should), the messages processed by the - backends will be posted on this bus. - - kwargs -- Any additional key-value parameters required to initialize the backends - """ - - backends = {} - - for k in Config.get_backends().keys(): - module = importlib.import_module('platypush.backend.' + k) - cfg = Config.get_backends()[k] - - # e.g. backend.pushbullet main class: PushbulletBackend - cls_name = functools.reduce( - lambda a,b: a.title() + b.title(), - (module.__name__.title().split('.')[2:]) - ) + 'Backend' - - try: - b = getattr(module, cls_name)(bus=bus, **cfg, **kwargs) - backends[k] = b - except AttributeError as e: - logging.warning('No such class in {}: {}'.format( - module.__name__, cls_name)) - raise RuntimeError(e) - - return backends - def get_module_and_name_from_action(action): """ Input : action=music.mpd.play Output : ('music.mpd', 'play') """