]> Frank Brehm's Git Trees - pixelpark/pp-admin-tools.git/commitdiff
Adding and using class DataPair
authorFrank Brehm <frank.brehm@pixelpark.com>
Tue, 19 Mar 2024 10:33:31 +0000 (11:33 +0100)
committerFrank Brehm <frank.brehm@pixelpark.com>
Tue, 19 Mar 2024 10:33:31 +0000 (11:33 +0100)
lib/pp_admintools/postfix_chain.py

index a066fa44adeb3e3a75f5ce568b9644188ccde2c2..85faf7600eee9e2a9ba8c52a66f7485e4266099f 100644 (file)
@@ -23,13 +23,70 @@ from .xlate import XLATOR
 _ = XLATOR.gettext
 ngettext = XLATOR.ngettext
 
-__version__ = '0.1.0'
+__version__ = '0.2.0'
 
 LOG = logging.getLogger(__name__)
 
 UTC = utc = datetime.timezone(datetime.timedelta(), 'UTC')
 
 
+# =============================================================================
+class DataPair(object):
+    """Encapsulates a pair of to integer values in the form of 'value of total'."""
+
+    re_data = re.compile(r'^\s*(?P<val>\d+)(?:\s*/\s*(?P<total>\d+))?\s*$')
+
+    # -------------------------------------------------------------------------
+    def __init__(self, value, total=None):
+        """Initialize this object."""
+        self.value = int(value)
+        if self.value < 0:
+            msg = _(
+                'The first value {v!r} of {c} must be greater than or equal to null.').format(
+                v=value, c=self.__class__.__name__)
+            raise ValueError(msg)
+
+        self.total = None
+        if total is not None:
+            self.total = int(total)
+            if self.total < self.value:
+                msg = _(
+                    'The total value {t!r} must be greater than or equal to the '
+                    'value {v}.').format(t=total, v=self.value)
+                raise ValueError(msg)
+
+    # -------------------------------------------------------------------------
+    @classmethod
+    def from_str(cls, value):
+        """Convert a string of format '2' or '0/2' into a DataPair object."""
+        m = cls.re_data.match(value)
+        if not m:
+            msg = _('Invalid value {v!r} of a {c}.').format(v=value, c=__class__.__name__)
+            raise ValueError(msg)
+        pair = cls(value=m['val'], total=m['total'])
+        return pair
+
+    # -------------------------------------------------------------------------
+    def __str__(self):
+        """Typecast into a string object."""
+        if self.total is None:
+            return str(self.value)
+        return '{}/{}'.format(self.value, self.total)
+
+    # -------------------------------------------------------------------------
+    def __repr__(self):
+        """Typecast into a string for reproduction."""
+        out = '<%s(' % (self.__class__.__name__)
+
+        fields = []
+        fields.append('value={!r}'.format(self.value))
+        if self.total is not None:
+            fields.append('total={!r}'.format(self.total))
+
+        out += ', '.join(fields) + ')>'
+        return out
+
+
 # =============================================================================
 class PostfixLogchainInfo(FbGenericBaseObject):
     """A class for encapsulating the information from a chain of Postfix log entries."""
@@ -83,11 +140,14 @@ class PostfixLogchainInfo(FbGenericBaseObject):
             self._auth = None
             return
 
+        if isinstance(value, int):
+            return DataPair(value)
         val = str(value).strip()
         if val == '':
             self._auth = None
+            return
         else:
-            self._auth = val
+            self._auth = DataPair.from_str(val)
 
     # -----------------------------------------------------------
     @property
@@ -142,7 +202,7 @@ class PostfixLogchainInfo(FbGenericBaseObject):
         fields = []
 
         if self.auth is not None:
-            fields.append('auth={!r}'.format(self.auth))
+            fields.append('auth={!r}'.format(str(self.auth)))
         if self.client_addr is not None:
             fields.append('client_addr={!r}'.format(str(self.client_addr)))
         if self.client_host is not None: