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"):
|
if host in ("127.0.0.1", "localhost", "::1"):
|
||||||
proxy = None
|
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__(
|
super().__init__(
|
||||||
homeserver = homeserver,
|
homeserver = homeserver,
|
||||||
user = user,
|
user = user,
|
||||||
|
@ -618,22 +633,40 @@ class MatrixClient(nio.AsyncClient):
|
||||||
display_name_mentions: Optional[Dict[str, str]] = None, # {id: name}
|
display_name_mentions: Optional[Dict[str, str]] = None, # {id: name}
|
||||||
reply_to_event_id: Optional[str] = None,
|
reply_to_event_id: Optional[str] = None,
|
||||||
) -> 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(
|
from_md = partial(
|
||||||
HTML.from_markdown, display_name_mentions=display_name_mentions,
|
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]
|
content: Dict[str, Any]
|
||||||
|
|
||||||
if text.startswith("/me ") and not escape:
|
if emote:
|
||||||
event_type = nio.RoomMessageEmote
|
event_type = nio.RoomMessageEmote
|
||||||
text = text[len("/me "):]
|
|
||||||
content = {"body": text, "msgtype": "m.emote"}
|
content = {"body": text, "msgtype": "m.emote"}
|
||||||
to_html = from_md(text, inline=True, outgoing=True)
|
to_html = from_md(text, inline=True, outgoing=True)
|
||||||
echo_body = from_md(text, inline=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)
|
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(
|
async def toggle_pause_transfer(
|
||||||
self, room_id: str, uuid: Union[str, UUID],
|
self, room_id: str, uuid: Union[str, UUID],
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@ -1023,6 +1072,7 @@ class MatrixClient(nio.AsyncClient):
|
||||||
room_id: str,
|
room_id: str,
|
||||||
transaction_id: UUID,
|
transaction_id: UUID,
|
||||||
event_type: Type[nio.Event],
|
event_type: Type[nio.Event],
|
||||||
|
fake_event: bool = False,
|
||||||
**event_fields,
|
**event_fields,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Register a local model `Event` while waiting for the server.
|
"""Register a local model `Event` while waiting for the server.
|
||||||
|
@ -1056,7 +1106,7 @@ class MatrixClient(nio.AsyncClient):
|
||||||
sender_id = self.user_id,
|
sender_id = self.user_id,
|
||||||
sender_name = our_info.display_name,
|
sender_name = our_info.display_name,
|
||||||
sender_avatar = our_info.avatar_url,
|
sender_avatar = our_info.avatar_url,
|
||||||
is_local_echo = True,
|
is_local_echo = not fake_event,
|
||||||
links = Event.parse_links(content),
|
links = Event.parse_links(content),
|
||||||
**event_fields,
|
**event_fields,
|
||||||
)
|
)
|
||||||
|
@ -1069,6 +1119,16 @@ class MatrixClient(nio.AsyncClient):
|
||||||
await self.set_room_last_event(room_id, event)
|
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(
|
async def _send_message(
|
||||||
self, room_id: str, content: dict, transaction_id: UUID,
|
self, room_id: str, content: dict, transaction_id: UUID,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
|
@ -541,3 +541,36 @@ class Keys:
|
||||||
|
|
||||||
# Sign out checked sessions if any, else sign out all sessions.
|
# Sign out checked sessions if any, else sign out all sessions.
|
||||||
sign_out = ["Alt+S", "Delete"]
|
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