Support of processing unknown events and event names with dots.
#Fixes 234
This commit is contained in:
pare
c9008a1cdc
commit
af59a46068
S'han modificat 2 arxius amb 75 adicions i 15 eliminacions
|
@ -45,6 +45,16 @@ class StreamListener(object):
|
||||||
contains the resulting conversation dict."""
|
contains the resulting conversation dict."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def on_unknown_event(self, name, unknown_event = None):
|
||||||
|
"""An unknown mastodon API event has been received. The name contains the event-name and unknown_event
|
||||||
|
contains the content of the unknown event.
|
||||||
|
|
||||||
|
This function must be implemented, if unknown events should be handled without an error.
|
||||||
|
"""
|
||||||
|
exception = MastodonMalformedEventError('Bad event type', name)
|
||||||
|
self.on_abort(exception)
|
||||||
|
raise exception
|
||||||
|
|
||||||
def handle_heartbeat(self):
|
def handle_heartbeat(self):
|
||||||
"""The server has sent us a keep-alive message. This callback may be
|
"""The server has sent us a keep-alive message. This callback may be
|
||||||
useful to carry out periodic housekeeping tasks, or just to confirm
|
useful to carry out periodic housekeeping tasks, or just to confirm
|
||||||
|
@ -56,6 +66,11 @@ class StreamListener(object):
|
||||||
Handles a stream of events from the Mastodon server. When each event
|
Handles a stream of events from the Mastodon server. When each event
|
||||||
is received, the corresponding .on_[name]() method is called.
|
is received, the corresponding .on_[name]() method is called.
|
||||||
|
|
||||||
|
When the Mastodon API changes, the on_unknown_event(name, content)
|
||||||
|
function is called.
|
||||||
|
The default behavior is to throw an error. Define a callback handler
|
||||||
|
to intercept unknown events if needed (and avoid errors)
|
||||||
|
|
||||||
response; a requests response object with the open stream for reading.
|
response; a requests response object with the open stream for reading.
|
||||||
"""
|
"""
|
||||||
event = {}
|
event = {}
|
||||||
|
@ -137,33 +152,32 @@ class StreamListener(object):
|
||||||
exception,
|
exception,
|
||||||
err
|
err
|
||||||
)
|
)
|
||||||
|
# New mastodon API also supports event names with dots:
|
||||||
handler_name = 'on_' + name
|
handler_name = 'on_' + name.replace('.', '_')
|
||||||
try:
|
# A generic way to handle unknown events to make legacy code more stable for future changes
|
||||||
handler = getattr(self, handler_name)
|
handler = getattr(self, handler_name, self.on_unknown_event)
|
||||||
except AttributeError as err:
|
if handler != self.on_unknown_event:
|
||||||
exception = MastodonMalformedEventError('Bad event type', name)
|
|
||||||
self.on_abort(exception)
|
|
||||||
six.raise_from(
|
|
||||||
exception,
|
|
||||||
err
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
handler(payload)
|
handler(payload)
|
||||||
|
else:
|
||||||
|
handler(name, payload)
|
||||||
|
|
||||||
|
|
||||||
class CallbackStreamListener(StreamListener):
|
class CallbackStreamListener(StreamListener):
|
||||||
"""
|
"""
|
||||||
Simple callback stream handler class.
|
Simple callback stream handler class.
|
||||||
Can optionally additionally send local update events to a separate handler.
|
Can optionally additionally send local update events to a separate handler.
|
||||||
|
Define an unknown_event_handler for new Mastodon API events. If not, the
|
||||||
|
listener will raise an error on new, not handled, events from the API.
|
||||||
"""
|
"""
|
||||||
def __init__(self, update_handler = None, local_update_handler = None, delete_handler = None, notification_handler = None, conversation_handler = None):
|
def __init__(self, update_handler = None, local_update_handler = None, delete_handler = None, notification_handler = None, conversation_handler = None, unknown_event_handler = None):
|
||||||
super(CallbackStreamListener, self).__init__()
|
super(CallbackStreamListener, self).__init__()
|
||||||
self.update_handler = update_handler
|
self.update_handler = update_handler
|
||||||
self.local_update_handler = local_update_handler
|
self.local_update_handler = local_update_handler
|
||||||
self.delete_handler = delete_handler
|
self.delete_handler = delete_handler
|
||||||
self.notification_handler = notification_handler
|
self.notification_handler = notification_handler
|
||||||
self.conversation_handler = conversation_handler
|
self.conversation_handler = conversation_handler
|
||||||
|
self.unknown_event_handler = unknown_event_handler
|
||||||
|
|
||||||
def on_update(self, status):
|
def on_update(self, status):
|
||||||
if self.update_handler != None:
|
if self.update_handler != None:
|
||||||
self.update_handler(status)
|
self.update_handler(status)
|
||||||
|
@ -188,3 +202,11 @@ class CallbackStreamListener(StreamListener):
|
||||||
def on_conversation(self, conversation):
|
def on_conversation(self, conversation):
|
||||||
if self.conversation_handler != None:
|
if self.conversation_handler != None:
|
||||||
self.conversation_handler(conversation)
|
self.conversation_handler(conversation)
|
||||||
|
|
||||||
|
def on_unknown_event(self, name, unknown_event = None):
|
||||||
|
if self.unknown_event_handler != None:
|
||||||
|
self.unknown_event_handler(name, unknown_event)
|
||||||
|
else:
|
||||||
|
exception = MastodonMalformedEventError('Bad event type', name)
|
||||||
|
self.on_abort(exception)
|
||||||
|
raise exception
|
||||||
|
|
|
@ -61,6 +61,8 @@ class Listener(StreamListener):
|
||||||
self.notifications = []
|
self.notifications = []
|
||||||
self.deletes = []
|
self.deletes = []
|
||||||
self.heartbeats = 0
|
self.heartbeats = 0
|
||||||
|
self.bla_called = False
|
||||||
|
self.do_something_called = False
|
||||||
|
|
||||||
def on_update(self, status):
|
def on_update(self, status):
|
||||||
self.updates.append(status)
|
self.updates.append(status)
|
||||||
|
@ -72,6 +74,11 @@ class Listener(StreamListener):
|
||||||
self.deletes.append(status_id)
|
self.deletes.append(status_id)
|
||||||
|
|
||||||
def on_blahblah(self, data):
|
def on_blahblah(self, data):
|
||||||
|
self.bla_called = True
|
||||||
|
pass
|
||||||
|
|
||||||
|
def on_do_something(self, data):
|
||||||
|
self.do_something_called = True
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def handle_heartbeat(self):
|
def handle_heartbeat(self):
|
||||||
|
@ -158,6 +165,37 @@ def test_unknown_event():
|
||||||
'data: {}',
|
'data: {}',
|
||||||
'',
|
'',
|
||||||
])
|
])
|
||||||
|
assert listener.bla_called == True
|
||||||
|
assert listener.updates == []
|
||||||
|
assert listener.notifications == []
|
||||||
|
assert listener.deletes == []
|
||||||
|
assert listener.heartbeats == 0
|
||||||
|
|
||||||
|
def test_unknown_handled_event():
|
||||||
|
"""Be tolerant of new unknown event types, if on_unknown_event is available"""
|
||||||
|
listener = Listener()
|
||||||
|
listener.on_unknown_event = lambda name, payload: None
|
||||||
|
|
||||||
|
listener.handle_stream_([
|
||||||
|
'event: complete.new.event',
|
||||||
|
'data: {"k": "v"}',
|
||||||
|
'',
|
||||||
|
])
|
||||||
|
|
||||||
|
assert listener.updates == []
|
||||||
|
assert listener.notifications == []
|
||||||
|
assert listener.deletes == []
|
||||||
|
assert listener.heartbeats == 0
|
||||||
|
|
||||||
|
def test_dotted_unknown_event():
|
||||||
|
"""Be tolerant of new event types with dots in the event-name"""
|
||||||
|
listener = Listener()
|
||||||
|
listener.handle_stream_([
|
||||||
|
'event: do.something',
|
||||||
|
'data: {}',
|
||||||
|
'',
|
||||||
|
])
|
||||||
|
assert listener.do_something_called == True
|
||||||
assert listener.updates == []
|
assert listener.updates == []
|
||||||
assert listener.notifications == []
|
assert listener.notifications == []
|
||||||
assert listener.deletes == []
|
assert listener.deletes == []
|
||||||
|
@ -169,7 +207,7 @@ def test_invalid_event():
|
||||||
with pytest.raises(MastodonMalformedEventError):
|
with pytest.raises(MastodonMalformedEventError):
|
||||||
listener.handle_stream_([
|
listener.handle_stream_([
|
||||||
'event: whatup',
|
'event: whatup',
|
||||||
'data: {}',
|
'data: {"k": "v"}',
|
||||||
'',
|
'',
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
Loading…
Referencia en una nova incidència