* 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
... | ... |
@@ -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 = [] |