feat: added send_message and join_room methods

This commit is contained in:
əlemi 2024-01-29 18:42:03 +01:00
parent c3783253e1
commit 5710a71651
Signed by: alemi
GPG key ID: A4895B84D311642C
2 changed files with 78 additions and 18 deletions

View file

@ -1,3 +1,4 @@
import uuid
import asyncio
import logging
@ -6,10 +7,12 @@ from typing import Callable, Awaitable
from aiohttp import ClientSession, web
from .matrix import Event, EventType
from .utils import mx_message
class AppService:
_rx: web.Application
_tx: ClientSession
_site: web.TCPSite
_client: ClientSession
_app: web.Application
_callbacks: dict[EventType, dict[str, Callable]]
as_token: str
@ -29,7 +32,8 @@ class AppService:
server_name: str,
logger: logging.Logger | None = None,
):
self._rx = web.Application()
self._app = web.Application()
self._client = ClientSession()
self._callbacks = {}
self.as_token = as_token
@ -40,7 +44,7 @@ class AppService:
self.logger = logger if logger is not None else logging.getLogger(__file__)
self._rx.add_routes([
self._app.add_routes([
web.put('/transactions/{transaction}', lambda req: self.handler(req))
])
@ -72,27 +76,47 @@ class AppService:
return func
return wrapper
async def join_room(self):
pass
async def join_room(self, room: str, mxid: str | None = None):
async with self._client.request(
method="POST",
url=f"/join/{room}",
headers={
"Authorization": f"Bearer {self.as_token}",
"Content-Type": "application/json",
},
params={"user_id": mxid} if mxid else {},
) as res:
doc = await res.json()
self.logger.debug("joined room %s with %s : %s", room, mxid, doc)
async def leave_room(self):
pass
raise NotImplementedError
async def send_message(self):
pass
async def send_message(self, room: str, text: str, mxid: str | None = None) -> str:
async with self._client.request(
method="PUT",
url=f"/rooms/{room}/send/m.room.message/{uuid.uuid4()}",
headers={
"Authorization": f"Bearer {self.as_token}",
"Content-Type": "application/json",
},
params={"user_id": mxid} if mxid else {},
json=mx_message(text),
) as res:
doc = await res.json()
self.logger.debug("sent message %s to %s as %s : %s", text, room, mxid, doc)
return doc["event_id"]
async def redact_message(self):
pass
raise NotImplementedError
async def start(self, host: str = "localhost", port: int = 25511):
runner = web.AppRunner(self._rx)
runner = web.AppRunner(self._app)
await runner.setup()
site = web.TCPSite(runner, host, port)
await site.start()
self._site = web.TCPSite(runner, host, port)
await self._site.start()
async def stop(self):
await self._site.stop()
await self._tx.close()
# utility function in case we need to block forever
async def idle():
while True:
await asyncio.sleep(3600)

36
src/aioappsrv/utils.py Normal file
View file

@ -0,0 +1,36 @@
import asyncio
from io import StringIO
from html.parser import HTMLParser
# thanks [stackoverflow](https://stackoverflow.com/questions/753052/strip-html-from-strings-in-python)
class MLStripper(HTMLParser):
def __init__(self):
super().__init__()
self.reset()
self.strict = False
self.convert_charrefs= True
self.text = StringIO()
def handle_data(self, d):
self.text.write(d)
def get_data(self):
return self.text.getvalue()
# remove all html tags from given string
def strip_html(html: str) -> str:
s = MLStripper()
s.feed(html)
return s.get_data()
# utility function in case we need to block forever
async def idle():
while True:
await asyncio.sleep(3600)
# wraps a HTML formatted message into its struct, stripping html
def mx_message(text: str) -> dict:
return {
"body": strip_html(text),
"msgtype": "m.text",
"format": "org.matrix.custom.html",
"formatted_body": text,
}