Statistics
| Branch: | Tag: | Revision:

root / snf-pithos-tools / pithos / tools / sh.py @ b8fa0222

History | View | Annotate | Download (31.2 kB)

1 cfac048c Giorgos Verigakis
#!/usr/bin/env python
2 cfac048c Giorgos Verigakis
3 2e662088 Antony Chazapis
# Copyright 2011-2012 GRNET S.A. All rights reserved.
4 a4c10cbc Sofia Papagiannaki
# 
5 a4c10cbc Sofia Papagiannaki
# Redistribution and use in source and binary forms, with or
6 a4c10cbc Sofia Papagiannaki
# without modification, are permitted provided that the following
7 a4c10cbc Sofia Papagiannaki
# conditions are met:
8 a4c10cbc Sofia Papagiannaki
# 
9 a4c10cbc Sofia Papagiannaki
#   1. Redistributions of source code must retain the above
10 a4c10cbc Sofia Papagiannaki
#      copyright notice, this list of conditions and the following
11 a4c10cbc Sofia Papagiannaki
#      disclaimer.
12 a4c10cbc Sofia Papagiannaki
# 
13 a4c10cbc Sofia Papagiannaki
#   2. Redistributions in binary form must reproduce the above
14 a4c10cbc Sofia Papagiannaki
#      copyright notice, this list of conditions and the following
15 a4c10cbc Sofia Papagiannaki
#      disclaimer in the documentation and/or other materials
16 a4c10cbc Sofia Papagiannaki
#      provided with the distribution.
17 a4c10cbc Sofia Papagiannaki
# 
18 a4c10cbc Sofia Papagiannaki
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
19 a4c10cbc Sofia Papagiannaki
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 a4c10cbc Sofia Papagiannaki
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 a4c10cbc Sofia Papagiannaki
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
22 a4c10cbc Sofia Papagiannaki
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 a4c10cbc Sofia Papagiannaki
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 a4c10cbc Sofia Papagiannaki
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
25 a4c10cbc Sofia Papagiannaki
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 a4c10cbc Sofia Papagiannaki
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 a4c10cbc Sofia Papagiannaki
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 a4c10cbc Sofia Papagiannaki
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 a4c10cbc Sofia Papagiannaki
# POSSIBILITY OF SUCH DAMAGE.
30 a4c10cbc Sofia Papagiannaki
# 
31 a4c10cbc Sofia Papagiannaki
# The views and conclusions contained in the software and
32 a4c10cbc Sofia Papagiannaki
# documentation are those of the authors and should not be
33 a4c10cbc Sofia Papagiannaki
# interpreted as representing official policies, either expressed
34 a4c10cbc Sofia Papagiannaki
# or implied, of GRNET S.A.
35 a4c10cbc Sofia Papagiannaki
36 cfac048c Giorgos Verigakis
from getpass import getuser
37 cfac048c Giorgos Verigakis
from optparse import OptionParser
38 bcb7c5a8 Sofia Papagiannaki
from os import environ
39 f07c5a53 Sofia Papagiannaki
from sys import argv, exit, stdin, stdout
40 d2d5c360 Sofia Papagiannaki
from datetime import datetime
41 5a96180b Antony Chazapis
42 6e147ecc Antony Chazapis
from pithos.tools.lib.client import Pithos_Client, Fault
43 6e147ecc Antony Chazapis
from pithos.tools.lib.util import get_user, get_auth, get_url
44 6e147ecc Antony Chazapis
from pithos.tools.lib.transfer import upload, download
45 cfac048c Giorgos Verigakis
46 cfac048c Giorgos Verigakis
import json
47 cfac048c Giorgos Verigakis
import logging
48 f07c5a53 Sofia Papagiannaki
import types
49 d2d5c360 Sofia Papagiannaki
import re
50 d2d5c360 Sofia Papagiannaki
import time as _time
51 bcb7c5a8 Sofia Papagiannaki
import os
52 cfac048c Giorgos Verigakis
53 cfac048c Giorgos Verigakis
_cli_commands = {}
54 cfac048c Giorgos Verigakis
55 cfac048c Giorgos Verigakis
def cli_command(*args):
56 cfac048c Giorgos Verigakis
    def decorator(cls):
57 cfac048c Giorgos Verigakis
        cls.commands = args
58 cfac048c Giorgos Verigakis
        for name in args:
59 cfac048c Giorgos Verigakis
            _cli_commands[name] = cls
60 cfac048c Giorgos Verigakis
        return cls
61 cfac048c Giorgos Verigakis
    return decorator
62 cfac048c Giorgos Verigakis
63 cfac048c Giorgos Verigakis
def class_for_cli_command(name):
64 cfac048c Giorgos Verigakis
    return _cli_commands[name]
65 cfac048c Giorgos Verigakis
66 cfac048c Giorgos Verigakis
class Command(object):
67 10998c60 Sofia Papagiannaki
    syntax = ''
68 10998c60 Sofia Papagiannaki
    
69 a2defd86 Sofia Papagiannaki
    def __init__(self, name, argv):
70 a2defd86 Sofia Papagiannaki
        parser = OptionParser('%%prog %s [options] %s' % (name, self.syntax))
71 96738a78 Sofia Papagiannaki
        parser.add_option('--url', dest='url', metavar='URL',
72 2a0d6ae0 Sofia Papagiannaki
                          default=get_url(), help='server URL (currently: %s)' % get_url())
73 2a0d6ae0 Sofia Papagiannaki
        parser.add_option('--user', dest='user', metavar='USER',
74 a5149fd0 Sofia Papagiannaki
                          default=get_user(),
75 2a0d6ae0 Sofia Papagiannaki
                          help='account USER (currently: %s)' % get_user())
76 2a0d6ae0 Sofia Papagiannaki
        parser.add_option('--token', dest='token', metavar='TOKEN',
77 a5149fd0 Sofia Papagiannaki
                          default=get_auth(),
78 2a0d6ae0 Sofia Papagiannaki
                          help='account TOKEN (currently: %s)' % get_auth())
79 f07c5a53 Sofia Papagiannaki
        parser.add_option('-v', action='store_true', dest='verbose',
80 2a0d6ae0 Sofia Papagiannaki
                          default=False, help='verbose output')
81 f07c5a53 Sofia Papagiannaki
        parser.add_option('-d', action='store_true', dest='debug',
82 2a0d6ae0 Sofia Papagiannaki
                          default=False, help='debug output')
83 cfac048c Giorgos Verigakis
        self.add_options(parser)
84 cfac048c Giorgos Verigakis
        options, args = parser.parse_args(argv)
85 cfac048c Giorgos Verigakis
        
86 cfac048c Giorgos Verigakis
        # Add options to self
87 cfac048c Giorgos Verigakis
        for opt in parser.option_list:
88 cfac048c Giorgos Verigakis
            key = opt.dest
89 cfac048c Giorgos Verigakis
            if key:
90 cfac048c Giorgos Verigakis
                val = getattr(options, key)
91 cfac048c Giorgos Verigakis
                setattr(self, key, val)
92 cfac048c Giorgos Verigakis
        
93 09fd65c7 Sofia Papagiannaki
        self.client = Pithos_Client(self.url, self.token, self.user, self.verbose,
94 f07c5a53 Sofia Papagiannaki
                             self.debug)
95 cfac048c Giorgos Verigakis
        
96 cfac048c Giorgos Verigakis
        self.parser = parser
97 cfac048c Giorgos Verigakis
        self.args = args
98 25c3841c Sofia Papagiannaki
    
99 25c3841c Sofia Papagiannaki
    def _build_args(self, attrs):
100 25c3841c Sofia Papagiannaki
        args = {}
101 25c3841c Sofia Papagiannaki
        for a in [a for a in attrs if getattr(self, a)]:
102 25c3841c Sofia Papagiannaki
            args[a] = getattr(self, a)
103 25c3841c Sofia Papagiannaki
        return args
104 25c3841c Sofia Papagiannaki
105 cfac048c Giorgos Verigakis
    def add_options(self, parser):
106 cfac048c Giorgos Verigakis
        pass
