Skip to content

Commit fb064fb

Browse files
authored
FIX copy and move metadata for localclient (#107)
Co-authored-by: Aditya Vaidya <[email protected]>
1 parent c605217 commit fb064fb

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

cottoncandy/localclient.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ def upload_file(self, file_name, cloud_name, permissions):
9797
source_bucket=None,
9898
destination_bucket=None,
9999
overwrite=True,
100+
copy_metadata=False,
100101
)
101102

102103
def upload_multipart(self, stream, cloud_name, metadata, permissions,
@@ -219,7 +220,7 @@ def list_objects(self, **kwargs):
219220
return results
220221

221222
def copy(self, source, destination, source_bucket, destination_bucket,
222-
overwrite):
223+
overwrite, copy_metadata=True):
223224
"""Copies an object
224225
225226
Parameters
@@ -232,6 +233,9 @@ def copy(self, source, destination, source_bucket, destination_bucket,
232233
destination_bucket : ignored
233234
overwrite : bool
234235
overwrite if destination exists
236+
copy_metadata : bool
237+
also copy metadata file? (we don't want to do this if copying from
238+
the local filesystem)
235239
236240
Returns
237241
-------
@@ -245,6 +249,11 @@ def copy(self, source, destination, source_bucket, destination_bucket,
245249
destination_bucket = source_bucket
246250
source = os.path.join(source_bucket, source)
247251
destination = os.path.join(destination_bucket, destination)
252+
if copy_metadata:
253+
source_metadata = os.path.join(source_bucket, source + METADATA_SUFFIX)
254+
destination_metadata = os.path.join(destination_bucket, destination + METADATA_SUFFIX)
255+
shutil.copy(source_metadata, destination_metadata)
256+
248257
auto_makedirs(destination)
249258
return shutil.copy(source, destination)
250259

@@ -272,8 +281,10 @@ def move(self, source, destination, source_bucket, destination_bucket,
272281
destination_bucket = source_bucket
273282
source = os.path.join(source_bucket, source)
274283
destination = os.path.join(destination_bucket, destination)
284+
source_metadata = os.path.join(source_bucket, source + METADATA_SUFFIX)
285+
destination_metadata = os.path.join(destination_bucket, destination + METADATA_SUFFIX)
275286
auto_makedirs(destination)
276-
return shutil.move(source, destination)
287+
return shutil.move(source, destination) and shutil.move(source_metadata, destination_metadata)
277288

278289
def delete(self, cloud_name, recursive=False, delete=False):
279290
"""Deletes an object
@@ -294,6 +305,9 @@ def delete(self, cloud_name, recursive=False, delete=False):
294305
cloud_name = os.path.join(self.path, cloud_name)
295306
if os.path.isfile(cloud_name):
296307
os.remove(cloud_name)
308+
cloud_metadata_name = cloud_name + METADATA_SUFFIX
309+
if os.path.isfile(cloud_metadata_name):
310+
os.remove(cloud_metadata_name)
297311
else:
298312
if recursive:
299313
shutil.rmtree(cloud_name)

cottoncandy/tests/test_roundtrip.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,3 +146,30 @@ def test_dict2cloud(cci, object_name):
146146
for k, v in content['deep'].items():
147147
assert np.allclose(v, dat['deep'][k])
148148
cci.rm(object_name, recursive=True)
149+
150+
151+
def test_copy(cci, object_name):
152+
# Tests that the object contents _and_ metadata are copied correctly
153+
dest_object_name = object_name + '_temp'
154+
for content in content_generator():
155+
cci.upload_raw_array(object_name, content)
156+
time.sleep(cci.wait_time)
157+
cci.cp(object_name, dest_object_name, overwrite=True)
158+
assert cci.exists_object(object_name)
159+
dat = cci.download_raw_array(dest_object_name)
160+
assert np.allclose(dat, content)
161+
cci.rm(object_name)
162+
cci.rm(dest_object_name)
163+
164+
165+
def test_move(cci, object_name):
166+
# Tests that the object contents _and_ metadata are moved correctly
167+
dest_object_name = object_name + '_temp'
168+
for content in content_generator():
169+
cci.upload_raw_array(object_name, content)
170+
time.sleep(cci.wait_time)
171+
cci.mv(object_name, dest_object_name, overwrite=True)
172+
assert not cci.exists_object(object_name)
173+
dat = cci.download_raw_array(dest_object_name)
174+
assert np.allclose(dat, content)
175+
cci.rm(dest_object_name)

0 commit comments

Comments
 (0)