From b334c272ceb51ffb1585ce050ab7bd03ea091798 Mon Sep 17 00:00:00 2001 From: Frank Brehm Date: Tue, 19 Mar 2024 12:02:17 +0100 Subject: [PATCH] Defining start, and and duration of the PostfixLogchainInfo. --- lib/pp_admintools/postfix_chain.py | 119 ++++++++++++++++++++++++++++- 1 file changed, 118 insertions(+), 1 deletion(-) diff --git a/lib/pp_admintools/postfix_chain.py b/lib/pp_admintools/postfix_chain.py index 85faf76..ed55f42 100644 --- a/lib/pp_admintools/postfix_chain.py +++ b/lib/pp_admintools/postfix_chain.py @@ -15,6 +15,7 @@ import logging import re # Third party modules +# from fb_tools.common import pp from fb_tools.obj import FbGenericBaseObject # Own modules @@ -23,7 +24,7 @@ from .xlate import XLATOR _ = XLATOR.gettext ngettext = XLATOR.ngettext -__version__ = '0.2.0' +__version__ = '0.3.0' LOG = logging.getLogger(__name__) @@ -127,6 +128,43 @@ class PostfixLogchainInfo(FbGenericBaseObject): self.auth = auth self.client_addr = client_addr self.client_host = client_host + self.end = end + self.start = start + + # ------------------------------------------------------------------------- + @classmethod + def date_fromisoformat(cls, datestr): + """Try to convert a string with an ISO-fromatted timestamp into a datetime object.""" + m = cls.re_isodatetime.search(datestr) + if not m: + return None + + params = { + 'year': int(m['year']), + 'month': int(m['month']), + 'day': int(m['day']), + 'minute': int(m['min']), + } + if m['sec'] is not None: + params['second'] = int(m['sec']) + + if m['nsec'] is not None: + params['microsecond'] = int(round(float('0.' + m['nsec']) * 1000000)) + + if m['utc']: + params['tzinfo'] = UTC + elif m['tz_hours'] is not None: + prefix = m['tz_hours'][0] + offset = 0 + if m['tz_mins'] is not None: + offset = int(m['tz_mins']) * 60 + offset += int(m['tz_hours'][1:]) * 3600 + if prefix == '-': + offset *= -1 + + params['tzinfo'] = datetime.timezone(datetime.timedelta(seconds=offset)) + + return datetime.datetime(**params) # ----------------------------------------------------------- @property @@ -194,6 +232,70 @@ class PostfixLogchainInfo(FbGenericBaseObject): return self._client_host = val + # ----------------------------------------------------------- + @property + def duration(self): + """Return the timediff between start and end of the SMRP transaction.""" + if not isinstance(self.start, datetime.datetime): + return None + if not isinstance(self.end, datetime.datetime): + return None + return self.end - self.start + + # ----------------------------------------------------------- + @property + def end(self): + """Return the timestamp of the end of the SMTP dialogue.""" + return self._end + + @end.setter + def end(self, value): + if value is None: + self._end = None + return + + if isinstance(value, datetime.datetime): + self._end = value + return + + val = str(value).strip() + if val == '': + self._end = None + return + + ts_end = self.date_fromisoformat(val) + if ts_end: + self._end = ts_end + return + self._end = val + + # ----------------------------------------------------------- + @property + def start(self): + """Return the timestamp of the starting of the SMTP dialogue.""" + return self._start + + @start.setter + def start(self, value): + if value is None: + self._start = None + return + + if isinstance(value, datetime.datetime): + self._start = value + return + + val = str(value).strip() + if val == '': + self._start = None + return + + ts_start = self.date_fromisoformat(val) + if ts_start: + self._start = ts_start + return + self._start = val + # ------------------------------------------------------------------------- def __repr__(self): """Typecast into a string for reproduction.""" @@ -207,6 +309,18 @@ class PostfixLogchainInfo(FbGenericBaseObject): fields.append('client_addr={!r}'.format(str(self.client_addr))) if self.client_host is not None: fields.append('client_host={!r}'.format(str(self.client_host))) + if self.end is not None: + if isinstance(self.end, datetime.datetime): + ts = self.end.isoformat(' ') + else: + ts = self.end + fields.append('end={!r}'.format(ts)) + if self.start is not None: + if isinstance(self.start, datetime.datetime): + ts = self.start.isoformat(' ') + else: + ts = self.start + fields.append('start={!r}'.format(ts)) if fields: out += ', '.join(fields) @@ -230,6 +344,9 @@ class PostfixLogchainInfo(FbGenericBaseObject): res['auth'] = self.auth res['client_addr'] = self.client_addr res['client_host'] = self.client_host + res['duration'] = self.duration + res['end'] = self.end + res['start'] = self.start return res -- 2.39.5