107 f7ab99df Sofia Papagiannaki
    
108 cfac048c Giorgos Verigakis
    def execute(self, *args):
109 cfac048c Giorgos Verigakis
        pass
110 cfac048c Giorgos Verigakis
111 cfac048c Giorgos Verigakis
@cli_command('list', 'ls')
112 cfac048c Giorgos Verigakis
class List(Command):
113 f07c5a53 Sofia Papagiannaki
    syntax = '[<container>[/<object>]]'
114 cfac048c Giorgos Verigakis
    description = 'list containers or objects'
115 cfac048c Giorgos Verigakis
    
116 cfac048c Giorgos Verigakis
    def add_options(self, parser):
117 3f5b02c7 Sofia Papagiannaki
        parser.add_option('-l', action='store_true', dest='detail',
118 3f5b02c7 Sofia Papagiannaki
                          default=False, help='show detailed output')
119 3f5b02c7 Sofia Papagiannaki
        parser.add_option('-n', action='store', type='int', dest='limit',
120 25c3841c Sofia Papagiannaki
                          default=10000, help='show limited output')
121 3f5b02c7 Sofia Papagiannaki
        parser.add_option('--marker', action='store', type='str',
122 3f5b02c7 Sofia Papagiannaki
                          dest='marker', default=None,
123 3f5b02c7 Sofia Papagiannaki
                          help='show output greater then marker')
124 3f5b02c7 Sofia Papagiannaki
        parser.add_option('--prefix', action='store', type='str',
125 3f5b02c7 Sofia Papagiannaki
                          dest='prefix', default=None,
126 3f5b02c7 Sofia Papagiannaki
                          help='show output starting with prefix')
127 3f5b02c7 Sofia Papagiannaki
        parser.add_option('--delimiter', action='store', type='str',
128 3f5b02c7 Sofia Papagiannaki
                          dest='delimiter', default=None,
129 3f5b02c7 Sofia Papagiannaki
                          help='show output up to the delimiter')
130 3f5b02c7 Sofia Papagiannaki
        parser.add_option('--path', action='store', type='str',
131 3f5b02c7 Sofia Papagiannaki
                          dest='path', default=None,
132 3f5b02c7 Sofia Papagiannaki
                          help='show output starting with prefix up to /')
133 3f5b02c7 Sofia Papagiannaki
        parser.add_option('--meta', action='store', type='str',
134 3f5b02c7 Sofia Papagiannaki
                          dest='meta', default=None,
135 3f5b02c7 Sofia Papagiannaki
                          help='show output having the specified meta keys')
136 3f5b02c7 Sofia Papagiannaki
        parser.add_option('--if-modified-since', action='store', type='str',
137 3f5b02c7 Sofia Papagiannaki
                          dest='if_modified_since', default=None,
138 3f5b02c7 Sofia Papagiannaki
                          help='show output if modified since then')
139 3f5b02c7 Sofia Papagiannaki
        parser.add_option('--if-unmodified-since', action='store', type='str',
140 3f5b02c7 Sofia Papagiannaki
                          dest='if_unmodified_since', default=None,
141 3f5b02c7 Sofia Papagiannaki
                          help='show output if not modified since then')
142 d2d5c360 Sofia Papagiannaki
        parser.add_option('--until', action='store', dest='until',
143 f0eacc2c Sofia Papagiannaki
                          default=None, help='show metadata until that date')
144 d2d5c360 Sofia Papagiannaki
        parser.add_option('--format', action='store', dest='format',
145 d2d5c360 Sofia Papagiannaki
                          default='%d/%m/%Y', help='format to parse until date')
146 f7ab99df Sofia Papagiannaki
    
147 cfac048c Giorgos Verigakis
    def execute(self, container=None):
148 cfac048c Giorgos Verigakis
        if container:
149 cfac048c Giorgos Verigakis
            self.list_objects(container)
150 cfac048c Giorgos Verigakis
        else:
151 cfac048c Giorgos Verigakis
            self.list_containers()
152 f7ab99df Sofia Papagiannaki
    
153 cfac048c Giorgos Verigakis
    def list_containers(self):
154 f0eacc2c Sofia Papagiannaki
        attrs = ['limit', 'marker', 'if_modified_since',
155 25c3841c Sofia Papagiannaki
                 'if_unmodified_since']
156 25c3841c Sofia Papagiannaki
        args = self._build_args(attrs)
157 f0eacc2c Sofia Papagiannaki
        args['format'] = 'json' if self.detail else 'text'
158 d2d5c360 Sofia Papagiannaki
        
159 f0eacc2c Sofia Papagiannaki
        if getattr(self, 'until'):
160 d2d5c360 Sofia Papagiannaki
            t = _time.strptime(self.until, self.format)
161 25c3841c Sofia Papagiannaki
            args['until'] = int(_time.mktime(t))
162 d2d5c360 Sofia Papagiannaki
        
163 25c3841c Sofia Papagiannaki
        l = self.client.list_containers(**args)
164 f07c5a53 Sofia Papagiannaki
        print_list(l)
165 f7ab99df Sofia Papagiannaki
    
166 cfac048c Giorgos Verigakis
    def list_objects(self, container):
167 bcb7c5a8 Sofia Papagiannaki
        #prepate params
168 bcb7c5a8 Sofia Papagiannaki
        params = {}
169 f0eacc2c Sofia Papagiannaki
        attrs = ['limit', 'marker', 'prefix', 'delimiter', 'path',
170 25c3841c Sofia Papagiannaki
                 'meta', 'if_modified_since', 'if_unmodified_since']
171 25c3841c Sofia Papagiannaki
        args = self._build_args(attrs)
172 f0eacc2c Sofia Papagiannaki
        args['format'] = 'json' if self.detail else 'text'
173 bcb7c5a8 Sofia Papagiannaki
        
174 bcb7c5a8 Sofia Papagiannaki
        if self.until:
175 bcb7c5a8 Sofia Papagiannaki
            t = _time.strptime(self.until, self.format)
176 25c3841c Sofia Papagiannaki
            args['until'] = int(_time.mktime(t))
177 bcb7c5a8 Sofia Papagiannaki
        
178 d2d5c360 Sofia Papagiannaki
        container, sep, object = container.partition('/')
179 d2d5c360 Sofia Papagiannaki
        if object:
180 d2d5c360 Sofia Papagiannaki
            return
181 d2d5c360 Sofia Papagiannaki
        
182 a4c10cbc Sofia Papagiannaki
        detail = 'json'
183 a2defd86 Sofia Papagiannaki
        #if request with meta quering disable trash filtering
184 a2defd86 Sofia Papagiannaki
        show_trashed = True if self.meta else False
185 25c3841c Sofia Papagiannaki
        l = self.client.list_objects(container, **args)
186 a4c10cbc Sofia Papagiannaki
        print_list(l, detail=self.detail)
187 cfac048c Giorgos Verigakis
188 cfac048c Giorgos Verigakis
@cli_command('meta')
189 cfac048c Giorgos Verigakis
class Meta(Command):
190 cfac048c Giorgos Verigakis
    syntax = '[<container>[/<object>]]'
191 f63cf249 Sofia Papagiannaki
    description = 'get account/container/object metadata'
192 0ea1dcc4 Sofia Papagiannaki
    
193 0ea1dcc4 Sofia Papagiannaki
    def add_options(self, parser):
194 0ea1dcc4 Sofia Papagiannaki
        parser.add_option('-r', action='store_true', dest='restricted',
195 0ea1dcc4 Sofia Papagiannaki
                          default=False, help='show only user defined metadata')
196 d2d5c360 Sofia Papagiannaki
        parser.add_option('--until', action='store', dest='until',
197 f0eacc2c Sofia Papagiannaki
                          default=None, help='show metadata until that date')
198 d2d5c360 Sofia Papagiannaki
        parser.add_option('--format', action='store', dest='format',
199 d2d5c360 Sofia Papagiannaki
                          default='%d/%m/%Y', help='format to parse until date')
