From 6f61fa323bba5e4c1da5949b445f0bbf0d5b76f7 Mon Sep 17 00:00:00 2001 From: retoor Date: Mon, 18 Aug 2025 22:28:14 +0200 Subject: [PATCH] Update. --- src/snek/app.py | 13 +++++- src/snek/service/channel_member.py | 14 +++--- src/snek/service/channel_message.py | 70 +++++++++++++---------------- src/snek/static/chat-input.js | 9 ++-- src/snek/view/rpc.py | 1 + 5 files changed, 53 insertions(+), 54 deletions(-) diff --git a/src/snek/app.py b/src/snek/app.py index c90db06..5b9bb7d 100644 --- a/src/snek/app.py +++ b/src/snek/app.py @@ -1,3 +1,6 @@ +import faulthandler +faulthandler.enable() + import asyncio import logging import pathlib @@ -24,7 +27,7 @@ from aiohttp_session import ( from aiohttp_session.cookie_storage import EncryptedCookieStorage from app.app import Application as BaseApplication from jinja2 import FileSystemLoader - +from snek.system.session import SQLiteSessionStorage from snek.forum import setup_forum from snek.mapper import get_mappers from snek.service import get_services @@ -151,7 +154,8 @@ class Application(BaseApplication): **kwargs, ) self.db = AsyncDataSet(kwargs["db_path"].replace("sqlite:///", "")) - session_setup(self, EncryptedCookieStorage(SESSION_KEY)) + self.session_storage = SQLiteSessionStorage(SESSION_KEY) + session_setup(self, self.session_storage) self.tasks = asyncio.Queue() self._middlewares.append(session_middleware) self._middlewares.append(auth_middleware) @@ -179,12 +183,17 @@ class Application(BaseApplication): self.ip2location = IP2Location.IP2Location( base_path.joinpath("IP2LOCATION-LITE-DB11.BIN") ) + self.on_startup.append(self.prepare_session_storage) self.on_startup.append(self.prepare_stats) self.on_startup.append(self.prepare_asyncio) self.on_startup.append(self.start_user_availability_service) self.on_startup.append(self.start_ssh_server) # self.on_startup.append(self.prepare_database) + async def prepare_session_storage(self, app): + await self.session_storage.setup() + print("Session storage prepared", flush=True) + async def prepare_stats(self, app): app["stats"] = create_stats_structure() print("Stats prepared", flush=True) diff --git a/src/snek/service/channel_member.py b/src/snek/service/channel_member.py index df96786..d98b7a9 100644 --- a/src/snek/service/channel_member.py +++ b/src/snek/service/channel_member.py @@ -12,8 +12,8 @@ class ChannelMemberService(BaseService): async def get_user_uids(self, channel_uid): async for model in self.mapper.query( - "SELECT user_uid FROM channel_member WHERE channel_uid=:channel_uid", - {"channel_uid": channel_uid}, + "SELECT user_uid FROM channel_member WHERE channel_uid=?", + channel_uid ): yield model["user_uid"] @@ -46,17 +46,16 @@ class ChannelMemberService(BaseService): async def get_dm(self, from_user, to_user): async for model in self.query( - "SELECT channel_member.* FROM channel_member INNER JOIN channel ON (channel.uid = channel_member.channel_uid and channel.tag = 'dm') INNER JOIN channel_member AS channel_member2 ON(channel_member2.channel_uid = channel.uid AND channel_member2.user_uid = :to_user) WHERE channel_member.user_uid=:from_user ", - {"from_user": from_user, "to_user": to_user}, + "SELECT channel_member.* FROM channel_member INNER JOIN channel ON (channel.uid = channel_member.channel_uid and channel.tag = 'dm') INNER JOIN channel_member AS channel_member2 ON(channel_member2.channel_uid = channel.uid AND channel_member2.user_uid = ?) WHERE channel_member.user_uid=?", + to_user, from_user ): return model if not from_user == to_user: return None async for model in self.query( - "SELECT channel_member.* FROM channel_member INNER JOIN channel ON (channel.uid = channel_member.channel_uid and channel.tag = 'dm') LEFT JOIN channel_member AS channel_member2 ON(channel_member2.channel_uid = NULL AND channel_member2.user_uid = NULL) WHERE channel_member.user_uid=:from_user ", - {"from_user": from_user, "to_user": to_user}, + "SELECT channel_member.* FROM channel_member INNER JOIN channel ON (channel.uid = channel_member.channel_uid and channel.tag = 'dm') LEFT JOIN channel_member AS channel_member2 ON(channel_member2.channel_uid IS NULL AND channel_member2.user_uid IS NULL) WHERE channel_member.user_uid=?", + to_user ): - return model async def get_other_dm_user(self, channel_uid, user_uid): @@ -72,3 +71,4 @@ class ChannelMemberService(BaseService): result = await self.create(channel_uid, from_user_uid) await self.create(channel_uid, to_user_uid) return result + diff --git a/src/snek/service/channel_message.py b/src/snek/service/channel_message.py index 12ab5f3..7cd47c7 100644 --- a/src/snek/service/channel_message.py +++ b/src/snek/service/channel_message.py @@ -12,7 +12,7 @@ class ChannelMessageService(BaseService): self._configured_indexes = False async def maintenance(self): - for message in self.mapper.db["channel_message"].find(): + for message in await self.mapper.db.find("channel_message"): print(message) try: message = await self.get(uid=message["uid"]) @@ -21,8 +21,7 @@ class ChannelMessageService(BaseService): html = message["html"] await self.save(message) - self.mapper.db["channel_message"].upsert( - { + self.mapper.db.upsert("channel_message",{ "uid": message["uid"], "updated_at": updated_at, }, @@ -78,18 +77,19 @@ class ChannelMessageService(BaseService): if await super().save(model): if not self._configured_indexes: - if not self.mapper.db["channel_message"].has_index( - ["is_final", "user_uid", "channel_uid"] - ): - self.mapper.db["channel_message"].create_index( - ["is_final", "user_uid", "channel_uid"], unique=False - ) - if not self.mapper.db["channel_message"].has_index(["uid"]): - self.mapper.db["channel_message"].create_index(["uid"], unique=True) - if not self.mapper.db["channel_message"].has_index(["deleted_at"]): - self.mapper.db["channel_message"].create_index( - ["deleted_at"], unique=False - ) + pass + #if not self.mapper.db["channel_message"].has_index( + # ["is_final", "user_uid", "channel_uid"] + #): + # self.mapper.db["channel_message"].create_index( + # ["is_final", "user_uid", "channel_uid"], unique=False + # ) + #if not self.mapper.db["channel_message"].has_index(["uid"]): + # self.mapper.db["channel_message"].create_index(["uid"], unique=True) + #if not self.mapper.db["channel_message"].has_index(["deleted_at"]): + # self.mapper.db["channel_message"].create_index( + # ["deleted_at"], unique=False + #) self._configured_indexes = True return model raise Exception(f"Failed to create channel message: {model.errors}.") @@ -99,10 +99,6 @@ class ChannelMessageService(BaseService): if not user: return {} - # if not message["html"].startswith(" '{channel['history_start']}'" + history_start_filter = f" AND created_at > ?" results = [] offset = page * page_size try: if timestamp: async for model in self.query( - f"SELECT * FROM channel_message WHERE channel_uid=:channel_uid AND created_at < :timestamp {history_start_filter} ORDER BY created_at DESC LIMIT :page_size OFFSET :offset", - { - "channel_uid": channel_uid, - "page_size": page_size, - "offset": offset, - "timestamp": timestamp, - }, + f"SELECT * FROM channel_message WHERE channel_uid=? AND created_at < ? {history_start_filter} ORDER BY created_at DESC LIMIT ? OFFSET ?", + channel_uid, + timestamp, + page_size, + offset ): results.append(model) elif page > 0: async for model in self.query( - f"SELECT * FROM channel_message WHERE channel_uid=:channel_uid WHERE created_at < :timestamp {history_start_filter} ORDER BY created_at DESC LIMIT :page_size", - *{ - "channel_uid": channel_uid, - "page_size": page_size, - "offset": offset, - "timestamp": timestamp, - }.values(), + f"SELECT * FROM channel_message WHERE channel_uid=? AND created_at < ? {history_start_filter} ORDER BY created_at DESC LIMIT ?", + channel_uid, + timestamp, + page_size ): results.append(model) else: async for model in self.query( - f"SELECT * FROM channel_message WHERE channel_uid=:channel_uid {history_start_filter} ORDER BY created_at DESC LIMIT :page_size OFFSET :offset", - *{ - "channel_uid": channel_uid, - "page_size": page_size, - "offset": offset, - }.values(), + f"SELECT * FROM channel_message WHERE channel_uid=? {history_start_filter} ORDER BY created_at DESC LIMIT ? OFFSET ?", + channel_uid, + page_size, + offset ): results.append(model) @@ -179,3 +168,4 @@ class ChannelMessageService(BaseService): print(ex) results.sort(key=lambda x: x["created_at"]) return results + diff --git a/src/snek/static/chat-input.js b/src/snek/static/chat-input.js index ec77c5c..23bf210 100644 --- a/src/snek/static/chat-input.js +++ b/src/snek/static/chat-input.js @@ -72,12 +72,10 @@ class ChatInputComponent extends NjetComponent { focus() { this.textarea.focus(); } - - getAuthors() { - return this.users.flatMap((user) => [user.username, user.nick]); + getAuthors() { + return this.users && this.users.flatMap ? this.users.flatMap(user => [user.username, user.nick]).filter(Boolean) : []; } - - extractMentions(text) { + extractMentions(text) { return Array.from(text.matchAll(/@([a-zA-Z0-9_-]+)/g), m => m[1]); } @@ -254,6 +252,7 @@ textToLeetAdvanced(text) { app.rpc.getRecentUsers(this.channelUid).then(users => { this.users = users; + console.info(users) }); this.messageUid = null; diff --git a/src/snek/view/rpc.py b/src/snek/view/rpc.py index 71feb86..3d41974 100644 --- a/src/snek/view/rpc.py +++ b/src/snek/view/rpc.py @@ -525,6 +525,7 @@ class RPCView(BaseView): except Exception as ex: print(str(ex), flush=True) logger.exception(ex) + traceback.print_exc() await self._send_json( {"callId": call_id, "success": False, "data": str(ex)} )