Skip to content

Commit

Permalink
Fix admin dashboard broken during boto3 upgrade (#193)
Browse files Browse the repository at this point in the history
  • Loading branch information
charlievrettos committed Sep 7, 2020
1 parent 5664138 commit 3923e7b
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 131 deletions.
37 changes: 12 additions & 25 deletions django_ses/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ def stats_to_list(stats_dict, localize=pytz):
current_tz = None
for dp in result['SendDataPoints']:
if current_tz:
utc_dt = datetime.strptime(dp['Timestamp'], '%Y-%m-%dT%H:%M:%SZ')
utc_dt = localize.utc.localize(utc_dt)
utc_dt = dp['Timestamp']
dp['Timestamp'] = current_tz.normalize(
utc_dt.astimezone(current_tz))
datapoints.append(dp)
Expand All @@ -61,23 +60,12 @@ def stats_to_list(stats_dict, localize=pytz):
return datapoints


def quota_parse(quota_dict):
"""
Parse the output of ``SESConnection.get_send_quota()`` to just the results.
"""
return quota_dict['GetSendQuotaResponse']['GetSendQuotaResult']


def emails_parse(emails_dict):
"""
Parse the output of ``SESConnection.list_verified_emails()`` and get
a list of emails.
"""
result = emails_dict['ListVerifiedEmailAddressesResponse'][
'ListVerifiedEmailAddressesResult']
emails = [email for email in result['VerifiedEmailAddresses']]

return sorted(emails)
return sorted([email for email in emails_dict['VerifiedEmailAddresses']])


def sum_stats(stats_data):
Expand All @@ -90,10 +78,10 @@ def sum_stats(stats_data):
t_delivery_attempts = 0
t_rejects = 0
for dp in stats_data:
t_bounces += int(dp['Bounces'])
t_complaints += int(dp['Complaints'])
t_delivery_attempts += int(dp['DeliveryAttempts'])
t_rejects += int(dp['Rejects'])
t_bounces += dp['Bounces']
t_complaints += dp['Complaints']
t_delivery_attempts += dp['DeliveryAttempts']
t_rejects += dp['Rejects']

return {
'Bounces': t_bounces,
Expand Down Expand Up @@ -125,23 +113,22 @@ def dashboard(request):
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_quota': quota_dict['Max24HourSend'],
'24hour_sent': quota_dict['SentLast24Hours'],
'24hour_remaining':
float(quota['Max24HourSend']) -
float(quota['SentLast24Hours']),
'persecond_rate': quota['MaxSendRate'],
quota_dict['Max24HourSend'] -
quota_dict['SentLast24Hours'],
'persecond_rate': quota_dict['MaxSendRate'],
'verified_emails': verified_emails,
'summary': summary,
'access_key': ses_conn.gs_access_key_id,
'access_key': settings.ACCESS_KEY,
'local_time': True,
}

Expand Down
208 changes: 102 additions & 106 deletions tests/test_stats.py
Original file line number Diff line number Diff line change
@@ -1,165 +1,161 @@
import pytz
from datetime import datetime

from django.test import TestCase

from django_ses.views import (emails_parse, stats_to_list, quota_parse,
sum_stats)
from django_ses.views import emails_parse, stats_to_list, sum_stats

# Mock of what boto's SESConnection.get_send_statistics() returns
STATS_DICT = {
u'SendDataPoints': [
{
u'Bounces': u'1',
u'Complaints': u'0',
u'DeliveryAttempts': u'11',
u'Rejects': u'0',
u'Timestamp': u'2011-02-28T13:50:00Z',
u'Bounces': 1,
u'Complaints': 0,
u'DeliveryAttempts': 11,
u'Rejects': 0,
u'Timestamp':
datetime(2011, 2, 28, 13, 50, tzinfo=pytz.utc),
},
{
u'Bounces': u'1',
u'Complaints': u'0',
u'DeliveryAttempts': u'3',
u'Rejects': u'0',
u'Timestamp': u'2011-02-24T23:35:00Z',
u'Bounces': 1,
u'Complaints': 0,
u'DeliveryAttempts': 3,
u'Rejects': 0,
u'Timestamp':
datetime(2011, 2, 24, 23, 35, tzinfo=pytz.utc),
},
{
u'Bounces': u'0',
u'Complaints': u'2',
u'DeliveryAttempts': u'8',
u'Rejects': u'0',
u'Timestamp': u'2011-02-24T16:35:00Z',
u'Bounces': 0,
u'Complaints': 2,
u'DeliveryAttempts': 8,
u'Rejects': 0,
u'Timestamp':
datetime(2011, 2, 24, 16, 35, tzinfo=pytz.utc),
},
{
u'Bounces': u'0',
u'Complaints': u'2',
u'DeliveryAttempts': u'33',
u'Rejects': u'0',
u'Timestamp': u'2011-02-25T20:35:00Z',
u'Bounces': 0,
u'Complaints': 2,
u'DeliveryAttempts': 33,
u'Rejects': 0,
u'Timestamp':
datetime(2011, 2, 25, 20, 35, tzinfo=pytz.utc),
},
{
u'Bounces': u'0',
u'Complaints': u'0',
u'DeliveryAttempts': u'3',
u'Rejects': u'3',
u'Timestamp': u'2011-02-28T23:35:00Z',
u'Bounces': 0,
u'Complaints': 0,
u'DeliveryAttempts': 3,
u'Rejects': 3,
u'Timestamp':
datetime(2011, 2, 28, 23, 35, tzinfo=pytz.utc),
},
{
u'Bounces': u'0',
u'Complaints': u'0',
u'DeliveryAttempts': u'2',
u'Rejects': u'3',
u'Timestamp': u'2011-02-25T22:50:00Z',
u'Bounces': 0,
u'Complaints': 0,
u'DeliveryAttempts': 2,
u'Rejects': 3,
u'Timestamp':
datetime(2011, 2, 25, 22, 50, tzinfo=pytz.utc),
},
{
u'Bounces': u'0',
u'Complaints': u'0',
u'DeliveryAttempts': u'6',
u'Rejects': u'0',
u'Timestamp': u'2011-03-01T13:20:00Z',
u'Bounces': 0,
u'Complaints': 0,
u'DeliveryAttempts': 6,
u'Rejects': 0,
u'Timestamp':
datetime(2011, 3, 1, 13, 20, tzinfo=pytz.utc),
},
],
}

QUOTA_DICT = {
u'GetSendQuotaResponse': {
u'GetSendQuotaResult': {
u'Max24HourSend': u'10000.0',
u'MaxSendRate': u'5.0',
u'SentLast24Hours': u'1677.0'
},
u'ResponseMetadata': {
u'RequestId': u'8f100233-44e7-11e0-a926-a198963635d8'
}
}
}

VERIFIED_EMAIL_DICT = {
u'ListVerifiedEmailAddressesResponse': {
u'ListVerifiedEmailAddressesResult': {
u'VerifiedEmailAddresses': [
u'test2@example.com',
u'test1@example.com',
u'test3@example.com'
]
u'VerifiedEmailAddresses': [
u'test2@example.com',
u'test1@example.com',
u'test3@example.com'
],
u'ResponseMetadata': {
u'RequestId': u'9afe9c18-44ed-11e0-802a-25a1a14c5a6e',
u'HTTPStatusCode': 200,
u'HTTPHeaders': {
u'x-amzn-requestid': u'9afe9c18-44ed-11e0-802a-25a1a14c5a6e',
u'content-type': u'text/xml',
u'content-length': u'536',
u'date': u'Thu, 20 Aug 2020 05:06:35 GMT'
},
u'ResponseMetadata': {
u'RequestId': u'9afe9c18-44ed-11e0-802a-25a1a14c5a6e'
}
u'RetryAttempts': 0
}
}


class StatParsingTest(TestCase):
def setUp(self):
self.stats_dict = STATS_DICT
self.quota_dict = QUOTA_DICT
self.emails_dict = VERIFIED_EMAIL_DICT

def test_stat_to_list(self):
expected_list = [
{
u'Bounces': u'0',
u'Complaints': u'2',
u'DeliveryAttempts': u'8',
u'Rejects': u'0',
u'Timestamp': u'2011-02-24T16:35:00Z',
u'Bounces': 0,
u'Complaints': 2,
u'DeliveryAttempts': 8,
u'Rejects': 0,
u'Timestamp':
datetime(2011, 2, 24, 16, 35, tzinfo=pytz.utc),
},
{
u'Bounces': u'1',
u'Complaints': u'0',
u'DeliveryAttempts': u'3',
u'Rejects': u'0',
u'Timestamp': u'2011-02-24T23:35:00Z',
u'Bounces': 1,
u'Complaints': 0,
u'DeliveryAttempts': 3,
u'Rejects': 0,
u'Timestamp':
datetime(2011, 2, 24, 23, 35, tzinfo=pytz.utc),
},
{
u'Bounces': u'0',
u'Complaints': u'2',
u'DeliveryAttempts': u'33',
u'Rejects': u'0',
u'Timestamp': u'2011-02-25T20:35:00Z',
u'Bounces': 0,
u'Complaints': 2,
u'DeliveryAttempts': 33,
u'Rejects': 0,
u'Timestamp':
datetime(2011, 2, 25, 20, 35, tzinfo=pytz.utc),
},
{
u'Bounces': u'0',
u'Complaints': u'0',
u'DeliveryAttempts': u'2',
u'Rejects': u'3',
u'Timestamp': u'2011-02-25T22:50:00Z',
u'Bounces': 0,
u'Complaints': 0,
u'DeliveryAttempts': 2,
u'Rejects': 3,
u'Timestamp':
datetime(2011, 2, 25, 22, 50, tzinfo=pytz.utc),
},
{
u'Bounces': u'1',
u'Complaints': u'0',
u'DeliveryAttempts': u'11',
u'Rejects': u'0',
u'Timestamp': u'2011-02-28T13:50:00Z',
u'Bounces': 1,
u'Complaints': 0,
u'DeliveryAttempts': 11,
u'Rejects': 0,
u'Timestamp':
datetime(2011, 2, 28, 13, 50, tzinfo=pytz.utc),
},
{
u'Bounces': u'0',
u'Complaints': u'0',
u'DeliveryAttempts': u'3',
u'Rejects': u'3',
u'Timestamp': u'2011-02-28T23:35:00Z',
u'Bounces': 0,
u'Complaints': 0,
u'DeliveryAttempts': 3,
u'Rejects': 3,
u'Timestamp':
datetime(2011, 2, 28, 23, 35, tzinfo=pytz.utc),
},
{
u'Bounces': u'0',
u'Complaints': u'0',
u'DeliveryAttempts': u'6',
u'Rejects': u'0',
u'Timestamp': u'2011-03-01T13:20:00Z',
u'Bounces': 0,
u'Complaints': 0,
u'DeliveryAttempts': 6,
u'Rejects': 0,
u'Timestamp':
datetime(2011, 3, 1, 13, 20, tzinfo=pytz.utc),
},
]
actual = stats_to_list(self.stats_dict, localize=False)

self.assertEqual(len(actual), len(expected_list))
self.assertEqual(actual, expected_list)

def test_quota_parse(self):
expected = {
u'Max24HourSend': u'10000.0',
u'MaxSendRate': u'5.0',
u'SentLast24Hours': u'1677.0',
}
actual = quota_parse(self.quota_dict)

self.assertEqual(actual, expected)

def test_emails_parse(self):
expected_list = [
u'test1@example.com',
Expand Down

0 comments on commit 3923e7b

Please sign in to comment.