From e1a101125839ca6ccd23bea3ce545ee2534d4c28 Mon Sep 17 00:00:00 2001 From: Frank Brehm Date: Tue, 19 Mar 2024 11:33:31 +0100 Subject: [PATCH] Adding and using class DataPair --- lib/pp_admintools/postfix_chain.py | 66 ++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/lib/pp_admintools/postfix_chain.py b/lib/pp_admintools/postfix_chain.py index a066fa4..85faf76 100644 --- a/lib/pp_admintools/postfix_chain.py +++ b/lib/pp_admintools/postfix_chain.py @@ -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\d+)(?:\s*/\s*(?P\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: -- 2.39.5