self._hostname = hostname
self._socket: Optional[socket] = None
self._recv_loop: Optional[Loop] = None
- self._caps: dict[str, set[str]] = {
- 'available': set(), 'enabled': set(), 'finished': set()}
+ self._cap_ls_done = False
+ self._caps: dict[str, Optional[bool]] = {}
self.id_ = uuid4()
self.assumed_open = False
self.realname = realname
Thread(target=connect, daemon=True, args=(self,)).start()
- def set_caps(self, caps: set[str], final_line: bool, enabled: bool
- ) -> None:
- 'Record available or enabled server capabilities.'
- category = 'enabled' if enabled else 'available'
- if category in self._caps['finished']:
- self._caps[category].clear()
- self._caps['finished'].remove(category)
- self._caps[category] |= caps
- if final_line:
- self._caps['finished'].add(category)
- self.log(f'# server caps {category}: {self._caps[category]}')
+ def collect_caps(self, params: tuple[str, ...]) -> None:
+ 'Record and list available or enabled server capabilities.'
+ collect_enabled = params[0] != 'LS'
+ 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()]))
@abstractmethod
def log(self, msg: str, chat: str = '') -> None:
elif msg.verb == 'PRIVMSG':
target.log(msg=str(msg.params), chat=msg.source)
elif msg.verb == 'CAP':
- subverb = msg.params[1]
- if subverb in {'LS', 'LIST'}:
- target.set_caps(final_line=msg.params[2] != '*',
- enabled=subverb == 'LIST',
- caps=set(msg.params[-1].strip().split()))
+ if msg.params[1] in {'LS', 'LIST'}:
+ target.collect_caps(msg.params[1:])