Statistics
| Branch: | Tag: | Revision:

root / tools / store @ bcb7c5a8

History | View | Annotate | Download (26.4 kB)

1 cfac048c Giorgos Verigakis
#!/usr/bin/env python
2 cfac048c Giorgos Verigakis
3 a4c10cbc Sofia Papagiannaki
# Copyright 2011 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 3f5b02c7 Sofia Papagiannaki
from pithos.lib.client import Client, Fault
41 d2d5c360 Sofia Papagiannaki
from datetime import datetime
42 cfac048c Giorgos Verigakis
43 cfac048c Giorgos Verigakis
import json
44 cfac048c Giorgos Verigakis
import logging
45 f07c5a53 Sofia Papagiannaki
import types
46 d2d5c360 Sofia Papagiannaki
import re
47 d2d5c360 Sofia Papagiannaki
import time as _time
48 bcb7c5a8 Sofia Papagiannaki
import os
49 cfac048c Giorgos Verigakis
50 e5cd3e33 Sofia Papagiannaki
DEFAULT_HOST = 'pithos.dev.grnet.gr'
51 cfac048c Giorgos Verigakis
DEFAULT_API = 'v1'
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 f07c5a53 Sofia Papagiannaki
        parser.add_option('--host', dest='host', metavar='HOST',
72 f07c5a53 Sofia Papagiannaki
                          default=DEFAULT_HOST, help='use server HOST')
73 f07c5a53 Sofia Papagiannaki
        parser.add_option('--user', dest='user', metavar='USERNAME',
74 bcb7c5a8 Sofia Papagiannaki
                          default=_get_user(),
75 bcb7c5a8 Sofia Papagiannaki
                          help='use account USERNAME')
76 bcb7c5a8 Sofia Papagiannaki
        parser.add_option('--token', dest='token', metavar='AUTH',
77 bcb7c5a8 Sofia Papagiannaki
                          default=_get_auth(),
78 bcb7c5a8 Sofia Papagiannaki
                          help='use account AUTH')
79 f07c5a53 Sofia Papagiannaki
        parser.add_option('--api', dest='api', metavar='API',
80 f07c5a53 Sofia Papagiannaki
                          default=DEFAULT_API, help='use api API')
81 f07c5a53 Sofia Papagiannaki
        parser.add_option('-v', action='store_true', dest='verbose',
82 f07c5a53 Sofia Papagiannaki
                          default=False, help='use verbose output')
83 f07c5a53 Sofia Papagiannaki
        parser.add_option('-d', action='store_true', dest='debug',
84 f07c5a53 Sofia Papagiannaki
                          default=False, help='use debug output')
85 cfac048c Giorgos Verigakis
        self.add_options(parser)
86 cfac048c Giorgos Verigakis
        options, args = parser.parse_args(argv)
87 cfac048c Giorgos Verigakis
        
88 cfac048c Giorgos Verigakis
        # Add options to self
89 cfac048c Giorgos Verigakis
        for opt in parser.option_list:
90 cfac048c Giorgos Verigakis
            key = opt.dest
91 cfac048c Giorgos Verigakis
            if key:
92 cfac048c Giorgos Verigakis
                val = getattr(options, key)
93 cfac048c Giorgos Verigakis
                setattr(self, key, val)
94 cfac048c Giorgos Verigakis
        
95 bcb7c5a8 Sofia Papagiannaki
        self.client = Client(self.host, self.token, self.user, self.api, self.verbose,
96 f07c5a53 Sofia Papagiannaki
                             self.debug)
97 cfac048c Giorgos Verigakis
        
98 cfac048c Giorgos Verigakis
        self.parser = parser
99 cfac048c Giorgos Verigakis
        self.args = args
100 f7ab99df Sofia Papagiannaki
        
101 cfac048c Giorgos Verigakis
    def add_options(self, parser):
102 cfac048c Giorgos Verigakis
        pass
103 f7ab99df Sofia Papagiannaki
    
104 cfac048c Giorgos Verigakis
    def execute(self, *args):
105 cfac048c Giorgos Verigakis
        pass
106 cfac048c Giorgos Verigakis
107 cfac048c Giorgos Verigakis
@cli_command('list', 'ls')
108 cfac048c Giorgos Verigakis
class List(Command):
109 f07c5a53 Sofia Papagiannaki
    syntax = '[<container>[/<object>]]'
110 cfac048c Giorgos Verigakis
    description = 'list containers or objects'
111 cfac048c Giorgos Verigakis
    
112 cfac048c Giorgos Verigakis
    def add_options(self, parser):
113 3f5b02c7 Sofia Papagiannaki
        parser.add_option('-l', action='store_true', dest='detail',
114 3f5b02c7 Sofia Papagiannaki
                          default=False, help='show detailed output')
115 3f5b02c7 Sofia Papagiannaki
        parser.add_option('-n', action='store', type='int', dest='limit',
116 3f5b02c7 Sofia Papagiannaki
                          default=1000, help='show limited output')
117 3f5b02c7 Sofia Papagiannaki
        parser.add_option('--marker', action='store', type='str',
118 3f5b02c7 Sofia Papagiannaki
                          dest='marker', default=None,
119 3f5b02c7 Sofia Papagiannaki
                          help='show output greater then marker')
120 3f5b02c7 Sofia Papagiannaki
        parser.add_option('--prefix', action='store', type='str',
121 3f5b02c7 Sofia Papagiannaki
                          dest='prefix', default=None,
122 3f5b02c7 Sofia Papagiannaki
                          help='show output starting with prefix')
123 3f5b02c7 Sofia Papagiannaki
        parser.add_option('--delimiter', action='store', type='str',
124 3f5b02c7 Sofia Papagiannaki
                          dest='delimiter', default=None,
125 3f5b02c7 Sofia Papagiannaki
                          help='show output up to the delimiter')
126 3f5b02c7 Sofia Papagiannaki
        parser.add_option('--path', action='store', type='str',
127 3f5b02c7 Sofia Papagiannaki
                          dest='path', default=None,
128 3f5b02c7 Sofia Papagiannaki
                          help='show output starting with prefix up to /')
129 3f5b02c7 Sofia Papagiannaki
        parser.add_option('--meta', action='store', type='str',
130 3f5b02c7 Sofia Papagiannaki
                          dest='meta', default=None,
131 3f5b02c7 Sofia Papagiannaki
                          help='show output having the specified meta keys')
132 3f5b02c7 Sofia Papagiannaki
        parser.add_option('--if-modified-since', action='store', type='str',
133 3f5b02c7 Sofia Papagiannaki
                          dest='if_modified_since', default=None,
134 3f5b02c7 Sofia Papagiannaki
                          help='show output if modified since then')
