diff --git a/Shared/DataTypes.py b/Shared/DataTypes.py new file mode 100644 index 0000000..23ec2ae --- /dev/null +++ b/Shared/DataTypes.py @@ -0,0 +1,4 @@ +str = b"s" +json = b"j" +bin = b"b" +other = b"o" \ No newline at end of file diff --git a/Shared/ESock.py b/Shared/ESock.py new file mode 100644 index 0000000..b670c09 --- /dev/null +++ b/Shared/ESock.py @@ -0,0 +1,58 @@ +import json +import socket +import struct +import time +import DataTypes + +class ESock: + def __init__(self, sock): + self._sock = sock + + def __getattr__(self, attr): + if attr == "recv": + return self.recv + elif attr == "send": + return self.send + return getattr(self._sock, attr) + + + def recv(self): + raw_metadata = self._sock.recv(8) + if raw_metadata == b"": + self._sock.close() + raise socket.error("Connection closed") + metadata = struct.unpack("cI", raw_metadata) + data_type = metadata[0] + data_length = metadata[1] + data = b'' + bufsize = 4096 + while len(data) < data_length: + if len(data) + bufsize <= data_length: + packet = self._sock.recv(bufsize) + else: + packet = self._sock.recv(data_length % bufsize) + if not packet: + return None + data += packet + if data_type == DataTypes.str: + data = data.decode() + elif data_type == DataTypes.json: + data = json.loads(data.decode()) + return data, data_type + + def send(self, data): + data_type = type(data) + if data_type is str: + data = data.encode() + self.sendall(struct.pack("cI", DataTypes.str, len(data)) + data) + elif data_type is dict or data_type is list: + data = json.dumps(data).encode() + self.sendall(struct.pack("cI", DataTypes.json, len(data)) + data) + elif data_type is bytes: + self.sendall(struct.pack("cI", DataTypes.bin, len(data)) + data) + else: + self.sendall(struct.pack("cI", DataTypes.other, len(data)) + data) + + + def __eq__(self, other): + return self.__dict == other.__dict__ \ No newline at end of file diff --git a/Shared/Logging.py b/Shared/Logging.py new file mode 100644 index 0000000..6b363fd --- /dev/null +++ b/Shared/Logging.py @@ -0,0 +1,59 @@ +import time +import inspect + +""" +HEADER = '\033[95m' Magenta +OKBLUE = '\033[94m' Blue +OKGREEN = '\033[92m' Green +WARNING = '\033[93m' Yellow +FAIL = '\033[91m' Red +ENDC = '\033[0m' +BOLD = '\033[1m' +""" + +# If the stack becomes too complex to figure out a caller we go through and assume the first valid module is the caller. +# This works reasonably well but isn't 100% accurate and will only happen if the caller is a thread. +def print_out(message, color): + stack = inspect.stack() + # Interestingly the if statement below is not executed when excepting KeyboardInterrupts. Weird. + # To prevent a crash we assume the module's name is 'Unknown' + module = "Unknown" + if inspect.getmodule(stack[2][0]) == None: + for i in stack[2:]: + if inspect.getmodule(i[0]) != None: + module = inspect.getmodule(i[0]).__name__ + else: + module = inspect.getmodule(stack[2][0]).__name__ + print("[%s] %s: %s%s\033[0m" % (time.strftime("%x %H:%M:%S"), module, color, message)) + + +def info(message): + print_out(message, '') + + +def header(message): + print_out(message, '\033[95m') + + +def warning(message): + print_out(message, '\033[93m') + + +def error(message): + print_out(message, '\033[91m') + + +def success(message, color="green"): + if color == "green": + print_out(message, '\033[92m') + elif color == "blue": + print_out(message, '\033[94m') + + +def bold(message): + print_out(message, '\033[1m') + + +def underline(message): + print_out(message, '\033[1m') +