home · contact · privacy
Simplify inner workings of ClientDb, get rid of some clearing necessities.
authorChristian Heller <c.heller@plomlompom.de>
Thu, 14 Aug 2025 09:41:41 +0000 (11:41 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Thu, 14 Aug 2025 09:41:41 +0000 (11:41 +0200)
ircplom/client.py
ircplom/client_tui.py

index 2f8d988870dd274b0195f6ba92e73f7123334a69..358b884cd507eebcdc88ac035197e5466d0e1acd 100644 (file)
@@ -79,8 +79,6 @@ class _CapsManager:
     def __init__(self, sender: Callable[[IrcMessage], None], db: 'ClientDb',
                  ) -> None:
         self._db = db
-        self._db.set('caps_LS', [])
-        self._db.set('caps_LIST', [])
         self._send = sender
         self._sent_challenges: list[str] = []
         self.sasl_wait = False
@@ -88,8 +86,6 @@ class _CapsManager:
     def clear(self) -> None:
         'Reset all negotiation knowledge to zero.'
         self._reset_negotation_steps()
-        self._db.set('caps_LS', [], confirm=False)
-        self._db.set('caps_LIST', [], confirm=False)
 
     @property
     def asdict(self) -> Optional[dict[str, _ServerCapability]]:
@@ -116,7 +112,7 @@ class _CapsManager:
         match params[0]:
             case 'NEW':
                 for param in params[-1].split():
-                    self._db.append('caps_LS', param)
+                    self._db.append('caps_LS', param, keep_confirmed=True)
             case 'DEL':
                 for param in params[-1].split():
                     del self._db.caps_LS[param]
@@ -126,8 +122,6 @@ class _CapsManager:
                         self._db.append('caps_LIST', name)
             case 'LS' | 'LIST':
                 key = f'caps_{params[0]}'
-                if getattr(self._db, key) is not None:
-                    self._db.set(key, [], confirm=False)
                 for item in params[-1].strip().split():
                     self._db.append(key, item)
                 if params[1] != '*':
@@ -177,15 +171,13 @@ class ClientDb:
 
     def __init__(self) -> None:
         self._dict: dict[str, int | str | list[str]] = {}
+        self._confirmeds: list[str] = []
 
     def __getattr__(self, key: str) -> Any:
-        if key[:1] != '_' and key in self._dict:
+        if key in self._dict and key in self._confirmeds:
             return self._dict[key]
         return None
 
-    def _unconf_key(self, key) -> str:
-        return f'_{key}'
-
     def set(self,
             key: str,
             value: Optional[int | str | list[str]],
@@ -193,42 +185,46 @@ class ClientDb:
             ) -> tuple[bool, bool]:
         'Ensures setting, returns if changed value or confirmation.'
         old_value, was_confirmed = self.get_force(key)
-        assert (old_value is not None) or (value is not None)
-        confirm_changed = confirm != was_confirmed
-        key_to_set = key if confirm else self._unconf_key(key)
-        key_to_unset = self._unconf_key(key) if confirm else key
         value_changed = (value is not None) and value != old_value
-        if value is not None:
-            self._dict[key_to_set] = value
-        if confirm_changed and old_value is not None:
-            if value is None:
-                self._dict[key_to_set] = old_value
-            del self._dict[key_to_unset]
+        if value is None:
+            if old_value is None:
+                if confirm:
+                    raise Exception
+                del self._dict[key]
+        elif value_changed:
+            self._dict[key] = value
+        confirm_changed = confirm != was_confirmed
+        if confirm_changed:
+            if confirm:
+                self._confirmeds += [key]
+            else:
+                self._confirmeds.remove(key)
         return (value_changed, confirm_changed)
 
-    def append(self, key: str, value: str) -> None:
+    def append(self, key: str, value: str, keep_confirmed=False) -> None:
         'To list[str] keyed by key, append value; if non-existant, create it.'
-        targeted = self.get_force(key)[0]
+        if not keep_confirmed and key in self._confirmeds:
+            self._confirmeds.remove(key)
+            del self._dict[key]
+        targeted = self._dict.get(key, None)
         if isinstance(targeted, list):
             targeted.append(value)
         elif targeted is None:
-            self._dict[self._unconf_key(key)] = [value]
+            self._dict[key] = [value]
         else:
             raise Exception
 
     def get_force(self, key: str) -> tuple[Optional[int | str | list[str]],
                                            bool]:
-        'Get even if only stored unconfirmed, tell if confirmed was found..'
-        conf = key in self._dict
-        find = self._dict.get(key if conf else self._unconf_key(key), None)
-        return (find, conf)
+        'Get even if only stored unconfirmed, tell if confirmed..'
+        return (self._dict.get(key, None), key in self._confirmeds)
 
     @property
     def conn_setup(self) -> IrcConnSetup:
         'Constructed out of stored entries *including* unconfirmed ones.'
         kwargs: dict[str, Any] = {}
         for field_name in IrcConnSetup._fields:
-            kwargs[field_name] = self.get_force(field_name)[0]
+            kwargs[field_name] = self._dict.get(field_name, None)
         return IrcConnSetup(**kwargs)
 
 
@@ -303,7 +299,10 @@ class Client(ABC, ClientQueueMixin):
                 self._log(to_log, scope=log_target)
         self._log(msg.raw, scope=LogScope.RAW, out=True)
 
-    def _update_db(self, key: str, value: Optional[int | str], confirm: bool
+    def _update_db(self,
+                   key: str,
+                   value: Optional[int | str | list[str]],
+                   confirm: bool
                    ) -> tuple[bool, bool]:
         'Wrap ._db.set into something accessible to subclass extension.'
         return self._db.set(key, value, confirm)
@@ -337,8 +336,6 @@ class Client(ABC, ClientQueueMixin):
             case '001' | 'NICK':
                 self._update_db('nickname', value=msg.params[0], confirm=True)
             case '005':
-                if self._db.isupports:
-                    self._db.set('isupports', [], False)
                 for param in msg.params[1:-1]:
                     self._db.append('isupports', param)
             case '375':
index b21fc671dfc3ee56f9290b0af713b1a1e050bb04..aa3b2d81dcb42e8dd7a8a4d590700b2059e052f7 100644 (file)
@@ -290,10 +290,14 @@ class _ClientKnowingTui(Client):
                 with open(f'{self.client_id}.log', 'a', encoding='utf8') as f:
                     f.write(('>' if kwargs['out'] else '<') + f' {msg}\n')
 
-    def _update_db(self, key: str, value: Optional[int | str], confirm: bool
-                   ) -> None:
-        value_changed, _ = super()._update_db(key, value, confirm)
+    def _update_db(self,
+                   key: str,
+                   value: Optional[int | str | list[str]],
+                   confirm: bool
+                   ) -> tuple[bool, bool]:
+        value_changed, conf_changed = super()._update_db(key, value, confirm)
         if value is None and not value_changed:  # local ._db may have fallback
             value = self._db.get_force(key)[0]   # values Tui._db doesn't
         self._client_tui_trigger('update', scope=LogScope.SERVER,
                                  key=key, value=value, confirmed=confirm)
+        return (value_changed, conf_changed)