pep8 kamaki.cli.commands
authorStavros Sachtouris <saxtouri@admin.grnet.gr>
Thu, 1 Nov 2012 13:20:14 +0000 (15:20 +0200)
committerStavros Sachtouris <saxtouri@admin.grnet.gr>
Thu, 1 Nov 2012 13:20:14 +0000 (15:20 +0200)
kamaki/cli/commands/__init__.py
kamaki/cli/commands/astakos_cli.py
kamaki/cli/commands/config_cli.py
kamaki/cli/commands/cyclades_cli.py
kamaki/cli/commands/history_cli.py
kamaki/cli/commands/image_cli.py
kamaki/cli/commands/pithos_cli.py
kamaki/cli/commands/quotaholder_cli.py
kamaki/clients/connection/tests.py [new file with mode: 0644]

index 802cc04..279b8ee 100644 (file)
@@ -31,6 +31,7 @@
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.command
 
+
 class _command_init(object):
     def __init__(self, arguments={}):
         self.arguments = arguments
@@ -40,4 +41,4 @@ class _command_init(object):
             pass
 
     def get_argument(self, argterm):
-       return self.arguments[argterm].value
\ No newline at end of file
+        return self.arguments[argterm].value
index 9eed43c..804eba7 100644 (file)
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.command
 
-
-from kamaki.cli import command#, set_api_description
-#set_api_description('astakos', 'Astakos API commands')
-API_DESCRIPTION = {'astakos':'Astakos API commands'}
+from kamaki.cli import command
 from kamaki.clients.astakos import AstakosClient, ClientError
 from kamaki.cli.utils import print_dict
 from kamaki.cli.errors import raiseCLIError
 from kamaki.cli.commands import _command_init
 
+
+API_DESCRIPTION = {'astakos': 'Astakos API commands'}
+
+
 class _astakos_init(_command_init):
     def main(self):
-        token = self.config.get('astakos', 'token') or self.config.get('global', 'token')
-        base_url = self.config.get('astakos', 'url') or self.config.get('global', 'url')
+        token = self.config.get('astakos', 'token')\
+            or self.config.get('global', 'token')
+        base_url = self.config.get('astakos', 'url')\
+            or self.config.get('global', 'url')
         if base_url is None:
             raise ClientError('no URL for astakos')
         self.client = AstakosClient(base_url=base_url, token=token)
 
+
 @command()
 class astakos_authenticate(_astakos_init):
     """Authenticate a user"""
@@ -58,4 +62,4 @@ class astakos_authenticate(_astakos_init):
             reply = self.client.authenticate()
         except ClientError as err:
             raiseCLIError(err)
-        print_dict(reply)
\ No newline at end of file
+        print_dict(reply)
index c339e64..d1f1a7d 100644 (file)
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.
 
-from kamaki.cli import command#, set_api_description
+from kamaki.cli import command
 from kamaki.cli.argument import FlagArgument
 from kamaki.cli.commands import _command_init
-#set_api_description('config', 'Configuration commands')
-API_DESCRIPTION = {'config':'Configuration commands'}
+
+
+API_DESCRIPTION = {'config': 'Configuration commands'}
+
 
 @command()
 class config_list(_command_init):
@@ -52,6 +54,7 @@ class config_list(_command_init):
             for key, val in sorted(items):
                 print('%s.%s = %s' % (section, key, val))
 
+
 @command()
 class config_get(_command_init):
     """Show a configuration option"""
@@ -63,6 +66,7 @@ class config_get(_command_init):
         if value is not None:
             print(value)
 
+
 @command()
 class config_set(_command_init):
     """Set a configuration option"""
@@ -73,6 +77,7 @@ class config_set(_command_init):
         self.config.set(section, key, value)
         self.config.write()
 
+
 @command()
 class config_delete(_command_init):
     """Delete a configuration option (and use the default value)"""
index a3a4896..9b75447 100644 (file)
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.
 
-API_DESCRIPTION = {'server':'Compute/Cyclades API server commands',
-    'flavor':'Compute/Cyclades API flavor commands',
-    'image':'Compute/Cyclades or Glance API image commands',
-    'network': 'Compute/Cyclades API network commands'}
-
 from kamaki.cli import command
-from kamaki.cli.utils import print_dict, print_items, print_list, format_size, bold
-from kamaki.cli.errors import CLIError, raiseCLIError
+from kamaki.cli.utils import print_dict, print_items, print_list, bold
+from kamaki.cli.errors import CLIError, raiseCLIError, CLISyntaxError
 from kamaki.clients.cyclades import CycladesClient, ClientError
 from kamaki.cli.argument import FlagArgument, ValueArgument
 from kamaki.cli.commands import _command_init
 
 from base64 import b64encode
-from os.path import abspath, exists
+from os.path import exists
+
+
+API_DESCRIPTION = {'server': 'Compute/Cyclades API server commands',
+    'flavor': 'Compute/Cyclades API flavor commands',
+    'image': 'Compute/Cyclades or Glance API image commands',
+    'network': 'Compute/Cyclades API network commands'}
+
 
 class _init_cyclades(_command_init):
     def main(self, service='compute'):
-        token = self.config.get(service, 'token') or self.config.get('global', 'token')
-        base_url = self.config.get(service, 'url') or self.config.get('global', 'url')
+        token = self.config.get(service, 'token')\
+            or self.config.get('global', 'token')
+        base_url = self.config.get(service, 'url')\
+            or self.config.get('global', 'url')
         self.client = CycladesClient(base_url=base_url, token=token)
 
+
 @command()
 class server_list(_init_cyclades):
     """List servers"""
@@ -64,7 +69,7 @@ class server_list(_init_cyclades):
         for server in servers:
             sname = server.pop('name')
             sid = server.pop('id')
-            print('%s (%s)'%(bold(sname), bold(unicode(sid))))
+            print('%s (%s)' % (bold(sname), bold(unicode(sid))))
             if self.get_argument('detail'):
                 server_info._print(server)
                 print('- - -')
@@ -78,23 +83,24 @@ class server_list(_init_cyclades):
         except ClientError as err:
             raiseCLIError(err)
 
+
 @command()
 class server_info(_init_cyclades):
     """Get server details"""
 
     @classmethod
-    def _print(self,server):
+    def _print(self, server):
         addr_dict = {}
-        if server.has_key('attachments'):
+        if 'attachments' in server:
             for addr in server['attachments']['values']:
                 ips = addr.pop('values', [])
                 for ip in ips:
-                    addr['IPv%s'%ip['version']] = ip['addr']
-                if addr.has_key('firewallProfile'):
+                    addr['IPv%s' % ip['version']] = ip['addr']
+                if 'firewallProfile' in addr:
                     addr['firewall'] = addr.pop('firewallProfile')
                 addr_dict[addr.pop('id')] = addr
             server['attachments'] = addr_dict if addr_dict is not {} else None
-        if server.has_key('metadata'):
+        if 'metadata' in server:
             server['metadata'] = server['metadata']['values']
         print_dict(server, ident=14)
 
@@ -109,21 +115,25 @@ class server_info(_init_cyclades):
                 importance=1)
         self._print(server)
 
+
 class PersonalityArgument(ValueArgument):
-    @property 
+    @property
     def value(self):
         return [self._value] if hasattr(self, '_value') else []
-    @value.setter 
+
+    @value.setter
     def value(self, newvalue):
         if newvalue == self.default:
             return self.value
         termlist = newvalue.split()
         if len(termlist) > 4:
-                raise CLISyntaxError(details='Wrong number of personality terms ("PATH [OWNER [GROUP [MODE]]]"')
+                raise CLISyntaxError(details='Wrong number of terms'\
+                    + ' ("PATH [OWNER [GROUP [MODE]]]"')
         path = termlist[0]
         self._value = dict(path=path)
         if not exists(path):
-            raise CLIError(message="File %s does not exist" % path, importance=1)
+            raise CLIError(message="File %s does not exist" % path,
+                importance=1)
         with open(path) as f:
             self._value['contents'] = b64encode(f.read())
         try:
@@ -133,14 +143,16 @@ class PersonalityArgument(ValueArgument):
         except IndexError:
             pass
 
+
 @command()
 class server_create(_init_cyclades):
     """Create a server"""
 
     def __init__(self, arguments={}):
         super(server_create, self).__init__(arguments)
