aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--modules/labeled_responses.py49
-rw-r--r--modules/line_handler/__init__.py20
-rw-r--r--modules/line_handler/ircv3.py1
-rw-r--r--src/IRCServer.py6
-rw-r--r--src/utils/irc/__init__.py3
5 files changed, 65 insertions, 14 deletions
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)