Browse code

2007-08-19 Michal Ludvig <michal@logix.cz>

* s3cmd: Better handling of multiple arguments for put, get and del




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

Michal Ludvig authored on 2007/08/18 22:27:28
Showing 2 changed files
... ...
@@ -1,3 +1,7 @@
1
+2007-08-19  Michal Ludvig  <michal@logix.cz>
2
+
3
+	* s3cmd: Better handling of multiple arguments for put, get and del
4
+
1 5
 2007-08-14  Michal Ludvig  <michal@logix.cz>
2 6
 
3 7
 	* setup.py, S3/Utils.py: Try import xml.etree.ElementTree
... ...
@@ -28,6 +28,11 @@ from S3 import Utils
28 28
 def output(message):
29 29
 	print message
30 30
 
31
+def check_args_type(args, type, verbose_type):
32
+	for arg in args:
33
+		if S3Uri(arg).type != type:
34
+			raise ParameterError("Expecting %s instead of '%s'" % (verbose_type, arg))
35
+
31 36
 def cmd_du(args):
32 37
 	s3 = S3(Config())
33 38
 	if len(args) > 0:
... ...
@@ -158,13 +163,13 @@ def cmd_object_put(args):
158 158
 	s3 = S3(Config())
159 159
 
160 160
 	uri_arg = args.pop()
161
-	files = args[:]
161
+	check_args_type(args, 'file', 'filename')
162 162
 
163 163
 	uri = S3Uri(uri_arg)
164 164
 	if uri.type != "s3":
165 165
 		raise ParameterError("Expecting S3 URI instead of '%s'" % uri_arg)
166 166
 
167
-	if len(files) > 1 and uri.object != "" and not Config().force:
167
+	if len(args) > 1 and uri.object() != "" and not Config().force:
168 168
 		error("When uploading multiple files the last argument must")
169 169
 		error("be a S3 URI specifying just the bucket name")
170 170
 		error("WITHOUT object name!")
... ...
@@ -172,9 +177,9 @@ def cmd_object_put(args):
172 172
 		error("object name will be prefixed to all stored filenames.")
173 173
 		sys.exit(1)
174 174
 	
175
-	for file in files:
175
+	for file in args:
176 176
 		uri_arg_final = str(uri)
177
-		if len(files) > 1 or uri.object() == "":
177
+		if len(args) > 1 or uri.object() == "":
178 178
 			uri_arg_final += os.path.basename(file)
179 179
 		
180 180
 		uri_final = S3Uri(uri_arg_final)
... ...
@@ -195,34 +200,62 @@ def cmd_object_put(args):
195 195
 def cmd_object_get(args):
196 196
 	s3 = S3(Config())
197 197
 
198
-	uri_arg = args.pop(0)
199
-	uri = S3Uri(uri_arg)
200
-	if uri.type != "s3" or not uri.has_object():
201
-		raise ParameterError("Expecting S3 URI instead of '%s'" % uri_arg)
198
+	if not S3Uri(args[0]).type == 's3':
199
+		raise ParameterError("Expecting S3 URI instead of '%s'" % args[0])
202 200
 
203
-	destination = len(args) > 0 and args.pop(0) or uri.object()
204
-	if os.path.isdir(destination):
205
-		destination += ("/" + uri.object())
206
-	if not Config().force and os.path.exists(destination):
207
-		raise ParameterError("File %s already exists. Use --force to overwrite it" % destination)
208
-	response = s3.object_get_uri(uri, destination)
209
-	if response["headers"].has_key("x-amz-meta-s3tools-gpgenc"):
210
-		gpg_decrypt(destination, response["headers"]["x-amz-meta-s3tools-gpgenc"])
211
-		response["size"] = os.stat(destination)[6]
212
-	if destination != "-":
213
-		output("Object %s saved as '%s' (%d bytes)" %
214
-			(uri, destination, response["size"]))
201
+	destination_dir = None
202
+	destination_file = None
203
+	if len(args) > 1:
204
+		if S3Uri(args[-1]).type == 's3':
205
+			# all S3, use object names to local dir
206
+			check_args_type(args, type="s3", verbose_type="S3 URI")	# May raise ParameterError
207
+		else:
208
+			if (len(args) > 2):
209
+				# last must be dir, all preceding S3
210
+				if not os.path.isdir(args[-1]):
211
+					raise ParameterError("Last parameter must be a directory")
212
+				destination_dir = args.pop()
213
+				check_args_type(args, type="s3", verbose_type="S3 URI")	# May raise ParameterError
214
+			else:
215
+				# last must be a dir or a filename
216
+				if os.path.isdir(args[-1]):
217
+					destination_dir = args.pop()
218
+				else:
219
+					destination_file = args.pop()
220
+
221
+	while (len(args)):
222
+		uri_arg = args.pop(0)
223
+		uri = S3Uri(uri_arg)
224
+
225
+		if destination_file:
226
+			destination = destination_file
227
+		elif destination_dir:
228
+			destination = destination_dir + "/" + uri.object()
229
+		else:
230
+			# By default the destination filename is the object name
231
+			destination = uri.object()
232
+
233
+		if not Config().force and os.path.exists(destination):
234
+			raise ParameterError("File %s already exists. Use --force to overwrite it" % destination)
235
+		response = s3.object_get_uri(uri, destination)
236
+		if response["headers"].has_key("x-amz-meta-s3tools-gpgenc"):
237
+			gpg_decrypt(destination, response["headers"]["x-amz-meta-s3tools-gpgenc"])
238
+			response["size"] = os.stat(destination)[6]
239
+		if destination != "-":
240
+			output("Object %s saved as '%s' (%d bytes)" %
241
+				(uri, destination, response["size"]))
215 242
 
216 243
 def cmd_object_del(args):
217 244
 	s3 = S3(Config())
218 245
 
219
-	uri_arg = args.pop(0)
220
-	uri = S3Uri(uri_arg)
221
-	if uri.type != "s3" or not uri.has_object():
222
-		raise ParameterError("Expecting S3 URI instead of '%s'" % uri_arg)
246
+	while (len(args)):
247
+		uri_arg = args.pop(0)
248
+		uri = S3Uri(uri_arg)
249
+		if uri.type != "s3" or not uri.has_object():
250
+			raise ParameterError("Expecting S3 URI instead of '%s'" % uri_arg)
223 251
 
224
-	response = s3.object_delete_uri(uri)
225
-	output("Object %s deleted" % uri)
252
+		response = s3.object_delete_uri(uri)
253
+		output("Object %s deleted" % uri)
226 254
 
227 255
 def resolve_list(lst, args):
228 256
 	retval = []