From 378f4b1f9324b9d04e89410c506779155a5cc355 Mon Sep 17 00:00:00 2001 From: jesopo Date: Wed, 14 Nov 2018 21:28:27 +0000 Subject: [PATCH] Better parsing of CTCP messages, support raw.send.privmsg/raw.send.notice in modules/line_handler.py --- modules/line_handler.py | 72 +++++++++++++++++++++++++++++------------ src/utils/irc.py | 14 ++++++++ 2 files changed, 65 insertions(+), 21 deletions(-) diff --git a/modules/line_handler.py b/modules/line_handler.py index 0beb7384..f8fa50f6 100644 --- a/modules/line_handler.py +++ b/modules/line_handler.py @@ -401,11 +401,24 @@ class Module(ModuleManager.BaseModule): message = event["args"][1] message_split = message.split(" ") target = event["args"][0] - action = message.startswith("\x01ACTION ") - if action: - message = message.replace("\x01ACTION ", "", 1) - if message.endswith("\x01"): - message = message[:-1] + + channel = None + if target[0] in event["server"].channel_types: + channel = event["server"].channels.get(event["args"][0]) + + action = False + ctcp_message = utils.irc.parse_ctcp(message) + if ctcp_message: + if ctcp_message.command == "ACTION": + action = True + message = ctcp_message.message + else: + if channel: + self._event(event, "ctcp.channel", channel=channel, + ctcp=ctcp_message) + else: + self._event(event, "ctcp.private", user=user, + ctcp=ctcp_message) if user and "account" in event["tags"]: user.identified_account = event["tags"]["account"] @@ -416,44 +429,61 @@ class Module(ModuleManager.BaseModule): "server": event["server"], "tags": event["tags"], "action": action} - if target[0] in event["server"].channel_types: - channel = event["server"].channels.get(event["args"][0]) + if is_channel: self._event(event, "message.channel", user=user, channel=channel, **kwargs) channel.buffer.add_message(user_nickname, message, action, event["tags"], user==None) elif event["server"].is_own_nickname(target): self._event(event, "message.private", user=user, **kwargs) - user.buffer.add_message(user_nickname, message, action, - event["tags"], user=None) + user.buffer.add_message(user.nickname, message, action, + event["tags"], False) + elif not "prefix" in event: + # a message we've sent to a user + user = event["server"].get_user(target) + user.buffer.add_message(None, message, action, event["tags"], True) + self._event(event, "message.private", user=user, **kwargs) - # we've received a notice + # we've received/sent a notice @utils.hook("raw.received.notice") + @utils.hook("raw.send.notice") def notice(self, event): message = event["args"][1] message_split = message.split(" ") target = event["args"][0] - if not event["prefix"] or event["prefix"].hostmask == event["server" - ].name or target == "*" or (not event["prefix"].hostname and - not event["server"].name): + if (("prefix" in event and not event["prefix"]) or + event["prefix"].hostmask == event["server"].name or + target == "*" or + (not event["prefix"].hostname and not event["server"].name)): event["server"].name = event["prefix"].hostmask self._event(event, "server-notice", message=message, message_split=message_split, server=event["server"]) else: - user = event["server"].get_user(event["prefix"].nickname) + user = None + user_nickname = None + if "prefix" in event: + user = event["server"].get_user(event["prefix"].nickname) + + kwargs = {"message": message, "message_split": message_split, + "server": event["server"], "tags": event["tags"]} if target[0] in event["server"].channel_types: channel = event["server"].channels.get(target) - self._event(event, "notice.channel", message=message, - message_split=message_split, user=user, - server=event["server"], channel=channel, - tags=event["tags"]) + self._event(event, "notice.channel", user=user, channel=channel, + **kwargs) + channel.buffer.add_notice(user_nickname, message, False, + event["tags"], user==None) elif event["server"].is_own_nickname(target): - self._event(event, "notice.private", message=message, - message_split=message_split, user=user, - server=event["server"], tags=event["tags"]) + self._event(event, "notice.private", user=user, **kwargs) + user.buffer.add_notice(user.nickname, message, False, + event["tags"], False) + elif not "prefix" in event: + # a notice we've sent to a user + user = event["server"].get_user(target) + user.buffer.add_message(None, message, action, event["tags"], True) + self._event(event, "notice.private", user=user, **kwargs) # IRCv3 TAGMSG, used to send tags without any other information @utils.hook("raw.received.tagmsg") diff --git a/src/utils/irc.py b/src/utils/irc.py index c39c84bc..c208e9d9 100644 --- a/src/utils/irc.py +++ b/src/utils/irc.py @@ -245,3 +245,17 @@ class IRCConnectionParameters(object): self.username = username self.realname = realname self.args = args + +class CTCPMessage(object): + def __init__(self, command: str, message: str): + self.command = command + self.message = message +def parse_ctcp(s: str) -> typing.Optional[CTCPMessage]: + ctcp = s.startswith("\x01") + if s.startswith("\x01"): + ctcp_command, sep, ctcp_message = s[1:].partition(" ") + if message.endswith("\x01"): + message = message[:-1] + return CTCPMessage(ctcp_command, ctcp_message) + + return None