aboutsummaryrefslogtreecommitdiff
path: root/modules/line_handler.py
diff options
context:
space:
mode:
authorGravatar jesopo2018-11-08 11:11:38 +0000
committerGravatar jesopo2018-11-08 11:13:19 +0000
commit4d272a3fa49275160d14a63f89dd838032735a1b (patch)
treec2dee81e22ddb2cd864bba6d9f224f9b4343d534 /modules/line_handler.py
parentExplicitly denote when an :arbitrary arg is present in an IRCLine (diff)
Refactor handling ISUPPORT and support hex escapes therein
Diffstat (limited to 'modules/line_handler.py')
-rw-r--r--modules/line_handler.py57
1 files changed, 34 insertions, 23 deletions
diff --git a/modules/line_handler.py b/modules/line_handler.py
index a3a04022..90153a1b 100644
--- a/modules/line_handler.py
+++ b/modules/line_handler.py
@@ -1,11 +1,11 @@
-import re, threading
+import codecs, re, threading
from src import ModuleManager, utils
-RE_PREFIXES = re.compile(r"\bPREFIX=\((\w+)\)(\W+)(?:\b|$)")
-RE_CHANMODES = re.compile(
- r"\bCHANMODES=(\w*),(\w*),(\w*),(\w*)(?:\b|$)")
-RE_CHANTYPES = re.compile(r"\bCHANTYPES=(\W+)(?:\b|$)")
-RE_CASEMAPPING = re.compile(r"\bCASEMAPPING=(\S+)")
+RE_ISUPPORT_ESCAPE = re.compile(r"\\x(\d\d)", re.I)
+RE_PREFIXES = re.compile(r"\((\w+)\)(\W+)")
+RE_CHANMODES = re.compile(r"(\w*),(\w*),(\w*),(\w*)")
+RE_CHANTYPES = re.compile(r"(\W+)")
+RE_CASEMAPPING = re.compile(r"(\S+)")
RE_MODES = re.compile(r"[-+]\w+")
CAPABILITIES = {"multi-prefix", "chghost", "invite-notify", "account-tag",
@@ -22,7 +22,7 @@ class Module(ModuleManager.BaseModule):
default_event = any(default_events)
kwargs = {"args": line.args, "tags": line.tags, "server": server,
- "prefix": line.prefix}
+ "prefix": line.prefix, "has_arbitrary": line.has_arbitrary}
self.events.on("raw").on(line.command).call_unsafe(**kwargs)
if default_event or not hooks:
@@ -62,33 +62,44 @@ class Module(ModuleManager.BaseModule):
# server telling us what it supports
@utils.hook("raw.005")
def handle_005(self, event):
- isupport_line = " ".join(event["args"][1:])
+ isupport_list = event["args"][1:]
+ if event["has_arbitrary"]:
+ isupport_list = isupport_list[:-1]
- if "NAMESX" in isupport_line:
+ isupport = {}
+ for i, item in enumerate(isupport_list):
+ key, sep, value = item.partition("=")
+ if value:
+ for match in RE_ISUPPORT_ESCAPE.finditer(value):
+ char = codecs.decode(match.group(1), "hex").decode("ascii")
+ value.replace(match.group(0), char)
+
+ if sep:
+ isupport[key] = value
+ else:
+ isupport[key] = None
+
+ if "NAMESX" in isupport:
event["server"].send("PROTOCTL NAMESX")
- match = re.search(RE_PREFIXES, isupport_line)
- if match:
+ if "PREFIX" in isupport:
+ modes, symbols = isupport["PREFIX"][1:].split(")", 1)
event["server"].prefix_symbols.clear()
event["server"].prefix_modes.clear()
- modes = match.group(1)
- symbols = match.group(2)
for symbol, mode in zip(symbols, modes):
event["server"].prefix_symbols[symbol] = mode
event["server"].prefix_modes[mode] = symbol
- match = re.search(RE_CHANMODES, isupport_line)
- if match:
- event["server"].channel_modes = list(match.group(4))
- match = re.search(RE_CHANTYPES, isupport_line)
- if match:
- event["server"].channel_types = list(match.group(1))
- match = re.search(RE_CASEMAPPING, isupport_line)
- if match:
- event["server"].case_mapping = match.group(1)
+ if "CHANMODES" in isupport:
+ chanmodes = list(isupport["CHANMODES"].split(",", 3)[3])
+ event["server"].channel_modes = chanmodes
+ if "CHANTYPES" in isupport:
+ event["server"].channel_types = list(isupport["CHANTYPES"])
+ if "CASEMAPPING" in isupport:
+ event["server"].case_mapping = isupport["CASEMAPPING"]
self.events.on("received.numeric.005").call(
- isupport=isupport_line, server=event["server"])
+ isupport=isupport, server=event["server"])
# whois respose (nickname, username, realname, hostname)
@utils.hook("raw.311", default_event=True)