import codecs, re RE_ISUPPORT_ESCAPE = re.compile(r"\\x(\d\d)", re.I) RE_MODES = re.compile(r"[-+]\w+") def ping(event): event["server"].send_pong(event["line"].args[0]) def handle_001(event): event["server"].socket.enable_write_throttle() event["server"].name = event["line"].source.hostmask event["server"].set_own_nickname(event["line"].args[0]) event["server"].send_whois(event["server"].nickname) event["server"].send_mode(event["server"].nickname) event["server"].connected = True def handle_005(events, event): isupport_list = event["line"].args[1:-1] 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 event["server"].isupport.update(isupport) if "NAMESX" in isupport and not event["server"].has_capability_str( "multi-prefix"): event["server"].send_raw("PROTOCTL NAMESX") if "PREFIX" in isupport: modes, symbols = isupport["PREFIX"][1:].split(")", 1) event["server"].prefix_symbols.clear() event["server"].prefix_modes.clear() for symbol, mode in zip(symbols, modes): event["server"].prefix_symbols[symbol] = mode event["server"].prefix_modes[mode] = symbol if "CHANMODES" in isupport: modes = isupport["CHANMODES"].split(",", 3) event["server"].channel_list_modes = list(modes[0]) event["server"].channel_parametered_modes = list(modes[1]) event["server"].channel_setting_modes = list(modes[2]) event["server"].channel_modes = list(modes[3]) if "CHANTYPES" in isupport: event["server"].channel_types = list(isupport["CHANTYPES"]) if "CASEMAPPING" in isupport: event["server"].case_mapping = isupport["CASEMAPPING"] if "STATUSMSG" in isupport: event["server"].statusmsg = list(isupport["STATUSMSG"]) events.on("received.005").call(isupport=isupport, server=event["server"]) def handle_004(event): event["server"].version = event["line"].args[2] def motd_start(event): event["server"].motd_lines.clear() def motd_line(event): event["server"].motd_lines.append(event["line"].args[1]) def _own_modes(server, modes): mode_chunks = RE_MODES.findall(modes) for chunk in mode_chunks: remove = chunk[0] == "-" for mode in chunk[1:]: server.change_own_mode(remove, mode) def mode(events, event): user = event["server"].get_user(event["line"].source.nickname) target = event["line"].args[0] is_channel = target[0] in event["server"].channel_types if is_channel: channel = event["server"].channels.get(target) modes = event["line"].args[1] args = event["line"].args[2:] new_modes = channel.parse_modes(modes, args[:]) events.on("received.mode.channel").call(modes=new_modes, channel=channel, server=event["server"], user=user, modes_str=modes, args_str=args) elif event["server"].is_own_nickname(target): modes = event["line"].args[1] _own_modes(event["server"], modes) events.on("self.mode").call(modes=modes, server=event["server"]) event["server"].send_who(event["server"].nickname) def handle_221(event): _own_modes(event["server"], event["line"].args[1]) def invite(events, event): target_channel = event["line"].args[1] user = event["server"].get_user(event["line"].source.nickname) target_user = event["server"].get_user(event["line"].args[0]) events.on("received.invite").call(user=user, target_channel=target_channel, server=event["server"], target_user=target_user) def handle_352(event): nickname = event["line"].args[5] username = event["line"].args[2] hostname = event["line"].args[3] if event["server"].is_own_nickname(nickname): event["server"].username = username event["server"].hostname = hostname target = event["server"].get_user(nickname) target.username = username target.hostname = hostname def handle_354(event): if event["line"].args[1] == "111": nickname = event["line"].args[4] username = event["line"].args[2] hostname = event["line"].args[3] realname = event["line"].args[6] account = event["line"].args[5] if event["server"].is_own_nickname(nickname): event["server"].username = username event["server"].hostname = hostname event["server"].realname = realname target = event["server"].get_user(nickname) target.username = username target.hostname = hostname target.realname = realname if not account == "0": target.identified_account = account else: target.identified_account = None def _nick_in_use(server): new_nick = "%s|" % server.connection_params.nickname server.send_nick(new_nick) def handle_433(event): _nick_in_use(event["server"]) def handle_437(event): _nick_in_use(event["server"])