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:
Fabio Manganiello 2021-04-02 19:27:25 +02:00
parent 641d9c0d41
commit 99831bf0c7
6 changed files with 58 additions and 44 deletions

View file

@ -117,7 +117,8 @@ class MusicMopidyBackend(Backend):
}
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)
event = msg.get('event')
if not event:
@ -213,14 +214,17 @@ class MusicMopidyBackend(Backend):
self._reconnect_thread.start()
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))
ws.close()
if ws:
ws.close()
return hndl
def _on_close(self):
def hndl(ws):
def hndl(*_):
self._connected_event.clear()
self._ws = None
self.logger.warning('Mopidy websocket connection closed')
@ -231,7 +235,7 @@ class MusicMopidyBackend(Backend):
return hndl
def _on_open(self):
def hndl(ws):
def hndl(*_):
self._connected_event.set()
self.logger.info('Mopidy websocket connected')

View file

@ -50,8 +50,8 @@ class TodoistBackend(Backend):
self._event_handled = False
def _on_msg(self):
# noinspection PyUnusedLocal
def hndl(ws, msg):
def hndl(*args):
msg = args[1] if len(args) > 1 else args[0]
msg = json.loads(msg)
if msg.get('type') == 'sync_needed':
self._refresh_all()
@ -68,15 +68,15 @@ class TodoistBackend(Backend):
time.sleep(10)
def _on_error(self):
# noinspection PyUnusedLocal
def hndl(ws, error):
def hndl(*args):
error = args[1] if len(args) > 1 else args[0]
self.logger.warning('Todoist websocket error: {}'.format(error))
self._retry_hndl()
return hndl
def _on_close(self):
def hndl(*_, **__):
def hndl(*_):
self.logger.info('Todoist websocket closed')
self._retry_hndl()

View file

@ -57,7 +57,9 @@ class TrelloBackend(Backend):
for b in boards:
b = self._plugin.get_board(b).board
# noinspection PyUnresolvedReferences
self._boards_by_id[b.id] = b
# noinspection PyUnresolvedReferences
self._boards_by_name[b.name] = b
self.url = self._websocket_url_base.format(token=self.token)
@ -79,8 +81,13 @@ class TrelloBackend(Backend):
self.logger.info('Trello boards subscribed')
def _on_msg(self):
# noinspection PyUnusedLocal
def hndl(ws: WebSocketApp, msg):
def hndl(*args):
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:
# Reply back with an empty message when the server sends an empty message
ws.send('')
@ -89,8 +96,8 @@ class TrelloBackend(Backend):
# noinspection PyBroadException
try:
msg = json.loads(msg)
except:
self.logger.warning('Received invalid JSON message from Trello: {}'.format(msg))
except Exception as e:
self.logger.warning('Received invalid JSON message from Trello: {}: {}'.format(msg, e))
return
if 'error' in msg:
@ -141,15 +148,14 @@ class TrelloBackend(Backend):
return hndl
def _on_error(self):
# noinspection PyUnusedLocal
def hndl(ws: WebSocketApp, error):
def hndl(*args):
error = args[1] if len(args) > 1 else args[0]
self.logger.warning('Trello websocket error: {}'.format(error))
return hndl
def _on_close(self):
# noinspection PyUnusedLocal
def hndl(ws: WebSocketApp):
def hndl(*_):
self.logger.warning('Trello websocket connection closed')
self._connected.clear()
self._req_id = 0
@ -166,9 +172,11 @@ class TrelloBackend(Backend):
def _on_open(self):
# noinspection PyUnusedLocal
def hndl(ws: WebSocketApp):
def hndl(*args):
ws = args[0] if args else None
self._connected.set()
self._send(ws, {'type': 'ping'})
if ws:
self._send(ws, {'type': 'ping'})
self.logger.info('Trello websocket connected')
return hndl

View file

@ -100,7 +100,8 @@ class MediaKodiPlugin(MediaPlugin):
bus.post(evt_type(player=self.host, plugin='media.kodi', **evt))
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))
msg = json.loads(msg)
method = msg.get('method')
@ -129,12 +130,13 @@ class MediaKodiPlugin(MediaPlugin):
return hndl
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))
return hndl
def _on_ws_close(self):
def hndl(ws):
def hndl(*_):
self._ws = None
self.logger.warning("Kodi websocket connection closed")
time.sleep(5)

View file

@ -1,6 +1,4 @@
import asyncio
import json
import os
import websockets
from platypush.context import get_or_create_event_loop
@ -18,30 +16,30 @@ class WebsocketPlugin(Plugin):
* **websockets** (``pip install websockets``)
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def __init__(self, **kwargs):
super().__init__(**kwargs)
@action
def send(self, url, msg, ssl_cert=None, ssl_key=None, ssl_cafile=None,
ssl_capath=None, *args, **kwargs):
def send(self, url, msg, ssl_cert=None, ssl_key=None, ssl_cafile=None, ssl_capath=None):
"""
Sends a message to a websocket.
: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 ssl_cert: Path to the SSL certificate to be used, if the SSL connection requires client authentication as well (default: None)
:type ssl_cert: str
:param ssl_cert: Path to the SSL certificate to be used, if the SSL connection requires client authentication
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)
:type ssl_key: str
:param ssl_key: Path to the SSL key to be used, if the SSL connection requires client authentication as well
(default: None) :type ssl_key: str
:param ssl_cafile: Path to the certificate authority file if required by the SSL configuration (default: None)
: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
"""
@ -56,19 +54,21 @@ class WebsocketPlugin(Plugin):
async with websockets.connect(url, **websocket_args) as websocket:
try:
await websocket.send(str(msg))
except websockets.exceptions.ConnectionClosed:
except websockets.exceptions.ConnectionClosed as err:
self.logger.warning('Error on websocket {}: {}'.
format(url, e))
format(url, err))
try: msg = json.dumps(msg)
except: pass
try:
msg = json.dumps(msg)
except Exception as e:
self.logger.debug(e)
try: msg = Message.build(json.loads(msg))
except: pass
try:
msg = Message.build(json.loads(msg))
except Exception as e:
self.logger.debug(e)
loop = get_or_create_event_loop()
loop.run_until_complete(send())
# vim:sw=4:ts=4:et:

View file

@ -74,7 +74,7 @@ setup(
# Support for Kafka backend and plugin
'kafka': ['kafka-python'],
# 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
'http': ['flask', 'frozendict', 'bcrypt'],
# Support for uWSGI HTTP backend