Refactor /cmd handling to be more extensible
This commit is contained in:
parent
4de8e87f06
commit
7d6fba5ac7
|
@ -179,6 +179,21 @@ class MatrixClient(nio.AsyncClient):
|
|||
if host in ("127.0.0.1", "localhost", "::1"):
|
||||
proxy = None
|
||||
|
||||
# self is passed in explicitly, so that it will also be passed to
|
||||
# handlers in the user config
|
||||
self.cmd_handler_map = {
|
||||
"me ": MatrixClient.handle_cmd_emote,
|
||||
}
|
||||
|
||||
try:
|
||||
self.cmd_handler_map = {
|
||||
**self.cmd_handler_map,
|
||||
**backend.settings.Commands.get_cmd_handler_map(),
|
||||
}
|
||||
except (AttributeError, KeyError):
|
||||
# make sure we don't break older configs
|
||||
pass
|
||||
|
||||
super().__init__(
|
||||
homeserver = homeserver,
|
||||
user = user,
|
||||
|
@ -618,22 +633,40 @@ class MatrixClient(nio.AsyncClient):
|
|||
display_name_mentions: Optional[Dict[str, str]] = None, # {id: name}
|
||||
reply_to_event_id: Optional[str] = None,
|
||||
) -> None:
|
||||
"""Send a markdown `m.text` or `m.notice` (with `/me`) message ."""
|
||||
if text.startswith("//") or text.startswith(r"\/"):
|
||||
await self._send_text(room_id, text[1:], display_name_mentions, reply_to_event_id)
|
||||
elif text.startswith("/"):
|
||||
for k,v in self.cmd_handler_map.items():
|
||||
if text.startswith("/"+k):
|
||||
await v(self, room_id, text[len("/"+k):], display_name_mentions, reply_to_event_id)
|
||||
break
|
||||
else:
|
||||
await self.send_fake_notice(
|
||||
room_id,
|
||||
r"That command was not recognised. To send a message starting with /, use //",
|
||||
)
|
||||
else:
|
||||
await self._send_text(room_id, text, display_name_mentions, reply_to_event_id)
|
||||
|
||||
|
||||
async def _send_text(
|
||||
self,
|
||||
room_id: str,
|
||||
text: str,
|
||||
display_name_mentions: Optional[Dict[str, str]] = None, # {id: name}
|
||||
reply_to_event_id: Optional[str] = None,
|
||||
emote: bool = False,
|
||||
) -> None:
|
||||
"""Send a markdown `m.text` or `m.emote` message ."""
|
||||
|
||||
from_md = partial(
|
||||
HTML.from_markdown, display_name_mentions=display_name_mentions,
|
||||
)
|
||||
|
||||
escape = False
|
||||
if text.startswith("//") or text.startswith(r"\/"):
|
||||
escape = True
|
||||
text = text[1:]
|
||||
|
||||
content: Dict[str, Any]
|
||||
|
||||
if text.startswith("/me ") and not escape:
|
||||
if emote:
|
||||
event_type = nio.RoomMessageEmote
|
||||
text = text[len("/me "):]
|
||||
content = {"body": text, "msgtype": "m.emote"}
|
||||
to_html = from_md(text, inline=True, outgoing=True)
|
||||
echo_body = from_md(text, inline=True)
|
||||
|
@ -699,6 +732,22 @@ class MatrixClient(nio.AsyncClient):
|
|||
await self._send_message(room_id, content, tx_id)
|
||||
|
||||
|
||||
async def handle_cmd_emote(
|
||||
self,
|
||||
room_id: str,
|
||||
text: str,
|
||||
display_name_mentions: Optional[Dict[str, str]] = None, # {id: name}
|
||||
reply_to_event_id: Optional[str] = None,
|
||||
):
|
||||
await self._send_text(
|
||||
room_id,
|
||||
text,
|
||||
display_name_mentions,
|
||||
reply_to_event_id,
|
||||
emote=True
|
||||
)
|
||||
|
||||
|
||||
async def toggle_pause_transfer(
|
||||
self, room_id: str, uuid: Union[str, UUID],
|
||||
) -> None:
|
||||
|
@ -1023,6 +1072,7 @@ class MatrixClient(nio.AsyncClient):
|
|||
room_id: str,
|
||||
transaction_id: UUID,
|
||||
event_type: Type[nio.Event],
|
||||
fake_event: bool = False,
|
||||
**event_fields,
|
||||
) -> None:
|
||||
"""Register a local model `Event` while waiting for the server.
|
||||
|
@ -1056,7 +1106,7 @@ class MatrixClient(nio.AsyncClient):
|
|||
sender_id = self.user_id,
|
||||
sender_name = our_info.display_name,
|
||||
sender_avatar = our_info.avatar_url,
|
||||
is_local_echo = True,
|
||||
is_local_echo = not fake_event,
|
||||
links = Event.parse_links(content),
|
||||
**event_fields,
|
||||
)
|
||||
|
@ -1069,6 +1119,16 @@ class MatrixClient(nio.AsyncClient):
|
|||
await self.set_room_last_event(room_id, event)
|
||||
|
||||
|
||||
async def send_fake_notice(self, room_id, msg):
|
||||
await self._local_echo(
|
||||
room_id,
|
||||
uuid4(),
|
||||
nio.RoomMessageNotice,
|
||||
content = msg,
|
||||
fake_event = True,
|
||||
)
|
||||
|
||||
|
||||
async def _send_message(
|
||||
self, room_id: str, content: dict, transaction_id: UUID,
|
||||
) -> None:
|
||||
|
|
|
@ -541,3 +541,36 @@ class Keys:
|
|||
|
||||
# Sign out checked sessions if any, else sign out all sessions.
|
||||
sign_out = ["Alt+S", "Delete"]
|
||||
|
||||
class Commands:
|
||||
# If you are an advanced user, here you can define new /commands
|
||||
#
|
||||
# get_cmd_handler_map should return a dictionary of the form
|
||||
# {
|
||||
# "command": command_handling_function,
|
||||
# "another_command": ...
|
||||
# }
|
||||
#
|
||||
# each command_handling_function should have the signature:
|
||||
#
|
||||
# async def command_handling_function(
|
||||
# matrix_client: moment.backend.MatrixClient,
|
||||
# room_id: str,
|
||||
# text: str, # text after the end of /command
|
||||
# display_name_mentions: Optional[Dict[str, str]] = None, # {id: name}
|
||||
# reply_to_event_id: Optional[str] = None,
|
||||
# ) -> None:
|
||||
|
||||
# Example:
|
||||
|
||||
def get_cmd_handler_map(self):
|
||||
return {
|
||||
# "rot13 ": self.handle_cmd_rot13,
|
||||
}
|
||||
|
||||
# @staticmethod
|
||||
# def handle_cmd_rot13(matrix_client, room_id, text, display_name_mentions, reply_to_event_id):
|
||||
# import codecs
|
||||
# matrix_client._send_text(
|
||||
# room_id, codecs.encode(text, 'rot_13'), display_name_mentions, reply_to_event_id
|
||||
# )
|
||||
|
|
Loading…
Reference in New Issue
Block a user