Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Side by Side Diff: boto/ses/connection.py

Issue 8669001: Pull in upstream boto from github at bcb719937de9ac2851e632d62b777352029a6d55 (Closed) Base URL: svn://svn.chromium.org/boto
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « boto/sdb/__init__.py ('k') | boto/ses/exceptions.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2010 Mitch Garnaat http://garnaat.org/ 1 # Copyright (c) 2010 Mitch Garnaat http://garnaat.org/
2 # Copyright (c) 2011 Harry Marr http://hmarr.com/ 2 # Copyright (c) 2011 Harry Marr http://hmarr.com/
3 # 3 #
4 # Permission is hereby granted, free of charge, to any person obtaining a 4 # Permission is hereby granted, free of charge, to any person obtaining a
5 # copy of this software and associated documentation files (the 5 # copy of this software and associated documentation files (the
6 # "Software"), to deal in the Software without restriction, including 6 # "Software"), to deal in the Software without restriction, including
7 # without limitation the rights to use, copy, modify, merge, publish, dis- 7 # without limitation the rights to use, copy, modify, merge, publish, dis-
8 # tribute, sublicense, and/or sell copies of the Software, and to permit 8 # tribute, sublicense, and/or sell copies of the Software, and to permit
9 # persons to whom the Software is furnished to do so, subject to the fol- 9 # persons to whom the Software is furnished to do so, subject to the fol-
10 # lowing conditions: 10 # lowing conditions:
(...skipping 10 matching lines...) Expand all
21 # IN THE SOFTWARE. 21 # IN THE SOFTWARE.
22 22
23 from boto.connection import AWSAuthConnection 23 from boto.connection import AWSAuthConnection
24 from boto.exception import BotoServerError 24 from boto.exception import BotoServerError
25 from boto.regioninfo import RegionInfo 25 from boto.regioninfo import RegionInfo
26 import boto 26 import boto
27 import boto.jsonresponse 27 import boto.jsonresponse
28 28
29 import urllib 29 import urllib
30 import base64 30 import base64
31 from boto.ses import exceptions as ses_exceptions
31 32
32 33
33 class SESConnection(AWSAuthConnection): 34 class SESConnection(AWSAuthConnection):
34 35
35 ResponseError = BotoServerError 36 ResponseError = BotoServerError
36 DefaultRegionName = 'us-east-1' 37 DefaultRegionName = 'us-east-1'
37 DefaultRegionEndpoint = 'email.us-east-1.amazonaws.com' 38 DefaultRegionEndpoint = 'email.us-east-1.amazonaws.com'
38 APIVersion = '2010-12-01' 39 APIVersion = '2010-12-01'
39 40
40 def __init__(self, aws_access_key_id=None, aws_secret_access_key=None, 41 def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
(...skipping 23 matching lines...) Expand all
64 :param items: Items to be included in the list 65 :param items: Items to be included in the list
65 66
66 :type label: string 67 :type label: string
67 :param label: The parameter list's name 68 :param label: The parameter list's name
68 """ 69 """
69 if isinstance(items, basestring): 70 if isinstance(items, basestring):
70 items = [items] 71 items = [items]
71 for i in range(1, len(items) + 1): 72 for i in range(1, len(items) + 1):
72 params['%s.%d' % (label, i)] = items[i - 1] 73 params['%s.%d' % (label, i)] = items[i - 1]
73 74
74
75 def _make_request(self, action, params=None): 75 def _make_request(self, action, params=None):
76 """Make a call to the SES API. 76 """Make a call to the SES API.
77 77
78 :type action: string 78 :type action: string
79 :param action: The API method to use (e.g. SendRawEmail) 79 :param action: The API method to use (e.g. SendRawEmail)
80 80
81 :type params: dict 81 :type params: dict
82 :param params: Parameters that will be sent as POST data with the API 82 :param params: Parameters that will be sent as POST data with the API
83 call. 83 call.
84 """ 84 """
85 ct = 'application/x-www-form-urlencoded; charset=UTF-8' 85 ct = 'application/x-www-form-urlencoded; charset=UTF-8'
86 headers = {'Content-Type': ct} 86 headers = {'Content-Type': ct}
87 params = params or {} 87 params = params or {}
88 params['Action'] = action 88 params['Action'] = action
89 89
90 for k, v in params.items(): 90 for k, v in params.items():
91 if isinstance(v, unicode): # UTF-8 encode only if it's Unicode 91 if isinstance(v, unicode): # UTF-8 encode only if it's Unicode
92 params[k] = v.encode('utf-8') 92 params[k] = v.encode('utf-8')
93 93
94 response = super(SESConnection, self).make_request( 94 response = super(SESConnection, self).make_request(
95 'POST', 95 'POST',
96 '/', 96 '/',
97 headers=headers, 97 headers=headers,
98 data=urllib.urlencode(params) 98 data=urllib.urlencode(params)
99 ) 99 )
100 body = response.read() 100 body = response.read()
101 if response.status == 200: 101 if response.status == 200:
102 list_markers = ('VerifiedEmailAddresses', 'SendDataPoints') 102 list_markers = ('VerifiedEmailAddresses', 'SendDataPoints')
103 e = boto.jsonresponse.Element(list_marker=list_markers) 103 e = boto.jsonresponse.Element(list_marker=list_markers)
104 h = boto.jsonresponse.XmlHandler(e, None) 104 h = boto.jsonresponse.XmlHandler(e, None)
105 h.parse(body) 105 h.parse(body)
106 return e 106 return e
107 else: 107 else:
108 boto.log.error('%s %s' % (response.status, response.reason)) 108 # HTTP codes other than 200 are considered errors. Go through
109 boto.log.error('%s' % body) 109 # some error handling to determine which exception gets raised,
110 raise self.ResponseError(response.status, response.reason, body) 110 self._handle_error(response, body)
111 111
112 def _handle_error(self, response, body):
113 """
114 Handle raising the correct exception, depending on the error. Many
115 errors share the same HTTP response code, meaning we have to get really
116 kludgey and do string searches to figure out what went wrong.
117 """
118 boto.log.error('%s %s' % (response.status, response.reason))
119 boto.log.error('%s' % body)
120
121 if "Address blacklisted." in body:
122 # Delivery failures happened frequently enough with the recipient's
123 # email address for Amazon to blacklist it. After a day or three,
124 # they'll be automatically removed, and delivery can be attempted
125 # again (if you write the code to do so in your application).
126 ExceptionToRaise = ses_exceptions.SESAddressBlacklistedError
127 exc_reason = "Address blacklisted."
128 elif "Email address is not verified." in body:
129 # This error happens when the "Reply-To" value passed to
130 # send_email() hasn't been verified yet.
131 ExceptionToRaise = ses_exceptions.SESAddressNotVerifiedError
132 exc_reason = "Email address is not verified."
133 elif "Daily message quota exceeded." in body:
134 # Encountered when your account exceeds the maximum total number
135 # of emails per 24 hours.
136 ExceptionToRaise = ses_exceptions.SESDailyQuotaExceededError
137 exc_reason = "Daily message quota exceeded."
138 elif "Maximum sending rate exceeded." in body:
139 # Your account has sent above its allowed requests a second rate.
140 ExceptionToRaise = ses_exceptions.SESMaxSendingRateExceededError
141 exc_reason = "Maximum sending rate exceeded."
142 else:
143 # This is either a common AWS error, or one that we don't devote
144 # its own exception to.
145 ExceptionToRaise = self.ResponseError
146 exc_reason = response.reason
147
148 raise ExceptionToRaise(response.status, exc_reason, body)
112 149
113 def send_email(self, source, subject, body, to_addresses, cc_addresses=None, 150 def send_email(self, source, subject, body, to_addresses, cc_addresses=None,
114 bcc_addresses=None, format='text', reply_addresses=None, 151 bcc_addresses=None, format='text', reply_addresses=None,
115 return_path=None, text_body=None, html_body=None): 152 return_path=None, text_body=None, html_body=None):
116 """Composes an email message based on input data, and then immediately 153 """Composes an email message based on input data, and then immediately
117 queues the message for sending. 154 queues the message for sending.
118 155
119 :type source: string 156 :type source: string
120 :param source: The sender's email address. 157 :param source: The sender's email address.
121 158
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 Refer to the Amazon SES Developer Guide for more details. 269 Refer to the Amazon SES Developer Guide for more details.
233 - Content must be base64-encoded, if MIME requires it. 270 - Content must be base64-encoded, if MIME requires it.
234 271
235 :type destinations: list of strings or string 272 :type destinations: list of strings or string
236 :param destinations: A list of destinations for the message. 273 :param destinations: A list of destinations for the message.
237 274
238 """ 275 """
239 params = { 276 params = {
240 'RawMessage.Data': base64.b64encode(raw_message), 277 'RawMessage.Data': base64.b64encode(raw_message),
241 } 278 }
242 279
243 if source: 280 if source:
244 params['Source'] = source 281 params['Source'] = source
245 282
246 if destinations: 283 if destinations:
247 self._build_list_params(params, destinations, 284 self._build_list_params(params, destinations,
248 'Destinations.member') 285 'Destinations.member')
249 286
250 return self._make_request('SendRawEmail', params) 287 return self._make_request('SendRawEmail', params)
251 288
252 def list_verified_email_addresses(self): 289 def list_verified_email_addresses(self):
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 :type email_adddress: string 340 :type email_adddress: string
304 :param email_address: The email address to be verified. 341 :param email_address: The email address to be verified.
305 342
306 :rtype: dict 343 :rtype: dict
307 :returns: A VerifyEmailAddressResponse structure. Note that keys must 344 :returns: A VerifyEmailAddressResponse structure. Note that keys must
308 be unicode strings. 345 be unicode strings.
309 """ 346 """
310 return self._make_request('VerifyEmailAddress', { 347 return self._make_request('VerifyEmailAddress', {
311 'EmailAddress': email_address, 348 'EmailAddress': email_address,
312 }) 349 })
OLDNEW
« no previous file with comments | « boto/sdb/__init__.py ('k') | boto/ses/exceptions.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698