This commit is contained in:
retoor 2025-05-21 18:18:55 +02:00
parent a92fd40b12
commit 4fa67e24cb
3 changed files with 44 additions and 16 deletions
src
snekbot.egg-info
snekbot

View File

@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: snekbot
Version: 1.0.0
Version: 1.1.0
Summary: Bot API for Snek chat
Author-email: retoor <retoor@molodetz.nl>
Keywords: chat,snek,molodetz,bot

View File

@ -89,7 +89,7 @@ class Bot:
async def get_channels(self, refresh=False):
if refresh or not self._channels:
self._channels = await (await self.rpc.get_channels())()
self._channels = await self.rpc.get_channels()
return self._channels
async def run_once(self):
@ -101,8 +101,8 @@ class Bot:
rpc = RPC(self.ws)
self.rpc = rpc
await (await rpc.login(self.username, self.password))()
self.user = await (await rpc.get_user(None))()
await rpc.login(self.username, self.password)
self.user = await rpc.get_user(None)
logger.debug("Logged in as: " + self.user["username"])
if is_initial:
@ -118,17 +118,31 @@ class Bot:
while True:
data = await rpc.receive()
if not data:
return
event = "?"
try:
event = data.event
except AttributeError:
pass
try:
message = data.message.strip()
event = "message"
except AttributeError:
pass
if event == "?":
continue
else:
elif event == "message":
break
try:
await getattr(self, "on_" + data.event)(**data.data)
except AttributeError:
logger.debug("Not implemented event: " + event)
if data.username == self.user["username"]:
await self.on_own_message(data.channel_uid, message)
elif message.startswith("ping"):

View File

@ -13,7 +13,7 @@ import logging
import pathlib
import subprocess
import uuid
import asyncio
import aiohttp
logger = logging.getLogger("snekbot.rpc")
@ -53,13 +53,15 @@ class RPC:
def __init__(self, ws):
self.ws = ws
self.current_call_id = None
self.queue = asyncio.Queue()
async def echo(self, data):
async def queue(self, data):
logger.debug("Schedule for retry: " + str(data))
await self.ws.send_json({"method": "echo", "args": [data]})
await self.queue.put(data)
def __getattr__(self, name):
async def method(*args, **kwargs):
no_response = kwargs.pop("_no_response", False)
self.current_call_id = str(uuid.uuid4())
payload = {
"method": name,
@ -73,12 +75,16 @@ class RPC:
while True:
response = await self.ws.receive()
data = response.json()
if not data.get("callId") == self.current_call_id:
await self.echo(data)
if data.get("callId") != self.current_call_id:
await self.queue.put(data)
continue
self.current_call_id = None
return self.Response(data)
return returner
if no_response:
return True
return await returner()
return method
@ -108,6 +114,16 @@ class RPC:
return response
async def receive(self):
popped = []
while not self.queue.empty():
msg = await self.queue.get()
if self.current_call_id == msg.get("callId"):
for m in popped:
await self.queue.put(m)
self.current_call_id = None
return self.Response(msg)
while True:
try:
msg = await self.ws.receive()
@ -121,12 +137,10 @@ class RPC:
logger.exception("WebSocket error.")
break
elif msg.type == aiohttp.WSMsgType.TEXT:
if (
self.current_call_id
and not msg.json().get("callId") != self.current_call_id
msg.json().get("callId") != self.current_call_id
):
await self.echo(msg.json())
await self.queue.put(msg.json())
continue
try:
response = self.Response(msg.json())