Source code for exporters.writers.mail_writer

import email
import os
import datetime
import six
from exporters.writers.base_writer import BaseWriter
from exporters.default_retries import retry_short
from exporters.utils import str_list


[docs]class MaxMailsSent(Exception): """ This exception is thrown when we try to send more than allowed mails number """
[docs]class MailWriter(BaseWriter): """ Send emails with items files attached - email (str) Email address where data will be sent - subject (str) Subject of the email - from (str) Sender of the email - max_mails_sent (str) maximum amount of emails that will be sent """ supported_options = { 'emails': {'type': str_list}, 'subject': {'type': six.string_types}, 'from': {'type': six.string_types, 'env_fallback': 'EXPORTERS_MAIL_FROM'}, 'max_mails_sent': {'type': six.integer_types, 'default': 5}, 'access_key': { 'type': six.string_types, 'env_fallback': 'EXPORTERS_MAIL_AWS_ACCESS_KEY', }, 'secret_key': { 'type': six.string_types, 'env_fallback': 'EXPORTERS_MAIL_AWS_SECRET_KEY', }, 'file_name': {'type': six.string_types, 'default': None} } def __init__(self, options, *args, **kwargs): import boto super(MailWriter, self).__init__(options, *args, **kwargs) self.emails = self.read_option('emails') self.subject = self.read_option('subject') self.sender = self.read_option('from') self.max_mails_sent = self.read_option('max_mails_sent') self.mails_sent = 0 access_key = self.read_option('access_key') secret_key = self.read_option('secret_key') self.ses = boto.connect_ses(access_key, secret_key) self.logger.info('MailWriter has been initiated. Sending to: {}'.format(self.emails)) self.writer_finished = False self.file_base_name = self._get_base_file_name(self.read_option('file_name')) def _get_base_file_name(self, file_name_base): if file_name_base: file_name_base = file_name_base.format(date=datetime.datetime.now()) file_name_base = datetime.datetime.now().strftime(file_name_base) return file_name_base return '' def _get_file_name(self): if self.compression_format != 'none': return '{}{}.{}.{}'.format( self.file_base_name, self.mails_sent, self.export_formatter.file_extension, self.compression_format ) else: return '{}{}.{}'.format( self.file_base_name, self.mails_sent, self.export_formatter.file_extension) def _write_mail(self, dump_path, group_key): if self.max_mails_sent == self.mails_sent: raise MaxMailsSent('Finishing job after max_mails_sent reached: {} mails sent.' .format(self.mails_sent)) m = email.mime.multipart.MIMEMultipart() m['Subject'] = self.subject m['From'] = self.sender # Attachment file_name = self._get_file_name() filesize = os.path.getsize(dump_path) with open(dump_path, 'rb') as fd: part = email.mime.base.MIMEBase('application', 'octet-stream') part.set_payload(fd.read()) email.encoders.encode_base64(part) part.add_header('Content-Disposition', 'attachment', filename=file_name) m.attach(part) # Message body body = "File Name: {key_name} \n" body += "Size: {filesize}\n" body += "Number of Records: {buffered_items}\n" body = body.format( key_name=file_name, filesize=filesize, buffered_items=self.grouping_info[tuple(group_key)]['buffered_items'] ) part = email.mime.text.MIMEText(body) m.attach(part) for destination in self.emails: self.send_mail(m, destination) self.mails_sent += 1 self.logger.debug('Sent {}'.format(dump_path))
[docs] def write(self, dump_path, group_key=None, file_name=None): if self.get_metadata('items_count'): self._write_mail(dump_path, group_key) else: self.logger.debug('Mail not sent. 0 records exported')
@retry_short
[docs] def send_mail(self, m, destination): self.logger.info('Sending email. Sending to: {}'.format(destination)) self.ses.send_raw_email( source=m['From'], raw_message=m.as_string(), destinations=destination) self.logger.info('Email sent to {}'.format(destination))