accept and reject invites to rooms

This commit is contained in:
histausse 2021-10-03 18:54:22 +02:00
parent 75d1683b38
commit d9528228ba
Signed by: histausse
GPG key ID: 67486F107F62E9E9
2 changed files with 54 additions and 14 deletions

View file

@ -23,7 +23,7 @@ class Client(Aobject):
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 whitelist_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 by id (the name starting with '!'). If set to None, the bot connect to
all room where it is invited. all room where it is invited.
@ -35,15 +35,16 @@ class Client(Aobject):
__rooms_by_id: dict[RoomId, Room] __rooms_by_id: dict[RoomId, Room]
__sync_token_file: AsyncPath __sync_token_file: AsyncPath
__sync_token:Optional[str] __sync_token:Optional[str]
__sync_token_queue:asyncio.Queue[str] __sync_token_queue: asyncio.Queue[str]
allowed_rooms: Optional[dict[RoomId, Room]] __invites_queue: asyncio.Queue[tuple[RoomId, nio.responses.InviteInfo]]
whitelist_rooms: Optional[dict[RoomId, Room]]
async def __init__( async def __init__(
self, self,
username: str, username: str,
homeserver: str, homeserver: str,
password: str, password: str,
allowed_rooms_names: Optional[list[Union[RoomAlias, RoomId]]]=None, whitelist_rooms_names: Optional[list[Union[RoomAlias, RoomId]]]=None,
sync_token_file:str="./.sync_token", sync_token_file:str="./.sync_token",
): ):
""" """
@ -51,7 +52,7 @@ class Client(Aobject):
username: the username used by the bot username: the username used by the bot
homeserver: the matrix home server of the bot (expl: "https://matrix.org") homeserver: the matrix home server of the bot (expl: "https://matrix.org")
password: the password of the user password: the password of the user
allowed_rooms: the list of the rooms where the bot is allowed to connect whitelist_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: (given by room id (expl: '!xxx:matrix.org') of room alias (expl:
'#xxx:matrix.org')) '#xxx:matrix.org'))
sync_token_file: the file where is stored the last sync token received from sync_token_file: the file where is stored the last sync token received from
@ -71,16 +72,17 @@ class Client(Aobject):
else: else:
self.__sync_token = None self.__sync_token = None
self.__sync_token_queue = asyncio.Queue() self.__sync_token_queue = asyncio.Queue()
self.__invites_queue = asyncio.Queue()
resp = await self.__client.login(password) resp = await self.__client.login(password)
if isinstance(resp, nio.responses.LoginError): if isinstance(resp, nio.responses.LoginError):
raise RuntimeError(f"Fail to connect: {resp.message}") raise RuntimeError(f"Fail to connect: {resp.message}")
self.allowed_rooms = None self.whitelist_rooms = None
if allowed_rooms_names: if whitelist_rooms_names:
self.allowed_rooms = {} self.whitelist_rooms = {}
rooms = await asyncio.gather(*(self.resolve_room(room_name) for room_name in allowed_rooms_names)) rooms = await asyncio.gather(*(self.resolve_room(room_name) for room_name in whitelist_rooms_names))
for room in rooms: for room in rooms:
self.allowed_rooms[room.id] = room # room uniqueness is handled by self.resolve_room self.whitelist_rooms[room.id] = room # room uniqueness is handled by self.resolve_room
async def resolve_room( async def resolve_room(
self, self,
@ -134,6 +136,39 @@ class Client(Aobject):
await file.write(token) await file.write(token)
self.__sync_token_queue.task_done() self.__sync_token_queue.task_done()
async def __process_invites(self)->NoReturn:
"""
Process invites to rooms.
"""
while True:
room_id, invite_info = await self.__invites_queue.get()
accept_invite = False
if self.whitelist_rooms is not None:
if room_id not in self.whitelist_rooms:
print(f"Received invite for {room_id}, but room_id is not in the white list.") # TODO: better logging
else:
accept_invite = True
print(f"Received invite for {room_id}: invite accepted.") # TODO: better logging
else:
accept_invite = True
print(f"Received invite for {room_id}: invite accepted.") # TODO: better logging
if accept_invite:
result = await self.__client.join(room_id)
if isinstance(result, nio.JoinError):
print(f"Error while joinning room {room_id}: {result.message}") # TODO: better logging
else:
print(f"{room_id} joined") # TODO: better logging
else:
result = await self.__client.room_leave(room_id)
if isinstance(result, nio.RoomLeaveError):
print(f"Error while leaving room {room_id}: {result.message}") # TODO: better logging
else:
print(f"{room_id} left") # TODO: better logging
self.__invites_queue.task_done()
async def __sync( async def __sync(
self, self,
sync_timeout:int=30 sync_timeout:int=30
@ -144,15 +179,20 @@ class Client(Aobject):
""" """
while True: while True:
sync_resp = await self.__client.sync( sync_resp = await self.__client.sync(
sync_delta*1000, sync_timeout*1000,
since=self.__sync_token since=self.__sync_token
) )
if isinstance(sync_resp, nio.responses.SyncError): if isinstance(sync_resp, nio.responses.SyncError):
print(f"Error while syncronizing: {sync_resp.message}") # TODO: use proper logging print(f"Error while syncronizing: {sync_resp.message}") # TODO: use proper logging
continue continue
self.__sync_token = sync_resp.next_batch self.__sync_token = sync_resp.next_batch
await self.__sync_token_queue.put(self.__sync_token) await self.__sync_token_queue.put(self.__sync_token)
invites = sync_resp.rooms.invite
for room_id in invites:
await self.__invites_queue.put((room_id, invites[room_id]))
async def run( async def run(
self, self,
sync_timeout:int=30 sync_timeout:int=30
@ -162,8 +202,9 @@ class Client(Aobject):
sync_timeout: the max time in sec between each sync. sync_timeout: the max time in sec between each sync.
""" """
await asyncio.gather( await asyncio.gather(
self.__sync(sync_delta=sync_delta), self.__sync(sync_timeout=sync_timeout),
self.__save_sync_tocken() self.__save_sync_tocken(),
self.__process_invites()
) )

View file

@ -16,7 +16,6 @@ async def main():
os.environ["PASSWD"], os.environ["PASSWD"],
os.environ["ROOMS"].split(",") os.environ["ROOMS"].split(",")
) )
print(client.allowed_rooms)
await client.run() await client.run()