Respect RFC1459 casemapping rules
This commit is contained in:
parent
7530bb7cbd
commit
6c8399fa0f
6 changed files with 45 additions and 17 deletions
|
@ -1,4 +1,5 @@
|
|||
import re
|
||||
import Utils
|
||||
|
||||
class BufferLine(object):
|
||||
def __init__(self, sender, message, action, from_self):
|
||||
|
@ -28,7 +29,7 @@ class Buffer(object):
|
|||
def find(self, pattern, **kwargs):
|
||||
from_self = kwargs.get("from_self", True)
|
||||
for_user = kwargs.get("for_user", "")
|
||||
for_user = for_user.lower() if for_user else None
|
||||
for_user = Utils.irc_lower(for_user) if for_user else None
|
||||
not_pattern = kwargs.get("not_pattern", None)
|
||||
for line in self.lines:
|
||||
if line.from_self and not from_self:
|
||||
|
@ -36,7 +37,7 @@ class Buffer(object):
|
|||
elif re.search(pattern, line.message):
|
||||
if not_pattern and re.search(not_pattern, line.message):
|
||||
continue
|
||||
if for_user and not line.sender.lower() == for_user:
|
||||
if for_user and not Utils.irc_lower(line.sender) == for_user:
|
||||
continue
|
||||
return line
|
||||
def skip_next(self):
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import uuid
|
||||
import IRCBuffer
|
||||
import IRCBuffer, Utils
|
||||
|
||||
class Channel(object):
|
||||
def __init__(self, name, id, server, bot):
|
||||
self.name = name.lower()
|
||||
self.name = Utils.irc_lower(name)
|
||||
self.id = id
|
||||
self.server = server
|
||||
self.bot = bot
|
||||
|
|
|
@ -5,6 +5,7 @@ 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_MODES = re.compile(r"[-+]\w+")
|
||||
|
||||
CAPABILITIES = {"multi-prefix", "chghost", "invite-notify", "account-tag",
|
||||
|
@ -136,6 +137,11 @@ class LineHandler(object):
|
|||
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)
|
||||
|
||||
self.events.on("received.numeric.005").call(
|
||||
isupport=isupport_line, server=event["server"])
|
||||
|
||||
|
@ -554,10 +560,11 @@ class LineHandler(object):
|
|||
|
||||
# we need a registered nickname for this channel
|
||||
def handle_477(self, event):
|
||||
if event["args"][1].lower() in event["server"].attempted_join:
|
||||
channel_name = Utils.irc_lower(event["args"][1])
|
||||
if channel_name in event["server"].attempted_join:
|
||||
self.bot.add_timer("rejoin", 5,
|
||||
channel_name=event["args"][1],
|
||||
key=event["server"].attempted_join[event["args"][1].lower()],
|
||||
key=event["server"].attempted_join[channel_name],
|
||||
server_id=event["server"].id)
|
||||
|
||||
# someone's been kicked from a channel
|
||||
|
|
19
IRCServer.py
19
IRCServer.py
|
@ -47,6 +47,7 @@ class Server(object):
|
|||
{"@": "o", "+": "v"})
|
||||
self.channel_modes = []
|
||||
self.channel_types = []
|
||||
self.case_mapping = "rfc1459"
|
||||
|
||||
self.last_read = time.monotonic()
|
||||
self.last_send = None
|
||||
|
@ -130,9 +131,9 @@ class Server(object):
|
|||
|
||||
def set_own_nickname(self, nickname):
|
||||
self.nickname = nickname
|
||||
self.nickname_lower = nickname.lower()
|
||||
self.nickname_lower = Utils.irc_lower(nickname)
|
||||
def is_own_nickname(self, nickname):
|
||||
return nickname.lower() == self.nickname_lower
|
||||
return Utils.irc_equals(nickname, self.nickname)
|
||||
|
||||
def add_own_mode(self, mode, arg=None):
|
||||
self.own_modes[mode] = arg
|
||||
|
@ -145,7 +146,7 @@ class Server(object):
|
|||
self.add_own_mode(mode, arg)
|
||||
|
||||
def has_user(self, nickname):
|
||||
return nickname.lower() in self.users
|
||||
return Utils.irc_lower(nickname) in self.users
|
||||
def get_user(self, nickname):
|
||||
if not self.has_user(nickname):
|
||||
user_id = self.get_user_id(nickname)
|
||||
|
@ -154,7 +155,7 @@ class Server(object):
|
|||
user=new_user, server=self)
|
||||
self.users[new_user.nickname_lower] = new_user
|
||||
self.new_users.add(new_user)
|
||||
return self.users[nickname.lower()]
|
||||
return self.users[Utils.irc_lower(nickname)]
|
||||
def get_user_id(self, nickname):
|
||||
self.bot.database.users.add(self.id, nickname)
|
||||
return self.bot.database.users.get_id(self.id, nickname)
|
||||
|
@ -164,12 +165,12 @@ class Server(object):
|
|||
channel.remove_user(user)
|
||||
|
||||
def change_user_nickname(self, old_nickname, new_nickname):
|
||||
user = self.users.pop(old_nickname.lower())
|
||||
user = self.users.pop(Utils.irc_lower(old_nickname))
|
||||
user._id = self.get_user_id(new_nickname)
|
||||
self.users[new_nickname.lower()] = user
|
||||
self.users[Utils.irc_lower(new_nickname)] = user
|
||||
def has_channel(self, channel_name):
|
||||
return channel_name[0] in self.channel_types and channel_name.lower(
|
||||
) in self.channels
|
||||
return channel_name[0] in self.channel_types and Utils.irc_lower(
|
||||
channel_name) in self.channels
|
||||
def get_channel(self, channel_name):
|
||||
if not self.has_channel(channel_name):
|
||||
channel_id = self.get_channel_id(channel_name)
|
||||
|
@ -178,7 +179,7 @@ class Server(object):
|
|||
self.events.on("new").on("channel").call(
|
||||
channel=new_channel, server=self)
|
||||
self.channels[new_channel.name] = new_channel
|
||||
return self.channels[channel_name.lower()]
|
||||
return self.channels[Utils.irc_lower(channel_name)]
|
||||
def get_channel_id(self, channel_name):
|
||||
self.bot.database.channels.add(self.id, channel_name)
|
||||
return self.bot.database.channels.get_id(self.id, channel_name)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import uuid
|
||||
import IRCBuffer
|
||||
import IRCBuffer, Utils
|
||||
|
||||
class User(object):
|
||||
def __init__(self, nickname, id, server, bot):
|
||||
|
@ -31,7 +31,7 @@ class User(object):
|
|||
|
||||
def set_nickname(self, nickname):
|
||||
self.nickname = nickname
|
||||
self.nickname_lower = nickname.lower()
|
||||
self.nickname_lower = Utils.irc_lower(nickname)
|
||||
self.name = self.nickname_lower
|
||||
def join_channel(self, channel):
|
||||
self.channels.add(channel)
|
||||
|
|
19
Utils.py
19
Utils.py
|
@ -1,10 +1,14 @@
|
|||
import json, re, traceback, urllib.request, urllib.parse, urllib.error, ssl
|
||||
import string
|
||||
import bs4
|
||||
|
||||
USER_AGENT = ("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 "
|
||||
"(KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36")
|
||||
REGEX_HTTP = re.compile("https?://", re.I)
|
||||
|
||||
RFC1459_UPPER = r'\[]~'
|
||||
RFC1459_UPPER = r'|{}^'
|
||||
|
||||
def remove_colon(s):
|
||||
if s.startswith(":"):
|
||||
s = s[1:]
|
||||
|
@ -13,6 +17,21 @@ def remove_colon(s):
|
|||
def arbitrary(s, n):
|
||||
return remove_colon(" ".join(s[n:]))
|
||||
|
||||
def _rfc1459_lower(s):
|
||||
for upper, lower in zip(RFC1459_UPPER, RFC1459_LOWER):
|
||||
s = s.replace(upper, lower)
|
||||
return s.lower()
|
||||
def irc_lower(server, s):
|
||||
if server.case_mapping == "ascii":
|
||||
return s.lower()
|
||||
elif server.case_mapping == "rfc1459":
|
||||
return _rfc1459_lower(s)
|
||||
else:
|
||||
raise ValueError("unknown casemapping '%s'" % server.case_mapping)
|
||||
|
||||
def irc_equals(server, s1, s2):
|
||||
return irc_lower(server, s1) == irc_lower(server, s2)
|
||||
|
||||
class IRCHostmask(object):
|
||||
def __init__(self, nickname, username, hostname, hostmask):
|
||||
self.nickname = nickname
|
||||
|
|
Loading…
Reference in a new issue