Mercurial > code > home > repos > homeauto
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