summaryrefslogtreecommitdiff
path: root/asciifarm/common/messages.py
diff options
context:
space:
mode:
Diffstat (limited to 'asciifarm/common/messages.py')
-rw-r--r--asciifarm/common/messages.py98
1 files changed, 98 insertions, 0 deletions
diff --git a/asciifarm/common/messages.py b/asciifarm/common/messages.py
new file mode 100644
index 0000000..059094e
--- /dev/null
+++ b/asciifarm/common/messages.py
@@ -0,0 +1,98 @@
+
+import re
+import unicodedata
+
+class InvalidMessageError(Exception):
+ errType = "invalidmessage"
+ description = ""
+
+ def __init__(self, description="", errType=None):
+ self.description = description
+ if errType is not None:
+ self.errType = errType
+
+class InvalidNameError(InvalidMessageError):
+ errType = "invalidname"
+
+class Message:
+
+ @classmethod
+ def msgType(cls):
+ return cls.typename
+
+ def to_json(self):
+ raise NotImplementedError
+
+ @classmethod
+ def from_json(cls, jsonobj):
+ raise NotImplementedError
+
+class ClientToServerMessage(Message):
+
+ def body(self):
+ raise NotImplementedError
+
+ def to_json(self):
+ return [self.typename, self.body()]
+
+ @classmethod
+ def from_json(cls, jsonlist):
+ assert len(jsonlist) == 2, InvalidMessageError
+ typename, body = jsonlist
+ assert typename == cls.msgType(), InvalidMessageError
+ return cls(body)
+
+
+class NameMessage(ClientToServerMessage):
+
+ typename = "name"
+ nameRegex = re.compile("(~|\w)\w*")
+ categories = {"Lu", "Ll", "Lt", "Lm", "Lo", "Nd", "Nl", "No", "Pc"}
+
+
+ def __init__(self, name):
+ assert isinstance(name, str), InvalidNameError("name must be a string")
+ assert (len(name) > 0), InvalidNameError("name needs at least one character")
+ assert (len(bytes(name, "utf-8")) <= 256), InvalidNameError("name may not be longer than 256 utf8 bytes")
+ for char in name if name[0] != "~" else name[1:]:
+ category = unicodedata.category(char)
+ assert category in self.categories, InvalidNameError("all name caracters must be in these unicode categories: " + "|".join(self.categories) + " (except the tilde in a tildename)")
+
+ #assert (name.rfind("~") < 1), InvalidNameError("tilde character may only occur at start of name")
+ #assert (self.nameRegex.match(name) is not None), InvalidNameError("name must match the following regex: {}".format(self.nameRegex.pattern))
+ self.name = name
+
+ def body(self):
+ return self.name
+
+
+class InputMessage(ClientToServerMessage):
+
+ typename = "input"
+
+ def __init__(self, inp):
+ self.inp = inp
+
+ def body(self):
+ return self.inp
+
+class ChatMessage(ClientToServerMessage):
+
+ typename = "chat"
+
+ def __init__(self, text):
+ assert isinstance(text, str), InvalidMessageError("chat message must be a string")
+ assert text.isprintable(), InvalidMessageError("chat messages may only contain printable unicode characters")
+ self.text = text
+
+ def body(self):
+ return self.text
+
+
+
+messages = {message.msgType(): message for message in [
+ NameMessage,
+ InputMessage,
+ ChatMessage
+]}
+