diff options
author | Lorenz Diener <[email protected]> | 2017-11-24 15:08:34 +0100 |
---|---|---|
committer | Lorenz Diener <[email protected]> | 2017-11-24 15:08:34 +0100 |
commit | e220e7cc60839ee1e3b27781b3b1cb609e593f85 (patch) | |
tree | 0575d9a30ad250247f7b3bb171cedfb0d4e8af60 /mastodon | |
parent | cea4d4251a0b998ae734811ee78651d60a138d3e (diff) | |
download | mastodon.py-e220e7cc60839ee1e3b27781b3b1cb609e593f85.tar.gz |
Many fixes for streaming stuff
Diffstat (limited to 'mastodon')
-rw-r--r-- | mastodon/Mastodon.py | 26 | ||||
-rw-r--r-- | mastodon/__init__.py | 4 | ||||
-rw-r--r-- | mastodon/streaming.py | 44 |
3 files changed, 42 insertions, 32 deletions
diff --git a/mastodon/Mastodon.py b/mastodon/Mastodon.py index c35ad2d..9b28861 100644 --- a/mastodon/Mastodon.py +++ b/mastodon/Mastodon.py | |||
@@ -17,10 +17,11 @@ import re | |||
17 | import copy | 17 | import copy |
18 | import threading | 18 | import threading |
19 | import sys | 19 | import sys |
20 | |||
20 | try: | 21 | try: |
21 | from urllib.parse import urlparse | 22 | from urllib.parse import urlparse |
22 | except ImportError: | 23 | except ImportError: |
23 | from urlparse import urlparse | 24 | from urlparse import urlparse |
24 | 25 | ||
25 | 26 | ||
26 | class Mastodon: | 27 | class Mastodon: |
@@ -1014,12 +1015,6 @@ class Mastodon: | |||
1014 | Streams events that are relevant to the authorized user, i.e. home | 1015 | Streams events that are relevant to the authorized user, i.e. home |
1015 | timeline and notifications. 'listener' should be a subclass of | 1016 | timeline and notifications. 'listener' should be a subclass of |
1016 | StreamListener which will receive callbacks for incoming events. | 1017 | StreamListener which will receive callbacks for incoming events. |
1017 | |||
1018 | If async is False, this method blocks forever. | ||
1019 | |||
1020 | If async is True, 'listener' will listen on another thread and this method | ||
1021 | will return a handle corresponding to the open connection. The | ||
1022 | connection may be closed at any time by calling its close() method. | ||
1023 | """ | 1018 | """ |
1024 | return self.__stream('/api/v1/streaming/user', listener, async=async) | 1019 | return self.__stream('/api/v1/streaming/user', listener, async=async) |
1025 | 1020 | ||
@@ -1027,12 +1022,6 @@ class Mastodon: | |||
1027 | """ | 1022 | """ |
1028 | Streams public events. 'listener' should be a subclass of StreamListener | 1023 | Streams public events. 'listener' should be a subclass of StreamListener |
1029 | which will receive callbacks for incoming events. | 1024 | which will receive callbacks for incoming events. |
1030 | |||
1031 | If async is False, this method blocks forever. | ||
1032 | |||
1033 | If async is True, 'listener' will listen on another thread and this method | ||
1034 | will return a handle corresponding to the open connection. The | ||
1035 | connection may be closed at any time by calling its close() method. | ||
1036 | """ | 1025 | """ |
1037 | return self.__stream('/api/v1/streaming/public', listener, async=async) | 1026 | return self.__stream('/api/v1/streaming/public', listener, async=async) |
1038 | 1027 | ||
@@ -1041,11 +1030,6 @@ class Mastodon: | |||
1041 | Streams local events. 'listener' should be a subclass of StreamListener | 1030 | Streams local events. 'listener' should be a subclass of StreamListener |
1042 | which will receive callbacks for incoming events. | 1031 | which will receive callbacks for incoming events. |
1043 | 1032 | ||
1044 | If async is False, this method blocks forever. | ||
1045 | |||
1046 | If async is True, 'listener' will listen on another thread and this method | ||
1047 | will return a handle corresponding to the open connection. The | ||
1048 | connection may be closed at any time by calling its close() method. | ||
1049 | """ | 1033 | """ |
1050 | return self.__stream('/api/v1/streaming/public/local', listener, async=async) | 1034 | return self.__stream('/api/v1/streaming/public/local', listener, async=async) |
1051 | 1035 | ||
@@ -1054,12 +1038,6 @@ class Mastodon: | |||
1054 | Returns all public statuses for the hashtag 'tag'. 'listener' should be | 1038 | Returns all public statuses for the hashtag 'tag'. 'listener' should be |
1055 | a subclass of StreamListener which will receive callbacks for incoming | 1039 | a subclass of StreamListener which will receive callbacks for incoming |
1056 | events. | 1040 | events. |
1057 | |||
1058 | If async is False, this method blocks forever. | ||
1059 | |||
1060 | If async is True, 'listener' will listen on another thread and this method | ||
1061 | will return a handle corresponding to the open connection. The | ||
1062 | connection may be closed at any time by calling its close() method. | ||
1063 | """ | 1041 | """ |
1064 | return self.__stream("/api/v1/streaming/hashtag?tag={}".format(tag), listener) | 1042 | return self.__stream("/api/v1/streaming/hashtag?tag={}".format(tag), listener) |
1065 | 1043 | ||
diff --git a/mastodon/__init__.py b/mastodon/__init__.py index 3123356..fdf776d 100644 --- a/mastodon/__init__.py +++ b/mastodon/__init__.py | |||
@@ -1,4 +1,4 @@ | |||
1 | from mastodon.Mastodon import Mastodon | 1 | from mastodon.Mastodon import Mastodon |
2 | from mastodon.streaming import StreamListener | 2 | from mastodon.streaming import StreamListener, CallbackStreamListener |
3 | 3 | ||
4 | __all__ = ['Mastodon', 'StreamListener'] | 4 | __all__ = ['Mastodon', 'StreamListener', 'CallbackStreamListener'] |
diff --git a/mastodon/streaming.py b/mastodon/streaming.py index cac2456..92a02dc 100644 --- a/mastodon/streaming.py +++ b/mastodon/streaming.py | |||
@@ -67,10 +67,6 @@ class StreamListener(object): | |||
67 | else: | 67 | else: |
68 | event[key] = value | 68 | event[key] = value |
69 | 69 | ||
70 | # end of stream | ||
71 | if event: | ||
72 | log.warn("outstanding partial event at end of stream: %s", event) | ||
73 | |||
74 | def _dispatch(self, event): | 70 | def _dispatch(self, event): |
75 | try: | 71 | try: |
76 | name = event['event'] | 72 | name = event['event'] |
@@ -92,8 +88,44 @@ class StreamListener(object): | |||
92 | handler_name = 'on_' + name | 88 | handler_name = 'on_' + name |
93 | try: | 89 | try: |
94 | handler = getattr(self, handler_name) | 90 | handler = getattr(self, handler_name) |
95 | except AttributeError: | 91 | except AttributeError as err: |
96 | log.warn("Unhandled event '%s'", name) | 92 | six.raise_from( |
93 | MastodonMalformedEventError('Bad event type', name), | ||
94 | err | ||
95 | ) | ||
97 | else: | 96 | else: |
98 | # TODO: allow handlers to return/raise to stop streaming cleanly | 97 | # TODO: allow handlers to return/raise to stop streaming cleanly |
99 | handler(payload) | 98 | handler(payload) |
99 | |||
100 | class CallbackStreamListener(StreamListener): | ||
101 | """ | ||
102 | Simple callback stream handler class. | ||
103 | Can optionally additionally send local update events to a separate handler. | ||
104 | """ | ||
105 | def __init__(self, update_handler = None, local_update_handler = None, delete_handler = None, notification_handler = None): | ||
106 | super(CallbackStreamListener, self).__init__() | ||
107 | self.update_handler = update_handler | ||
108 | self.local_update_handler = local_update_handler | ||
109 | self.delete_handler = delete_handler | ||
110 | self.notification_handler = notification_handler | ||
111 | |||
112 | def on_update(self, status): | ||
113 | if self.update_handler != None: | ||
114 | self.update_handler(status) | ||
115 | |||
116 | try: | ||
117 | if self.local_update_handler != None and not "@" in status["account"]["acct"]: | ||
118 | self.local_update_handler(status) | ||
119 | except Exception as err: | ||
120 | six.raise_from( | ||
121 | MastodonMalformedEventError('received bad update', status), | ||
122 | err | ||
123 | ) | ||
124 | |||
125 | def on_delete(self, deleted_id): | ||
126 | if self.delete_handler != None: | ||
127 | self.delete_handler(deleted_id) | ||
128 | |||
129 | def on_notification(self, notification): | ||
130 | if self.notification_handler != None: | ||
131 | self.notification_handler(notification) \ No newline at end of file | ||