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

Side by Side Diff: third_party/gsutil/boto/sqs/message.py

Issue 12042069: Scripts to download files from google storage based on sha1 sums (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Removed gsutil/tests and gsutil/docs Created 7 years, 10 months 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
OLDNEW
(Empty)
1 # Copyright (c) 2006,2007 Mitch Garnaat http://garnaat.org/
2 #
3 # Permission is hereby granted, free of charge, to any person obtaining a
4 # copy of this software and associated documentation files (the
5 # "Software"), to deal in the Software without restriction, including
6 # without limitation the rights to use, copy, modify, merge, publish, dis-
7 # tribute, sublicense, and/or sell copies of the Software, and to permit
8 # persons to whom the Software is furnished to do so, subject to the fol-
9 # lowing conditions:
10 #
11 # The above copyright notice and this permission notice shall be included
12 # in all copies or substantial portions of the Software.
13 #
14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
16 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
17 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 # IN THE SOFTWARE.
21
22 """
23 SQS Message
24
25 A Message represents the data stored in an SQS queue. The rules for what is all owed within an SQS
26 Message are here:
27
28 http://docs.amazonwebservices.com/AWSSimpleQueueService/2008-01-01/SQSDevelo perGuide/Query_QuerySendMessage.html
29
30 So, at it's simplest level a Message just needs to allow a developer to store by tes in it and get the bytes
31 back out. However, to allow messages to have richer semantics, the Message clas s must support the
32 following interfaces:
33
34 The constructor for the Message class must accept a keyword parameter "queue" wh ich is an instance of a
35 boto Queue object and represents the queue that the message will be stored in. The default value for
36 this parameter is None.
37
38 The constructor for the Message class must accept a keyword parameter "body" whi ch represents the
39 content or body of the message. The format of this parameter will depend on the behavior of the
40 particular Message subclass. For example, if the Message subclass provides dict ionary-like behavior to the
41 user the body passed to the constructor should be a dict-like object that can be used to populate
42 the initial state of the message.
43
44 The Message class must provide an encode method that accepts a value of the same type as the body
45 parameter of the constructor and returns a string of characters that are able to be stored in an
46 SQS message body (see rules above).
47
48 The Message class must provide a decode method that accepts a string of characte rs that can be
49 stored (and probably were stored!) in an SQS message and return an object of a t ype that is consistent
50 with the "body" parameter accepted on the class constructor.
51
52 The Message class must provide a __len__ method that will return the size of the encoded message
53 that would be stored in SQS based on the current state of the Message object.
54
55 The Message class must provide a get_body method that will return the body of th e message in the
56 same format accepted in the constructor of the class.
57
58 The Message class must provide a set_body method that accepts a message body in the same format
59 accepted by the constructor of the class. This method should alter to the inter nal state of the
60 Message object to reflect the state represented in the message body parameter.
61
62 The Message class must provide a get_body_encoded method that returns the curren t body of the message
63 in the format in which it would be stored in SQS.
64 """
65
66 import base64
67 import StringIO
68 from boto.sqs.attributes import Attributes
69 from boto.exception import SQSDecodeError
70 import boto
71
72 class RawMessage:
73 """
74 Base class for SQS messages. RawMessage does not encode the message
75 in any way. Whatever you store in the body of the message is what
76 will be written to SQS and whatever is returned from SQS is stored
77 directly into the body of the message.
78 """
79
80 def __init__(self, queue=None, body=''):
81 self.queue = queue
82 self.set_body(body)
83 self.id = None
84 self.receipt_handle = None
85 self.md5 = None
86 self.attributes = Attributes(self)
87
88 def __len__(self):
89 return len(self.encode(self._body))
90
91 def startElement(self, name, attrs, connection):
92 if name == 'Attribute':
93 return self.attributes
94 return None
95
96 def endElement(self, name, value, connection):
97 if name == 'Body':
98 self.set_body(self.decode(value))
99 elif name == 'MessageId':
100 self.id = value
101 elif name == 'ReceiptHandle':
102 self.receipt_handle = value
103 elif name == 'MD5OfMessageBody':
104 self.md5 = value
105 else:
106 setattr(self, name, value)
107
108 def encode(self, value):
109 """Transform body object into serialized byte array format."""
110 return value
111
112 def decode(self, value):
113 """Transform seralized byte array into any object."""
114 return value
115
116 def set_body(self, body):
117 """Override the current body for this object, using decoded format."""
118 self._body = body
119
120 def get_body(self):
121 return self._body
122
123 def get_body_encoded(self):
124 """
125 This method is really a semi-private method used by the Queue.write
126 method when writing the contents of the message to SQS.
127 You probably shouldn't need to call this method in the normal course of events.
128 """
129 return self.encode(self.get_body())
130
131 def delete(self):
132 if self.queue:
133 return self.queue.delete_message(self)
134
135 def change_visibility(self, visibility_timeout):
136 if self.queue:
137 self.queue.connection.change_message_visibility(self.queue,
138 self.receipt_handle,
139 visibility_timeout)
140
141 class Message(RawMessage):
142 """
143 The default Message class used for SQS queues. This class automatically
144 encodes/decodes the message body using Base64 encoding to avoid any
145 illegal characters in the message body. See:
146
147 http://developer.amazonwebservices.com/connect/thread.jspa?messageID=49680%E C%88%90
148
149 for details on why this is a good idea. The encode/decode is meant to
150 be transparent to the end-user.
151 """
152
153 def encode(self, value):
154 return base64.b64encode(value)
155
156 def decode(self, value):
157 try:
158 value = base64.b64decode(value)
159 except:
160 boto.log.warning('Unable to decode message')
161 return value
162 return value
163
164 class MHMessage(Message):
165 """
166 The MHMessage class provides a message that provides RFC821-like
167 headers like this:
168
169 HeaderName: HeaderValue
170
171 The encoding/decoding of this is handled automatically and after
172 the message body has been read, the message instance can be treated
173 like a mapping object, i.e. m['HeaderName'] would return 'HeaderValue'.
174 """
175
176 def __init__(self, queue=None, body=None, xml_attrs=None):
177 if body == None or body == '':
178 body = {}
179 Message.__init__(self, queue, body)
180
181 def decode(self, value):
182 try:
183 msg = {}
184 fp = StringIO.StringIO(value)
185 line = fp.readline()
186 while line:
187 delim = line.find(':')
188 key = line[0:delim]
189 value = line[delim+1:].strip()
190 msg[key.strip()] = value.strip()
191 line = fp.readline()
192 except:
193 raise SQSDecodeError('Unable to decode message', self)
194 return msg
195
196 def encode(self, value):
197 s = ''
198 for item in value.items():
199 s = s + '%s: %s\n' % (item[0], item[1])
200 return s
201
202 def __getitem__(self, key):
203 if key in self._body:
204 return self._body[key]
205 else:
206 raise KeyError(key)
207
208 def __setitem__(self, key, value):
209 self._body[key] = value
210 self.set_body(self._body)
211
212 def keys(self):
213 return self._body.keys()
214
215 def values(self):
216 return self._body.values()
217
218 def items(self):
219 return self._body.items()
220
221 def has_key(self, key):
222 return key in self._body
223
224 def update(self, d):
225 self._body.update(d)
226 self.set_body(self._body)
227
228 def get(self, key, default=None):
229 return self._body.get(key, default)
230
231 class EncodedMHMessage(MHMessage):
232 """
233 The EncodedMHMessage class provides a message that provides RFC821-like
234 headers like this:
235
236 HeaderName: HeaderValue
237
238 This variation encodes/decodes the body of the message in base64 automatical ly.
239 The message instance can be treated like a mapping object,
240 i.e. m['HeaderName'] would return 'HeaderValue'.
241 """
242
243 def decode(self, value):
244 try:
245 value = base64.b64decode(value)
246 except:
247 raise SQSDecodeError('Unable to decode message', self)
248 return MHMessage.decode(self, value)
249
250 def encode(self, value):
251 value = MHMessage.encode(self, value)
252 return base64.b64encode(value)
253
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698