Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 1 addition & 6 deletions gcloud/storage/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,20 +39,15 @@ def path(self):
"""Abstract getter for the object path."""
raise NotImplementedError

def __init__(self, name=None, properties=None):
def __init__(self, name=None):
"""_PropertyMixin constructor.

:type name: string
:param name: The name of the object.

:type properties: dict
:param properties: All the other data provided by Cloud Storage.
"""
self.name = name
self._properties = {}
self._changes = set()
if properties is not None:
self._properties.update(properties)

@property
def properties(self):
Expand Down
16 changes: 11 additions & 5 deletions gcloud/storage/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,9 @@ def get_bucket(bucket_name, connection=None):
if connection is None:
connection = get_default_connection()

bucket_path = Bucket.path_helper(bucket_name)
response = connection.api_request(method='GET', path=bucket_path)
return Bucket(properties=response, connection=connection)
bucket = Bucket(bucket_name, connection=connection)
bucket._reload_properties()
return bucket


def create_bucket(bucket_name, project=None, connection=None):
Expand Down Expand Up @@ -169,7 +169,10 @@ def create_bucket(bucket_name, project=None, connection=None):
response = connection.api_request(method='POST', path='/b',
query_params=query_params,
data={'name': bucket_name})
return Bucket(properties=response, connection=connection)
name = response.get('name')
bucket = Bucket(name, connection=connection)
bucket._properties = response
return bucket


class _BucketIterator(Iterator):
Expand All @@ -194,4 +197,7 @@ def get_items_from_response(self, response):
:param response: The JSON API response for a page of buckets.
"""
for item in response.get('items', []):
yield Bucket(properties=item, connection=self.connection)
name = item.get('name')
bucket = Bucket(name, connection=self.connection)
bucket._properties = item
yield bucket
7 changes: 2 additions & 5 deletions gcloud/storage/blob.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,17 +62,14 @@ class Blob(_PropertyMixin):
# ACL rules are lazily retrieved.
_acl = None

def __init__(self, name, bucket=None, properties=None):
if name is None and properties is not None:
name = properties.get('name')

def __init__(self, name, bucket=None):
if bucket is None:
bucket = _implicit_environ.get_default_bucket()

if bucket is None:
raise ValueError('A Blob must have a bucket set.')

super(Blob, self).__init__(name=name, properties=properties)
super(Blob, self).__init__(name=name)

self.bucket = bucket

Expand Down
16 changes: 10 additions & 6 deletions gcloud/storage/bucket.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,10 @@ def get_items_from_response(self, response):
"""
self.prefixes = tuple(response.get('prefixes', ()))
for item in response.get('items', []):
yield Blob(None, properties=item, bucket=self.bucket)
name = item.get('name')
blob = Blob(name, bucket=self.bucket)
blob._properties = item
yield blob


class Bucket(_PropertyMixin):
Expand All @@ -92,10 +95,8 @@ class Bucket(_PropertyMixin):
# ACL rules are lazily retrieved.
_acl = _default_object_acl = None

def __init__(self, name=None, connection=None, properties=None):
if name is None and properties is not None:
name = properties.get('name')
super(Bucket, self).__init__(name=name, properties=properties)
def __init__(self, name=None, connection=None):
super(Bucket, self).__init__(name=name)
self._connection = connection

def __repr__(self):
Expand Down Expand Up @@ -190,7 +191,10 @@ def get_blob(self, blob_name):
try:
response = self.connection.api_request(method='GET',
path=blob.path)
return Blob(None, bucket=self, properties=response)
name = response.get('name') # Expect this to be blob_name
blob = Blob(name, bucket=self)
blob._properties = response
return blob
except NotFound:
return None

Expand Down
4 changes: 3 additions & 1 deletion gcloud/storage/iterator.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ class MyIterator(Iterator):
def get_items_from_response(self, response):
items = response.get('items', [])
for item in items:
yield MyItemClass(properties=item, other_arg=True)
my_item = MyItemClass(other_arg=True)
my_item._properties = item
yield my_item

You then can use this to get **all** the results from a resource::

