From 367eb1c60ed295b75b7d41f8e5d4955b8037bdad Mon Sep 17 00:00:00 2001 From: jesopo Date: Thu, 30 May 2019 15:34:39 +0100 Subject: [PATCH] Make labeled-resposnes it's own module, tag and track every sent line --- modules/labeled_responses.py | 49 ++++++++++++++++++++++++++++++++ modules/line_handler/__init__.py | 20 ++++++------- modules/line_handler/ircv3.py | 1 - src/IRCServer.py | 6 +++- src/utils/irc/__init__.py | 3 ++ 5 files changed, 65 insertions(+), 14 deletions(-) create mode 100644 modules/labeled_responses.py diff --git a/modules/labeled_responses.py b/modules/labeled_responses.py new file mode 100644 index 00000000..eee53c58 --- /dev/null +++ b/modules/labeled_responses.py @@ -0,0 +1,49 @@ +import uuid +from src import ModuleManager, utils + +CAP = utils.irc.Capability(None, "draft/labeled-response-0.2") +TAG = utils.irc.MessageTag(None, "draft/label") + +CAP_TO_TAG = { + "draft/labeled-response-0.2": "draft/label" +} + +class Module(ModuleManager.BaseModule): + @utils.hook("new.server") + def new_server(self, event): + event["server"]._label_cache = {} + + @utils.hook("received.cap.ls") + @utils.hook("received.cap.new") + def on_cap(self, event): + if CAP.available(event["capabilities"]): + return CAP.copy() + + @utils.hook("preprocess.send") + def raw_send(self, event): + available_cap = event["server"].available_capability(CAP) + + if available_cap: + label = TAG.get_value(event["line"].tags) + if label == None: + tag_key = CAP_TO_TAG[available_cap] + label = str(uuid.uuid4()) + event["line"].tags[tag_key] = label + + event["server"]._label_cache[label] = event["line"] + + @utils.hook("raw.received") + def raw_recv(self, event): + if not event["line"].command == "BATCH": + label = TAG.get_value(event["line"].tags) + if not label == None: + self._recv(event["server"], label, event["line"]) + + @utils.hook("received.batch.end") + def batch_end(self, event): + if TAG.match(event["batch"].type): + self._recv(event["server"], event["batch"].identifier, None) + + def _recv(self, server, label, line): + cached_line = server._label_cache.pop(label) + # do something with the line! diff --git a/modules/line_handler/__init__.py b/modules/line_handler/__init__.py index 1d4881f9..a1b05426 100644 --- a/modules/line_handler/__init__.py +++ b/modules/line_handler/__init__.py @@ -2,10 +2,6 @@ import enum from src import EventManager, ModuleManager, utils from . import channel, core, ircv3, message, user -LABELED_BATCH = { - "draft/labeled-response": "draft/label" -} - class Module(ModuleManager.BaseModule): def _handle(self, server, line): hooks = self.events.on("raw.received").on(line.command).get_hooks() @@ -186,20 +182,20 @@ class Module(ModuleManager.BaseModule): if modifier == "+": batch_type = event["args"][1] - event["server"].batches[identifier] = utils.irc.IRCRecvBatch( - identifier, batch_type, event["tags"]) + batch = utils.irc.IRCRecvBatch(identifier, batch_type, + event["tags"]) + event["server"].batches[identifier] = batch + + self.events.on("received.batch.start").call(batch=batch, + server=event["server"]) else: batch = event["server"].batches[identifier] del event["server"].batches[identifier] - add_tags = {} - if batch.type in LABELED_BATCH.keys(): - tag_name = LABELED_BATCH[batch.type] - add_tags[tag_name] = batch.tags[tag_name] + self.events.on("received.batch.end").call(batch=batch, + server=event["server"]) for line in batch.lines: - if add_tags: - line.tags.update(add_tags) self._handle(event["server"], line) # IRCv3 CHGHOST, a user's username and/or hostname has changed diff --git a/modules/line_handler/ircv3.py b/modules/line_handler/ircv3.py index 8b6b459d..d9f83b75 100644 --- a/modules/line_handler/ircv3.py +++ b/modules/line_handler/ircv3.py @@ -13,7 +13,6 @@ CAPABILITIES = [ utils.irc.Capability("cap-notify"), utils.irc.Capability("batch"), utils.irc.Capability("echo-message"), - utils.irc.Capability(None, "draft/labeled-response-0.2"), utils.irc.Capability(None, "draft/rename"), utils.irc.Capability(None, "draft/setname") ] diff --git a/src/IRCServer.py b/src/IRCServer.py index c970f5de..6838968e 100644 --- a/src/IRCServer.py +++ b/src/IRCServer.py @@ -248,6 +248,8 @@ class Server(IRCObject.Object): self.events.on("preprocess.send").on(line_parsed.command ).call_unsafe(server=self, line=line_parsed) + self.events.on("preprocess.send").call_unsafe(server=self, + line=line_parsed) line = line_parsed.format() line_obj = IRCLine.SentLine(datetime.datetime.utcnow(), self.hostmask(), @@ -283,9 +285,11 @@ class Server(IRCObject.Object): def send_authenticate(self, text: str) -> IRCLine.SentLine: return self.send(utils.irc.protocol.authenticate(text)) def has_capability(self, capability: utils.irc.Capability) -> bool: - return bool(capability.available(self.agreed_capabilities)) + return bool(self.available_capability(capability)) def has_capability_str(self, capability: str) -> bool: return capability in self.agreed_capabilities + def available_capability(self, capability: utils.irc.Capability) -> bool: + return capability.available(self.agreed_capabilities) def waiting_for_capabilities(self) -> bool: return bool(len(self._capabilities_waiting)) diff --git a/src/utils/irc/__init__.py b/src/utils/irc/__init__.py index 14bbb5b0..3be9b279 100644 --- a/src/utils/irc/__init__.py +++ b/src/utils/irc/__init__.py @@ -300,6 +300,9 @@ class MessageTag(object): def get_value(self, tags: typing.Dict[str, str]) -> typing.Optional[str]: key = list(set(tags.keys())&self._names) return tags[key[0]] if key else None + def match(self, s: str) -> typing.Optional[str]: + key = list(set([s])&self._names) + return key[0] if key else None def hostmask_match(hostmask: str, pattern: str) -> bool: return fnmatch.fnmatchcase(hostmask, pattern)