Statistics
| Branch: | Tag: | Revision:

root / snf-pithos-tools / pithos / tools / sh.py @ 6f6cec5a

History | View | Annotate | Download (31.3 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 54ca3d0f Sofia Papagiannaki
            if data is object:
424 54ca3d0f Sofia Papagiannaki
                hashmap = json.loads()
425 54ca3d0f Sofia Papagiannaki
                self.client.create_object_by_hashmap(container, object, hashmap,
426 54ca3d0f Sofia Papagiannaki
                                                 meta=meta, **args)
427 54ca3d0f Sofia Papagiannaki
            else:
428 54ca3d0f Sofia Papagiannaki
                print "Expected object"
429 25c3841c Sofia Papagiannaki
        elif self.x_object_manifest:
430 25c3841c Sofia Papagiannaki
            self.client.create_manifestation(container, object, self.x_object_manifest)
431 cd6ada1d Sofia Papagiannaki
        elif not f:
432 cd6ada1d Sofia Papagiannaki
            self.client.create_zero_length_object(container, object, meta=meta, **args)
433 25c3841c Sofia Papagiannaki
        else:
434 4211443b Sofia Papagiannaki
            self.client.create_object(container, object, f, meta=meta, **args)
435 d2d5c360 Sofia Papagiannaki
        if f:
436 d2d5c360 Sofia Papagiannaki
            f.close()
437 cfac048c Giorgos Verigakis
438 cfac048c Giorgos Verigakis
@cli_command('copy', 'cp')
439 cfac048c Giorgos Verigakis
class CopyObject(Command):
440 7812e1f9 Sofia Papagiannaki
    syntax = '<src container>/<src object> [<dst container>/]<dst object> [key=val] [...]'
441 f89e3cf4 Sofia Papagiannaki
    description = 'copy an object to a different location'
442 cfac048c Giorgos Verigakis
    
443 ad71a0ce Sofia Papagiannaki
    def add_options(self, parser):
444 ad71a0ce Sofia Papagiannaki
        parser.add_option('--version', action='store',
445 ad71a0ce Sofia Papagiannaki
                          dest='version', default=False,
446 ad71a0ce Sofia Papagiannaki
                          help='copy specific version')
447 7812e1f9 Sofia Papagiannaki
        parser.add_option('--public', action='store_true',
448 7812e1f9 Sofia Papagiannaki
                          dest='public', default=False,
449 7812e1f9 Sofia Papagiannaki
                          help='make object publicly accessible')
450 d4a63b9b Sofia Papagiannaki
        parser.add_option('--content-type', action='store',
451 d4a63b9b Sofia Papagiannaki
                          dest='content_type', default=None,
452 d4a63b9b Sofia Papagiannaki
                          help='change object\'s content type')
453 f7ab99df Sofia Papagiannaki
    
454 7812e1f9 Sofia Papagiannaki
    def execute(self, src, dst, *args):
455 cfac048c Giorgos Verigakis
        src_container, sep, src_object = src.partition('/')
456 cfac048c Giorgos Verigakis
        dst_container, sep, dst_object = dst.partition('/')
457 7812e1f9 Sofia Papagiannaki
        
458 7812e1f9 Sofia Papagiannaki
        #prepare user defined meta
459 7812e1f9 Sofia Papagiannaki
        meta = {}
460 7812e1f9 Sofia Papagiannaki
        for arg in args:
461 7812e1f9 Sofia Papagiannaki
            key, sep, val = arg.partition('=')
462 7812e1f9 Sofia Papagiannaki
            meta[key] = val
463 7812e1f9 Sofia Papagiannaki
        
464 cfac048c Giorgos Verigakis
        if not sep:
465 cfac048c Giorgos Verigakis
            dst_container = src_container
466 cfac048c Giorgos Verigakis
            dst_object = dst
467 7812e1f9 Sofia Papagiannaki
        
468 d4a63b9b Sofia Papagiannaki
        args = {'content_type':self.content_type} if self.content_type else {}
469 f07c5a53 Sofia Papagiannaki
        self.client.copy_object(src_container, src_object, dst_container,
470 d4a63b9b Sofia Papagiannaki
                                dst_object, meta, self.public, self.version,
471 d4a63b9b Sofia Papagiannaki
                                **args)
472 cfac048c Giorgos Verigakis
473 cfac048c Giorgos Verigakis
@cli_command('set')
474 3f5b02c7 Sofia Papagiannaki
class SetMeta(Command):
475 3f5b02c7 Sofia Papagiannaki
    syntax = '[<container>[/<object>]] key=val [key=val] [...]'
476 f63cf249 Sofia Papagiannaki
    description = 'set account/container/object metadata'
477 cfac048c Giorgos Verigakis
    
478 cfac048c Giorgos Verigakis
    def execute(self, path, *args):
479 3f5b02c7 Sofia Papagiannaki
        #in case of account fix the args
480 f07c5a53 Sofia Papagiannaki
        if path.find('=') != -1:
481 3f5b02c7 Sofia Papagiannaki
            args = list(args)
482 3f5b02c7 Sofia Papagiannaki
            args.append(path)
483 3f5b02c7 Sofia Papagiannaki
            args = tuple(args)
484 3f5b02c7 Sofia Papagiannaki
            path = ''
485 cfac048c Giorgos Verigakis
        meta = {}
486 cfac048c Giorgos Verigakis
        for arg in args:
487 cfac048c Giorgos Verigakis
            key, sep, val = arg.partition('=')
488 cfac048c Giorgos Verigakis
            meta[key.strip()] = val.strip()
489 3f5b02c7 Sofia Papagiannaki
        container, sep, object = path.partition('/')
490 3f5b02c7 Sofia Papagiannaki
        if object:
491 3f5b02c7 Sofia Papagiannaki
            self.client.update_object_metadata(container, object, **meta)
492 3f5b02c7 Sofia Papagiannaki
        elif container:
493 3f5b02c7 Sofia Papagiannaki
            self.client.update_container_metadata(container, **meta)
494 3f5b02c7 Sofia Papagiannaki
        else:
495 3f5b02c7 Sofia Papagiannaki
            self.client.update_account_metadata(**meta)
496 cfac048c Giorgos Verigakis
497 f07c5a53 Sofia Papagiannaki
@cli_command('update')
498 f07c5a53 Sofia Papagiannaki
class UpdateObject(Command):
499 f07c5a53 Sofia Papagiannaki
    syntax = '<container>/<object> path [key=val] [...]'
500 e3fd7f91 Sofia Papagiannaki
    description = 'update object metadata/data (default mode: append)'
501 f07c5a53 Sofia Papagiannaki
    
502 f07c5a53 Sofia Papagiannaki
    def add_options(self, parser):
503 f07c5a53 Sofia Papagiannaki
        parser.add_option('-a', action='store_true', dest='append',
504 e3fd7f91 Sofia Papagiannaki
                          default=True, help='append data')
505 bcb7c5a8 Sofia Papagiannaki
        parser.add_option('--offset', action='store',
506 bcb7c5a8 Sofia Papagiannaki
                          dest='offset',
507 a2defd86 Sofia Papagiannaki
                          default=None, help='starting offest to be updated')
508 f9e723fd Sofia Papagiannaki
        parser.add_option('--range', action='store', dest='content_range',
509 f07c5a53 Sofia Papagiannaki
                          default=None, help='range of data to be updated')
510 f07c5a53 Sofia Papagiannaki
        parser.add_option('--chunked', action='store_true', dest='chunked',
511 f07c5a53 Sofia Papagiannaki
                          default=False, help='set chunked transfer mode')
512 f07c5a53 Sofia Papagiannaki
        parser.add_option('--content-encoding', action='store',
513 25c3841c Sofia Papagiannaki
                          dest='content_encoding', default=None,
514 f07c5a53 Sofia Papagiannaki
                          help='provide the object MIME content type')
515 f07c5a53 Sofia Papagiannaki
        parser.add_option('--content-disposition', action='store', type='str',
516 25c3841c Sofia Papagiannaki
                          dest='content_disposition', default=None,
517 f07c5a53 Sofia Papagiannaki
                          help='provide the presentation style of the object')
518 f07c5a53 Sofia Papagiannaki
        parser.add_option('--manifest', action='store', type='str',
519 25c3841c Sofia Papagiannaki
                          dest='x_object_manifest', default=None,
520 d3fd269f Sofia Papagiannaki
                          help='use for large file support')        
521 d3fd269f Sofia Papagiannaki
        parser.add_option('--sharing', action='store',
522 25c3841c Sofia Papagiannaki
                          dest='x_object_sharing', default=None,
523 d3fd269f Sofia Papagiannaki
                          help='define sharing object policy')
524 bcb7c5a8 Sofia Papagiannaki
        parser.add_option('--nosharing', action='store_true',
525 bcb7c5a8 Sofia Papagiannaki
                          dest='no_sharing', default=None,
526 bcb7c5a8 Sofia Papagiannaki
                          help='clear object sharing policy')
527 bcb7c5a8 Sofia Papagiannaki
        parser.add_option('-f', action='store',
528 bcb7c5a8 Sofia Papagiannaki
                          dest='srcpath', default=None,
529 bcb7c5a8 Sofia Papagiannaki
                          help='file descriptor to read from: pass - for standard input')
530 7812e1f9 Sofia Papagiannaki
        parser.add_option('--public', action='store_true',
531 25c3841c Sofia Papagiannaki
                          dest='x_object_public', default=False,
532 7812e1f9 Sofia Papagiannaki
                          help='make object publicly accessible')
533 633bbb9f Sofia Papagiannaki
        parser.add_option('--replace', action='store_true',
534 633bbb9f Sofia Papagiannaki
                          dest='replace', default=False,
535 633bbb9f Sofia Papagiannaki
                          help='override metadata')
536 f7ab99df Sofia Papagiannaki
    
537 bcb7c5a8 Sofia Papagiannaki
    def execute(self, path, *args):
538 bcb7c5a8 Sofia Papagiannaki
        if path.find('=') != -1:
539 bcb7c5a8 Sofia Papagiannaki
            raise Fault('Missing path argument')
540 bcb7c5a8 Sofia Papagiannaki
        
541 f07c5a53 Sofia Papagiannaki
        #prepare user defined meta
542 bcb7c5a8 Sofia Papagiannaki
        meta = {}
543 f07c5a53 Sofia Papagiannaki
        for arg in args:
544 f07c5a53 Sofia Papagiannaki
            key, sep, val = arg.partition('=')
545 bcb7c5a8 Sofia Papagiannaki
            meta[key] = val
546 f07c5a53 Sofia Papagiannaki
        
547 25c3841c Sofia Papagiannaki
        
548 25c3841c Sofia Papagiannaki
        attrs = ['content_encoding', 'content_disposition', 'x_object_sharing',
549 f9e723fd Sofia Papagiannaki
                 'x_object_public', 'x_object_manifest', 'replace', 'offset',
550 f9e723fd Sofia Papagiannaki
                 'content_range']
551 25c3841c Sofia Papagiannaki
        args = self._build_args(attrs)
552 25c3841c Sofia Papagiannaki
        
553 38bf2cdc Sofia Papagiannaki
        if self.no_sharing:
554 38bf2cdc Sofia Papagiannaki
            args['x_object_sharing'] = ''
555 38bf2cdc Sofia Papagiannaki
        
556 f07c5a53 Sofia Papagiannaki
        container, sep, object = path.partition('/')
557 f07c5a53 Sofia Papagiannaki
        
558 a2defd86 Sofia Papagiannaki
        f = None
559 bcb7c5a8 Sofia Papagiannaki
        if self.srcpath:
560 25c3841c Sofia Papagiannaki
            f = open(self.srcpath) if self.srcpath != '-' else stdin
561 25c3841c Sofia Papagiannaki
        
562 25c3841c Sofia Papagiannaki
        if self.chunked:
563 25c3841c Sofia Papagiannaki
            self.client.update_object_using_chunks(container, object, f,
564 25c3841c Sofia Papagiannaki
                                                    meta=meta, **args)
565 25c3841c Sofia Papagiannaki
        else:
566 f0964245 Sofia Papagiannaki
            self.client.update_object(container, object, f, meta=meta, **args)
567 a2defd86 Sofia Papagiannaki
        if f:
568 a2defd86 Sofia Papagiannaki
            f.close()
569 f07c5a53 Sofia Papagiannaki
570 f07c5a53 Sofia Papagiannaki
@cli_command('move', 'mv')
571 f07c5a53 Sofia Papagiannaki
class MoveObject(Command):
572 f07c5a53 Sofia Papagiannaki
    syntax = '<src container>/<src object> [<dst container>/]<dst object>'
573 f89e3cf4 Sofia Papagiannaki
    description = 'move an object to a different location'
574 f89e3cf4 Sofia Papagiannaki
    
575 f89e3cf4 Sofia Papagiannaki
    def add_options(self, parser):
576 7812e1f9 Sofia Papagiannaki
        parser.add_option('--public', action='store_true',
577 7812e1f9 Sofia Papagiannaki
                          dest='public', default=False,
578 7812e1f9 Sofia Papagiannaki
                          help='make object publicly accessible')
579 d4a63b9b Sofia Papagiannaki
        parser.add_option('--content-type', action='store',
580 d4a63b9b Sofia Papagiannaki
                          dest='content_type', default=None,
581 d4a63b9b Sofia Papagiannaki
                          help='change object\'s content type')
582 f07c5a53 Sofia Papagiannaki
    
583 7812e1f9 Sofia Papagiannaki
    def execute(self, src, dst, *args):
584 f07c5a53 Sofia Papagiannaki
        src_container, sep, src_object = src.partition('/')
585 f07c5a53 Sofia Papagiannaki
        dst_container, sep, dst_object = dst.partition('/')
586 f07c5a53 Sofia Papagiannaki
        if not sep:
587 f07c5a53 Sofia Papagiannaki
            dst_container = src_container
588 f07c5a53 Sofia Papagiannaki
            dst_object = dst
589 7812e1f9 Sofia Papagiannaki
        
590 7812e1f9 Sofia Papagiannaki
        #prepare user defined meta
591 7812e1f9 Sofia Papagiannaki
        meta = {}
592 7812e1f9 Sofia Papagiannaki
        for arg in args:
593 7812e1f9 Sofia Papagiannaki
            key, sep, val = arg.partition('=')
594 7812e1f9 Sofia Papagiannaki
            meta[key] = val
595 7812e1f9 Sofia Papagiannaki
        
596 d4a63b9b Sofia Papagiannaki
        args = {'content_type':self.content_type} if self.content_type else {}
597 f07c5a53 Sofia Papagiannaki
        self.client.move_object(src_container, src_object, dst_container,
598 97d45f69 Antony Chazapis
                                dst_object, meta, self.public, **args)
599 f7ab99df Sofia Papagiannaki
600 f7ab99df Sofia Papagiannaki
@cli_command('unset')
601 bcb7c5a8 Sofia Papagiannaki
class UnsetObject(Command):
602 f7ab99df Sofia Papagiannaki
    syntax = '<container>/[<object>] key [key] [...]'
603 f89e3cf4 Sofia Papagiannaki
    description = 'delete metadata info'
604 f7ab99df Sofia Papagiannaki
    
605 f7ab99df Sofia Papagiannaki
    def execute(self, path, *args):
606 f7ab99df Sofia Papagiannaki
        #in case of account fix the args
607 961f2fbe Sofia Papagiannaki
        if len(args) == 0:
608 f7ab99df Sofia Papagiannaki
            args = list(args)
609 f7ab99df Sofia Papagiannaki
            args.append(path)
610 f7ab99df Sofia Papagiannaki
            args = tuple(args)
611 f7ab99df Sofia Papagiannaki
            path = ''
612 f7ab99df Sofia Papagiannaki
        meta = []
613 f7ab99df Sofia Papagiannaki
        for key in args:
614 f7ab99df Sofia Papagiannaki
            meta.append(key)
615 f7ab99df Sofia Papagiannaki
        container, sep, object = path.partition('/')
616 f7ab99df Sofia Papagiannaki
        if object:
617 f7ab99df Sofia Papagiannaki
            self.client.delete_object_metadata(container, object, meta)
618 f7ab99df Sofia Papagiannaki
        elif container:
619 f7ab99df Sofia Papagiannaki
            self.client.delete_container_metadata(container, meta)
620 f7ab99df Sofia Papagiannaki
        else:
621 f7ab99df Sofia Papagiannaki
            self.client.delete_account_metadata(meta)
622 f7ab99df Sofia Papagiannaki
623 d3fd269f Sofia Papagiannaki
@cli_command('group')
624 f63cf249 Sofia Papagiannaki
class CreateGroup(Command):
625 d3fd269f Sofia Papagiannaki
    syntax = 'key=val [key=val] [...]'
626 f63cf249 Sofia Papagiannaki
    description = 'create account groups'
627 d3fd269f Sofia Papagiannaki
    
628 bcb7c5a8 Sofia Papagiannaki
    def execute(self, *args):
629 d3fd269f Sofia Papagiannaki
        groups = {}
630 d3fd269f Sofia Papagiannaki
        for arg in args:
631 d3fd269f Sofia Papagiannaki
            key, sep, val = arg.partition('=')
632 d3fd269f Sofia Papagiannaki
            groups[key] = val
633 bcb7c5a8 Sofia Papagiannaki
        self.client.set_account_groups(**groups)
634 bcb7c5a8 Sofia Papagiannaki
635 f63cf249 Sofia Papagiannaki
@cli_command('ungroup')
636 f63cf249 Sofia Papagiannaki
class DeleteGroup(Command):
637 f63cf249 Sofia Papagiannaki
    syntax = 'key [key] [...]'
638 f63cf249 Sofia Papagiannaki
    description = 'delete account groups'
639 f63cf249 Sofia Papagiannaki
    
640 f63cf249 Sofia Papagiannaki
    def execute(self, *args):
641 f63cf249 Sofia Papagiannaki
        groups = []
642 f63cf249 Sofia Papagiannaki
        for arg in args:
643 f63cf249 Sofia Papagiannaki
            groups.append(arg)
644 f63cf249 Sofia Papagiannaki
        self.client.unset_account_groups(groups)
645 f63cf249 Sofia Papagiannaki
646 bcb7c5a8 Sofia Papagiannaki
@cli_command('policy')
647 bcb7c5a8 Sofia Papagiannaki
class SetPolicy(Command):
648 bcb7c5a8 Sofia Papagiannaki
    syntax = 'container key=val [key=val] [...]'
649 f89e3cf4 Sofia Papagiannaki
    description = 'set container policies'
650 bcb7c5a8 Sofia Papagiannaki
    
651 bcb7c5a8 Sofia Papagiannaki
    def execute(self, path, *args):
652 bcb7c5a8 Sofia Papagiannaki
        if path.find('=') != -1:
653 bcb7c5a8 Sofia Papagiannaki
            raise Fault('Missing container argument')
654 bcb7c5a8 Sofia Papagiannaki
        
655 bcb7c5a8 Sofia Papagiannaki
        container, sep, object = path.partition('/')
656 bcb7c5a8 Sofia Papagiannaki
        
657 bcb7c5a8 Sofia Papagiannaki
        if object:
658 bcb7c5a8 Sofia Papagiannaki
            raise Fault('Only containers have policies')
659 bcb7c5a8 Sofia Papagiannaki
        
660 bcb7c5a8 Sofia Papagiannaki
        policies = {}
661 bcb7c5a8 Sofia Papagiannaki
        for arg in args:
662 bcb7c5a8 Sofia Papagiannaki
            key, sep, val = arg.partition('=')
663 bcb7c5a8 Sofia Papagiannaki
            policies[key] = val
664 bcb7c5a8 Sofia Papagiannaki
        
665 bcb7c5a8 Sofia Papagiannaki
        self.client.set_container_policies(container, **policies)
666 d3fd269f Sofia Papagiannaki
667 f89e3cf4 Sofia Papagiannaki
@cli_command('publish')
668 f89e3cf4 Sofia Papagiannaki
class PublishObject(Command):
669 f89e3cf4 Sofia Papagiannaki
    syntax = '<container>/<object>'
670 f89e3cf4 Sofia Papagiannaki
    description = 'publish an object'
671 f89e3cf4 Sofia Papagiannaki
    
672 f89e3cf4 Sofia Papagiannaki
    def execute(self, src):
673 f89e3cf4 Sofia Papagiannaki
        src_container, sep, src_object = src.partition('/')
674 f89e3cf4 Sofia Papagiannaki
        
675 f89e3cf4 Sofia Papagiannaki
        self.client.publish_object(src_container, src_object)
676 f89e3cf4 Sofia Papagiannaki
677 f89e3cf4 Sofia Papagiannaki
@cli_command('unpublish')
678 f89e3cf4 Sofia Papagiannaki
class UnpublishObject(Command):
679 f89e3cf4 Sofia Papagiannaki
    syntax = '<container>/<object>'
680 f89e3cf4 Sofia Papagiannaki
    description = 'unpublish an object'
681 f89e3cf4 Sofia Papagiannaki
    
682 f89e3cf4 Sofia Papagiannaki
    def execute(self, src):
683 f89e3cf4 Sofia Papagiannaki
        src_container, sep, src_object = src.partition('/')
684 f89e3cf4 Sofia Papagiannaki
        
685 f89e3cf4 Sofia Papagiannaki
        self.client.unpublish_object(src_container, src_object)
686 f89e3cf4 Sofia Papagiannaki
687 d4a63b9b Sofia Papagiannaki
@cli_command('sharing')
688 d4a63b9b Sofia Papagiannaki
class SharingObject(Command):
689 d4a63b9b Sofia Papagiannaki
    syntax = 'list users sharing objects with the user'
690 d4a63b9b Sofia Papagiannaki
    description = 'list user accounts sharing objects with the user'
691 d4a63b9b Sofia Papagiannaki
    
692 d4a63b9b Sofia Papagiannaki
    def add_options(self, parser):
693 d4a63b9b Sofia Papagiannaki
        parser.add_option('-l', action='store_true', dest='detail',
694 d4a63b9b Sofia Papagiannaki
                          default=False, help='show detailed output')
695 d4a63b9b Sofia Papagiannaki
        parser.add_option('-n', action='store', type='int', dest='limit',
696 d4a63b9b Sofia Papagiannaki
                          default=10000, help='show limited output')
697 d4a63b9b Sofia Papagiannaki
        parser.add_option('--marker', action='store', type='str',
698 d4a63b9b Sofia Papagiannaki
                          dest='marker', default=None,
699 d4a63b9b Sofia Papagiannaki
                          help='show output greater then marker')
700 d4a63b9b Sofia Papagiannaki
        
701 d4a63b9b Sofia Papagiannaki
    
702 d4a63b9b Sofia Papagiannaki
    def execute(self):
703 d4a63b9b Sofia Papagiannaki
        attrs = ['limit', 'marker']
704 d4a63b9b Sofia Papagiannaki
        args = self._build_args(attrs)
705 d4a63b9b Sofia Papagiannaki
        args['format'] = 'json' if self.detail else 'text'
706 d4a63b9b Sofia Papagiannaki
        
707 d4a63b9b Sofia Papagiannaki
        print_list(self.client.list_shared_by_others(**args))
708 d4a63b9b Sofia Papagiannaki
709 822cc7eb Antony Chazapis
@cli_command('send')
710 822cc7eb Antony Chazapis
class Send(Command):
711 822cc7eb Antony Chazapis
    syntax = '<file> <container>[/<prefix>]'
712 822cc7eb Antony Chazapis
    description = 'upload file to container (using prefix)'
713 f546c15e Antony Chazapis
    
714 f546c15e Antony Chazapis
    def execute(self, file, path):
715 f546c15e Antony Chazapis
        container, sep, prefix = path.partition('/')
716 822cc7eb Antony Chazapis
        upload(self.client, file, container, prefix)
717 822cc7eb Antony Chazapis
718 f546c15e Antony Chazapis
@cli_command('receive')
719 f546c15e Antony Chazapis
class Receive(Command):
720 f546c15e Antony Chazapis
    syntax = '<container>/<object> <file>'
721 f546c15e Antony Chazapis
    description = 'download object to file'
722 f546c15e Antony Chazapis
    
723 f546c15e Antony Chazapis
    def execute(self, path, file):
724 f546c15e Antony Chazapis
        container, sep, object = path.partition('/')
725 f546c15e Antony Chazapis
        download(self.client, container, object, file)
726 f546c15e Antony Chazapis
727 cfac048c Giorgos Verigakis
def print_usage():
728 10998c60 Sofia Papagiannaki
    cmd = Command('', [])
729 cfac048c Giorgos Verigakis
    parser = cmd.parser
730 cfac048c Giorgos Verigakis
    parser.usage = '%prog <command> [options]'
731 cfac048c Giorgos Verigakis
    parser.print_help()
732 cfac048c Giorgos Verigakis
    
733 cfac048c Giorgos Verigakis
    commands = []
734 cfac048c Giorgos Verigakis
    for cls in set(_cli_commands.values()):
735 cfac048c Giorgos Verigakis
        name = ', '.join(cls.commands)
736 cfac048c Giorgos Verigakis
        description = getattr(cls, 'description', '')
737 cfac048c Giorgos Verigakis
        commands.append('  %s %s' % (name.ljust(12), description))
738 cfac048c Giorgos Verigakis
    print '\nCommands:\n' + '\n'.join(sorted(commands))
739 cfac048c Giorgos Verigakis
740 a4c10cbc Sofia Papagiannaki
def print_dict(d, header='name', f=stdout, detail=True):
741 ae75584f Sofia Papagiannaki
    header = header if header in d else 'subdir'
742 f07c5a53 Sofia Papagiannaki
    if header and header in d:
743 ae75584f Sofia Papagiannaki
        f.write('%s\n' %d.pop(header).encode('utf8'))
744 a4c10cbc Sofia Papagiannaki
    if detail:
745 a4c10cbc Sofia Papagiannaki
        patterns = ['^x_(account|container|object)_meta_(\w+)$']
746 a4c10cbc Sofia Papagiannaki
        patterns.append(patterns[0].replace('_', '-'))
747 a4c10cbc Sofia Papagiannaki
        for key, val in sorted(d.items()):
748 a4c10cbc Sofia Papagiannaki
            f.write('%s: %s\n' % (key.rjust(30), val))
749 f07c5a53 Sofia Papagiannaki
750 a4c10cbc Sofia Papagiannaki
def print_list(l, verbose=False, f=stdout, detail=True):
751 f07c5a53 Sofia Papagiannaki
    for elem in l:
752 f07c5a53 Sofia Papagiannaki
        #if it's empty string continue
753 f07c5a53 Sofia Papagiannaki
        if not elem:
754 f07c5a53 Sofia Papagiannaki
            continue
755 f07c5a53 Sofia Papagiannaki
        if type(elem) == types.DictionaryType:
756 a4c10cbc Sofia Papagiannaki
            print_dict(elem, f=f, detail=detail)
757 f07c5a53 Sofia Papagiannaki
        elif type(elem) == types.StringType:
758 f07c5a53 Sofia Papagiannaki
            if not verbose:
759 f07c5a53 Sofia Papagiannaki
                elem = elem.split('Traceback')[0]
760 f07c5a53 Sofia Papagiannaki
            f.write('%s\n' % elem)
761 f07c5a53 Sofia Papagiannaki
        else:
762 f07c5a53 Sofia Papagiannaki
            f.write('%s\n' % elem)
763 cfac048c Giorgos Verigakis
764 8fe01d72 Sofia Papagiannaki
def print_versions(data, f=stdout):
765 8fe01d72 Sofia Papagiannaki
    if 'versions' not in data:
766 8fe01d72 Sofia Papagiannaki
        f.write('%s\n' %data)
767 8fe01d72 Sofia Papagiannaki
        return
768 8fe01d72 Sofia Papagiannaki
    f.write('versions:\n')
769 8fe01d72 Sofia Papagiannaki
    for id, t in data['versions']:
770 e414f54d Sofia Papagiannaki
        f.write('%s @ %s\n' % (str(id).rjust(30), datetime.fromtimestamp(float(t))))
771 8fe01d72 Sofia Papagiannaki
772 9e826a59 Kostas Papadimitriou
773 cfac048c Giorgos Verigakis
def main():
774 cfac048c Giorgos Verigakis
    try:
775 cfac048c Giorgos Verigakis
        name = argv[1]
776 cfac048c Giorgos Verigakis
        cls = class_for_cli_command(name)
777 cfac048c Giorgos Verigakis
    except (IndexError, KeyError):
778 cfac048c Giorgos Verigakis
        print_usage()
779 cfac048c Giorgos Verigakis
        exit(1)
780 f07c5a53 Sofia Papagiannaki
    
781 a2defd86 Sofia Papagiannaki
    cmd = cls(name, argv[2:])
782 cfac048c Giorgos Verigakis
    
783 95e92490 Sofia Papagiannaki
    try:
784 95e92490 Sofia Papagiannaki
        cmd.execute(*cmd.args)
785 95e92490 Sofia Papagiannaki
    except TypeError, e:
786 95e92490 Sofia Papagiannaki
        cmd.parser.print_help()
787 95e92490 Sofia Papagiannaki
        exit(1)
788 95e92490 Sofia Papagiannaki
    except Fault, f:
789 af6d3b5d Antony Chazapis
        status = '%s ' % f.status if f.status else ''
790 95e92490 Sofia Papagiannaki
        print '%s%s' % (status, f.data)
791 cfac048c Giorgos Verigakis
792 9e826a59 Kostas Papadimitriou
793 cfac048c Giorgos Verigakis
if __name__ == '__main__':
794 cfac048c Giorgos Verigakis
    main()