diff --git a/mylib/report.py b/mylib/report.py index 63eac99..dd44309 100644 --- a/mylib/report.py +++ b/mylib/report.py @@ -5,31 +5,73 @@ import atexit import logging +from mylib.config import ConfigurableObject +from mylib.config import StringOption +from mylib.email import EmailClient + log = logging.getLogger(__name__) -class Report: # pylint: disable=useless-object-inheritance +class Report(ConfigurableObject): # pylint: disable=useless-object-inheritance """ Logging report """ + _config_name = 'report' + _config_comment = 'Email report' + _defaults = { + 'recipient': None, + 'subject': 'Report', + 'loglevel': 'WARNING', + 'logformat': '%(asctime)s - %(levelname)s - %(message)s', + } + content = [] handler = None formatter = None - subject = None - rcpt_to = None email_client = None - def __init__(self, loglevel=logging.WARNING, logformat='%(asctime)s - %(levelname)s - %(message)s', - subject=None, rcpt_to=None, email_client=None): - self.handler = logging.StreamHandler(self) - self.handler.setLevel(loglevel) - self.formatter = logging.Formatter(logformat) - self.handler.setFormatter(self.formatter) - - self.subject = subject - self.rcpt_to = rcpt_to + def __init__(self, email_client=None, initialize=True, **kwargs): + super().__init__(**kwargs) self.email_client = email_client + if initialize: + self.initialize() + + def configure(self, **kwargs): # pylint: disable=arguments-differ + """ Configure options on registered mylib.Config object """ + section = super().configure(**kwargs) + + section.add_option( + StringOption, 'recipient', comment='Report recipient email address') + section.add_option( + StringOption, 'subject', default=self._defaults['subject'], + comment='Report email subject') + section.add_option( + StringOption, 'loglevel', default=self._defaults['loglevel'], + comment='Report log level (as accept by python logging, for instance "INFO")') + section.add_option( + StringOption, 'logformat', default=self._defaults['logformat'], + comment='Report log level (as accept by python logging, for instance "INFO")') + + if not self.email_client: + self.email_client = EmailClient(config=self._config) + self.email_client.configure() + + return section + + def initialize(self, loaded_config=None): + """ Configuration initialized hook """ + super().initialize(loaded_config=loaded_config) + self.handler = logging.StreamHandler(self) + + loglevel = self._get_option('loglevel').upper() + assert hasattr(logging, loglevel), ( + f'Invalid report loglevel {loglevel}') + self.handler.setLevel(getattr(logging, loglevel)) + + self.formatter = logging.Formatter(self._get_option('logformat')) + self.handler.setFormatter(self.formatter) + def get_handler(self): """ Retreive logging handler """ return self.handler @@ -44,24 +86,27 @@ class Report: # pylint: disable=useless-object-inheritance def send(self, subject=None, rcpt_to=None, email_client=None, just_try=False): """ Send report using an EmailClient """ - if not self.rcpt_to and not rcpt_to: + if rcpt_to is None: + rcpt_to = self._get_option('recipient') + if not rcpt_to: log.debug('No report recipient, do not send report') return True - assert self.subject or subject, "You must provide report subject using Report.__init__ or Report.send" - assert self.email_client or email_client, "You must provide email client using Report.__init__ or Report.send" + if subject is None: + subject = self._get_option('subject') + assert subject, "You must provide report subject using Report.__init__ or Report.send" + if email_client is None: + email_client = self.email_client + assert email_client, ( + "You must provide an email client __init__(), send() or send_at_exit() methods argument email_client") content = self.get_content() if not content: log.debug('Report is empty, do not send it') return True - msg = email_client.forge_message( - self.rcpt_to or rcpt_to, - subject=self.subject or subject, - text_body=content - ) - if email_client.send(self.rcpt_to or rcpt_to, msg=msg, just_try=just_try): - log.debug('Report sent to %s', self.rcpt_to or rcpt_to) + msg = email_client.forge_message(rcpt_to, subject=subject, text_body=content) + if email_client.send(rcpt_to, msg=msg, just_try=just_try): + log.debug('Report sent to %s', rcpt_to) return True - log.error('Fail to send report to %s', self.rcpt_to or rcpt_to) + log.error('Fail to send report to %s', rcpt_to) return False def send_at_exit(self, **kwargs):