Browse code

* s3cmd: Support for 'cp' command. * S3/S3.py: Added S3.object.copy() method. * s3cmd.1: Document 'cp' command. * NEWS: Let everyone know ;-)

git-svn-id: https://s3tools.svn.sourceforge.net/svnroot/s3tools/s3cmd/trunk@262 830e0280-6d2a-0410-9c65-932aecc39d9d

Michal Ludvig authored on 2008/11/20 22:57:41
Showing 5 changed files
... ...
@@ -1,3 +1,12 @@
1
+2008-11-21  Michal Ludvig  <michal@logix.cz>
2
+
3
+	* s3cmd: Support for 'cp' command.
4
+	* S3/S3.py: Added S3.object.copy() method.
5
+	* s3cmd.1: Document 'cp' command.
6
+	* NEWS: Let everyone know ;-)
7
+	Thanks Andrew Ryan for a patch proposal!
8
+	https://sourceforge.net/forum/forum.php?thread_id=2346987&forum_id=618865
9
+
1 10
 2008-11-17  Michal Ludvig  <michal@logix.cz>
2 11
 
3 12
 	* S3/Progress.py: Two progress meter implementations.
... ...
@@ -4,6 +4,7 @@ s3cmd 0.9.9   -   ???
4 4
 * Removing of non-empty buckets with --force
5 5
 * Recursively remove objects from buckets with a given
6 6
   prefix with --recursive (-r)
7
+* Copying objects, within or between buckets. (Andrew Ryan)
7 8
 
8 9
 s3cmd 0.9.8.4 -   2008-11-07
9 10
 =============
... ...
@@ -199,6 +199,21 @@ class S3(object):
199 199
 		response = self.send_request(request)
200 200
 		return response
201 201
 
202
+	def object_copy(self, src_uri, dst_uri, extra_headers = None):
203
+		if src_uri.type != "s3":
204
+			raise ValueError("Expected URI type 's3', got '%s'" % src_uri.type)
205
+		if dst_uri.type != "s3":
206
+			raise ValueError("Expected URI type 's3', got '%s'" % dst_uri.type)
207
+		headers = SortedDict()
208
+		headers['x-amz-copy-source'] = "/%s/%s" % (src_uri.bucket(), self.urlencode_string(src_uri.object()))
209
+		if self.config.acl_public:
210
+			headers["x-amz-acl"] = "public-read"
211
+		if extra_headers:
212
+			headers.update(extra_headers)
213
+		request = self.create_request("OBJECT_PUT", uri = dst_uri, headers = headers)
214
+		response = self.send_request(request)
215
+		return response
216
+
202 217
 	def object_info(self, uri):
203 218
 		request = self.create_request("OBJECT_HEAD", uri = uri)
204 219
 		response = self.send_request(request)
... ...
@@ -308,6 +308,25 @@ def subcmd_object_del_uri(uri, recursive = None):
308 308
 		response = s3.object_delete(_uri)
309 309
 		output("Object %s deleted" % _uri)
310 310
 
311
+def cmd_cp(args):
312
+	s3 = S3(Config())
313
+	src_uri = S3Uri(args.pop(0))
314
+	dst_uri = S3Uri(args.pop(0))
315
+
316
+	if len(args): 
317
+		raise ParameterError("Too many parameters! Expected: %s" % commands['cp']['param']) 
318
+
319
+	if src_uri.type != "s3" or dst_uri.type != "s3": 
320
+		raise ParameterError("Parameters are not URIs! Expected: %s" % commands['cp']['param']) 
321
+
322
+	if dst_uri.object() == "":
323
+		dst_uri = S3Uri(dst_uri.uri() + src_uri.object())
324
+ 
325
+	response = s3.object_copy(src_uri, dst_uri) 
326
+	output("Object is copied to %s" % dst_uri)
327
+	if Config().acl_public:
328
+		output("Public URL is: %s" % dst_uri.public_url())
329
+
311 330
 def cmd_info(args):
312 331
 	s3 = S3(Config())
313 332
 
... ...
@@ -882,6 +901,7 @@ commands_list = [
882 882
 	{"cmd":"sync", "label":"Synchronize a directory tree to S3", "param":"LOCAL_DIR s3://BUCKET[/PREFIX] or s3://BUCKET[/PREFIX] LOCAL_DIR", "func":cmd_sync, "argc":2},
883 883
 	{"cmd":"du", "label":"Disk usage by buckets", "param":"[s3://BUCKET[/PREFIX]]", "func":cmd_du, "argc":0},
884 884
 	{"cmd":"info", "label":"Get various information about Buckets or Objects", "param":"s3://BUCKET[/OBJECT]", "func":cmd_info, "argc":1},
885
+	{"cmd":"cp", "label":"Copy object", "param":"s3://BUCKET1/OBJECT1 s3://BUCKET2[/OBJECT2]", "func":cmd_cp, "argc":2},
885 886
 	#{"cmd":"setacl", "label":"Modify Access control list for Bucket or Object", "param":"s3://BUCKET[/OBJECT]", "func":cmd_setacl, "argc":1},
886 887
 	]
887 888
 
... ...
@@ -42,6 +42,10 @@ Backup a directory tree to S3
42 42
 \fBsync\fR \fIs3://BUCKET[/PREFIX] LOCAL_DIR\fR
43 43
 Restore a tree from S3 to local directory
44 44
 .TP
45
+\fBcp\fR \fIs3://BUCKET1/OBJECT1 s3://BUCKET2[/OBJECT2]\fR 
46
+Make a copy of a file. Either in the same bucket with a different name
47
+or in another bucket with the same or different name.
48
+.TP 
45 49
 \fBinfo\fR \fIs3://BUCKET[/OBJECT]\fR
46 50
 Get various information about a Bucket or Object
47 51
 .TP