]> Frank Brehm's Git Trees - pixelpark/pp-admin-tools.git/commitdiff
Defining start, and and duration of the PostfixLogchainInfo.
authorFrank Brehm <frank.brehm@pixelpark.com>
Tue, 19 Mar 2024 11:02:17 +0000 (12:02 +0100)
committerFrank Brehm <frank.brehm@pixelpark.com>
Tue, 19 Mar 2024 11:02:17 +0000 (12:02 +0100)
lib/pp_admintools/postfix_chain.py

index 85faf7600eee9e2a9ba8c52a66f7485e4266099f..ed55f429a1b4cacb4c687167cb1a52ab9e15b980 100644 (file)
@@ -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