From 40b8bd42fd3f2f2ea38fce342a421ebf09812829 Mon Sep 17 00:00:00 2001 From: retoor Date: Thu, 5 Dec 2024 19:34:58 +0100 Subject: [PATCH] Initial commit. --- .gitignore | 6 + Makefile | 28 ++++ dist/ragnar-1.3.37.tar.gz | Bin 0 -> 2507 bytes dist/rchat-1.0.0-py3-none-any.whl | Bin 0 -> 3542 bytes dist/rchat-1.0.0.tar.gz | Bin 0 -> 2915 bytes pyproject.toml | 3 + setup.cfg | 28 ++++ src/rchat.egg-info/PKG-INFO | 14 ++ src/rchat.egg-info/SOURCES.txt | 12 ++ src/rchat.egg-info/dependency_links.txt | 1 + src/rchat.egg-info/entry_points.txt | 2 + src/rchat.egg-info/requires.txt | 5 + src/rchat.egg-info/top_level.txt | 1 + src/rchat/__init__.py | 5 + src/rchat/__main__.py | 14 ++ src/rchat/app.py | 134 ++++++++++++++++ src/rchat/faker.py | 3 + src/rchat/static/index.html | 204 ++++++++++++++++++++++++ 18 files changed, 460 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 dist/ragnar-1.3.37.tar.gz create mode 100644 dist/rchat-1.0.0-py3-none-any.whl create mode 100644 dist/rchat-1.0.0.tar.gz create mode 100644 pyproject.toml create mode 100644 setup.cfg create mode 100644 src/rchat.egg-info/PKG-INFO create mode 100644 src/rchat.egg-info/SOURCES.txt create mode 100644 src/rchat.egg-info/dependency_links.txt create mode 100644 src/rchat.egg-info/entry_points.txt create mode 100644 src/rchat.egg-info/requires.txt create mode 100644 src/rchat.egg-info/top_level.txt create mode 100644 src/rchat/__init__.py create mode 100644 src/rchat/__main__.py create mode 100644 src/rchat/app.py create mode 100644 src/rchat/faker.py create mode 100644 src/rchat/static/index.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c7d91b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.vscode +rchat.db* +config.py +.venv +.history +__pycache__ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..35cc240 --- /dev/null +++ b/Makefile @@ -0,0 +1,28 @@ +BIN = ./.venv/bin/ +PYTHON = ./.venv/bin/python +PIP = ./.venv/bin/pip + +APP_NAME=rchat + +all: ensure_repo ensure_env format install build + +ensure_repo: + -@git init + +ensure_env: + -@python3 -m venv .venv + +install: + $(PIP) install -e . + +format: + $(PIP) install shed + . $(BIN)/activate && shed + +build: format install + $(PIP) install build + $(PYTHON) -m build + +run: + $(BIN)rchat.serve + diff --git a/dist/ragnar-1.3.37.tar.gz b/dist/ragnar-1.3.37.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..35eb21555b2aaaac33097b66da2696c0eea4842e GIT binary patch literal 2507 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 SWx{bZ=ILY^DY{}hy8i+%H!Rrz literal 0 HcmV?d00001 diff --git a/dist/rchat-1.0.0-py3-none-any.whl b/dist/rchat-1.0.0-py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..63559298c8a57c613ba8e379690938b2cb13e66b GIT binary patch literal 3542 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 literal 0 HcmV?d00001 diff --git a/dist/rchat-1.0.0.tar.gz b/dist/rchat-1.0.0.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..9d5584deb3d0b0a11cd768381a2ea6fdd5038544 GIT binary patch literal 2915 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.7 +install_requires = + aiohttp + faker + dataset + app @ git+https://retoor.molodetz.nl/retoor/app.git + mololog @ git+https://retoor.molodetz.nl/retoor/mololog.git + +[options.packages.find] +where = src + +[options.entry_points] +console_scripts = + rchat.serve = rchat.__main__:main diff --git a/src/rchat.egg-info/PKG-INFO b/src/rchat.egg-info/PKG-INFO new file mode 100644 index 0000000..5ed40a3 --- /dev/null +++ b/src/rchat.egg-info/PKG-INFO @@ -0,0 +1,14 @@ +Metadata-Version: 2.1 +Name: rchat +Version: 1.0.0 +Summary: rchat +Author: retoor +Author-email: retoor@molodetz.nl +License: MIT +Requires-Python: >=3.7 +Description-Content-Type: text/markdown +Requires-Dist: aiohttp +Requires-Dist: faker +Requires-Dist: dataset +Requires-Dist: app@ git+https://retoor.molodetz.nl/retoor/app.git +Requires-Dist: mololog@ git+https://retoor.molodetz.nl/retoor/mololog.git diff --git a/src/rchat.egg-info/SOURCES.txt b/src/rchat.egg-info/SOURCES.txt new file mode 100644 index 0000000..cd2cf3b --- /dev/null +++ b/src/rchat.egg-info/SOURCES.txt @@ -0,0 +1,12 @@ +pyproject.toml +setup.cfg +src/rchat/__init__.py +src/rchat/__main__.py +src/rchat/app.py +src/rchat/faker.py +src/rchat.egg-info/PKG-INFO +src/rchat.egg-info/SOURCES.txt +src/rchat.egg-info/dependency_links.txt +src/rchat.egg-info/entry_points.txt +src/rchat.egg-info/requires.txt +src/rchat.egg-info/top_level.txt \ No newline at end of file diff --git a/src/rchat.egg-info/dependency_links.txt b/src/rchat.egg-info/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/rchat.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/src/rchat.egg-info/entry_points.txt b/src/rchat.egg-info/entry_points.txt new file mode 100644 index 0000000..766c935 --- /dev/null +++ b/src/rchat.egg-info/entry_points.txt @@ -0,0 +1,2 @@ +[console_scripts] +rchat.serve = rchat.__main__:main diff --git a/src/rchat.egg-info/requires.txt b/src/rchat.egg-info/requires.txt new file mode 100644 index 0000000..2bd7e86 --- /dev/null +++ b/src/rchat.egg-info/requires.txt @@ -0,0 +1,5 @@ +aiohttp +faker +dataset +app@ git+https://retoor.molodetz.nl/retoor/app.git +mololog@ git+https://retoor.molodetz.nl/retoor/mololog.git diff --git a/src/rchat.egg-info/top_level.txt b/src/rchat.egg-info/top_level.txt new file mode 100644 index 0000000..e189468 --- /dev/null +++ b/src/rchat.egg-info/top_level.txt @@ -0,0 +1 @@ +rchat diff --git a/src/rchat/__init__.py b/src/rchat/__init__.py new file mode 100644 index 0000000..a2d757f --- /dev/null +++ b/src/rchat/__init__.py @@ -0,0 +1,5 @@ +import logging + +logging.basicConfig(level=logging.INFO) + +log = logging.getLogger(__name__) diff --git a/src/rchat/__main__.py b/src/rchat/__main__.py new file mode 100644 index 0000000..a5ed602 --- /dev/null +++ b/src/rchat/__main__.py @@ -0,0 +1,14 @@ +from aiohttp import web + +from rchat.app import create_app + + +def main(): + app = create_app() + web.run_app(app, port=8080) + + +# Run the server +if __name__ == "__main__": + main() +# static/index.html diff --git a/src/rchat/app.py b/src/rchat/app.py new file mode 100644 index 0000000..551adf9 --- /dev/null +++ b/src/rchat/app.py @@ -0,0 +1,134 @@ +# server.py +import json +import pathlib +import uuid + +import aiohttp +from aiohttp import web +from app.app import Application as BaseApplication +from mololog.client import patch + +from rchat.faker import fake + +patch("https://mololog.molodetz.nl/") + + +class Application(BaseApplication): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.clients = {} + self.sessions = {} + self.base_folder = pathlib.Path(__file__).parent + self.static_folder = self.base_folder.joinpath("static") + self.router.add_get("/ws", self.websocket_handler) + self.router.add_get("/", self.index_handler) + self.router.add_static("/", path=self.static_folder, name="static") + + async def index_handler(self, request): + content = self.static_folder.joinpath("index.html") + + return web.Response(body=content.read_text(), content_type="text/html") + + async def websocket_handler(self, request): + ws = web.WebSocketResponse() + await ws.prepare(request) + session = request.session + if not 'username' in session: + session['username'] = fake.name().split(" ")[0] + session['uid'] = str(uuid.uuid4()) + session['session_id'] = session['uid'] + + username = session["username"] + session_id = session["session_id"] + uid = session["uid"] + + response = ws + response.set_cookie( + samesite=True, + name="rchat_session", + value=session_id, + max_age=365 * 24 * 60 * 60, + httponly=True, + ) + + try: + + for message in await self.find("messages", {}): + await ws.send_json(message) + + await ws.send_json( + { + "type": "system", + "message": f'Welcome, your name is {session["username"]}.', + } + ) + + await self.broadcast( + {"type": "system", "message": f"{username} joined the chat."} + ) + + self.clients[uid] = ws + + async for msg in ws: + if msg.type == aiohttp.WSMsgType.TEXT: + try: + data = json.loads(msg.data) + + message = data.get("message") + if message: + if message.startswith("/nick "): + original_name = session["username"] + session["username"] = message[len("/nick ") :] + + await self.broadcast( + { + "type": "system", + "message": f'{original_name} is renamed to {session["username"]}.', + } + ) + + continue + + await self.broadcast( + { + "type": "chat", + "sender": session["username"], + "message": data.get("message", ""), + } + ) + + except json.JSONDecodeError: + await ws.send_json( + {"type": "error", "message": "Invalid message format."} + ) + + elif msg.type == aiohttp.WSMsgType.ERROR: + print( + f"WebSocket connection closed with exception {ws.exception()}." + ) + + finally: + if uid in self.clients: + del self.clients[uid] + await self.broadcast( + {"type": "system", "message": f"{username} left the chat."}, + exclude=uid, + ) + + return ws + + async def broadcast(self, message, exclude=None): + await self.insert("messages", message) + for uid, client_ws in self.clients.items(): + if uid == exclude: + continue + try: + await client_ws.send_json(message) + except Exception as e: + print(f"Error sending to client {uid}: {e}.") + + +def create_app(): + app = Application() + + return app diff --git a/src/rchat/faker.py b/src/rchat/faker.py new file mode 100644 index 0000000..3b09bd3 --- /dev/null +++ b/src/rchat/faker.py @@ -0,0 +1,3 @@ +from faker import Faker + +fake = Faker() diff --git a/src/rchat/static/index.html b/src/rchat/static/index.html new file mode 100644 index 0000000..936dcec --- /dev/null +++ b/src/rchat/static/index.html @@ -0,0 +1,204 @@ + + + + + rchat + + + + +
+
+
+ + + +
+
+ + + + + \ No newline at end of file