view lib/twisted_sse_demo/sse_client.py @ 1250:81ab17e377b7

patchsource py3 support. might break py2 Ignore-this: e7559afeb74ffa53bf2085f78455014 darcs-hash:3bc2fc52891ea205aa79f89a16d3d7b341cda35e
author drewp <drewp@bigasterisk.com>
date Thu, 18 Apr 2019 21:58:19 -0700
parents ee168d55524a
children 9e1f067010b3
line wrap: on
line source

from twisted.protocols.basic import LineReceiver


class EventSourceProtocol(LineReceiver):
    def __init__(self):
        self.MAX_LENGTH = 1 << 20
        self.callbacks = {}
        self.finished = None
        # Initialize the event and data buffers
        self.event = 'message'
        self.data = ''

    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 == '':
            # Dispatch event
            self.dispatchEvent()
        else:
            try:
                field, value = line.split(':', 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 == '':
                # This is a comment; ignore
                pass
            elif field == 'data':
                self.data += value + '\n'
            elif field == 'event':
                self.event = value
            elif field == 'id':
                # Not implemented
                pass
            elif field == 'retry':
                # Not implemented
                pass

    def connectionLost(self, reason):
        if self.finished:
            self.finished.callback(None)

    def dispatchEvent(self):
        """
        Dispatch the event
        """
        # If last character is LF, strip it.
        if self.data.endswith('\n'):
            self.data = self.data[:-1]
        if self.event in self.callbacks:
            self.callbacks[self.event](self.data)
        self.data = ''
        self.event = 'message'

def lstrip(value):
    return value[1:] if value.startswith(' ') else value