Expand Down
8 changes: 4 additions & 4 deletions gcloud/storage/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def test_miss(self):
'storage',
conn.API_VERSION,
'b',
'nonesuch',
'nonesuch?projection=noAcl',
])
http = conn._http = Http(
{'status': '404', 'content-type': 'application/json'},
Expand All @@ -52,7 +52,7 @@ def _lookup_bucket_hit_helper(self, use_default=False):
'storage',
conn.API_VERSION,
'b',
'%s' % (BLOB_NAME,),
'%s?projection=noAcl' % (BLOB_NAME,),
])
http = conn._http = Http(
{'status': '200', 'content-type': 'application/json'},
Expand Down Expand Up @@ -156,7 +156,7 @@ def test_miss(self):
'storage',
conn.API_VERSION,
'b',
'nonesuch',
'nonesuch?projection=noAcl',
])
http = conn._http = Http(
{'status': '404', 'content-type': 'application/json'},
Expand All @@ -177,7 +177,7 @@ def _get_bucket_hit_helper(self, use_default=False):
'storage',
conn.API_VERSION,
'b',
'%s' % (BLOB_NAME,),
'%s?projection=noAcl' % (BLOB_NAME,),
])
http = conn._http = Http(
{'status': '200', 'content-type': 'application/json'},
Expand Down
31 changes: 5 additions & 26 deletions gcloud/storage/test_blob.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ class Test_Blob(unittest2.TestCase):

def _makeOne(self, *args, **kw):
from gcloud.storage.blob import Blob
return Blob(*args, **kw)
properties = kw.pop('properties', None)
blob = Blob(*args, **kw)
blob._properties = properties or {}
return blob

def test_ctor_no_bucket(self):
self.assertRaises(ValueError, self._makeOne, None)
Expand Down Expand Up @@ -63,29 +66,6 @@ def test_ctor_explicit(self):
self.assertEqual(blob.properties, properties)
self.assertTrue(blob._acl is None)

def test_ctor_no_name_defaults(self):
BLOB_NAME = 'blob-name'
properties = {'key': 'value', 'name': BLOB_NAME}
FAKE_BUCKET = _Bucket(None)
blob = self._makeOne(None, bucket=FAKE_BUCKET, properties=properties)
self.assertEqual(blob.bucket, FAKE_BUCKET)
self.assertEqual(blob.connection, None)
self.assertEqual(blob.name, BLOB_NAME)
self.assertEqual(blob.properties, properties)
self.assertTrue(blob._acl is None)

def test_ctor_no_name_explicit(self):
BLOB_NAME = 'blob-name'
connection = _Connection()
bucket = _Bucket(connection)
properties = {'key': 'value', 'name': BLOB_NAME}
blob = self._makeOne(None, properties=properties, bucket=bucket)
self.assertTrue(blob.bucket is bucket)
self.assertTrue(blob.connection is connection)
self.assertEqual(blob.name, BLOB_NAME)
self.assertEqual(blob.properties, properties)
self.assertTrue(blob._acl is None)

def test_acl_property(self):
from gcloud.storage.acl import ObjectACL
FAKE_BUCKET = _Bucket(None)
Expand Down Expand Up @@ -1043,8 +1023,7 @@ def __init__(self, connection):

def copy_blob(self, blob, destination_bucket, new_name):
destination_bucket._blobs[new_name] = self._blobs[blob.name]
return blob.__class__(None, bucket=destination_bucket,
properties={'name': new_name})
return blob.__class__(new_name, bucket=destination_bucket)

def delete_blob(self, blob_name):
del self._blobs[blob_name]
Expand Down
48 changes: 15 additions & 33 deletions gcloud/storage/test_bucket.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,10 @@ class Test_Bucket(unittest2.TestCase):

def _makeOne(self, *args, **kw):
from gcloud.storage.bucket import Bucket
return Bucket(*args, **kw)
properties = kw.pop('properties', None)
bucket = Bucket(*args, **kw)
bucket._properties = properties or {}
return bucket

def test_ctor_defaults(self):
bucket = self._makeOne()
Expand All @@ -78,34 +81,13 @@ def test_ctor_explicit(self):
NAME = 'name'
connection = _Connection()
properties = {'key': 'value'}
bucket = self._makeOne(NAME, connection, properties)
bucket = self._makeOne(NAME, connection, properties=properties)
self.assertTrue(bucket.connection is connection)
self.assertEqual(bucket.name, NAME)
self.assertEqual(bucket._properties, properties)
self.assertTrue(bucket._acl is None)
self.assertTrue(bucket._default_object_acl is None)

def test_ctor_no_name_defaults(self):
NAME = 'name'
properties = {'key': 'value', 'name': NAME}
bucket = self._makeOne(properties=properties)
self.assertEqual(bucket.connection, None)
self.assertEqual(bucket.name, NAME)
self.assertEqual(bucket.properties, properties)
self.assertTrue(bucket._acl is None)
self.assertTrue(bucket._default_object_acl is None)

def test_ctor_no_name_explicit(self):
NAME = 'name'
connection = _Connection()
properties = {'key': 'value', 'name': NAME}
bucket = self._makeOne(connection=connection, properties=properties)
self.assertTrue(bucket.connection is connection)
self.assertEqual(bucket.name, NAME)
self.assertEqual(bucket.properties, properties)
self.assertTrue(bucket._acl is None)
self.assertTrue(bucket._default_object_acl is None)

def test___iter___empty(self):
NAME = 'name'
connection = _Connection({'items': []})
Expand Down Expand Up @@ -164,7 +146,7 @@ def api_request(cls, *args, **kwargs):
raise NotFound(args)

BUCKET_NAME = 'bucket-name'
bucket = self._makeOne(connection=_FakeConnection, name=BUCKET_NAME)
bucket = self._makeOne(BUCKET_NAME, connection=_FakeConnection)
self.assertFalse(bucket.exists())
expected_called_kwargs = {
'method': 'GET',
Expand All @@ -188,7 +170,7 @@ def api_request(cls, *args, **kwargs):
return object()

BUCKET_NAME = 'bucket-name'
bucket = self._makeOne(connection=_FakeConnection, name=BUCKET_NAME)
bucket = self._makeOne(BUCKET_NAME, connection=_FakeConnection)
self.assertTrue(bucket.exists())
expected_called_kwargs = {
'method': 'GET',
Expand Down Expand Up @@ -592,7 +574,7 @@ def test_get_cors_eager(self):
}
before = {'cors': [CORS_ENTRY, {}]}
connection = _Connection()
bucket = self._makeOne(NAME, connection, before)
bucket = self._makeOne(NAME, connection, properties=before)
entries = bucket.get_cors()
self.assertEqual(len(entries), 2)
self.assertEqual(entries[0]['maxAgeSeconds'],
Expand Down Expand Up @@ -697,7 +679,7 @@ def test_get_lifecycle_eager(self):
LC_RULE = {'action': {'type': 'Delete'}, 'condition': {'age': 42}}
before = {'lifecycle': {'rule': [LC_RULE]}}
connection = _Connection()
bucket = self._makeOne(NAME, connection, before)
bucket = self._makeOne(NAME, connection, properties=before)
entries = bucket.get_lifecycle()
self.assertEqual(len(entries), 1)
self.assertEqual(entries[0]['action']['type'], 'Delete')
Expand Down Expand Up @@ -744,7 +726,7 @@ def test_location_getter(self):
NAME = 'name'
connection = _Connection()
before = {'location': 'AS'}
bucket = self._makeOne(NAME, connection, before)
bucket = self._makeOne(NAME, connection, properties=before)
self.assertEqual(bucket.location, 'AS')
kw = connection._requested
self.assertEqual(len(kw), 0)
Expand Down Expand Up @@ -795,7 +777,7 @@ def test_enable_logging_defaults(self):
}
connection = _Connection(resp_to_reload, resp_to_enable_logging,
resp_to_enable_logging)
bucket = self._makeOne(NAME, connection, before)
bucket = self._makeOne(NAME, connection, properties=before)
self.assertTrue(bucket.get_logging() is None)
bucket.enable_logging(LOG_BUCKET)
info = bucket.get_logging()
Expand Down Expand Up @@ -826,7 +808,7 @@ def test_enable_logging_explicit(self):
connection = _Connection(resp_to_reload,
resp_to_enable_logging,
resp_to_enable_logging)
bucket = self._makeOne(NAME, connection, before)
bucket = self._makeOne(NAME, connection, properties=before)
self.assertTrue(bucket.get_logging() is None)
bucket.enable_logging(LOG_BUCKET, LOG_PFX)
info = bucket.get_logging()
Expand All @@ -852,7 +834,7 @@ def test_disable_logging(self):
resp_to_disable_logging = {'logging': None}
connection = _Connection(resp_to_reload, resp_to_disable_logging,
resp_to_disable_logging)
bucket = self._makeOne(NAME, connection, before)
bucket = self._makeOne(NAME, connection, properties=before)
self.assertTrue(bucket.get_logging() is not None)
bucket.disable_logging()
self.assertTrue(bucket.get_logging() is None)
Expand Down Expand Up @@ -923,7 +905,7 @@ def test_versioning_enabled_getter(self):
NAME = 'name'
before = {'versioning': {'enabled': True}}
connection = _Connection()
bucket = self._makeOne(NAME, connection, before)
bucket = self._makeOne(NAME, connection, properties=before)
self.assertEqual(bucket.versioning_enabled, True)
kw = connection._requested
self.assertEqual(len(kw), 0)
Expand All @@ -933,7 +915,7 @@ def test_versioning_enabled_setter(self):
before = {'versioning': {'enabled': False}}
after = {'versioning': {'enabled': True}}
connection = _Connection(after)
bucket = self._makeOne(NAME, connection, before)
bucket = self._makeOne(NAME, connection, properties=before)
self.assertFalse(bucket.versioning_enabled)
bucket.versioning_enabled = True
bucket.patch()
Expand Down