forked from platypush/platypush
Fix compatibility with all versions of websocket-client, regardless of the list of arguments required by the callbacks (either ws as a first argument or not)
This commit is contained in:
parent
641d9c0d41
commit
99831bf0c7
6 changed files with 58 additions and 44 deletions
|
@ -117,7 +117,8 @@ class MusicMopidyBackend(Backend):
|
||||||
}
|
}
|
||||||
|
|
||||||
def _on_msg(self):
|
def _on_msg(self):
|
||||||
def hndl(ws, msg):
|
def hndl(*args):
|
||||||
|
msg = args[1] if len(args) > 1 else args[0]
|
||||||
msg = json.loads(msg)
|
msg = json.loads(msg)
|
||||||
event = msg.get('event')
|
event = msg.get('event')
|
||||||
if not event:
|
if not event:
|
||||||
|
@ -213,14 +214,17 @@ class MusicMopidyBackend(Backend):
|
||||||
self._reconnect_thread.start()
|
self._reconnect_thread.start()
|
||||||
|
|
||||||
def _on_error(self):
|
def _on_error(self):
|
||||||
def hndl(ws, error):
|
def hndl(*args):
|
||||||
|
error = args[1] if len(args) > 1 else args[0]
|
||||||
|
ws = args[0] if len(args) > 1 else None
|
||||||
self.logger.warning('Mopidy websocket error: {}'.format(error))
|
self.logger.warning('Mopidy websocket error: {}'.format(error))
|
||||||
ws.close()
|
if ws:
|
||||||
|
ws.close()
|
||||||
|
|
||||||
return hndl
|
return hndl
|
||||||
|
|
||||||
def _on_close(self):
|
def _on_close(self):
|
||||||
def hndl(ws):
|
def hndl(*_):
|
||||||
self._connected_event.clear()
|
self._connected_event.clear()
|
||||||
self._ws = None
|
self._ws = None
|
||||||
self.logger.warning('Mopidy websocket connection closed')
|
self.logger.warning('Mopidy websocket connection closed')
|
||||||
|
@ -231,7 +235,7 @@ class MusicMopidyBackend(Backend):
|
||||||
return hndl
|
return hndl
|
||||||
|
|
||||||
def _on_open(self):
|
def _on_open(self):
|
||||||
def hndl(ws):
|
def hndl(*_):
|
||||||
self._connected_event.set()
|
self._connected_event.set()
|
||||||
self.logger.info('Mopidy websocket connected')
|
self.logger.info('Mopidy websocket connected')
|
||||||
|
|
||||||
|
|
|
@ -50,8 +50,8 @@ class TodoistBackend(Backend):
|
||||||
self._event_handled = False
|
self._event_handled = False
|
||||||
|
|
||||||
def _on_msg(self):
|
def _on_msg(self):
|
||||||
# noinspection PyUnusedLocal
|
def hndl(*args):
|
||||||
def hndl(ws, msg):
|
msg = args[1] if len(args) > 1 else args[0]
|
||||||
msg = json.loads(msg)
|
msg = json.loads(msg)
|
||||||
if msg.get('type') == 'sync_needed':
|
if msg.get('type') == 'sync_needed':
|
||||||
self._refresh_all()
|
self._refresh_all()
|
||||||
|
@ -68,15 +68,15 @@ class TodoistBackend(Backend):
|
||||||
time.sleep(10)
|
time.sleep(10)
|
||||||
|
|
||||||
def _on_error(self):
|
def _on_error(self):
|
||||||
# noinspection PyUnusedLocal
|
def hndl(*args):
|
||||||
def hndl(ws, error):
|
error = args[1] if len(args) > 1 else args[0]
|
||||||
self.logger.warning('Todoist websocket error: {}'.format(error))
|
self.logger.warning('Todoist websocket error: {}'.format(error))
|
||||||
self._retry_hndl()
|
self._retry_hndl()
|
||||||
|
|
||||||
return hndl
|
return hndl
|
||||||
|
|
||||||
def _on_close(self):
|
def _on_close(self):
|
||||||
def hndl(*_, **__):
|
def hndl(*_):
|
||||||
self.logger.info('Todoist websocket closed')
|
self.logger.info('Todoist websocket closed')
|
||||||
self._retry_hndl()
|
self._retry_hndl()
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,9 @@ class TrelloBackend(Backend):
|
||||||
|
|
||||||
for b in boards:
|
for b in boards:
|
||||||
b = self._plugin.get_board(b).board
|
b = self._plugin.get_board(b).board
|
||||||
|
# noinspection PyUnresolvedReferences
|
||||||
self._boards_by_id[b.id] = b
|
self._boards_by_id[b.id] = b
|
||||||
|
# noinspection PyUnresolvedReferences
|
||||||
self._boards_by_name[b.name] = b
|
self._boards_by_name[b.name] = b
|
||||||
|
|
||||||
self.url = self._websocket_url_base.format(token=self.token)
|
self.url = self._websocket_url_base.format(token=self.token)
|
||||||
|
@ -79,8 +81,13 @@ class TrelloBackend(Backend):
|
||||||
self.logger.info('Trello boards subscribed')
|
self.logger.info('Trello boards subscribed')
|
||||||
|
|
||||||
def _on_msg(self):
|
def _on_msg(self):
|
||||||
# noinspection PyUnusedLocal
|
def hndl(*args):
|
||||||
def hndl(ws: WebSocketApp, msg):
|
if len(args) < 2:
|
||||||
|
self.logger.warning('Missing websocket argument - make sure that you are using '
|
||||||
|
'a version of websocket-client < 0.53.0 or >= 0.58.0')
|
||||||
|
return
|
||||||
|
|
||||||
|
ws, msg = args[:2]
|
||||||
if not msg:
|
if not msg:
|
||||||
# Reply back with an empty message when the server sends an empty message
|
# Reply back with an empty message when the server sends an empty message
|
||||||
ws.send('')
|
ws.send('')
|
||||||
|
@ -89,8 +96,8 @@ class TrelloBackend(Backend):
|
||||||
# noinspection PyBroadException
|
# noinspection PyBroadException
|
||||||
try:
|
try:
|
||||||
msg = json.loads(msg)
|
msg = json.loads(msg)
|
||||||
except:
|
except Exception as e:
|
||||||
self.logger.warning('Received invalid JSON message from Trello: {}'.format(msg))
|
self.logger.warning('Received invalid JSON message from Trello: {}: {}'.format(msg, e))
|
||||||
return
|
return
|
||||||
|
|
||||||
if 'error' in msg:
|
if 'error' in msg:
|
||||||
|
@ -141,15 +148,14 @@ class TrelloBackend(Backend):
|
||||||
return hndl
|
return hndl
|
||||||
|
|
||||||
def _on_error(self):
|
def _on_error(self):
|
||||||
# noinspection PyUnusedLocal
|
def hndl(*args):
|
||||||
def hndl(ws: WebSocketApp, error):
|
error = args[1] if len(args) > 1 else args[0]
|
||||||
self.logger.warning('Trello websocket error: {}'.format(error))
|
self.logger.warning('Trello websocket error: {}'.format(error))
|
||||||
|
|
||||||
return hndl
|
return hndl
|
||||||
|
|
||||||
def _on_close(self):
|
def _on_close(self):
|
||||||
# noinspection PyUnusedLocal
|
def hndl(*_):
|
||||||
def hndl(ws: WebSocketApp):
|
|
||||||
self.logger.warning('Trello websocket connection closed')
|
self.logger.warning('Trello websocket connection closed')
|
||||||
self._connected.clear()
|
self._connected.clear()
|
||||||
self._req_id = 0
|
self._req_id = 0
|
||||||
|
@ -166,9 +172,11 @@ class TrelloBackend(Backend):
|
||||||
|
|
||||||
def _on_open(self):
|
def _on_open(self):
|
||||||
# noinspection PyUnusedLocal
|
# noinspection PyUnusedLocal
|
||||||
def hndl(ws: WebSocketApp):
|
def hndl(*args):
|
||||||
|
ws = args[0] if args else None
|
||||||
self._connected.set()
|
self._connected.set()
|
||||||
self._send(ws, {'type': 'ping'})
|
if ws:
|
||||||
|
self._send(ws, {'type': 'ping'})
|
||||||
self.logger.info('Trello websocket connected')
|
self.logger.info('Trello websocket connected')
|
||||||
|
|
||||||
return hndl
|
return hndl
|
||||||
|
|
|
@ -100,7 +100,8 @@ class MediaKodiPlugin(MediaPlugin):
|
||||||
bus.post(evt_type(player=self.host, plugin='media.kodi', **evt))
|
bus.post(evt_type(player=self.host, plugin='media.kodi', **evt))
|
||||||
|
|
||||||
def _on_ws_msg(self):
|
def _on_ws_msg(self):
|
||||||
def hndl(ws, msg):
|
def hndl(*args):
|
||||||
|
msg = args[1] if len(args) > 1 else args[0]
|
||||||
self.logger.info("Received Kodi message: {}".format(msg))
|
self.logger.info("Received Kodi message: {}".format(msg))
|
||||||
msg = json.loads(msg)
|
msg = json.loads(msg)
|
||||||
method = msg.get('method')
|
method = msg.get('method')
|
||||||
|
@ -129,12 +130,13 @@ class MediaKodiPlugin(MediaPlugin):
|
||||||
return hndl
|
return hndl
|
||||||
|
|
||||||
def _on_ws_error(self):
|
def _on_ws_error(self):
|
||||||
def hndl(ws, error):
|
def hndl(*args):
|
||||||
|
error = args[1] if len(args) > 1 else args[0]
|
||||||
self.logger.warning("Kodi websocket connection error: {}".format(error))
|
self.logger.warning("Kodi websocket connection error: {}".format(error))
|
||||||
return hndl
|
return hndl
|
||||||
|
|
||||||
def _on_ws_close(self):
|
def _on_ws_close(self):
|
||||||
def hndl(ws):
|
def hndl(*_):
|
||||||
self._ws = None
|
self._ws = None
|
||||||
self.logger.warning("Kodi websocket connection closed")
|
self.logger.warning("Kodi websocket connection closed")
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
import asyncio
|
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import websockets
|
import websockets
|
||||||
|
|
||||||
from platypush.context import get_or_create_event_loop
|
from platypush.context import get_or_create_event_loop
|
||||||
|
@ -18,30 +16,30 @@ class WebsocketPlugin(Plugin):
|
||||||
* **websockets** (``pip install websockets``)
|
* **websockets** (``pip install websockets``)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
@action
|
@action
|
||||||
def send(self, url, msg, ssl_cert=None, ssl_key=None, ssl_cafile=None,
|
def send(self, url, msg, ssl_cert=None, ssl_key=None, ssl_cafile=None, ssl_capath=None):
|
||||||
ssl_capath=None, *args, **kwargs):
|
|
||||||
"""
|
"""
|
||||||
Sends a message to a websocket.
|
Sends a message to a websocket.
|
||||||
|
|
||||||
:param url: Websocket URL, e.g. ws://localhost:8765 or wss://localhost:8765
|
:param url: Websocket URL, e.g. ws://localhost:8765 or wss://localhost:8765
|
||||||
:type topic: str
|
:type url: str
|
||||||
|
|
||||||
:param msg: Message to be sent. It can be a list, a dict, or a Message object
|
:param msg: Message to be sent. It can be a list, a dict, or a Message object
|
||||||
|
|
||||||
:param ssl_cert: Path to the SSL certificate to be used, if the SSL connection requires client authentication as well (default: None)
|
:param ssl_cert: Path to the SSL certificate to be used, if the SSL connection requires client authentication
|
||||||
:type ssl_cert: str
|
as well (default: None) :type ssl_cert: str
|
||||||
|
|
||||||
:param ssl_key: Path to the SSL key to be used, if the SSL connection requires client authentication as well (default: None)
|
:param ssl_key: Path to the SSL key to be used, if the SSL connection requires client authentication as well
|
||||||
:type ssl_key: str
|
(default: None) :type ssl_key: str
|
||||||
|
|
||||||
:param ssl_cafile: Path to the certificate authority file if required by the SSL configuration (default: None)
|
:param ssl_cafile: Path to the certificate authority file if required by the SSL configuration (default: None)
|
||||||
:type ssl_cafile: str
|
:type ssl_cafile: str
|
||||||
|
|
||||||
:param ssl_capath: Path to the certificate authority directory if required by the SSL configuration (default: None)
|
:param ssl_capath: Path to the certificate authority directory if required by the SSL configuration
|
||||||
|
(default: None)
|
||||||
:type ssl_capath: str
|
:type ssl_capath: str
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -56,19 +54,21 @@ class WebsocketPlugin(Plugin):
|
||||||
async with websockets.connect(url, **websocket_args) as websocket:
|
async with websockets.connect(url, **websocket_args) as websocket:
|
||||||
try:
|
try:
|
||||||
await websocket.send(str(msg))
|
await websocket.send(str(msg))
|
||||||
except websockets.exceptions.ConnectionClosed:
|
except websockets.exceptions.ConnectionClosed as err:
|
||||||
self.logger.warning('Error on websocket {}: {}'.
|
self.logger.warning('Error on websocket {}: {}'.
|
||||||
format(url, e))
|
format(url, err))
|
||||||
|
|
||||||
try: msg = json.dumps(msg)
|
try:
|
||||||
except: pass
|
msg = json.dumps(msg)
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.debug(e)
|
||||||
|
|
||||||
try: msg = Message.build(json.loads(msg))
|
try:
|
||||||
except: pass
|
msg = Message.build(json.loads(msg))
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.debug(e)
|
||||||
|
|
||||||
loop = get_or_create_event_loop()
|
loop = get_or_create_event_loop()
|
||||||
loop.run_until_complete(send())
|
loop.run_until_complete(send())
|
||||||
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -74,7 +74,7 @@ setup(
|
||||||
# Support for Kafka backend and plugin
|
# Support for Kafka backend and plugin
|
||||||
'kafka': ['kafka-python'],
|
'kafka': ['kafka-python'],
|
||||||
# Support for Pushbullet backend and plugin
|
# Support for Pushbullet backend and plugin
|
||||||
'pushbullet': ['pushbullet.py @ https://github.com/rbrcsk/pushbullet.py/tarball/master'],
|
'pushbullet': ['pushbullet.py @ https://github.com/BlackLight/pushbullet.py/tarball/master'],
|
||||||
# Support for HTTP backend
|
# Support for HTTP backend
|
||||||
'http': ['flask', 'frozendict', 'bcrypt'],
|
'http': ['flask', 'frozendict', 'bcrypt'],
|
||||||
# Support for uWSGI HTTP backend
|
# Support for uWSGI HTTP backend
|
||||||
|
|
Loading…
Reference in a new issue