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

Side by Side Diff: third_party/gsutil/20110627/boto/boto/s3/multipart.py

Issue 10199002: Upgrade gsutil to 3.4 (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed comments Created 8 years, 7 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 # Copyright (c) 2006-2010 Mitch Garnaat http://garnaat.org/
2 # Copyright (c) 2010, Eucalyptus Systems, Inc.
3 #
4 # Permission is hereby granted, free of charge, to any person obtaining a
5 # copy of this software and associated documentation files (the
6 # "Software"), to deal in the Software without restriction, including
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
9 # persons to whom the Software is furnished to do so, subject to the fol-
10 # lowing conditions:
11 #
12 # The above copyright notice and this permission notice shall be included
13 # in all copies or substantial portions of the Software.
14 #
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
17 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
18 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 # IN THE SOFTWARE.
22
23 import user
24 import key
25 from boto import handler
26 import xml.sax
27
28 class CompleteMultiPartUpload(object):
29 """
30 Represents a completed MultiPart Upload. Contains the
31 following useful attributes:
32
33 * location - The URI of the completed upload
34 * bucket_name - The name of the bucket in which the upload
35 is contained
36 * key_name - The name of the new, completed key
37 * etag - The MD5 hash of the completed, combined upload
38 """
39
40 def __init__(self, bucket=None):
41 self.bucket = None
42 self.location = None
43 self.bucket_name = None
44 self.key_name = None
45 self.etag = None
46
47 def __repr__(self):
48 return '<CompleteMultiPartUpload: %s.%s>' % (self.bucket_name,
49 self.key_name)
50
51 def startElement(self, name, attrs, connection):
52 return None
53
54 def endElement(self, name, value, connection):
55 if name == 'Location':
56 self.location = value
57 elif name == 'Bucket':
58 self.bucket_name = value
59 elif name == 'Key':
60 self.key_name = value
61 elif name == 'ETag':
62 self.etag = value
63 else:
64 setattr(self, name, value)
65
66 class Part(object):
67 """
68 Represents a single part in a MultiPart upload.
69 Attributes include:
70
71 * part_number - The integer part number
72 * last_modified - The last modified date of this part
73 * etag - The MD5 hash of this part
74 * size - The size, in bytes, of this part
75 """
76
77 def __init__(self, bucket=None):
78 self.bucket = bucket
79 self.part_number = None
80 self.last_modified = None
81 self.etag = None
82 self.size = None
83
84 def __repr__(self):
85 if isinstance(self.part_number, int):
86 return '<Part %d>' % self.part_number
87 else:
88 return '<Part %s>' % None
89
90 def startElement(self, name, attrs, connection):
91 return None
92
93 def endElement(self, name, value, connection):
94 if name == 'PartNumber':
95 self.part_number = int(value)
96 elif name == 'LastModified':
97 self.last_modified = value
98 elif name == 'ETag':
99 self.etag = value
100 elif name == 'Size':
101 self.size = int(value)
102 else:
103 setattr(self, name, value)
104
105 def part_lister(mpupload, part_number_marker=None):
106 """
107 A generator function for listing parts of a multipart upload.
108 """
109 more_results = True
110 part = None
111 while more_results:
112 parts = mpupload.get_all_parts(None, part_number_marker)
113 for part in parts:
114 yield part
115 part_number_marker = mpupload.next_part_number_marker
116 more_results= mpupload.is_truncated
117
118 class MultiPartUpload(object):
119 """
120 Represents a MultiPart Upload operation.
121 """
122
123 def __init__(self, bucket=None):
124 self.bucket = bucket
125 self.bucket_name = None
126 self.key_name = None
127 self.id = id
128 self.initiator = None
129 self.owner = None
130 self.storage_class = None
131 self.initiated = None
132 self.part_number_marker = None
133 self.next_part_number_marker = None
134 self.max_parts = None
135 self.is_truncated = False
136 self._parts = None
137
138 def __repr__(self):
139 return '<MultiPartUpload %s>' % self.key_name
140
141 def __iter__(self):
142 return part_lister(self)
143
144 def to_xml(self):
145 self.get_all_parts()
146 s = '<CompleteMultipartUpload>\n'
147 for part in self:
148 s += ' <Part>\n'
149 s += ' <PartNumber>%d</PartNumber>\n' % part.part_number
150 s += ' <ETag>%s</ETag>\n' % part.etag
151 s += ' </Part>\n'
152 s += '</CompleteMultipartUpload>'
153 return s
154
155 def startElement(self, name, attrs, connection):
156 if name == 'Initiator':
157 self.initiator = user.User(self)
158 return self.initiator
159 elif name == 'Owner':
160 self.owner = user.User(self)
161 return self.owner
162 elif name == 'Part':
163 part = Part(self.bucket)
164 self._parts.append(part)
165 return part
166 return None
167
168 def endElement(self, name, value, connection):
169 if name == 'Bucket':
170 self.bucket_name = value
171 elif name == 'Key':
172 self.key_name = value
173 elif name == 'UploadId':
174 self.id = value
175 elif name == 'StorageClass':
176 self.storage_class = value
177 elif name == 'PartNumberMarker':
178 self.part_number_marker = value
179 elif name == 'NextPartNumberMarker':
180 self.next_part_number_marker = value
181 elif name == 'MaxParts':
182 self.max_parts = int(value)
183 elif name == 'IsTruncated':
184 if value == 'true':
185 self.is_truncated = True
186 else:
187 self.is_truncated = False
188 else:
189 setattr(self, name, value)
190
191 def get_all_parts(self, max_parts=None, part_number_marker=None):
192 """
193 Return the uploaded parts of this MultiPart Upload. This is
194 a lower-level method that requires you to manually page through
195 results. To simplify this process, you can just use the
196 object itself as an iterator and it will automatically handle
197 all of the paging with S3.
198 """
199 self._parts = []
200 query_args = 'uploadId=%s' % self.id
201 if max_parts:
202 query_args += '&max_parts=%d' % max_parts
203 if part_number_marker:
204 query_args += '&part-number-marker=%s' % part_number_marker
205 response = self.bucket.connection.make_request('GET', self.bucket.name,
206 self.key_name,
207 query_args=query_args)
208 body = response.read()
209 if response.status == 200:
210 h = handler.XmlHandler(self, self)
211 xml.sax.parseString(body, h)
212 return self._parts
213
214 def upload_part_from_file(self, fp, part_num, headers=None, replace=True,
215 cb=None, num_cb=10, policy=None, md5=None):
216 """
217 Upload another part of this MultiPart Upload.
218
219 :type fp: file
220 :param fp: The file object you want to upload.
221
222 :type part_num: int
223 :param part_num: The number of this part.
224
225 The other parameters are exactly as defined for the
226 :class:`boto.s3.key.Key` set_contents_from_file method.
227 """
228 if part_num < 1:
229 raise ValueError('Part numbers must be greater than zero')
230 query_args = 'uploadId=%s&partNumber=%d' % (self.id, part_num)
231 key = self.bucket.new_key(self.key_name)
232 key.set_contents_from_file(fp, headers, replace, cb, num_cb, policy,
233 md5, reduced_redundancy=False,
234 query_args=query_args)
235
236 def complete_upload(self):
237 """
238 Complete the MultiPart Upload operation. This method should
239 be called when all parts of the file have been successfully
240 uploaded to S3.
241
242 :rtype: :class:`boto.s3.multipart.CompletedMultiPartUpload`
243 :returns: An object representing the completed upload.
244 """
245 xml = self.to_xml()
246 return self.bucket.complete_multipart_upload(self.key_name,
247 self.id, xml)
248
249 def cancel_upload(self):
250 """
251 Cancels a MultiPart Upload operation. The storage consumed by
252 any previously uploaded parts will be freed. However, if any
253 part uploads are currently in progress, those part uploads
254 might or might not succeed. As a result, it might be necessary
255 to abort a given multipart upload multiple times in order to
256 completely free all storage consumed by all parts.
257 """
258 self.bucket.cancel_multipart_upload(self.key_name, self.id)
259
260
OLDNEW
« no previous file with comments | « third_party/gsutil/20110627/boto/boto/s3/key.py ('k') | third_party/gsutil/20110627/boto/boto/s3/prefix.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698