Source code for bi_etl.notifiers.email

import email
import re
import smtplib
from email.mime.text import MIMEText
from typing import Optional

import bi_etl.config.notifiers_config as notifiers_config
from bi_etl.notifiers.notifier_base import NotifierBase, NotifierException


[docs] class Email(NotifierBase):
[docs] def __init__(self, config_section: notifiers_config.SMTP_Notifier, *, name: Optional[str] = None): super().__init__(name=name) self.config_section = config_section
[docs] def send(self, subject, message, sensitive_message=None, attachment=None, throw_exception=False): distro_list = self.config_section.distro_list if not distro_list: self.log.warning(f'{self.config_section} distro_list option not found. No mail sent.') to_addresses = list() if isinstance(distro_list, list): to_addresses.extend(distro_list) elif isinstance(distro_list, str): for to_address in re.split(r'[,;\n]', distro_list): to_address = to_address.strip() self.log.info(f'Adding {to_address} to send list') to_addresses.append(to_address) else: raise ValueError(f"distro_list not list or string but {type(distro_list)} with value {distro_list}") server = None try: if isinstance(message, email.message.Message): if subject is not None: message['subject'] = subject if 'To' not in message: message['To'] = ','.join(to_addresses) if 'From' not in message: if 'Sender' not in message: message['Sender'] = self.config_section.email_from else: if message is None: message = '' message = MIMEText(message) if subject is not None: subject_escaped = subject reserved_list = ['\n', '\r'] for reserved in reserved_list: subject_escaped = subject_escaped.replace(reserved, ' ') message['subject'] = subject_escaped message['Sender'] = self.config_section.email_from message['To'] = ','.join(to_addresses) gateway = self.config_section.gateway_host gateway_port = self.config_section.gateway_port gateway_userid = self.config_section.user_id gateway_password = self.config_section.get_password() use_ssl = self.config_section.use_ssl if use_ssl: server = smtplib.SMTP_SSL(gateway, port=gateway_port) else: server = smtplib.SMTP(gateway, port=gateway_port) server.set_debuglevel(self.config_section.debug) if gateway_userid is not None: server.login(gateway_userid, gateway_password) results_of_send = server.send_message(message) self.log.debug(f"results_of_send = {results_of_send}") for recipient in results_of_send: self.log.warn(f"Problem sending to: {recipient}") except smtplib.SMTPRecipientsRefused as e: self.log.critical(f"All recipients were refused.\n{e.recipients}") if throw_exception: raise NotifierException(e) except smtplib.SMTPHeloError as e: self.log.critical(f"The server didn't reply properly to the HELO greeting.\n{e}") if throw_exception: raise NotifierException(e) except smtplib.SMTPSenderRefused as e: self.log.critical(f"The server didn't accept the from_addr {message.get('Sender', None)}.\n{e}") if throw_exception: raise NotifierException(e) except smtplib.SMTPDataError as e: self.log.critical( f"The server replied with an unexpected error code (other than a refusal of a recipient).\n{e}" ) if throw_exception: raise NotifierException(e) finally: try: if server is not None: reply = server.quit() self.log.debug(f"server quit reply = {reply}") self.log.info('Mail sent') except Exception as e: self.log.exception(e)