135 3f5b02c7 Sofia Papagiannaki
        parser.add_option('--if-unmodified-since', action='store', type='str',
136 3f5b02c7 Sofia Papagiannaki
                          dest='if_unmodified_since', default=None,
137 3f5b02c7 Sofia Papagiannaki
                          help='show output if not modified since then')
138 d2d5c360 Sofia Papagiannaki
        parser.add_option('--until', action='store', dest='until',
139 d2d5c360 Sofia Papagiannaki
                          default=False, help='show metadata until that date')
140 d2d5c360 Sofia Papagiannaki
        parser.add_option('--format', action='store', dest='format',
141 d2d5c360 Sofia Papagiannaki
                          default='%d/%m/%Y', help='format to parse until date')
142 f7ab99df Sofia Papagiannaki
    
143 cfac048c Giorgos Verigakis
    def execute(self, container=None):
144 cfac048c Giorgos Verigakis
        if container:
145 cfac048c Giorgos Verigakis
            self.list_objects(container)
146 cfac048c Giorgos Verigakis
        else:
147 cfac048c Giorgos Verigakis
            self.list_containers()
148 f7ab99df Sofia Papagiannaki
    
149 cfac048c Giorgos Verigakis
    def list_containers(self):
150 f07c5a53 Sofia Papagiannaki
        params = {'limit':self.limit, 'marker':self.marker}
151 f07c5a53 Sofia Papagiannaki
        headers = {'IF_MODIFIED_SINCE':self.if_modified_since,
152 f07c5a53 Sofia Papagiannaki
                   'IF_UNMODIFIED_SINCE':self.if_unmodified_since}
153 d2d5c360 Sofia Papagiannaki
        
154 d2d5c360 Sofia Papagiannaki
        if self.until:
155 d2d5c360 Sofia Papagiannaki
            t = _time.strptime(self.until, self.format)
156 d2d5c360 Sofia Papagiannaki
            params['until'] = int(_time.mktime(t))
157 d2d5c360 Sofia Papagiannaki
        
158 f07c5a53 Sofia Papagiannaki
        l = self.client.list_containers(self.detail, params, headers)
159 f07c5a53 Sofia Papagiannaki
        print_list(l)
160 f7ab99df Sofia Papagiannaki
    
161 cfac048c Giorgos Verigakis
    def list_objects(self, container):
162 bcb7c5a8 Sofia Papagiannaki
        #prepate params
163 bcb7c5a8 Sofia Papagiannaki
        params = {}
164 bcb7c5a8 Sofia Papagiannaki
        attrs = ['limit', 'marker', 'prefix', 'delimiter', 'path', 'meta']
165 bcb7c5a8 Sofia Papagiannaki
        for a in [a for a in attrs if getattr(self, a)]:
166 bcb7c5a8 Sofia Papagiannaki
            params[a] = getattr(self, a)
167 bcb7c5a8 Sofia Papagiannaki
        
168 bcb7c5a8 Sofia Papagiannaki
        if self.until:
169 bcb7c5a8 Sofia Papagiannaki
            t = _time.strptime(self.until, self.format)
170 bcb7c5a8 Sofia Papagiannaki
            params['until'] = int(_time.mktime(t))
171 bcb7c5a8 Sofia Papagiannaki
        
172 f07c5a53 Sofia Papagiannaki
        headers = {'IF_MODIFIED_SINCE':self.if_modified_since,
173 f07c5a53 Sofia Papagiannaki
                   'IF_UNMODIFIED_SINCE':self.if_unmodified_since}
174 d2d5c360 Sofia Papagiannaki
        container, sep, object = container.partition('/')
175 d2d5c360 Sofia Papagiannaki
        if object:
176 d2d5c360 Sofia Papagiannaki
            return
177 d2d5c360 Sofia Papagiannaki
        
178 a4c10cbc Sofia Papagiannaki
        detail = 'json'
179 a2defd86 Sofia Papagiannaki
        #if request with meta quering disable trash filtering
180 a2defd86 Sofia Papagiannaki
        show_trashed = True if self.meta else False
181 bcb7c5a8 Sofia Papagiannaki
        l = self.client.list_objects(container, detail, headers,
182 bcb7c5a8 Sofia Papagiannaki
                                     include_trashed = show_trashed, **params)
183 a4c10cbc Sofia Papagiannaki
        print_list(l, detail=self.detail)
184 cfac048c Giorgos Verigakis
185 cfac048c Giorgos Verigakis
@cli_command('meta')
186 cfac048c Giorgos Verigakis
class Meta(Command):
187 cfac048c Giorgos Verigakis
    syntax = '[<container>[/<object>]]'
188 cfac048c Giorgos Verigakis
    description = 'get the metadata of an account, a container or an object'
189 0ea1dcc4 Sofia Papagiannaki
    
190 0ea1dcc4 Sofia Papagiannaki
    def add_options(self, parser):
191 0ea1dcc4 Sofia Papagiannaki
        parser.add_option('-r', action='store_true', dest='restricted',
192 0ea1dcc4 Sofia Papagiannaki
                          default=False, help='show only user defined metadata')
193 d2d5c360 Sofia Papagiannaki
        parser.add_option('--until', action='store', dest='until',
194 d2d5c360 Sofia Papagiannaki
                          default=False, help='show metadata until that date')
195 d2d5c360 Sofia Papagiannaki
        parser.add_option('--format', action='store', dest='format',
196 d2d5c360 Sofia Papagiannaki
                          default='%d/%m/%Y', help='format to parse until date')
