diff --git a/src/channels.py b/src/channels.py index c51f7da..f52f89c 100644 --- a/src/channels.py +++ b/src/channels.py @@ -4,6 +4,7 @@ from enum import Enum from src.context import IRCContext, Features, lower from src.events import Event +from src import settings as var from src import users Main = None # main channel @@ -259,6 +260,9 @@ class Channel(IRCContext): if not self.modes[mode]: del self.modes[mode] del user.channels[self] + if len(user.channels) == 0: + event = Event("cleanup_user", {}) + event.dispatch(var, user) def _clear(self): for user in self.users: diff --git a/src/users.py b/src/users.py index 075a2b5..ca5e10c 100644 --- a/src/users.py +++ b/src/users.py @@ -1,16 +1,15 @@ -from weakref import WeakSet import fnmatch import re from src.context import IRCContext, Features, lower, equals from src import settings as var -from src import db +from src import db, events import botconfig Bot = None # bot instance -_users = WeakSet() +_users = set() _arg_msg = "(nick={0!r}, ident={1!r}, host={2!r}, realname={3!r}, account={4!r}, allow_bot={5})" @@ -183,6 +182,14 @@ def parse_rawnick_as_dict(rawnick, *, default=None): return _raw_nick_pattern.search(rawnick).groupdict(default) +def _cleanup_user(evt, var, user): + """Removes a user from our global tracking set once it has left all channels.""" + _users.discard(user) + +# Can't use @event_listener decorator since src/decorators.py imports us +# (meaning decorator isn't defined at the point in time we are run) +events.add_listener("cleanup_user", _cleanup_user) + class User(IRCContext): is_user = True