def __init__(self, sender: Callable[[IrcMessage], None]) -> None:
self._send = sender
self._challenges: dict[str, bool] = {}
- self._dict: dict[str, _ServerCapability] = {}
+ self.dict: dict[str, _ServerCapability] = {}
self.sasl_wait = False
def clear(self) -> None:
'Reset all negotiation knowledge to zero.'
self.sasl_wait = False
self._challenges.clear()
- self._dict.clear()
+ self.dict.clear()
- def process_msg(self, params: tuple[str, ...]) -> list[str]:
- 'Parse CAP params to negot. steps, DB inputs; once done return latter.'
+ def process_msg(self, params: tuple[str, ...]) -> bool | str:
+ 'Parse CAP params to negot. steps, DB inputs; return error or success.'
if params[0] in {'NEW', 'DEL'}: # don't bother fiddling, just re-do
self.clear()
self.challenge('LS', '302')
- return []
+ return False
if self._challenged('END') or self.sasl_wait:
- return [f'ignoring post-END CAP message not NEW, DEL: {params}']
+ return f'ignoring post-END CAP message not NEW, DEL: {params}'
match params[0]:
case 'LS' | 'LIST':
self._collect_caps(params)
case 'ACK' | 'NAK':
for cap_name in params[-1].split():
self._challenge_set(f'REQ:{cap_name}', done=True)
- self._dict[cap_name].enabled = params[0] == 'ACK'
+ self.dict[cap_name].enabled = params[0] == 'ACK'
if self._challenge_met('LIST'):
self.sasl_wait = (
- 'sasl' in self._dict
- and 'PLAIN' in self._dict['sasl'].data.split(','))
+ 'sasl' in self.dict
+ and 'PLAIN' in self.dict['sasl'].data.split(','))
if not self.sasl_wait:
self.challenge('END')
- return (['server capabilities (enabled: "+"):']
- + [cap.str_for_log(cap_name)
- for cap_name, cap in self._dict.items()])
+ return True
if self._challenge_met('LS'):
for cap_name in _NAMES_DESIRED_SERVER_CAPS:
- if (cap_name in self._dict
- and (not self._dict[cap_name].enabled)):
+ if (cap_name in self.dict
+ and (not self.dict[cap_name].enabled)):
self.challenge('REQ', cap_name, key_fused=True)
self.challenge('LIST')
- return []
+ return False
def challenge(self, *params, key_fused: bool = False) -> None:
'Run CAP command with params, handle cap neg. state.'
is_final_line = params[1] != '*'
if self._challenge_met(verb):
if verb == 'LS':
- self._dict.clear()
+ self.dict.clear()
else:
- for cap in self._dict.values():
+ for cap in self.dict.values():
cap.enabled = False
self._challenge_set(verb)
for item in items:
if verb == 'LS':
splitted = item.split('=', maxsplit=1)
- self._dict[splitted[0]] = _ServerCapability(
+ self.dict[splitted[0]] = _ServerCapability(
enabled=False, data=''.join(splitted[1:]))
else:
- self._dict[item].enabled = True
+ self.dict[item].enabled = True
if is_final_line:
self._challenge_set(verb, done=True)
stream=nickname,
prefix=_LOG_PREFIX_PRIVMSG)
case 'CAP':
- for to_log in self._caps.process_msg(msg.params[1:]):
- self._log.add(to_log)
+ if (result := self._caps.process_msg(msg.params[1:])):
+ if isinstance(result, str):
+ self._log.add(result)
+ else:
+ for line in (['server capabilities (enabled: "+"):']
+ + [cap.str_for_log(c_name) for c_name, cap
+ in self._caps.dict.items()]):
+ self._log.add(line)
if self._caps.sasl_wait:
if self.conn_setup.password:
self.send(IrcMessage('AUTHENTICATE', ('PLAIN',)))