From: Christian Heller Date: Fri, 21 Nov 2025 22:27:24 +0000 (+0100) Subject: Record prefix memberships in Channel.prefixes dictionary. X-Git-Url: https://plomlompom.com/repos/%7B%7Bprefix%7D%7D/%7B%7Bdb.prefix%7D%7D/calendar?a=commitdiff_plain;h=2ec9ef87565e0ce44f2822d2e6e5160982bc57cc;p=ircplom Record prefix memberships in Channel.prefixes dictionary. --- diff --git a/src/ircplom/client.py b/src/ircplom/client.py index 23accb6..514e410 100644 --- a/src/ircplom/client.py +++ b/src/ircplom/client.py @@ -123,6 +123,7 @@ class Channel: 'Collects .topic, and in .user_ids inhabitant IDs.' topic: Topic user_ids: Iterable[str] + prefixes: Dict[tuple[str, ...]] exits: Dict[str] @@ -187,10 +188,17 @@ class _Channel(Channel): def add_from_namreply(self, items: tuple[str, ...]) -> None: 'Add to .user_ids items assumed as nicknames with membership prefixes.' + prefixes = self._get_membership_prefixes() for item in items: - n_u_h = NickUserHost(item.lstrip(self._get_membership_prefixes())) + prefix = ''.join([pfx for pfx in prefixes if item.startswith(pfx)]) + n_u_h = NickUserHost(item.lstrip(prefix)) user_id = self._userid_for_nickuserhost(n_u_h, create_if_none=True) self.user_ids.completable_add(user_id, on_complete=False) + if prefix: + if prefix in self.prefixes.keys(): + self.prefixes[prefix] += (user_id,) + else: + self.prefixes[prefix] = (user_id,) def add_user(self, user: '_User') -> None: 'To .user_ids add user.nickname, keep .user_ids declared complete.' @@ -200,6 +208,9 @@ class _Channel(Channel): def remove_user(self, user: '_User', msg: str) -> None: 'From .user_ids remove .nickname, keep .user_ids declared complete.' + for prefix in self.prefixes.keys(): + self.prefixes[prefix] = tuple(id_ for id_ in self.prefixes[prefix] + if id_ != user.id_) self.exits[user.id_] = msg self.user_ids.completable_remove(user.id_, on_complete=True) del self.exits[user.id_] @@ -332,6 +343,7 @@ class _UpdatingChannel(UpdatingAttrsMixin, _Channel): user_ids: UpdatingCompletableStringsSet topic: _UpdatingCompletableTopic exits: UpdatingDict[str] + prefixes: UpdatingDict[tuple[str, ...]] class _UpdatingUser(UpdatingAttrsMixin, _User): diff --git a/src/ircplom/client_tui.py b/src/ircplom/client_tui.py index 14e7d94..63e0779 100644 --- a/src/ircplom/client_tui.py +++ b/src/ircplom/client_tui.py @@ -284,6 +284,7 @@ class _UpdatingDict(Dict[DictItem], _UpdatingNode): class _UpdatingChannel(_UpdatingNode, Channel): user_ids: set[str] exits: _UpdatingDict[str] + prefixes: _UpdatingDict[tuple[str, ...]] def recursive_set_and_report_change(self, update: _Update) -> None: super().recursive_set_and_report_change(update) diff --git a/src/ircplom/db_primitives.py b/src/ircplom/db_primitives.py index 76d2c85..38b1939 100644 --- a/src/ircplom/db_primitives.py +++ b/src/ircplom/db_primitives.py @@ -60,7 +60,6 @@ class Dict(Clearable, Generic[DictItem]): # for Clearable.clear. def __setitem__(self, key: str, val: DictItem) -> None: - assert isinstance(val, self._item_cls), (type(val), self._item_cls) self._dict[key] = val def __getitem__(self, key: str) -> DictItem: diff --git a/src/tests/channels.test b/src/tests/channels.test index 31838a8..657188f 100644 --- a/src/tests/channels.test +++ b/src/tests/channels.test @@ -40,9 +40,17 @@ insert join-empty : + CHAN_WIN_ID=3 CHANNEL :#ch_test0 > /join TARGET log LOG_WIN_ID $ already in that channel -× part-other -insert servermsglogged : + MSG ::NICK!~NICK@NICK.NICK PART :#ch_test0 -insert parts-core : + exitMSG= exitPREFIX= USERIDS_CLEAR=set§to:§REMAINING_IDS CHANNEL=#ch_test0 CHAN_WIN_ID=3 § : +× part-other-0 +insert servermsglogged : + MSG ::NICK!~NICK@NICK.NICK PART ARGS + +× part-other-0-no-msg +insert part-other-0 : + ARGS ::#ch_test0 + +× part-other-1 +insert parts-core : + USERIDS_CLEAR=set§to:§REMAINING_IDS CHANNEL=#ch_test0 CHAN_WIN_ID=3 § : + +× part-other-1-no-msg +insert part-other-1 : + exitMSG= exitPREFIX : × ×-------------------------- @@ -106,11 +114,14 @@ insert part : + CHANNEL=#ch_test0 CHAN_WIN_ID=3 USERIDS_CLEAR :set to: [1] log 1 $ users:1 deleted # check /join into channel with many other users, with multi-line 353 -insert join-channel-0 : + CHANNEL=#ch_test0 RESIDENT_NAMES :foo baz oof +insert join-channel-0 : + CHANNEL=#ch_test0 RESIDENT_NAMES :foo @baz +oof insert user-set-to :1 + USER_ID=2 USERNICK :baz +log 1 $ channels:#ch_test0:prefixes:@ set to: [2] insert user-set-to :1 + USER_ID=3 USERNICK :oof -insert servermsglogged : + MSG ::foo.bar.baz 353 foo = #ch_test0 :rab zab +log 1 $ channels:#ch_test0:prefixes:+ set to: [3] +insert servermsglogged : + MSG ::foo.bar.baz 353 foo = #ch_test0 :+rab zab insert user-set-to :1 + USER_ID=4 USERNICK :rab +log 1 $ channels:#ch_test0:prefixes:+ set to: [3], [4] insert user-set-to :1 + USER_ID=5 USERNICK :zab insert join-channel-1 : + CHANNEL=#ch_test0 RESIDENT_IDS :[2], [3], [4], [5], [me] log 3 $ residents: baz, oof, rab, zab, foo @@ -148,14 +159,18 @@ insert servermsglogged : + MSG ::*.?.net NOTICE #ch_test0 :msg_test6 msg_test7 log 3 < (*.?.net) msg_test6 msg_test7 # check part of user visible, and of user NOT visible in other channel -insert part-other : + NICK=baz USER_ID=2 REMAINING_IDS :[3], [4], [5], [me] -insert part-other : + NICK=oof USER_ID=3 REMAINING_IDS :[4], [5], [me] +insert part-other-0-no-msg : + NICK :baz +log 1 $ channels:#ch_test0:prefixes:@ emptied +insert part-other-1-no-msg : + USER_ID=2 NICK=baz REMAINING_IDS :[3], [4], [5], [me] +insert part-other-0-no-msg : + NICK :oof +log 1 $ channels:#ch_test0:prefixes:+ set to: [4] +insert part-other-1-no-msg : + USER_ID=3 NICK=oof REMAINING_IDS :[4], [5], [me] log 1 $ users:3 deleted # check other-user part with exit message -insert servermsglogged : + MSG ::zab!~zab@zab.zab PART #ch_test0 :goodbye +insert part-other-0 : + NICK=zab ARGS :#ch_test0 :goodbye insert user-set-to 1: + USER_ID=5 USERNAME=~zab USERHOST :zab.zab -insert parts-core : + CHAN_WIN_ID=3 CHANNEL=#ch_test0 USER_ID=5 NICK=zab exitPREFIX=:§ exitMSG=goodbye USERIDS_CLEAR=set§to:§[4],§[me] § : +insert part-other-1 : + USER_ID=5 NICK=zab exitPREFIX=:§ exitMSG=goodbye REMAINING_IDS=[4],§[me] § : log 1 $ users:5 deleted # check re-join of user kept visible in other channel diff --git a/src/tests/isupports.test b/src/tests/isupports.test index 8b9bd1b..69e0546 100644 --- a/src/tests/isupports.test +++ b/src/tests/isupports.test @@ -84,14 +84,18 @@ insert join-empty : + CHAN_WIN_ID=6 CHANNEL :#ch_test5 # test effect of PREFIX insert join-channel-0 : +0 CHANNEL=#ch_test6 RESIDENT_NAMES :foo @bar +baz =quux insert user-set-to :1 +1 USER_ID=1 USERNICK :bar +log 1 $ channels:#ch_test6:prefixes:@ set to: [1] insert user-set-to :1 +1 USER_ID=2 USERNICK :baz +log 1 $ channels:#ch_test6:prefixes:+ set to: [2] insert user-set-to :1 +1 USER_ID=3 USERNICK :=quux insert join-channel-1 : +0 CHANNEL=#ch_test6 RESIDENT_IDS :[1], [2], [3], [me] log 7 $ residents: bar, baz, =quux, foo insert un-default : +0 KEY=PREFIX VALUE :(vE)+= insert join-channel-0 : +0 CHANNEL=#ch_test7 RESIDENT_NAMES :foo @bar +baz =quux insert user-set-to :1 +1 USER_ID=4 USERNICK :@bar +log 1 $ channels:#ch_test7:prefixes:+ set to: [2] insert user-set-to :1 +1 USER_ID=5 USERNICK :quux +log 1 $ channels:#ch_test7:prefixes:= set to: [5] insert join-channel-1 : +0 CHANNEL=#ch_test7 RESIDENT_IDS :[2], [4], [5], [me] log 8 $ residents: baz, @bar, quux, foo diff --git a/src/tests/lib/part b/src/tests/lib/part index fc214d8..e6b5e92 100644 --- a/src/tests/lib/part +++ b/src/tests/lib/part @@ -9,7 +9,6 @@ log 1 $ channels:CHANNEL:exits:USER_ID deleted × parts-core insert exit-channel : + exitTYPE=P exitDESC :parts -× part-1 × part > /part log 1 > PART :CHANNEL diff --git a/src/tests/test.test b/src/tests/test.test index 3e776eb..6400cc2 100644 --- a/src/tests/test.test +++ b/src/tests/test.test @@ -113,6 +113,7 @@ log rename_win_ids $ foo1!~baz@baz.bar.foo renames foo # join channel with other user insert join-channel-0 : +0 CHANNEL=#test RESIDENT_NAMES :foo @baz insert user-set-to :1 +1 USER_ID=1 USERNICK :baz +log 1 $ channels:#test:prefixes:@ set to: [1] insert join-channel-1 : +0 CHANNEL=#test RESIDENT_IDS :[1], [me] log 4 $ residents: baz, foo