commit db117cacc993603dc49638d0f4931ef98f7d3323
Author: Sofia Papagiannaki <papagian@gmail.com>
Date:   Tue Jun 26 19:09:47 2012 +0300

    Extend client library & pithos-sh to support mass delete/copy/remove
    
    Refs: #2611

diff --git a/snf-pithos-tools/pithos/tools/lib/client.py b/snf-pithos-tools/pithos/tools/lib/client.py
index 5dec80b..cbe88ac 100644
--- a/snf-pithos-tools/pithos/tools/lib/client.py
+++ b/snf-pithos-tools/pithos/tools/lib/client.py
@@ -460,7 +460,7 @@ class OOS_Client(Client):
     
     def _change_obj_location(self, src_container, src_object, dst_container,
                              dst_object, remove=False, meta={}, account=None,
-                             content_type=None, **headers):
+                             content_type=None, delimiter=None, **headers):
         account = account or self.account
         path = '/%s/%s/%s' % (account, dst_container, dst_object)
         headers = {} if not headers else headers
@@ -476,16 +476,18 @@ class OOS_Client(Client):
             headers['content_type'] = content_type
         else:
             params['ignore_content_type'] = ''
+        if delimiter:
+        	params['delimiter'] = delimiter
         return self.put(path, headers=headers, params=params)
     
     def copy_object(self, src_container, src_object, dst_container, dst_object,
-                   meta={}, account=None, content_type=None, **headers):
+                   meta={}, account=None, content_type=None, delimiter=None, **headers):
         """copies an object"""
         account = account or self.account
         return self._change_obj_location(src_container, src_object,
                                    dst_container, dst_object, account=account,
                                    remove=False, meta=meta,
-                                   content_type=content_type, **headers)
+                                   content_type=content_type, delimiter=delimiter, **headers)
     
     def move_object(self, src_container, src_object, dst_container,
                              dst_object, meta={}, account=None,
@@ -870,10 +872,12 @@ class Pithos_Client(OOS_Client):
         args['x_source_object'] = source
         return self.update_object(container, object, f=None, **args)
     
-    def delete_object(self, container, object, until=None, account=None):
+    def delete_object(self, container, object, until=None, account=None, delimiter=None):
         """deletes an object or the object history until the date provided"""
         account = account or self.account
         params = {'until':until} if until else {}
+        if delimiter:
+        	params['delimiter'] = delimiter
         return OOS_Client.delete_object(self, container, object, params, account)
     
     def trash_object(self, container, object):
@@ -908,7 +912,7 @@ class Pithos_Client(OOS_Client):
     
     def copy_object(self, src_container, src_object, dst_container, dst_object,
                     meta={}, public=False, version=None, account=None,
-                    content_type=None):
+                    content_type=None, delimiter=None):
         """copies an object"""
         account = account or self.account
         headers = {}
@@ -918,17 +922,19 @@ class Pithos_Client(OOS_Client):
         return OOS_Client.copy_object(self, src_container, src_object,
                                       dst_container, dst_object, meta=meta,
                                       account=account, content_type=content_type,
+                                      delimiter=delimiter,
                                       **headers)
     
     def move_object(self, src_container, src_object, dst_container,
                              dst_object, meta={}, public=False,
-                             account=None, content_type=None):
+                             account=None, content_type=None, delimiter=None):
         """moves an object"""
         headers = {}
         headers['x_object_public'] = public
         return OOS_Client.move_object(self, src_container, src_object,
                                       dst_container, dst_object, meta=meta,
                                       account=account, content_type=content_type,
+                                      delimiter=delimiter,
                                       **headers)
     
     def list_shared_by_others(self, limit=None, marker=None, format='text'):
diff --git a/snf-pithos-tools/pithos/tools/sh.py b/snf-pithos-tools/pithos/tools/sh.py
index 0a18478..255ccdb 100755
--- a/snf-pithos-tools/pithos/tools/sh.py
+++ b/snf-pithos-tools/pithos/tools/sh.py
@@ -256,6 +256,12 @@ class Delete(Command):
                           default=None, help='remove history until that date')
         parser.add_option('--format', action='store', dest='format',
                           default='%d/%m/%Y', help='format to parse until date')
+        parser.add_option('--delimiter', action='store', type='str',
+                          dest='delimiter', default=None,
+                          help='mass delete objects with path staring with <src object> + delimiter')
+        parser.add_option('-r', action='store_true',
+                          dest='recursive', default=False,
+                          help='mass delimiter objects with delimiter /')
     
     def execute(self, path):
         container, sep, object = path.partition('/')
@@ -265,7 +271,12 @@ class Delete(Command):
             until = int(_time.mktime(t))
         
         if object:
-            self.client.delete_object(container, object, until)
+            kwargs = {}
+            if self.delimiter:
+                kwargs['delimiter'] = self.delimiter
+            elif self.recursive:
+                kwargs['delimiter'] = '/'
+            self.client.delete_object(container, object, until, **kwargs)
         else:
             self.client.delete_container(container, until)
 
@@ -447,6 +458,12 @@ class CopyObject(Command):
         parser.add_option('--content-type', action='store',
                           dest='content_type', default=None,
                           help='change object\'s content type')
+        parser.add_option('--delimiter', action='store', type='str',
+                          dest='delimiter', default=None,
+                          help='mass copy objects with path staring with <src object> + delimiter')
+        parser.add_option('-r', action='store_true',
+                          dest='recursive', default=False,
+                          help='mass copy with delimiter /')
     
     def execute(self, src, dst, *args):
         src_container, sep, src_object = src.partition('/')
@@ -463,6 +480,10 @@ class CopyObject(Command):
             dst_object = dst
         
         args = {'content_type':self.content_type} if self.content_type else {}
+        if self.delimiter:
+        	args['delimiter'] = self.delimiter
+        elif self.recursive:
+        	args['delimiter'] = '/'
         self.client.copy_object(src_container, src_object, dst_container,
                                 dst_object, meta, self.public, self.version,
                                 **args)
@@ -576,6 +597,12 @@ class MoveObject(Command):
         parser.add_option('--content-type', action='store',
                           dest='content_type', default=None,
                           help='change object\'s content type')
+        parser.add_option('--delimiter', action='store', type='str',
+                          dest='delimiter', default=None,
+                          help='mass move objects with path staring with <src object> + delimiter')
+        parser.add_option('-r', action='store_true',
+                          dest='recursive', default=False,
+                          help='mass move objects with delimiter /')
     
     def execute(self, src, dst, *args):
         src_container, sep, src_object = src.partition('/')
@@ -591,6 +618,10 @@ class MoveObject(Command):
             meta[key] = val
         
         args = {'content_type':self.content_type} if self.content_type else {}
+        if self.delimiter:
+        	args['delimiter'] = self.delimiter
+        elif self.recursive:
+        	args['delimiter'] = '/'
         self.client.move_object(src_container, src_object, dst_container,
                                 dst_object, meta, self.public, **args)
 
