1 |
1 |
#!/usr/bin/env python
|
2 |
2 |
|
|
3 |
# Copyright 2011 GRNET S.A. All rights reserved.
|
|
4 |
#
|
|
5 |
# Redistribution and use in source and binary forms, with or
|
|
6 |
# without modification, are permitted provided that the following
|
|
7 |
# conditions are met:
|
|
8 |
#
|
|
9 |
# 1. Redistributions of source code must retain the above
|
|
10 |
# copyright notice, this list of conditions and the following
|
|
11 |
# disclaimer.
|
|
12 |
#
|
|
13 |
# 2. Redistributions in binary form must reproduce the above
|
|
14 |
# copyright notice, this list of conditions and the following
|
|
15 |
# disclaimer in the documentation and/or other materials
|
|
16 |
# provided with the distribution.
|
|
17 |
#
|
|
18 |
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
|
|
19 |
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
20 |
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
21 |
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
|
|
22 |
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
23 |
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
24 |
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
|
25 |
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|
26 |
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
27 |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
28 |
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
29 |
# POSSIBILITY OF SUCH DAMAGE.
|
|
30 |
#
|
|
31 |
# The views and conclusions contained in the software and
|
|
32 |
# documentation are those of the authors and should not be
|
|
33 |
# interpreted as representing official policies, either expressed
|
|
34 |
# or implied, of GRNET S.A.
|
|
35 |
|
3 |
36 |
from getpass import getuser
|
4 |
37 |
from optparse import OptionParser
|
5 |
38 |
from os.path import basename
|
... | ... | |
132 |
165 |
t = _time.strptime(self.until, self.format)
|
133 |
166 |
params['until'] = int(_time.mktime(t))
|
134 |
167 |
|
135 |
|
l = self.client.list_objects(container, self.detail, params, headers)
|
136 |
|
print_list(l)
|
|
168 |
detail = 'json'
|
|
169 |
l = self.client.list_objects(container, detail, params, headers)
|
|
170 |
print_list(l, detail=self.detail)
|
137 |
171 |
|
138 |
172 |
@cli_command('meta')
|
139 |
173 |
class Meta(Command):
|
... | ... | |
294 |
328 |
headers = {}
|
295 |
329 |
if self.manifest:
|
296 |
330 |
headers['X_OBJECT_MANIFEST'] = self.manifest
|
297 |
|
|
298 |
|
attrs = ['etag', 'content-encoding', 'content-disposition']
|
299 |
331 |
|
300 |
332 |
attrs = ['etag', 'content-encoding', 'content-disposition',
|
301 |
333 |
'content-type']
|
... | ... | |
425 |
457 |
syntax = '<src container>/<src object> [<dst container>/]<dst object>'
|
426 |
458 |
description = 'moves an object to a different location'
|
427 |
459 |
|
428 |
|
def add_options(self, parser):
|
429 |
|
parser.add_option('--version', action='store',
|
430 |
|
dest='version', default=False,
|
431 |
|
help='move specific version')
|
432 |
|
|
433 |
460 |
def execute(self, src, dst):
|
434 |
461 |
src_container, sep, src_object = src.partition('/')
|
435 |
462 |
dst_container, sep, dst_object = dst.partition('/')
|
... | ... | |
437 |
464 |
dst_container = src_container
|
438 |
465 |
dst_object = dst
|
439 |
466 |
|
440 |
|
version = getattr(self, 'version')
|
441 |
|
if version:
|
442 |
|
headers = {}
|
443 |
|
headers['X_SOURCE_VERSION'] = version
|
444 |
467 |
self.client.move_object(src_container, src_object, dst_container,
|
445 |
468 |
dst_object, headers)
|
446 |
469 |
|
... | ... | |
500 |
523 |
commands.append(' %s %s' % (name.ljust(12), description))
|
501 |
524 |
print '\nCommands:\n' + '\n'.join(sorted(commands))
|
502 |
525 |
|
503 |
|
def print_dict(d, header='name', f=stdout):
|
|
526 |
def print_dict(d, header='name', f=stdout, detail=True):
|
504 |
527 |
header = header in d and header or 'subdir'
|
505 |
528 |
if header and header in d:
|
506 |
529 |
f.write('%s\n' %d.pop(header))
|
507 |
|
patterns = ['^x_(account|container|object)_meta_(\w+)$']
|
508 |
|
patterns.append(patterns[0].replace('_', '-'))
|
509 |
|
for key, val in sorted(d.items()):
|
510 |
|
for p in patterns:
|
511 |
|
p = re.compile(p)
|
512 |
|
m = p.match(key)
|
513 |
|
if m:
|
514 |
|
key = m.group(2)
|
515 |
|
f.write('%s: %s\n' % (key.rjust(30), val))
|
|
530 |
if detail:
|
|
531 |
patterns = ['^x_(account|container|object)_meta_(\w+)$']
|
|
532 |
patterns.append(patterns[0].replace('_', '-'))
|
|
533 |
for key, val in sorted(d.items()):
|
|
534 |
for p in patterns:
|
|
535 |
p = re.compile(p)
|
|
536 |
m = p.match(key)
|
|
537 |
if m:
|
|
538 |
key = m.group(2)
|
|
539 |
f.write('%s: %s\n' % (key.rjust(30), val))
|
516 |
540 |
|
517 |
|
def print_list(l, verbose=False, f=stdout):
|
|
541 |
def print_list(l, verbose=False, f=stdout, detail=True):
|
518 |
542 |
for elem in l:
|
519 |
543 |
#if it's empty string continue
|
520 |
544 |
if not elem:
|
521 |
545 |
continue
|
522 |
546 |
if type(elem) == types.DictionaryType:
|
523 |
|
print_dict(elem, f=f)
|
|
547 |
print_dict(elem, f=f, detail=detail)
|
524 |
548 |
elif type(elem) == types.StringType:
|
525 |
549 |
if not verbose:
|
526 |
550 |
elem = elem.split('Traceback')[0]
|