forked from platypush/platypush
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 .config import Config
|
||||||
from .context import register_backends
|
from .context import register_backends
|
||||||
from .event.processor import EventProcessor
|
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.event import Event, StopEvent
|
||||||
from .message.request import Request
|
from .message.request import Request
|
||||||
from .message.response import Response
|
from .message.response import Response
|
||||||
|
from .procedure import Procedure
|
||||||
|
|
||||||
__author__ = 'Fabio Manganiello <blacklight86@gmail.com>'
|
__author__ = 'Fabio Manganiello <blacklight86@gmail.com>'
|
||||||
__version__ = '0.6'
|
__version__ = '0.6'
|
||||||
|
@ -75,9 +75,15 @@ class Daemon(object):
|
||||||
msg -- platypush.message.Message instance """
|
msg -- platypush.message.Message instance """
|
||||||
|
|
||||||
if isinstance(msg, Request):
|
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))
|
logging.info('Processing request: {}'.format(msg))
|
||||||
msg.execute(n_tries=self.n_tries)
|
|
||||||
|
|
||||||
|
msg.execute(n_tries=self.n_tries)
|
||||||
self.processed_requests += 1
|
self.processed_requests += 1
|
||||||
if self.requests_to_process \
|
if self.requests_to_process \
|
||||||
and self.processed_requests >= 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:
|
if 'device_id' not in self._config:
|
||||||
self._config['device_id'] = socket.gethostname()
|
self._config['device_id'] = socket.gethostname()
|
||||||
|
|
||||||
|
self.backends = {}
|
||||||
|
self.plugins = {}
|
||||||
|
self.event_hooks = {}
|
||||||
|
self.procedures = {}
|
||||||
self._init_components()
|
self._init_components()
|
||||||
|
|
||||||
|
|
||||||
def _init_components(self):
|
def _init_components(self):
|
||||||
self.backends = {}
|
|
||||||
self.plugins = {}
|
|
||||||
self.event_hooks = {}
|
|
||||||
|
|
||||||
for key in self._config.keys():
|
for key in self._config.keys():
|
||||||
if key.startswith('backend.'):
|
if key.startswith('backend.'):
|
||||||
backend_name = '.'.join(key.split('.')[1:])
|
backend_name = '.'.join(key.split('.')[1:])
|
||||||
|
@ -77,6 +77,9 @@ class Config(object):
|
||||||
elif key.startswith('event.hook.'):
|
elif key.startswith('event.hook.'):
|
||||||
hook_name = '.'.join(key.split('.')[2:])
|
hook_name = '.'.join(key.split('.')[2:])
|
||||||
self.event_hooks[hook_name] = self._config[key]
|
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:
|
else:
|
||||||
self.plugins[key] = self._config[key]
|
self.plugins[key] = self._config[key]
|
||||||
|
|
||||||
|
@ -98,6 +101,12 @@ class Config(object):
|
||||||
if _default_config_instance is None: _default_config_instance = Config()
|
if _default_config_instance is None: _default_config_instance = Config()
|
||||||
return _default_config_instance.event_hooks
|
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
|
@staticmethod
|
||||||
def get_default_pusher_backend():
|
def get_default_pusher_backend():
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -5,22 +5,21 @@ import traceback
|
||||||
|
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
|
||||||
from threading import Thread
|
|
||||||
|
|
||||||
from platypush.message import Message
|
from platypush.message import Message
|
||||||
from platypush.message.response import Response
|
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):
|
class Request(Message):
|
||||||
""" Request message class """
|
""" 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:
|
Params:
|
||||||
target -- Target node [String]
|
target -- Target node [String]
|
||||||
action -- Action to be executed (e.g. music.mpd.play) [String]
|
action -- Action to be executed (e.g. music.mpd.play) [String]
|
||||||
origin -- Origin node [String]
|
origin -- Origin node [String]
|
||||||
id -- Message ID, or None to get it auto-generated
|
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]
|
args -- Additional arguments for the action [Dict]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -29,7 +28,7 @@ class Request(Message):
|
||||||
self.action = action
|
self.action = action
|
||||||
self.origin = origin
|
self.origin = origin
|
||||||
self.args = args
|
self.args = args
|
||||||
self.backend = None
|
self.backend = backend
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def build(cls, msg):
|
def build(cls, msg):
|
||||||
|
@ -58,7 +57,7 @@ class Request(Message):
|
||||||
n_tries -- Number of tries in case of failure before raising a RuntimeError
|
n_tries -- Number of tries in case of failure before raising a RuntimeError
|
||||||
"""
|
"""
|
||||||
def _thread_func(n_tries):
|
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)
|
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)
|
plugin = plugin_class(**plugin_conf)
|
||||||
modules[plugin_name] = plugin
|
modules[plugin_name] = plugin
|
||||||
except AttributeError as e:
|
except AttributeError as e:
|
||||||
logging.warning('No such class in {}: {}'.format(
|
logging.warning('No such class in {}: {}'.format(plugin_name, cls_name))
|
||||||
plugin_name, cls_name))
|
|
||||||
raise RuntimeError(e)
|
raise RuntimeError(e)
|
||||||
|
|
||||||
return plugin
|
return plugin
|
||||||
|
|
||||||
|
|
||||||
def get_module_and_name_from_action(action):
|
def get_module_and_method_from_action(action):
|
||||||
""" Input : action=music.mpd.play
|
""" Input : action=music.mpd.play
|
||||||
Output : ('music.mpd', 'play') """
|
Output : ('music.mpd', 'play') """
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue