| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -191,8 +191,28 @@ def delete_keys(self, keys): | |||
| 191 | 191 | for key in keys: | |
| 192 | 192 | self.delete_key(key) | |
| 193 | 193 | ||
| 194 | - def copy_key(self): # pragma NO COVER | ||
| 195 | - raise NotImplementedError | ||
| 194 | + def copy_key(self, key, destination_bucket, new_name=None): | ||
| 195 | + """Copy the given key to the given bucket, optionally with a new name. | ||
| 196 | + | ||
| 197 | + :type key: string or :class:`gcloud.storage.key.Key` | ||
| 198 | + :param key: The key to be copied. | ||
| 199 | + | ||
| 200 | + :type destination_bucket: :class:`gcloud.storage.bucket.Bucket` | ||
| 201 | + :param destination_bucket: The bucket into which the key should be | ||
| 202 | + copied. | ||
| 203 | + | ||
| 204 | + :type new_name: string | ||
| 205 | + :param new_name: (optional) the new name for the copied file. | ||
| 206 | + | ||
| 207 | + :rtype: :class:`gcloud.storage.key.Key` | ||
| 208 | + :returns: The new Key. | ||
| 209 | + """ | ||
| 210 | + if new_name is None: | ||
| 211 | + new_name = key.name | ||
| 212 | + new_key = destination_bucket.new_key(new_name) | ||
| 213 | + api_path = key.path + '/copyTo' + new_key.path | ||
| 214 | + self.connection.api_request(method='POST', path=api_path) | ||
| 215 | + return new_key | ||
| 196 | 216 | ||
| 197 | 217 | def upload_file(self, filename, key=None): | |
| 198 | 218 | """Shortcut method to upload a file into this bucket. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -133,6 +133,22 @@ def exists(self): | |||
| 133 | 133 | ||
| 134 | 134 | return self.bucket.get_key(self.name) is not None | |
| 135 | 135 | ||
| 136 | + def rename(self, new_name): | ||
| 137 | + """Renames this key. | ||
| 138 | + | ||
| 139 | + Effectively, copies key to the same bucket with a new name, then | ||
| 140 | + deletes the key. | ||
| 141 | + | ||
| 142 | + :type new_name: string | ||
| 143 | + :param new_name: The new name for this key. | ||
| 144 | + | ||
| 145 | + :rtype: :class:`Key` | ||
| 146 | + :returns: The newly-copied key. | ||
| 147 | + """ | ||
| 148 | + new_key = self.bucket.copy_key(self, self.bucket, new_name) | ||
| 149 | + self.bucket.delete_key(self) | ||
| 150 | + return new_key | ||
| 151 | + | ||
| 136 | 152 | def delete(self): | |
| 137 | 153 | """Deletes a key from Cloud Storage. | |
| 138 | 154 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -247,6 +247,50 @@ def test_delete_keys_miss(self): | |||
| 247 | 247 | self.assertEqual(kw[1]['method'], 'DELETE') | |
| 248 | 248 | self.assertEqual(kw[1]['path'], '/b/%s/o/%s' % (NAME, NONESUCH)) | |
| 249 | 249 | ||
| 250 | + def test_copy_keys_wo_name(self): | ||
| 251 | + SOURCE = 'source' | ||
| 252 | + DEST = 'dest' | ||
| 253 | + KEY = 'key' | ||
| 254 | + | ||
| 255 | + class _Key(object): | ||
| 256 | + name = KEY | ||
| 257 | + path = '/b/%s/o/%s' % (SOURCE, KEY) | ||
| 258 | + | ||
| 259 | + connection = _Connection({}) | ||
| 260 | + source = self._makeOne(connection, SOURCE) | ||
| 261 | + dest = self._makeOne(connection, DEST) | ||
| 262 | + key = _Key() | ||
| 263 | + new_key = source.copy_key(key, dest) | ||
| 264 | + self.assertTrue(new_key.bucket is dest) | ||
| 265 | + self.assertEqual(new_key.name, KEY) | ||
| 266 | + kw, = connection._requested | ||
| 267 | + COPY_PATH = '/b/%s/o/%s/copyTo/b/%s/o/%s' % (SOURCE, KEY, DEST, KEY) | ||
| 268 | + self.assertEqual(kw['method'], 'POST') | ||
| 269 | + self.assertEqual(kw['path'], COPY_PATH) | ||
| 270 | + | ||
| 271 | + def test_copy_keys_w_name(self): | ||
| 272 | + SOURCE = 'source' | ||
| 273 | + DEST = 'dest' | ||
| 274 | + KEY = 'key' | ||
| 275 | + NEW_NAME = 'new_name' | ||
| 276 | + | ||
| 277 | + class _Key(object): | ||
| 278 | + name = KEY | ||
| 279 | + path = '/b/%s/o/%s' % (SOURCE, KEY) | ||
| 280 | + | ||
| 281 | + connection = _Connection({}) | ||
| 282 | + source = self._makeOne(connection, SOURCE) | ||
| 283 | + dest = self._makeOne(connection, DEST) | ||
| 284 | + key = _Key() | ||
| 285 | + new_key = source.copy_key(key, dest, NEW_NAME) | ||
| 286 | + self.assertTrue(new_key.bucket is dest) | ||
| 287 | + self.assertEqual(new_key.name, NEW_NAME) | ||
| 288 | + kw, = connection._requested | ||
| 289 | + COPY_PATH = ( | ||
| 290 | + '/b/%s/o/%s/copyTo/b/%s/o/%s' % (SOURCE, KEY, DEST, NEW_NAME)) | ||
| 291 | + self.assertEqual(kw['method'], 'POST') | ||
| 292 | + self.assertEqual(kw['path'], COPY_PATH) | ||
| 293 | + | ||
| 250 | 294 | def test_upload_file_default_key(self): | |
| 251 | 295 | from gcloud.test_credentials import _Monkey | |
| 252 | 296 | from gcloud.storage import bucket as MUT | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -95,6 +95,21 @@ def test_exists_hit(self): | |||
| 95 | 95 | bucket._keys[KEY] = 1 | |
| 96 | 96 | self.assertTrue(key.exists()) | |
| 97 | 97 | ||
| 98 | + def test_rename(self): | ||
| 99 | + KEY = 'key' | ||
| 100 | + NEW_NAME = 'new-name' | ||
| 101 | + connection = _Connection() | ||
| 102 | + bucket = _Bucket(connection) | ||
| 103 | + key = self._makeOne(bucket, KEY) | ||
| 104 | + bucket._keys[KEY] = 1 | ||
| 105 | + orig_key_path = key.path | ||
| 106 | + new_key = key.rename(NEW_NAME) | ||
| 107 | + self.assertEqual(key.name, KEY) | ||
| 108 | + self.assertEqual(new_key.name, NEW_NAME) | ||
| 109 | + self.assertFalse(KEY in bucket._keys) | ||
| 110 | + self.assertTrue(KEY in bucket._deleted) | ||
| 111 | + self.assertTrue(NEW_NAME in bucket._keys) | ||
| 112 | + | ||
| 98 | 113 | def test_delete(self): | |
| 99 | 114 | KEY = 'key' | |
| 100 | 115 | connection = _Connection() | |
@@ -584,9 +599,15 @@ class _Bucket(object): | |||
| 584 | 599 | def __init__(self, connection): | |
| 585 | 600 | self.connection = connection | |
| 586 | 601 | self._keys = {} | |
| 602 | + self._deleted = [] | ||
| 587 | 603 | ||
| 588 | 604 | def get_key(self, key): | |
| 589 | 605 | return self._keys.get(key) # XXX s.b. 'key.name'? | |
| 590 | 606 | ||
| 607 | + def copy_key(self, key, destination_bucket, new_name): | ||
| 608 | + destination_bucket._keys[new_name] = self._keys[key.name] | ||
| 609 | + return key.from_dict({'name': new_name}, bucket=destination_bucket) | ||
| 610 | + | ||
| 591 | 611 | def delete_key(self, key): | |
| 592 | 612 | del self._keys[key.name] # XXX s.b. 'key'? | |
| 613 | + self._deleted.append(key.name) | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments