From: Christian Heller Date: Wed, 6 Aug 2025 17:40:54 +0000 (+0200) Subject: Overhaul chat= message targeting into explicitly named streams. X-Git-Url: https://plomlompom.com/repos/booking/%7B%7B%20web_path%20%7D%7D/%7B%7Bdb.prefix%7D%7D/static/gitweb.css?a=commitdiff_plain;h=refs%2Fheads%2Fmaster;p=ircplom Overhaul chat= message targeting into explicitly named streams. --- diff --git a/ircplom/client.py b/ircplom/client.py index e55f148..71cf2e5 100644 --- a/ircplom/client.py +++ b/ircplom/client.py @@ -12,7 +12,10 @@ from ircplom.irc_conn import (BaseIrcConnection, IrcConnAbortException, IrcMessage, PORT_SSL) ClientsDb = dict[str, 'Client'] -CHAT_GLOB = '*' +STREAM_GLOB = '*' +STREAM_PREFIX_META = ':' +STREAM_SERVER = f'{STREAM_PREFIX_META}server' +STREAM_RAW = f'{STREAM_PREFIX_META}raw' _LOG_PREFIX_PRIVMSG = '' _LOG_PREFIX_SEND_RAW = '=>|' @@ -210,7 +213,8 @@ class Client(ABC, ClientQueueMixin): 'Steps to perform right after connection.' assert self.conn is not None self.log.add('connected to server (SSL: ' - f'{"yes" if self.conn.ssl else "no"})', chat=CHAT_GLOB) + f'{"yes" if self.conn.ssl else "no"})', + stream=STREAM_GLOB) self._caps.challenge('LS', '302') self.send(IrcMessage(verb='USER', params=(getuser(), '0', '*', @@ -218,22 +222,22 @@ class Client(ABC, ClientQueueMixin): self.send(IrcMessage(verb='NICK', params=(self.conn_setup.nickname,))) @abstractmethod - def _log(self, msg: str, chat: str = '') -> None: - '''Write msg into log of chat, whatever shape that may have. - - Messages to chat=CHAT_GLOB are meant to appear in all widgets mapped to - the client, those to chat="" only in the initial connection window. - ''' - - def send(self, msg: IrcMessage, chat: str = '', to_log: str = '') -> None: + def _log(self, msg: str, stream: str = STREAM_SERVER) -> None: + 'Write msg into log of stream, whatever shape that may have.' + + def send(self, + msg: IrcMessage, + stream: str = STREAM_SERVER, + to_log: str = '' + ) -> None: 'Send line-separator-delimited message over socket.' if not self.conn: self.log.alert('cannot send, connection seems closed') return self.conn.send(msg) if to_log: - self.log.add(to_log, prefix='', chat=chat) - self.log.add(msg.raw, prefix=_LOG_PREFIX_SEND_RAW, chat=':raw') + self.log.add(to_log, prefix='', stream=stream) + self.log.add(msg.raw, prefix=_LOG_PREFIX_SEND_RAW, stream=STREAM_RAW) def update_login(self, nick_confirmed: bool, nickname: str = '') -> None: '''Manage conn_setup.nickname, .nick_confirmed. @@ -246,7 +250,8 @@ class Client(ABC, ClientQueueMixin): verb = ('set' if first_run else f'changed from "{self.conn_setup.nickname}"') self.conn_setup.nickname = nickname - self.log.add(f'{prefix} {verb} to "{nickname}"', chat=CHAT_GLOB) + self.log.add(f'{prefix} {verb} to "{nickname}"', + stream=STREAM_GLOB) if first_run or nick_confirmed != self.nick_confirmed: self.nick_confirmed = nick_confirmed if not first_run: @@ -255,7 +260,7 @@ class Client(ABC, ClientQueueMixin): def close(self) -> None: 'Close both recv Loop and socket.' - self.log.add(msg='disconnecting from server', chat=CHAT_GLOB) + self.log.add(msg='disconnecting from server', stream=STREAM_GLOB) self._caps.clear() if self.conn: self.conn.close() @@ -264,7 +269,7 @@ class Client(ABC, ClientQueueMixin): def handle_msg(self, msg: IrcMessage) -> None: 'Process incoming msg towards appropriate client steps.' - self.log.add(msg.raw, prefix=_LOG_PREFIX_RECV_RAW, chat=':raw') + self.log.add(msg.raw, prefix=_LOG_PREFIX_RECV_RAW, stream=STREAM_RAW) match msg.verb: case 'PING': self.send(IrcMessage(verb='PONG', params=(msg.params[0],))) @@ -274,7 +279,8 @@ class Client(ABC, ClientQueueMixin): self.update_login(nickname=msg.params[0], nick_confirmed=True) case 'PRIVMSG': nickname = msg.source.split('!')[0] - self.log.add(f'<[{nickname}] {msg.params[-1]}', chat=nickname, + self.log.add(f'<[{nickname}] {msg.params[-1]}', + stream=nickname, prefix=_LOG_PREFIX_PRIVMSG) case 'CAP': for to_log in self._caps.process_msg(msg.params[1:]): diff --git a/ircplom/client_tui.py b/ircplom/client_tui.py index 13a0dc6..14557ea 100644 --- a/ircplom/client_tui.py +++ b/ircplom/client_tui.py @@ -7,8 +7,9 @@ from typing import Any, Optional from ircplom.tui_base import (BaseTui, PromptWidget, TuiEvent, Window, CMD_SHORTCUTS) from ircplom.irc_conn import IrcMessage -from ircplom.client import (CHAT_GLOB, IrcConnSetup, Client, ClientIdMixin, - ClientQueueMixin, NewClientEvent) +from ircplom.client import ( + STREAM_GLOB, STREAM_PREFIX_META, STREAM_RAW, STREAM_SERVER, + IrcConnSetup, Client, ClientIdMixin, ClientQueueMixin, NewClientEvent) CMD_SHORTCUTS['disconnect'] = 'window.disconnect' CMD_SHORTCUTS['nick'] = 'window.nick' @@ -20,13 +21,13 @@ _PROMPT_UPDATE_TRIGGER_KEYS = {'nick_confirmed', 'nickname'} class _ClientWindow(Window, ClientQueueMixin): - def __init__(self, chat: str = '', **kwargs) -> None: - self.chat = chat + def __init__(self, stream: str, **kwargs) -> None: + self.stream = stream super().__init__(**kwargs) @property def _status_title(self) -> str: - return f'{super()._status_title}|{self.client_id}|{self.chat}' + return f'{super()._status_title}|{self.client_id}|{self.stream}' def _send_msg(self, verb: str, params: tuple[str, ...], **kwargs) -> None: self._cputs('send', msg=IrcMessage(verb=verb, params=params), **kwargs) @@ -46,7 +47,7 @@ class _ClientWindow(Window, ClientQueueMixin): def cmd__privmsg(self, target: str, msg: str) -> None: 'Send chat message msg to target.' self._send_msg('PRIVMSG', (target, msg), - chat=target, to_log=f'>[MYSELF] {msg}') + stream=target, to_log=f'>[MYSELF] {msg}') class _PrivmsgPromptWidget(PromptWidget): @@ -72,8 +73,8 @@ class _PrivmsgWindow(_ClientWindow): prompt: _PrivmsgPromptWidget def cmd__chat(self, msg: str) -> None: - 'PRIVMSG to .chat.' - self.cmd__privmsg(self.chat, msg) + 'PRIVMSG to target identified by .stream.' + self.cmd__privmsg(self.stream, msg) class ClientTui(BaseTui): @@ -83,13 +84,12 @@ class ClientTui(BaseTui): super().__init__(**kwargs) self.clients_data: dict[str, dict[str, Any]] = {} - def _new_client_window(self, client_id: str, chat: str = '' - ) -> _ClientWindow: + def _new_client_window(self, client_id: str, stream: str) -> _ClientWindow: new_idx = len(self._windows) - win_class = (_PrivmsgWindow if (chat and chat[0].isalpha()) + win_class = (_PrivmsgWindow if stream[0:1] != STREAM_PREFIX_META else _ClientWindow) win = win_class(idx=new_idx, term=self._term, _q_out=self._q_out, - client_id=client_id, chat=chat) + client_id=client_id, stream=stream) if isinstance(win, _PrivmsgWindow): win.prompt.update_prefix(**{k: self.clients_data[client_id][k] for k in _PROMPT_UPDATE_TRIGGER_KEYS}) @@ -102,19 +102,20 @@ class ClientTui(BaseTui): return [win for win in self._windows if isinstance(win, _ClientWindow)] def client_wins(self, client_id: str = '') -> list[_ClientWindow]: - 'All _ClientWindows matching client_id; if none, create one.' + 'All _ClientWindows matching client_id; if none, create basics.' wins = [w for w in self._all_client_wins if client_id == w.client_id] if not wins: - wins = [self._new_client_window(client_id=client_id)] + for stream in (STREAM_SERVER, STREAM_RAW): + wins += [self._new_client_window(client_id, stream)] return wins - def client_win(self, client_id: str, chat: str = '') -> _ClientWindow: - 'That _ClientWindow matching client_id and chat; if none, create one.' + def client_win(self, client_id: str, stream: str) -> _ClientWindow: + 'That _ClientWindow matching client_id and stream; if none, create.' client_wins = self.client_wins(client_id) - candidates = [win for win in client_wins if win.chat == chat] + candidates = [win for win in client_wins if win.stream == stream] if candidates: return candidates[0] - win = self._new_client_window(client_id=client_id, chat=chat) + win = self._new_client_window(client_id=client_id, stream=stream) return win def cmd__connect(self, @@ -149,15 +150,16 @@ class ClientTui(BaseTui): @dataclass class _ClientLogEvent(TuiEvent, ClientIdMixin): - chat: str + stream: str msg: str def affect(self, target: ClientTui) -> None: - if self.chat == CHAT_GLOB: + if self.stream == STREAM_GLOB: for win in target.client_wins(self.client_id): win.log.append(self.msg) else: - target.client_win(self.client_id, self.chat).log.append(self.msg) + target.client_win(self.client_id, self.stream + ).log.append(self.msg) target.redraw_affected() @@ -182,8 +184,8 @@ class _ClientDataEvent(TuiEvent, ClientIdMixin): class _ClientKnowingTui(Client): - def _log(self, msg: str, chat: str = '') -> None: - self._cput(_ClientLogEvent, chat=chat, msg=msg) + def _log(self, msg: str, stream: str = STREAM_SERVER) -> None: + self._cput(_ClientLogEvent, stream=stream, msg=msg) def update_login(self, nick_confirmed: bool, nickname: str = '') -> None: super().update_login(nick_confirmed, nickname)