Better parsing of CTCP messages, support raw.send.privmsg/raw.send.notice in

modules/line_handler.py
This commit is contained in:
jesopo 2018-11-14 21:28:27 +00:00
parent 05eea3b585
commit 378f4b1f93
2 changed files with 65 additions and 21 deletions

View file

@ -401,11 +401,24 @@ class Module(ModuleManager.BaseModule):
message = event["args"][1] message = event["args"][1]
message_split = message.split(" ") message_split = message.split(" ")
target = event["args"][0] target = event["args"][0]
action = message.startswith("\x01ACTION ")
if action: channel = None
message = message.replace("\x01ACTION ", "", 1) if target[0] in event["server"].channel_types:
if message.endswith("\x01"): channel = event["server"].channels.get(event["args"][0])
message = message[:-1]
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"]: if user and "account" in event["tags"]:
user.identified_account = event["tags"]["account"] user.identified_account = event["tags"]["account"]
@ -416,44 +429,61 @@ class Module(ModuleManager.BaseModule):
"server": event["server"], "tags": event["tags"], "server": event["server"], "tags": event["tags"],
"action": action} "action": action}
if target[0] in event["server"].channel_types: if is_channel:
channel = event["server"].channels.get(event["args"][0])
self._event(event, "message.channel", user=user, channel=channel, self._event(event, "message.channel", user=user, channel=channel,
**kwargs) **kwargs)
channel.buffer.add_message(user_nickname, message, action, channel.buffer.add_message(user_nickname, message, action,
event["tags"], user==None) event["tags"], user==None)
elif event["server"].is_own_nickname(target): elif event["server"].is_own_nickname(target):
self._event(event, "message.private", user=user, **kwargs) self._event(event, "message.private", user=user, **kwargs)
user.buffer.add_message(user_nickname, message, action, user.buffer.add_message(user.nickname, message, action,
event["tags"], user=None) 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.received.notice")
@utils.hook("raw.send.notice")
def notice(self, event): def notice(self, event):
message = event["args"][1] message = event["args"][1]
message_split = message.split(" ") message_split = message.split(" ")
target = event["args"][0] target = event["args"][0]
if not event["prefix"] or event["prefix"].hostmask == event["server" if (("prefix" in event and not event["prefix"]) or
].name or target == "*" or (not event["prefix"].hostname and event["prefix"].hostmask == event["server"].name or
not event["server"].name): target == "*" or
(not event["prefix"].hostname and not event["server"].name)):
event["server"].name = event["prefix"].hostmask event["server"].name = event["prefix"].hostmask
self._event(event, "server-notice", message=message, self._event(event, "server-notice", message=message,
message_split=message_split, server=event["server"]) message_split=message_split, server=event["server"])
else: 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: if target[0] in event["server"].channel_types:
channel = event["server"].channels.get(target) channel = event["server"].channels.get(target)
self._event(event, "notice.channel", message=message, self._event(event, "notice.channel", user=user, channel=channel,
message_split=message_split, user=user, **kwargs)
server=event["server"], channel=channel, channel.buffer.add_notice(user_nickname, message, False,
tags=event["tags"]) event["tags"], user==None)
elif event["server"].is_own_nickname(target): elif event["server"].is_own_nickname(target):
self._event(event, "notice.private", message=message, self._event(event, "notice.private", user=user, **kwargs)
message_split=message_split, user=user, user.buffer.add_notice(user.nickname, message, False,
server=event["server"], tags=event["tags"]) 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 # IRCv3 TAGMSG, used to send tags without any other information
@utils.hook("raw.received.tagmsg") @utils.hook("raw.received.tagmsg")

View file

@ -245,3 +245,17 @@ class IRCConnectionParameters(object):
self.username = username self.username = username
self.realname = realname self.realname = realname
self.args = args 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