feat: added send_message and join_room methods
This commit is contained in:
parent
c3783253e1
commit
5710a71651
2 changed files with 78 additions and 18 deletions
|
@ -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
36
src/aioappsrv/utils.py
Normal 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,
|
||||
}
|
Loading…
Reference in a new issue