forked from platypush/platypush
Removed legacy "local" backend and pusher script
This commit is contained in:
parent
adb472da7f
commit
6f224cbda9
8 changed files with 6 additions and 297 deletions
|
@ -3,6 +3,12 @@
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
Given the high speed of development in the first phase, changes are being reported only starting from v0.20.2.
|
Given the high speed of development in the first phase, changes are being reported only starting from v0.20.2.
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- Removed legacy `pusher` script and `local` backend.
|
||||||
|
|
||||||
## [0.20.5] - 2021-03-12
|
## [0.20.5] - 2021-03-12
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -34,7 +34,6 @@ Backends
|
||||||
platypush/backend/kafka.rst
|
platypush/backend/kafka.rst
|
||||||
platypush/backend/light.hue.rst
|
platypush/backend/light.hue.rst
|
||||||
platypush/backend/linode.rst
|
platypush/backend/linode.rst
|
||||||
platypush/backend/local.rst
|
|
||||||
platypush/backend/mail.rst
|
platypush/backend/mail.rst
|
||||||
platypush/backend/midi.rst
|
platypush/backend/midi.rst
|
||||||
platypush/backend/mqtt.rst
|
platypush/backend/mqtt.rst
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
``platypush.backend.local``
|
|
||||||
===========================
|
|
||||||
|
|
||||||
.. automodule:: platypush.backend.local
|
|
||||||
:members:
|
|
|
@ -1,80 +0,0 @@
|
||||||
import os
|
|
||||||
import time
|
|
||||||
|
|
||||||
from .. import Backend
|
|
||||||
|
|
||||||
from platypush.message import Message
|
|
||||||
from platypush.message.response import Response
|
|
||||||
|
|
||||||
|
|
||||||
class LocalBackend(Backend):
|
|
||||||
"""
|
|
||||||
Sends and receive messages on two distinct local FIFOs, one for the requests and one for the responses.
|
|
||||||
This is a legacy backend that should only be used for testing purposes.
|
|
||||||
|
|
||||||
You can use this backend either to send local commands to push through
|
|
||||||
Pusher (or any other script), or debug. You can even send command on the
|
|
||||||
command line and read the responses in this way::
|
|
||||||
|
|
||||||
# Send the request. Remember: the JSON must be all on one line.
|
|
||||||
$ cat <<EOF > /tmp/platypush-requests.fifo
|
|
||||||
{"type": "request", "target": "node_name", "action": "shell.exec", "args": {"cmd":"echo ping"}, "origin": "node_name", "id": "put_an_id_here"}
|
|
||||||
EOF
|
|
||||||
$ cat /tmp/platypush-responses.fifo
|
|
||||||
ping
|
|
||||||
$
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, request_fifo, response_fifo, **kwargs):
|
|
||||||
super().__init__(**kwargs)
|
|
||||||
|
|
||||||
self.request_fifo = request_fifo
|
|
||||||
self.response_fifo = response_fifo
|
|
||||||
|
|
||||||
try: os.mkfifo(self.request_fifo)
|
|
||||||
except FileExistsError as e: pass
|
|
||||||
|
|
||||||
try: os.mkfifo(self.response_fifo)
|
|
||||||
except FileExistsError as e: pass
|
|
||||||
|
|
||||||
def send_message(self, msg, **kwargs):
|
|
||||||
fifo = self.response_fifo \
|
|
||||||
if isinstance(msg, Response) or self._request_context \
|
|
||||||
else self.request_fifo
|
|
||||||
|
|
||||||
msg = '{}\n'.format(str(msg)).encode('utf-8')
|
|
||||||
|
|
||||||
with open(fifo, 'wb') as f:
|
|
||||||
f.write(msg)
|
|
||||||
|
|
||||||
|
|
||||||
def _get_next_message(self):
|
|
||||||
fifo = self.response_fifo if self._request_context else self.request_fifo
|
|
||||||
with open(fifo, 'rb', 0) as f:
|
|
||||||
msg = f.readline()
|
|
||||||
|
|
||||||
return Message.build(msg) if len(msg) else None
|
|
||||||
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
super().run()
|
|
||||||
self.logger.info('Initialized local backend on {} and {}'.
|
|
||||||
format(self.request_fifo, self.response_fifo))
|
|
||||||
|
|
||||||
while not self.should_stop():
|
|
||||||
try:
|
|
||||||
msg = self._get_next_message()
|
|
||||||
if not msg: continue
|
|
||||||
except Exception as e:
|
|
||||||
self.logger.exception(e)
|
|
||||||
time.sleep(0.2)
|
|
||||||
continue
|
|
||||||
|
|
||||||
self.logger.debug('Received message on the local backend: {}, thread_id: '.format(msg, self.thread_id))
|
|
||||||
|
|
||||||
if self.should_stop(): break
|
|
||||||
self.on_message(msg)
|
|
||||||
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
|
||||||
|
|
|
@ -360,17 +360,6 @@ class Config(object):
|
||||||
_default_config_instance = Config()
|
_default_config_instance = Config()
|
||||||
return _default_config_instance.cronjobs
|
return _default_config_instance.cronjobs
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_default_pusher_backend():
|
|
||||||
"""
|
|
||||||
Gets the default pusher backend from the config
|
|
||||||
"""
|
|
||||||
backends = [k for k in Config.get_backends().keys()
|
|
||||||
if 'pusher' in Config.get_backends()[k]
|
|
||||||
and Config.get_backends()[k]['pusher'] is True]
|
|
||||||
|
|
||||||
return backends[0] if backends else None
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _get_default_cfgfile(cls):
|
def _get_default_cfgfile(cls):
|
||||||
for location in cls._cfgfile_locations:
|
for location in cls._cfgfile_locations:
|
||||||
|
|
|
@ -1,193 +0,0 @@
|
||||||
import argparse
|
|
||||||
import logging
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from platypush.bus import Bus
|
|
||||||
from platypush.config import Config
|
|
||||||
from platypush.context import register_backends
|
|
||||||
from platypush.message.request import Request
|
|
||||||
|
|
||||||
|
|
||||||
class Pusher(object):
|
|
||||||
"""
|
|
||||||
Main class to send messages and events to a node
|
|
||||||
"""
|
|
||||||
|
|
||||||
""" Configuration file path """
|
|
||||||
config_file = None
|
|
||||||
|
|
||||||
""" Default backend name """
|
|
||||||
backend = None
|
|
||||||
|
|
||||||
""" Pusher local bus. The response will be processed here """
|
|
||||||
bus = None
|
|
||||||
|
|
||||||
""" Configured backends as a name => object map """
|
|
||||||
backends = {}
|
|
||||||
|
|
||||||
""" Default response_wait timeout """
|
|
||||||
default_response_wait_timeout = 5
|
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, config_file=None, backend=None, on_response=None):
|
|
||||||
"""
|
|
||||||
Constructor.
|
|
||||||
Params:
|
|
||||||
config_file -- Path to the configuration file - default:
|
|
||||||
~/.config/platypush/config.yaml or
|
|
||||||
/etc/platypush/config.yaml)
|
|
||||||
backend -- Name of the backend where pusher will send the
|
|
||||||
request and wait for the response (kafka
|
|
||||||
or pushbullet). Default: whatever is specified
|
|
||||||
with pusher=true in your configuration file
|
|
||||||
on_response -- Method that will be invoked upon response receipt.
|
|
||||||
Takes a platypush.message.response.Response as arg.
|
|
||||||
Default: print the response and exit.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Initialize the configuration
|
|
||||||
self.config_file = config_file
|
|
||||||
log_conf = Config.get('logging')
|
|
||||||
Config.init(config_file)
|
|
||||||
logging.basicConfig(level=log_conf['level']
|
|
||||||
if log_conf and 'level' in log_conf
|
|
||||||
else logging.info, stream=sys.stdout)
|
|
||||||
|
|
||||||
self.on_response = on_response or self.default_on_response()
|
|
||||||
self.backend = backend or Config.get_default_pusher_backend()
|
|
||||||
self.bus = Bus()
|
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def parse_build_args(cls, args):
|
|
||||||
""" Parse the recognized options from a list of cmdline arguments """
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
parser.add_argument('--config', '-c', dest='config', required=False,
|
|
||||||
default=None, help="Configuration file path (default: " +
|
|
||||||
"~/.config/platypush/config.yaml or " +
|
|
||||||
"/etc/platypush/config.yaml")
|
|
||||||
|
|
||||||
parser.add_argument('--type', '-p', dest='type', required=False,
|
|
||||||
default='request', help="Type of message to send, request or event")
|
|
||||||
|
|
||||||
parser.add_argument('--target', '-t', dest='target', required=False,
|
|
||||||
default=Config.get('device_id'),
|
|
||||||
help="Destination of the command")
|
|
||||||
|
|
||||||
parser.add_argument('--action', '-a', dest='action', required=False,
|
|
||||||
default=None, help="Action to execute, as " +
|
|
||||||
"package.method (e.g. music.mpd.play), if this is a request")
|
|
||||||
|
|
||||||
parser.add_argument('--event', '-e', dest='event', required=False,
|
|
||||||
default=None, help="Event type, as full " +
|
|
||||||
"package.class (e.g. " +
|
|
||||||
"platypush.message.event.ping.PingEvent), if this is an event")
|
|
||||||
|
|
||||||
parser.add_argument('--backend', '-b', dest='backend', required=False,
|
|
||||||
default=None, help="Backend to deliver the message " +
|
|
||||||
"[pushbullet|kafka] (default: whatever " +
|
|
||||||
"specified in your config with pusher=True)")
|
|
||||||
|
|
||||||
parser.add_argument('--timeout', '-T', dest='timeout', required=False,
|
|
||||||
default=cls.default_response_wait_timeout, help="The application " +
|
|
||||||
"will wait for a response for this number of seconds " +
|
|
||||||
"(default: " + str(cls.default_response_wait_timeout) + " seconds. "
|
|
||||||
"A zero value means that the application " +
|
|
||||||
" will exit without waiting for a response)")
|
|
||||||
|
|
||||||
opts, args = parser.parse_known_args(args)
|
|
||||||
|
|
||||||
if len(args) % 2 != 0:
|
|
||||||
parser.print_help()
|
|
||||||
raise RuntimeError('Odd number of key-value options passed: {}'.format(args))
|
|
||||||
|
|
||||||
if opts.type == 'request' and not opts.action:
|
|
||||||
parser.print_help()
|
|
||||||
raise RuntimeError('No action provided for the request'.format(args))
|
|
||||||
|
|
||||||
if opts.type == 'event' and not opts.event:
|
|
||||||
parser.print_help()
|
|
||||||
raise RuntimeError('No type provided for the event'.format(args))
|
|
||||||
|
|
||||||
opts.args = {}
|
|
||||||
for i in range(0, len(args), 2):
|
|
||||||
opts.args[re.sub('^-+', '', args[i])] = args[i+1]
|
|
||||||
|
|
||||||
return opts
|
|
||||||
|
|
||||||
def get_backend(self, name):
|
|
||||||
# Lazy init
|
|
||||||
if not self.backends:
|
|
||||||
self.backends = register_backends(bus=self.bus)
|
|
||||||
|
|
||||||
if name not in self.backends:
|
|
||||||
raise RuntimeError('No such backend configured: {}'.format(name))
|
|
||||||
return self.backends[name]
|
|
||||||
|
|
||||||
def default_on_response(self):
|
|
||||||
def _f(response):
|
|
||||||
logging.info('Received response: {}'.format(response))
|
|
||||||
# self.backend_instance.stop()
|
|
||||||
return _f
|
|
||||||
|
|
||||||
def send_event(self, target=Config.get('device_id'),
|
|
||||||
type='platypush.message.event.Event', backend=None, **kwargs):
|
|
||||||
if not backend: backend = self.backend
|
|
||||||
|
|
||||||
self.backend_instance = self.get_backend(backend)
|
|
||||||
self.backend_instance.send_event({
|
|
||||||
'target': target,
|
|
||||||
'args': {
|
|
||||||
'type': type,
|
|
||||||
**kwargs
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
def send_request(self, target, action, backend=None,
|
|
||||||
timeout=default_response_wait_timeout, **kwargs):
|
|
||||||
"""
|
|
||||||
Sends a message on a backend and optionally waits for an answer.
|
|
||||||
Params:
|
|
||||||
target -- Target node
|
|
||||||
action -- Action to be executed in the form plugin.path.method
|
|
||||||
(e.g. shell.exec or music.mpd.play)
|
|
||||||
backend -- Name of the backend that will process the request and get
|
|
||||||
the response (e.g. 'pushbullet' or 'kafka') (default: whichever
|
|
||||||
backend marked as pusher=true in your config.yaml)
|
|
||||||
timeout -- Response receive timeout in seconds
|
|
||||||
- Pusher Default: 5 seconds
|
|
||||||
- If timeout == 0 or None: Pusher exits without waiting for a response
|
|
||||||
**kwargs -- Optional key-valued arguments for the action method
|
|
||||||
(e.g. cmd='echo ping' or groups="['Living Room']")
|
|
||||||
"""
|
|
||||||
|
|
||||||
def _timeout_hndl(signum, frame):
|
|
||||||
""" Default response timeout handle: raise RuntimeError and exit """
|
|
||||||
|
|
||||||
if not backend: backend = self.backend
|
|
||||||
|
|
||||||
req = Request.build({
|
|
||||||
'target' : target,
|
|
||||||
'action' : action,
|
|
||||||
'args' : kwargs,
|
|
||||||
})
|
|
||||||
|
|
||||||
self.backend_instance = self.get_backend(backend)
|
|
||||||
self.backend_instance.send_request(req, on_response=self.on_response,
|
|
||||||
response_timeout=timeout)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
opts = Pusher.parse_build_args(sys.argv[1:])
|
|
||||||
pusher = Pusher(config_file=opts.config, backend=opts.backend)
|
|
||||||
|
|
||||||
if opts.type == 'event':
|
|
||||||
pusher.send_event(target=opts.target, type=opts.event, **opts.args)
|
|
||||||
else:
|
|
||||||
pusher.send_request(target=opts.target, action=opts.action, timeout=opts.timeout, **opts.args)
|
|
||||||
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
from platypush.pusher import main
|
|
||||||
|
|
||||||
main()
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
|
||||||
|
|
1
setup.py
1
setup.py
|
@ -41,7 +41,6 @@ setup(
|
||||||
entry_points={
|
entry_points={
|
||||||
'console_scripts': [
|
'console_scripts': [
|
||||||
'platypush=platypush:main',
|
'platypush=platypush:main',
|
||||||
'pusher=platypush.pusher:main',
|
|
||||||
'platydock=platypush.platydock:main',
|
'platydock=platypush.platydock:main',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue