예제 #1
0
class AmazonTransport(object):  # pragma: no cover
    __slots__ = ('ephemeral', 'id', 'key', 'host', 'connection')

    def __init__(self, config):
        self.id = config.get('id')
        self.key = config.get('key')
        self.host = config.get('host', "email.us-east-1.amazonaws.com")
        self.connection = None

    def startup(self):
        self.connection = SESConnection(aws_access_key_id=self.id,
                                        aws_secret_access_key=self.key,
                                        host=self.host)

    def deliver(self, message):
        try:
            response = self.connection.send_raw_email(
                source=message.author.encode(),
                destinations=message.recipients.encode(),
                raw_message=str(message))

            return (response['SendRawEmailResponse']['SendRawEmailResult']
                    ['MessageId'], response['SendRawEmailResponse']
                    ['ResponseMetadata']['RequestId'])

        except SESConnection.ResponseError:
            raise  # TODO: Raise appropriate internal exception.
            # ['status', 'reason', 'body', 'request_id', 'error_code', 'error_message']

    def shutdown(self):
        if self.connection:
            self.connection.close()

        self.connection = None
예제 #2
0
 def ses_notify(pricedict, stocks):
     print "notify", pricedict, stocks
     lines = []
     keys = pricedict.keys()
     keys.sort()
     if stocks:
         lines.append("big movers, %s" % ",".join(stocks))
     for k in keys:
         v = pricedict[k]
         lines.append("%s : %.2f" % (k,v))
     message = "\n".join(lines)
     print message
     import json
     with open("/home/yata/keys.json") as f:
         data = f.read()
         keys = json.loads(data)
     from boto.ses import SESConnection
     connection = SESConnection(
         aws_access_key_id=keys["AWS_ACCESS_KEY"],
         aws_secret_access_key=keys["AWS_SECRET_KEY"]
         )
     connection.send_email("*****@*****.**",
                           "stock update", message,
                           ["*****@*****.**", "*****@*****.**"],
                           )
예제 #3
0
    def emit(self, record):
        """
        Emit a record.

        Format the record and send it to the specified addressees.
        """
        client = SESConnection(self.aws_key, self.aws_secret)

        message = MIMEMultipart('alternative')
        message.set_charset('UTF-8')

        message['Subject'] = self._encode_str(self.getSubject(record))
        message['From'] = self._encode_str(self.fromaddr)
        message['To'] = self._convert_to_strings(self.toaddrs)

        from email.utils import formatdate

        body = self.format(record)
        body = "Date: {0}\r\n\r\n {1}".format(formatdate(), body)

        message.attach(MIMEText(self._encode_str(body), 'plain'))

        return client.send_raw_email(message.as_string(),
                                     self.fromaddr,
                                     destinations=self.toaddrs)
예제 #4
0
 def __init__(self, aws_access_key, aws_secret_key):
     try:
         self.ses_conn = SESConnection(aws_access_key_id=aws_access_key,
                                       aws_secret_access_key=aws_secret_key)
     except:
         print "SES Connection was failed !!"
         exit()
예제 #5
0
    def emit(self, record):
        """
        Emit a record.

        Format the record and send it to the specified addressees.
        """
        client =  SESConnection(self.aws_key, self.aws_secret)

        message = MIMEMultipart('alternative')
        message.set_charset('UTF-8')

        message['Subject'] = self._encode_str(self.getSubject(record))
        message['From'] = self._encode_str(self.fromaddr)
        message['To'] = self._convert_to_strings(self.toaddrs)

        from email.utils import formatdate

        body = self.format(record)
        body = "From: %s\r\n" \
               "To: %s\r\n" \
               "Subject: %s\r\n" \
               "Date: %s\r\n\r\n" \
               "%s" % (
               self.fromaddr,
               ",".join(self.toaddrs),
               self.getSubject(record),
               formatdate(),
               body)

        message.attach(MIMEText(self._encode_str(body), 'plain'))

        return client.send_raw_email(message.as_string(), self.fromaddr,
                                     destinations=self.toaddrs)
예제 #6
0
파일: run.py 프로젝트: gmc-dev/hours
def send_email(date_from, date_to, email=config['email']['default_to'], worklogs=None):
    worklogs = worklogs or get_worklogs(date_from, date_to)

    # put data into weeks
    weeks = {}
    for date in worklogs:
        # add issue date
        for worklog in worklogs[date]:
            issue, description = get_jira_issue(worklog['task_name'])
            if not issue:
                worklog['issue'] = worklog['task_name']
                worklog['comment'] = ''
                continue

            worklog['issue'] = '<a href="%s" target="_blank">%s: %s</a>' % (issue.permalink(), str(issue), issue.fields.summary)
            worklog['comment'] = description

        week = '%i-%02i' % (date.year, date.isocalendar()[1])
        if week not in weeks:
            weeks[week] = {}
        weeks[week][date] = worklogs[date]

    html = build_email(weeks, config['email']['template'])

    connection = SESConnection(aws_access_key_id=config['email']['aws']['access_key_id'],
                               aws_secret_access_key=config['email']['aws']['secret_access_key'])

    subject = 'Hours report %s - %s' % (date_from.strftime('%m/%d'), date_to.strftime('%m/%d'))

    connection.send_email(config['email']['from'], subject, html, email, format='html')
예제 #7
0
def ses_email(config, to_address, subject, body):
    connection = SESConnection(
        aws_access_key_id=config['AWS_ACCESS_KEY_ID'],
        aws_secret_access_key=config['AWS_SECRET_ACCESS_KEY_ID'])
    from_address = '"SolutionNet" <{0}>'.format(config['FROM_EMAIL_ADDRESS'])

    connection.send_email(from_address, str(subject), str(escape(body)),
                          str(to_address))
예제 #8
0
def dashboard(request):
    """
    Graph SES send statistics over time.
    """
    cache_key = 'vhash:django_ses_stats'
    cached_view = cache.get(cache_key)
    if cached_view:
        return cached_view

    region = RegionInfo(name=getattr(settings, 'AWS_SES_REGION_NAME',
                                     SESConnection.DefaultRegionName),
                        endpoint=getattr(settings, 'AWS_SES_REGION_ENDPOINT',
                                         SESConnection.DefaultRegionEndpoint))

    ses_conn = SESConnection(
        aws_access_key_id=getattr(settings, 'AWS_ACCESS_KEY_ID', None),
        aws_secret_access_key=getattr(settings, 'AWS_SECRET_ACCESS_KEY', None),
        region=region)

    quota_dict = ses_conn.get_send_quota()
    verified_emails_dict = ses_conn.list_verified_email_addresses()
    stats = ses_conn.get_send_statistics()

    quota = quota_parse(quota_dict)
    verified_emails = emails_parse(verified_emails_dict)
    ordered_data = stats_to_list(stats)
    summary = sum_stats(ordered_data)

    extra_context = {
        'title':
        'SES Statistics',
        'datapoints':
        ordered_data,
        '24hour_quota':
        quota['Max24HourSend'],
        '24hour_sent':
        quota['SentLast24Hours'],
        '24hour_remaining':
        float(quota['Max24HourSend']) - float(quota['SentLast24Hours']),
        'persecond_rate':
        quota['MaxSendRate'],
        'verified_emails':
        verified_emails,
        'summary':
        summary,
        'access_key':
        ses_conn.gs_access_key_id,
        'local_time':
        True if pytz else False,
    }

    response = render_to_response('django_ses/send_stats.html',
                                  extra_context,
                                  context_instance=RequestContext(request))

    cache.set(cache_key, response, 60 * 15)  # Cache for 15 minutes
    return response
예제 #9
0
def ses_email(config, to_address, subject, body):
    connection = SESConnection(
        aws_access_key_id=config['AWS_ACCESS_KEY_ID'],
        aws_secret_access_key=config['AWS_SECRET_ACCESS_KEY'],
        region=next(i for i in regions() if i.name == config['AWS_REGION']))
    from_address = '"SolutionNet" <{0}>'.format(config['FROM_EMAIL_ADDRESS'])

    connection.send_email(from_address, str(subject), str(body),
                          str(to_address))
예제 #10
0
def ses_email(config, to_address, subject, body):
    connection = SESConnection(aws_access_key_id=config['AWS_ACCESS_KEY_ID'],
                               aws_secret_access_key=config['AWS_SECRET_ACCESS_KEY_ID'])
    from_address = '"SolutionNet" <{0}>'.format(config['FROM_EMAIL_ADDRESS'])

    connection.send_email(from_address,
                          str(subject),
                          str(escape(body)),
                          str(to_address))
예제 #11
0
def dashboard(request):
    """
    Graph SES send statistics over time.
    """
    cache_key = 'vhash:django_ses_stats'
    cached_view = cache.get(cache_key)
    if cached_view:
        return cached_view

    region = RegionInfo(name=settings.AWS_SES_REGION_NAME,
                        endpoint=settings.AWS_SES_REGION_ENDPOINT)

    ses_conn = SESConnection(
        aws_access_key_id=settings.ACCESS_KEY,
        aws_secret_access_key=settings.SECRET_KEY,
        region=region,
        proxy=settings.AWS_SES_PROXY,
        proxy_port=settings.AWS_SES_PROXY_PORT,
    )

    quota_dict = ses_conn.get_send_quota()
    verified_emails_dict = ses_conn.list_verified_email_addresses()
    stats = ses_conn.get_send_statistics()

    quota = quota_parse(quota_dict)
    verified_emails = emails_parse(verified_emails_dict)
    ordered_data = stats_to_list(stats)
    summary = sum_stats(ordered_data)

    extra_context = {
        'title':
        'SES Statistics',
        'datapoints':
        ordered_data,
        '24hour_quota':
        quota['Max24HourSend'],
        '24hour_sent':
        quota['SentLast24Hours'],
        '24hour_remaining':
        float(quota['Max24HourSend']) - float(quota['SentLast24Hours']),
        'persecond_rate':
        quota['MaxSendRate'],
        'verified_emails':
        verified_emails,
        'summary':
        summary,
        'access_key':
        ses_conn.gs_access_key_id,
        'local_time':
        True,
    }

    response = render(request, 'django_ses/send_stats.html', extra_context)

    cache.set(cache_key, response, 60 * 15)  # Cache for 15 minutes
    return response
예제 #12
0
    def send_ses(self, sender_from, recipients, body):
        # SES Connection create
        aws_access_key = EXTERNAL_CONFIG['aws_access_key']
        aws_secret_key = EXTERNAL_CONFIG['aws_secret_key']

        from boto.ses import SESConnection
        ses_conn = SESConnection(aws_access_key, aws_secret_key)
        ret = ses_conn.send_raw_email(sender_from, body, destinations=[])

        current_app.logger.debug('sent mail to %s by SES' % (str(recipients),))
        return ret
예제 #13
0
    def __init__(self, source, to_addresses, subject, **kw):
        self.ses = SESConnection()

        self._source = source
        self._to_addresses = to_addresses
        self._cc_addresses = None
        self._bcc_addresses = None

        self.subject = subject
        self.text = None
        self.html = None
        self.attachments = []
예제 #14
0
def send_mail_data(subject, body, format):
    connection = SESConnection(aws_access_key_id=AWS_ACCESS_KEY_ID, aws_secret_access_key=AWS_SECRET_ACCESS_KEY)
    try:
        emails = Mail.objects.all().values_list('email', flat=True)
    except Mail.DoesNotExist:
        emails = []
    for i in range(0, len(emails), MAX_MAILS_PER_SEC):
        to_addresses = emails[i:(i + MAX_MAILS_PER_SEC)]
        connection.send_email(source=DEFAULT_EMAIL_SENDER, subject=subject, body=body,
                              to_addresses=DEFAULT_EMAIL_SENDER,
                              bcc_addresses=to_addresses,
                              format=format)
        time.sleep(1)
예제 #15
0
파일: ses.py 프로젝트: manasgarg/djmail
    def open(self):
        """Create a connection to the AWS API server. This can be reused for
        sending multiple emails.
        """
        if self.connection:
            return False

        try:
            self.connection = SESConnection(
                aws_access_key_id=self._access_key_id,
                aws_secret_access_key=self._access_key)
        except:
            if not self.fail_silently:
                raise
예제 #16
0
def dashboard(request):
    """
    Graph SES send statistics over time.
    """
    cache_key = 'vhash:django_ses_stats'
    cached_view = cache.get(cache_key)
    if cached_view:
        return cached_view

    region = RegionInfo(
        name=getattr(settings, 'AWS_SES_REGION_NAME',
            SESConnection.DefaultRegionName),
        endpoint=getattr(settings, 'AWS_SES_REGION_ENDPOINT',
            SESConnection.DefaultRegionEndpoint))

    ses_conn = SESConnection(
        aws_access_key_id=getattr(settings, 'AWS_ACCESS_KEY_ID', None),
        aws_secret_access_key=getattr(settings, 'AWS_SECRET_ACCESS_KEY', None),
        region=region)

    quota_dict = ses_conn.get_send_quota()
    verified_emails_dict = ses_conn.list_verified_email_addresses()
    stats = ses_conn.get_send_statistics()

    quota = quota_parse(quota_dict)
    verified_emails = emails_parse(verified_emails_dict)
    ordered_data = stats_to_list(stats)
    summary = sum_stats(ordered_data)

    extra_context = {
        'title': 'SES Statistics',
        'datapoints': ordered_data,
        '24hour_quota': quota['Max24HourSend'],
        '24hour_sent': quota['SentLast24Hours'],
        '24hour_remaining': float(quota['Max24HourSend']) -
                            float(quota['SentLast24Hours']),
        'persecond_rate': quota['MaxSendRate'],
        'verified_emails': verified_emails,
        'summary': summary,
        'access_key': ses_conn.gs_access_key_id,
        'local_time': True if pytz else False,
    }

    response = render_to_response(
        'django_ses/send_stats.html',
        extra_context,
        context_instance=RequestContext(request))

    cache.set(cache_key, response, 60 * 15)  # Cache for 15 minutes
    return response
예제 #17
0
class AWSSESSender:
    def __init__(self, aws_access_key, aws_secret_key):
        try:
            self.ses_conn = SESConnection(aws_access_key_id=aws_access_key,
                                          aws_secret_access_key=aws_secret_key)
        except:
            print "SES Connection was failed !!"
            exit()

    def send_email(self, sender, subject, body, recipient_list):
        if self.ses_conn != None:
            self.ses_conn.send_email(sender, subject, body, recipient_list)
        else:
            print "Connection object is null!!"

    def send_raw_email(self, sender, subject, body, recipient_list,
                       attachment_path):
        msg = MIMEMultipart()
        msg['Subject'] = subject
        msg['From'] = sender

        to_list = ""

        for idx, data in enumerate(recipient_list):
            if idx < len(recipient_list) - 1:
                to_list += data + ","
            else:
                to_list += data

        msg['To'] = to_list
        msg.premable = 'Multipart Message.\n'

        # Assembling Mail body
        part = MIMEText(body)
        msg.attach(part)

        # Assembling Attachment
        part = MIMEApplication(open(attachment_path, 'rb').read())
        part.add_header('Content-Disposition',
                        'attachment',
                        filename=os.path.basename(attachment_path))
        msg.attach(part)

        # Send RAW email
        if self.ses_conn != None:
            self.ses_conn.send_raw_email(msg.as_string(),
                                         source=msg['From'],
                                         destinations=recipient_list)
        else:
            print "Connection object is null!!"
예제 #18
0
def dashboard(request):
    """
    Graph SES send statistics over time.
    """
    cache_key = 'vhash:django_ses_stats'
    cached_view = cache.get(cache_key)
    if cached_view:
        return cached_view

    region = RegionInfo(
        name=settings.AWS_SES_REGION_NAME,
        endpoint=settings.AWS_SES_REGION_ENDPOINT)

    ses_conn = SESConnection(
        aws_access_key_id=settings.ACCESS_KEY,
        aws_secret_access_key=settings.SECRET_KEY,
        region=region,
        proxy=settings.AWS_SES_PROXY,
        proxy_port=settings.AWS_SES_PROXY_PORT,
    )

    quota_dict = ses_conn.get_send_quota()
    verified_emails_dict = ses_conn.list_verified_email_addresses()
    stats = ses_conn.get_send_statistics()

    quota = quota_parse(quota_dict)
    verified_emails = emails_parse(verified_emails_dict)
    ordered_data = stats_to_list(stats)
    summary = sum_stats(ordered_data)

    extra_context = {
        'title': 'SES Statistics',
        'datapoints': ordered_data,
        '24hour_quota': quota['Max24HourSend'],
        '24hour_sent': quota['SentLast24Hours'],
        '24hour_remaining': float(quota['Max24HourSend']) -
                            float(quota['SentLast24Hours']),
        'persecond_rate': quota['MaxSendRate'],
        'verified_emails': verified_emails,
        'summary': summary,
        'access_key': ses_conn.gs_access_key_id,
        'local_time': True,
    }

    response = render(request, 'django_ses/send_stats.html', extra_context)

    cache.set(cache_key, response, 60 * 15)  # Cache for 15 minutes
    return response
예제 #19
0
 def conn(self):
     if not self._conn:
         self._conn = SESConnection(
             aws_access_key_id=self.config['access_key'],
             aws_secret_access_key=self.config['secret_key'],
         )
     return self._conn
예제 #20
0
class AmazonTransport(object):
    __slots__ = ('ephemeral', 'id', 'key', 'host', 'connection')
    
    def __init__(self, config):
        self.id = config.get('id')
        self.key = config.get('key')
        self.host = config.get('host', "email.us-east-1.amazonaws.com")
        self.connection = None
    
    def startup(self):
        self.connection = SESConnection(
                aws_access_key_id = self.id,
                aws_secret_access_key = self.key,
                host = self.host
            )
    
    def deliver(self, message):
        try:
            response = self.connection.send_raw_email(
                    source = message.author.encode(),
                    destinations = message.recipients.encode(),
                    raw_message = str(message)
                )
            
            return (
                    response['SendRawEmailResponse']['SendRawEmailResult']['MessageId'],
                    response['SendRawEmailResponse']['ResponseMetadata']['RequestId']
                )
        
        except SESConnection.ResponseError, err:
            raise # TODO: Raise appropriate internal exception.
예제 #21
0
    def handle(self, *args, **options):

        verbosity = options.get('verbosity', 0)
        add_email = options.get('add', False)
        delete_email = options.get('delete', False)
        list_emails = options.get('list', False)

        access_key_id = settings.ACCESS_KEY
        access_key = settings.SECRET_KEY
        region = RegionInfo(
            name=settings.AWS_SES_REGION_NAME,
            endpoint=settings.AWS_SES_REGION_ENDPOINT)

        connection = SESConnection(
                aws_access_key_id=access_key_id,
                aws_secret_access_key=access_key,
                region=region)

        if add_email:
            if verbosity != '0':
                print "Adding email: %s" % add_email
            connection.verify_email_address(add_email)
        elif delete_email:
            if verbosity != '0':
                print "Removing email: %s" % delete_email
            connection.delete_verified_email_address(delete_email)
        elif list_emails:
            if verbosity != '0':
                print "Fetching list of verified emails:"
            response = connection.list_verified_email_addresses()
            emails = response['ListVerifiedEmailAddressesResponse'][
                'ListVerifiedEmailAddressesResult']['VerifiedEmailAddresses']
            for email in emails:
                print email
예제 #22
0
 def handle(self, *args, **options):
     
     verbosity = options.get('verbosity', 0)
     add_email = options.get('add', False)
     delete_email = options.get('delete', False)
     list_emails = options.get('list', False)
     
     access_key_id = getattr(settings, 'AWS_ACCESS_KEY_ID', None)
     access_key = getattr(settings, 'AWS_SECRET_ACCESS_KEY', None)
     api_endpoint = getattr(settings, 'AWS_SES_API_HOST',
                                  '%s.%s' % (
                                     SESConnection.DefaultRegionName,
                                     SESConnection.DefaultRegionEndpoint))
     
     connection = SESConnection(
             aws_access_key_id=access_key_id,
             aws_secret_access_key=access_key,
             host=api_endpoint,
         )
     
     if add_email:
         if verbosity != '0':
             print "Adding email: %s"  % add_email
         connection.verify_email_address(add_email)
     elif delete_email:
         if verbosity != '0':
             print "Removing email: %s" % delete_email
         connection.delete_verified_email_address(delete_email)
     elif list_emails:
         if verbosity != '0':
             print "Fetching list of verified emails:"
         response = connection.list_verified_email_addresses()
         emails = response['ListVerifiedEmailAddressesResponse']['ListVerifiedEmailAddressesResult']['VerifiedEmailAddresses']
         for email in emails:
             print email
예제 #23
0
def notify_user(user_notification):
    email = user_notification.user.email
    email_body = _body(user_notification)
    email_subject = _subject(user_notification)
    if settings.DEBUG:
        print("Sending email: {0} with subject: {1} to: {2}".format(
                email_string, email_subject, email))
    else:
        connection = SESConnection(
            aws_access_key_id=settings.AWS_ACCESS_KEY,
            aws_secret_access_key=settings.AWS_SECRET_KEY)
        connection.send_email(
            source="*****@*****.**",
            subject=email_subject,
            body=email_body,
            to_addresses=[email],
            format='html',
            cc_addresses=['*****@*****.**'])
예제 #24
0
def dashboard(request):
    """
    Graph SES send statistics over time.
    """
    cache_key = "vhash:django_ses_stats"
    cached_view = cache.get(cache_key)
    if cached_view:
        return cached_view

    region = RegionInfo(name=settings.AWS_SES_REGION_NAME, endpoint=settings.AWS_SES_REGION_ENDPOINT)

    ses_conn = SESConnection(
        aws_access_key_id=settings.ACCESS_KEY,
        aws_secret_access_key=settings.SECRET_KEY,
        region=region,
        boto_profile_name=settings.BOTO_PROFILE_NAME,
    )

    quota_dict = ses_conn.get_send_quota()
    verified_emails_dict = ses_conn.list_verified_email_addresses()
    stats = ses_conn.get_send_statistics()

    quota = quota_parse(quota_dict)
    verified_emails = emails_parse(verified_emails_dict)
    ordered_data = stats_to_list(stats)
    summary = sum_stats(ordered_data)

    extra_context = {
        "title": "SES Statistics",
        "datapoints": ordered_data,
        "24hour_quota": quota["Max24HourSend"],
        "24hour_sent": quota["SentLast24Hours"],
        "24hour_remaining": float(quota["Max24HourSend"]) - float(quota["SentLast24Hours"]),
        "persecond_rate": quota["MaxSendRate"],
        "verified_emails": verified_emails,
        "summary": summary,
        "access_key": ses_conn.gs_access_key_id,
        "local_time": True if pytz else False,
    }

    response = render_to_response("django_ses/send_stats.html", extra_context, context_instance=RequestContext(request))

    cache.set(cache_key, response, 60 * 15)  # Cache for 15 minutes
    return response
예제 #25
0
def _send_email(email, amount, confirm_code):
    if not settings.DEBUG:
        context = {
            'confirm_url': 'http://{0}{1}'.format(
                Site.objects.get_current().domain,
                reverse('main:confirm_pledge', args=[confirm_code])) }
        connection = SESConnection(
            aws_access_key_id=settings.AWS_ACCESS_KEY,
            aws_secret_access_key=settings.AWS_SECRET_KEY)
        connection.send_email(
            source="*****@*****.**",
            subject="Please confirm your pledge",
            body=render_to_string('pledge_email.html', context),
            to_addresses=[email],
            format='html',
            cc_addresses=['*****@*****.**'])
    else:
        print('Sent email to {0} about {1} with confirm code {2}'.format(
                email, amount, confirm_code))
예제 #26
0
	def handle_noargs(self, **options):
		subject = 'hi krista'
		fromName = 'krista'
		fromAddress = '*****@*****.**'
		toAddressesStr = '*****@*****.**'
		textBody = 'hihihi'
		htmlBody = 'body yo yo yo'
		Charset.add_charset('utf-8', Charset.QP, Charset.QP, 'utf-8')
    		msg = MIMEMultipart('alternative')
    		msg['Subject'] = subject
    		msg['From'] = "" + str(fromName) + " <" + fromAddress + ">"
    		msg['To'] = toAddressesStr
    
    		connection = SESConnection(aws_access_key_id=settings.AWS_ACCESS_KEY, 
				aws_secret_access_key=settings.AWS_SECRET_KEY)
    		connection.send_email(fromName + " <" + fromAddress + ">", 
			subject, body=htmlBody, 
			to_addresses=toAddressesStr, text_body=textBody, 
			format="html", return_path=fromAddress)
    def handle(self, *args, **options):

        connection = SESConnection(
            aws_access_key_id=settings.ACCESS_KEY,
            aws_secret_access_key=settings.SECRET_KEY,
            proxy=settings.AWS_SES_PROXY,
            proxy_port=settings.AWS_SES_PROXY_PORT,
            proxy_user=settings.AWS_SES_PROXY_USER,
            proxy_pass=settings.AWS_SES_PROXY_PASS,
        )
        stats = connection.get_send_statistics()
        data_points = stats_to_list(stats, localize=False)
        stats_dict = defaultdict(stat_factory)

        for data in data_points:
            attempts = int(data['DeliveryAttempts'])
            bounces = int(data['Bounces'])
            complaints = int(data['Complaints'])
            rejects = int(data['Rejects'])
            date = data['Timestamp'].split('T')[0]
            stats_dict[date]['delivery_attempts'] += attempts
            stats_dict[date]['bounces'] += bounces
            stats_dict[date]['complaints'] += complaints
            stats_dict[date]['rejects'] += rejects

        for k, v in stats_dict.items():
            stat, created = SESStat.objects.get_or_create(
                date=k,
                defaults={
                    'delivery_attempts': v['delivery_attempts'],
                    'bounces': v['bounces'],
                    'complaints': v['complaints'],
                    'rejects': v['rejects'],
            })

            # If statistic is not new, modify data if values are different
            if not created and stat.delivery_attempts != v['delivery_attempts']:
                stat.delivery_attempts = v['delivery_attempts']
                stat.bounces = v['bounces']
                stat.complaints = v['complaints']
                stat.rejects = v['rejects']
                stat.save()
예제 #28
0
    def handle(self, *args, **options):

        connection = SESConnection(
            aws_access_key_id=settings.ACCESS_KEY,
            aws_secret_access_key=settings.SECRET_KEY,
            proxy=settings.AWS_SES_PROXY,
            proxy_port=settings.AWS_SES_PROXY_PORT,
            proxy_user=settings.AWS_SES_PROXY_USER,
            proxy_pass=settings.AWS_SES_PROXY_PASS,
        )
        stats = connection.get_send_statistics()
        data_points = stats_to_list(stats, localize=False)
        stats_dict = defaultdict(stat_factory)

        for data in data_points:
            attempts = int(data['DeliveryAttempts'])
            bounces = int(data['Bounces'])
            complaints = int(data['Complaints'])
            rejects = int(data['Rejects'])
            date = data['Timestamp'].split('T')[0]
            stats_dict[date]['delivery_attempts'] += attempts
            stats_dict[date]['bounces'] += bounces
            stats_dict[date]['complaints'] += complaints
            stats_dict[date]['rejects'] += rejects

        for k, v in stats_dict.items():
            stat, created = SESStat.objects.get_or_create(
                date=k,
                defaults={
                    'delivery_attempts': v['delivery_attempts'],
                    'bounces': v['bounces'],
                    'complaints': v['complaints'],
                    'rejects': v['rejects'],
                })

            # If statistic is not new, modify data if values are different
            if not created and stat.delivery_attempts != v['delivery_attempts']:
                stat.delivery_attempts = v['delivery_attempts']
                stat.bounces = v['bounces']
                stat.complaints = v['complaints']
                stat.rejects = v['rejects']
                stat.save()
예제 #29
0
    def open(self):
        """Create a connection to the AWS API server. This can be reused for
        sending multiple emails.
        """
        if self.connection:
            return False

        try:
            self.connection = SESConnection(
                aws_access_key_id=self._access_key_id,
                aws_secret_access_key=self._access_key,
                region=self._region,
                proxy=self._proxy,
                proxy_port=self._proxy_port,
                proxy_user=self._proxy_user,
                proxy_pass=self._proxy_pass,
            )
        except Exception:
            if not self.fail_silently:
                raise
예제 #30
0
 def handle(self, *args, **options):
     
     verbosity = options.get('verbosity', 0)
     add_email = options.get('add', False)
     delete_email = options.get('delete', False)
     list_emails = options.get('list', False)
     
     access_key_id = getattr(settings, 'AWS_ACCESS_KEY_ID', None)
     access_key = getattr(settings, 'AWS_SECRET_ACCESS_KEY', None)
     api_endpoint = getattr(settings, 'AWS_SES_API_HOST',
                                  SESConnection.DefaultHost)
     
     connection = SESConnection(
             aws_access_key_id=access_key_id,
             aws_secret_access_key=access_key,
             host=api_endpoint,
         )
     
     if add_email:
         if verbosity != '0':
             print "Adding email: %s"  % add_email
         connection.verify_email_address(add_email)
     elif delete_email:
         if verbosity != '0':
             print "Removing email: %s" % delete_email
         connection.delete_verified_email_address(delete_email)
     elif list_emails:
         if verbosity != '0':
             print "Fetching list of verified emails:"
         response = connection.list_verified_email_addresses()
         emails = response['ListVerifiedEmailAddressesResponse']['ListVerifiedEmailAddressesResult']['VerifiedEmailAddresses']
         for email in emails:
             print email
예제 #31
0
    def handle(self, *args, **options):

        verbosity = options.get("verbosity", 0)
        add_email = options.get("add", False)
        delete_email = options.get("delete", False)
        list_emails = options.get("list", False)

        access_key_id = getattr(settings, "AWS_ACCESS_KEY_ID", None)
        access_key = getattr(settings, "AWS_SECRET_ACCESS_KEY", None)

        connection = SESConnection(aws_access_key_id=access_key_id, aws_secret_access_key=access_key)

        if add_email:
            if verbosity != "0":
                print "Adding email: %s" % add_email
            connection.verify_email_address(add_email)
        elif delete_email:
            if verbosity != "0":
                print "Removing email: %s" % delete_email
            connection.delete_verified_email_address(delete_email)
        elif list_emails:
            if verbosity != "0":
                print "Fetching list of verified emails:"
            response = connection.list_verified_email_addresses()
            emails = response["ListVerifiedEmailAddressesResponse"]["ListVerifiedEmailAddressesResult"][
                "VerifiedEmailAddresses"
            ]
            for email in emails:
                print email
예제 #32
0
    def handle(self, *args, **options):

        verbosity = options.get('verbosity', 0)
        add_email = options.get('add', False)
        delete_email = options.get('delete', False)
        list_emails = options.get('list', False)

        access_key_id = settings.ACCESS_KEY
        access_key = settings.SECRET_KEY
        region = RegionInfo(
            name=settings.AWS_SES_REGION_NAME,
            endpoint=settings.AWS_SES_REGION_ENDPOINT)

        connection = SESConnection(
                aws_access_key_id=access_key_id,
                aws_secret_access_key=access_key,
                region=region)

        if add_email:
            if verbosity != '0':
                print "Adding email: %s" % add_email
            connection.verify_email_address(add_email)
        elif delete_email:
            if verbosity != '0':
                print "Removing email: %s" % delete_email
            connection.delete_verified_email_address(delete_email)
        elif list_emails:
            if verbosity != '0':
                print "Fetching list of verified emails:"
            response = connection.list_verified_email_addresses()
            emails = response['ListVerifiedEmailAddressesResponse'][
                'ListVerifiedEmailAddressesResult']['VerifiedEmailAddresses']
            for email in emails:
                print email
예제 #33
0
def connect_ses(aws_access_key_id=None, aws_secret_access_key=None, **kwargs):
    """
    :type aws_access_key_id: string
    :param aws_access_key_id: Your AWS Access Key ID

    :type aws_secret_access_key: string
    :param aws_secret_access_key: Your AWS Secret Access Key

    :rtype: :class:`boto.ses.SESConnection`
    :return: A connection to Amazon's SES
    """
    from boto.ses import SESConnection
    return SESConnection(aws_access_key_id, aws_secret_access_key, **kwargs)
예제 #34
0
    def handle(self, *args, **options):

        connection = SESConnection(
            aws_access_key_id=getattr(settings, "AWS_ACCESS_KEY_ID", None),
            aws_secret_access_key=getattr(settings, "AWS_SECRET_ACCESS_KEY", None),
        )
        stats = connection.get_send_statistics()
        data_points = stats_to_list(stats, localize=False)
        stats_dict = defaultdict(stat_factory)

        for data in data_points:
            attempts = int(data["DeliveryAttempts"])
            bounces = int(data["Bounces"])
            complaints = int(data["Complaints"])
            rejects = int(data["Rejects"])
            date = data["Timestamp"].split("T")[0]
            stats_dict[date]["delivery_attempts"] += attempts
            stats_dict[date]["bounces"] += bounces
            stats_dict[date]["complaints"] += complaints
            stats_dict[date]["rejects"] += rejects

        for k, v in stats_dict.items():
            stat, created = SESStat.objects.get_or_create(
                date=k,
                defaults={
                    "delivery_attempts": v["delivery_attempts"],
                    "bounces": v["bounces"],
                    "complaints": v["complaints"],
                    "rejects": v["rejects"],
                },
            )

            # If statistic is not new, modify data if values are different
            if not created and stat.delivery_attempts != v["delivery_attempts"]:
                stat.delivery_attempts = v["delivery_attempts"]
                stat.bounces = v["bounces"]
                stat.complaints = v["complaints"]
                stat.rejects = v["rejects"]
                stat.save()
예제 #35
0
def send(subject,body,toAddressesStr,fromName,fromAddress,replacements):
  connection = SESConnection(aws_access_key_id=settings.AWS_ACCESS_KEY, aws_secret_access_key=settings.AWS_SECRET_KEY)

  ###Send Welcome Email
  htmlBody = "%s%s%s" % (HEADER,body,END)

  textBody = "%s\n\n\n%s" % (strip_tags(body), "Use link below to unsubscribe from these reminders: \n{{unsubscribe}}")
  textBody = textBody.replace("&nbsp;","")
  textBody = textBody.replace("&rsquo;","'")
  textBody = textBody.replace("&lsquo;","'")
  textBody = textBody.replace("&rdquo;",'"')
  textBody = textBody.replace("&ldquo;",'"')

  for key, value in replacements.iteritems():
    textBody = textBody.replace(key,value)
    htmlBody = htmlBody.replace(key,value)
    subject = subject.replace(key,value)

  connection.send_email(fromName + " <" + fromAddress + ">", 
    subject, body=htmlBody, to_addresses=toAddressesStr, 
    text_body=textBody, format="html", 
    return_path=fromAddress)
예제 #36
0
    def open(self):
        """Create a connection to the AWS API server. This can be reused for
        sending multiple emails.
        """
        if self.connection:
            return False

        try:
            self.connection = SESConnection(
                aws_access_key_id=self._access_key_id, aws_secret_access_key=self._access_key, host=self._api_endpoint
            )
        except:
            if not self.fail_silently:
                raise
