diff --git a/pkgs/matrix-bot/matrix_bot/__init__.py b/pkgs/matrix-bot/matrix_bot/__init__.py index 49d0925e..0aa7c622 100644 --- a/pkgs/matrix-bot/matrix_bot/__init__.py +++ b/pkgs/matrix-bot/matrix_bot/__init__.py @@ -70,13 +70,6 @@ def create_parser(prog: str | None = None) -> argparse.ArgumentParser: default="https://git.clan.lol", ) - parser.add_argument( - "--trigger-labels", - help="The labels that trigger the bot", - default=["needs-review"], - nargs="+", - ) - return parser @@ -106,7 +99,6 @@ def main() -> None: url=args.gitea_url, owner=args.repo_owner, repo=args.repo_name, - trigger_labels=args.trigger_labels, access_token=os.getenv("GITEA_ACCESS_TOKEN"), ) diff --git a/pkgs/matrix-bot/matrix_bot/bot.py b/pkgs/matrix-bot/matrix_bot/bot.py index 45d0d649..24c817cc 100644 --- a/pkgs/matrix-bot/matrix_bot/bot.py +++ b/pkgs/matrix-bot/matrix_bot/bot.py @@ -3,12 +3,11 @@ import logging log = logging.getLogger(__name__) import time from pathlib import Path -import json + import aiohttp from nio import ( AsyncClient, JoinResponse, - JoinedMembersResponse, MatrixRoom, RoomMessageText, ) @@ -17,15 +16,14 @@ from matrix_bot.gitea import ( GiteaData, PullState, fetch_pull_requests, - fetch_repo_labels, ) from .locked_open import read_locked_file, write_locked_file -from .matrix import MatrixData, send_message +from .matrix import MatrixData, get_room_members, send_message async def message_callback(room: MatrixRoom, event: RoomMessageText) -> None: - print( + log.debug( f"Message received in room {room.display_name}\n" f"{room.user_name(event.sender)} | {event.body}" ) @@ -40,40 +38,51 @@ async def bot_run( # If you made a new room and haven't joined as that user, you can use room: JoinResponse = await client.join(matrix.room) - users: JoinedMembersResponse = await client.joined_members(room.room_id) + if not room.transport_response.ok: + log.error("This can happen if the room doesn't exist or the bot isn't invited") + raise Exception(f"Failed to join room {room}") - if not users.transport_response.ok: - raise Exception(f"Failed to get users {users}") - - for user in users.members: - print(f"User: {user.user_id} {user.display_name}") - - labels = await fetch_repo_labels(gitea, http) - label_ids: list[int] = [] - for label in labels: - if label["name"] in gitea.trigger_labels: - label_ids.append(label["id"]) + # Get the members of the room + users = await get_room_members(client, room) + # Fetch the pull requests tstart = time.time() pulls = await fetch_pull_requests(gitea, http, limit=50, state=PullState.ALL) + # Read the last updated pull request last_updated_path = Path("last_updated.json") last_updated = read_locked_file(last_updated_path) + # Check if the pull request is mergeable and needs review + # and if the pull request is newer than the last updated pull request for pull in pulls: - if pull["requested_reviewers"] and pull["mergeable"]: + requested_reviewers = pull["requested_reviewers"] + if requested_reviewers and pull["mergeable"]: if last_updated == {}: last_updated = pull elif pull["updated_at"] < last_updated["updated_at"]: last_updated = pull else: continue - log.info(f"Pull request {pull['title']} needs review") - message = f"Pull request {pull['title']} needs review\n{pull['html_url']}" - await send_message(client, room, message, user_ids=["@qubasa:gchq.icu"]) + # Check if the requested reviewers are in the room + requested_reviewers = [r["login"].lower() for r in requested_reviewers] + ping_users = [] + for user in users: + if user.display_name.lower() in requested_reviewers: + ping_users.append(user.user_id) + + # Send a message to the room and mention the users + log.info(f"Pull request {pull['title']} needs review") + message = ( + f"Review Requested:\n{pull['title']}\n{pull['html_url']}" + ) + await send_message(client, room, message, user_ids=ping_users) + + # Write the new last updated pull request write_locked_file(last_updated_path, last_updated) + # Time taken tend = time.time() tdiff = round(tend - tstart) log.debug(f"Time taken: {tdiff}s") diff --git a/pkgs/matrix-bot/matrix_bot/gitea.py b/pkgs/matrix-bot/matrix_bot/gitea.py index 22e0a644..470ba803 100644 --- a/pkgs/matrix-bot/matrix_bot/gitea.py +++ b/pkgs/matrix-bot/matrix_bot/gitea.py @@ -3,7 +3,7 @@ import logging log = logging.getLogger(__name__) -from dataclasses import dataclass, field +from dataclasses import dataclass from enum import Enum import aiohttp @@ -15,7 +15,6 @@ class GiteaData: owner: str repo: str access_token: str | None = None - trigger_labels: list[str] = field(default_factory=list) def endpoint_url(gitea: GiteaData, endpoint: str) -> str: diff --git a/pkgs/matrix-bot/matrix_bot/main.py b/pkgs/matrix-bot/matrix_bot/main.py index 2e7cbf0e..d4d4b0c6 100644 --- a/pkgs/matrix-bot/matrix_bot/main.py +++ b/pkgs/matrix-bot/matrix_bot/main.py @@ -10,11 +10,7 @@ log = logging.getLogger(__name__) curr_dir = Path(__file__).parent -from nio import ( - AsyncClient, - ProfileGetAvatarResponse, - RoomMessageText, -) +from nio import AsyncClient, ClientConfig, ProfileGetAvatarResponse, RoomMessageText from matrix_bot.bot import bot_run, message_callback from matrix_bot.matrix import set_avatar, upload_image @@ -24,8 +20,13 @@ async def bot_main( matrix: MatrixData, gitea: GiteaData, ) -> None: + # Setup client configuration to handle encryption + client_config = ClientConfig( + encryption_enabled=False, + ) + log.info(f"Connecting to {matrix.server} as {matrix.user}") - client = AsyncClient(matrix.server, matrix.user) + client = AsyncClient(matrix.server, matrix.user, config=client_config) client.add_event_callback(message_callback, RoomMessageText) log.info(await client.login(matrix.password)) diff --git a/pkgs/matrix-bot/matrix_bot/matrix.py b/pkgs/matrix-bot/matrix_bot/matrix.py index 4d4c6dce..4ade0162 100644 --- a/pkgs/matrix-bot/matrix_bot/matrix.py +++ b/pkgs/matrix-bot/matrix_bot/matrix.py @@ -7,8 +7,10 @@ from dataclasses import dataclass from nio import ( AsyncClient, + JoinedMembersResponse, JoinResponse, ProfileSetAvatarResponse, + RoomMember, RoomSendResponse, UploadResponse, ) @@ -33,6 +35,14 @@ async def set_avatar(client: AsyncClient, mxc_url: str) -> None: from nio import AsyncClient +async def get_room_members(client: AsyncClient, room: JoinResponse) -> list[RoomMember]: + users: JoinedMembersResponse = await client.joined_members(room.room_id) + + if not users.transport_response.ok: + raise Exception(f"Failed to get users {users}") + return users.members + + async def send_message( client: AsyncClient, room: JoinResponse,