Skip to content

Commit f3ff033

Browse files
committed
Switch data dicts to casefolded variants
1 parent abca955 commit f3ff033

1 file changed

Lines changed: 41 additions & 36 deletions

File tree

plugins/chan_track.py

Lines changed: 41 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,7 @@ class WeakDict(dict):
1818
pass
1919

2020

21-
class DataDict(defaultdict):
22-
def __init__(self, *args, **kwargs):
23-
super().__init__(*args, **kwargs)
24-
21+
class KeyFoldMixin:
2522
def __contains__(self, item):
2623
return super().__contains__(item.casefold())
2724

@@ -34,8 +31,18 @@ def __setitem__(self, key, value):
3431
def __delitem__(self, key):
3532
super().__delitem__(key.casefold())
3633

34+
35+
class KeyFoldDict(dict, KeyFoldMixin):
36+
pass
37+
38+
39+
class KeyFoldWeakValueDict(WeakValueDictionary, KeyFoldMixin):
40+
pass
41+
42+
43+
class ChanDict(defaultdict, KeyFoldMixin):
3744
def __missing__(self, key):
38-
data = WeakDict(name=key, users={})
45+
data = WeakDict(name=key, users=KeyFoldDict())
3946
self[key] = data
4047
return data
4148

@@ -65,19 +72,24 @@ def get_chan_data(bot):
6572

6673
@hook.connect
6774
def init_chan_data(conn):
68-
chan_data = conn.memory.setdefault("chan_data", DataDict())
75+
chan_data = conn.memory.setdefault("chan_data", ChanDict())
6976
chan_data.clear()
7077

71-
users = conn.memory.setdefault("users", WeakValueDictionary())
78+
users = conn.memory.setdefault("users", KeyFoldWeakValueDict())
7279
users.clear()
7380

7481

82+
def add_user_membership(user, chan, membership):
83+
chans = user.setdefault("channels", KeyFoldWeakValueDict())
84+
chans[chan] = membership
85+
86+
7587
def replace_user_data(conn, chan_data):
7688
statuses = {status.prefix: status for status in set(conn.memory["server_info"]["statuses"].values())}
7789
users = conn.memory["users"]
7890
old_users = chan_data['users']
7991
new_data = chan_data.pop("new_users", [])
80-
new_users = {}
92+
new_users = KeyFoldDict()
8193
caps = conn.memory.get("server_caps", {})
8294
has_uh_i_n = caps.get("userhost-in-names", False)
8395
has_multi_pfx = caps.get("multi-prefix", False)
@@ -103,19 +115,18 @@ def replace_user_data(conn, chan_data):
103115
else:
104116
user_data["nick"] = name
105117

106-
nick_cf = user_data["nick"].casefold()
107-
new_users[nick_cf] = memb_data
108-
if nick_cf in old_users:
109-
old_data = old_users[nick_cf]
118+
nick = user_data["nick"]
119+
new_users[nick] = memb_data
120+
if nick in old_users:
121+
old_data = old_users[nick]
110122
old_data.update(memb_data) # New data takes priority over old data
111123
memb_data.update(old_data)
112124

113-
old_user_data = users.setdefault(nick_cf, user_data)
125+
old_user_data = users.setdefault(nick, user_data)
114126
old_user_data.update(user_data)
115127
user_data = old_user_data
116128
memb_data["user"] = user_data
117-
user_chans = user_data.setdefault("channels", WeakValueDictionary())
118-
user_chans[chan_data["name"].casefold()] = memb_data
129+
add_user_membership(user_data, chan_data["name"], memb_data)
119130

120131
old_users.clear()
121132
old_users.update(new_users) # Reassigning the dict would break other references to the data, so just update instead
@@ -168,11 +179,10 @@ def perm_check(chan, conn, nick):
168179
return False
169180

170181
chan_data = chans[chan]
171-
nick_cf = nick.casefold()
172-
if nick_cf not in chan_data["users"]:
182+
if nick not in chan_data["users"]:
173183
return False
174184

175-
memb = chan_data["users"][nick_cf]
185+
memb = chan_data["users"][nick]
176186
status = memb["status"]
177187
if status and status[0].level > 1:
178188
return True
@@ -223,12 +233,11 @@ def on_join(chan, nick, user, host, conn):
223233

224234
users = conn.memory['users']
225235
user_data = WeakDict(nick=nick, user=user, host=host)
226-
user_data = users.setdefault(nick.casefold(), user_data)
236+
user_data = users.setdefault(nick, user_data)
227237
chan_data = conn.memory["chan_data"][chan]
228238
memb_data = WeakDict(chan=weakref.proxy(chan_data), user=user_data, status=[])
229-
chan_data["users"][nick.casefold()] = memb_data
230-
user_chans = user_data.setdefault("channels", WeakValueDictionary())
231-
user_chans[chan.casefold()] = memb_data
239+
chan_data["users"][nick] = memb_data
240+
add_user_membership(user_data, chan, memb_data)
232241

233242

234243
def on_mode(chan, irc_paramlist, conn):
@@ -267,7 +276,7 @@ def on_mode(chan, irc_paramlist, conn):
267276
param = mode_params.pop(0)
268277

269278
if is_status:
270-
memb = chan_data["users"][param.casefold()]
279+
memb = chan_data["users"][param]
271280
status = statuses[c]
272281
if adding:
273282
memb["status"].append(status)
@@ -283,16 +292,15 @@ def on_part(chan, nick, conn):
283292
chan = chan[1:]
284293

285294
channels = conn.memory["chan_data"]
286-
nick_cf = nick.casefold()
287-
if nick_cf == conn.nick.casefold():
295+
if nick.casefold() == conn.nick.casefold():
288296
try:
289297
del channels[chan]
290298
except KeyError:
291299
pass
292300
else:
293301
chan_data = channels[chan]
294302
try:
295-
del chan_data["users"][nick_cf]
303+
del chan_data["users"][nick]
296304
except KeyError:
297305
pass
298306

@@ -304,27 +312,24 @@ def on_kick(chan, target, conn):
304312

305313
@hook.irc_raw('QUIT')
306314
def on_quit(nick, conn):
307-
nick_cf = nick.casefold()
308315
users = conn.memory["users"]
309-
if nick_cf in users:
310-
user = users[nick_cf]
316+
if nick in users:
317+
user = users[nick]
311318
for memb in user.get("channels", {}).values():
312319
chan = memb["chan"]
313-
chan["users"].pop(nick_cf)
320+
chan["users"].pop(nick)
314321

315322

316323
@hook.irc_raw('NICK')
317324
def on_nick(nick, irc_paramlist, conn):
318325
users = conn.memory["users"]
319-
nick_cf = nick.casefold()
320326
new_nick = irc_paramlist[0]
321327
if new_nick.startswith(':'):
322328
new_nick = new_nick[1:]
323329

324-
new_nick_cf = new_nick.casefold()
325-
user = users.pop(nick_cf)
326-
users[new_nick_cf] = user
330+
user = users.pop(nick)
331+
users[new_nick] = user
327332
user["nick"] = nick
328-
for memb in user["channels"].values():
333+
for memb in user.get("channels", {}).values():
329334
chan_users = memb["chan"]["users"]
330-
chan_users[new_nick_cf] = chan_users.pop(nick_cf)
335+
chan_users[new_nick] = chan_users.pop(nick)

0 commit comments

Comments
 (0)