import websockets import json from storage import Storage class Routes(): __connections = set() __storages = {} def __init__(self): self.__commands = { "add": self._add_entity, "get": self._get_entity, "mod": self._mod_entity, "del": self._del_entity, "describe": self._describe } def __storage(self, name): if not name in self.__storages: self.__storages[name] = Storage(name) return self.__storages[name] def __get_entity(self, event): return event.get("entity", None) def __get_data(self, event): return event.get("data", {}) def __get_event(self, name, event, data): return { "entity": name, "event": event, "data": data } async def _add_entity(self, websocket, event): name = self.__get_entity(event) data = self.__get_data(event) if name and data: self.__storage(name).create(data) await self._broadcast(websocket, self.__get_event(name, "created", data)) async def _get_entity(self, websocket, event): name = self.__get_entity(event) ts = self.__get_data(event).get("ts", 0) data = self.__storage(name).read(ts) await websocket.send(json.dumps(self.__get_event(name, "received", data ))) async def _mod_entity(self, websocket, event): name = self.__get_entity(event) data = self.__get_data(event) if name and data: self.__storage(name).update(data) await self._broadcast(websocket, self.__get_event(name, "modified", data)) async def _del_entity(self, websocket, event): name = self.__get_entity(event) entity_id = self.__get_data(event).get("id", None) if self.__storage(name).delete(entity_id): await self._broadcast(websocket, self.__get_event(name, "deleted", entity_id )) async def _describe(self, websocket, event): data = {} for connection in self.__connections: user_id = connection.user["id"] data[user_id] = data[user_id] + 1 if user_id in data else 1 await websocket.send(json.dumps(self.__get_event("connections", "described", data))) async def _broadcast(self, _, event): websockets.broadcast(self.__connections, json.dumps(event)) async def add_connection(self, connection): self.__connections.add(connection) await self._broadcast(connection, self.__get_event("users", "connected", connection.user)) async def remove_connection(self, connection): self.__connections.remove(connection) await self._broadcast(connection, self.__get_event("users", "disconnected", connection.user)) async def call(self, command, websocket, event): handler = self.__commands.get(command, self._broadcast) await handler(websocket, event) def users(self): return self.__storage("users").read()