From 7a3732905e8dbf2be959257097d606e1048dbb33 Mon Sep 17 00:00:00 2001 From: Frank Brehm Date: Tue, 19 Mar 2024 12:39:56 +0100 Subject: [PATCH] Extending class PostfixLogchainInfo --- lib/pp_admintools/postfix_chain.py | 181 ++++++++++++++++++++++++++--- test/test_20_postfix_chain.py | 3 +- 2 files changed, 166 insertions(+), 18 deletions(-) diff --git a/lib/pp_admintools/postfix_chain.py b/lib/pp_admintools/postfix_chain.py index ed55f42..711b9de 100644 --- a/lib/pp_admintools/postfix_chain.py +++ b/lib/pp_admintools/postfix_chain.py @@ -9,6 +9,7 @@ from __future__ import absolute_import # Standard modules +import copy import datetime import ipaddress import logging @@ -24,7 +25,7 @@ from .xlate import XLATOR _ = XLATOR.gettext ngettext = XLATOR.ngettext -__version__ = '0.3.0' +__version__ = '0.4.0' LOG = logging.getLogger(__name__) @@ -87,6 +88,10 @@ class DataPair(object): out += ', '.join(fields) + ')>' return out + # ------------------------------------------------------------------------- + def __copy__(self): + """Copy the current data pair into a new object.""" + return self.__class__(self.value, total=self.total) # ============================================================================= class PostfixLogchainInfo(FbGenericBaseObject): @@ -105,8 +110,8 @@ class PostfixLogchainInfo(FbGenericBaseObject): # ------------------------------------------------------------------------- def __init__( self, client_host=None, client_addr=None, start=None, end=None, message_id=None, - postfix_pid=None, ehlo=None, starttls=None, sent_quit=None, auth=None, commands=None, - rcpt=None, data=None, mail=None, from_address=None, to_address=None): + postfix_id=None, ehlo=None, starttls=None, sent_quit=None, auth=None, commands=None, + rcpt=None, data=None, mail=None, from_address=None, to_address=None, smtpd_pid=None): """Initialize this object.""" self._auth = None self._client_addr = None @@ -118,9 +123,10 @@ class PostfixLogchainInfo(FbGenericBaseObject): self._from_address = None self._mail = None self._message_id = None - self._postfix_pid = None + self._postfix_id = None self._rcpt = None self._sent_quit = None + self._smtpd_pid = None self._start = None self._starttls = None self._to_address = None @@ -128,8 +134,13 @@ class PostfixLogchainInfo(FbGenericBaseObject): self.auth = auth self.client_addr = client_addr self.client_host = client_host + self.ehlo = ehlo self.end = end + self.message_id = message_id + self.postfix_id = postfix_id + self.sent_quit = sent_quit self.start = start + self.starttls = starttls # ------------------------------------------------------------------------- @classmethod @@ -179,7 +190,11 @@ class PostfixLogchainInfo(FbGenericBaseObject): return if isinstance(value, int): - return DataPair(value) + self._auth = DataPair(value) + return + if isinstance(value, DataPair): + self._auth = copy.copy(value) + return val = str(value).strip() if val == '': self._auth = None @@ -242,6 +257,31 @@ class PostfixLogchainInfo(FbGenericBaseObject): return None return self.end - self.start + # ----------------------------------------------------------- + @property + def ehlo(self): + """Return statistics about the EHLO command in SMTP dialogue.""" + return self._ehlo + + @ehlo.setter + def ehlo(self, value): + if value is None: + self._ehlo = None + return + + if isinstance(value, int): + self._ehlo = DataPair(value) + return + if isinstance(value, DataPair): + self._ehlo = copy.copy(value) + return + val = str(value).strip() + if val == '': + self._ehlo = None + return + else: + self._ehlo = DataPair.from_str(val) + # ----------------------------------------------------------- @property def end(self): @@ -263,12 +303,76 @@ class PostfixLogchainInfo(FbGenericBaseObject): self._end = None return - ts_end = self.date_fromisoformat(val) + if hasattr(datetime.datetime, 'fromisoformat'): + ts_end = datetime.datetime.fromisoformat(val) + else: + ts_end = self.date_fromisoformat(val) if ts_end: self._end = ts_end return self._end = val + # ----------------------------------------------------------- + @property + def message_id(self): + """Return the message ID of the mail, which the Pastfix chain is covering.""" + return self._message_id + + @message_id.setter + def message_id(self, value): + if value is None: + self._message_id = None + return + + val = str(value).strip() + if val == '': + self._message_id = None + return + self._message_id = val + + # ----------------------------------------------------------- + @property + def postfix_id(self): + """Return the Postfix ID of the mail, which the Pastfix chain is covering.""" + return self._postfix_id + + @postfix_id.setter + def postfix_id(self, value): + if value is None: + self._postfix_id = None + return + + val = str(value).strip().upper() + if val == '': + self._postfix_id = None + return + self._postfix_id = val + + # ----------------------------------------------------------- + @property + def sent_quit(self): + """Return statistics about the quit command in SMTP dialogue.""" + return self._sent_quit + + @sent_quit.setter + def sent_quit(self, value): + if value is None: + self._sent_quit = None + return + + if isinstance(value, int): + self._sent_quit = DataPair(value) + return + if isinstance(value, DataPair): + self._sent_quit = copy.copy(value) + return + val = str(value).strip() + if val == '': + self._sent_quit = None + return + else: + self._sent_quit = DataPair.from_str(val) + # ----------------------------------------------------------- @property def start(self): @@ -290,12 +394,40 @@ class PostfixLogchainInfo(FbGenericBaseObject): self._start = None return - ts_start = self.date_fromisoformat(val) + if hasattr(datetime.datetime, 'fromisoformat'): + ts_start = datetime.datetime.fromisoformat(val) + else: + ts_start = self.date_fromisoformat(val) if ts_start: self._start = ts_start return self._start = val + # ----------------------------------------------------------- + @property + def starttls(self): + """Return statistics about the starttls command in SMTP dialogue.""" + return self._starttls + + @starttls.setter + def starttls(self, value): + if value is None: + self._starttls = None + return + + if isinstance(value, int): + self._starttls = DataPair(value) + return + if isinstance(value, DataPair): + self._starttls = copy.copy(value) + return + val = str(value).strip() + if val == '': + self._starttls = None + return + else: + self._starttls = DataPair.from_str(val) + # ------------------------------------------------------------------------- def __repr__(self): """Typecast into a string for reproduction.""" @@ -303,24 +435,34 @@ class PostfixLogchainInfo(FbGenericBaseObject): fields = [] - if self.auth is not None: - fields.append('auth={!r}'.format(str(self.auth))) + if self.client_host is not None: + fields.append('client_host={!r}'.format(self.client_host)) if self.client_addr is not None: 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 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.message_id is not None: + fields.append('message_id={!r}'.format(self.message_id)) + if self.postfix_id is not None: + fields.append('postfix_id={!r}'.format(self.postfix_id)) + if self.ehlo is not None: + fields.append('ehlo={!r}'.format(str(self.ehlo))) + if self.starttls is not None: + fields.append('starttls={!r}'.format(str(self.starttls))) + if self.sent_quit is not None: + fields.append('sent_quit={!r}'.format(str(self.sent_quit))) + if self.auth is not None: + fields.append('auth={!r}'.format(str(self.auth))) if fields: out += ', '.join(fields) @@ -345,8 +487,13 @@ class PostfixLogchainInfo(FbGenericBaseObject): res['client_addr'] = self.client_addr res['client_host'] = self.client_host res['duration'] = self.duration + res['ehlo'] = self.ehlo res['end'] = self.end + res['message_id'] = self.message_id + res['postfix_id'] = self.postfix_id + res['sent_quit'] = self.sent_quit res['start'] = self.start + res['starttls'] = self.starttls return res diff --git a/test/test_20_postfix_chain.py b/test/test_20_postfix_chain.py index 49fd0ea..904d348 100755 --- a/test/test_20_postfix_chain.py +++ b/test/test_20_postfix_chain.py @@ -91,7 +91,7 @@ class TestPostfixChain(PpAdminToolsTestcase): start='2024-03-15T17:24:52.816303+01:00', end='2024-03-15T17:24:53.304534+01:00', message_id=msg_id, - postfix_pid='23456', + postfix_id='8443240D3514', ehlo='2', starttls='0/1', sent_quit='1', @@ -102,6 +102,7 @@ class TestPostfixChain(PpAdminToolsTestcase): mail=1, from_address='frank.brehm@pixelpark.com', to_address='frank@brehm-online.com', + smtpd_pid='23456', ) LOG.debug('PostfixLogchainInfo %r: {!r}'.format(chain)) LOG.debug('PostfixLogchainInfo %s:\n{}'.format(chain)) -- 2.39.5