From 9ed1eaad40ce8639dc0b629f37033dba1cff3639 Mon Sep 17 00:00:00 2001 From: Christian Heller Date: Sat, 6 Sep 2025 06:42:56 +0200 Subject: [PATCH] Communicate user exits via User.exit_msg rather than client-side logging. --- ircplom/client.py | 16 +++++++--------- ircplom/client_tui.py | 32 ++++++++++++++++++++++++-------- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/ircplom/client.py b/ircplom/client.py index c61ece4..f8e4c1d 100644 --- a/ircplom/client.py +++ b/ircplom/client.py @@ -263,7 +263,7 @@ class LogScope(Enum): SERVER = auto() RAW = auto() CHAT = auto() - NICKNAME = auto() + USER = auto() SAME = auto() @@ -407,6 +407,7 @@ class _NickUserHost(NickUserHost): class _User(_NickUserHost): modes: str = '?' + exit_msg: str = '' @property def id_(self) -> str: @@ -784,21 +785,18 @@ class Client(ABC, ClientQueueMixin): else ret['channel'])} self._log(ret['message'], out=False, **kw) elif ret['_verb'] == 'PART': + ret['parter'].exit_msg = 'P' + ret.get('message', '') + ret['parter'].exit_msg = '' self.db.channels[ret['channel']].remove_user(ret['parter']) - if 'message' in ret: - self._log(f'{ret["parter"]} parts: {ret["message"]}', - LogScope.CHAT, target=ret['channel']) if ret['parter'] is self.db.users['me']: del self.db.channels[ret['channel']] self.db.purge_users() elif ret['_verb'] == 'PING': self.send(IrcMessage(verb='PONG', params=(ret['reply'],))) elif ret['_verb'] == 'QUIT': - for ch_name, ch in self.db.chans_of_user(ret['quitter'].id_ - ).items(): - ch.remove_user(ret['quitter']) - self._log(f'{ret["quitter"]} quits: {ret["message"]}', - LogScope.CHAT, target=ch_name) + ret['quitter'].exit_msg = 'Q' + ret['message'] + for channel in self.db.chans_of_user(ret['quitter'].id_).values(): + channel.remove_user(ret['quitter']) ClientsDb = dict[str, Client] diff --git a/ircplom/client_tui.py b/ircplom/client_tui.py index dea90f5..54005e2 100644 --- a/ircplom/client_tui.py +++ b/ircplom/client_tui.py @@ -213,8 +213,6 @@ class _UpdatingChannel(_UpdatingNode): else: msg['nuhs:joining'] = tuple(id_ for id_ in update.value if id_ not in self.user_ids) - msg['nuhs:parting'] = tuple(id_ for id_ in self.user_ids - if id_ not in update.value) if super().set_and_check_for_change(update): if update.path == ('topic',): msg = f'raw:{self.topic.who} set topic to: {self.topic.what}' @@ -223,9 +221,24 @@ class _UpdatingChannel(_UpdatingNode): class _UpdatingUser(_UpdatingNode, NickUserHost): - log_scopes = {('nick',): LogScope.NICKNAME} + log_scopes = {('nick',): LogScope.USER, + ('exit_msg',): LogScope.USER} prev_nick = '?' modes = '?' + exit_msg = '' + + def set_and_check_for_change(self, update: _Update + ) -> Optional[tuple[LogScope, Any]]: + if update.path == ('exit_msg',): + assert isinstance(update.value, str) + if super().set_and_check_for_change(update) and update.value: + return self._scope(update.path), { + 'user': str(self), + 'msg': (f': {update.value[1:]}' if len(update.value) > 1 + else ''), + 'verb': 'quits' if update.value[0] == 'Q' else 'parts'} + return None + return super().set_and_check_for_change(update) @property def prev(self) -> str: @@ -330,13 +343,16 @@ class _ClientWindowsManager: scope, value = result log_path = ':'.join(update.path) log_kwargs: dict[str, Any] = {'scope': scope} - if scope in {LogScope.CHAT, LogScope.NICKNAME}: + if scope in {LogScope.CHAT, LogScope.USER}: log_kwargs |= {'target': update.path[1]} if value is None: self.log(f'{log_path} cleared', **log_kwargs) - elif scope is LogScope.NICKNAME: - self.log(f'{self.db.users[update.path[1]].prev} renames {value}', - **log_kwargs) + elif scope is LogScope.USER: + if update.path[-1] == 'nick': + msg = f'{self.db.users[update.path[1]].prev} renames {value}' + elif update.path[-1] == 'exit_msg': + msg = f'{value["user"]} {value["verb"]}{value["msg"]}' + self.log(msg, **log_kwargs) elif isinstance(value, dict): for verb, item in [(k, v) for k, v in value.items() if v]: toks = verb.split(':', maxsplit=1) @@ -383,7 +399,7 @@ class ClientTui(BaseTui): if kwargs['target'] != m.db.users['me'].nick else kwargs['sender']) return [m.window(LogScope.CHAT, chatname=chatname)] - if scope == LogScope.NICKNAME: + if scope == LogScope.USER: return m.windows_for_userid(kwargs['target']) return [m.window(scope)] return super()._log_target_wins(**kwargs) -- 2.30.2