Routes was moved to self class
This commit is contained in:
@@ -4,6 +4,7 @@ RUN pip install websockets
|
|||||||
|
|
||||||
WORKDIR /beerlog-srv
|
WORKDIR /beerlog-srv
|
||||||
COPY beerlog-srv.py .
|
COPY beerlog-srv.py .
|
||||||
|
COPY routes.py .
|
||||||
COPY storage.py .
|
COPY storage.py .
|
||||||
|
|
||||||
ARG BEERLOG_PORT
|
ARG BEERLOG_PORT
|
||||||
|
|||||||
@@ -5,84 +5,31 @@ import websockets
|
|||||||
import json
|
import json
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
from storage import Storage
|
from routes import Routes
|
||||||
|
|
||||||
|
|
||||||
|
routes = Routes()
|
||||||
|
|
||||||
CONNECTIONS = set()
|
|
||||||
STORAGES = { "users": Storage("users") }
|
|
||||||
|
|
||||||
class UserInfoProtocol(websockets.BasicAuthWebSocketServerProtocol):
|
class UserInfoProtocol(websockets.BasicAuthWebSocketServerProtocol):
|
||||||
async def check_credentials(self, username, password):
|
async def check_credentials(self, username, password):
|
||||||
all_users = storage("users").read()
|
all_users = routes.users()
|
||||||
self.user = all_users[username] if username in all_users else None
|
self.user = all_users.get(username, None)
|
||||||
return self.user != None
|
return self.user != None
|
||||||
|
|
||||||
def storage(name):
|
|
||||||
if not name in STORAGES:
|
|
||||||
STORAGES[name] = Storage(name)
|
|
||||||
return STORAGES[name]
|
|
||||||
|
|
||||||
def _get_entity(event):
|
|
||||||
return event.get("entity", None)
|
|
||||||
|
|
||||||
def _get_data(event):
|
|
||||||
return event.get("data", {})
|
|
||||||
|
|
||||||
async def add_entity(websocket, event):
|
|
||||||
name = _get_entity(event)
|
|
||||||
data = _get_data(event)
|
|
||||||
if name and data:
|
|
||||||
storage(name).create(data)
|
|
||||||
await broadcast(websocket, { "entity": name, "event": "created", "data": data })
|
|
||||||
|
|
||||||
async def get_entity(websocket, event):
|
|
||||||
name = _get_entity(event)
|
|
||||||
ts = _get_data(event).get("ts", 0)
|
|
||||||
data = storage(name).read(ts)
|
|
||||||
await websocket.send(json.dumps({ "entity": name, "event": "received", "data": data }))
|
|
||||||
|
|
||||||
async def mod_entity(websocket, event):
|
|
||||||
name = _get_entity(event)
|
|
||||||
data = _get_data(event)
|
|
||||||
if name and data:
|
|
||||||
storage(name).update(data)
|
|
||||||
await broadcast(websocket, { "entity": name, "event": "modified", "data": data })
|
|
||||||
|
|
||||||
async def del_entity(websocket, event):
|
|
||||||
name = _get_entity(event)
|
|
||||||
entity_id = _get_data(event).get("id", None)
|
|
||||||
if storage(name).delete(entity_id):
|
|
||||||
await broadcast(websocket, { "entity": name, "event": "deleted", "data": entity_id })
|
|
||||||
|
|
||||||
async def describe(websocket, event):
|
|
||||||
connections = list(CONNECTIONS)
|
|
||||||
data = { c.user["id"]: connections.count(c) for c in connections }
|
|
||||||
await websocket.send(json.dumps({ "entity": "connections", "event": "described", "data": data }))
|
|
||||||
|
|
||||||
async def broadcast(websocket, event):
|
|
||||||
websockets.broadcast(CONNECTIONS, json.dumps(event))
|
|
||||||
|
|
||||||
COMMANDS = {
|
|
||||||
"add": add_entity,
|
|
||||||
"get": get_entity,
|
|
||||||
"mod": mod_entity,
|
|
||||||
"del": del_entity,
|
|
||||||
"describe": describe
|
|
||||||
}
|
|
||||||
|
|
||||||
async def handle(websocket):
|
async def handle(websocket):
|
||||||
try:
|
try:
|
||||||
CONNECTIONS.add(websocket)
|
await routes.add_connection(websocket)
|
||||||
await broadcast(websocket, { "event": "connected", "entity": "users", "data": websocket.user})
|
|
||||||
|
|
||||||
async for message in websocket:
|
async for message in websocket:
|
||||||
event = json.loads(message)
|
event = json.loads(message)
|
||||||
print(event, file=sys.stderr)
|
print(event, file=sys.stderr)
|
||||||
handler = COMMANDS.get(event["action"], broadcast)
|
await routes.call(event["action"], websocket, event)
|
||||||
await handler(websocket, event)
|
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
CONNECTIONS.remove(websocket)
|
await routes.remove_connection(websocket)
|
||||||
await broadcast(websocket, { "event": "disconnected", "entity": "users", "data": websocket.user})
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
port = os.environ.get("BEERLOG_PORT", 8000)
|
port = os.environ.get("BEERLOG_PORT", 8000)
|
||||||
@@ -91,5 +38,5 @@ async def main():
|
|||||||
async with websockets.serve(handle, host, port, create_protocol=UserInfoProtocol):
|
async with websockets.serve(handle, host, port, create_protocol=UserInfoProtocol):
|
||||||
await asyncio.Future()
|
await asyncio.Future()
|
||||||
|
|
||||||
asyncio.run(main())
|
|
||||||
|
|
||||||
|
asyncio.run(main())
|
||||||
|
|||||||
80
routes.py
Normal file
80
routes.py
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
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 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 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 broadcast(websocket, self.__get_event(name, "deleted", entity_id ))
|
||||||
|
|
||||||
|
async def _describe(self, websocket, event):
|
||||||
|
connections = list(self.__connections)
|
||||||
|
data = { c.user["id"]: connections.count(c) for c in connections }
|
||||||
|
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()
|
||||||
Reference in New Issue
Block a user