Added code for handling procedures - solves #1
This commit is contained in:
parent
6e019865bc
commit
617c0f8a07
5 changed files with 79 additions and 16 deletions
|
@ -9,10 +9,10 @@ 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, get_module_and_name_from_action
|
||||
from .message.event import Event, StopEvent
|
||||
from .message.request import Request
|
||||
from .message.response import Response
|
||||
from .procedure import Procedure
|
||||
|
||||
__author__ = 'Fabio Manganiello <blacklight86@gmail.com>'
|
||||
__version__ = '0.6'
|
||||
|
@ -75,9 +75,15 @@ class Daemon(object):
|
|||
msg -- platypush.message.Message instance """
|
||||
|
||||
if isinstance(msg, Request):
|
||||
if msg.action.startswith('procedure.'):
|
||||
logging.info('Executing procedure request: {}'.format(msg))
|
||||
proc_name = msg.action.split('.')[-1]
|
||||
proc_config = Config.get_procedures()[proc_name]
|
||||
msg = Procedure.build(name=proc_name, requests=proc_config, backend=msg.backend, id=msg.id)
|
||||
else:
|
||||
logging.info('Processing request: {}'.format(msg))
|
||||
msg.execute(n_tries=self.n_tries)
|
||||
|
||||
msg.execute(n_tries=self.n_tries)
|
||||
self.processed_requests += 1
|
||||
if self.requests_to_process \
|
||||
and self.processed_requests >= self.requests_to_process:
|
||||
|
|
|
@ -62,14 +62,14 @@ class Config(object):
|
|||
if 'device_id' not in self._config:
|
||||
self._config['device_id'] = socket.gethostname()
|
||||
|
||||
self.backends = {}
|
||||
self.plugins = {}
|
||||
self.event_hooks = {}
|
||||
self.procedures = {}
|
||||
self._init_components()
|
||||
|
||||
|
||||
def _init_components(self):
|
||||
self.backends = {}
|
||||
self.plugins = {}
|
||||
self.event_hooks = {}
|
||||
|
||||
for key in self._config.keys():
|
||||
if key.startswith('backend.'):
|
||||
backend_name = '.'.join(key.split('.')[1:])
|
||||
|
@ -77,6 +77,9 @@ class Config(object):
|
|||
elif key.startswith('event.hook.'):
|
||||
hook_name = '.'.join(key.split('.')[2:])
|
||||
self.event_hooks[hook_name] = self._config[key]
|
||||
elif key.startswith('procedure.'):
|
||||
procedure_name = '.'.join(key.split('.')[1:])
|
||||
self.procedures[procedure_name] = self._config[key]
|
||||
else:
|
||||
self.plugins[key] = self._config[key]
|
||||
|
||||
|
@ -98,6 +101,12 @@ class Config(object):
|
|||
if _default_config_instance is None: _default_config_instance = Config()
|
||||
return _default_config_instance.event_hooks
|
||||
|
||||
@staticmethod
|
||||
def get_procedures():
|
||||
global _default_config_instance
|
||||
if _default_config_instance is None: _default_config_instance = Config()
|
||||
return _default_config_instance.procedures
|
||||
|
||||
@staticmethod
|
||||
def get_default_pusher_backend():
|
||||
"""
|
||||
|
|
|
@ -5,22 +5,21 @@ import traceback
|
|||
|
||||
from threading import Thread
|
||||
|
||||
from threading import Thread
|
||||
|
||||
from platypush.message import Message
|
||||
from platypush.message.response import Response
|
||||
from platypush.utils import get_or_load_plugin, get_module_and_name_from_action
|
||||
from platypush.utils import get_or_load_plugin, get_module_and_method_from_action
|
||||
|
||||
class Request(Message):
|
||||
""" Request message class """
|
||||
|
||||
def __init__(self, target, action, origin=None, id=None, args={}):
|
||||
def __init__(self, target, action, origin=None, id=None, backend=None, args={}):
|
||||
"""
|
||||
Params:
|
||||
target -- Target node [String]
|
||||
action -- Action to be executed (e.g. music.mpd.play) [String]
|
||||
origin -- Origin node [String]
|
||||
id -- Message ID, or None to get it auto-generated
|
||||
backend -- Backend connected to the request, where the response will be delivered
|
||||
args -- Additional arguments for the action [Dict]
|
||||
"""
|
||||
|
||||
|
@ -29,7 +28,7 @@ class Request(Message):
|
|||
self.action = action
|
||||
self.origin = origin
|
||||
self.args = args
|
||||
self.backend = None
|
||||
self.backend = backend
|
||||
|
||||
@classmethod
|
||||
def build(cls, msg):
|
||||
|
@ -58,7 +57,7 @@ class Request(Message):
|
|||
n_tries -- Number of tries in case of failure before raising a RuntimeError
|
||||
"""
|
||||
def _thread_func(n_tries):
|
||||
(module_name, method_name) = get_module_and_name_from_action(self.action)
|
||||
(module_name, method_name) = get_module_and_method_from_action(self.action)
|
||||
|
||||
plugin = get_or_load_plugin(module_name)
|
||||
|
||||
|
|
50
platypush/procedure/__init__.py
Normal file
50
platypush/procedure/__init__.py
Normal file
|
@ -0,0 +1,50 @@
|
|||
import logging
|
||||
|
||||
from ..config import Config
|
||||
from ..message.request import Request
|
||||
|
||||
class Procedure(object):
|
||||
""" Procedure class. A procedure is a pre-configured list of requests """
|
||||
|
||||
def __init__(self, name, requests, backend=None):
|
||||
"""
|
||||
Params:
|
||||
name -- Procedure name
|
||||
requests -- List of platylist.message.request.Request objects
|
||||
"""
|
||||
|
||||
self.name = name
|
||||
self.requests = requests
|
||||
self.backend = backend
|
||||
|
||||
for req in requests:
|
||||
req.backend = self.backend
|
||||
|
||||
@classmethod
|
||||
def build(cls, name, requests, backend=None, id=None, **kwargs):
|
||||
reqs = []
|
||||
for request_config in requests:
|
||||
request_config['origin'] = Config.get('device_id')
|
||||
request_config['id'] = id
|
||||
if 'target' not in request_config:
|
||||
request_config['target'] = request_config['origin']
|
||||
|
||||
request = Request.build(request_config)
|
||||
reqs.append(request)
|
||||
|
||||
return cls(name=name, requests=reqs, backend=backend, **kwargs)
|
||||
|
||||
def execute(self, n_tries=1):
|
||||
"""
|
||||
Execute the requests in the procedure
|
||||
Params:
|
||||
n_tries -- Number of tries in case of failure before raising a RuntimeError
|
||||
"""
|
||||
|
||||
logging.info('Executing request {}'.format(self.name))
|
||||
for request in self.requests:
|
||||
request.execute(n_tries)
|
||||
|
||||
|
||||
# vim:sw=4:ts=4:et:
|
||||
|
|
@ -35,14 +35,13 @@ def get_or_load_plugin(plugin_name, reload=False):
|
|||
plugin = plugin_class(**plugin_conf)
|
||||
modules[plugin_name] = plugin
|
||||
except AttributeError as e:
|
||||
logging.warning('No such class in {}: {}'.format(
|
||||
plugin_name, cls_name))
|
||||
logging.warning('No such class in {}: {}'.format(plugin_name, cls_name))
|
||||
raise RuntimeError(e)
|
||||
|
||||
return plugin
|
||||
|
||||
|
||||
def get_module_and_name_from_action(action):
|
||||
def get_module_and_method_from_action(action):
|
||||
""" Input : action=music.mpd.play
|
||||
Output : ('music.mpd', 'play') """
|
||||
|
||||
|
|
Loading…
Reference in a new issue