<commit_before>import logging
import os
import re

import boto3
import pendulum

from . import exceptions

# Set up logging
log = logging.getLogger(__name__)
log.setLevel(logging.DEBUG)


class SesMailNotification(object):
    def __init__(self, data, s3_bucket=None):
        self.data = data
        self.headers = data['commonHeaders']
        self.subject = self.headers['subject']
        self.source = data['source']

        self.message_id = data['messageId']
        self._body = None
        # S3 bucket where SES messages are saved to
        if s3_bucket:
            self.s3_bucket = s3_bucket
        else:
            self.s3_bucket = os.getenv('S3_BUCKET_NAME')

    def body(self):
        """
        Retrieves the body of the email from S3.

        This requires that you set up a previous action in your SES rules to
        store the message in S3.
        """

        if self._body is None:
            log.debug("Downloading message body from s3://{}/{}".format(
                self.s3_bucket, self.message_id))
            s3 = boto3.client('s3')
            obj = s3.get_object(Bucket=self.s3_bucket, Key=self.message_id)
            self._body = obj['Body'].read().decode('utf-8')

        return self._body

    @property
    def from_email(self):
        """
        Cleans the return address provided in the "source" field of the SES
        notification.

        This is primarily used for stripping the BATV signatures, but can
        potentially be used for other sanitizations in the future.
        """

        if self.source.startswith("prvs="):
            # This is a BATV reply address; strip off everything before the
            # prevs=TOKEN= prefix by finding the index of the second =
            index = self.source.index("=", 5) + 1
            return self.source[index:]

        return self.source


def send_ses_email(to, subject, body, **kwargs):
    """
    Sends an email via SES
    """

    source = kwargs.get('source', os.environ.get('EMAIL_SOURCE'))
    bcc = kwargs.get('bcc', os.environ.get('EMAIL_BCC'))

    msg = {
        'Subject': {
            'Data': subject,
            'Charset': 'UTF-8'
        },
        'Body': {
            'Text': {
                'Data': body,
                'Charset': 'UTF-8'
            }
        }
    }

    destination = dict(ToAddresses=[to])
    if bcc:
        destination['BccAddresses'] = [bcc]

    ses = boto3.client('ses')
    log.info("Sending email to {}".format(to))

    return ses.send_email(
        Source=source,
        Destination=destination,
        Message=msg
    )


def send_confirmation(to, reservation):
    """
    Sends an email confirming that the user's checkin has been scheduled
    """

    subject = "Your checkin has been scheduled!"
    body = (
        "Thanks for scheduling a checkin for your flight. I will set "
        "my alarm and wake up to check you in 24 hours before your "
        "departure. Fly safe!\n\n"
        "Confirmation Number: %s\n"
        "Check-in times:\n"
    ) % (reservation.confirmation_number)

    for c in reversed(reservation.check_in_times):<commit_msg>Update confirmation email copy<commit_after>import logging
import os
import re

import boto3
import pendulum

from . import exceptions

# Set up logging
log = logging.getLogger(__name__)
log.setLevel(logging.DEBUG)


class SesMailNotification(object):
    def __init__(self, data, s3_bucket=None):
        self.data = data
        self.headers = data['commonHeaders']
        self.subject = self.headers['subject']
        self.source = data['source']

        self.message_id = data['messageId']
        self._body = None
        # S3 bucket where SES messages are saved to
        if s3_bucket:
            self.s3_bucket = s3_bucket
        else:
            self.s3_bucket = os.getenv('S3_BUCKET_NAME')

    def body(self):
        """
        Retrieves the body of the email from S3.

        This requires that you set up a previous action in your SES rules to
        store the message in S3.
        """

        if self._body is None:
            log.debug("Downloading message body from s3://{}/{}".format(
                self.s3_bucket, self.message_id))
            s3 = boto3.client('s3')
            obj = s3.get_object(Bucket=self.s3_bucket, Key=self.message_id)
            self._body = obj['Body'].read().decode('utf-8')

        return self._body

    @property
    def from_email(self):
        """
        Cleans the return address provided in the "source" field of the SES
        notification.

        This is primarily used for stripping the BATV signatures, but can
        potentially be used for other sanitizations in the future.
        """

        if self.source.startswith("prvs="):
            # This is a BATV reply address; strip off everything before the
            # prevs=TOKEN= prefix by finding the index of the second =
            index = self.source.index("=", 5) + 1
            return self.source[index:]

        return self.source


def send_ses_email(to, subject, body, **kwargs):
    """
    Sends an email via SES
    """

    source = kwargs.get('source', os.environ.get('EMAIL_SOURCE'))
    bcc = kwargs.get('bcc', os.environ.get('EMAIL_BCC'))

    msg = {
        'Subject': {
            'Data': subject,
            'Charset': 'UTF-8'
        },
        'Body': {
            'Text': {
                'Data': body,
                'Charset': 'UTF-8'
            }
        }
    }

    destination = dict(ToAddresses=[to])
    if bcc:
        destination['BccAddresses'] = [bcc]

    ses = boto3.client('ses')
    log.info("Sending email to {}".format(to))

    return ses.send_email(
        Source=source,
        Destination=destination,
        Message=msg
    )


def send_confirmation(to, reservation):
    """
    Sends an email confirming that the user's checkin has been scheduled
    """

    subject = "Your checkin has been scheduled!"
    body = (
        "Thanks for scheduling a checkin for your flight. I will set "
        "my alarm and wake up to check you in 24 hours before your "
        "departure.\n\n"
        "The boarding position which you receive is based on the number of Early Bird passengers on your flight. "
        "80% of checkins are in position B15 or better, which almost guarantees you won't stuck with a middle seat. "
        "Enjoy your flight!\n\n"
        "Confirmation Number: %s\n"
        "Check-in times:\n"
    ) % (reservation.confirmation_number)

    for c in reversed(reservation.check_in_times):
{'fraction_non_alphanumeric': 0.10414436458174033, 'fraction_numerical': 0.008258143447010246, 'mean_word_length': 2.1142857142857143, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '190613', 'n_tokens_mistral': 1956, 'n_tokens_neox': 1879, 'n_words': 580}