Statistics
| Branch: | Tag: | Revision:

root / tools / store @ f0964245

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