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

Side by Side Diff: third_party/boto/gs/key.py

Issue 12633019: Added boto/ to depot_tools/third_party (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: Moved boto down by one Created 7 years, 9 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
« no previous file with comments | « third_party/boto/gs/cors.py ('k') | third_party/boto/gs/resumable_upload_handler.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Copyright 2010 Google Inc.
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 import base64
23 import binascii
24 import os
25 import re
26 import StringIO
27 from boto.exception import BotoClientError
28 from boto.s3.key import Key as S3Key
29 from boto.s3.keyfile import KeyFile
30
31 class Key(S3Key):
32 """
33 Represents a key (object) in a GS bucket.
34
35 :ivar bucket: The parent :class:`boto.gs.bucket.Bucket`.
36 :ivar name: The name of this Key object.
37 :ivar metadata: A dictionary containing user metadata that you
38 wish to store with the object or that has been retrieved from
39 an existing object.
40 :ivar cache_control: The value of the `Cache-Control` HTTP header.
41 :ivar content_type: The value of the `Content-Type` HTTP header.
42 :ivar content_encoding: The value of the `Content-Encoding` HTTP header.
43 :ivar content_disposition: The value of the `Content-Disposition` HTTP
44 header.
45 :ivar content_language: The value of the `Content-Language` HTTP header.
46 :ivar etag: The `etag` associated with this object.
47 :ivar last_modified: The string timestamp representing the last
48 time this object was modified in GS.
49 :ivar owner: The ID of the owner of this object.
50 :ivar storage_class: The storage class of the object. Currently, one of:
51 STANDARD | DURABLE_REDUCED_AVAILABILITY.
52 :ivar md5: The MD5 hash of the contents of the object.
53 :ivar size: The size, in bytes, of the object.
54 :ivar generation: The generation number of the object.
55 :ivar meta_generation: The generation number of the object metadata.
56 :ivar encrypted: Whether the object is encrypted while at rest on
57 the server.
58 """
59 generation = None
60 meta_generation = None
61
62 def __repr__(self):
63 if self.generation and self.meta_generation:
64 ver_str = '#%s.%s' % (self.generation, self.meta_generation)
65 else:
66 ver_str = ''
67 if self.bucket:
68 return '<Key: %s,%s%s>' % (self.bucket.name, self.name, ver_str)
69 else:
70 return '<Key: None,%s%s>' % (self.name, ver_str)
71
72 def endElement(self, name, value, connection):
73 if name == 'Key':
74 self.name = value
75 elif name == 'ETag':
76 self.etag = value
77 elif name == 'IsLatest':
78 if value == 'true':
79 self.is_latest = True
80 else:
81 self.is_latest = False
82 elif name == 'LastModified':
83 self.last_modified = value
84 elif name == 'Size':
85 self.size = int(value)
86 elif name == 'StorageClass':
87 self.storage_class = value
88 elif name == 'Owner':
89 pass
90 elif name == 'VersionId':
91 self.version_id = value
92 elif name == 'Generation':
93 self.generation = value
94 elif name == 'MetaGeneration':
95 self.meta_generation = value
96 else:
97 setattr(self, name, value)
98
99 def handle_version_headers(self, resp, force=False):
100 self.meta_generation = resp.getheader('x-goog-metageneration', None)
101 self.generation = resp.getheader('x-goog-generation', None)
102
103 def get_file(self, fp, headers=None, cb=None, num_cb=10,
104 torrent=False, version_id=None, override_num_retries=None,
105 response_headers=None):
106 query_args = None
107 if self.generation:
108 query_args = ['generation=%s' % self.generation]
109 self._get_file_internal(fp, headers=headers, cb=cb, num_cb=num_cb,
110 override_num_retries=override_num_retries,
111 response_headers=response_headers,
112 query_args=query_args)
113
114 def delete(self):
115 return self.bucket.delete_key(self.name, version_id=self.version_id,
116 generation=self.generation)
117
118 def add_email_grant(self, permission, email_address):
119 """
120 Convenience method that provides a quick way to add an email grant to a
121 key. This method retrieves the current ACL, creates a new grant based on
122 the parameters passed in, adds that grant to the ACL and then PUT's the
123 new ACL back to GS.
124
125 :type permission: string
126 :param permission: The permission being granted. Should be one of:
127 READ|FULL_CONTROL
128 See http://code.google.com/apis/storage/docs/developer-guide.html#au thorization
129 for more details on permissions.
130
131 :type email_address: string
132 :param email_address: The email address associated with the Google
133 account to which you are granting the permission.
134 """
135 acl = self.get_acl()
136 acl.add_email_grant(permission, email_address)
137 self.set_acl(acl)
138
139 def add_user_grant(self, permission, user_id):
140 """
141 Convenience method that provides a quick way to add a canonical user
142 grant to a key. This method retrieves the current ACL, creates a new
143 grant based on the parameters passed in, adds that grant to the ACL and
144 then PUT's the new ACL back to GS.
145
146 :type permission: string
147 :param permission: The permission being granted. Should be one of:
148 READ|FULL_CONTROL
149 See http://code.google.com/apis/storage/docs/developer-guide.html#au thorization
150 for more details on permissions.
151
152 :type user_id: string
153 :param user_id: The canonical user id associated with the GS account to
154 which you are granting the permission.
155 """
156 acl = self.get_acl()
157 acl.add_user_grant(permission, user_id)
158 self.set_acl(acl)
159
160 def add_group_email_grant(self, permission, email_address, headers=None):
161 """
162 Convenience method that provides a quick way to add an email group
163 grant to a key. This method retrieves the current ACL, creates a new
164 grant based on the parameters passed in, adds that grant to the ACL and
165 then PUT's the new ACL back to GS.
166
167 :type permission: string
168 :param permission: The permission being granted. Should be one of:
169 READ|FULL_CONTROL
170 See http://code.google.com/apis/storage/docs/developer-guide.html#au thorization
171 for more details on permissions.
172
173 :type email_address: string
174 :param email_address: The email address associated with the Google
175 Group to which you are granting the permission.
176 """
177 acl = self.get_acl(headers=headers)
178 acl.add_group_email_grant(permission, email_address)
179 self.set_acl(acl, headers=headers)
180
181 def add_group_grant(self, permission, group_id):
182 """
183 Convenience method that provides a quick way to add a canonical group
184 grant to a key. This method retrieves the current ACL, creates a new
185 grant based on the parameters passed in, adds that grant to the ACL and
186 then PUT's the new ACL back to GS.
187
188 :type permission: string
189 :param permission: The permission being granted. Should be one of:
190 READ|FULL_CONTROL
191 See http://code.google.com/apis/storage/docs/developer-guide.html#au thorization
192 for more details on permissions.
193
194 :type group_id: string
195 :param group_id: The canonical group id associated with the Google
196 Groups account you are granting the permission to.
197 """
198 acl = self.get_acl()
199 acl.add_group_grant(permission, group_id)
200 self.set_acl(acl)
201
202 def set_contents_from_file(self, fp, headers=None, replace=True,
203 cb=None, num_cb=10, policy=None, md5=None,
204 res_upload_handler=None, size=None, rewind=False,
205 if_generation=None):
206 """
207 Store an object in GS using the name of the Key object as the
208 key in GS and the contents of the file pointed to by 'fp' as the
209 contents.
210
211 :type fp: file
212 :param fp: the file whose contents are to be uploaded
213
214 :type headers: dict
215 :param headers: additional HTTP headers to be sent with the PUT request.
216
217 :type replace: bool
218 :param replace: If this parameter is False, the method will first check
219 to see if an object exists in the bucket with the same key. If it
220 does, it won't overwrite it. The default value is True which will
221 overwrite the object.
222
223 :type cb: function
224 :param cb: a callback function that will be called to report
225 progress on the upload. The callback should accept two integer
226 parameters, the first representing the number of bytes that have
227 been successfully transmitted to GS and the second representing the
228 total number of bytes that need to be transmitted.
229
230 :type num_cb: int
231 :param num_cb: (optional) If a callback is specified with the cb
232 parameter, this parameter determines the granularity of the callback
233 by defining the maximum number of times the callback will be called
234 during the file transfer.
235
236 :type policy: :class:`boto.gs.acl.CannedACLStrings`
237 :param policy: A canned ACL policy that will be applied to the new key
238 in GS.
239
240 :type md5: A tuple containing the hexdigest version of the MD5 checksum
241 of the file as the first element and the Base64-encoded version of
242 the plain checksum as the second element. This is the same format
243 returned by the compute_md5 method.
244 :param md5: If you need to compute the MD5 for any reason prior to
245 upload, it's silly to have to do it twice so this param, if present,
246 will be used as the MD5 values of the file. Otherwise, the checksum
247 will be computed.
248
249 :type res_upload_handler: ResumableUploadHandler
250 :param res_upload_handler: If provided, this handler will perform the
251 upload.
252
253 :type size: int
254 :param size: (optional) The Maximum number of bytes to read from
255 the file pointer (fp). This is useful when uploading
256 a file in multiple parts where you are splitting the
257 file up into different ranges to be uploaded. If not
258 specified, the default behaviour is to read all bytes
259 from the file pointer. Less bytes may be available.
260 Notes:
261
262 1. The "size" parameter currently cannot be used when
263 a resumable upload handler is given but is still
264 useful for uploading part of a file as implemented
265 by the parent class.
266 2. At present Google Cloud Storage does not support
267 multipart uploads.
268
269 :type rewind: bool
270 :param rewind: (optional) If True, the file pointer (fp) will be
271 rewound to the start before any bytes are read from
272 it. The default behaviour is False which reads from
273 the current position of the file pointer (fp).
274
275 :type if_generation: int
276 :param if_generation: (optional) If set to a generation number, the
277 object will only be written to if its current generation number is
278 this value. If set to the value 0, the object will only be written
279 if it doesn't already exist.
280
281 :rtype: int
282 :return: The number of bytes written to the key.
283
284 TODO: At some point we should refactor the Bucket and Key classes,
285 to move functionality common to all providers into a parent class,
286 and provider-specific functionality into subclasses (rather than
287 just overriding/sharing code the way it currently works).
288 """
289 provider = self.bucket.connection.provider
290 if res_upload_handler and size:
291 # could use size instead of file_length if provided but...
292 raise BotoClientError('"size" param not supported for resumable uplo ads.')
293 headers = headers or {}
294 if policy:
295 headers[provider.acl_header] = policy
296
297 if rewind:
298 # caller requests reading from beginning of fp.
299 fp.seek(0, os.SEEK_SET)
300 else:
301 # The following seek/tell/seek logic is intended
302 # to detect applications using the older interface to
303 # set_contents_from_file(), which automatically rewound the
304 # file each time the Key was reused. This changed with commit
305 # 14ee2d03f4665fe20d19a85286f78d39d924237e, to support uploads
306 # split into multiple parts and uploaded in parallel, and at
307 # the time of that commit this check was added because otherwise
308 # older programs would get a success status and upload an empty
309 # object. Unfortuantely, it's very inefficient for fp's implemented
310 # by KeyFile (used, for example, by gsutil when copying between
311 # providers). So, we skip the check for the KeyFile case.
312 # TODO: At some point consider removing this seek/tell/seek
313 # logic, after enough time has passed that it's unlikely any
314 # programs remain that assume the older auto-rewind interface.
315 if not isinstance(fp, KeyFile):
316 spos = fp.tell()
317 fp.seek(0, os.SEEK_END)
318 if fp.tell() == spos:
319 fp.seek(0, os.SEEK_SET)
320 if fp.tell() != spos:
321 # Raise an exception as this is likely a programming
322 # error whereby there is data before the fp but nothing
323 # after it.
324 fp.seek(spos)
325 raise AttributeError('fp is at EOF. Use rewind option '
326 'or seek() to data start.')
327 # seek back to the correct position.
328 fp.seek(spos)
329
330 if hasattr(fp, 'name'):
331 self.path = fp.name
332 if self.bucket != None:
333 if isinstance(fp, KeyFile):
334 # Avoid EOF seek for KeyFile case as it's very inefficient.
335 key = fp.getkey()
336 size = key.size - fp.tell()
337 self.size = size
338 # At present both GCS and S3 use MD5 for the etag for
339 # non-multipart-uploaded objects. If the etag is 32 hex
340 # chars use it as an MD5, to avoid having to read the file
341 # twice while transferring.
342 if (re.match('^"[a-fA-F0-9]{32}"$', key.etag)):
343 etag = key.etag.strip('"')
344 md5 = (etag, base64.b64encode(binascii.unhexlify(etag)))
345 if size:
346 self.size = size
347 else:
348 # If md5 is provided, still need to size so
349 # calculate based on bytes to end of content
350 spos = fp.tell()
351 fp.seek(0, os.SEEK_END)
352 self.size = fp.tell() - spos
353 fp.seek(spos)
354 size = self.size
355
356 if md5 == None:
357 md5 = self.compute_md5(fp, size)
358 self.md5 = md5[0]
359 self.base64md5 = md5[1]
360
361 if self.name == None:
362 self.name = self.md5
363
364 if not replace:
365 if self.bucket.lookup(self.name):
366 return
367
368 if if_generation is not None:
369 headers['x-goog-if-generation-match'] = str(if_generation)
370
371 if res_upload_handler:
372 res_upload_handler.send_file(self, fp, headers, cb, num_cb)
373 else:
374 # Not a resumable transfer so use basic send_file mechanism.
375 self.send_file(fp, headers, cb, num_cb, size=size)
376
377 def set_contents_from_filename(self, filename, headers=None, replace=True,
378 cb=None, num_cb=10, policy=None, md5=None,
379 reduced_redundancy=None,
380 res_upload_handler=None,
381 if_generation=None):
382 """
383 Store an object in GS using the name of the Key object as the
384 key in GS and the contents of the file named by 'filename'.
385 See set_contents_from_file method for details about the
386 parameters.
387
388 :type filename: string
389 :param filename: The name of the file that you want to put onto GS
390
391 :type headers: dict
392 :param headers: Additional headers to pass along with the request to GS.
393
394 :type replace: bool
395 :param replace: If True, replaces the contents of the file if it
396 already exists.
397
398 :type cb: function
399 :param cb: (optional) a callback function that will be called to report
400 progress on the download. The callback should accept two integer
401 parameters, the first representing the number of bytes that have
402 been successfully transmitted from GS and the second representing
403 the total number of bytes that need to be transmitted.
404
405 :type cb: int
406 :param num_cb: (optional) If a callback is specified with the cb
407 parameter this parameter determines the granularity of the callback
408 by defining the maximum number of times the callback will be called
409 during the file transfer.
410
411 :type policy: :class:`boto.gs.acl.CannedACLStrings`
412 :param policy: A canned ACL policy that will be applied to the new key
413 in GS.
414
415 :type md5: A tuple containing the hexdigest version of the MD5 checksum
416 of the file as the first element and the Base64-encoded version of
417 the plain checksum as the second element. This is the same format
418 returned by the compute_md5 method.
419 :param md5: If you need to compute the MD5 for any reason prior to
420 upload, it's silly to have to do it twice so this param, if present,
421 will be used as the MD5 values of the file. Otherwise, the checksum
422 will be computed.
423
424 :type res_upload_handler: ResumableUploadHandler
425 :param res_upload_handler: If provided, this handler will perform the
426 upload.
427
428 :type if_generation: int
429 :param if_generation: (optional) If set to a generation number, the
430 object will only be written to if its current generation number is
431 this value. If set to the value 0, the object will only be written
432 if it doesn't already exist.
433 """
434 # Clear out any previously computed md5 hashes, since we are setting the content.
435 self.md5 = None
436 self.base64md5 = None
437
438 fp = open(filename, 'rb')
439 self.set_contents_from_file(fp, headers, replace, cb, num_cb,
440 policy, md5, res_upload_handler,
441 if_generation=if_generation)
442 fp.close()
443
444 def set_contents_from_string(self, s, headers=None, replace=True,
445 cb=None, num_cb=10, policy=None, md5=None,
446 if_generation=None):
447 """
448 Store an object in S3 using the name of the Key object as the
449 key in S3 and the string 's' as the contents.
450 See set_contents_from_file method for details about the
451 parameters.
452
453 :type headers: dict
454 :param headers: Additional headers to pass along with the
455 request to AWS.
456
457 :type replace: bool
458 :param replace: If True, replaces the contents of the file if
459 it already exists.
460
461 :type cb: function
462 :param cb: a callback function that will be called to report
463 progress on the upload. The callback should accept
464 two integer parameters, the first representing the
465 number of bytes that have been successfully
466 transmitted to S3 and the second representing the
467 size of the to be transmitted object.
468
469 :type cb: int
470 :param num_cb: (optional) If a callback is specified with
471 the cb parameter this parameter determines the
472 granularity of the callback by defining
473 the maximum number of times the callback will
474 be called during the file transfer.
475
476 :type policy: :class:`boto.s3.acl.CannedACLStrings`
477 :param policy: A canned ACL policy that will be applied to the
478 new key in S3.
479
480 :type md5: A tuple containing the hexdigest version of the MD5
481 checksum of the file as the first element and the
482 Base64-encoded version of the plain checksum as the
483 second element. This is the same format returned by
484 the compute_md5 method.
485 :param md5: If you need to compute the MD5 for any reason prior
486 to upload, it's silly to have to do it twice so this
487 param, if present, will be used as the MD5 values
488 of the file. Otherwise, the checksum will be computed.
489
490 :type if_generation: int
491 :param if_generation: (optional) If set to a generation number, the
492 object will only be written to if its current generation number is
493 this value. If set to the value 0, the object will only be written
494 if it doesn't already exist.
495 """
496
497 # Clear out any previously computed md5 hashes, since we are setting the content.
498 self.md5 = None
499 self.base64md5 = None
500
501 if isinstance(s, unicode):
502 s = s.encode("utf-8")
503 fp = StringIO.StringIO(s)
504 r = self.set_contents_from_file(fp, headers, replace, cb, num_cb,
505 policy, md5,
506 if_generation=if_generation)
507 fp.close()
508 return r
509
510 def set_contents_from_stream(self, *args, **kwargs):
511 """
512 Store an object using the name of the Key object as the key in
513 cloud and the contents of the data stream pointed to by 'fp' as
514 the contents.
515
516 The stream object is not seekable and total size is not known.
517 This has the implication that we can't specify the
518 Content-Size and Content-MD5 in the header. So for huge
519 uploads, the delay in calculating MD5 is avoided but with a
520 penalty of inability to verify the integrity of the uploaded
521 data.
522
523 :type fp: file
524 :param fp: the file whose contents are to be uploaded
525
526 :type headers: dict
527 :param headers: additional HTTP headers to be sent with the
528 PUT request.
529
530 :type replace: bool
531 :param replace: If this parameter is False, the method will first check
532 to see if an object exists in the bucket with the same key. If it
533 does, it won't overwrite it. The default value is True which will
534 overwrite the object.
535
536 :type cb: function
537 :param cb: a callback function that will be called to report
538 progress on the upload. The callback should accept two integer
539 parameters, the first representing the number of bytes that have
540 been successfully transmitted to GS and the second representing the
541 total number of bytes that need to be transmitted.
542
543 :type num_cb: int
544 :param num_cb: (optional) If a callback is specified with the
545 cb parameter, this parameter determines the granularity of
546 the callback by defining the maximum number of times the
547 callback will be called during the file transfer.
548
549 :type policy: :class:`boto.gs.acl.CannedACLStrings`
550 :param policy: A canned ACL policy that will be applied to the new key
551 in GS.
552
553 :type reduced_redundancy: bool
554 :param reduced_redundancy: If True, this will set the storage
555 class of the new Key to be REDUCED_REDUNDANCY. The Reduced
556 Redundancy Storage (RRS) feature of S3, provides lower
557 redundancy at lower storage cost.
558
559 :type size: int
560 :param size: (optional) The Maximum number of bytes to read from
561 the file pointer (fp). This is useful when uploading a
562 file in multiple parts where you are splitting the file up
563 into different ranges to be uploaded. If not specified,
564 the default behaviour is to read all bytes from the file
565 pointer. Less bytes may be available.
566
567 :type if_generation: int
568 :param if_generation: (optional) If set to a generation number, the
569 object will only be written to if its current generation number is
570 this value. If set to the value 0, the object will only be written
571 if it doesn't already exist.
572 """
573 if_generation = kwargs.pop('if_generation', None)
574 if if_generation is not None:
575 headers = kwargs.get('headers', {})
576 headers['x-goog-if-generation-match'] = str(if_generation)
577 kwargs['headers'] = headers
578 super(Key, self).set_contents_from_stream(*args, **kwargs)
579
580 def set_acl(self, acl_or_str, headers=None, generation=None,
581 if_generation=None, if_metageneration=None):
582 """Sets the ACL for this object.
583
584 :type acl_or_str: string or :class:`boto.gs.acl.ACL`
585 :param acl_or_str: A canned ACL string (see
586 :data:`~.gs.acl.CannedACLStrings`) or an ACL object.
587
588 :type headers: dict
589 :param headers: Additional headers to set during the request.
590
591 :type generation: int
592 :param generation: If specified, sets the ACL for a specific generation
593 of a versioned object. If not specified, the current version is
594 modified.
595
596 :type if_generation: int
597 :param if_generation: (optional) If set to a generation number, the acl
598 will only be updated if its current generation number is this value.
599
600 :type if_metageneration: int
601 :param if_metageneration: (optional) If set to a metageneration number,
602 the acl will only be updated if its current metageneration number is
603 this value.
604 """
605 if self.bucket != None:
606 self.bucket.set_acl(acl_or_str, self.name, headers=headers,
607 generation=generation,
608 if_generation=if_generation,
609 if_metageneration=if_metageneration)
610
611 def get_acl(self, headers=None, generation=None):
612 """Returns the ACL of this object.
613
614 :param dict headers: Additional headers to set during the request.
615
616 :param int generation: If specified, gets the ACL for a specific
617 generation of a versioned object. If not specified, the current
618 version is returned.
619
620 :rtype: :class:`.gs.acl.ACL`
621 """
622 if self.bucket != None:
623 return self.bucket.get_acl(self.name, headers=headers,
624 generation=generation)
625
626 def get_xml_acl(self, headers=None, generation=None):
627 """Returns the ACL string of this object.
628
629 :param dict headers: Additional headers to set during the request.
630
631 :param int generation: If specified, gets the ACL for a specific
632 generation of a versioned object. If not specified, the current
633 version is returned.
634
635 :rtype: str
636 """
637 if self.bucket != None:
638 return self.bucket.get_xml_acl(self.name, headers=headers,
639 generation=generation)
640
641 def set_xml_acl(self, acl_str, headers=None, generation=None,
642 if_generation=None, if_metageneration=None):
643 """Sets this objects's ACL to an XML string.
644
645 :type acl_str: string
646 :param acl_str: A string containing the ACL XML.
647
648 :type headers: dict
649 :param headers: Additional headers to set during the request.
650
651 :type generation: int
652 :param generation: If specified, sets the ACL for a specific generation
653 of a versioned object. If not specified, the current version is
654 modified.
655
656 :type if_generation: int
657 :param if_generation: (optional) If set to a generation number, the acl
658 will only be updated if its current generation number is this value.
659
660 :type if_metageneration: int
661 :param if_metageneration: (optional) If set to a metageneration number,
662 the acl will only be updated if its current metageneration number is
663 this value.
664 """
665 if self.bucket != None:
666 return self.bucket.set_xml_acl(acl_str, self.name, headers=headers,
667 generation=generation,
668 if_generation=if_generation,
669 if_metageneration=if_metageneration)
670
671 def set_canned_acl(self, acl_str, headers=None, generation=None,
672 if_generation=None, if_metageneration=None):
673 """Sets this objects's ACL using a predefined (canned) value.
674
675 :type acl_str: string
676 :param acl_str: A canned ACL string. See
677 :data:`~.gs.acl.CannedACLStrings`.
678
679 :type headers: dict
680 :param headers: Additional headers to set during the request.
681
682 :type generation: int
683 :param generation: If specified, sets the ACL for a specific generation
684 of a versioned object. If not specified, the current version is
685 modified.
686
687 :type if_generation: int
688 :param if_generation: (optional) If set to a generation number, the acl
689 will only be updated if its current generation number is this value.
690
691 :type if_metageneration: int
692 :param if_metageneration: (optional) If set to a metageneration number,
693 the acl will only be updated if its current metageneration number is
694 this value.
695 """
696 if self.bucket != None:
697 return self.bucket.set_canned_acl(
698 acl_str,
699 self.name,
700 headers=headers,
701 generation=generation,
702 if_generation=if_generation,
703 if_metageneration=if_metageneration
704 )
OLDNEW
« no previous file with comments | « third_party/boto/gs/cors.py ('k') | third_party/boto/gs/resumable_upload_handler.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698