Initialize the client

And so we start with an ideous non async methode...
This commit is contained in:
histausse 2021-10-03 03:00:42 +02:00
parent 0e1daa3604
commit e78b4c7b72
Signed by: histausse
GPG key ID: 67486F107F62E9E9
5 changed files with 115 additions and 3 deletions

1
.gitignore vendored
View file

@ -137,4 +137,3 @@ dmypy.json
# Cython debug symbols # Cython debug symbols
cython_debug/ cython_debug/

View file

@ -8,7 +8,7 @@ url = https://gitea.auro.re/histausse/matrix-bot
[options] [options]
packages = matrix_bot packages = matrix_bot
python_requires = >=3.6 python_requires = >=3.9.2
package_dir = =src package_dir = =src
install_requires = install_requires =
matrix-nio>=0.18.7 matrix-nio>=0.18.7

View file

@ -3,10 +3,85 @@ The Client class.
Connect to the matrix server and handle interactions with the server. Connect to the matrix server and handle interactions with the server.
""" """
import asyncio
import nio
from typing import (
Optional,
NoReturn,
Union
)
from .utils import (
Room,
RoomAlias,
RoomId
)
class Client: class Client:
""" """
Connect to the matrix server and handle interactions with the Connect to the matrix server and handle interactions with the
server. server.
allowed_rooms: dict of the rooms where the bot is allowed to connect, indexed
by id (the name starting with '!'). If set to None, the bot connect to
all room where it is invited.
""" """
pass
__client: nio.AsyncClient
allowed_rooms: Optional[dict[RoomId, Room]]
def __init__(
self,
username: str,
homeserver: str,
password: str,
allowed_rooms_names: Optional[list[Union[RoomAlias, RoomId]]]=None
):
"""
Initialize the Client.
username: the username used by the bot
homeserver: the matrix home server of the bot (expl: "https://matrix.org")
password: the password of the user
allowed_rooms: the list of the rooms where the bot is allowed to connect
(given by room id (expl: '!xxx:matrix.org') of room alias (expl:
'#xxx:matrix.org'))
"""
loop = asyncio.get_event_loop()
self.__client = nio.AsyncClient(
homeserver,
username
)
resp = loop.run_until_complete(self.__client.login(password))
if isinstance(resp, nio.responses.LoginError):
raise RuntimeError(f"Fail to connect: {resp.message}")
# Where is the async map when you need it?
self.allowed_rooms = None
if allowed_rooms_names:
self.allowed_rooms = {}
for room_name in allowed_rooms_names:
room = loop.run_until_complete(self.resolve_room(room_name))
if room.id in self.allowed_rooms:
self.allowed_rooms[room.id].aliases.update(room.aliases)
else:
self.allowed_rooms[room.id] = room
async def resolve_room(
self,
room_name: Union[RoomAlias, RoomId]
)->Room:
"""
Lookup a room from its id or alias.
"""
if len(room_name) == 0:
raise ValueError(f"Invalid room_name: {room_name}")
if room_name[0] == '!':
return Room(id=room_name)
elif room_name[0] != '#':
raise ValueError(f"Invalid room_name: {room_name}")
else:
resp = await self.__client.room_resolve_alias(room_name)
if isinstance(resp, nio.responses.RoomResolveAliasError):
raise RuntimeError(f"Error while resolving alias: {resp.message}")
return Room(id=resp.room_id,aliases={room_name})

19
src/matrix_bot/utils.py Normal file
View file

@ -0,0 +1,19 @@
"""
Utilities for the bot.
"""
from dataclasses import (
dataclass,
field
)
RoomAlias = str
RoomId = str
@dataclass
class Room:
""" Class representing a room.
"""
id: RoomId
aliases: set[RoomAlias] = field(default_factory=set)

19
tests/test.py Normal file
View file

@ -0,0 +1,19 @@
"""
Not really tests, because I don't know how to testt without a whole matrix server.
"""
import os
from dotenv import load_dotenv
from matrix_bot.client import Client
from getpass import getpass
if __name__ == "__main__":
load_dotenv()
client = Client(
os.environ["MUSER"],
os.environ["HOMESERVER"],
os.environ["PASSWD"],
os.environ["ROOMS"].split(",")
)
print(client.allowed_rooms)