From e290a9f5cb7985c63f564e968fb404769266c775 Mon Sep 17 00:00:00 2001 From: retoor Date: Fri, 31 Jan 2025 11:06:23 +0000 Subject: [PATCH] feat: add asyncssh dependency, snecssh service, gallery CSS, and traceback in RPC error handling Add snecssh service to compose.yml with asyncssh dependency in pyproject.toml. Introduce gallery and tile CSS classes in base.css for image grid layout. Include commented-out tile-grid and upload-button elements in chat-window.js. Load media-upload.js script in web.html template. Wrap RPC method execution in try-except to return structured error response with exception message and formatted traceback. --- compose.yml | 15 ++++++++++++++- pyproject.toml | 3 ++- src/snek/static/base.css | 23 +++++++++++++++++++++++ src/snek/static/chat-window.js | 9 ++++++++- src/snek/templates/web.html | 1 + src/snek/view/rpc.py | 9 +++++++-- 6 files changed, 55 insertions(+), 5 deletions(-) diff --git a/compose.yml b/compose.yml index 7be013dd..ce2b02c9 100644 --- a/compose.yml +++ b/compose.yml @@ -10,4 +10,17 @@ services: - PYTHONDONTWRITEBYTECODE="1" entrypoint: ["gunicorn", "-w", "1", "-k", "aiohttp.worker.GunicornWebWorker", "snek.gunicorn:app","--bind","0.0.0.0:8081"] #["python","-m","snek.app"] - \ No newline at end of file + snecssh: + build: + context: . + dockerfile: DockerfileDrive + restart: always + ports: + - "2225:2225" + volumes: + - ./:/code + environment: + - PYTHONDONTWRITEBYTECODE="1" + entrypoint: ["python","-m","snekssh.app2"] + #["python","-m","snek.app"] + diff --git a/pyproject.toml b/pyproject.toml index 22ec4eb9..a2a0ccb6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,6 +24,7 @@ dependencies = [ "mistune", "aiohttp-session", "cryptography", - "requests" + "requests", + "asyncssh" ] diff --git a/src/snek/static/base.css b/src/snek/static/base.css index 42d4b33e..46b9fef3 100644 --- a/src/snek/static/base.css +++ b/src/snek/static/base.css @@ -4,6 +4,29 @@ box-sizing: border-box; } +.gallery { + padding: 50px; + height: auto; + overflow: auto; + flex: 1; + &.tile { + width: 100px; + height: 100px; + object-fit: cover; + margin-right: 10px; + border-radius: 5px; + margin: 20px; + } +} +.tile { + + width: 100px; + height: 100px; + object-fit: cover; + margin-right: 10px; + border-radius: 5px; + margin: 20px; +} body { font-family: Arial, sans-serif; diff --git a/src/snek/static/chat-window.js b/src/snek/static/chat-window.js index bdad37e1..58845b4c 100644 --- a/src/snek/static/chat-window.js +++ b/src/snek/static/chat-window.js @@ -23,6 +23,7 @@ class ChatWindowElement extends HTMLElement { const chatHeader = document.createElement("div") chatHeader.classList.add("chat-header") + const chatTitle = document.createElement('h2') @@ -37,7 +38,13 @@ class ChatWindowElement extends HTMLElement { channelElement.setAttribute("channel", channel.uid) //channelElement.classList.add("chat-messages") this.container.appendChild(channelElement) - + //const tileElement = document.createElement('tile-grid') + //tileElement.classList.add("message-list") + //this.container.appendChild(tileElement) + //const uploadButton = document.createElement('upload-button') + //uploadButton.grid = tileElement + //uploadButton.setAttribute('grid', "#grid") + //this.container.appendChild(uploadButton) const chatInput = document.createElement('chat-input') chatInput.addEventListener("submit",(e)=>{ diff --git a/src/snek/templates/web.html b/src/snek/templates/web.html index b2e96771..3882548a 100644 --- a/src/snek/templates/web.html +++ b/src/snek/templates/web.html @@ -4,6 +4,7 @@ Snek + diff --git a/src/snek/view/rpc.py b/src/snek/view/rpc.py index b48f4d0c..3619bd66 100644 --- a/src/snek/view/rpc.py +++ b/src/snek/view/rpc.py @@ -1,5 +1,6 @@ from aiohttp import web from snek.system.view import BaseView +import traceback class RPCView(BaseView): @@ -117,7 +118,11 @@ class RPCView(BaseView): method = getattr(self,method_name.replace(".","_"),None) if not method: raise Exception("Method not found") - result = await method(*args) + try: + result = await method(*args) + except Exception as ex: + result = dict({"callId":call_id,"success": False, "data":{"exception":str(ex),"traceback":traceback.format_exc()}}) + #dict(error=ex=str(ex),traceback=traceback.format_exc()) await self.ws.send_json({"callId":call_id,"success":True,"data":result}) except Exception as ex: await self.ws.send_json({"callId":call_id,"success":False,"data":str(ex)}) @@ -145,4 +150,4 @@ class RPCView(BaseView): await self.services.socket.delete(ws) print("WebSocket connection closed") - return ws \ No newline at end of file + return ws