From 4e516fdea6a9429dec854710bb81de42d7fc31b0 Mon Sep 17 00:00:00 2001 From: Christian Heller Date: Thu, 4 Sep 2025 07:41:31 +0200 Subject: [PATCH] For any NICK_USER_HOST message tokens potentially update entry; get rid of irregular "set_user" tasks. --- ircplom/client.py | 22 ++++++++++++---------- ircplom/msg_parse_expectations.py | 31 ++++++++++++++++++------------- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/ircplom/client.py b/ircplom/client.py index db59a89..e26dd0a 100644 --- a/ircplom/client.py +++ b/ircplom/client.py @@ -519,11 +519,14 @@ class _ClientDb(_UpdatingMixin, SharedClientDbFields): def userid_for_nickuserhost(self, nickuserhost: _NickUserHost, - create_if_none=False) -> str: + create_if_none=False, + allow_none=False + ) -> Optional[str]: 'Return user_id for nickuserhost.nick, create if none, maybe update.' matches = [id_ for id_ in self.users.keys() if self.users[id_].nick == nickuserhost.nick] - assert len(matches) in ({0, 1} if create_if_none else {1}) + assert len(matches) in ({0, 1} if (create_if_none or allow_none) + else {1}) if len(matches) == 1: id_ = matches[0] if '?' in {nickuserhost.user, nickuserhost.host}: @@ -531,7 +534,7 @@ class _ClientDb(_UpdatingMixin, SharedClientDbFields): return id_ stored = self.users[id_] if '?' in {stored.user, stored.host}: - assert stored.user == stored.host + assert stored.host in {stored.user, '?'} self.users.set_updating(id_, nickuserhost) else: assert nickuserhost.host == stored.host @@ -539,9 +542,11 @@ class _ClientDb(_UpdatingMixin, SharedClientDbFields): self.users.set_updating(id_, nickuserhost) else: assert nickuserhost.user == stored.user - else: + elif create_if_none: id_ = str(uuid4()) self.users.set_updating(id_, nickuserhost) + else: + return None return id_ @@ -708,12 +713,8 @@ class Client(ABC, ClientQueueMixin): if '_verb' not in ret: self._log(f'PLEASE IMPLEMENT HANDLER FOR: {msg.raw}') return - for task, tok_names in [t for t in ret['_tasks'].items() - if t[0].verb == 'set']: - assert task.path == ('user',) - assert tok_names in (['sender'], ['joiner']) - self.db.userid_for_nickuserhost(ret[tok_names[0]], - create_if_none=True) + for nickuserhost in ret['_nickuserhosts']: + self.db.userid_for_nickuserhost(nickuserhost, allow_none=True) for verb in ('setattr', 'do', 'doafter'): for task, tok_names in [t for t in ret['_tasks'].items() if t[0].verb == verb]: @@ -772,6 +773,7 @@ class Client(ABC, ClientQueueMixin): self.db.channels[ret['channel']].append_nick(ret['joiner']) elif ret['_verb'] == 'NICK': user_id = self.db.userid_for_nickuserhost(ret['named']) + assert user_id is not None self.db.users[user_id].nick = ret['nick'] if user_id == 'me': self.db.nick_wanted = ret['nick'] diff --git a/ircplom/msg_parse_expectations.py b/ircplom/msg_parse_expectations.py index 9983902..4d372b6 100644 --- a/ircplom/msg_parse_expectations.py +++ b/ircplom/msg_parse_expectations.py @@ -101,19 +101,23 @@ class _MsgParseExpectation: } parsed: dict[str, str | tuple[str, ...]] = {} singled_tasks: list[tuple[_Command, str]] = [] + nickuserhosts = [] for ex_tok, cmp_tok in [(ex_tok, cmp_fields[idx]) for idx, ex_tok in enumerate(ex_fields)]: if (not isinstance(ex_tok.type_, str))\ and ex_tok.type_ in validators\ and (not validators[ex_tok.type_](cmp_tok)): return None - if ex_tok.code: - parsed[ex_tok.code.title] = ( - cmp_tok if (isinstance(ex_tok.type_, str) - or ex_tok.type_ not in parsers) - else parsers[ex_tok.type_](cmp_tok)) - singled_tasks += [(cmd, ex_tok.code.title) - for cmd in ex_tok.code.commands] + if ex_tok.code or ex_tok.type_ is _MsgTok.NICK_USER_HOST: + value = (cmp_tok if (isinstance(ex_tok.type_, str) + or ex_tok.type_ not in parsers) + else parsers[ex_tok.type_](cmp_tok)) + if ex_tok.type_ is _MsgTok.NICK_USER_HOST: + nickuserhosts += [value] + if ex_tok.code: + parsed[ex_tok.code.title] = value + singled_tasks += [(cmd, ex_tok.code.title) + for cmd in ex_tok.code.commands] for code in self.bonus_tasks: singled_tasks += [(cmd, code.title) for cmd in code.commands] tasks: dict[_Command, list[str]] = {} @@ -121,7 +125,8 @@ class _MsgParseExpectation: if cmd not in tasks: tasks[cmd] = [] tasks[cmd] += [title] - return parsed | {'_verb': self.verb, '_tasks': tasks} + return parsed | {'_verb': self.verb, '_tasks': tasks, + '_nickuserhosts': nickuserhosts} MSG_EXPECTATIONS: list[_MsgParseExpectation] = [ @@ -458,7 +463,7 @@ MSG_EXPECTATIONS: list[_MsgParseExpectation] = [ _MsgParseExpectation( 'JOIN', - (_MsgTok.NICK_USER_HOST, 'set_user:joiner'), + (_MsgTok.NICK_USER_HOST, ':joiner'), ((_MsgTok.CHANNEL, ':channel'),)), _MsgParseExpectation( @@ -492,23 +497,23 @@ MSG_EXPECTATIONS: list[_MsgParseExpectation] = [ (_MsgTok.ANY, ':message'))), _MsgParseExpectation( 'NOTICE', - (_MsgTok.NICK_USER_HOST, 'set_user:sender'), + (_MsgTok.NICK_USER_HOST, ':sender'), ((_MsgTok.NICKNAME, 'setattr_db.users.me:nick'), (_MsgTok.ANY, ':message'))), _MsgParseExpectation( 'NOTICE', - (_MsgTok.NICK_USER_HOST, 'set_user:sender'), + (_MsgTok.NICK_USER_HOST, ':sender'), ((_MsgTok.CHANNEL, ':channel'), (_MsgTok.ANY, ':message'))), _MsgParseExpectation( 'PRIVMSG', - (_MsgTok.NICK_USER_HOST, 'set_user:sender'), + (_MsgTok.NICK_USER_HOST, ':sender'), ((_MsgTok.NICKNAME, 'setattr_db.users.me:nick'), (_MsgTok.ANY, ':message'))), _MsgParseExpectation( 'PRIVMSG', - (_MsgTok.NICK_USER_HOST, 'set_user:sender'), + (_MsgTok.NICK_USER_HOST, ':sender'), ((_MsgTok.CHANNEL, ':channel'), (_MsgTok.ANY, ':message'))), -- 2.30.2