home · contact · privacy
Refactor params parsing.
authorChristian Heller <c.heller@plomlompom.de>
Tue, 19 Aug 2025 06:39:10 +0000 (08:39 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Tue, 19 Aug 2025 06:39:10 +0000 (08:39 +0200)
ircplom/client.py

index 7736ddf445a632a655523faa7156b15d4a1cbaa2..c97855ab596aaea89dbface767466520798e128c 100644 (file)
@@ -97,10 +97,22 @@ _EXPECTATIONS: tuple[_MsgParseExpectation, ...] = (
 class _IrcMsg(IrcMessage):
     'Extends IrcMessage with some conveniences.'
 
+    def source_is_server(self, compare: str) -> bool:
+        'Return if .source parse-able as our server.'
+        return '.' in self.source\
+            and compare.split('.')[-2:] == self.source.split('.')[-2:]\
+            and not ('!' in self.source or '@' in self.source)
+
     @property
-    def nick_from_source(self) -> str:
-        'Parse .source into user nickname.'
-        return self.source.split('!')[0]
+    def source_to_user_address(self) -> Optional[tuple[str, ...]]:
+        'Parse .source into toks of full user address.'
+        toks = self.source.split('!')
+        if len(toks) != 2:
+            return None
+        toks = toks[0:1] + toks[1].split('@')
+        if len(toks) != 3:
+            return None
+        return tuple(toks)
 
 
 class LogScope(Enum):
@@ -576,31 +588,24 @@ class Client(ABC, ClientQueueMixin):
 
     def _match_msg(self, msg: _IrcMsg, verb: str):
         'Test .source, .verb, .params.'
-        for expect in [x for x in _EXPECTATIONS if verb == x.verb == msg.verb]:
+        for ex in [ex for ex in _EXPECTATIONS if verb == ex.verb == msg.verb]:
             to_return: dict[str, Any] = {'params': []}
-            if expect.source is _MsgSource.NONE:
+            if ex.source is _MsgSource.NONE:
                 if msg.source != '':
                     continue
-            elif expect.source is _MsgSource.SERVER:
-                if ('!' in msg.source
-                        or '@' in msg.source
-                        or '.' not in msg.source
-                        or self._db.hostname.split('.')[-2:]
-                        != msg.source.split('.')[-2:]):
-                    continue
-            elif expect.source is _MsgSource.USER_ADDRESS:
-                toks = msg.source.split('!')
-                if len(toks) != 2:
+            elif ex.source is _MsgSource.SERVER:
+                if not msg.source_is_server(self._db.hostname):
                     continue
-                toks = toks[0:1] + toks[1].split('@')
-                if len(toks) != 3:
+            elif ex.source is _MsgSource.USER_ADDRESS:
+                if (toks := msg.source_to_user_address):
+                    to_return['nickname'] = toks[0]
+                else:
                     continue
-                to_return['nickname'] = toks[0]
-            n_len_params = len(msg.params)
-            if expect.params:
-                if n_len_params != len(expect.params):
+            len_params = len(msg.params)
+            if ex.params:
+                if len_params != len(ex.params):
                     continue
-                for idx, exp_param in enumerate(expect.params):
+                for idx, exp_param in enumerate(ex.params):
                     param = msg.params[idx]
                     if isinstance(exp_param, str) and exp_param != param:
                         continue
@@ -611,11 +616,10 @@ class Client(ABC, ClientQueueMixin):
                         to_return['channel'] = self._db.chan(param)
                     if exp_param is _MsgParam.ANY:
                         to_return['params'] += [param]
-            elif expect.len_max_params:
-                if not (expect.len_min_params <= n_len_params
-                        <= expect.len_max_params):
+            elif ex.len_max_params:
+                if not ex.len_min_params <= len_params <= ex.len_max_params:
                     continue
-            elif n_len_params != expect.len_min_params:
+            elif len_params != ex.len_min_params:
                 continue
             return to_return
         return False
@@ -707,8 +711,7 @@ class Client(ABC, ClientQueueMixin):
             self._log(msg.params[-1], out=False, target=msg.params[0], **kw)
         elif (ret := self._match_msg(msg, 'PART')):
             log_msg = f'{ret["nickname"]} {msg.verb.lower()}s {ret["ch_name"]}'
-            if len(ret['params']):
-                log_msg += f': {ret["params"][0]}'
+            log_msg += f': {ret["params"][0]}' if ret['params'] else ''
             self._log(log_msg, scope=LogScope.CHAT, target=ret['ch_name'])
             if ret['nickname'] == self._db.nickname:
                 self._db.del_chan(ret['ch_name'])