message.py 2.31 KB
# -*- coding: utf-8 -*-
__all__ = ["decode", "Message", "OkMessage", "KoMessage", "DownloadRequest"
        , "UploadRequest", "DownloadPrimRequest", "ClientDone", "ServerDone"
        , "NumMessage", "BoolMessage", "ReturnRequest", "CheckoutRequest",
        "CheckinRequest", "StatsRequest"]


class Message(object):

    """
    Base class for SSL communication messages.
    """

    def __init__(self, contents=""):
        self.contents = contents

    def get_contents(self):
        return self.contents

    @classmethod
    def from_contents(cls, contents):
        return cls(contents)

    def encode(self):
        """
        Prepare message to be sent over network.
        WARNING: Do not override this method.
        """
        # Add "-" on the beggining to prevent
        # message contents from being void.
        return self.msg_type, "-" + self.get_contents()


class NumMessage(Message):

    def __init__(self, n):
        self.number = n

    def get_contents(self):
        return str(self.number)

    @classmethod
    def from_contents(cls, contents):
        return cls(int(contents))

    def get_number(self):
        return self.number


class BoolMessage(Message):

    def __init__(self, b):
        self.b = b

    def get_contents(self):
        return "1" if self.b else "0"

    @classmethod
    def from_contents(cls, contents):
        return cls(bool(int(contents)))

    def get_boolean(self):
        return self.b

class ReturnRequest(NumMessage):
    pass

class CheckoutRequest(Message):
    pass

class CheckinRequest(NumMessage):
    pass

class DownloadRequest(NumMessage):
    pass

class DownloadPrimRequest(NumMessage):
    pass

class UploadRequest(NumMessage):
    pass

class OkMessage(Message):
    pass

class KoMessage(Message):
    pass

class StatsRequest(Message):
    pass

class ServerDone(Message):
    pass

class ClientDone(Message):
    pass


def subclasses(cls):
    yield cls
    for child in cls.__subclasses__():
        for desc in subclasses(child):
            yield desc

def decode(msg_type, contents):
    for cls in subclasses(Message):
        if cls.msg_type == msg_type:
            # Discard first, dummy character;
            # Confront Message.encode method.
            return cls.from_contents(contents[1:])

for i, cls in enumerate(subclasses(Message)):
    cls.msg_type = i