From a4c10cbcfd73fed26004cd2fe9c0665782f18297 Mon Sep 17 00:00:00 2001 From: Sofia Papagiannaki Date: Tue, 21 Jun 2011 14:49:37 +0300 Subject: [PATCH] add license & introduce include_trashed parameter (default False) in list_objects Refs #567 --- pithos/lib/client.py | 58 +++++++++++++++++++++++++++++++++++++-- tools/store | 74 +++++++++++++++++++++++++++++++++----------------- 2 files changed, 105 insertions(+), 27 deletions(-) diff --git a/pithos/lib/client.py b/pithos/lib/client.py index 2067d1b..0762a0b 100644 --- a/pithos/lib/client.py +++ b/pithos/lib/client.py @@ -1,3 +1,36 @@ +# Copyright 2011 GRNET S.A. All rights reserved. +# +# Redistribution and use in source and binary forms, with or +# without modification, are permitted provided that the following +# conditions are met: +# +# 1. Redistributions of source code must retain the above +# copyright notice, this list of conditions and the following +# disclaimer. +# +# 2. Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS +# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# The views and conclusions contained in the software and +# documentation are those of the authors and should not be +# interpreted as representing official policies, either expressed +# or implied, of GRNET S.A. + from httplib import HTTPConnection, HTTP from sys import stdin @@ -225,8 +258,29 @@ class Client(object): # Storage Container Services - def list_objects(self, container, detail=False, params=None, headers=None): - return self._list('/' + container, detail, params, headers) + def _filter(self, l, d): + """ + filter out from l elements having the metadata values provided + """ + ll = l + for elem in l: + if type(elem) == types.DictionaryType: + for key in d.keys(): + k = 'x_object_meta_%s' % key + if k in elem.keys() and elem[k] == d[key]: + ll.remove(elem) + break + return ll + + def _filter_trashed(self, l): + return self._filter(l, {'trash':'true'}) + + def list_objects(self, container, detail=False, params=None, headers=None, + include_trashed=False): + l = self._list('/' + container, detail, params, headers) + if not include_trashed: + l = self._filter_trashed(l) + return l def create_container(self, container, headers=None): status, header, data = self.put('/' + container, headers=headers) diff --git a/tools/store b/tools/store index 4c35262..2fa6873 100755 --- a/tools/store +++ b/tools/store @@ -1,5 +1,38 @@ #!/usr/bin/env python +# Copyright 2011 GRNET S.A. All rights reserved. +# +# Redistribution and use in source and binary forms, with or +# without modification, are permitted provided that the following +# conditions are met: +# +# 1. Redistributions of source code must retain the above +# copyright notice, this list of conditions and the following +# disclaimer. +# +# 2. Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS +# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# The views and conclusions contained in the software and +# documentation are those of the authors and should not be +# interpreted as representing official policies, either expressed +# or implied, of GRNET S.A. + from getpass import getuser from optparse import OptionParser from os.path import basename @@ -132,8 +165,9 @@ class List(Command): t = _time.strptime(self.until, self.format) params['until'] = int(_time.mktime(t)) - l = self.client.list_objects(container, self.detail, params, headers) - print_list(l) + detail = 'json' + l = self.client.list_objects(container, detail, params, headers) + print_list(l, detail=self.detail) @cli_command('meta') class Meta(Command): @@ -294,8 +328,6 @@ class PutObject(Command): headers = {} if self.manifest: headers['X_OBJECT_MANIFEST'] = self.manifest - - attrs = ['etag', 'content-encoding', 'content-disposition'] attrs = ['etag', 'content-encoding', 'content-disposition', 'content-type'] @@ -425,11 +457,6 @@ class MoveObject(Command): syntax = '/ [/]' description = 'moves an object to a different location' - def add_options(self, parser): - parser.add_option('--version', action='store', - dest='version', default=False, - help='move specific version') - def execute(self, src, dst): src_container, sep, src_object = src.partition('/') dst_container, sep, dst_object = dst.partition('/') @@ -437,10 +464,6 @@ class MoveObject(Command): dst_container = src_container dst_object = dst - version = getattr(self, 'version') - if version: - headers = {} - headers['X_SOURCE_VERSION'] = version self.client.move_object(src_container, src_object, dst_container, dst_object, headers) @@ -500,27 +523,28 @@ def print_usage(): commands.append(' %s %s' % (name.ljust(12), description)) print '\nCommands:\n' + '\n'.join(sorted(commands)) -def print_dict(d, header='name', f=stdout): +def print_dict(d, header='name', f=stdout, detail=True): header = header in d and header or 'subdir' if header and header in d: f.write('%s\n' %d.pop(header)) - patterns = ['^x_(account|container|object)_meta_(\w+)$'] - patterns.append(patterns[0].replace('_', '-')) - for key, val in sorted(d.items()): - for p in patterns: - p = re.compile(p) - m = p.match(key) - if m: - key = m.group(2) - f.write('%s: %s\n' % (key.rjust(30), val)) + if detail: + patterns = ['^x_(account|container|object)_meta_(\w+)$'] + patterns.append(patterns[0].replace('_', '-')) + for key, val in sorted(d.items()): + for p in patterns: + p = re.compile(p) + m = p.match(key) + if m: + key = m.group(2) + f.write('%s: %s\n' % (key.rjust(30), val)) -def print_list(l, verbose=False, f=stdout): +def print_list(l, verbose=False, f=stdout, detail=True): for elem in l: #if it's empty string continue if not elem: continue if type(elem) == types.DictionaryType: - print_dict(elem, f=f) + print_dict(elem, f=f, detail=detail) elif type(elem) == types.StringType: if not verbose: elem = elem.split('Traceback')[0] -- 1.7.10.4