From: Christian Heller Date: Sun, 27 Jul 2025 17:18:14 +0000 (+0200) Subject: Improve CAPS collection logic, display. X-Git-Url: https://plomlompom.com/repos/booking/process?a=commitdiff_plain;h=refs%2Fheads%2Fmaster;p=ircplom Improve CAPS collection logic, display. --- diff --git a/ircplom/irc_conn.py b/ircplom/irc_conn.py index b24f555..deafb54 100644 --- a/ircplom/irc_conn.py +++ b/ircplom/irc_conn.py @@ -153,8 +153,6 @@ class _ConnectedEvent(ClientEvent): def affect(self, target: 'Client') -> None: target.log(msg='# connected to server', chat=CHAT_GLOB) target.send(IrcMessage(verb='CAP', params=('LS', '302'))) - target.send(IrcMessage(verb='CAP', params=('LIST',))) - target.send(IrcMessage(verb='CAP', params=('END',))) target.send(IrcMessage(verb='USER', params=(getuser(), '0', '*', target.realname))) target.send(IrcMessage(verb='NICK', params=(target.nickname,))) @@ -203,8 +201,8 @@ class Client(ABC, ClientQueueMixin): self._hostname = hostname self._socket: Optional[socket] = None self._recv_loop: Optional[Loop] = None - self._cap_ls_done = False - self._caps: dict[str, Optional[bool]] = {} + self.cap_neg_state: set[str] = set() + self.caps: dict[str, tuple[bool, str]] = {} self.id_ = uuid4() self.assumed_open = False self.realname = realname @@ -235,26 +233,30 @@ class Client(ABC, ClientQueueMixin): Thread(target=connect, daemon=True, args=(self,)).start() def collect_caps(self, params: tuple[str, ...]) -> None: - 'Record and list available or enabled server capabilities.' - collect_enabled = params[0] != 'LS' + 'Record available and enabled server capabilities.' + verb = params[0] + items = params[-1].strip().split() is_final_line = params[1] != '*' - listed_names = params[-1].strip().split() - if collect_enabled: - for k in [k for k, v in self._caps.items() if v is None]: - self._caps[k] = False - for name in [name for name in self._caps - if name.split('=')[0] in listed_names]: - self._caps[name] = True - else: - if self._cap_ls_done: - self._caps.clear() - for cap_name in listed_names: - self._caps[cap_name] = None - self._cap_ls_done = is_final_line - if is_final_line and collect_enabled: - self.log('# server capabilities available (* if enabled): ' - + ', '.join([(f'(*){k}' if v else k) - for k, v in self._caps.items()])) + doneness = f'{verb} done' + waiting = f'{verb} wait' + if doneness in self.cap_neg_state: + if verb == 'LS': + self.caps.clear() + else: + for name in self.caps: + self.caps[name] = (False, self.caps[name][1]) + self.cap_neg_state.remove(doneness) + if waiting not in self.cap_neg_state: + self.cap_neg_state.add(waiting) + for item in items: + if verb == 'LS': + splitted = item.split('=', maxsplit=1) + self.caps[splitted[0]] = (False, ''.join(splitted[1:])) + else: + self.caps[item] = (True, self.caps[item][1]) + if is_final_line: + self.cap_neg_state.remove(waiting) + self.cap_neg_state.add(doneness) @abstractmethod def log(self, msg: str, chat: str = '') -> None: @@ -348,3 +350,14 @@ class _RecvEvent(ClientEvent, PayloadMixin): elif msg.verb == 'CAP': if msg.params[1] in {'LS', 'LIST'}: target.collect_caps(msg.params[1:]) + if ('LIST done' in target.cap_neg_state + and 'listed' not in target.cap_neg_state): + target.send(IrcMessage(verb='CAP', params=('END',))) + target.log('# available server capabilities (enabled: "+"):') + for cap_name, config in target.caps.items(): + target.log(f'# {"+" if config[0] else "-"} {cap_name}' + + (f' ({config[1]})' if config[1] else '')) + target.cap_neg_state.add('listed') + elif ('LS done' in target.cap_neg_state + and 'LIST wait' not in target.cap_neg_state): + target.send(IrcMessage(verb='CAP', params=('LIST',)))