Skip to content

Commit

Permalink
Merge pull request #224 from tseaver/pr_99-gsalgado-master
Browse files Browse the repository at this point in the history
Rebase PR #99 and fix up
  • Loading branch information
dhermes committed Oct 7, 2014
2 parents 2db8ce0 + dcaae75 commit 941a2c7
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 2 deletions.
24 changes: 22 additions & 2 deletions gcloud/storage/bucket.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,28 @@ def delete_keys(self, keys):
for key in keys:
self.delete_key(key)

def copy_key(self): # pragma NO COVER
raise NotImplementedError
def copy_key(self, key, destination_bucket, new_name=None):
"""Copy the given key to the given bucket, optionally with a new name.
:type key: string or :class:`gcloud.storage.key.Key`
:param key: The key to be copied.
:type destination_bucket: :class:`gcloud.storage.bucket.Bucket`
:param destination_bucket: The bucket into which the key should be
copied.
:type new_name: string
:param new_name: (optional) the new name for the copied file.
:rtype: :class:`gcloud.storage.key.Key`
:returns: The new Key.
"""
if new_name is None:
new_name = key.name
new_key = destination_bucket.new_key(new_name)
api_path = key.path + '/copyTo' + new_key.path
self.connection.api_request(method='POST', path=api_path)
return new_key

def upload_file(self, filename, key=None):
"""Shortcut method to upload a file into this bucket.
Expand Down
16 changes: 16 additions & 0 deletions gcloud/storage/key.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,22 @@ def exists(self):

return self.bucket.get_key(self.name) is not None

def rename(self, new_name):
"""Renames this key.
Effectively, copies key to the same bucket with a new name, then
deletes the key.
:type new_name: string
:param new_name: The new name for this key.
:rtype: :class:`Key`
:returns: The newly-copied key.
"""
new_key = self.bucket.copy_key(self, self.bucket, new_name)
self.bucket.delete_key(self)
return new_key

def delete(self):
"""Deletes a key from Cloud Storage.
Expand Down
44 changes: 44 additions & 0 deletions gcloud/storage/test_bucket.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,50 @@ def test_delete_keys_miss(self):
self.assertEqual(kw[1]['method'], 'DELETE')
self.assertEqual(kw[1]['path'], '/b/%s/o/%s' % (NAME, NONESUCH))

def test_copy_keys_wo_name(self):
SOURCE = 'source'
DEST = 'dest'
KEY = 'key'

class _Key(object):
name = KEY
path = '/b/%s/o/%s' % (SOURCE, KEY)

connection = _Connection({})
source = self._makeOne(connection, SOURCE)
dest = self._makeOne(connection, DEST)
key = _Key()
new_key = source.copy_key(key, dest)
self.assertTrue(new_key.bucket is dest)
self.assertEqual(new_key.name, KEY)
kw, = connection._requested
COPY_PATH = '/b/%s/o/%s/copyTo/b/%s/o/%s' % (SOURCE, KEY, DEST, KEY)
self.assertEqual(kw['method'], 'POST')
self.assertEqual(kw['path'], COPY_PATH)

def test_copy_keys_w_name(self):
SOURCE = 'source'
DEST = 'dest'
KEY = 'key'
NEW_NAME = 'new_name'

class _Key(object):
name = KEY
path = '/b/%s/o/%s' % (SOURCE, KEY)

connection = _Connection({})
source = self._makeOne(connection, SOURCE)
dest = self._makeOne(connection, DEST)
key = _Key()
new_key = source.copy_key(key, dest, NEW_NAME)
self.assertTrue(new_key.bucket is dest)
self.assertEqual(new_key.name, NEW_NAME)
kw, = connection._requested
COPY_PATH = (
'/b/%s/o/%s/copyTo/b/%s/o/%s' % (SOURCE, KEY, DEST, NEW_NAME))
self.assertEqual(kw['method'], 'POST')
self.assertEqual(kw['path'], COPY_PATH)

def test_upload_file_default_key(self):
from gcloud.test_credentials import _Monkey
from gcloud.storage import bucket as MUT
Expand Down
21 changes: 21 additions & 0 deletions gcloud/storage/test_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,21 @@ def test_exists_hit(self):
bucket._keys[KEY] = 1
self.assertTrue(key.exists())

def test_rename(self):
KEY = 'key'
NEW_NAME = 'new-name'
connection = _Connection()
bucket = _Bucket(connection)
key = self._makeOne(bucket, KEY)
bucket._keys[KEY] = 1
orig_key_path = key.path
new_key = key.rename(NEW_NAME)
self.assertEqual(key.name, KEY)
self.assertEqual(new_key.name, NEW_NAME)
self.assertFalse(KEY in bucket._keys)
self.assertTrue(KEY in bucket._deleted)
self.assertTrue(NEW_NAME in bucket._keys)

def test_delete(self):
KEY = 'key'
connection = _Connection()
Expand Down Expand Up @@ -584,9 +599,15 @@ class _Bucket(object):
def __init__(self, connection):
self.connection = connection
self._keys = {}
self._deleted = []

def get_key(self, key):
return self._keys.get(key) # XXX s.b. 'key.name'?

def copy_key(self, key, destination_bucket, new_name):
destination_bucket._keys[new_name] = self._keys[key.name]
return key.from_dict({'name': new_name}, bucket=destination_bucket)

def delete_key(self, key):
del self._keys[key.name] # XXX s.b. 'key'?
self._deleted.append(key.name)

0 comments on commit 941a2c7

Please sign in to comment.