22
33import os
44
5+ from gcloud .storage ._helpers import _ACLMetadataMixin
56from gcloud .storage import exceptions
67from gcloud .storage .acl import BucketACL
78from gcloud .storage .acl import DefaultObjectACL
1011from gcloud .storage .key import _KeyIterator
1112
1213
13- class Bucket (object ):
14+ class Bucket (_ACLMetadataMixin ):
1415 """A class representing a Bucket on Cloud Storage.
1516
1617 :type connection: :class:`gcloud.storage.connection.Connection`
@@ -19,13 +20,19 @@ class Bucket(object):
1920 :type name: string
2021 :param name: The name of the bucket.
2122 """
23+
24+ METADATA_ACL_FIELDS = ('acl' , 'defaultObjectAcl' )
25+ """Tuple of metadata fields pertaining to bucket ACLs."""
26+
27+ ACL_CLASS = BucketACL
28+ """Class which holds ACL data for buckets."""
29+
2230 # ACL rules are lazily retrieved.
2331 _acl = _default_object_acl = None
2432
2533 def __init__ (self , connection = None , name = None , metadata = None ):
26- self .connection = connection
27- self .name = name
28- self .metadata = metadata
34+ super (Bucket , self ).__init__ (name = name , metadata = metadata )
35+ self ._connection = connection
2936
3037 @property
3138 def acl (self ):
@@ -63,6 +70,15 @@ def __iter__(self):
6370 def __contains__ (self , key ):
6471 return self .get_key (key ) is not None
6572
73+ @property
74+ def connection (self ):
75+ """Getter property for the connection to use with this Bucket.
76+
77+ :rtype: :class:`gcloud.storage.connection.Connection`
78+ :returns: The connection to use.
79+ """
80+ return self ._connection
81+
6682 @property
6783 def path (self ):
6884 """The URL path to this bucket."""
@@ -326,85 +342,6 @@ def upload_file_object(self, file_obj, key=None):
326342 key = self .new_key (os .path .basename (file_obj .name ))
327343 return key .set_contents_from_file (file_obj )
328344
329- def has_metadata (self , field = None ):
330- """Check if metadata is available locally.
331-
332- :type field: string
333- :param field: (optional) the particular field to check for.
334-
335- :rtype: bool
336- :returns: Whether metadata is available locally.
337- """
338- if not self .metadata :
339- return False
340- elif field and field not in self .metadata :
341- return False
342- else :
343- return True
344-
345- def reload_metadata (self ):
346- """Reload metadata from Cloud Storage.
347-
348- :rtype: :class:`Bucket`
349- :returns: The bucket you just reloaded data for.
350- """
351- # Pass only '?projection=noAcl' here because 'acl'/'defaultObjectAcl'
352- # are handled via 'get_acl()'/'get_default_object_acl()'
353- query_params = {'projection' : 'noAcl' }
354- self .metadata = self .connection .api_request (
355- method = 'GET' , path = self .path , query_params = query_params )
356- return self
357-
358- def get_metadata (self , field = None , default = None ):
359- """Get all metadata or a specific field.
360-
361- If you request a field that isn't available, and that field can
362- be retrieved by refreshing data from Cloud Storage, this method
363- will reload the data using :func:`Bucket.reload_metadata`.
364-
365- :type field: string
366- :param field: (optional) A particular field to retrieve from metadata.
367-
368- :type default: anything
369- :param default: The value to return if the field provided wasn't found.
370-
371- :rtype: dict or anything
372- :returns: All metadata or the value of the specific field.
373- """
374- if field == 'acl' :
375- raise KeyError ("Use 'get_acl()'" )
376-
377- if field == 'defaultObjectAcl' :
378- raise KeyError ("Use 'get_default_object_acl()'" )
379-
380- if not self .has_metadata (field = field ):
381- self .reload_metadata ()
382-
383- if field :
384- return self .metadata .get (field , default )
385- else :
386- return self .metadata
387-
388- def patch_metadata (self , metadata ):
389- """Update particular fields of this bucket's metadata.
390-
391- This method will only update the fields provided and will not
392- touch the other fields.
393-
394- It will also reload the metadata locally based on the servers
395- response.
396-
397- :type metadata: dict
398- :param metadata: The dictionary of values to update.
399-
400- :rtype: :class:`Bucket`
401- :returns: The current bucket.
402- """
403- self .metadata = self .connection .api_request (
404- method = 'PATCH' , path = self .path , data = metadata ,
405- query_params = {'projection' : 'full' })
406- return self
407-
408345 def configure_website (self , main_page_suffix = None , not_found_page = None ):
409346 """Configure website-related metadata.
410347
@@ -491,8 +428,7 @@ def make_public(self, recursive=False, future=False):
491428 :param future: If True, this will make all objects created in the
492429 future public as well.
493430 """
494- self .get_acl ().all ().grant_read ()
495- self .acl .save ()
431+ super (Bucket , self ).make_public ()
496432
497433 if future :
498434 doa = self .get_default_object_acl ()
0 commit comments