diff lib/twisted_sse/sse_client.py @ 510:b1337ad3ec2d

mv twisted_sse Ignore-this: a59fadbe80bc4a393b1dab8228e022c1
author drewp@bigasterisk.com
date Mon, 22 Apr 2019 21:58:09 -0700
parents lib/twisted_sse_demo/sse_client.py@a8073bcddd8b
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/twisted_sse/sse_client.py	Mon Apr 22 21:58:09 2019 -0700
@@ -0,0 +1,67 @@
+from twisted.protocols.basic import LineReceiver
+
+
+class EventSourceProtocol(LineReceiver):
+    def __init__(self, onConnectionLost):
+        self.onConnectionLost = onConnectionLost
+        self.delimiter = b'\n'
+        self.MAX_LENGTH = 1 << 20
+        self.callbacks = {}
+        self.finished = None
+        # Initialize the event and data buffers
+        self.event = b'message'
+        self.data = b''
+
+    def lineLengthExceeded(self, line):
+        raise NotImplementedError('line too long')
+
+    def setFinishedDeferred(self, d):
+        self.finished = d
+
+    def addCallback(self, event, func):
+        self.callbacks[event] = func
+
+    def lineReceived(self, line):
+        if line == b'':
+            # Dispatch event
+            self.dispatchEvent()
+        else:
+            try:
+                field, value = line.split(b':', 1)
+                # If value starts with a space, strip it.
+                value = lstrip(value)
+            except ValueError:
+                # We got a line with no colon, treat it as a field(ignore)
+                return
+
+            if field == b'':
+                # This is a comment; ignore
+                pass
+            elif field == b'data':
+                self.data += value + b'\n'
+            elif field == b'event':
+                self.event = value
+            elif field == b'id':
+                # Not implemented
+                pass
+            elif field == b'retry':
+                # Not implemented
+                pass
+
+    def connectionLost(self, reason):
+        self.onConnectionLost(reason)
+
+    def dispatchEvent(self):
+        """
+        Dispatch the event
+        """
+        # If last character is LF, strip it.
+        if self.data.endswith(b'\n'):
+            self.data = self.data[:-1]
+        if self.event in self.callbacks:
+            self.callbacks[self.event](self.data)
+        self.data = b''
+        self.event = b'message'
+
+def lstrip(value):
+    return value[1:] if value.startswith(b' ') else value