-        self.arguments['personality'] = PersonalityArgument(parsed_name='--personality',
-            help='add a personality file ( "PATH [OWNER [GROUP [MODE]]]" )')
+        self.arguments['personality'] = PersonalityArgument(\
+            help='add a personality file ( "PATH [OWNER [GROUP [MODE]]]" )',
+            parsed_name='--personality')
 
     def update_parser(self, parser):
         parser.add_argument('--personality', dest='personalities',
@@ -151,12 +163,15 @@ class server_create(_init_cyclades):
     def main(self, name, flavor_id, image_id):
         super(self.__class__, self).main()
         try:
-            reply = self.client.create_server(name, int(flavor_id), image_id,
+            reply = self.client.create_server(name,
+                int(flavor_id),
+                image_id,
                 self.get_argument('personality'))
         except ClientError as err:
             raiseCLIError(err)
         print_dict(reply)
 
+
 @command()
 class server_rename(_init_cyclades):
     """Update a server's name"""
@@ -168,7 +183,9 @@ class server_rename(_init_cyclades):
         except ClientError as err:
             raiseCLIError(err)
         except ValueError:
-            raise CLIError(message='Server id must be positive integer', importance=1)
+            raise CLIError(message='Server id must be positive integer',
+                importance=1)
+
 
 @command()
 class server_delete(_init_cyclades):
@@ -181,7 +198,9 @@ class server_delete(_init_cyclades):
         except ClientError as err:
             raiseCLIError(err)
         except ValueError:
-            raise CLIError(message='Server id must be positive integer', importance=1)
+            raise CLIError(message='Server id must be positive integer',
+                importance=1)
+
 
 @command()
 class server_reboot(_init_cyclades):
@@ -194,11 +213,14 @@ class server_reboot(_init_cyclades):
     def main(self, server_id):
         super(self.__class__, self).main()
         try:
-            self.client.reboot_server(int(server_id), self.get_argument('hard'))
+            self.client.reboot_server(int(server_id),
+                self.get_argument('hard'))
         except ClientError as err:
             raiseCLIError(err)
         except ValueError:
-            raise CLIError(message='Server id must be positive integer', importance=1)
+            raise CLIError(message='Server id must be positive integer',
+                importance=1)
+
 
 @command()
 class server_start(_init_cyclades):
@@ -211,7 +233,9 @@ class server_start(_init_cyclades):
         except ClientError as err:
             raiseCLIError(err)
         except ValueError:
-            raise CLIError(message='Server id must be positive integer', importance=1)
+            raise CLIError(message='Server id must be positive integer',
+                importance=1)
+
 
 @command()
 class server_shutdown(_init_cyclades):
@@ -224,7 +248,9 @@ class server_shutdown(_init_cyclades):
         except ClientError as err:
             raiseCLIError(err)
         except ValueError:
-            raise CLIError(message='Server id must be positive integer', importance=1)
+            raise CLIError(message='Server id must be positive integer',
+                importance=1)
+
 
 @command()
 class server_console(_init_cyclades):
@@ -237,9 +263,11 @@ class server_console(_init_cyclades):
         except ClientError as err:
             raiseCLIError(err)
         except ValueError:
-            raise CLIError(message='Server id must be positive integer', importance=1)
+            raise CLIError(message='Server id must be positive integer',
+                importance=1)
         print_dict(reply)
 
+
 @command()
 class server_firewall(_init_cyclades):
     """Set the server's firewall profile"""
@@ -251,7 +279,9 @@ class server_firewall(_init_cyclades):
         except ClientError as err:
             raiseCLIError(err)
         except ValueError:
-            raise CLIError(message='Server id must be positive integer', importance=1)
+            raise CLIError(message='Server id must be positive integer',
+                importance=1)
+
 
 @command()
 class server_addr(_init_cyclades):
@@ -264,9 +294,11 @@ class server_addr(_init_cyclades):
         except ClientError as err:
             raiseCLIError(err)
         except ValueError:
-            raise CLIError(message='Server id must be positive integer', importance=1)
+            raise CLIError(message='Server id must be positive integer',
+                importance=1)
         print_list(reply)
 
+
 @command()
 class server_meta(_init_cyclades):
     """Get a server's metadata"""
@@ -276,11 +308,13 @@ class server_meta(_init_cyclades):
         try:
             reply = self.client.get_server_metadata(int(server_id), key)
         except ValueError:
-            raise CLIError(message='Server id must be positive integer', importance=1)
+            raise CLIError(message='Server id must be positive integer',
+                importance=1)
         except ClientError as err:
             raiseCLIError(err)
         print_dict(reply)
 
+
 @command()
 class server_addmeta(_init_cyclades):
     """Add server metadata"""
@@ -288,13 +322,16 @@ class server_addmeta(_init_cyclades):
     def main(self, server_id, key, val):
         super(self.__class__, self).main()
         try:
-            reply = self.client.create_server_metadata(int(server_id), key, val)
+            reply = self.client.create_server_metadata(\
+                int(server_id), key, val)
         except ClientError as err:
             raiseCLIError(err)
         except ValueError:
-            raise CLIError(message='Server id must be positive integer', importance=1)
+            raise CLIError(message='Server id must be positive integer',
+                importance=1)
         print_dict(reply)
 
+
 @command()
 class server_setmeta(_init_cyclades):
     """Update server's metadata"""
@@ -303,13 +340,16 @@ class server_setmeta(_init_cyclades):
         super(self.__class__, self).main()
         metadata = {key: val}
         try:
-            reply = self.client.update_server_metadata(int(server_id), **metadata)
+            reply = self.client.update_server_metadata(int(server_id),
+                **metadata)
         except ClientError as err:
             raiseCLIError(err)
         except ValueError:
-            raise CLIError(message='Server id must be positive integer', importance=1)
+            raise CLIError(message='Server id must be positive integer',
+                importance=1)
         print_dict(reply)
 
+
 @command()
 class server_delmeta(_init_cyclades):
     """Delete server metadata"""
@@ -321,7 +361,9 @@ class server_delmeta(_init_cyclades):
         except ClientError as err:
             raiseCLIError(err)
         except ValueError:
-            raise CLIError(message='Server id must be positive integer', importance=1)
+            raise CLIError(message='Server id must be positive integer',
+                importance=1)
+
 
 @command()
 class server_stats(_init_cyclades):
@@ -334,9 +376,11 @@ class server_stats(_init_cyclades):
         except ClientError as err:
             raiseCLIError(err)
         except ValueError:
-            raise CLIError(message='Server id must be positive integer', importance=1)
+            raise CLIError(message='Server id must be positive integer',
+                importance=1)
         print_dict(reply, exclude=('serverRef',))
 
+
 @command()
 class flavor_list(_init_cyclades):
     """List flavors"""
@@ -353,6 +397,7 @@ class flavor_list(_init_cyclades):
             raiseCLIError(err)
         print_items(flavors)
 
+
 @command()
 class flavor_info(_init_cyclades):
     """Get flavor details"""
@@ -364,9 +409,11 @@ class flavor_info(_init_cyclades):
         except ClientError as err:
             raiseCLIError(err)
         except ValueError:
-            raise CLIError(message='Server id must be positive integer', importance=1)
+            raise CLIError(message='Server id must be positive integer',
+                importance=1)
         print_dict(flavor)
 
+
 @command()
 class network_list(_init_cyclades):
     """List networks"""
@@ -379,7 +426,7 @@ class network_list(_init_cyclades):
         for net in nets:
             netname = bold(net.pop('name'))
             netid = bold(unicode(net.pop('id')))
-            print('%s (%s)'%(netname, netid))
+            print('%s (%s)' % (netname, netid))
             if self.get_argument('detail'):
                 network_info.print_network(net)
 
@@ -391,35 +438,42 @@ class network_list(_init_cyclades):
             raiseCLIError(err)
         self.print_networks(networks)
 
+
 @command()
 class network_create(_init_cyclades):
     """Create a network"""
 
     def __init__(self, arguments={}):
         super(network_create, self).__init__(arguments)
-        self.arguments['cidr'] = ValueArgument('specific cidr for new network', '--with-cidr')
-        self.arguments['gateway'] = ValueArgument('specific gateway for new network',
-            '--with-gateway')
-        self.arguments['dhcp'] = ValueArgument('specific dhcp for new network', '--with-dhcp')
-        self.arguments['type'] = ValueArgument('specific type for new network', '--with-type')
+        self.arguments['cidr'] =\
+            ValueArgument('specific cidr for new network', '--with-cidr')
+        self.arguments['gateway'] =\
+            ValueArgument('specific gateway for new network', '--with-gateway')
+        self.arguments['dhcp'] =\
+            ValueArgument('specific dhcp for new network', '--with-dhcp')
+        self.arguments['type'] =\
+            ValueArgument('specific type for new network', '--with-type')
 
     def main(self, name):
         super(self.__class__, self).main()
         try:
-            reply = self.client.create_network(name, cidr= self.get_argument('cidr'),
-                gateway=self.get_argument('gateway'), dhcp=self.get_argument('dhcp'),
+            reply = self.client.create_network(name,
+                cidr=self.get_argument('cidr'),
+                gateway=self.get_argument('gateway'),
+                dhcp=self.get_argument('dhcp'),
                 type=self.get_argument('type'))
         except ClientError as err:
             raiseCLIError(err)
         print_dict(reply)
 
+
 @command()
 class network_info(_init_cyclades):
     """Get network details"""
 
     @classmethod
     def print_network(self, net):
-        if net.has_key('attachments'):
+        if 'attachments' in net:
             att = net['attachments']['values']
             net['attachments'] = att if len(att) > 0 else None
         print_dict(net, ident=14)
@@ -432,6 +486,7 @@ class network_info(_init_cyclades):
             raiseCLIError(err)
         network_info.print_network(network)
 
+
 @command()
 class network_rename(_init_cyclades):
     """Update network name"""
@@ -443,6 +498,7 @@ class network_rename(_init_cyclades):
         except ClientError as err:
             raiseCLIError(err)
 
+
 @command()
 class network_delete(_init_cyclades):
     """Delete a network"""
@@ -454,6 +510,7 @@ class network_delete(_init_cyclades):
         except ClientError as err:
             raiseCLIError(err)
 
+
 @command()
 class network_connect(_init_cyclades):
     """Connect a server to a network"""
@@ -465,6 +522,7 @@ class network_connect(_init_cyclades):
         except ClientError as err:
             raiseCLIError(err)
 
+
 @command()
 class network_disconnect(_init_cyclades):
     """Disconnect a nic that connects a server to a network"""
index ff9acb0..aee76b4 100644 (file)
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.
 
-API_DESCRIPTION=dict(history='Command history')
-
-from kamaki.cli.argument import IntArgument, ValueArgument, FlagArgument
+from kamaki.cli.argument import IntArgument, ValueArgument
 from kamaki.cli.history import History
-from kamaki.cli.utils import print_list
 from kamaki.cli import command
 from kamaki.cli.commands import _command_init
 
+
+API_DESCRIPTION = {'history': 'Command history'}
+
+
 class _init_history(_command_init):
-       def main(self):
-               self.history = History(self.config.get('history', 'file'))
+    def main(self):
+        self.history = History(self.config.get('history', 'file'))
+
 
 @command()
 class history(_init_history):
-       """Show history [containing terms...]"""
+    """Show history [containing terms...]"""
+
+    def __init__(self, arguments={}):
+        super(history, self).__init__(arguments)
+        self.arguments['limit'] =\
+            IntArgument('number of lines to show', '-n', default=0)
+        self.arguments['match'] =\
+            ValueArgument('show lines that match all given terms', '--match')
 
-       def __init__(self, arguments={}):
-               super(history, self).__init__(arguments)
-               self.arguments['limit'] = IntArgument('number of lines to show', '-n', default=0)
-               self.arguments['match'] = ValueArgument('show lines that match all given terms', '--match')
+    def main(self):
+        super(history, self).main()
+        ret = self.history.get(match_terms=self.get_argument('match'),
+            limit=self.get_argument('limit'))
+        print(''.join(ret))
 
-       def main(self):
-               super(history, self).main()
-               ret = self.history.get(match_terms = self.get_argument('match'),
-                       limit=self.get_argument('limit'))
-               print(''.join(ret))
 
 @command()
 class history_clean(_init_history):
-       """Clean up history"""
+    """Clean up history"""
 
-       def main(self):
-               super(history_clean, self).main()
-               self.history.clean()
+    def main(self):
+        super(history_clean, self).main()
+        self.history.clean()
index 300e5c2..74a91bb 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright 2011-2012 GRNET S.A. All rights reserved.
+# Copyright 2012 GRNET S.A. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or
 # without modification, are permitted provided that the following
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.command
 
-API_DESCRIPTION = {'image':'Compute/Cyclades or Glance API image commands'}
-
 from kamaki.cli import command
 from kamaki.cli.errors import raiseCLIError
 from kamaki.cli.utils import print_dict, print_items, bold
 from kamaki.clients.image import ImageClient, ClientError
-from kamaki.cli.argument import FlagArgument, ValueArgument, KeyValueArgument, IntArgument
+from kamaki.cli.argument import\
+    FlagArgument, ValueArgument, KeyValueArgument, IntArgument
 from kamaki.cli.commands.cyclades_cli import _init_cyclades
 from kamaki.cli.commands import _command_init
 
+
+API_DESCRIPTION = {'image': 'Compute/Cyclades or Glance API image commands'}
+
+
 class _init_image(_command_init):
     def main(self):
         try:
-            token = self.config.get('image', 'token') or self.config.get('global', 'token')
-            base_url = self.config.get('image', 'url') or self.config.get('global', 'url')
+            token = self.config.get('image', 'token')\
+                or self.config.get('compute', 'token')\
+                or self.config.get('global', 'token')
+            base_url = self.config.get('image', 'url')\
+                or self.config.get('compute', 'url')\
+                or self.config.get('global', 'url')
             self.client = ImageClient(base_url=base_url, token=token)
         except ClientError as err:
             raiseCLIError(err)
 
+
 @command()
 class image_public(_init_image):
     """List public images"""
@@ -57,32 +65,43 @@ class image_public(_init_image):
     def __init__(self, arguments={}):
         super(image_public, self).__init__(arguments)
         self.arguments['detail'] = FlagArgument('show detailed output', '-l')
-        self.arguments['container_format'] = ValueArgument('filter by container format',
-            '--container-format')
-        self.arguments['disk_format'] = ValueArgument('filter by disk format', '--disk-format')
+        self.arguments['container_format'] =\
+            ValueArgument('filter by container format', '--container-format')
+        self.arguments['disk_format'] =\
+            ValueArgument('filter by disk format', '--disk-format')
         self.arguments['name'] = ValueArgument('filter by name', '--name')
-        self.arguments['size_min'] = IntArgument('filter by minimum size', '--size-min')
-        self.arguments['size_max'] = IntArgument('filter by maximum size', '--size-max')
-        self.arguments['status'] = ValueArgument('filter by status', '--status')
-        self.arguments['order'] = ValueArgument('order by FIELD (use a - prefix to reverse order)',
+        self.arguments['size_min'] =\
+            IntArgument('filter by minimum size', '--size-min')
+        self.arguments['size_max'] =\
+            IntArgument('filter by maximum size', '--size-max')
+        self.arguments['status'] =\
+            ValueArgument('filter by status', '--status')
+        self.arguments['order'] =\
+            ValueArgument('order by FIELD (use a - prefix to reverse order)',
             '--order', default='')
 
     def main(self):
         super(self.__class__, self).main()
         filters = {}
-        for arg in ('container_format', 'disk_format', 'name', 'size_min', 'size_max', 'status'):
+        for arg in ('container_format',
+            'disk_format',
+            'name',
+            'size_min',
+            'size_max',
+            'status'):
             val = self.get_argument(arg)
             if val is not None:
                 filters[arg] = val
 
         order = self.get_argument('order')
+        detail = self.get_argument('detail')
         try:
-            images = self.client.list_public(self.get_argument('detail'), filters=filters,
-                order=order)
+            images = self.client.list_public(detail, filters, order)
         except ClientError as err:
             raiseCLIError(err)
         print_items(images, title=('name',))
 
+
 @command()
 class image_meta(_init_image):
     """Get image metadata"""
@@ -95,21 +114,27 @@ class image_meta(_init_image):
             raiseCLIError(err)
         print_dict(image)
 
+
 @command()
 class image_register(_init_image):
     """Register an image"""
 
     def __init__(self, arguments={}):
         super(image_register, self).__init__(arguments)
-        self.arguments['checksum'] = ValueArgument('set image checksum', '--checksum')
-        self.arguments['container_format'] = ValueArgument('set container format',
-            '--container-format')
-        self.arguments['disk_format'] = ValueArgument('set disk format', '--disk-format')
+        self.arguments['checksum'] =\
+            ValueArgument('set image checksum', '--checksum')
+        self.arguments['container_format'] =\
+            ValueArgument('set container format', '--container-format')
+        self.arguments['disk_format'] =\
+            ValueArgument('set disk format', '--disk-format')
         self.arguments['id'] = ValueArgument('set image ID', '--id')
-        self.arguments['owner'] = ValueArgument('set image owner (admin only)', '--owner')
-        self.arguments['properties'] = KeyValueArgument(parsed_name='--properties',
-            help = 'add properties in the form key1=val1,key2=val2,...')
-        self.arguments['is_public'] = FlagArgument('mark image as public', '--public')
+        self.arguments['owner'] =\
+            ValueArgument('set image owner (admin only)', '--owner')
+        self.arguments['properties'] =\
+            KeyValueArgument(parsed_name='--properties',
+            help='add properties in the form key1=val1,key2=val2,...')
+        self.arguments['is_public'] =\
+            FlagArgument('mark image as public', '--public')
         self.arguments['size'] = IntArgument('set image size', '--size')
 
     def main(self, name, location):
@@ -121,21 +146,31 @@ class image_register(_init_image):
                 account = account[:-1]
             container = self.config.get('store', 'container') \
                 or self.config.get('global', 'container')
-            location = 'pithos://%s/%s'%(account, location) \
-                if container is None or len(container) == 0 \
-                else 'pithos://%s/%s/%s' % (account, container, location)
+            if container is None or len(container) == 0:
+                location = 'pithos://%s/%s' % (account, location)
+            else:
+                location = 'pithos://%s/%s/%s' % (account, container, location)
 
         params = {}
-        for key in ('checksum','container_format','disk_format','id','owner','size','is_public'):
+        for key in ('checksum',
+            'container_format',
+            'disk_format', 'id',
+            'owner',
+            'size',
+            'is_public'):
             val = self.get_argument(key)
             if val is not None:
                 params[key] = val
 
         try:
-            self.client.register(name, location, params, self.get_argument('properties'))
+            self.client.register(name,
+                location,
+                params,
+                self.get_argument('properties'))
         except ClientError as err:
             raiseCLIError(err)
 
+
 @command()
 class image_members(_init_image):
     """Get image members"""
@@ -149,6 +184,7 @@ class image_members(_init_image):
         for member in members:
             print(member['member_id'])
 
+
 @command()
 class image_shared(_init_image):
     """List shared images"""
@@ -162,6 +198,7 @@ class image_shared(_init_image):
         for image in images:
             print(image['image_id'])
 
+
 @command()
 class image_addmember(_init_image):
     """Add a member to an image"""
@@ -173,6 +210,7 @@ class image_addmember(_init_image):
         except ClientError as err:
             raiseCLIError(err)
 
+
 @command()
 class image_delmember(_init_image):
     """Remove a member from an image"""
@@ -184,6 +222,7 @@ class image_delmember(_init_image):
         except ClientError as err:
             raiseCLIError(err)
 
+
 @command()
 class image_setmembers(_init_image):
     """Set the members of an image"""
@@ -208,7 +247,7 @@ class image_list(_init_cyclades):
         for img in images:
             iname = img.pop('name')
             iid = img.pop('id')
-            print('%s (%s)'%(bold(iname), bold(unicode(iid))))
+            print('%s (%s)' % (bold(iname), bold(unicode(iid))))
             if self.get_argument('detail'):
                 image_info._print(img)
 
@@ -220,13 +259,14 @@ class image_list(_init_cyclades):
             raiseCLIError(err)
         self._print(images)
 
+
 @command()
 class image_info(_init_cyclades):
     """Get image details"""
 
     @classmethod
     def _print(self, image):
-        if image.has_key('metadata'):
+        if 'metadata' in image:
             image['metadata'] = image['metadata']['values']
         print_dict(image, ident=14)
 
@@ -238,6 +278,7 @@ class image_info(_init_cyclades):
             raiseCLIError(err)
         self._print(image)
 
+
 @command()
 class image_delete(_init_cyclades):
     """Delete image"""
@@ -249,6 +290,7 @@ class image_delete(_init_cyclades):
         except ClientError as err:
             raiseCLIError(err)
 
+
 @command()
 class image_properties(_init_cyclades):
     """Get image properties"""
@@ -261,6 +303,7 @@ class image_properties(_init_cyclades):
             raiseCLIError(err)
         print_dict(reply)
 
+
 @command()
 class image_addproperty(_init_cyclades):
     """Add an image property"""
@@ -273,6 +316,7 @@ class image_addproperty(_init_cyclades):
             raiseCLIError(err)
         print_dict(reply)
 
+
 @command()
 class image_setproperty(_init_cyclades):
     """Update an image property"""
@@ -286,6 +330,7 @@ class image_setproperty(_init_cyclades):
             raiseCLIError(err)
         print_dict(reply)
 
+
 @command()
 class image_delproperty(_init_cyclades):
     """Delete an image property"""
@@ -295,4 +340,4 @@ class image_delproperty(_init_cyclades):
         try:
             self.client.delete_image_metadata(image_id, key)
         except ClientError as err:
-            raiseCLIError(err)
\ No newline at end of file
+            raiseCLIError(err)
index ac290ab..9700efd 100644 (file)
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.command
 
-from kamaki.cli import command#, set_api_description
-from kamaki.clients.utils import filter_in
+from kamaki.cli import command
 from kamaki.cli.errors import CLIError, raiseCLIError
-from kamaki.cli.utils import format_size, print_dict, pretty_keys, print_list
+from kamaki.cli.utils import format_size, print_dict, pretty_keys
 from kamaki.cli.argument import FlagArgument, ValueArgument, IntArgument
 from kamaki.cli.commands import _command_init
-#set_api_description('store', 'Pithos+ storage commands')
-API_DESCRIPTION = dict(store='Pithos+ storage commands')
 from kamaki.clients.pithos import PithosClient, ClientError
 from kamaki.cli.utils import bold
-from sys import stdout, exit
-import signal
-from time import localtime, strftime, strptime, mktime
+from sys import stdout
+from time import localtime, strftime
 from datetime import datetime as dtm
 
+
+API_DESCRIPTION = dict(store='Pithos+ storage commands')
+
 try:
     from progress.bar import IncrementalBar
 except ImportError:
-    #progress not installed - pls, pip install progress
+    # progress not installed - pls, pip install progress
     pass
 
-#Argument functionality
+# Argument functionality
+
+
 class DelimiterArgument(ValueArgument):
     def __init__(self, caller_obj, help='', parsed_name=None, default=None):
         super(DelimiterArgument, self).__init__(help, parsed_name, default)
         self.caller_obj = caller_obj
 
-    @property 
+    @property
     def value(self):
         if self.caller_obj.get_argument('recursive'):
             return '/'
         return getattr(self, '_value', self.default)
-    @value.setter 
+
+    @value.setter
     def value(self, newvalue):
         self._value = newvalue
 
+
 class MetaArgument(ValueArgument):
-    @property 
+    @property
     def value(self):
         if self._value is None:
             return self.default
         metadict = dict()
         for metastr in self._value.split('_'):
-            (key,val) = metastr.split(':')
-            metadict[key]=val
+            (key, val) = metastr.split(':')
+            metadict[key] = val
         return metadict
+
     @value.setter
     def value(self, newvalue):
         if newvalue is None:
             self._value = self.default
         self._value = newvalue
 
+
 class ProgressBarArgument(FlagArgument):
 
     def __init__(self, help='', parsed_name='', default=True):
@@ -93,13 +98,15 @@ class ProgressBarArgument(FlagArgument):
         except NameError:
             print('Waring: no progress bar functionality')
 
-    @property 
+    @property
     def value(self):
         return getattr(self, '_value', self.default)
-    @value.setter 
+
+    @value.setter
     def value(self, newvalue):
         """By default, it is on (True)"""
         self._value = not newvalue
+
     def get_generator(self, message, message_len=25):
         try:
             bar = ProgressBar(message.ljust(message_len))
@@ -107,9 +114,11 @@ class ProgressBarArgument(FlagArgument):
             return None
         return bar.get_generator()
 
+
 try:
     class ProgressBar(IncrementalBar):
         suffix = '%(percent)d%% - %(eta)ds'
+
         def get_generator(self):
             def progress_gen(n):
                 for i in self.iter(range(n)):
@@ -119,10 +128,12 @@ try:
 except NameError:
     pass
 
+
 class SharingArgument(ValueArgument):
-    @property 
+    @property
     def value(self):
         return getattr(self, '_value', self.default)
+
     @value.setter
     def value(self, newvalue):
         perms = {}
@@ -132,23 +143,29 @@ class SharingArgument(ValueArgument):
             return
         for p in permlist:
             try:
-                (key,val) = p.split('=')
+                (key, val) = p.split('=')
             except ValueError:
-                raise CLIError(message='Error in --sharing', details='Incorrect format', importance=1)
+                raise CLIError(message='Error in --sharing',
+                    details='Incorrect format',
+                    importance=1)
             if key.lower() not in ('read', 'write'):
-                raise CLIError(message='Error in --sharing', details='Invalid permition key %s'%key, importance=1)
+                raise CLIError(message='Error in --sharing',
+                    details='Invalid permition key %s' % key,
+                    importance=1)
             val_list = val.split(',')
-            if not perms.has_key(key):
-                perms[key]=[]
+            if not key in perms:
+                perms[key] = []
             for item in val_list:
                 if item not in perms[key]:
                     perms[key].append(item)
         self._value = perms
 
+
 class RangeArgument(ValueArgument):
-    @property 
+    @property
     def value(self):
         return getattr(self, '_value', self.default)
+
     @value.setter
     def value(self, newvalue):
         if newvalue is None:
@@ -156,7 +173,8 @@ class RangeArgument(ValueArgument):
             return
         (start, end) = newvalue.split('-')
         (start, end) = (int(start), int(end))
-        self._value = '%s-%s'%(start, end)
+        self._value = '%s-%s' % (start, end)
+
 
 class DateArgument(ValueArgument):
     DATE_FORMATS = ["%a %b %d %H:%M:%S %Y",
@@ -165,9 +183,10 @@ class DateArgument(ValueArgument):
 
     INPUT_FORMATS = DATE_FORMATS + ["%d-%m-%Y", "%H:%M:%S %d-%m-%Y"]
 
-    @property 
+    @property
     def value(self):
         return getattr(self, '_value', self.default)
+
     @value.setter
     def value(self, newvalue):
         if newvalue is None:
@@ -183,44 +202,59 @@ class DateArgument(ValueArgument):
             self._value = t.strftime(self.DATE_FORMATS[0])
             return
         raise CLIError('Date Argument Error',
-            details='%s not a valid date. correct formats:\n\t%s'%(datestr, self.INPUT_FORMATS))
+            details='%s not a valid date. correct formats:\n\t%s'\
+            % (datestr, self.INPUT_FORMATS))
+
+
+# Command specs
+
 
-#Command specs
 class _pithos_init(_command_init):
     def main(self):
-        self.token = self.config.get('store', 'token') or self.config.get('global', 'token')
-        self.base_url = self.config.get('store', 'url') or self.config.get('global', 'url')
-        self.account = self.config.get('store', 'account') or self.config.get('global', 'account')
-        self.container = self.config.get('store', 'container') or self.config.get('global',
-            'container')
-        self.client = PithosClient(base_url=self.base_url, token=self.token, account=self.account,
+        self.token = self.config.get('store', 'token')\
+            or self.config.get('global', 'token')
+        self.base_url = self.config.get('store', 'url')\
+            or self.config.get('global', 'url')
+        self.account = self.config.get('store', 'account')\
+            or self.config.get('global', 'account')
+        self.container = self.config.get('store', 'container')\
+            or self.config.get('global', 'container')
+        self.client = PithosClient(base_url=self.base_url,
+            token=self.token,
+            account=self.account,
             container=self.container)
 
+
 class _store_account_command(_pithos_init):
     """Base class for account level storage commands"""
 
     def __init__(self, arguments={}):
         super(_store_account_command, self).__init__(arguments)
-        self.arguments['account'] = ValueArgument('Specify the account', '--account')
+        self.arguments['account'] =\
+            ValueArgument('Specify the account', '--account')
 
     def generator(self, message):
-       return None 
+        return None
 
     def main(self):
         super(_store_account_command, self).main()
         if self.arguments['account'].value is not None:
             self.client.account = self.arguments['account'].value
 
+
 class _store_container_command(_store_account_command):
     """Base class for container level storage commands"""
 
     def __init__(self, arguments={}):
         super(_store_container_command, self).__init__(arguments)
-        self.arguments['container'] = ValueArgument('Specify the container name', '--container')
+        self.arguments['container'] =\
+            ValueArgument('Specify the container name', '--container')
         self.container = None
         self.path = None
 
-    def extract_container_and_path(self, container_with_path, path_is_optional=True):
+    def extract_container_and_path(self,
+        container_with_path,
+        path_is_optional=True):
         assert isinstance(container_with_path, str)
         if ':' not in container_with_path:
             if self.get_argument('container') is not None:
@@ -247,45 +281,46 @@ class _store_container_command(_store_account_command):
     def main(self, container_with_path=None, path_is_optional=True):
         super(_store_container_command, self).main()
         if container_with_path is not None:
-            self.extract_container_and_path(container_with_path, path_is_optional)
+            self.extract_container_and_path(container_with_path,
+                path_is_optional)
             self.client.container = self.container
         elif self.get_argument('container') is not None:
             self.client.container = self.get_argument('container')
         self.container = self.client.container
 
-"""
-@command()
-class store_test(_store_container_command):
-    "Test stuff something""
-
-    def main(self):
-        super(self.__class__, self).main('pithos')
-        r = self.client.container_get()
-        print(unicode(r.content)+' '+unicode(r.json))
-"""
 
 @command()
 class store_list(_store_container_command):
     """List containers, object trees or objects in a directory
     """
 
-    def __init__(self, arguments = {}):
+    def __init__(self, arguments={}):
         super(store_list, self).__init__(arguments)
         self.arguments['detail'] = FlagArgument('show detailed output', '-l')
-        self.arguments['show_size'] = ValueArgument('print output in chunks of size N', '-N')
+        self.arguments['show_size'] =\
+            ValueArgument('print output in chunks of size N', '-N')
         self.arguments['limit'] = IntArgument('show limited output', '-n')
-        self.arguments['marker'] = ValueArgument('show output greater that marker', '--marker')
-        self.arguments['prefix'] = ValueArgument('show output staritng with prefix', '--prefix')
-        self.arguments['delimiter'] = ValueArgument('show output up to delimiter', '--delimiter')
-        self.arguments['path'] = ValueArgument('show output starting with prefix up to /', '--path')
-        self.arguments['meta'] = ValueArgument('show output haviung the specified meta keys',
+        self.arguments['marker'] =\
+            ValueArgument('show output greater that marker', '--marker')
+        self.arguments['prefix'] =\
+            ValueArgument('show output staritng with prefix', '--prefix')
+        self.arguments['delimiter'] =\
+            ValueArgument('show output up to delimiter', '--delimiter')
+        self.arguments['path'] =\
+            ValueArgument('show output starting with prefix up to /', '--path')
+        self.arguments['meta'] =\
+            ValueArgument('show output haviung the specified meta keys',
             '--meta', default=[])
-        self.arguments['if_modified_since'] = ValueArgument('show output modified since then',
-            '--if-modified-since')
-        self.arguments['if_unmodified_since'] = ValueArgument('show output not modified since then',
+        self.arguments['if_modified_since'] =\
+            ValueArgument('show output modified since then',
+                '--if-modified-since')
+        self.arguments['if_unmodified_since'] =\
+            ValueArgument('show output not modified since then',
             '--if-unmodified-since')
-        self.arguments['until'] = DateArgument('show metadata until then', '--until')
-        self.arguments['format'] = ValueArgument('format to parse until data (default: d/m/Y H:M:S',
+        self.arguments['until'] =\
+            DateArgument('show metadata until then', '--until')
+        self.arguments['format'] =\
+            ValueArgument('format to parse until data (default: d/m/Y H:M:S',
             '--format')
         self.arguments['shared'] = FlagArgument('show only shared', '--shared')
         self.arguments['public'] = FlagArgument('show only public', '--public')
@@ -298,29 +333,29 @@ class store_list(_store_container_command):
         except (AttributeError, TypeError):
             limit = len(object_list) + 1
         #index = 0
-        for index,obj in enumerate(object_list):
-            if not obj.has_key('content_type'):
+        for index, obj in enumerate(object_list):
+            if 'content_type' not in obj:
                 continue
             pretty_obj = obj.copy()
             index += 1
-            empty_space = ' '*(len(str(len(object_list))) - len(str(index)))
+            empty_space = ' ' * (len(str(len(object_list))) - len(str(index)))
             if obj['content_type'] == 'application/directory':
                 isDir = True
                 size = 'D'
             else:
                 isDir = False
                 size = format_size(obj['bytes'])
-                pretty_obj['bytes'] = '%s (%s)'%(obj['bytes'],size)
+                pretty_obj['bytes'] = '%s (%s)' % (obj['bytes'], size)
             oname = bold(obj['name'])
             if self.get_argument('detail'):
-                print('%s%s. %s'%(empty_space, index, oname))
+                print('%s%s. %s' % (empty_space, index, oname))
                 print_dict(pretty_keys(pretty_obj), exclude=('name'))
                 print
             else:
-                oname = '%s%s. %6s %s'%(empty_space, index, size, oname)
+                oname = '%s%s. %6s %s' % (empty_space, index, size, oname)
                 oname += '/' if isDir else ''
                 print(oname)
-            if limit <= index < len(object_list) and index%limit == 0:
+            if limit <= index < len(object_list) and index % limit == 0:
                 print('(press "enter" to continue)')
                 sys.stdin.read(1)
 
@@ -330,24 +365,25 @@ class store_list(_store_container_command):
             limit = self.get_argument('show_size')
             limit = int(limit)
         except (AttributeError, TypeError):
-            limit = len(container_list)+1
-        for index,container in enumerate(container_list):
-            if container.has_key('bytes'):
-                size = format_size(container['bytes']) 
-            cname = '%s. %s'%(index+1, bold(container['name']))
+            limit = len(container_list) + 1
+        for index, container in enumerate(container_list):
+            if 'bytes' in container:
+                size = format_size(container['bytes'])
+            cname = '%s. %s' % (index + 1, bold(container['name']))
             if self.get_argument('detail'):
                 print(cname)
                 pretty_c = container.copy()
-                if container.has_key('bytes'):
-                    pretty_c['bytes'] = '%s (%s)'%(container['bytes'], size)
+                if 'bytes' in container:
+                    pretty_c['bytes'] = '%s (%s)' % (container['bytes'], size)
                 print_dict(pretty_keys(pretty_c), exclude=('name'))
                 print
             else:
-                if container.has_key('count') and container.has_key('bytes'):
-                    print('%s (%s, %s objects)' % (cname, size, container['count']))
+                if 'count' in container and 'bytes' in container:
+                    print('%s (%s, %s objects)'\
+                    % (cname, size, container['count']))
                 else:
                     print(cname)
-            if limit <= index < len(container_list) and index%limit == 0:
+            if limit <= index < len(container_list) and index % limit == 0:
                 print('(press "enter" to continue)')
                 sys.stdin.read(1)
 
@@ -358,44 +394,54 @@ class store_list(_store_container_command):
                 r = self.client.account_get(limit=self.get_argument('limit'),
                     marker=self.get_argument('marker'),
                     if_modified_since=self.get_argument('if_modified_since'),
-                    if_unmodified_since=self.get_argument('if_unmodified_since'),
+                    if_unmodified_since=self.get_argument(\
+                        'if_unmodified_since'),
                     until=self.get_argument('until'),
                     show_only_shared=self.get_argument('shared'))
                 self.print_containers(r.json)
             else:
                 r = self.client.container_get(limit=self.get_argument('limit'),
-                    marker=self.get_argument('marker'), prefix=self.get_argument('prefix'),
-                    delimiter=self.get_argument('delimiter'), path=self.get_argument('path'),
+                    marker=self.get_argument('marker'),
+                    prefix=self.get_argument('prefix'),
+                    delimiter=self.get_argument('delimiter'),
+                    path=self.get_argument('path'),
                     if_modified_since=self.get_argument('if_modified_since'),
-                    if_unmodified_since=self.get_argument('if_unmodified_since'),
+                    if_unmodified_since=self.get_argument(\
+                        'if_unmodified_since'),
                     until=self.get_argument('until'),
-                    meta=self.get_argument('meta'), show_only_shared=self.get_argument('shared'))
+                    meta=self.get_argument('meta'),
+                    show_only_shared=self.get_argument('shared'))
                 self.print_objects(r.json)
         except ClientError as err:
             raiseCLIError(err)
 
+
 @command()
 class store_mkdir(_store_container_command):
     """Create a directory"""
 
     def main(self, container___directory):
-        super(self.__class__, self).main(container___directory, path_is_optional=False)
+        super(self.__class__,
+            self).main(container___directory, path_is_optional=False)
         try:
             self.client.create_directory(self.path)
         except ClientError as err:
             raiseCLIError(err)
 
+
 @command()
 class store_create(_store_container_command):
     """Create a container or a directory object"""
 
-
     def __init__(self, arguments={}):
         super(self.__class__, self).__init__(arguments)
-        self.arguments['versioning'] = ValueArgument('set container versioning (auto/none)',
+        self.arguments['versioning'] = \
+            ValueArgument('set container versioning (auto/none)',
             '--versioning')
-        self.arguments['quota'] = IntArgument('set default container quota', '--quota')
-        self.arguments['meta'] = MetaArgument('set container metadata', '--meta')
+        self.arguments['quota'] =\
+            IntArgument('set default container quota', '--quota')
+        self.arguments['meta'] =\
+            MetaArgument('set container metadata', '--meta')
 
     def main(self, container____directory__):
         super(self.__class__, self).main(container____directory__)
@@ -409,28 +455,36 @@ class store_create(_store_container_command):
         except ClientError as err:
             raiseCLIError(err)
 
+
 @command()
 class store_copy(_store_container_command):
     """Copy an object"""
 
     def __init__(self, arguments={}):
         super(self.__class__, self).__init__(arguments)
-        self.arguments['source_version']=ValueArgument('copy specific version', '--source-version')
-        self.arguments['public']=ValueArgument('make object publicly accessible', '--public')
-        self.arguments['content_type']=ValueArgument('change object\'s content type',
-            '--content-type')
-        self.arguments['delimiter']=DelimiterArgument(self, parsed_name='--delimiter',
-            help = u'mass copy objects with path staring with src_object + delimiter')
-        self.arguments['recursive']=FlagArgument('mass copy with delimiter /', ('-r','--recursive'))
+        self.arguments['source_version'] = ValueArgument(\
+            'copy specific version', '--source-version')
+        self.arguments['public'] = ValueArgument(\
+            'make object publicly accessible', '--public')
+        self.arguments['content_type'] = ValueArgument(\
+            'change object\'s content type', '--content-type')
+        self.arguments['delimiter'] = DelimiterArgument(self,
+            parsed_name='--delimiter',
+            help=u'copy objects prefixed as src_object + delimiter')
+        self.arguments['recursive'] = FlagArgument(
+            'mass copy with delimiter /', ('-r', '--recursive'))
 
     def main(self, source_container___path, destination_container____path__):
-        super(self.__class__, self).main(source_container___path, path_is_optional=False)
+        super(self.__class__,
+            self).main(source_container___path, path_is_optional=False)
         try:
             dst = destination_container____path__.split(':')
             dst_cont = dst[0]
             dst_path = dst[1] if len(dst) > 1 else False
-            self.client.copy_object(src_container = self.container, src_object = self.path,
-                dst_container = dst_cont, dst_object = dst_path,
+            self.client.copy_object(src_container=self.container,
+                src_object=self.path,
+                dst_container=dst_cont,
+                dst_object=dst_path,
                 source_version=self.get_argument('source_version'),
                 public=self.get_argument('public'),
                 content_type=self.get_argument('content_type'),
@@ -438,6 +492,7 @@ class store_copy(_store_container_command):
         except ClientError as err:
             raiseCLIError(err)
 
+
 @command()
 class store_move(_store_container_command):
     """Copy an object"""
@@ -445,22 +500,29 @@ class store_move(_store_container_command):
     def __init__(self, arguments={}):
         super(self.__class__, self).__init__(arguments)
 
-        self.arguments['source_version']=ValueArgument('copy specific version', '--source-version')
-        self.arguments['public']=FlagArgument('make object publicly accessible', '--public')
-        self.arguments['content_type']=ValueArgument('change object\'s content type',
-            '--content-type')
-        self.arguments['delimiter']=DelimiterArgument(self, parsed_name='--delimiter',
-            help = u'mass copy objects with path staring with src_object + delimiter')
-        self.arguments['recursive']=FlagArgument('mass copy with delimiter /', ('-r','--recursive'))
+        self.arguments['source_version'] = ValueArgument(\
+            'copy specific version', '--source-version')
+        self.arguments['public'] = FlagArgument(\
+            'make object publicly accessible', '--public')
+        self.arguments['content_type'] = ValueArgument(\
+            'change object\'s content type', '--content-type')
+        self.arguments['delimiter'] = DelimiterArgument(self,
+            parsed_name='--delimiter',
+            help='move objects prefixed as src_object + delimiter')
+        self.arguments['recursive'] = FlagArgument(\
+            'copy with delimiter /', ('-r', '--recursive'))
 
     def main(self, source_container___path, destination_container____path__):
-        super(self.__class__, self).main(source_container___path, path_is_optional=False)
+        super(self.__class__,
+            self).main(source_container___path, path_is_optional=False)
         try:
             dst = destination_container____path__.split(':')
             dst_cont = dst[0]
             dst_path = dst[1] if len(dst) > 1 else False
-            self.client.move_object(src_container = self.container, src_object = self.path,
-                dst_container = dst_cont, dst_object = dst_path,
+            self.client.move_object(src_container=self.container,
+                src_object=self.path,
+                dst_container=dst_cont,
+                dst_object=dst_path,
                 source_version=self.get_argument('source_version'),
                 public=self.get_argument('public'),
                 content_type=self.get_argument('content_type'),
@@ -468,59 +530,74 @@ class store_move(_store_container_command):
         except ClientError as err:
             raiseCLIError(err)
 
+
 @command()
 class store_append(_store_container_command):
     """Append local file to (existing) remote object"""
 
     def __init__(self, arguments={}):
         super(self.__class__, self).__init__(arguments)
-        self.arguments['progress_bar'] = ProgressBarArgument('do not show progress bar', '--no-progress-bar')
+        self.arguments['progress_bar'] = ProgressBarArgument(\
+            'do not show progress bar', '--no-progress-bar')
 
     def main(self, local_path, container___path):
-        super(self.__class__, self).main(container___path, path_is_optional=False)
+        super(self.__class__,
+            self).main(container___path, path_is_optional=False)
         try:
             f = open(local_path, 'r')
             try:
-                upload_cb = self.arguments['progress_bar'].get_generator('Appending blocks')
+                progress_bar = self.arguments['progress_bar']
+                upload_cb = progress_bar.get_generator('Appending blocks')
             except Exception:
-                upload_cb=None
-            self.client.append_object(object=self.path, source_file = f, upload_cb = upload_cb)
+                upload_cb = None
+            self.client.append_object(object=self.path,
+                source_file=f,
+                upload_cb=upload_cb)
         except ClientError as err:
             raiseCLIError(err)
 
+
 @command()
 class store_truncate(_store_container_command):
     """Truncate remote file up to a size"""
 
     def main(self, container___path, size=0):
-        super(self.__class__, self).main(container___path, path_is_optional=False)
+        super(self.__class__,
+            self).main(container___path, path_is_optional=False)
         try:
             self.client.truncate_object(self.path, size)
         except ClientError as err:
             raiseCLIError(err)
 
+
 @command()
 class store_overwrite(_store_container_command):
     """Overwrite part (from start to end) of a remote file"""
 
     def __init__(self, arguments={}):
         super(self.__class__, self).__init__(arguments)
-        self.arguments['progress_bar'] = ProgressBarArgument('do not show progress bar',
-            '--no-progress-bar')
+        self.arguments['progress_bar'] = ProgressBarArgument(\
+            'do not show progress bar', '--no-progress-bar')
 
     def main(self, local_path, container___path, start, end):
-        super(self.__class__, self).main(container___path, path_is_optional=False)
+        super(self.__class__,
+            self).main(container___path, path_is_optional=False)
         try:
             f = open(local_path, 'r')
             try:
-                upload_cb = self.arguments['progress_bar'].get_generator('Overwritting blocks')
+                progress_bar = self.arguments['progress_bar']
+                upload_cb = progress_bar.get_generator('Overwritting blocks')
             except Exception:
                 upload_cb = None
-            self.client.overwrite_object(object=self.path, start=start, end=end,
-                source_file=f, upload_cb = upload_cb)
+            self.client.overwrite_object(object=self.path,
+                start=start,
+                end=end,
+                source_file=f,
+                upload_cb=upload_cb)
         except ClientError as err:
             raiseCLIError(err)
 
+
 @command()
 class store_manifest(_store_container_command):
     """Create a remote file with uploaded parts by manifestation"""
@@ -528,48 +605,60 @@ class store_manifest(_store_container_command):
     def __init__(self, arguments={}):
         super(self.__class__, self).__init__(arguments)
         self.arguments['etag'] = ValueArgument('check written data', '--etag')
-        self.arguments['content_encoding']=ValueArgument('provide the object MIME content type',
-            '--content-encoding')
-        self.arguments['content_disposition'] = ValueArgument('provide the presentation style of the object',
+        self.arguments['content_encoding'] = ValueArgument(\
+            'provide the object MIME content type', '--content-encoding')
+        self.arguments['content_disposition'] = ValueArgument(\
+            'provide the presentation style of the object',
             '--content-disposition')
-        self.arguments['content_type']=ValueArgument('create object with specific content type',
-            '--content-type')
-        self.arguments['sharing']=SharingArgument(parsed_name='--sharing',
-            help='define sharing object policy ( "read=user1,grp1,user2,... write=user1,grp2,...')
-        self.arguments['public']=FlagArgument('make object publicly accessible', '--public')
-        
+        self.arguments['content_type'] = ValueArgument(\
+            'create object with specific content type', '--content-type')
+        self.arguments['sharing'] = SharingArgument(parsed_name='--sharing',
+            help='define object sharing policy ' +\
+            '( "read=user1,grp1,user2,... write=user1,grp2,..." )')
+        self.arguments['public'] = FlagArgument(\
+            'make object publicly accessible', '--public')
+
     def main(self, container___path):
-        super(self.__class__, self).main(container___path, path_is_optional=False)
+        super(self.__class__,
+            self).main(container___path, path_is_optional=False)
         try:
             self.client.create_object_by_manifestation(self.path,
                 content_encoding=self.get_argument('content_encoding'),
                 content_disposition=self.get_argument('content_disposition'),
                 content_type=self.get_argument('content_type'),
-                sharing=self.get_argument('sharing'), public=self.get_argument('public'))
+                sharing=self.get_argument('sharing'),
+                public=self.get_argument('public'))
         except ClientError as err:
             raiseCLIError(err)
 
+
 @command()
 class store_upload(_store_container_command):
     """Upload a file"""
 
     def __init__(self, arguments={}):
         super(self.__class__, self).__init__(arguments)
-        self.arguments['use_hashes'] = FlagArgument('provide hashmap file instead of data',
-            '--use-hashes')
+        self.arguments['use_hashes'] = FlagArgument(\
+            'provide hashmap file instead of data', '--use-hashes')
         self.arguments['etag'] = ValueArgument('check written data', '--etag')
-        self.arguments['unchunked'] = FlagArgument('avoid chunked transfer mode', '--unchunked')
-        self.arguments['content_encoding']=ValueArgument('provide the object MIME content type',
-            '--content-encoding')
-        self.arguments['content_disposition'] = ValueArgument('provide the presentation style of the object',
+        self.arguments['unchunked'] = FlagArgument(\
+            'avoid chunked transfer mode', '--unchunked')
+        self.arguments['content_encoding'] = ValueArgument(\
+            'provide the object MIME content type', '--content-encoding')
+        self.arguments['content_disposition'] = ValueArgument(\
+            'provide the presentation style of the object',
             '--content-disposition')
-        self.arguments['content_type']=ValueArgument('create object with specific content type',
-            '--content-type')
-        self.arguments['sharing']=SharingArgument(parsed_name='--sharing',
-            help='define sharing object policy ( "read=user1,grp1,user2,... write=user1,grp2,...')
-        self.arguments['public']=FlagArgument('make object publicly accessible', '--public')
-        self.arguments['poolsize']=IntArgument('set pool size', '--with-pool-size')
-        self.arguments['progress_bar'] = ProgressBarArgument('do not show progress bar', '--no-progress-bar')
+        self.arguments['content_type'] = ValueArgument(\
+            'create object with specific content type', '--content-type')
+        self.arguments['sharing'] = SharingArgument(parsed_name='--sharing',
+            help='define sharing object policy ' +\
+            '( "read=user1,grp1,user2,... write=user1,grp2,...')
+        self.arguments['public'] = FlagArgument(\
+            'make object publicly accessible', '--public')
+        self.arguments['poolsize'] = IntArgument(\
+            'set pool size', '--with-pool-size')
+        self.arguments['progress_bar'] = ProgressBarArgument(\
+            'do not show progress bar', '--no-progress-bar')
 
     def main(self, local_path, container____path__):
         super(self.__class__, self).main(container____path__)
@@ -577,48 +666,60 @@ class store_upload(_store_container_command):
         poolsize = self.get_argument('poolsize')
         if poolsize is not None:
             self.POOL_SIZE = poolsize
+        params = dict(content_encoding=self.get_argument('content_encoding'),
+            content_type=self.get_argument('content_type'),
+            content_disposition=self.get_argument('content_disposition'),
+            sharing=self.get_argument('sharing'),
+            public=self.get_argument('public'))
         try:
             with open(local_path) as f:
                 if self.get_argument('unchunked'):
                     self.client.upload_object_unchunked(remote_path, f,
-                    etag=self.get_argument('etag'), withHashFile=self.get_argument('use_hashes'),
-                    content_encoding=self.get_argument('content_encoding'),
-                    content_disposition=self.get_argument('content_disposition'),
-                    content_type=self.get_argument('content_type'),
-                    sharing=self.get_argument('sharing'), public=self.get_argument('public'))
+                    etag=self.get_argument('etag'),
+                    withHashFile=self.get_argument('use_hashes'),
+                    **params)
                 else:
-                    hash_cb=self.arguments['progress_bar'].get_generator('Calculating block hashes')
-                    upload_cb=self.arguments['progress_bar'].get_generator('Uploading')
-                    self.client.upload_object(remote_path, f, hash_cb=hash_cb, upload_cb=upload_cb,
-                    content_encoding=self.get_argument('content_encoding'),
-                    content_disposition=self.get_argument('content_disposition'),
-                    content_type=self.get_argument('content_type'),
-                    sharing=self.get_argument('sharing'), public=self.get_argument('public'))
+                    progress_bar = self.arguments['progress_bar']
+                    hash_cb = progress_bar.get_generator(\
+                        'Calculating block hashes')
+                    upload_cb = progress_bar.get_generator('Uploading')
+                    self.client.upload_object(remote_path, f,
+                    hash_cb=hash_cb,
+                    upload_cb=upload_cb,
+                    **params)
         except ClientError as err:
             raiseCLIError(err)
         except IOError as err:
-            raise CLIError(message='Failed to read form file %s'%local_path, importance=2, details=unicode(err))
+            raise CLIError(message='Failed to read form file %s' % local_path,
+                importance=2,
+                details=unicode(err))
         print 'Upload completed'
 
+
 @command()
 class store_cat(_store_container_command):
     """Print a file to console"""
 
     def __init__(self, arguments={}):
         super(self.__class__, self).__init__(arguments)
-        self.arguments['range'] = RangeArgument('show range of data', '--range')
-        self.arguments['if_match'] = ValueArgument('show output if ETags match', '--if-match')
-        self.arguments['if_none_match'] = ValueArgument('show output if ETags match',
-            '--if-none-match')
-        self.arguments['if_modified_since'] = DateArgument('show output modified since then',
+        self.arguments['range'] =\
+            RangeArgument('show range of data', '--range')
+        self.arguments['if_match'] =\
+            ValueArgument('show output if ETags match', '--if-match')
+        self.arguments['if_none_match'] =\
+            ValueArgument('show output if ETags match', '--if-none-match')
+        self.arguments['if_modified_since'] =\
+            DateArgument('show output modified since then',
             '--if-modified-since')
-        self.arguments['if_unmodified_since'] = DateArgument('show output unmodified since then',
+        self.arguments['if_unmodified_since'] =\
+            DateArgument('show output unmodified since then',
             '--if-unmodified-since')
-        self.arguments['object_version'] = ValueArgument('get the specific version',
-            '--object-version')
+        self.arguments['object_version'] =\
+            ValueArgument('get the specific version', '--object-version')
 
     def main(self, container___path):
-        super(self.__class__, self).main(container___path, path_is_optional=False)
+        super(self.__class__,
+            self).main(container___path, path_is_optional=False)
         self.client.download_object(self.path, stdout,
             range=self.get_argument('range'),
             version=self.get_argument('object_version'),
@@ -627,6 +728,7 @@ class store_cat(_store_container_command):
             if_modified_since=self.get_argument('if_modified_since'),
             if_unmodified_since=self.get_argument('if_unmodified_since'))
 
+
 @command()
 class store_download(_store_container_command):
     """Download a file"""
@@ -634,46 +736,54 @@ class store_download(_store_container_command):
     def __init__(self, arguments={}):
         super(self.__class__, self).__init__(arguments)
         self.arguments['resume'] = FlagArgument(parsed_name='--resume',
-            help = 'Resume a previous download instead of overwritting it')
-        self.arguments['range'] = RangeArgument('show range of data', '--range')
-        self.arguments['if_match'] = ValueArgument('show output if ETags match', '--if-match')
-        self.arguments['if_none_match'] = ValueArgument('show output if ETags match',
-            '--if-none-match')
-        self.arguments['if_modified_since'] = DateArgument('show output modified since then',
-            '--if-modified-since')
-        self.arguments['if_unmodified_since'] = DateArgument('show output unmodified since then',
-            '--if-unmodified-since')
-        self.arguments['object_version'] = ValueArgument('get the specific version',
-            '--object-version')
-        self.arguments['poolsize']=IntArgument('set pool size', '--with-pool-size')
-        self.arguments['progress_bar'] = ProgressBarArgument('do not show progress bar',
-            '--no-progress-bar')
+            help='Resume a previous download instead of overwritting it')
+        self.arguments['range'] = RangeArgument(\
+            'show range of data', '--range')
+        self.arguments['if_match'] = ValueArgument(\
+            'show output if ETags match', '--if-match')
+        self.arguments['if_none_match'] = ValueArgument(\
+            'show output if ETags match', '--if-none-match')
+        self.arguments['if_modified_since'] = DateArgument(\
+            'show output modified since then', '--if-modified-since')
+        self.arguments['if_unmodified_since'] = DateArgument(\
+            'show output unmodified since then', '--if-unmodified-since')
+        self.arguments['object_version'] = ValueArgument(\
+            'get the specific version', '--object-version')
+        self.arguments['poolsize'] = IntArgument(\
+            'set pool size', '--with-pool-size')
+        self.arguments['progress_bar'] = ProgressBarArgument(\
+            'do not show progress bar', '--no-progress-bar')
 
     def main(self, container___path, local_path):
-        super(self.__class__, self).main(container___path, path_is_optional=False)
+        super(self.__class__,
+            self).main(container___path, path_is_optional=False)
 
-        #setup output stream
-        parallel = False
+        # setup output stream
         if local_path is None:
             out = stdout
         else:
             try:
                 if self.get_argument('resume'):
-                    out=open(local_path, 'rwb+')
+                    out = open(local_path, 'rwb+')
                 else:
-                    out=open(local_path, 'wb+')
+                    out = open(local_path, 'wb+')
             except IOError as err:
-                raise CLIError(message='Cannot write to file %s - %s'%(local_path,unicode(err)),
+                raise CLIError(message='Cannot write to file %s - %s'\
+                    % (local_path, unicode(err)),
                     importance=1)
-        download_cb = self.arguments['progress_bar'].get_generator('Downloading')
+        progress_bar = self.arguments['progress_bar']
+        download_cb = progress_bar.get_generator('Downloading')
         poolsize = self.get_argument('poolsize')
         if poolsize is not None:
             self.POOL_SIZE = int(poolsize)
 
         try:
-            self.client.download_object(self.path, out, download_cb,
-                range=self.get_argument('range'), version=self.get_argument('object_version'),
-                if_match=self.get_argument('if_match'), resume=self.get_argument('resume'),
+            self.client.download_object(self.path, out,
+                download_cb=download_cb,
+                range=self.get_argument('range'),
+                version=self.get_argument('object_version'),
+                if_match=self.get_argument('if_match'),
+                resume=self.get_argument('resume'),
                 if_none_match=self.get_argument('if_none_match'),
                 if_modified_since=self.get_argument('if_modified_since'),
                 if_unmodified_since=self.get_argument('if_unmodified_since'))
@@ -685,24 +795,29 @@ class store_download(_store_container_command):
                 print('to resume, re-run with --resume')
         print
 
+
 @command()
 class store_hashmap(_store_container_command):
     """Get the hashmap of an object"""
 
     def __init__(self, arguments={}):
         super(self.__class__, self).__init__(arguments)
-        self.arguments['if_match'] = ValueArgument('show output if ETags match', '--if-match')
-        self.arguments['if_none_match'] = ValueArgument('show output if ETags match',
-            '--if-none-match')
-        self.arguments['if_modified_since'] = DateArgument('show output modified since then',
+        self.arguments['if_match'] =\
+            ValueArgument('show output if ETags match', '--if-match')
+        self.arguments['if_none_match'] =\
+            ValueArgument('show output if ETags match', '--if-none-match')
+        self.arguments['if_modified_since'] =\
+            DateArgument('show output modified since then',
             '--if-modified-since')
-        self.arguments['if_unmodified_since'] = DateArgument('show output unmodified since then',
+        self.arguments['if_unmodified_since'] =\
+            DateArgument('show output unmodified since then',
             '--if-unmodified-since')
-        self.arguments['object_version'] = ValueArgument('get the specific version',
-            '--object-version')
+        self.arguments['object_version'] =\
+            ValueArgument('get the specific version', '--object-version')
 
     def main(self, container___path):
-        super(self.__class__, self).main(container___path, path_is_optional=False)
+        super(self.__class__,
+            self).main(container___path, path_is_optional=False)
         try:
             data = self.client.get_object_hashmap(self.path,
                 version=self.arguments('object_version'),
@@ -714,17 +829,21 @@ class store_hashmap(_store_container_command):
             raiseCLIError(err)
         print_dict(data)
 
+
 @command()
 class store_delete(_store_container_command):
     """Delete a container [or an object]"""
 
     def __init__(self, arguments={}):
         super(self.__class__, self).__init__(arguments)
-        self.arguments['until'] = DateArgument('remove history until that date', '--until')
-        self.arguments['recursive'] = FlagArgument('empty dir or container and delete (if dir)',
-            ('-r','--recursive'))
-        self.arguments['delimiter'] = DelimiterArgument(self, parsed_name='--delimiter',
-            help = 'mass delete objects with path staring with <object><delimiter>')
+        self.arguments['until'] = DateArgument(\
+            'remove history until that date', '--until')
+        self.arguments['recursive'] = FlagArgument(\
+            'empty dir or container and delete (if dir)',
+            ('-r', '--recursive'))
+        self.arguments['delimiter'] = DelimiterArgument(self,
+            parsed_name='--delimiter',
+            help='delete objects prefixed with <object><delimiter>')
 
     def main(self, container____path__):
         super(self.__class__, self).main(container____path__)
@@ -733,16 +852,18 @@ class store_delete(_store_container_command):
                 self.client.del_container(until=self.get_argument('until'),
                     delimiter=self.get_argument('delimiter'))
             else:
-                #self.client.delete_object(self.path)
-                self.client.del_object(self.path, until=self.get_argument('until'),
+                # self.client.delete_object(self.path)
+                self.client.del_object(self.path,
+                    until=self.get_argument('until'),
                     delimiter=self.get_argument('delimiter'))
         except ClientError as err:
             raiseCLIError(err)
 
+
 @command()
 class store_purge(_store_container_command):
     """Purge a container"""
-    
+
     def main(self, container):
         super(self.__class__, self).main(container)
         try:
@@ -750,45 +871,52 @@ class store_purge(_store_container_command):
         except ClientError as err:
             raiseCLIError(err)
 
+
 @command()
 class store_publish(_store_container_command):
     """Publish an object"""
 
     def main(self, container___path):
-        super(self.__class__, self).main(container___path, path_is_optional=False)
+        super(self.__class__,
+            self).main(container___path, path_is_optional=False)
         try:
             self.client.publish_object(self.path)
         except ClientError as err:
             raiseCLIError(err)
 
+
 @command()
 class store_unpublish(_store_container_command):
     """Unpublish an object"""
 
     def main(self, container___path):
-        super(self.__class__, self).main(container___path, path_is_optional=False)
+        super(self.__class__,
+            self).main(container___path, path_is_optional=False)
         try:
             self.client.unpublish_object(self.path)
         except ClientError as err:
             raiseCLIError(err)
 
+
 @command()
 class store_permitions(_store_container_command):
     """Get object read/write permitions"""
 
     def main(self, container___path):
-        super(self.__class__, self).main(container___path, path_is_optional=False)
+        super(self.__class__,
+            self).main(container___path, path_is_optional=False)
         try:
             reply = self.client.get_object_sharing(self.path)
             print_dict(reply)
         except ClientError as err:
             raiseCLIError(err)
 
+
 @command()
 class store_setpermitions(_store_container_command):
     """Set sharing permitions"""
 
-    def format_permition_dict(self,permitions):
+    def format_permition_dict(self, permitions):
         read = False
         write = False
         for perms in permitions:
@@ -803,12 +931,13 @@ class store_setpermitions(_store_container_command):
                 read = False
                 write = False
         if not read and not write:
-            raise CLIError(message='Usage:\tread=<groups,users> write=<groups,users>',
-                importance=0)
-        return (read,write)
+            raise CLIError(importance=0,
+                message='Usage:\tread=<groups,users> write=<groups,users>')
+        return (read, write)
 
     def main(self, container___path, *permitions):
-        super(self.__class__, self).main(container___path, path_is_optional=False)
+        super(self.__class__,
+            self).main(container___path, path_is_optional=False)
         (read, write) = self.format_permition_dict(permitions)
         try:
             self.client.set_object_sharing(self.path,
@@ -816,22 +945,24 @@ class store_setpermitions(_store_container_command):
         except ClientError as err:
             raiseCLIError(err)
 
+
 @command()
 class store_delpermitions(_store_container_command):
     """Delete all sharing permitions"""
 
     def main(self, container___path):
-        super(self.__class__, self).main(container___path, path_is_optional=False)
+        super(self.__class__,
+            self).main(container___path, path_is_optional=False)
         try:
             self.client.del_object_sharing(self.path)
         except ClientError as err:
             raiseCLIError(err)
 
+
 @command()
 class store_info(_store_container_command):
     """Get information for account [, container [or object]]"""
 
-    
     def main(self, container____path__=None):
         super(self.__class__, self).main(container____path__)
         try:
@@ -845,50 +976,59 @@ class store_info(_store_container_command):
             raiseCLIError(err)
         print_dict(reply)
 
+
 @command()
 class store_meta(_store_container_command):
     """Get custom meta-content for account [, container [or object]]"""
 
-    def __init__(self, arguments = {}):
+    def __init__(self, arguments={}):
         super(self.__class__, self).__init__(arguments)
-        self.arguments['detail'] = FlagArgument('show detailed output', '-l')
-        self.arguments['until'] = DateArgument('show metadata until then', '--until')
-        self.arguments['object_version'] = ValueArgument(parsed_name='--object-version',
+        self.arguments['detail'] =\
+            FlagArgument('show detailed output', '-l')
+        self.arguments['until'] =\
+            DateArgument('show metadata until then', '--until')
+        self.arguments['object_version'] =\
+            ValueArgument(parsed_name='--object-version',
             help='show specific version \ (applies only for objects)')
 
-    def main(self, container____path__ = None):
+    def main(self, container____path__=None):
         super(self.__class__, self).main(container____path__)
 
         detail = self.get_argument('detail')
         try:
             if self.container is None:
                 print(bold(self.client.account))
+                until = self.get_argument('until')
                 if detail:
-                    reply = self.client.get_account_info(until=self.get_argument('until'))
+                    reply = self.client.get_account_info(until=until)
                 else:
-                    reply = self.client.get_account_meta(until=self.get_argument('until'))
+                    reply = self.client.get_account_meta(until=until)
                     reply = pretty_keys(reply, '-')
             elif self.path is None:
-                print(bold(self.client.account+': '+self.container))
+                print(bold('%s: %s' % self.client.account, self.container))
                 if detail:
-                    reply = self.client.get_container_info(until = self.get_argument('until'))
+                    reply = self.client.get_container_info(until=until)
                 else:
-                    cmeta = self.client.get_container_meta(until=self.get_argument('until'))
-                    ometa = self.client.get_container_object_meta(until=self.get_argument('until'))
-                    reply = {'container-meta':pretty_keys(cmeta, '-'),
-                        'object-meta':pretty_keys(ometa, '-')}
+                    cmeta = self.client.get_container_meta(until=until)
+                    ometa = self.client.get_container_object_meta(until=until)
+                    reply = {'container-meta': pretty_keys(cmeta, '-'),
+                        'object-meta': pretty_keys(ometa, '-')}
             else:
-                print(bold(self.client.account+': '+self.container+':'+self.path))
-                version=self.get_argument('object_version')
+                print('%s: %s:%s'\
+                % (bold(self.client.account, self.container, self.path)))
+                version = self.get_argument('object_version')
                 if detail:
-                    reply = self.client.get_object_info(self.path, version = version)
+                    reply = self.client.get_object_info(self.path,
+                        version=version)
                 else:
-                    reply = self.client.get_object_meta(self.path, version=version)
+                    reply = self.client.get_object_meta(self.path,
+                        version=version)
                     reply = pretty_keys(pretty_keys(reply, '-'))
         except ClientError as err:
             raiseCLIError(err)
         print_dict(reply)
 
+
 @command()
 class store_setmeta(_store_container_command):
     """Set a new metadatum for account [, container [or object]]"""
@@ -898,18 +1038,18 @@ class store_setmeta(_store_container_command):
         try:
             metakey, metavalue = metakey___metaval.split(':')
         except ValueError:
-            raise CLIError(message='Meta variables should be formated as metakey:metavalue',
-                importance=1)
+            raise CLIError(message='Usage:  metakey:metavalue', importance=1)
         try:
             if self.container is None:
-                self.client.set_account_meta({metakey:metavalue})
+                self.client.set_account_meta({metakey: metavalue})
             elif self.path is None:
-                self.client.set_container_meta({metakey:metavalue})
+                self.client.set_container_meta({metakey: metavalue})
             else:
-                self.client.set_object_meta(self.path, {metakey:metavalue})
+                self.client.set_object_meta(self.path, {metakey: metavalue})
         except ClientError as err:
             raiseCLIError(err)
 
+
 @command()
 class store_delmeta(_store_container_command):
     """Delete an existing metadatum of account [, container [or object]]"""
@@ -926,11 +1066,12 @@ class store_delmeta(_store_container_command):
         except ClientError as err:
             raiseCLIError(err)
 
+
 @command()
 class store_quota(_store_account_command):
     """Get  quota for account [or container]"""
 
-    def main(self, container = None):
+    def main(self, container=None):
         super(self.__class__, self).main()
         try:
             if container is None:
@@ -941,11 +1082,12 @@ class store_quota(_store_account_command):
             raiseCLIError(err)
         print_dict(reply)
 
+
 @command()
 class store_setquota(_store_account_command):
     """Set new quota (in KB) for account [or container]"""
 
-    def main(self, quota, container = None):
+    def main(self, quota, container=None):
         super(self.__class__, self).main()
         try:
             if container is None:
@@ -956,11 +1098,12 @@ class store_setquota(_store_account_command):
         except ClientError as err:
             raiseCLIError(err)
 
+
 @command()
 class store_versioning(_store_account_command):
     """Get  versioning for account [or container ]"""
 
-    def main(self, container = None):
+    def main(self, container=None):
         super(self.__class__, self).main()
         try:
             if container is None:
@@ -971,11 +1114,12 @@ class store_versioning(_store_account_command):
             raiseCLIError(err)
         print_dict(reply)
 
+
 @command()
 class store_setversioning(_store_account_command):
     """Set new versioning (auto, none) for account [or container]"""
 
-    def main(self, versioning, container = None):
+    def main(self, versioning, container=None):
         super(self.__class__, self).main()
         try:
             if container is None:
@@ -986,6 +1130,7 @@ class store_setversioning(_store_account_command):
         except ClientError as err:
             raiseCLIError(err)
 
+
 @command()
 class store_group(_store_account_command):
     """Get user groups details for account"""
@@ -998,6 +1143,7 @@ class store_group(_store_account_command):
             raiseCLIError(err)
         print_dict(reply)
 
+
 @command()
 class store_setgroup(_store_account_command):
     """Create/update a new user group on account"""
@@ -1009,6 +1155,7 @@ class store_setgroup(_store_account_command):
         except ClientError as err:
             raiseCLIError(err)
 
+
 @command()
 class store_delgroup(_store_account_command):
     """Delete a user group on an account"""
@@ -1020,30 +1167,36 @@ class store_delgroup(_store_account_command):
         except ClientError as err:
             raiseCLIError(err)
 
+
 @command()
 class store_sharers(_store_account_command):
     """List the accounts that share objects with default account"""
 
-    def __init__(self, arguments = {}):
+    def __init__(self, arguments={}):
         super(self.__class__, self).__init__(arguments)
-        self.arguments['detail'] = FlagArgument('show detailed output', '-l')
-        self.arguments['limit'] = IntArgument('show limited output', '--n', default=1000)
-        self.arguments['marker'] = ValueArgument('show output greater then marker', '--marker')
+        self.arguments['detail'] =\
+            FlagArgument('show detailed output', '-l')
+        self.arguments['limit'] =\
+            IntArgument('show limited output', '--n', default=1000)
+        self.arguments['marker'] =\
+            ValueArgument('show output greater then marker', '--marker')
 
     def main(self):
         super(self.__class__, self).main()
         try:
-            accounts = self.client.get_sharing_accounts(marker=self.get_argument('marker'))
+            marker = self.get_argument('marker')
+            accounts = self.client.get_sharing_accounts(marker=marker)
         except ClientError as err:
             raiseCLIError(err)
 
         for acc in accounts:
-            stdout.write(bold(acc['name'])+' ')
+            stdout.write(bold(acc['name']) + ' ')
             if self.get_argument('detail'):
                 print_dict(acc, exclude='name', ident=18)
         if not self.get_argument('detail'):
             print
 
+
 @command()
 class store_versions(_store_container_command):
     """Get the version list of an object"""
@@ -1055,8 +1208,8 @@ class store_versions(_store_container_command):
         except ClientError as err:
             raise CLIError(err)
 
-        print('%s:%s versions'%(self.container,self.path))
+        print('%s:%s versions' % (self.container, self.path))
         for vitem in versions:
             t = localtime(float(vitem[1]))
             vid = bold(unicode(vitem[0]))
-            print('\t%s \t(%s)'%(vid, strftime('%d-%m-%Y %H:%M:%S', t)))
+            print('\t%s \t(%s)' % (vid, strftime('%d-%m-%Y %H:%M:%S', t)))
index 539bab8..08ec0ad 100644 (file)
 
 from kamaki.clients.quotaholder import QuotaHolderClient
 from kamaki.cli import command
-API_DESCRIPTION=dict(quotaholder='Quota Holder commands')
 from kamaki.cli.commands import _command_init
 
+
+API_DESCRIPTION = dict(quotaholder='Quota Holder commands')
+
+
 class _quotaholder_init(_command_init):
-       def main(self):
-               self.token = self.config.get('quotaholder', 'token') or self.config.get('global', 'token')
-               self.base_url = self.config.get('quotaholder', 'url') or self.config.get('global', 'url')
-               self.client = QuotaHolderClient(self.base_url, self.token)
+    def main(self):
+        self.token = self.config.get('quotaholder', 'token')\
+            or self.config.get('global', 'token')
+        self.base_url = self.config.get('quotaholder', 'url')\
+            or self.config.get('global', 'url')
+        self.client = QuotaHolderClient(self.base_url, self.token)
+
 
 @command()
 class quotaholder_test(_quotaholder_init):
-       """Test quota holder commands - devel/testing only"""
+    """Test quota holder commands - devel/testing only"""
 
-       def main(self):
-               super(self.__class__, self).main()
-               print('We will test quota holder stuff')
-               r = self.client.test_quota()
-               print('That is what we got {%s}'%r)
+    def main(self):
+        super(self.__class__, self).main()
+        print('We will test quota holder stuff')
+        r = self.client.test_quota()
+        print('That is what we got {%s}' % r)
diff --git a/kamaki/clients/connection/tests.py b/kamaki/clients/connection/tests.py
new file mode 100644 (file)
index 0000000..5e043b4
--- /dev/null
@@ -0,0 +1,114 @@
+# 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.
+
+import gevent
+import gevent.monkey
+# Monkey-patch everything for gevent early on
+gevent.monkey.patch_all()
+import gevent.pool
+
+from argparse import ArgumentParser
+import unittest
+from time import sleep
+
+from kamaki.clients.connection.kamakicon import KamakiHTTPConnection, KamakiHTTPResponse
+from kamaki.clients.connection import HTTPConnectionError
+
+class testKamakiCon(unittest.TestCase):
+       def setUp(self):
+               self.async_pool=None
+               self.conn1 = KamakiHTTPConnection()
+               self.conn2 = KamakiHTTPConnection()
+               self.conn3 = KamakiHTTPConnection()
+               self.conn4 = KamakiHTTPConnection()
+
+               self.conn1.url = 'https://pithos.okeanos.io/v1/saxtouri@admin.grnet.gr/pithos?path=files'
+               self.conn1.set_header('X-Auth-Token', '0TpoyAXqJSPxLdDuZHiLOA==')
+               self.conn2.url = 'https://pithos.okeanos.io/v1/saxtouri@admin.grnet.gr/pithos'
+               self.conn2.set_header('X-Auth-Token', '0TpoyAXqJSPxLdDuZHiLOA==')
+               self.conn3.url = 'https://pithos.okeanos.io/v1/saxtouri@admin.grnet.gr/pithos?path=subdir'
+               self.conn3.set_header('X-Auth-Token', '0TpoyAXqJSPxLdDuZHiLOA==')
+               self.conn4.url = 'https://pithos.okeanos.io/v1/saxtouri@admin.grnet.gr'
+               self.conn4.set_header('X-Auth-Token', '0TpoyAXqJSPxLdDuZHiLOA==')
+
+       def tearDown(self):
+               pass
+
+       def _get_async_content(self, con, **kwargs):
+               class SilentGreenlet(gevent.Greenlet):
+                       def _report_error(self, exc_info):
+                               _stderr = None
+                               try:
+                                       _stderr = sys._stderr
+                                       sys.stderr = StringIO()
+                                       gevent.Greenlet._report_error(self, exc_info)
+                               finally:
+                                       sys.stderr = _stderr
+               POOL_SIZE = 2
+               if self.async_pool is None:
+                       self.async_pool = gevent.pool.Pool(size=POOL_SIZE)
+               g = SilentGreenlet(self._get_content_len, con, **kwargs)
+               self.async_pool.start(g)
+               return g
+
+       def _get_content_len(self, con, **kwargs):
+               r = con.perform_request('GET', **kwargs)
+               return len(r.content)
+
+       def test_gevents(self):
+               h1 = self._get_async_content(self.conn1)
+               h2 = self._get_async_content(self.conn2)
+               h3 = self._get_async_content(self.conn3)
+               h4 = self._get_async_content(self.conn2, async_headers={'X-Auth-Token':'FAKETOKEN'})
+               h5 = self._get_async_content(self.conn1)
+
+
+               while not (h1.ready() and h2.ready() and h3.ready() and h4.ready() and h5.ready()):
+                       sleep(.000001)
+
+               r1 = h1.value
+               r2 = h2.value
+               r3 = h3.value
+               r4 = h4.value
+               r5 = h5.value
+               self.assertEqual(r1, r5)
+               self.assertNotEqual(r2, r4)
+               #print('1:%s 2:%s 3:%s 4:%s 5:%s'%(r1, r2, r3, r4, r5))
+
+
+               gevent.joinall([h1, h2, h3, h4, h5])
+
+if __name__ == '__main__':
+       suiteFew = unittest.TestSuite()
+       suiteFew.addTest(unittest.makeSuite(testKamakiCon))
+       unittest.TextTestRunner(verbosity = 2).run(suiteFew)
\ No newline at end of file