Compare commits

...

4 Commits

Author SHA1 Message Date
histausse e78b4c7b72
Initialize the client
And so we start with an ideous non async methode...
3 years ago
histausse 0e1daa3604
add matrix-nio to dependencies 3 years ago
histausse 8cbdf346e2
add Client class 3 years ago
histausse 9c993c86e7
add config files for pip packaging 3 years ago

1
.gitignore vendored

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

@ -0,0 +1,4 @@
[build-system]
requires = ["setuptools>=42.0", "wheel"]
build-backend = "setuptools.build_meta"

@ -0,0 +1,23 @@
aiofiles==0.6.0
aiohttp==3.7.4.post0
aiohttp-socks==0.6.0
async-timeout==3.0.1
attrs==21.2.0
chardet==4.0.0
future==0.18.2
h11==0.12.0
h2==4.0.0
hpack==4.0.0
hyperframe==6.0.1
idna==3.2
jsonschema==3.2.0
Logbook==1.5.3
matrix-nio==0.18.7
multidict==5.1.0
pycryptodome==3.10.4
pyrsistent==0.18.0
python-socks==1.2.4
six==1.16.0
typing-extensions==3.10.0.2
unpaddedbase64==2.1.0
yarl==1.6.3

@ -0,0 +1,14 @@
[metadata]
name = matrix-bot
author = Jean-Marie 'Histausse' Mineau
author_email = histausse@protonmail
description = A package implementing a reusable class to make matrix bots.
long_description = file:README.md
url = https://gitea.auro.re/histausse/matrix-bot
[options]
packages = matrix_bot
python_requires = >=3.9.2
package_dir = =src
install_requires =
matrix-nio>=0.18.7

@ -0,0 +1,5 @@
from setuptools import setup
if __name__ == "__main__":
setup()

@ -0,0 +1,87 @@
"""
The Client class.
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:
"""
Connect to the matrix server and handle interactions with the
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.
"""
__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})

@ -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)

@ -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)
Loading…
Cancel
Save