200 e3fd7f91 Sofia Papagiannaki
        parser.add_option('--version', action='store', dest='version',
201 e3fd7f91 Sofia Papagiannaki
                          default=None, help='show specific version \
202 e3fd7f91 Sofia Papagiannaki
                                  (applies only for objects)')
203 f7ab99df Sofia Papagiannaki
    
204 cfac048c Giorgos Verigakis
    def execute(self, path=''):
205 cfac048c Giorgos Verigakis
        container, sep, object = path.partition('/')
206 f546c15e Antony Chazapis
        args = {'restricted': self.restricted}
207 f0eacc2c Sofia Papagiannaki
        if getattr(self, 'until'):
208 d2d5c360 Sofia Papagiannaki
            t = _time.strptime(self.until, self.format)
209 25c3841c Sofia Papagiannaki
            args['until'] = int(_time.mktime(t))
210 7812e1f9 Sofia Papagiannaki
        
211 cfac048c Giorgos Verigakis
        if object:
212 0ea1dcc4 Sofia Papagiannaki
            meta = self.client.retrieve_object_metadata(container, object,
213 8fe01d72 Sofia Papagiannaki
                                                        self.restricted,
214 8fe01d72 Sofia Papagiannaki
                                                        self.version)
215 cfac048c Giorgos Verigakis
        elif container:
216 25c3841c Sofia Papagiannaki
            meta = self.client.retrieve_container_metadata(container, **args)
217 cfac048c Giorgos Verigakis
        else:
218 25c3841c Sofia Papagiannaki
            meta = self.client.retrieve_account_metadata(**args)
219 f07c5a53 Sofia Papagiannaki
        if meta == None:
220 f07c5a53 Sofia Papagiannaki
            print 'Entity does not exist'
221 f07c5a53 Sofia Papagiannaki
        else:
222 f07c5a53 Sofia Papagiannaki
            print_dict(meta, header=None)
223 cfac048c Giorgos Verigakis
224 cfac048c Giorgos Verigakis
@cli_command('create')
225 cfac048c Giorgos Verigakis
class CreateContainer(Command):
226 f07c5a53 Sofia Papagiannaki
    syntax = '<container> [key=val] [...]'
227 cfac048c Giorgos Verigakis
    description = 'create a container'
228 5a8dc30c Sofia Papagiannaki
    
229 5a8dc30c Sofia Papagiannaki
    def add_options(self, parser):
230 93abb8b2 Antony Chazapis
        parser.add_option('--versioning', action='store', dest='versioning',
231 5a8dc30c Sofia Papagiannaki
                          default=None, help='set container versioning (auto/none)')
232 93abb8b2 Antony Chazapis
        parser.add_option('--quota', action='store', dest='quota',
233 5a8dc30c Sofia Papagiannaki
                          default=None, help='set default container quota')
234 cfac048c Giorgos Verigakis
    
235 f07c5a53 Sofia Papagiannaki
    def execute(self, container, *args):
236 bcb7c5a8 Sofia Papagiannaki
        meta = {}
237 f07c5a53 Sofia Papagiannaki
        for arg in args:
238 f07c5a53 Sofia Papagiannaki
            key, sep, val = arg.partition('=')
239 bcb7c5a8 Sofia Papagiannaki
            meta[key] = val
240 93abb8b2 Antony Chazapis
        policy = {}
241 93abb8b2 Antony Chazapis
        if getattr(self, 'versioning'):
242 93abb8b2 Antony Chazapis
            policy['versioning'] = self.versioning
243 93abb8b2 Antony Chazapis
        if getattr(self, 'quota'):
244 93abb8b2 Antony Chazapis
            policy['quota'] = self.quota
245 5a8dc30c Sofia Papagiannaki
        ret = self.client.create_container(container, meta=meta, policies=policy)
246 cfac048c Giorgos Verigakis
        if not ret:
247 cfac048c Giorgos Verigakis
            print 'Container already exists'
248 cfac048c Giorgos Verigakis
249 cfac048c Giorgos Verigakis
@cli_command('delete', 'rm')
250 cfac048c Giorgos Verigakis
class Delete(Command):
251 cfac048c Giorgos Verigakis
    syntax = '<container>[/<object>]'
252 cfac048c Giorgos Verigakis
    description = 'delete a container or an object'
253 cfac048c Giorgos Verigakis
    
254 25c3841c Sofia Papagiannaki
    def add_options(self, parser):
255 25c3841c Sofia Papagiannaki
        parser.add_option('--until', action='store', dest='until',
256 f0eacc2c Sofia Papagiannaki
                          default=None, help='remove history until that date')
257 25c3841c Sofia Papagiannaki
        parser.add_option('--format', action='store', dest='format',
258 25c3841c Sofia Papagiannaki
                          default='%d/%m/%Y', help='format to parse until date')
259 25c3841c Sofia Papagiannaki
    
260 cfac048c Giorgos Verigakis
    def execute(self, path):
261 cfac048c Giorgos Verigakis
        container, sep, object = path.partition('/')
262 f0eacc2c Sofia Papagiannaki
        until = None
263 f0eacc2c Sofia Papagiannaki
        if getattr(self, 'until'):
264 25c3841c Sofia Papagiannaki
            t = _time.strptime(self.until, self.format)
265 25c3841c Sofia Papagiannaki
            until = int(_time.mktime(t))
266 25c3841c Sofia Papagiannaki
        
267 cfac048c Giorgos Verigakis
        if object:
268 25c3841c Sofia Papagiannaki
            self.client.delete_object(container, object, until)
269 cfac048c Giorgos Verigakis
        else:
270 25c3841c Sofia Papagiannaki
            self.client.delete_container(container, until)
271 cfac048c Giorgos Verigakis
272 cfac048c Giorgos Verigakis
@cli_command('get')
273 cfac048c Giorgos Verigakis
class GetObject(Command):
274 cfac048c Giorgos Verigakis
    syntax = '<container>/<object>'
275 cfac048c Giorgos Verigakis
    description = 'get the data of an object'
276 cfac048c Giorgos Verigakis
    
277 f07c5a53 Sofia Papagiannaki
    def add_options(self, parser):
278 f07c5a53 Sofia Papagiannaki
        parser.add_option('-l', action='store_true', dest='detail',
279 f07c5a53 Sofia Papagiannaki
                          default=False, help='show detailed output')
280 f07c5a53 Sofia Papagiannaki
        parser.add_option('--range', action='store', dest='range',
281 f07c5a53 Sofia Papagiannaki
                          default=None, help='show range of data')
282 25c3841c Sofia Papagiannaki
        parser.add_option('--if-range', action='store', dest='if_range',
283 b44d602e Sofia Papagiannaki
                          default=None, help='show range of data')
284 25c3841c Sofia Papagiannaki
        parser.add_option('--if-match', action='store', dest='if_match',
285 f07c5a53 Sofia Papagiannaki
                          default=None, help='show output if ETags match')
286 f07c5a53 Sofia Papagiannaki
        parser.add_option('--if-none-match', action='store',
287 25c3841c Sofia Papagiannaki
                          dest='if_none_match', default=None,
288 f07c5a53 Sofia Papagiannaki
                          help='show output if ETags don\'t match')
289 f07c5a53 Sofia Papagiannaki
        parser.add_option('--if-modified-since', action='store', type='str',
290 25c3841c Sofia Papagiannaki
                          dest='if_modified_since', default=None,
291 f07c5a53 Sofia Papagiannaki
                          help='show output if modified since then')
292 f07c5a53 Sofia Papagiannaki
        parser.add_option('--if-unmodified-since', action='store', type='str',
293 25c3841c Sofia Papagiannaki
                          dest='if_unmodified_since', default=None,
294 f07c5a53 Sofia Papagiannaki
                          help='show output if not modified since then')
295 bcb7c5a8 Sofia Papagiannaki
        parser.add_option('-o', action='store', type='str',
296 f07c5a53 Sofia Papagiannaki
                          dest='file', default=None,
297 f07c5a53 Sofia Papagiannaki
                          help='save output in file')
298 8fe01d72 Sofia Papagiannaki
        parser.add_option('--version', action='store', type='str',
299 ad71a0ce Sofia Papagiannaki
                          dest='version', default=None,
300 085a31d7 Sofia Papagiannaki
                          help='get the specific \
301 8fe01d72 Sofia Papagiannaki
                               version')
302 085a31d7 Sofia Papagiannaki
        parser.add_option('--versionlist', action='store_true',
303 085a31d7 Sofia Papagiannaki
                          dest='versionlist', default=False,
304 085a31d7 Sofia Papagiannaki
                          help='get the full object version list')
305 f9e723fd Sofia Papagiannaki
        parser.add_option('--hashmap', action='store_true',
306 f9e723fd Sofia Papagiannaki
                          dest='hashmap', default=False,
307 f9e723fd Sofia Papagiannaki
                          help='get the object hashmap instead')
308 f7ab99df Sofia Papagiannaki
    
309 cfac048c Giorgos Verigakis
    def execute(self, path):
310 f0eacc2c Sofia Papagiannaki
        attrs = ['if_match', 'if_none_match', 'if_modified_since',
311 f9e723fd Sofia Papagiannaki
                 'if_unmodified_since', 'hashmap']
312 25c3841c Sofia Papagiannaki
        args = self._build_args(attrs)
313 f0eacc2c Sofia Papagiannaki
        args['format'] = 'json' if self.detail else 'text'
314 f07c5a53 Sofia Papagiannaki
        if self.range:
315 f546c15e Antony Chazapis
            args['range'] = 'bytes=%s' % self.range
316 25c3841c Sofia Papagiannaki
        if getattr(self, 'if_range'):
317 25c3841c Sofia Papagiannaki
            args['if-range'] = 'If-Range:%s' % getattr(self, 'if_range')
318 25c3841c Sofia Papagiannaki
        
319 cfac048c Giorgos Verigakis
        container, sep, object = path.partition('/')
320 25c3841c Sofia Papagiannaki
        data = None
321 085a31d7 Sofia Papagiannaki
        if self.versionlist:
322 25c3841c Sofia Papagiannaki
            if 'detail' in args.keys():
323 25c3841c Sofia Papagiannaki
                args.pop('detail')
324 7f769d34 Sofia Papagiannaki
            args.pop('format')
325 11999722 Sofia Papagiannaki
            self.detail = True
326 25c3841c Sofia Papagiannaki
            data = self.client.retrieve_object_versionlist(container, object, **args)
327 25c3841c Sofia Papagiannaki
        elif self.version:
328 25c3841c Sofia Papagiannaki
            data = self.client.retrieve_object_version(container, object,
329 25c3841c Sofia Papagiannaki
                                                       self.version, **args)
330 f9e723fd Sofia Papagiannaki
        elif self.hashmap:
331 f9e723fd Sofia Papagiannaki
            if 'detail' in args.keys():
332 f9e723fd Sofia Papagiannaki
                args.pop('detail')
333 f9e723fd Sofia Papagiannaki
            args.pop('format')
334 f9e723fd Sofia Papagiannaki
            self.detail = True
335 f9e723fd Sofia Papagiannaki
            data = self.client.retrieve_object_hashmap(container, object, **args)
336 25c3841c Sofia Papagiannaki
        else:
337 25c3841c Sofia Papagiannaki
            data = self.client.retrieve_object(container, object, **args)    
338 25c3841c Sofia Papagiannaki
        
339 af6d3b5d Antony Chazapis
        f = open(self.file, 'w') if self.file else stdout
340 f9e723fd Sofia Papagiannaki
        if self.detail or type(data) == types.DictionaryType:
341 085a31d7 Sofia Papagiannaki
            if self.versionlist:
342 8fe01d72 Sofia Papagiannaki
                print_versions(data, f=f)
343 f07c5a53 Sofia Papagiannaki
            else:
344 8fe01d72 Sofia Papagiannaki
                print_dict(data, f=f)
345 f07c5a53 Sofia Papagiannaki
        else:
346 8fe01d72 Sofia Papagiannaki
            f.write(data)
347 8fe01d72 Sofia Papagiannaki
        f.close()
348 cfac048c Giorgos Verigakis
349 f7ab99df Sofia Papagiannaki
@cli_command('mkdir')
350 f7ab99df Sofia Papagiannaki
class PutMarker(Command):
351 f7ab99df Sofia Papagiannaki
    syntax = '<container>/<directory marker>'
352 f7ab99df Sofia Papagiannaki
    description = 'create a directory marker'
353 f7ab99df Sofia Papagiannaki
    
354 f7ab99df Sofia Papagiannaki
    def execute(self, path):
355 f7ab99df Sofia Papagiannaki
        container, sep, object = path.partition('/')
356 f7ab99df Sofia Papagiannaki
        self.client.create_directory_marker(container, object)
357 f7ab99df Sofia Papagiannaki
358 cfac048c Giorgos Verigakis
@cli_command('put')
359 cfac048c Giorgos Verigakis
class PutObject(Command):
360 f63cf249 Sofia Papagiannaki
    syntax = '<container>/<object> [key=val] [...]'
361 f89e3cf4 Sofia Papagiannaki
    description = 'create/override object'
362 f7ab99df Sofia Papagiannaki
    
363 f07c5a53 Sofia Papagiannaki
    def add_options(self, parser):
364 bcb7c5a8 Sofia Papagiannaki
        parser.add_option('--use_hashes', action='store_true', dest='use_hashes',
365 bcb7c5a8 Sofia Papagiannaki
                          default=False, help='provide hashmap instead of data')
366 f07c5a53 Sofia Papagiannaki
        parser.add_option('--chunked', action='store_true', dest='chunked',
367 f07c5a53 Sofia Papagiannaki
                          default=False, help='set chunked transfer mode')
368 f07c5a53 Sofia Papagiannaki
        parser.add_option('--etag', action='store', dest='etag',
369 f07c5a53 Sofia Papagiannaki
                          default=None, help='check written data')
370 f07c5a53 Sofia Papagiannaki
        parser.add_option('--content-encoding', action='store',
371 25c3841c Sofia Papagiannaki
                          dest='content_encoding', default=None,
372 f07c5a53 Sofia Papagiannaki
                          help='provide the object MIME content type')
373 f07c5a53 Sofia Papagiannaki
        parser.add_option('--content-disposition', action='store', type='str',
374 25c3841c Sofia Papagiannaki
                          dest='content_disposition', default=None,
375 f07c5a53 Sofia Papagiannaki
                          help='provide the presentation style of the object')
376 25c3841c Sofia Papagiannaki
        #parser.add_option('-S', action='store',
377 25c3841c Sofia Papagiannaki
        #                  dest='segment_size', default=False,
378 25c3841c Sofia Papagiannaki
        #                  help='use for large file support')
379 050ec33b Sofia Papagiannaki
        parser.add_option('--manifest', action='store',
380 25c3841c Sofia Papagiannaki
                          dest='x_object_manifest', default=None,
381 f9e723fd Sofia Papagiannaki
                          help='provide object parts prefix in <container>/<object> form')
382 25c3841c Sofia Papagiannaki
        parser.add_option('--content-type', action='store',
383 25c3841c Sofia Papagiannaki
                          dest='content_type', default=None,
384 f7ab99df Sofia Papagiannaki
                          help='create object with specific content type')
385 d3fd269f Sofia Papagiannaki
        parser.add_option('--sharing', action='store',
386 25c3841c Sofia Papagiannaki
                          dest='x_object_sharing', default=None,
387 d3fd269f Sofia Papagiannaki
                          help='define sharing object policy')
388 bcb7c5a8 Sofia Papagiannaki
        parser.add_option('-f', action='store',
389 bcb7c5a8 Sofia Papagiannaki
                          dest='srcpath', default=None,
390 f89e3cf4 Sofia Papagiannaki
                          help='file descriptor to read from (pass - for standard input)')
391 25c3841c Sofia Papagiannaki
        parser.add_option('--public', action='store_true',
392 25c3841c Sofia Papagiannaki
                          dest='x_object_public', default=False,
393 7812e1f9 Sofia Papagiannaki
                          help='make object publicly accessible')
394 f89e3cf4 Sofia Papagiannaki
    
395 bcb7c5a8 Sofia Papagiannaki
    def execute(self, path, *args):
396 bcb7c5a8 Sofia Papagiannaki
        if path.find('=') != -1:
397 bcb7c5a8 Sofia Papagiannaki
            raise Fault('Missing path argument')
398 bcb7c5a8 Sofia Papagiannaki
        
399 bcb7c5a8 Sofia Papagiannaki
        #prepare user defined meta
400 bcb7c5a8 Sofia Papagiannaki
        meta = {}
401 bcb7c5a8 Sofia Papagiannaki
        for arg in args:
402 bcb7c5a8 Sofia Papagiannaki
            key, sep, val = arg.partition('=')
403 bcb7c5a8 Sofia Papagiannaki
            meta[key] = val
404 d3fd269f Sofia Papagiannaki
        
405 25c3841c Sofia Papagiannaki
        attrs = ['etag', 'content_encoding', 'content_disposition',
406 25c3841c Sofia Papagiannaki
                 'content_type', 'x_object_sharing', 'x_object_public']
407 25c3841c Sofia Papagiannaki
        args = self._build_args(attrs)
408 f07c5a53 Sofia Papagiannaki
        
409 cfac048c Giorgos Verigakis
        container, sep, object = path.partition('/')
410 f07c5a53 Sofia Papagiannaki
        
411 d2d5c360 Sofia Papagiannaki
        f = None
412 bcb7c5a8 Sofia Papagiannaki
        if self.srcpath:
413 bcb7c5a8 Sofia Papagiannaki
            f = open(self.srcpath) if self.srcpath != '-' else stdin
414 bcb7c5a8 Sofia Papagiannaki
        
415 bcb7c5a8 Sofia Papagiannaki
        if self.use_hashes and not f:
416 bcb7c5a8 Sofia Papagiannaki
            raise Fault('Illegal option combination')
417 25c3841c Sofia Papagiannaki
        
418 25c3841c Sofia Papagiannaki
        if self.chunked:
419 25c3841c Sofia Papagiannaki
            self.client.create_object_using_chunks(container, object, f,
420 25c3841c Sofia Papagiannaki
                                                    meta=meta, **args)
421 25c3841c Sofia Papagiannaki
        elif self.use_hashes:
422 54ca3d0f Sofia Papagiannaki
            data = f.read()
423 b8fa0222 Sofia Papagiannaki
            hashmap = json.loads(data)
424 b8fa0222 Sofia Papagiannaki
            self.client.create_object_by_hashmap(container, object, hashmap,
425 b8fa0222 Sofia Papagiannaki
                                             meta=meta, **args)
426 25c3841c Sofia Papagiannaki
        elif self.x_object_manifest:
427 25c3841c Sofia Papagiannaki
            self.client.create_manifestation(container, object, self.x_object_manifest)
428 cd6ada1d Sofia Papagiannaki
        elif not f:
429 cd6ada1d Sofia Papagiannaki
            self.client.create_zero_length_object(container, object, meta=meta, **args)
430 25c3841c Sofia Papagiannaki
        else:
431 4211443b Sofia Papagiannaki
            self.client.create_object(container, object, f, meta=meta, **args)
432 d2d5c360 Sofia Papagiannaki
        if f:
433 d2d5c360 Sofia Papagiannaki
            f.close()
434 cfac048c Giorgos Verigakis
435 cfac048c Giorgos Verigakis
@cli_command('copy', 'cp')
436 cfac048c Giorgos Verigakis
class CopyObject(Command):
437 7812e1f9 Sofia Papagiannaki
    syntax = '<src container>/<src object> [<dst container>/]<dst object> [key=val] [...]'
438 f89e3cf4 Sofia Papagiannaki
    description = 'copy an object to a different location'
439 cfac048c Giorgos Verigakis
    
440 ad71a0ce Sofia Papagiannaki
    def add_options(self, parser):
441 ad71a0ce Sofia Papagiannaki
        parser.add_option('--version', action='store',
442 ad71a0ce Sofia Papagiannaki
                          dest='version', default=False,
443 ad71a0ce Sofia Papagiannaki
                          help='copy specific version')
444 7812e1f9 Sofia Papagiannaki
        parser.add_option('--public', action='store_true',
445 7812e1f9 Sofia Papagiannaki
                          dest='public', default=False,
446 7812e1f9 Sofia Papagiannaki
                          help='make object publicly accessible')
447 d4a63b9b Sofia Papagiannaki
        parser.add_option('--content-type', action='store',
448 d4a63b9b Sofia Papagiannaki
                          dest='content_type', default=None,
449 d4a63b9b Sofia Papagiannaki
                          help='change object\'s content type')
450 f7ab99df Sofia Papagiannaki
    
451 7812e1f9 Sofia Papagiannaki
    def execute(self, src, dst, *args):
452 cfac048c Giorgos Verigakis
        src_container, sep, src_object = src.partition('/')
453 cfac048c Giorgos Verigakis
        dst_container, sep, dst_object = dst.partition('/')
454 7812e1f9 Sofia Papagiannaki
        
455 7812e1f9 Sofia Papagiannaki
        #prepare user defined meta
456 7812e1f9 Sofia Papagiannaki
        meta = {}
457 7812e1f9 Sofia Papagiannaki
        for arg in args:
458 7812e1f9 Sofia Papagiannaki
            key, sep, val = arg.partition('=')
459 7812e1f9 Sofia Papagiannaki
            meta[key] = val
460 7812e1f9 Sofia Papagiannaki
        
461 cfac048c Giorgos Verigakis
        if not sep:
462 cfac048c Giorgos Verigakis
            dst_container = src_container
463 cfac048c Giorgos Verigakis
            dst_object = dst
464 7812e1f9 Sofia Papagiannaki
        
465 d4a63b9b Sofia Papagiannaki
        args = {'content_type':self.content_type} if self.content_type else {}
466 f07c5a53 Sofia Papagiannaki
        self.client.copy_object(src_container, src_object, dst_container,
467 d4a63b9b Sofia Papagiannaki
                                dst_object, meta, self.public, self.version,
468 d4a63b9b Sofia Papagiannaki
                                **args)
469 cfac048c Giorgos Verigakis
470 cfac048c Giorgos Verigakis
@cli_command('set')
471 3f5b02c7 Sofia Papagiannaki
class SetMeta(Command):
472 3f5b02c7 Sofia Papagiannaki
    syntax = '[<container>[/<object>]] key=val [key=val] [...]'
473 f63cf249 Sofia Papagiannaki
    description = 'set account/container/object metadata'
474 cfac048c Giorgos Verigakis
    
475 cfac048c Giorgos Verigakis
    def execute(self, path, *args):
476 3f5b02c7 Sofia Papagiannaki
        #in case of account fix the args
477 f07c5a53 Sofia Papagiannaki
        if path.find('=') != -1:
478 3f5b02c7 Sofia Papagiannaki
            args = list(args)
479 3f5b02c7 Sofia Papagiannaki
            args.append(path)
480 3f5b02c7 Sofia Papagiannaki
            args = tuple(args)
481 3f5b02c7 Sofia Papagiannaki
            path = ''
482 cfac048c Giorgos Verigakis
        meta = {}
483 cfac048c Giorgos Verigakis
        for arg in args:
484 cfac048c Giorgos Verigakis
            key, sep, val = arg.partition('=')
485 cfac048c Giorgos Verigakis
            meta[key.strip()] = val.strip()
486 3f5b02c7 Sofia Papagiannaki
        container, sep, object = path.partition('/')
487 3f5b02c7 Sofia Papagiannaki
        if object:
488 3f5b02c7 Sofia Papagiannaki
            self.client.update_object_metadata(container, object, **meta)
489 3f5b02c7 Sofia Papagiannaki
        elif container:
490 3f5b02c7 Sofia Papagiannaki
            self.client.update_container_metadata(container, **meta)
491 3f5b02c7 Sofia Papagiannaki
        else:
492 3f5b02c7 Sofia Papagiannaki
            self.client.update_account_metadata(**meta)
493 cfac048c Giorgos Verigakis
494 f07c5a53 Sofia Papagiannaki
@cli_command('update')
495 f07c5a53 Sofia Papagiannaki
class UpdateObject(Command):
496 f07c5a53 Sofia Papagiannaki
    syntax = '<container>/<object> path [key=val] [...]'
497 e3fd7f91 Sofia Papagiannaki
    description = 'update object metadata/data (default mode: append)'
498 f07c5a53 Sofia Papagiannaki
    
499 f07c5a53 Sofia Papagiannaki
    def add_options(self, parser):
500 f07c5a53 Sofia Papagiannaki
        parser.add_option('-a', action='store_true', dest='append',
501 e3fd7f91 Sofia Papagiannaki
                          default=True, help='append data')
502 bcb7c5a8 Sofia Papagiannaki
        parser.add_option('--offset', action='store',
503 bcb7c5a8 Sofia Papagiannaki
                          dest='offset',
504 a2defd86 Sofia Papagiannaki
                          default=None, help='starting offest to be updated')
505 f9e723fd Sofia Papagiannaki
        parser.add_option('--range', action='store', dest='content_range',
506 f07c5a53 Sofia Papagiannaki
                          default=None, help='range of data to be updated')
507 f07c5a53 Sofia Papagiannaki
        parser.add_option('--chunked', action='store_true', dest='chunked',
508 f07c5a53 Sofia Papagiannaki
                          default=False, help='set chunked transfer mode')
509 f07c5a53 Sofia Papagiannaki
        parser.add_option('--content-encoding', action='store',
510 25c3841c Sofia Papagiannaki
                          dest='content_encoding', default=None,
511 f07c5a53 Sofia Papagiannaki
                          help='provide the object MIME content type')
512 f07c5a53 Sofia Papagiannaki
        parser.add_option('--content-disposition', action='store', type='str',
513 25c3841c Sofia Papagiannaki
                          dest='content_disposition', default=None,
514 f07c5a53 Sofia Papagiannaki
                          help='provide the presentation style of the object')
515 f07c5a53 Sofia Papagiannaki
        parser.add_option('--manifest', action='store', type='str',
516 25c3841c Sofia Papagiannaki
                          dest='x_object_manifest', default=None,
517 d3fd269f Sofia Papagiannaki
                          help='use for large file support')        
518 d3fd269f Sofia Papagiannaki
        parser.add_option('--sharing', action='store',
519 25c3841c Sofia Papagiannaki
                          dest='x_object_sharing', default=None,
520 d3fd269f Sofia Papagiannaki
                          help='define sharing object policy')
521 bcb7c5a8 Sofia Papagiannaki
        parser.add_option('--nosharing', action='store_true',
522 bcb7c5a8 Sofia Papagiannaki
                          dest='no_sharing', default=None,
523 bcb7c5a8 Sofia Papagiannaki
                          help='clear object sharing policy')
524 bcb7c5a8 Sofia Papagiannaki
        parser.add_option('-f', action='store',
525 bcb7c5a8 Sofia Papagiannaki
                          dest='srcpath', default=None,
526 bcb7c5a8 Sofia Papagiannaki
                          help='file descriptor to read from: pass - for standard input')
527 7812e1f9 Sofia Papagiannaki
        parser.add_option('--public', action='store_true',
528 25c3841c Sofia Papagiannaki
                          dest='x_object_public', default=False,
529 7812e1f9 Sofia Papagiannaki
                          help='make object publicly accessible')
530 633bbb9f Sofia Papagiannaki
        parser.add_option('--replace', action='store_true',
531 633bbb9f Sofia Papagiannaki
                          dest='replace', default=False,
532 633bbb9f Sofia Papagiannaki
                          help='override metadata')
533 f7ab99df Sofia Papagiannaki
    
534 bcb7c5a8 Sofia Papagiannaki
    def execute(self, path, *args):
535 bcb7c5a8 Sofia Papagiannaki
        if path.find('=') != -1:
536 bcb7c5a8 Sofia Papagiannaki
            raise Fault('Missing path argument')
537 bcb7c5a8 Sofia Papagiannaki
        
538 f07c5a53 Sofia Papagiannaki
        #prepare user defined meta
539 bcb7c5a8 Sofia Papagiannaki
        meta = {}
540 f07c5a53 Sofia Papagiannaki
        for arg in args:
541 f07c5a53 Sofia Papagiannaki
            key, sep, val = arg.partition('=')
542 bcb7c5a8 Sofia Papagiannaki
            meta[key] = val
543 f07c5a53 Sofia Papagiannaki
        
544 25c3841c Sofia Papagiannaki
        
545 25c3841c Sofia Papagiannaki
        attrs = ['content_encoding', 'content_disposition', 'x_object_sharing',
546 f9e723fd Sofia Papagiannaki
                 'x_object_public', 'x_object_manifest', 'replace', 'offset',
547 f9e723fd Sofia Papagiannaki
                 'content_range']
548 25c3841c Sofia Papagiannaki
        args = self._build_args(attrs)
549 25c3841c Sofia Papagiannaki
        
550 38bf2cdc Sofia Papagiannaki
        if self.no_sharing:
551 38bf2cdc Sofia Papagiannaki
            args['x_object_sharing'] = ''
552 38bf2cdc Sofia Papagiannaki
        
553 f07c5a53 Sofia Papagiannaki
        container, sep, object = path.partition('/')
554 f07c5a53 Sofia Papagiannaki
        
555 a2defd86 Sofia Papagiannaki
        f = None
556 bcb7c5a8 Sofia Papagiannaki
        if self.srcpath:
557 25c3841c Sofia Papagiannaki
            f = open(self.srcpath) if self.srcpath != '-' else stdin
558 25c3841c Sofia Papagiannaki
        
559 25c3841c Sofia Papagiannaki
        if self.chunked:
560 25c3841c Sofia Papagiannaki
            self.client.update_object_using_chunks(container, object, f,
561 25c3841c Sofia Papagiannaki
                                                    meta=meta, **args)
562 25c3841c Sofia Papagiannaki
        else:
563 f0964245 Sofia Papagiannaki
            self.client.update_object(container, object, f, meta=meta, **args)
564 a2defd86 Sofia Papagiannaki
        if f:
565 a2defd86 Sofia Papagiannaki
            f.close()
566 f07c5a53 Sofia Papagiannaki
567 f07c5a53 Sofia Papagiannaki
@cli_command('move', 'mv')
568 f07c5a53 Sofia Papagiannaki
class MoveObject(Command):
569 f07c5a53 Sofia Papagiannaki
    syntax = '<src container>/<src object> [<dst container>/]<dst object>'
570 f89e3cf4 Sofia Papagiannaki
    description = 'move an object to a different location'
571 f89e3cf4 Sofia Papagiannaki
    
572 f89e3cf4 Sofia Papagiannaki
    def add_options(self, parser):
573 7812e1f9 Sofia Papagiannaki
        parser.add_option('--public', action='store_true',
574 7812e1f9 Sofia Papagiannaki
                          dest='public', default=False,
575 7812e1f9 Sofia Papagiannaki
                          help='make object publicly accessible')
576 d4a63b9b Sofia Papagiannaki
        parser.add_option('--content-type', action='store',
577 d4a63b9b Sofia Papagiannaki
                          dest='content_type', default=None,
578 d4a63b9b Sofia Papagiannaki
                          help='change object\'s content type')
579 f07c5a53 Sofia Papagiannaki
    
580 7812e1f9 Sofia Papagiannaki
    def execute(self, src, dst, *args):
581 f07c5a53 Sofia Papagiannaki
        src_container, sep, src_object = src.partition('/')
582 f07c5a53 Sofia Papagiannaki
        dst_container, sep, dst_object = dst.partition('/')
583 f07c5a53 Sofia Papagiannaki
        if not sep:
584 f07c5a53 Sofia Papagiannaki
            dst_container = src_container
585 f07c5a53 Sofia Papagiannaki
            dst_object = dst
586 7812e1f9 Sofia Papagiannaki
        
587 7812e1f9 Sofia Papagiannaki
        #prepare user defined meta
588 7812e1f9 Sofia Papagiannaki
        meta = {}
589 7812e1f9 Sofia Papagiannaki
        for arg in args:
590 7812e1f9 Sofia Papagiannaki
            key, sep, val = arg.partition('=')
591 7812e1f9 Sofia Papagiannaki
            meta[key] = val
592 7812e1f9 Sofia Papagiannaki
        
593 d4a63b9b Sofia Papagiannaki
        args = {'content_type':self.content_type} if self.content_type else {}
594 f07c5a53 Sofia Papagiannaki
        self.client.move_object(src_container, src_object, dst_container,
595 97d45f69 Antony Chazapis
                                dst_object, meta, self.public, **args)
596 f7ab99df Sofia Papagiannaki
597 f7ab99df Sofia Papagiannaki
@cli_command('unset')
598 bcb7c5a8 Sofia Papagiannaki
class UnsetObject(Command):
599 f7ab99df Sofia Papagiannaki
    syntax = '<container>/[<object>] key [key] [...]'
600 f89e3cf4 Sofia Papagiannaki
    description = 'delete metadata info'
601 f7ab99df Sofia Papagiannaki
    
602 f7ab99df Sofia Papagiannaki
    def execute(self, path, *args):
603 f7ab99df Sofia Papagiannaki
        #in case of account fix the args
604 961f2fbe Sofia Papagiannaki
        if len(args) == 0:
605 f7ab99df Sofia Papagiannaki
            args = list(args)
606 f7ab99df Sofia Papagiannaki
            args.append(path)
607 f7ab99df Sofia Papagiannaki
            args = tuple(args)
608 f7ab99df Sofia Papagiannaki
            path = ''
609 f7ab99df Sofia Papagiannaki
        meta = []
610 f7ab99df Sofia Papagiannaki
        for key in args:
611 f7ab99df Sofia Papagiannaki
            meta.append(key)
612 f7ab99df Sofia Papagiannaki
        container, sep, object = path.partition('/')
613 f7ab99df Sofia Papagiannaki
        if object:
614 f7ab99df Sofia Papagiannaki
            self.client.delete_object_metadata(container, object, meta)
615 f7ab99df Sofia Papagiannaki
        elif container:
616 f7ab99df Sofia Papagiannaki
            self.client.delete_container_metadata(container, meta)
617 f7ab99df Sofia Papagiannaki
        else:
618 f7ab99df Sofia Papagiannaki
            self.client.delete_account_metadata(meta)
619 f7ab99df Sofia Papagiannaki
620 d3fd269f Sofia Papagiannaki
@cli_command('group')
621 f63cf249 Sofia Papagiannaki
class CreateGroup(Command):
622 d3fd269f Sofia Papagiannaki
    syntax = 'key=val [key=val] [...]'
623 f63cf249 Sofia Papagiannaki
    description = 'create account groups'
624 d3fd269f Sofia Papagiannaki
    
625 bcb7c5a8 Sofia Papagiannaki
    def execute(self, *args):
626 d3fd269f Sofia Papagiannaki
        groups = {}
627 d3fd269f Sofia Papagiannaki
        for arg in args:
628 d3fd269f Sofia Papagiannaki
            key, sep, val = arg.partition('=')
629 d3fd269f Sofia Papagiannaki
            groups[key] = val
630 bcb7c5a8 Sofia Papagiannaki
        self.client.set_account_groups(**groups)
631 bcb7c5a8 Sofia Papagiannaki
632 f63cf249 Sofia Papagiannaki
@cli_command('ungroup')
633 f63cf249 Sofia Papagiannaki
class DeleteGroup(Command):
634 f63cf249 Sofia Papagiannaki
    syntax = 'key [key] [...]'
635 f63cf249 Sofia Papagiannaki
    description = 'delete account groups'
636 f63cf249 Sofia Papagiannaki
    
637 f63cf249 Sofia Papagiannaki
    def execute(self, *args):
638 f63cf249 Sofia Papagiannaki
        groups = []
639 f63cf249 Sofia Papagiannaki
        for arg in args:
640 f63cf249 Sofia Papagiannaki
            groups.append(arg)
641 f63cf249 Sofia Papagiannaki
        self.client.unset_account_groups(groups)
642 f63cf249 Sofia Papagiannaki
643 bcb7c5a8 Sofia Papagiannaki
@cli_command('policy')
644 bcb7c5a8 Sofia Papagiannaki
class SetPolicy(Command):
645 bcb7c5a8 Sofia Papagiannaki
    syntax = 'container key=val [key=val] [...]'
646 f89e3cf4 Sofia Papagiannaki
    description = 'set container policies'
647 bcb7c5a8 Sofia Papagiannaki
    
648 bcb7c5a8 Sofia Papagiannaki
    def execute(self, path, *args):
649 bcb7c5a8 Sofia Papagiannaki
        if path.find('=') != -1:
650 bcb7c5a8 Sofia Papagiannaki
            raise Fault('Missing container argument')
651 bcb7c5a8 Sofia Papagiannaki
        
652 bcb7c5a8 Sofia Papagiannaki
        container, sep, object = path.partition('/')
653 bcb7c5a8 Sofia Papagiannaki
        
654 bcb7c5a8 Sofia Papagiannaki
        if object:
655 bcb7c5a8 Sofia Papagiannaki
            raise Fault('Only containers have policies')
656 bcb7c5a8 Sofia Papagiannaki
        
657 bcb7c5a8 Sofia Papagiannaki
        policies = {}
658 bcb7c5a8 Sofia Papagiannaki
        for arg in args:
659 bcb7c5a8 Sofia Papagiannaki
            key, sep, val = arg.partition('=')
660 bcb7c5a8 Sofia Papagiannaki
            policies[key] = val
661 bcb7c5a8 Sofia Papagiannaki
        
662 bcb7c5a8 Sofia Papagiannaki
        self.client.set_container_policies(container, **policies)
663 d3fd269f Sofia Papagiannaki
664 f89e3cf4 Sofia Papagiannaki
@cli_command('publish')
665 f89e3cf4 Sofia Papagiannaki
class PublishObject(Command):
666 f89e3cf4 Sofia Papagiannaki
    syntax = '<container>/<object>'
667 f89e3cf4 Sofia Papagiannaki
    description = 'publish an object'
668 f89e3cf4 Sofia Papagiannaki
    
669 f89e3cf4 Sofia Papagiannaki
    def execute(self, src):
670 f89e3cf4 Sofia Papagiannaki
        src_container, sep, src_object = src.partition('/')
671 f89e3cf4 Sofia Papagiannaki
        
672 f89e3cf4 Sofia Papagiannaki
        self.client.publish_object(src_container, src_object)
673 f89e3cf4 Sofia Papagiannaki
674 f89e3cf4 Sofia Papagiannaki
@cli_command('unpublish')
675 f89e3cf4 Sofia Papagiannaki
class UnpublishObject(Command):
676 f89e3cf4 Sofia Papagiannaki
    syntax = '<container>/<object>'
677 f89e3cf4 Sofia Papagiannaki
    description = 'unpublish an object'
678 f89e3cf4 Sofia Papagiannaki
    
679 f89e3cf4 Sofia Papagiannaki
    def execute(self, src):
680 f89e3cf4 Sofia Papagiannaki
        src_container, sep, src_object = src.partition('/')
681 f89e3cf4 Sofia Papagiannaki
        
682 f89e3cf4 Sofia Papagiannaki
        self.client.unpublish_object(src_container, src_object)
683 f89e3cf4 Sofia Papagiannaki
684 d4a63b9b Sofia Papagiannaki
@cli_command('sharing')
685 d4a63b9b Sofia Papagiannaki
class SharingObject(Command):
686 d4a63b9b Sofia Papagiannaki
    syntax = 'list users sharing objects with the user'
687 d4a63b9b Sofia Papagiannaki
    description = 'list user accounts sharing objects with the user'
688 d4a63b9b Sofia Papagiannaki
    
689 d4a63b9b Sofia Papagiannaki
    def add_options(self, parser):
690 d4a63b9b Sofia Papagiannaki
        parser.add_option('-l', action='store_true', dest='detail',
691 d4a63b9b Sofia Papagiannaki
                          default=False, help='show detailed output')
692 d4a63b9b Sofia Papagiannaki
        parser.add_option('-n', action='store', type='int', dest='limit',
693 d4a63b9b Sofia Papagiannaki
                          default=10000, help='show limited output')
694 d4a63b9b Sofia Papagiannaki
        parser.add_option('--marker', action='store', type='str',
695 d4a63b9b Sofia Papagiannaki
                          dest='marker', default=None,
696 d4a63b9b Sofia Papagiannaki
                          help='show output greater then marker')
697 d4a63b9b Sofia Papagiannaki
        
698 d4a63b9b Sofia Papagiannaki
    
699 d4a63b9b Sofia Papagiannaki
    def execute(self):
700 d4a63b9b Sofia Papagiannaki
        attrs = ['limit', 'marker']
701 d4a63b9b Sofia Papagiannaki
        args = self._build_args(attrs)
702 d4a63b9b Sofia Papagiannaki
        args['format'] = 'json' if self.detail else 'text'
703 d4a63b9b Sofia Papagiannaki
        
704 d4a63b9b Sofia Papagiannaki
        print_list(self.client.list_shared_by_others(**args))
705 d4a63b9b Sofia Papagiannaki
706 822cc7eb Antony Chazapis
@cli_command('send')
707 822cc7eb Antony Chazapis
class Send(Command):
708 822cc7eb Antony Chazapis
    syntax = '<file> <container>[/<prefix>]'
709 822cc7eb Antony Chazapis
    description = 'upload file to container (using prefix)'
710 f546c15e Antony Chazapis
    
711 f546c15e Antony Chazapis
    def execute(self, file, path):
712 f546c15e Antony Chazapis
        container, sep, prefix = path.partition('/')
713 822cc7eb Antony Chazapis
        upload(self.client, file, container, prefix)
714 822cc7eb Antony Chazapis
715 f546c15e Antony Chazapis
@cli_command('receive')
716 f546c15e Antony Chazapis
class Receive(Command):
717 f546c15e Antony Chazapis
    syntax = '<container>/<object> <file>'
718 f546c15e Antony Chazapis
    description = 'download object to file'
719 f546c15e Antony Chazapis
    
720 f546c15e Antony Chazapis
    def execute(self, path, file):
721 f546c15e Antony Chazapis
        container, sep, object = path.partition('/')
722 f546c15e Antony Chazapis
        download(self.client, container, object, file)
723 f546c15e Antony Chazapis
724 cfac048c Giorgos Verigakis
def print_usage():
725 10998c60 Sofia Papagiannaki
    cmd = Command('', [])
726 cfac048c Giorgos Verigakis
    parser = cmd.parser
727 cfac048c Giorgos Verigakis
    parser.usage = '%prog <command> [options]'
728 cfac048c Giorgos Verigakis
    parser.print_help()
729 cfac048c Giorgos Verigakis
    
730 cfac048c Giorgos Verigakis
    commands = []
731 cfac048c Giorgos Verigakis
    for cls in set(_cli_commands.values()):
732 cfac048c Giorgos Verigakis
        name = ', '.join(cls.commands)
733 cfac048c Giorgos Verigakis
        description = getattr(cls, 'description', '')
734 cfac048c Giorgos Verigakis
        commands.append('  %s %s' % (name.ljust(12), description))
735 cfac048c Giorgos Verigakis
    print '\nCommands:\n' + '\n'.join(sorted(commands))
736 cfac048c Giorgos Verigakis
737 a4c10cbc Sofia Papagiannaki
def print_dict(d, header='name', f=stdout, detail=True):
738 ae75584f Sofia Papagiannaki
    header = header if header in d else 'subdir'
739 f07c5a53 Sofia Papagiannaki
    if header and header in d:
740 ae75584f Sofia Papagiannaki
        f.write('%s\n' %d.pop(header).encode('utf8'))
741 a4c10cbc Sofia Papagiannaki
    if detail:
742 a4c10cbc Sofia Papagiannaki
        patterns = ['^x_(account|container|object)_meta_(\w+)$']
743 a4c10cbc Sofia Papagiannaki
        patterns.append(patterns[0].replace('_', '-'))
744 a4c10cbc Sofia Papagiannaki
        for key, val in sorted(d.items()):
745 a4c10cbc Sofia Papagiannaki
            f.write('%s: %s\n' % (key.rjust(30), val))
746 f07c5a53 Sofia Papagiannaki
747 a4c10cbc Sofia Papagiannaki
def print_list(l, verbose=False, f=stdout, detail=True):
748 f07c5a53 Sofia Papagiannaki
    for elem in l:
749 f07c5a53 Sofia Papagiannaki
        #if it's empty string continue
750 f07c5a53 Sofia Papagiannaki
        if not elem:
751 f07c5a53 Sofia Papagiannaki
            continue
752 f07c5a53 Sofia Papagiannaki
        if type(elem) == types.DictionaryType:
753 a4c10cbc Sofia Papagiannaki
            print_dict(elem, f=f, detail=detail)
754 f07c5a53 Sofia Papagiannaki
        elif type(elem) == types.StringType:
755 f07c5a53 Sofia Papagiannaki
            if not verbose:
756 f07c5a53 Sofia Papagiannaki
                elem = elem.split('Traceback')[0]
757 f07c5a53 Sofia Papagiannaki
            f.write('%s\n' % elem)
758 f07c5a53 Sofia Papagiannaki
        else:
759 f07c5a53 Sofia Papagiannaki
            f.write('%s\n' % elem)
760 cfac048c Giorgos Verigakis
761 8fe01d72 Sofia Papagiannaki
def print_versions(data, f=stdout):
762 8fe01d72 Sofia Papagiannaki
    if 'versions' not in data:
763 8fe01d72 Sofia Papagiannaki
        f.write('%s\n' %data)
764 8fe01d72 Sofia Papagiannaki
        return
765 8fe01d72 Sofia Papagiannaki
    f.write('versions:\n')
766 8fe01d72 Sofia Papagiannaki
    for id, t in data['versions']:
767 e414f54d Sofia Papagiannaki
        f.write('%s @ %s\n' % (str(id).rjust(30), datetime.fromtimestamp(float(t))))
768 8fe01d72 Sofia Papagiannaki
769 9e826a59 Kostas Papadimitriou
770 cfac048c Giorgos Verigakis
def main():
771 cfac048c Giorgos Verigakis
    try:
772 cfac048c Giorgos Verigakis
        name = argv[1]
773 cfac048c Giorgos Verigakis
        cls = class_for_cli_command(name)
774 cfac048c Giorgos Verigakis
    except (IndexError, KeyError):
775 cfac048c Giorgos Verigakis
        print_usage()
776 cfac048c Giorgos Verigakis
        exit(1)
777 f07c5a53 Sofia Papagiannaki
    
778 a2defd86 Sofia Papagiannaki
    cmd = cls(name, argv[2:])
779 cfac048c Giorgos Verigakis
    
780 95e92490 Sofia Papagiannaki
    try:
781 95e92490 Sofia Papagiannaki
        cmd.execute(*cmd.args)
782 95e92490 Sofia Papagiannaki
    except TypeError, e:
783 95e92490 Sofia Papagiannaki
        cmd.parser.print_help()
784 95e92490 Sofia Papagiannaki
        exit(1)
785 95e92490 Sofia Papagiannaki
    except Fault, f:
786 af6d3b5d Antony Chazapis
        status = '%s ' % f.status if f.status else ''
787 95e92490 Sofia Papagiannaki
        print '%s%s' % (status, f.data)
788 cfac048c Giorgos Verigakis
789 9e826a59 Kostas Papadimitriou
790 cfac048c Giorgos Verigakis
if __name__ == '__main__':
791 cfac048c Giorgos Verigakis
    main()