예제 #37
0
def send_invite(modeladmin, request, queryset):
    for r in queryset:
        h = hashlib.md5("%s%sfunkyfresh" % (request.user.id, r.email))
        i = Invite.objects.create(owner=request.user,
                                  email=r.email,
                                  code=h.hexdigest())
        r.delete()
        c = SESConnection(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
        send_mail(
            "[muxlist] You're invited!",
            render_to_string('email/invite.html', {
                'hostname': HOSTNAME,
                'invite': i
            }), SERVER_EMAIL, [i.email])
예제 #38
0
class AmazonSMTPServer(smtpd.SMTPServer):
    amazonSES = SESConnection()

    def process_message(self, peer, mailfrom, rcpttos, data):
        if 'False' in rcpttos:
            logging.info('No recipient email')
            return
        data = email.message_from_string(data)
        # Amazon SES don't support 'Organization' header, which is created
        # by email_template module
        if 'Organization' in data:
            del data['Organization']
        data = data.as_string()
        result = self.amazonSES.send_raw_email(mailfrom, data, rcpttos)
        logging.info('Email to %s sent' % rcpttos)
예제 #39
0
def send_mail(msg):
    global access_key
    global secret_key

    client = SESConnection(
        aws_access_key_id=access_key, aws_secret_access_key=secret_key)
    senders = msg["From"].split(",")
    recipients = msg["To"].split(',')
    for sender in senders:
        client.send_raw_email(msg.as_string(), sender, recipients)
    client.close()
예제 #40
0
def get_boto_ses_connection():
    """
    Shortcut for instantiating and returning a boto SESConnection object.
    
    :rtype: boto.ses.SESConnection
    :returns: A boto SESConnection object, from which email sending is done.
    """
    access_key_id = getattr(settings, 'AWS_ACCESS_KEY_ID', None)
    access_key = getattr(settings, 'AWS_SECRET_ACCESS_KEY', None)
    api_endpoint = getattr(settings, 'AWS_SES_API_HOST',
                           SESConnection.DefaultHost)

    return SESConnection(
        aws_access_key_id=access_key_id,
        aws_secret_access_key=access_key,
        host=api_endpoint,
    )
예제 #41
0
    def open(self):
        """Create a connection to the AWS API server. This can be reused for
        sending multiple emails.
        """
        if self.connection:
            return False

        try:
            self.connection = SESConnection(
                aws_access_key_id=self._access_key_id,
                aws_secret_access_key=self._access_key,
                region=self._region,
                profile_name=self._boto_profile_name,
            )
        except:
            if not self.fail_silently:
                raise
예제 #42
0
    def open(self):
        """Create a connection to the AWS API server. This can be reused for
        sending multiple emails.
        """
        if self.connection:
            return False

        try:
            self.connection = SESConnection(
                aws_access_key_id=self._access_key_id,
                aws_secret_access_key=self._access_key,
                region=self._region,
                proxy=self._proxy,
                proxy_port=self._proxy_port,
                proxy_user=self._proxy_user,
                proxy_pass=self._proxy_pass,
            )
        except Exception:
            if not self.fail_silently:
                raise
예제 #43
0
    def handle(self, *args, **options):

        verbosity = options.get('verbosity', 0)
        add_email = options.get('add', False)
        delete_email = options.get('delete', False)
        list_emails = options.get('list', False)

        access_key_id = settings.ACCESS_KEY
        access_key = settings.SECRET_KEY
        region = RegionInfo(
            name=settings.AWS_SES_REGION_NAME,
            endpoint=settings.AWS_SES_REGION_ENDPOINT)
        proxy = settings.AWS_SES_PROXY
        proxy_port = settings.AWS_SES_PROXY_PORT
        proxy_user = settings.AWS_SES_PROXY_USER
        proxy_pass = settings.AWS_SES_PROXY_PASS


        connection = SESConnection(
                aws_access_key_id=access_key_id,
                aws_secret_access_key=access_key,
                region=region,
                proxy=proxy,
                proxy_port=proxy_port,
                proxy_user=proxy_user,
                proxy_pass=proxy_pass,
        )

        if add_email:
            if verbosity != '0':
                print("Adding email: " + add_email)
            connection.verify_email_address(add_email)
        elif delete_email:
            if verbosity != '0':
                print("Removing email: " + delete_email)
            connection.delete_verified_email_address(delete_email)
        elif list_emails:
            if verbosity != '0':
                print("Fetching list of verified emails:")
            response = connection.list_verified_email_addresses()
            emails = response['ListVerifiedEmailAddressesResponse'][
                'ListVerifiedEmailAddressesResult']['VerifiedEmailAddresses']
            for email in emails:
                print(email)
예제 #44
0
def mailsender(request):
    
    mail = request.FILES[u"file"].read()
    to = request.GET["to"]
    
    #split headers
    i = mail.find("\n\n")
    headers, mail = mail[:i], mail[i:]
    headers = headers.split("\n")
    allowed = {"MIME-Version", "Message-ID", "In-Reply-To", "Content-Type", 
               "Date", "Subject", "From", "To", "Bcc", "Cc", "References"}
    
    from_ = None
    
    h = []
    i=0
    while i<len(headers):
        add = False
        header = headers[i][:headers[i].find(":")]
        if header in allowed:
            add = True
        if header == "From":
            from_ = headers[i][headers[i].find(":")+1:].strip()
            
        while True:
            if add: 
                h.append(headers[i])
            i += 1
            if i>=len(headers) or headers[i][0] not in " \t":
                break
            
    mail = "\n".join(h) + mail
    
    #find from email
    i = from_.find("<")
    if i != -1:
        from_ = from_[i+1:]
        from_ = from_[:from_.find(">")]
    
    #logger.info("headers: %s", str(headers))
    #logger.info("h: %s", str(h))
    
    logger.info("Mail from %s to %s recieved", from_, to)
    # Only allow sending from altekamereren domains and registered users.
    if not from_.endswith("@altekamereren.org") \
            and not from_.endswith("@altekamereren.com") \
            and User.objects.filter(email=from_).exists():
        logger.info("Sender not accepted.")
        return HttpResponse(status=403)
    
    to = to.replace(u"flojt", u"flöjt")
    reciever = to.split("@")[0]
    if reciever in ak.sections:
        user_emails = [user.email for user in User.objects.filter(
            instrument__in=ak.section_to_short_instruments[reciever], 
            is_active=True)]

        

        logger.info("Sending to section %s: %s", to, str(user_emails))

    elif reciever == u"infolistan":
        reciever = [user.email for user in User.objects.filter(is_active=True)]
        logger.info("Sending to infolistan: %s", str(reciever))
    else:
        logger.info("List not accepted.")
        return HttpResponse(status=400)
    
    from django.conf import settings
    from boto.ses import SESConnection
    from boto.exception import BotoServerError
    
    access_key_id = getattr(settings, 'AWS_ACCESS_KEY_ID', None)
    access_key = getattr(settings, 'AWS_SECRET_ACCESS_KEY', None)
    api_endpoint = getattr(settings, 'AWS_SES_API_HOST',
                                     SESConnection.DefaultHost)
    connection = SESConnection(
                aws_access_key_id=access_key_id,
                aws_secret_access_key=access_key,
                host=api_endpoint,
    )
    
    if not user_emails:
        return HttpResponse(status=400)

    try:
        connection.send_raw_email(mail, settings.ADMINS[0][1], user_emails)
    except BotoServerError as e:
        i = e.body.find("<Message>")
        message = e.body[i+len("<Message>"):]
        message = message[:message.find("</Message>")]
        
        if message == "Email address is not verified.":
            if MailVerificationSent.objects.filter(email=from_, 
                    sent__gte=datetime.datetime.now() - datetime.timedelta(days=1)
                        ).exists():
                connection.verify_email_address(from_)
                logger.error("Sending verify mail to: %s", from_)
                MailVerificationSent(email=from_).save()
            else:
                logger.error("Verify mail already sent today: %s", from_)
            return HttpResponse(status=444)
        else:
            raise

    
    return HttpResponse()
예제 #45
0
def send_email(fromaddr, toaddrs, subject, txtdata):
    from boto.ses import SESConnection
    connection = SESConnection(
        aws_access_key_id=keys["AWS_ACCESS_KEY"],
        aws_secret_access_key=keys["AWS_SECRET_KEY"])
    connection.send_email(fromaddr, subject, txtdata, toaddrs)
예제 #46
0
class SESBackend(BaseEmailBackend):
    """A Django Email backend that uses Amazon's Simple Email Service.
    """

    def __init__(self, fail_silently=False, aws_access_key=None,
                 aws_secret_key=None, aws_region_name=None,
                 aws_region_endpoint=None, aws_auto_throttle=None,
                 dkim_domain=None, dkim_key=None, dkim_selector=None,
                 dkim_headers=None, **kwargs):

        super(SESBackend, self).__init__(fail_silently=fail_silently, **kwargs)
        self._access_key_id = aws_access_key or settings.ACCESS_KEY
        self._access_key = aws_secret_key or settings.SECRET_KEY
        self._region = RegionInfo(
            name=aws_region_name or settings.AWS_SES_REGION_NAME,
            endpoint=aws_region_endpoint or settings.AWS_SES_REGION_ENDPOINT)
        self._throttle = aws_auto_throttle or settings.AWS_SES_AUTO_THROTTLE

        self.dkim_domain = dkim_domain or settings.DKIM_DOMAIN
        self.dkim_key = dkim_key or settings.DKIM_PRIVATE_KEY
        self.dkim_selector = dkim_selector or settings.DKIM_SELECTOR
        self.dkim_headers = dkim_headers or settings.DKIM_HEADERS

        self.connection = None

    def open(self):
        """Create a connection to the AWS API server. This can be reused for
        sending multiple emails.
        """
        if self.connection:
            return False

        try:
            self.connection = SESConnection(
                aws_access_key_id=self._access_key_id,
                aws_secret_access_key=self._access_key,
                region=self._region,
            )
        except:
            if not self.fail_silently:
                raise

    def close(self):
        """Close any open HTTP connections to the API server.
        """
        try:
            self.connection.close()
            self.connection = None
        except:
            if not self.fail_silently:
                raise

    def send_messages(self, email_messages):
        """Sends one or more EmailMessage objects and returns the number of
        email messages sent.
        """
        if not email_messages:
            return

        new_conn_created = self.open()
        if not self.connection:
            # Failed silently
            return

        num_sent = 0
        source = settings.AWS_SES_RETURN_PATH
        for message in email_messages:
            # Automatic throttling. Assumes that this is the only SES client
            # currently operating. The AWS_SES_AUTO_THROTTLE setting is a
            # factor to apply to the rate limit, with a default of 0.5 to stay
            # well below the actual SES throttle.
            # Set the setting to 0 or None to disable throttling.
            if self._throttle:
                global recent_send_times

                now = datetime.now()

                # Get and cache the current SES max-per-second rate limit
                # returned by the SES API.
                rate_limit = self.get_rate_limit()

                # Prune from recent_send_times anything more than a few seconds
                # ago. Even though SES reports a maximum per-second, the way
                # they enforce the limit may not be on a one-second window.
                # To be safe, we use a two-second window (but allow 2 times the
                # rate limit) and then also have a default rate limit factor of
                # 0.5 so that we really limit the one-second amount in two
                # seconds.
                window = 2.0  # seconds
                window_start = now - timedelta(seconds=window)
                new_send_times = []
                for time in recent_send_times:
                    if time > window_start:
                        new_send_times.append(time)
                recent_send_times = new_send_times

                # If the number of recent send times in the last 1/_throttle
                # seconds exceeds the rate limit, add a delay.
                # Since I'm not sure how Amazon determines at exactly what
                # point to throttle, better be safe than sorry and let in, say,
                # half of the allowed rate.
                if len(new_send_times) > rate_limit * window * self._throttle:
                    # Sleep the remainder of the window period.
                    delta = now - new_send_times[0]
                    total_seconds = (delta.microseconds + (delta.seconds +
                            delta.days * 24 * 3600) * 10**6) / 10**6
                    delay = window - total_seconds
                    if delay > 0:
                        sleep(delay)

                recent_send_times.append(now)
                # end of throttling

            try:
                response = self.connection.send_raw_email(
                    source=source or message.from_email,
                    destinations=message.recipients(),
                    raw_message=unicode(dkim_sign(message.message().as_string(),
                                                  dkim_key=self.dkim_key,
                                                  dkim_domain=self.dkim_domain,
                                                  dkim_selector=self.dkim_selector,
                                                  dkim_headers=self.dkim_headers,
                                                  ), 'utf-8')
                )
                message.extra_headers['status'] = 200
                message.extra_headers['message_id'] = response[
                    'SendRawEmailResponse']['SendRawEmailResult']['MessageId']
                message.extra_headers['request_id'] = response[
                    'SendRawEmailResponse']['ResponseMetadata']['RequestId']
                num_sent += 1
            except SESConnection.ResponseError, err:
                # Store failure information so to post process it if required
                error_keys = ['status', 'reason', 'body', 'request_id',
                                'error_code', 'error_message']
                for key in error_keys:
                    message.extra_headers[key] = getattr(err, key, None)
                if not self.fail_silently:
                    raise

        if new_conn_created:
            self.close()

        return num_sent
예제 #47
0
"""

import mimetypes
from email import encoders
from email.utils import COMMASPACE
from email.mime.multipart import MIMEMultipart
from email.mime.audio import MIMEAudio
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
from email.mime.text import MIMEText
from boto.ses import SESConnection

AWS_ACCESS_KEY = 'PUT ACCESS KEY HERE'
AWS_SECRET_KEY = 'PUT SECRET KEY HERE'

connection = SESConnection(AWS_ACCESS_KEY, AWS_SECRET_KEY)


class SESMessage(object):
    """
    Usage:
    
    msg = SESMessage('*****@*****.**', '*****@*****.**', 'The subject')
    msg.text = 'Text body'
    msg.html = 'HTML body'
    msg.send()
    
    """
    def __init__(self, source, to_addresses, subject, **kw):
        self.ses = connection
예제 #48
0
class SESBackend(BaseEmailBackend):
    """A Django Email backend that uses Amazon's Simple Email Service.
    """

    def __init__(self, fail_silently=False, *args, **kwargs):
        super(SESBackend, self).__init__(fail_silently=fail_silently, *args, **kwargs)

        self._access_key_id = getattr(settings, "AWS_ACCESS_KEY_ID", None)
        self._access_key = getattr(settings, "AWS_SECRET_ACCESS_KEY", None)
        self._api_endpoint = getattr(settings, "AWS_SES_API_HOST", SESConnection.DefaultHost)

        self.connection = None

    def open(self):
        """Create a connection to the AWS API server. This can be reused for
        sending multiple emails.
        """
        if self.connection:
            return False

        try:
            self.connection = SESConnection(
                aws_access_key_id=self._access_key_id, aws_secret_access_key=self._access_key, host=self._api_endpoint
            )
        except:
            if not self.fail_silently:
                raise

    def close(self):
        """Close any open HTTP connections to the API server.
        """
        try:
            self.connection.close()
            self.connection = None
        except:
            if not self.fail_silently:
                raise

    def send_messages(self, email_messages):
        """Sends one or more EmailMessage objects and returns the number of
        email messages sent.
        """
        if not email_messages:
            return

        new_conn_created = self.open()
        if not self.connection:
            # Failed silently
            return

        num_sent = 0
        for message in email_messages:
            try:
                response = self.connection.send_raw_email(
                    source=message.from_email,
                    destinations=message.recipients(),
                    raw_message=message.message().as_string(),
                )
                message.extra_headers["status"] = 200
                message.extra_headers["message_id"] = response["SendRawEmailResponse"]["SendRawEmailResult"][
                    "MessageId"
                ]
                message.extra_headers["request_id"] = response["SendRawEmailResponse"]["ResponseMetadata"]["RequestId"]
                num_sent += 1
            except SESConnection.ResponseError, err:
                # Store failure information so you can post process it if required
                error_keys = ["status", "reason", "body", "request_id", "error_code", "error_message"]
                for key in error_keys:
                    message.extra_headers[key] = getattr(err, key, None)
                if not self.fail_silently:
                    raise

        if new_conn_created:
            self.close()

        return num_sent
예제 #49
0
class SesSender(object):
	logger = None

	def run(self):
		self.init_log()
		self.init_signer()
		try:
			self.log("Args: %r" % argv)
			self.log("Env: %r" % dict(environ))
			self.get_parties()
			self.get_credentials()
			self.make_connection()
			self.process_message()
			self.send_message()
		except Exception:
			self.abort('Unspecified error',1)

	def get_parties(self):
		try:
			self.sender = argv[1]
			self.recipients = argv[2:]
		except Exception:
			self.abort('Missing Sender / Recipients',2)

	def get_credentials(self):
		try:
			self.aws_id = environ['AWS_ACCESS_KEY_ID']
			self.aws_key = environ['AWS_SECRET_KEY']
			assert self.aws_id is not None
			assert self.aws_key is not None
		except Exception:
			self.abort('Missing AWS Credentials',3)

	def make_connection(self):
		try:
			self.conn = SESConnection(self.aws_id,self.aws_key)
		except Exception:
			self.abort('Failed to establish connection',4)

	def process_message(self):
		try:
			msg = stdin.read()
			assert msg[:4] == 'From'
			msg = self.sanitize_headers(msg)
			envelope,msg = msg.split('\n',1)
			self.msg = self.sign_message(msg)
			self.log('Sender: %r' % self.sender)
			self.log('Recipients: %r' % self.recipients)
			self.log('Message:\n' + msg)
		except Exception:
			self.abort('Failed to process message text',5)

	def sanitize_headers(self, msg):
		msg_obj = Parser().parsestr(msg)
		for hdr in msg_obj.keys():
			if hdr not in aws_allowed_headers and not hdr.startswith('X-'):
				del msg_obj[hdr]
		return str(msg_obj)

	def sign_message(self, msg):
		if self.dkim:
			return DKIM(msg).sign(self.dkim_selector,
				self.dkim_domain, self.dkim_private_key,
				canonicalize=('relaxed', 'simple'),
				include_headers=dkim_include_headers) + msg
		else:
			return msg

	def send_message(self):
		try:
			self.conn.send_raw_email(
				source=self.sender,
				raw_message=self.msg,
				destinations=self.recipients
			)
		except BotoServerError, bse:
			if 'InvalidTokenId' in bse.body:
				self.abort('Bad AWS Credentials (token)',6)
			if 'SignatureDoesNotMatch' in bse.body:
				self.abort('Bad AWS Credentials (signature)',6)
			if bse.error_code == 'Throttling':
				self.abort('Failed to actually deliver message: quota exceeded',9)
			self.abort('Failed to actually deliver message:',7)
		except Exception:
			self.abort('Failed to actually deliver message:',7)
예제 #50
0
 def startup(self):
     self.connection = SESConnection(
             aws_access_key_id = self.id,
             aws_secret_access_key = self.key,
             host = self.host
         )
예제 #51
0
 def get_client(self):
     if not self.client:
         self.client = SESConnection(self.aws_key, self.aws_secret)
     return self.client
예제 #52
0
class SESBackend(BaseEmailBackend):
    """A Django Email backend that uses Amazon's Simple Email Service.
    """
    def __init__(self,
                 fail_silently=False,
                 aws_access_key=None,
                 aws_secret_key=None,
                 aws_region_name=None,
                 aws_region_endpoint=None,
                 aws_auto_throttle=None,
                 dkim_domain=None,
                 dkim_key=None,
                 dkim_selector=None,
                 dkim_headers=None,
                 proxy=None,
                 proxy_port=None,
                 proxy_user=None,
                 proxy_pass=None,
                 **kwargs):

        super(SESBackend, self).__init__(fail_silently=fail_silently, **kwargs)
        self._access_key_id = aws_access_key or settings.ACCESS_KEY
        self._access_key = aws_secret_key or settings.SECRET_KEY
        self._region = RegionInfo(name=aws_region_name
                                  or settings.AWS_SES_REGION_NAME,
                                  endpoint=aws_region_endpoint
                                  or settings.AWS_SES_REGION_ENDPOINT)
        self._throttle = aws_auto_throttle or settings.AWS_SES_AUTO_THROTTLE
        self._proxy = proxy or settings.AWS_SES_PROXY
        self._proxy_port = proxy_port or settings.AWS_SES_PROXY_PORT
        self._proxy_user = proxy_user or settings.AWS_SES_PROXY_USER
        self._proxy_pass = proxy_pass or settings.AWS_SES_PROXY_PASS

        self.dkim_domain = dkim_domain or settings.DKIM_DOMAIN
        self.dkim_key = dkim_key or settings.DKIM_PRIVATE_KEY
        self.dkim_selector = dkim_selector or settings.DKIM_SELECTOR
        self.dkim_headers = dkim_headers or settings.DKIM_HEADERS

        self.connection = None

    def open(self):
        """Create a connection to the AWS API server. This can be reused for
        sending multiple emails.
        """
        if self.connection:
            return False

        try:
            self.connection = SESConnection(
                aws_access_key_id=self._access_key_id,
                aws_secret_access_key=self._access_key,
                region=self._region,
                proxy=self._proxy,
                proxy_port=self._proxy_port,
                proxy_user=self._proxy_user,
                proxy_pass=self._proxy_pass,
            )
        except Exception:
            if not self.fail_silently:
                raise

    def close(self):
        """Close any open HTTP connections to the API server.
        """
        try:
            self.connection.close()
            self.connection = None
        except Exception:
            if not self.fail_silently:
                raise

    def send_messages(self, email_messages):
        """Sends one or more EmailMessage objects and returns the number of
        email messages sent.
        """
        if not email_messages:
            return

        new_conn_created = self.open()
        if not self.connection:
            # Failed silently
            return

        num_sent = 0
        source = settings.AWS_SES_RETURN_PATH
        for message in email_messages:
            # SES Configuration sets. If the AWS_SES_CONFIGURATION_SET setting
            # is not None, append the appropriate header to the message so that
            # SES knows which configuration set it belongs to.
            #
            # If settings.AWS_SES_CONFIGURATION_SET is a callable, pass it the
            # message object and dkim settings and expect it to return a string
            # containing the SES Configuration Set name.
            if (settings.AWS_SES_CONFIGURATION_SET and
                    'X-SES-CONFIGURATION-SET' not in message.extra_headers):
                if callable(settings.AWS_SES_CONFIGURATION_SET):
                    message.extra_headers[
                        'X-SES-CONFIGURATION-SET'] = settings.AWS_SES_CONFIGURATION_SET(
                            message,
                            dkim_domain=self.dkim_domain,
                            dkim_key=self.dkim_key,
                            dkim_selector=self.dkim_selector,
                            dkim_headers=self.dkim_headers)
                else:
                    message.extra_headers[
                        'X-SES-CONFIGURATION-SET'] = settings.AWS_SES_CONFIGURATION_SET

            # Automatic throttling. Assumes that this is the only SES client
            # currently operating. The AWS_SES_AUTO_THROTTLE setting is a
            # factor to apply to the rate limit, with a default of 0.5 to stay
            # well below the actual SES throttle.
            # Set the setting to 0 or None to disable throttling.
            if self._throttle:
                global recent_send_times

                now = datetime.now()

                # Get and cache the current SES max-per-second rate limit
                # returned by the SES API.
                rate_limit = self.get_rate_limit()
                logger.debug(u"send_messages.throttle rate_limit='{}'".format(
                    rate_limit))

                # Prune from recent_send_times anything more than a few seconds
                # ago. Even though SES reports a maximum per-second, the way
                # they enforce the limit may not be on a one-second window.
                # To be safe, we use a two-second window (but allow 2 times the
                # rate limit) and then also have a default rate limit factor of
                # 0.5 so that we really limit the one-second amount in two
                # seconds.
                window = 2.0  # seconds
                window_start = now - timedelta(seconds=window)
                new_send_times = []
                for time in recent_send_times:
                    if time > window_start:
                        new_send_times.append(time)
                recent_send_times = new_send_times

                # If the number of recent send times in the last 1/_throttle
                # seconds exceeds the rate limit, add a delay.
                # Since I'm not sure how Amazon determines at exactly what
                # point to throttle, better be safe than sorry and let in, say,
                # half of the allowed rate.
                if len(new_send_times) > rate_limit * window * self._throttle:
                    # Sleep the remainder of the window period.
                    delta = now - new_send_times[0]
                    total_seconds = (delta.microseconds +
                                     (delta.seconds + delta.days * 24 * 3600) *
                                     10**6) / 10**6
                    delay = window - total_seconds
                    if delay > 0:
                        sleep(delay)

                recent_send_times.append(now)
                # end of throttling

            try:
                response = self.connection.send_raw_email(
                    source=source or message.from_email,
                    destinations=message.recipients(),
                    raw_message=dkim_sign(message.message().as_string(),
                                          dkim_key=self.dkim_key,
                                          dkim_domain=self.dkim_domain,
                                          dkim_selector=self.dkim_selector,
                                          dkim_headers=self.dkim_headers))
                message.extra_headers['status'] = 200
                message.extra_headers['message_id'] = response[
                    'SendRawEmailResponse']['SendRawEmailResult']['MessageId']
                message.extra_headers['request_id'] = response[
                    'SendRawEmailResponse']['ResponseMetadata']['RequestId']
                num_sent += 1
                if 'X-SES-CONFIGURATION-SET' in message.extra_headers:
                    logger.debug(
                        u"send_messages.sent from='{}' recipients='{}' message_id='{}' request_id='{}' ses-configuration-set='{}'"
                        .format(
                            message.from_email,
                            ", ".join(message.recipients()),
                            message.extra_headers['message_id'],
                            message.extra_headers['request_id'],
                            message.extra_headers['X-SES-CONFIGURATION-SET']))
                else:
                    logger.debug(
                        u"send_messages.sent from='{}' recipients='{}' message_id='{}' request_id='{}'"
                        .format(message.from_email,
                                ", ".join(message.recipients()),
                                message.extra_headers['message_id'],
                                message.extra_headers['request_id']))

            except SESConnection.ResponseError as err:
                # Store failure information so to post process it if required
                error_keys = [
                    'status', 'reason', 'body', 'request_id', 'error_code',
                    'error_message'
                ]
                for key in error_keys:
                    message.extra_headers[key] = getattr(err, key, None)
                if not self.fail_silently:
                    raise

        if new_conn_created:
            self.close()

        return num_sent

    def get_rate_limit(self):
        if self._access_key_id in cached_rate_limits:
            return cached_rate_limits[self._access_key_id]

        new_conn_created = self.open()
        if not self.connection:
            raise Exception(
                "No connection is available to check current SES rate limit.")
        try:
            quota_dict = self.connection.get_send_quota()
            max_per_second = quota_dict['GetSendQuotaResponse'][
                'GetSendQuotaResult']['MaxSendRate']
            ret = float(max_per_second)
            cached_rate_limits[self._access_key_id] = ret
            return ret
        finally:
            if new_conn_created:
                self.close()
예제 #53
0
class SESBackend(BaseEmailBackend):
    """A Django Email backend that uses Amazon's Simple Email Service.
    """
    def __init__(self,
                 fail_silently=False,
                 aws_access_key=None,
                 aws_secret_key=None,
                 aws_region_name=None,
                 aws_region_endpoint=None,
                 aws_auto_throttle=None,
                 dkim_domain=None,
                 dkim_key=None,
                 dkim_selector=None,
                 dkim_headers=None,
                 **kwargs):

        super(SESBackend, self).__init__(fail_silently=fail_silently, **kwargs)
        self._access_key_id = aws_access_key or settings.ACCESS_KEY
        self._access_key = aws_secret_key or settings.SECRET_KEY
        self._region = RegionInfo(name=aws_region_name
                                  or settings.AWS_SES_REGION_NAME,
                                  endpoint=aws_region_endpoint
                                  or settings.AWS_SES_REGION_ENDPOINT)
        self._throttle = aws_auto_throttle or settings.AWS_SES_AUTO_THROTTLE

        self.dkim_domain = dkim_domain or settings.DKIM_DOMAIN
        self.dkim_key = dkim_key or settings.DKIM_PRIVATE_KEY
        self.dkim_selector = dkim_selector or settings.DKIM_SELECTOR
        self.dkim_headers = dkim_headers or settings.DKIM_HEADERS

        self.connection = None

    def open(self):
        """Create a connection to the AWS API server. This can be reused for
        sending multiple emails.
        """
        if self.connection:
            return False

        try:
            self.connection = SESConnection(
                aws_access_key_id=self._access_key_id,
                aws_secret_access_key=self._access_key,
                region=self._region,
            )
        except:
            if not self.fail_silently:
                raise

    def close(self):
        """Close any open HTTP connections to the API server.
        """
        try:
            self.connection.close()
            self.connection = None
        except:
            if not self.fail_silently:
                raise

    def send_messages(self, email_messages):
        """Sends one or more EmailMessage objects and returns the number of
        email messages sent.
        """
        if not email_messages:
            return

        new_conn_created = self.open()
        if not self.connection:
            # Failed silently
            return

        num_sent = 0
        source = settings.AWS_SES_RETURN_PATH
        for message in email_messages:
            # Automatic throttling. Assumes that this is the only SES client
            # currently operating. The AWS_SES_AUTO_THROTTLE setting is a
            # factor to apply to the rate limit, with a default of 0.5 to stay
            # well below the actual SES throttle.
            # Set the setting to 0 or None to disable throttling.
            if self._throttle:
                global recent_send_times

                now = datetime.now()

                # Get and cache the current SES max-per-second rate limit
                # returned by the SES API.
                rate_limit = self.get_rate_limit()

                # Prune from recent_send_times anything more than a few seconds
                # ago. Even though SES reports a maximum per-second, the way
                # they enforce the limit may not be on a one-second window.
                # To be safe, we use a two-second window (but allow 2 times the
                # rate limit) and then also have a default rate limit factor of
                # 0.5 so that we really limit the one-second amount in two
                # seconds.
                window = 2.0  # seconds
                window_start = now - timedelta(seconds=window)
                new_send_times = []
                for time in recent_send_times:
                    if time > window_start:
                        new_send_times.append(time)
                recent_send_times = new_send_times

                # If the number of recent send times in the last 1/_throttle
                # seconds exceeds the rate limit, add a delay.
                # Since I'm not sure how Amazon determines at exactly what
                # point to throttle, better be safe than sorry and let in, say,
                # half of the allowed rate.
                if len(new_send_times) > rate_limit * window * self._throttle:
                    # Sleep the remainder of the window period.
                    delta = now - new_send_times[0]
                    total_seconds = (delta.microseconds +
                                     (delta.seconds + delta.days * 24 * 3600) *
                                     10**6) / 10**6
                    delay = window - total_seconds
                    if delay > 0:
                        sleep(delay)

                recent_send_times.append(now)
                # end of throttling

            try:
                response = self.connection.send_raw_email(
                    source=source or message.from_email,
                    destinations=message.recipients(),
                    raw_message=unicode(
                        dkim_sign(
                            message.message().as_string(),
                            dkim_key=self.dkim_key,
                            dkim_domain=self.dkim_domain,
                            dkim_selector=self.dkim_selector,
                            dkim_headers=self.dkim_headers,
                        ), 'utf-8'))
                message.extra_headers['status'] = 200
                message.extra_headers['message_id'] = response[
                    'SendRawEmailResponse']['SendRawEmailResult']['MessageId']
                message.extra_headers['request_id'] = response[
                    'SendRawEmailResponse']['ResponseMetadata']['RequestId']
                num_sent += 1
            except SESConnection.ResponseError, err:
                # Store failure information so to post process it if required
                error_keys = [
                    'status', 'reason', 'body', 'request_id', 'error_code',
                    'error_message'
                ]
                for key in error_keys:
                    message.extra_headers[key] = getattr(err, key, None)
                if not self.fail_silently:
                    raise

        if new_conn_created:
            self.close()

        return num_sent
예제 #54
0
class SESBackend(BaseEmailBackend):
    """A Django Email backend that uses Amazon's Simple Email Service.
    """
    def __init__(self, fail_silently=False, *args, **kwargs):
        super(SESBackend, self).__init__(fail_silently=fail_silently,
                                         *args,
                                         **kwargs)

        self._access_key_id = getattr(settings, 'AWS_ACCESS_KEY_ID', None)
        self._access_key = getattr(settings, 'AWS_SECRET_ACCESS_KEY', None)
        self._api_endpoint = getattr(settings, 'AWS_SES_API_HOST',
                                     SESConnection.DefaultHost)

        self.connection = None

    def open(self):
        """Create a connection to the AWS API server. This can be reused for
        sending multiple emails.
        """
        if self.connection:
            return False

        try:
            self.connection = SESConnection(
                aws_access_key_id=self._access_key_id,
                aws_secret_access_key=self._access_key,
                host=self._api_endpoint,
            )
        except:
            if not self.fail_silently:
                raise

    def close(self):
        """Close any open HTTP connections to the API server.
        """
        try:
            self.connection.close()
            self.connection = None
        except:
            if not self.fail_silently:
                raise

    def send_messages(self, email_messages):
        """Sends one or more EmailMessage objects and returns the number of
        email messages sent.
        """
        if not email_messages:
            return

        new_conn_created = self.open()
        if not self.connection:
            # Failed silently
            return

        num_sent = 0
        for message in email_messages:
            try:
                response = self.connection.send_raw_email(
                    source=message.from_email,
                    destinations=message.recipients(),
                    raw_message=message.message().as_string(),
                )
                message.extra_headers['status'] = 200
                message.extra_headers['message_id'] = response[
                    'SendRawEmailResponse']['SendRawEmailResult']['MessageId']
                message.extra_headers['request_id'] = response[
                    'SendRawEmailResponse']['ResponseMetadata']['RequestId']
                num_sent += 1
            except SESConnection.ResponseError, err:
                # Store failure information so you can post process it if required
                error_keys = [
                    'status', 'reason', 'body', 'request_id', 'error_code',
                    'error_message'
                ]
                for key in error_keys:
                    message.extra_headers[key] = getattr(err, key, None)
                if not self.fail_silently:
                    raise

        if new_conn_created:
            self.close()

        return num_sent
예제 #55
0
	def make_connection(self):
		try:
			self.conn = SESConnection(self.aws_id,self.aws_key)
		except Exception:
			self.abort('Failed to establish connection',4)
예제 #56
0
class SESBackend(BaseEmailBackend):
    """A Django Email backend that uses Amazon's Simple Email Service.
    """

    def __init__(self, fail_silently=False, aws_access_key=None,
                 aws_secret_key=None, aws_region_name=None,
                 aws_region_endpoint=None, aws_auto_throttle=None,
                 dkim_domain=None, dkim_key=None, dkim_selector=None,
                 dkim_headers=None, proxy=None, proxy_port=None,
                 proxy_user=None, proxy_pass=None, **kwargs):

        super(SESBackend, self).__init__(fail_silently=fail_silently, **kwargs)
        self._access_key_id = aws_access_key or settings.ACCESS_KEY
        self._access_key = aws_secret_key or settings.SECRET_KEY
        self._region = RegionInfo(
            name=aws_region_name or settings.AWS_SES_REGION_NAME,
            endpoint=aws_region_endpoint or settings.AWS_SES_REGION_ENDPOINT)
        self._throttle = aws_auto_throttle or settings.AWS_SES_AUTO_THROTTLE
        self._proxy = proxy or settings.AWS_SES_PROXY
        self._proxy_port = proxy_port or settings.AWS_SES_PROXY_PORT
        self._proxy_user = proxy_user or settings.AWS_SES_PROXY_USER
        self._proxy_pass = proxy_pass or settings.AWS_SES_PROXY_PASS

        self.dkim_domain = dkim_domain or settings.DKIM_DOMAIN
        self.dkim_key = dkim_key or settings.DKIM_PRIVATE_KEY
        self.dkim_selector = dkim_selector or settings.DKIM_SELECTOR
        self.dkim_headers = dkim_headers or settings.DKIM_HEADERS

        self.connection = None

    def open(self):
        """Create a connection to the AWS API server. This can be reused for
        sending multiple emails.
        """
        if self.connection:
            return False

        try:
            self.connection = SESConnection(
                aws_access_key_id=self._access_key_id,
                aws_secret_access_key=self._access_key,
                region=self._region,
                proxy=self._proxy,
                proxy_port=self._proxy_port,
                proxy_user=self._proxy_user,
                proxy_pass=self._proxy_pass,
            )
        except Exception:
            if not self.fail_silently:
                raise

    def close(self):
        """Close any open HTTP connections to the API server.
        """
        try:
            self.connection.close()
            self.connection = None
        except Exception:
            if not self.fail_silently:
                raise

    def send_messages(self, email_messages):
        """Sends one or more EmailMessage objects and returns the number of
        email messages sent.
        """
        if not email_messages:
            return

        new_conn_created = self.open()
        if not self.connection:
            # Failed silently
            return

        num_sent = 0
        source = settings.AWS_SES_RETURN_PATH
        for message in email_messages:
            # SES Configuration sets. If the AWS_SES_CONFIGURATION_SET setting
            # is not None, append the appropriate header to the message so that
            # SES knows which configuration set it belongs to.
            #
            # If settings.AWS_SES_CONFIGURATION_SET is a callable, pass it the
            # message object and dkim settings and expect it to return a string
            # containing the SES Configuration Set name.
            if (settings.AWS_SES_CONFIGURATION_SET and
                'X-SES-CONFIGURATION-SET' not in message.extra_headers):
                if callable(settings.AWS_SES_CONFIGURATION_SET):
                    message.extra_headers[
                        'X-SES-CONFIGURATION-SET'] = settings.AWS_SES_CONFIGURATION_SET(
                            message,
                            dkim_domain=self.dkim_domain,
                            dkim_key=self.dkim_key,
                            dkim_selector=self.dkim_selector,
                            dkim_headers=self.dkim_headers
                        )
                else:
                    message.extra_headers[
                        'X-SES-CONFIGURATION-SET'] = settings.AWS_SES_CONFIGURATION_SET

            # Automatic throttling. Assumes that this is the only SES client
            # currently operating. The AWS_SES_AUTO_THROTTLE setting is a
            # factor to apply to the rate limit, with a default of 0.5 to stay
            # well below the actual SES throttle.
            # Set the setting to 0 or None to disable throttling.
            if self._throttle:
                global recent_send_times

                now = datetime.now()

                # Get and cache the current SES max-per-second rate limit
                # returned by the SES API.
                rate_limit = self.get_rate_limit()
                logger.debug(u"send_messages.throttle rate_limit='{}'".format(rate_limit))

                # Prune from recent_send_times anything more than a few seconds
                # ago. Even though SES reports a maximum per-second, the way
                # they enforce the limit may not be on a one-second window.
                # To be safe, we use a two-second window (but allow 2 times the
                # rate limit) and then also have a default rate limit factor of
                # 0.5 so that we really limit the one-second amount in two
                # seconds.
                window = 2.0  # seconds
                window_start = now - timedelta(seconds=window)
                new_send_times = []
                for time in recent_send_times:
                    if time > window_start:
                        new_send_times.append(time)
                recent_send_times = new_send_times

                # If the number of recent send times in the last 1/_throttle
                # seconds exceeds the rate limit, add a delay.
                # Since I'm not sure how Amazon determines at exactly what
                # point to throttle, better be safe than sorry and let in, say,
                # half of the allowed rate.
                if len(new_send_times) > rate_limit * window * self._throttle:
                    # Sleep the remainder of the window period.
                    delta = now - new_send_times[0]
                    total_seconds = (delta.microseconds + (delta.seconds +
                                     delta.days * 24 * 3600) * 10**6) / 10**6
                    delay = window - total_seconds
                    if delay > 0:
                        sleep(delay)

                recent_send_times.append(now)
                # end of throttling

            try:
                response = self.connection.send_raw_email(
                    source=source or message.from_email,
                    destinations=message.recipients(),
                    raw_message=dkim_sign(message.message().as_string(),
                                          dkim_key=self.dkim_key,
                                          dkim_domain=self.dkim_domain,
                                          dkim_selector=self.dkim_selector,
                                          dkim_headers=self.dkim_headers)
                )
                message.extra_headers['status'] = 200
                message.extra_headers['message_id'] = response[
                    'SendRawEmailResponse']['SendRawEmailResult']['MessageId']
                message.extra_headers['request_id'] = response[
                    'SendRawEmailResponse']['ResponseMetadata']['RequestId']
                num_sent += 1
                if 'X-SES-CONFIGURATION-SET' in message.extra_headers:
                    logger.debug(u"send_messages.sent from='{}' recipients='{}' message_id='{}' request_id='{}' ses-configuration-set='{}'".format(
                        message.from_email,
                        ", ".join(message.recipients()),
                        message.extra_headers['message_id'],
                        message.extra_headers['request_id'],
                        message.extra_headers['X-SES-CONFIGURATION-SET']
                    ))
                else:
                    logger.debug(u"send_messages.sent from='{}' recipients='{}' message_id='{}' request_id='{}'".format(
                        message.from_email,
                        ", ".join(message.recipients()),
                        message.extra_headers['message_id'],
                        message.extra_headers['request_id']
                    ))

            except SESConnection.ResponseError as err:
                # Store failure information so to post process it if required
                error_keys = ['status', 'reason', 'body', 'request_id',
                              'error_code', 'error_message']
                for key in error_keys:
                    message.extra_headers[key] = getattr(err, key, None)
                if not self.fail_silently:
                    raise

        if new_conn_created:
            self.close()

        return num_sent

    def get_rate_limit(self):
        if self._access_key_id in cached_rate_limits:
            return cached_rate_limits[self._access_key_id]

        new_conn_created = self.open()
        if not self.connection:
            raise Exception(
                "No connection is available to check current SES rate limit.")
        try:
            quota_dict = self.connection.get_send_quota()
            max_per_second = quota_dict['GetSendQuotaResponse'][
                'GetSendQuotaResult']['MaxSendRate']
            ret = float(max_per_second)
            cached_rate_limits[self._access_key_id] = ret
            return ret
        finally:
            if new_conn_created:
                self.close()
예제 #57
0
class SESMessage(object):
    """
    Usage:

    msg = SESMessage('*****@*****.**', '*****@*****.**', 'The subject')
    msg.text = 'Text body'
    msg.html = 'HTML body'
    msg.send()

    """
    def __init__(self, source, to_addresses, subject, **kw):
        self.ses = SESConnection()

        self._source = source
        self._to_addresses = to_addresses
        self._cc_addresses = None
        self._bcc_addresses = None

        self.subject = subject
        self.text = None
        self.html = None
        self.attachments = []

    def send(self):
        if not self.ses:
            raise Exception, 'No connection found'

        if (self.text and not self.html and not self.attachments) or \
           (self.html and not self.text and not self.attachments):
            return self.ses.send_email(self._source,
                                       self.subject,
                                       self.text or self.html,
                                       self._to_addresses,
                                       self._cc_addresses,
                                       self._bcc_addresses,
                                       format='text' if self.text else 'html')
        else:
            if not self.attachments:
                message = MIMEMultipart('alternative')

                message['Subject'] = self.subject
                message['From'] = self._source
                if isinstance(self._to_addresses, (list, tuple)):
                    message['To'] = COMMASPACE.join(self._to_addresses)
                else:
                    message['To'] = self._to_addresses

                message.attach(MIMEText(self.text, 'plain'))
                message.attach(MIMEText(self.html, 'html'))
            else:
                raise NotImplementedError, 'SES does not currently allow ' + \
                                           'messages with attachments.'
#                message = MIMEMultipart()
#
#                message_alt = MIMEMultipart('alternative')
#
#                if self.text:
#                    message_alt.attach(MIMEText(self.text, 'plain'))
#                if self.html:
#                    message_alt.attach(MIMEText(self.html, 'html'))
#
#                message.attach(message_alt)
#
#                message['Subject'] = self.subject
#                message['From'] = self._source
#                if isinstance(self._to_addresses, (list, tuple)):
#                    message['To'] = COMMASPACE.join(self._to_addresses)
#                else:
#                    message['To'] = self._to_addresses
#                message.preamble = 'You will not see this in a MIME-aware mail reader.\n'

#                print 'message: ', message.as_string()

#                for attachment in self.attachments:
#                    # Guess the content type based on the file's extension.  Encoding
#                    # will be ignored, although we should check for simple things like
#                    # gzip'd or compressed files.
#                    ctype, encoding = mimetypes.guess_type(attachment)
#                    if ctype is None or encoding is not None:
#                        # No guess could be made, or the file is encoded (compressed), so
#                        # use a generic bag-of-bits type.
#                        ctype = 'application/octet-stream'
#                    maintype, subtype = ctype.split('/', 1)
#                    if maintype == 'text':
#                        fp = open(attachment)
#                        # Note: we should handle calculating the charset
#                        part = MIMEText(fp.read(), _subtype=subtype)
#                        fp.close()
#                    elif maintype == 'image':
#                        fp = open(attachment, 'rb')
#                        part = MIMEImage(fp.read(), _subtype=subtype)
#                        fp.close()
#                    elif maintype == 'audio':
#                        fp = open(attachment, 'rb')
#                        part = MIMEAudio(fp.read(), _subtype=subtype)
#                        fp.close()
#                    else:
#                        fp = open(attachment, 'rb')
#                        part = MIMEBase(maintype, subtype)
#                        part.set_payload(fp.read())
#                        fp.close()
#                        # Encode the payload using Base64
#                        encoders.encode_base64(part)
#                    # Set the filename parameter
#                    part.add_header('Content-Disposition', 'attachment', filename=attachment)
#                    message.attach(part)

            return self.ses.send_raw_email(self._source,
                                           message.as_string(),
                                           destinations=self._to_addresses)
예제 #58
0
 def startup(self):
     self.connection = SESConnection(aws_access_key_id=self.id,
                                     aws_secret_access_key=self.key,
                                     host=self.host)