197 e3fd7f91 Sofia Papagiannaki
        parser.add_option('--version', action='store', dest='version',
198 e3fd7f91 Sofia Papagiannaki
                          default=None, help='show specific version \
199 e3fd7f91 Sofia Papagiannaki
                                  (applies only for objects)')
200 f7ab99df Sofia Papagiannaki
    
201 cfac048c Giorgos Verigakis
    def execute(self, path=''):
202 cfac048c Giorgos Verigakis
        container, sep, object = path.partition('/')
203 d2d5c360 Sofia Papagiannaki
        if self.until:
204 d2d5c360 Sofia Papagiannaki
            t = _time.strptime(self.until, self.format)
205 d2d5c360 Sofia Papagiannaki
            self.until = int(_time.mktime(t))
206 cfac048c Giorgos Verigakis
        if object:
207 0ea1dcc4 Sofia Papagiannaki
            meta = self.client.retrieve_object_metadata(container, object,
208 8fe01d72 Sofia Papagiannaki
                                                        self.restricted,
209 8fe01d72 Sofia Papagiannaki
                                                        self.version)
210 cfac048c Giorgos Verigakis
        elif container:
211 0ea1dcc4 Sofia Papagiannaki
            meta = self.client.retrieve_container_metadata(container,
212 d2d5c360 Sofia Papagiannaki
                                                           self.restricted,
213 d2d5c360 Sofia Papagiannaki
                                                           self.until)
214 cfac048c Giorgos Verigakis
        else:
215 d2d5c360 Sofia Papagiannaki
            meta = self.client.account_metadata(self.restricted, self.until)
216 f07c5a53 Sofia Papagiannaki
        if meta == None:
217 f07c5a53 Sofia Papagiannaki
            print 'Entity does not exist'
218 f07c5a53 Sofia Papagiannaki
        else:
219 f07c5a53 Sofia Papagiannaki
            print_dict(meta, header=None)
220 cfac048c Giorgos Verigakis
221 cfac048c Giorgos Verigakis
@cli_command('create')
222 cfac048c Giorgos Verigakis
class CreateContainer(Command):
223 f07c5a53 Sofia Papagiannaki
    syntax = '<container> [key=val] [...]'
224 cfac048c Giorgos Verigakis
    description = 'create a container'
225 cfac048c Giorgos Verigakis
    
226 f07c5a53 Sofia Papagiannaki
    def execute(self, container, *args):
227 f07c5a53 Sofia Papagiannaki
        headers = {}
228 bcb7c5a8 Sofia Papagiannaki
        meta = {}
229 f07c5a53 Sofia Papagiannaki
        for arg in args:
230 f07c5a53 Sofia Papagiannaki
            key, sep, val = arg.partition('=')
231 bcb7c5a8 Sofia Papagiannaki
            meta[key] = val
232 bcb7c5a8 Sofia Papagiannaki
        ret = self.client.create_container(container, headers, **meta)
233 cfac048c Giorgos Verigakis
        if not ret:
234 cfac048c Giorgos Verigakis
            print 'Container already exists'
235 cfac048c Giorgos Verigakis
236 cfac048c Giorgos Verigakis
@cli_command('delete', 'rm')
237 cfac048c Giorgos Verigakis
class Delete(Command):
238 cfac048c Giorgos Verigakis
    syntax = '<container>[/<object>]'
239 cfac048c Giorgos Verigakis
    description = 'delete a container or an object'
240 cfac048c Giorgos Verigakis
    
241 cfac048c Giorgos Verigakis
    def execute(self, path):
242 cfac048c Giorgos Verigakis
        container, sep, object = path.partition('/')
243 cfac048c Giorgos Verigakis
        if object:
244 cfac048c Giorgos Verigakis
            self.client.delete_object(container, object)
245 cfac048c Giorgos Verigakis
        else:
246 cfac048c Giorgos Verigakis
            self.client.delete_container(container)
247 cfac048c Giorgos Verigakis
248 cfac048c Giorgos Verigakis
@cli_command('get')
249 cfac048c Giorgos Verigakis
class GetObject(Command):
250 cfac048c Giorgos Verigakis
    syntax = '<container>/<object>'
251 cfac048c Giorgos Verigakis
    description = 'get the data of an object'
252 cfac048c Giorgos Verigakis
    
253 f07c5a53 Sofia Papagiannaki
    def add_options(self, parser):
254 f07c5a53 Sofia Papagiannaki
        parser.add_option('-l', action='store_true', dest='detail',
255 f07c5a53 Sofia Papagiannaki
                          default=False, help='show detailed output')
256 f07c5a53 Sofia Papagiannaki
        parser.add_option('--range', action='store', dest='range',
257 f07c5a53 Sofia Papagiannaki
                          default=None, help='show range of data')
258 f07c5a53 Sofia Papagiannaki
        parser.add_option('--if-match', action='store', dest='if-match',
259 f07c5a53 Sofia Papagiannaki
                          default=None, help='show output if ETags match')
260 f07c5a53 Sofia Papagiannaki
        parser.add_option('--if-none-match', action='store',
261 f07c5a53 Sofia Papagiannaki
                          dest='if-none-match', default=None,
262 f07c5a53 Sofia Papagiannaki
                          help='show output if ETags don\'t match')
263 f07c5a53 Sofia Papagiannaki
        parser.add_option('--if-modified-since', action='store', type='str',
264 f07c5a53 Sofia Papagiannaki
                          dest='if-modified-since', default=None,
265 f07c5a53 Sofia Papagiannaki
                          help='show output if modified since then')
266 f07c5a53 Sofia Papagiannaki
        parser.add_option('--if-unmodified-since', action='store', type='str',
267 f07c5a53 Sofia Papagiannaki
                          dest='if-unmodified-since', default=None,
268 f07c5a53 Sofia Papagiannaki
                          help='show output if not modified since then')
269 bcb7c5a8 Sofia Papagiannaki
        parser.add_option('-o', action='store', type='str',
270 f07c5a53 Sofia Papagiannaki
                          dest='file', default=None,
271 f07c5a53 Sofia Papagiannaki
                          help='save output in file')
272 8fe01d72 Sofia Papagiannaki
        parser.add_option('--version', action='store', type='str',
273 ad71a0ce Sofia Papagiannaki
                          dest='version', default=None,
274 085a31d7 Sofia Papagiannaki
                          help='get the specific \
275 8fe01d72 Sofia Papagiannaki
                               version')
276 085a31d7 Sofia Papagiannaki
        parser.add_option('--versionlist', action='store_true',
277 085a31d7 Sofia Papagiannaki
                          dest='versionlist', default=False,
278 085a31d7 Sofia Papagiannaki
                          help='get the full object version list')
279 f7ab99df Sofia Papagiannaki
    
280 cfac048c Giorgos Verigakis
    def execute(self, path):
281 f07c5a53 Sofia Papagiannaki
        headers = {}
282 f07c5a53 Sofia Papagiannaki
        if self.range:
283 f07c5a53 Sofia Papagiannaki
            headers['RANGE'] = 'bytes=%s' %self.range
284 f07c5a53 Sofia Papagiannaki
        attrs = ['if-match', 'if-none-match', 'if-modified-since',
285 f07c5a53 Sofia Papagiannaki
                 'if-unmodified-since']
286 f07c5a53 Sofia Papagiannaki
        attrs = [a for a in attrs if getattr(self, a)]
287 f07c5a53 Sofia Papagiannaki
        for a in attrs:
288 f07c5a53 Sofia Papagiannaki
            headers[a.replace('-', '_').upper()] = getattr(self, a)
289 cfac048c Giorgos Verigakis
        container, sep, object = path.partition('/')
290 085a31d7 Sofia Papagiannaki
        if self.versionlist:
291 085a31d7 Sofia Papagiannaki
            self.version = 'list'
292 085a31d7 Sofia Papagiannaki
            self.detail = True
293 f07c5a53 Sofia Papagiannaki
        data = self.client.retrieve_object(container, object, self.detail,
294 8fe01d72 Sofia Papagiannaki
                                          headers, self.version)
295 8fe01d72 Sofia Papagiannaki
        f = self.file and open(self.file, 'w') or stdout
296 8fe01d72 Sofia Papagiannaki
        if self.detail:
297 8fe01d72 Sofia Papagiannaki
            data = json.loads(data)
298 085a31d7 Sofia Papagiannaki
            if self.versionlist:
299 8fe01d72 Sofia Papagiannaki
                print_versions(data, f=f)
300 f07c5a53 Sofia Papagiannaki
            else:
301 8fe01d72 Sofia Papagiannaki
                print_dict(data, f=f)
302 f07c5a53 Sofia Papagiannaki
        else:
303 8fe01d72 Sofia Papagiannaki
            f.write(data)
304 8fe01d72 Sofia Papagiannaki
        f.close()
305 cfac048c Giorgos Verigakis
306 f7ab99df Sofia Papagiannaki
@cli_command('mkdir')
307 f7ab99df Sofia Papagiannaki
class PutMarker(Command):
308 f7ab99df Sofia Papagiannaki
    syntax = '<container>/<directory marker>'
309 f7ab99df Sofia Papagiannaki
    description = 'create a directory marker'
310 f7ab99df Sofia Papagiannaki
    
311 f7ab99df Sofia Papagiannaki
    def execute(self, path):
312 f7ab99df Sofia Papagiannaki
        container, sep, object = path.partition('/')
313 f7ab99df Sofia Papagiannaki
        self.client.create_directory_marker(container, object)
314 f7ab99df Sofia Papagiannaki
315 cfac048c Giorgos Verigakis
@cli_command('put')
316 cfac048c Giorgos Verigakis
class PutObject(Command):
317 f07c5a53 Sofia Papagiannaki
    syntax = '<container>/<object> <path> [key=val] [...]'
318 f07c5a53 Sofia Papagiannaki
    description = 'create/override object with path contents or standard input'
319 f7ab99df Sofia Papagiannaki
    
320 f07c5a53 Sofia Papagiannaki
    def add_options(self, parser):
321 bcb7c5a8 Sofia Papagiannaki
        parser.add_option('--use_hashes', action='store_true', dest='use_hashes',
322 bcb7c5a8 Sofia Papagiannaki
                          default=False, help='provide hashmap instead of data')
323 f07c5a53 Sofia Papagiannaki
        parser.add_option('--chunked', action='store_true', dest='chunked',
324 f07c5a53 Sofia Papagiannaki
                          default=False, help='set chunked transfer mode')
325 f07c5a53 Sofia Papagiannaki
        parser.add_option('--etag', action='store', dest='etag',
326 f07c5a53 Sofia Papagiannaki
                          default=None, help='check written data')
327 f07c5a53 Sofia Papagiannaki
        parser.add_option('--content-encoding', action='store',
328 f07c5a53 Sofia Papagiannaki
                          dest='content-encoding', default=None,
329 f07c5a53 Sofia Papagiannaki
                          help='provide the object MIME content type')
330 f07c5a53 Sofia Papagiannaki
        parser.add_option('--content-disposition', action='store', type='str',
331 f07c5a53 Sofia Papagiannaki
                          dest='content-disposition', default=None,
332 f07c5a53 Sofia Papagiannaki
                          help='provide the presentation style of the object')
333 961f2fbe Sofia Papagiannaki
        parser.add_option('-S', action='store',
334 961f2fbe Sofia Papagiannaki
                          dest='segment-size', default=False,
335 f07c5a53 Sofia Papagiannaki
                          help='use for large file support')
336 961f2fbe Sofia Papagiannaki
        parser.add_option('--manifest', action='store_true',
337 961f2fbe Sofia Papagiannaki
                          dest='manifest', default=None,
338 961f2fbe Sofia Papagiannaki
                          help='upload a manifestation file')
339 f7ab99df Sofia Papagiannaki
        parser.add_option('--type', action='store',
340 f7ab99df Sofia Papagiannaki
                          dest='content-type', default=False,
341 f7ab99df Sofia Papagiannaki
                          help='create object with specific content type')
342 bcb7c5a8 Sofia Papagiannaki
        #parser.add_option('--touch', action='store_true',
343 bcb7c5a8 Sofia Papagiannaki
        #                  dest='touch', default=False,
344 bcb7c5a8 Sofia Papagiannaki
        #                  help='create object with zero data')
345 d3fd269f Sofia Papagiannaki
        parser.add_option('--sharing', action='store',
346 d3fd269f Sofia Papagiannaki
                          dest='sharing', default=None,
347 d3fd269f Sofia Papagiannaki
                          help='define sharing object policy')
348 bcb7c5a8 Sofia Papagiannaki
        parser.add_option('-f', action='store',
349 bcb7c5a8 Sofia Papagiannaki
                          dest='srcpath', default=None,
350 bcb7c5a8 Sofia Papagiannaki
                          help='file descriptor to read from: pass - for standard input')
351 bcb7c5a8 Sofia Papagiannaki
        
352 bcb7c5a8 Sofia Papagiannaki
    def execute(self, path, *args):
353 bcb7c5a8 Sofia Papagiannaki
        if path.find('=') != -1:
354 bcb7c5a8 Sofia Papagiannaki
            raise Fault('Missing path argument')
355 bcb7c5a8 Sofia Papagiannaki
        
356 bcb7c5a8 Sofia Papagiannaki
        #prepare user defined meta
357 bcb7c5a8 Sofia Papagiannaki
        meta = {}
358 bcb7c5a8 Sofia Papagiannaki
        for arg in args:
359 bcb7c5a8 Sofia Papagiannaki
            key, sep, val = arg.partition('=')
360 bcb7c5a8 Sofia Papagiannaki
            meta[key] = val
361 d3fd269f Sofia Papagiannaki
        
362 f07c5a53 Sofia Papagiannaki
        headers = {}
363 bcb7c5a8 Sofia Papagiannaki
        manifest = getattr(self, 'manifest')
364 bcb7c5a8 Sofia Papagiannaki
        if manifest:
365 bcb7c5a8 Sofia Papagiannaki
            # if it's manifestation file
366 bcb7c5a8 Sofia Papagiannaki
            # send zero-byte data with X-Object-Manifest header
367 bcb7c5a8 Sofia Papagiannaki
            self.touch = True
368 bcb7c5a8 Sofia Papagiannaki
            headers['X_OBJECT_MANIFEST'] = manifest
369 d3fd269f Sofia Papagiannaki
        if self.sharing:
370 d3fd269f Sofia Papagiannaki
            headers['X_OBJECT_SHARING'] = self.sharing
371 f7ab99df Sofia Papagiannaki
        
372 f7ab99df Sofia Papagiannaki
        attrs = ['etag', 'content-encoding', 'content-disposition',
373 f7ab99df Sofia Papagiannaki
                 'content-type']
374 f07c5a53 Sofia Papagiannaki
        attrs = [a for a in attrs if getattr(self, a)]
375 f07c5a53 Sofia Papagiannaki
        for a in attrs:
376 f07c5a53 Sofia Papagiannaki
            headers[a.replace('-', '_').upper()] = getattr(self, a)
377 f07c5a53 Sofia Papagiannaki
        
378 cfac048c Giorgos Verigakis
        container, sep, object = path.partition('/')
379 f07c5a53 Sofia Papagiannaki
        
380 d2d5c360 Sofia Papagiannaki
        f = None
381 bcb7c5a8 Sofia Papagiannaki
        if self.srcpath:
382 bcb7c5a8 Sofia Papagiannaki
            f = open(self.srcpath) if self.srcpath != '-' else stdin
383 bcb7c5a8 Sofia Papagiannaki
        
384 bcb7c5a8 Sofia Papagiannaki
        if self.use_hashes and not f:
385 bcb7c5a8 Sofia Papagiannaki
            raise Fault('Illegal option combination')
386 bcb7c5a8 Sofia Papagiannaki
        
387 bcb7c5a8 Sofia Papagiannaki
        self.client.create_object(container, object, f, chunked=self.chunked,
388 bcb7c5a8 Sofia Papagiannaki
                                  headers=headers, use_hashes=self.use_hashes,
389 bcb7c5a8 Sofia Papagiannaki
                                  **meta)
390 d2d5c360 Sofia Papagiannaki
        if f:
391 d2d5c360 Sofia Papagiannaki
            f.close()
392 cfac048c Giorgos Verigakis
393 cfac048c Giorgos Verigakis
@cli_command('copy', 'cp')
394 cfac048c Giorgos Verigakis
class CopyObject(Command):
395 cfac048c Giorgos Verigakis
    syntax = '<src container>/<src object> [<dst container>/]<dst object>'
396 cfac048c Giorgos Verigakis
    description = 'copies an object to a different location'
397 cfac048c Giorgos Verigakis
    
398 ad71a0ce Sofia Papagiannaki
    def add_options(self, parser):
399 ad71a0ce Sofia Papagiannaki
        parser.add_option('--version', action='store',
400 ad71a0ce Sofia Papagiannaki
                          dest='version', default=False,
401 ad71a0ce Sofia Papagiannaki
                          help='copy specific version')
402 f7ab99df Sofia Papagiannaki
    
403 cfac048c Giorgos Verigakis
    def execute(self, src, dst):
404 cfac048c Giorgos Verigakis
        src_container, sep, src_object = src.partition('/')
405 cfac048c Giorgos Verigakis
        dst_container, sep, dst_object = dst.partition('/')
406 cfac048c Giorgos Verigakis
        if not sep:
407 cfac048c Giorgos Verigakis
            dst_container = src_container
408 cfac048c Giorgos Verigakis
            dst_object = dst
409 ad71a0ce Sofia Papagiannaki
        version = getattr(self, 'version')
410 ad71a0ce Sofia Papagiannaki
        if version:
411 ad71a0ce Sofia Papagiannaki
            headers = {}
412 7e999dec Sofia Papagiannaki
            headers['X_SOURCE_VERSION'] = version
413 f07c5a53 Sofia Papagiannaki
        self.client.copy_object(src_container, src_object, dst_container,
414 7e999dec Sofia Papagiannaki
                                dst_object, headers)
415 cfac048c Giorgos Verigakis
416 cfac048c Giorgos Verigakis
@cli_command('set')
417 3f5b02c7 Sofia Papagiannaki
class SetMeta(Command):
418 3f5b02c7 Sofia Papagiannaki
    syntax = '[<container>[/<object>]] key=val [key=val] [...]'
419 3f5b02c7 Sofia Papagiannaki
    description = 'set metadata'
420 cfac048c Giorgos Verigakis
    
421 cfac048c Giorgos Verigakis
    def execute(self, path, *args):
422 3f5b02c7 Sofia Papagiannaki
        #in case of account fix the args
423 f07c5a53 Sofia Papagiannaki
        if path.find('=') != -1:
424 3f5b02c7 Sofia Papagiannaki
            args = list(args)
425 3f5b02c7 Sofia Papagiannaki
            args.append(path)
426 3f5b02c7 Sofia Papagiannaki
            args = tuple(args)
427 3f5b02c7 Sofia Papagiannaki
            path = ''
428 cfac048c Giorgos Verigakis
        meta = {}
429 cfac048c Giorgos Verigakis
        for arg in args:
430 cfac048c Giorgos Verigakis
            key, sep, val = arg.partition('=')
431 cfac048c Giorgos Verigakis
            meta[key.strip()] = val.strip()
432 3f5b02c7 Sofia Papagiannaki
        container, sep, object = path.partition('/')
433 3f5b02c7 Sofia Papagiannaki
        if object:
434 3f5b02c7 Sofia Papagiannaki
            self.client.update_object_metadata(container, object, **meta)
435 3f5b02c7 Sofia Papagiannaki
        elif container:
436 3f5b02c7 Sofia Papagiannaki
            self.client.update_container_metadata(container, **meta)
437 3f5b02c7 Sofia Papagiannaki
        else:
438 3f5b02c7 Sofia Papagiannaki
            self.client.update_account_metadata(**meta)
439 cfac048c Giorgos Verigakis
440 f07c5a53 Sofia Papagiannaki
@cli_command('update')
441 f07c5a53 Sofia Papagiannaki
class UpdateObject(Command):
442 f07c5a53 Sofia Papagiannaki
    syntax = '<container>/<object> path [key=val] [...]'
443 e3fd7f91 Sofia Papagiannaki
    description = 'update object metadata/data (default mode: append)'
444 f07c5a53 Sofia Papagiannaki
    
445 f07c5a53 Sofia Papagiannaki
    def add_options(self, parser):
446 f07c5a53 Sofia Papagiannaki
        parser.add_option('-a', action='store_true', dest='append',
447 e3fd7f91 Sofia Papagiannaki
                          default=True, help='append data')
448 bcb7c5a8 Sofia Papagiannaki
        parser.add_option('--offset', action='store',
449 bcb7c5a8 Sofia Papagiannaki
                          dest='offset',
450 a2defd86 Sofia Papagiannaki
                          default=None, help='starting offest to be updated')
451 f07c5a53 Sofia Papagiannaki
        parser.add_option('--range', action='store', dest='content-range',
452 f07c5a53 Sofia Papagiannaki
                          default=None, help='range of data to be updated')
453 f07c5a53 Sofia Papagiannaki
        parser.add_option('--chunked', action='store_true', dest='chunked',
454 f07c5a53 Sofia Papagiannaki
                          default=False, help='set chunked transfer mode')
455 f07c5a53 Sofia Papagiannaki
        parser.add_option('--content-encoding', action='store',
456 f07c5a53 Sofia Papagiannaki
                          dest='content-encoding', default=None,
457 f07c5a53 Sofia Papagiannaki
                          help='provide the object MIME content type')
458 f07c5a53 Sofia Papagiannaki
        parser.add_option('--content-disposition', action='store', type='str',
459 f07c5a53 Sofia Papagiannaki
                          dest='content-disposition', default=None,
460 f07c5a53 Sofia Papagiannaki
                          help='provide the presentation style of the object')
461 f07c5a53 Sofia Papagiannaki
        parser.add_option('--manifest', action='store', type='str',
462 f07c5a53 Sofia Papagiannaki
                          dest='manifest', default=None,
463 d3fd269f Sofia Papagiannaki
                          help='use for large file support')        
464 d3fd269f Sofia Papagiannaki
        parser.add_option('--sharing', action='store',
465 d3fd269f Sofia Papagiannaki
                          dest='sharing', default=None,
466 d3fd269f Sofia Papagiannaki
                          help='define sharing object policy')
467 bcb7c5a8 Sofia Papagiannaki
        parser.add_option('--nosharing', action='store_true',
468 bcb7c5a8 Sofia Papagiannaki
                          dest='no_sharing', default=None,
469 bcb7c5a8 Sofia Papagiannaki
                          help='clear object sharing policy')
470 bcb7c5a8 Sofia Papagiannaki
        parser.add_option('-f', action='store',
471 bcb7c5a8 Sofia Papagiannaki
                          dest='srcpath', default=None,
472 bcb7c5a8 Sofia Papagiannaki
                          help='file descriptor to read from: pass - for standard input')
473 f7ab99df Sofia Papagiannaki
    
474 bcb7c5a8 Sofia Papagiannaki
    def execute(self, path, *args):
475 bcb7c5a8 Sofia Papagiannaki
        if path.find('=') != -1:
476 bcb7c5a8 Sofia Papagiannaki
            raise Fault('Missing path argument')
477 bcb7c5a8 Sofia Papagiannaki
        
478 f07c5a53 Sofia Papagiannaki
        headers = {}
479 f07c5a53 Sofia Papagiannaki
        if self.manifest:
480 f07c5a53 Sofia Papagiannaki
            headers['X_OBJECT_MANIFEST'] = self.manifest
481 d3fd269f Sofia Papagiannaki
        if self.sharing:
482 d3fd269f Sofia Papagiannaki
            headers['X_OBJECT_SHARING'] = self.sharing
483 f07c5a53 Sofia Papagiannaki
        
484 bcb7c5a8 Sofia Papagiannaki
        if self.no_sharing:
485 bcb7c5a8 Sofia Papagiannaki
            headers['X_OBJECT_SHARING'] = ''
486 f07c5a53 Sofia Papagiannaki
        
487 f07c5a53 Sofia Papagiannaki
        attrs = ['content-encoding', 'content-disposition']
488 f07c5a53 Sofia Papagiannaki
        attrs = [a for a in attrs if getattr(self, a)]
489 f07c5a53 Sofia Papagiannaki
        for a in attrs:
490 f07c5a53 Sofia Papagiannaki
            headers[a.replace('-', '_').upper()] = getattr(self, a)
491 f07c5a53 Sofia Papagiannaki
        
492 f07c5a53 Sofia Papagiannaki
        #prepare user defined meta
493 bcb7c5a8 Sofia Papagiannaki
        meta = {}
494 f07c5a53 Sofia Papagiannaki
        for arg in args:
495 f07c5a53 Sofia Papagiannaki
            key, sep, val = arg.partition('=')
496 bcb7c5a8 Sofia Papagiannaki
            meta[key] = val
497 f07c5a53 Sofia Papagiannaki
        
498 f07c5a53 Sofia Papagiannaki
        container, sep, object = path.partition('/')
499 f07c5a53 Sofia Papagiannaki
        
500 a2defd86 Sofia Papagiannaki
        f = None
501 a2defd86 Sofia Papagiannaki
        chunked = False
502 bcb7c5a8 Sofia Papagiannaki
        if self.srcpath:
503 bcb7c5a8 Sofia Papagiannaki
            f = self.srcpath != '-' and open(self.srcpath) or stdin
504 bcb7c5a8 Sofia Papagiannaki
        if f:
505 bcb7c5a8 Sofia Papagiannaki
            chunked = True if (self.chunked or f == stdin) else False
506 f07c5a53 Sofia Papagiannaki
        self.client.update_object(container, object, f, chunked=chunked,
507 bcb7c5a8 Sofia Papagiannaki
                                  headers=headers, offset=self.offset, **meta)
508 a2defd86 Sofia Papagiannaki
        if f:
509 a2defd86 Sofia Papagiannaki
            f.close()
510 f07c5a53 Sofia Papagiannaki
511 f07c5a53 Sofia Papagiannaki
@cli_command('move', 'mv')
512 f07c5a53 Sofia Papagiannaki
class MoveObject(Command):
513 f07c5a53 Sofia Papagiannaki
    syntax = '<src container>/<src object> [<dst container>/]<dst object>'
514 f07c5a53 Sofia Papagiannaki
    description = 'moves an object to a different location'
515 f07c5a53 Sofia Papagiannaki
    
516 f07c5a53 Sofia Papagiannaki
    def execute(self, src, dst):
517 f07c5a53 Sofia Papagiannaki
        src_container, sep, src_object = src.partition('/')
518 f07c5a53 Sofia Papagiannaki
        dst_container, sep, dst_object = dst.partition('/')
519 f07c5a53 Sofia Papagiannaki
        if not sep:
520 f07c5a53 Sofia Papagiannaki
            dst_container = src_container
521 f07c5a53 Sofia Papagiannaki
            dst_object = dst
522 085a31d7 Sofia Papagiannaki
        
523 f07c5a53 Sofia Papagiannaki
        self.client.move_object(src_container, src_object, dst_container,
524 085a31d7 Sofia Papagiannaki
                                dst_object, headers)
525 f07c5a53 Sofia Papagiannaki
526 a2defd86 Sofia Papagiannaki
@cli_command('remove')
527 f7ab99df Sofia Papagiannaki
class TrashObject(Command):
528 f7ab99df Sofia Papagiannaki
    syntax = '<container>/<object>'
529 f7ab99df Sofia Papagiannaki
    description = 'trashes an object'
530 f7ab99df Sofia Papagiannaki
    
531 f7ab99df Sofia Papagiannaki
    def execute(self, src):
532 f7ab99df Sofia Papagiannaki
        src_container, sep, src_object = src.partition('/')
533 f7ab99df Sofia Papagiannaki
        
534 f7ab99df Sofia Papagiannaki
        self.client.trash_object(src_container, src_object)
535 f7ab99df Sofia Papagiannaki
536 f7ab99df Sofia Papagiannaki
@cli_command('restore')
537 f7ab99df Sofia Papagiannaki
class TrashObject(Command):
538 f7ab99df Sofia Papagiannaki
    syntax = '<container>/<object>'
539 f7ab99df Sofia Papagiannaki
    description = 'trashes an object'
540 f7ab99df Sofia Papagiannaki
    
541 f7ab99df Sofia Papagiannaki
    def execute(self, src):
542 f7ab99df Sofia Papagiannaki
        src_container, sep, src_object = src.partition('/')
543 f7ab99df Sofia Papagiannaki
        
544 f7ab99df Sofia Papagiannaki
        self.client.restore_object(src_container, src_object)
545 f7ab99df Sofia Papagiannaki
546 f7ab99df Sofia Papagiannaki
@cli_command('unset')
547 bcb7c5a8 Sofia Papagiannaki
class UnsetObject(Command):
548 f7ab99df Sofia Papagiannaki
    syntax = '<container>/[<object>] key [key] [...]'
549 f7ab99df Sofia Papagiannaki
    description = 'deletes metadata info'
550 f7ab99df Sofia Papagiannaki
    
551 f7ab99df Sofia Papagiannaki
    def execute(self, path, *args):
552 f7ab99df Sofia Papagiannaki
        #in case of account fix the args
553 961f2fbe Sofia Papagiannaki
        if len(args) == 0:
554 f7ab99df Sofia Papagiannaki
            args = list(args)
555 f7ab99df Sofia Papagiannaki
            args.append(path)
556 f7ab99df Sofia Papagiannaki
            args = tuple(args)
557 f7ab99df Sofia Papagiannaki
            path = ''
558 f7ab99df Sofia Papagiannaki
        meta = []
559 f7ab99df Sofia Papagiannaki
        for key in args:
560 f7ab99df Sofia Papagiannaki
            meta.append(key)
561 f7ab99df Sofia Papagiannaki
        container, sep, object = path.partition('/')
562 f7ab99df Sofia Papagiannaki
        if object:
563 f7ab99df Sofia Papagiannaki
            self.client.delete_object_metadata(container, object, meta)
564 f7ab99df Sofia Papagiannaki
        elif container:
565 f7ab99df Sofia Papagiannaki
            self.client.delete_container_metadata(container, meta)
566 f7ab99df Sofia Papagiannaki
        else:
567 f7ab99df Sofia Papagiannaki
            self.client.delete_account_metadata(meta)
568 f7ab99df Sofia Papagiannaki
569 d3fd269f Sofia Papagiannaki
@cli_command('group')
570 d3fd269f Sofia Papagiannaki
class SetGroup(Command):
571 d3fd269f Sofia Papagiannaki
    syntax = 'key=val [key=val] [...]'
572 bcb7c5a8 Sofia Papagiannaki
    description = 'set group account info'
573 d3fd269f Sofia Papagiannaki
    
574 bcb7c5a8 Sofia Papagiannaki
    def execute(self, *args):
575 d3fd269f Sofia Papagiannaki
        groups = {}
576 d3fd269f Sofia Papagiannaki
        for arg in args:
577 d3fd269f Sofia Papagiannaki
            key, sep, val = arg.partition('=')
578 d3fd269f Sofia Papagiannaki
            groups[key] = val
579 bcb7c5a8 Sofia Papagiannaki
        self.client.set_account_groups(**groups)
580 bcb7c5a8 Sofia Papagiannaki
581 bcb7c5a8 Sofia Papagiannaki
@cli_command('policy')
582 bcb7c5a8 Sofia Papagiannaki
class SetPolicy(Command):
583 bcb7c5a8 Sofia Papagiannaki
    syntax = 'container key=val [key=val] [...]'
584 bcb7c5a8 Sofia Papagiannaki
    description = 'set contianer policies'
585 bcb7c5a8 Sofia Papagiannaki
    
586 bcb7c5a8 Sofia Papagiannaki
    def execute(self, path, *args):
587 bcb7c5a8 Sofia Papagiannaki
        if path.find('=') != -1:
588 bcb7c5a8 Sofia Papagiannaki
            raise Fault('Missing container argument')
589 bcb7c5a8 Sofia Papagiannaki
        
590 bcb7c5a8 Sofia Papagiannaki
        container, sep, object = path.partition('/')
591 bcb7c5a8 Sofia Papagiannaki
        
592 bcb7c5a8 Sofia Papagiannaki
        if object:
593 bcb7c5a8 Sofia Papagiannaki
            raise Fault('Only containers have policies')
594 bcb7c5a8 Sofia Papagiannaki
        
595 bcb7c5a8 Sofia Papagiannaki
        policies = {}
596 bcb7c5a8 Sofia Papagiannaki
        for arg in args:
597 bcb7c5a8 Sofia Papagiannaki
            key, sep, val = arg.partition('=')
598 bcb7c5a8 Sofia Papagiannaki
            policies[key] = val
599 bcb7c5a8 Sofia Papagiannaki
        
600 bcb7c5a8 Sofia Papagiannaki
        self.client.set_container_policies(container, **policies)
601 d3fd269f Sofia Papagiannaki
602 cfac048c Giorgos Verigakis
def print_usage():
603 10998c60 Sofia Papagiannaki
    cmd = Command('', [])
604 cfac048c Giorgos Verigakis
    parser = cmd.parser
605 cfac048c Giorgos Verigakis
    parser.usage = '%prog <command> [options]'
606 cfac048c Giorgos Verigakis
    parser.print_help()
607 cfac048c Giorgos Verigakis
    
608 cfac048c Giorgos Verigakis
    commands = []
609 cfac048c Giorgos Verigakis
    for cls in set(_cli_commands.values()):
610 cfac048c Giorgos Verigakis
        name = ', '.join(cls.commands)
611 cfac048c Giorgos Verigakis
        description = getattr(cls, 'description', '')
612 cfac048c Giorgos Verigakis
        commands.append('  %s %s' % (name.ljust(12), description))
613 cfac048c Giorgos Verigakis
    print '\nCommands:\n' + '\n'.join(sorted(commands))
614 cfac048c Giorgos Verigakis
615 a4c10cbc Sofia Papagiannaki
def print_dict(d, header='name', f=stdout, detail=True):
616 f07c5a53 Sofia Papagiannaki
    header = header in d and header or 'subdir'
617 f07c5a53 Sofia Papagiannaki
    if header and header in d:
618 f07c5a53 Sofia Papagiannaki
        f.write('%s\n' %d.pop(header))
619 a4c10cbc Sofia Papagiannaki
    if detail:
620 a4c10cbc Sofia Papagiannaki
        patterns = ['^x_(account|container|object)_meta_(\w+)$']
621 a4c10cbc Sofia Papagiannaki
        patterns.append(patterns[0].replace('_', '-'))
622 a4c10cbc Sofia Papagiannaki
        for key, val in sorted(d.items()):
623 a4c10cbc Sofia Papagiannaki
            for p in patterns:
624 a4c10cbc Sofia Papagiannaki
                p = re.compile(p)
625 a4c10cbc Sofia Papagiannaki
                m = p.match(key)
626 a4c10cbc Sofia Papagiannaki
                if m:
627 a4c10cbc Sofia Papagiannaki
                    key = m.group(2)
628 a4c10cbc Sofia Papagiannaki
            f.write('%s: %s\n' % (key.rjust(30), val))
629 f07c5a53 Sofia Papagiannaki
630 a4c10cbc Sofia Papagiannaki
def print_list(l, verbose=False, f=stdout, detail=True):
631 f07c5a53 Sofia Papagiannaki
    for elem in l:
632 f07c5a53 Sofia Papagiannaki
        #if it's empty string continue
633 f07c5a53 Sofia Papagiannaki
        if not elem:
634 f07c5a53 Sofia Papagiannaki
            continue
635 f07c5a53 Sofia Papagiannaki
        if type(elem) == types.DictionaryType:
636 a4c10cbc Sofia Papagiannaki
            print_dict(elem, f=f, detail=detail)
637 f07c5a53 Sofia Papagiannaki
        elif type(elem) == types.StringType:
638 f07c5a53 Sofia Papagiannaki
            if not verbose:
639 f07c5a53 Sofia Papagiannaki
                elem = elem.split('Traceback')[0]
640 f07c5a53 Sofia Papagiannaki
            f.write('%s\n' % elem)
641 f07c5a53 Sofia Papagiannaki
        else:
642 f07c5a53 Sofia Papagiannaki
            f.write('%s\n' % elem)
643 cfac048c Giorgos Verigakis
644 8fe01d72 Sofia Papagiannaki
def print_versions(data, f=stdout):
645 8fe01d72 Sofia Papagiannaki
    if 'versions' not in data:
646 8fe01d72 Sofia Papagiannaki
        f.write('%s\n' %data)
647 8fe01d72 Sofia Papagiannaki
        return
648 8fe01d72 Sofia Papagiannaki
    f.write('versions:\n')
649 8fe01d72 Sofia Papagiannaki
    for id, t in data['versions']:
650 8fe01d72 Sofia Papagiannaki
        f.write('%s @ %s\n' % (str(id).rjust(30), datetime.fromtimestamp(t)))
651 8fe01d72 Sofia Papagiannaki
652 bcb7c5a8 Sofia Papagiannaki
def _get_user():
653 bcb7c5a8 Sofia Papagiannaki
        try:
654 bcb7c5a8 Sofia Papagiannaki
            return os.environ['PITHOS_USER']
655 bcb7c5a8 Sofia Papagiannaki
        except KeyError:
656 bcb7c5a8 Sofia Papagiannaki
            return getuser()
657 bcb7c5a8 Sofia Papagiannaki
658 bcb7c5a8 Sofia Papagiannaki
def _get_auth():
659 bcb7c5a8 Sofia Papagiannaki
        try:
660 bcb7c5a8 Sofia Papagiannaki
            return os.environ['PITHOS_AUTH']
661 bcb7c5a8 Sofia Papagiannaki
        except KeyError:
662 bcb7c5a8 Sofia Papagiannaki
            return '0000'
663 bcb7c5a8 Sofia Papagiannaki
    
664 bcb7c5a8 Sofia Papagiannaki
665 cfac048c Giorgos Verigakis
def main():
666 cfac048c Giorgos Verigakis
    try:
667 cfac048c Giorgos Verigakis
        name = argv[1]
668 cfac048c Giorgos Verigakis
        cls = class_for_cli_command(name)
669 cfac048c Giorgos Verigakis
    except (IndexError, KeyError):
670 cfac048c Giorgos Verigakis
        print_usage()
671 cfac048c Giorgos Verigakis
        exit(1)
672 f07c5a53 Sofia Papagiannaki
    
673 a2defd86 Sofia Papagiannaki
    cmd = cls(name, argv[2:])
674 cfac048c Giorgos Verigakis
    
675 e5cd3e33 Sofia Papagiannaki
    try:
676 e5cd3e33 Sofia Papagiannaki
        cmd.execute(*cmd.args)
677 e3fd7f91 Sofia Papagiannaki
    except TypeError, e:
678 e5cd3e33 Sofia Papagiannaki
        cmd.parser.print_help()
679 e5cd3e33 Sofia Papagiannaki
        exit(1)
680 e5cd3e33 Sofia Papagiannaki
    except Fault, f:
681 f7ab99df Sofia Papagiannaki
        status = f.status and '%s ' % f.status or ''
682 f7ab99df Sofia Papagiannaki
        print '%s%s' % (status, f.data)
683 cfac048c Giorgos Verigakis
684 cfac048c Giorgos Verigakis
if __name__ == '__main__':
685 cfac048c Giorgos Verigakis
    main()