Statistics
| Branch: | Tag: | Revision:

root / snf-pithos-tools / pithos / tools / lib / client.py @ db117cac

History | View | Annotate | Download (41.6 kB)

1 2e662088 Antony Chazapis
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2 a4c10cbc Sofia Papagiannaki
# 
3 a4c10cbc Sofia Papagiannaki
# Redistribution and use in source and binary forms, with or
4 a4c10cbc Sofia Papagiannaki
# without modification, are permitted provided that the following
5 a4c10cbc Sofia Papagiannaki
# conditions are met:
6 a4c10cbc Sofia Papagiannaki
# 
7 a4c10cbc Sofia Papagiannaki
#   1. Redistributions of source code must retain the above
8 a4c10cbc Sofia Papagiannaki
#      copyright notice, this list of conditions and the following
9 a4c10cbc Sofia Papagiannaki
#      disclaimer.
10 a4c10cbc Sofia Papagiannaki
# 
11 a4c10cbc Sofia Papagiannaki
#   2. Redistributions in binary form must reproduce the above
12 a4c10cbc Sofia Papagiannaki
#      copyright notice, this list of conditions and the following
13 a4c10cbc Sofia Papagiannaki
#      disclaimer in the documentation and/or other materials
14 a4c10cbc Sofia Papagiannaki
#      provided with the distribution.
15 a4c10cbc Sofia Papagiannaki
# 
16 a4c10cbc Sofia Papagiannaki
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 a4c10cbc Sofia Papagiannaki
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 a4c10cbc Sofia Papagiannaki
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 a4c10cbc Sofia Papagiannaki
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 a4c10cbc Sofia Papagiannaki
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 a4c10cbc Sofia Papagiannaki
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 a4c10cbc Sofia Papagiannaki
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 a4c10cbc Sofia Papagiannaki
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 a4c10cbc Sofia Papagiannaki
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 a4c10cbc Sofia Papagiannaki
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 a4c10cbc Sofia Papagiannaki
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 a4c10cbc Sofia Papagiannaki
# POSSIBILITY OF SUCH DAMAGE.
28 a4c10cbc Sofia Papagiannaki
# 
29 a4c10cbc Sofia Papagiannaki
# The views and conclusions contained in the software and
30 a4c10cbc Sofia Papagiannaki
# documentation are those of the authors and should not be
31 a4c10cbc Sofia Papagiannaki
# interpreted as representing official policies, either expressed
32 a4c10cbc Sofia Papagiannaki
# or implied, of GRNET S.A.
33 a4c10cbc Sofia Papagiannaki
34 09fd65c7 Sofia Papagiannaki
from httplib import HTTPConnection, HTTPSConnection, HTTP
35 ec1b8d3e Sofia Papagiannaki
from sys import stdin
36 f0eacc2c Sofia Papagiannaki
from xml.dom import minidom
37 9471fece Sofia Papagiannaki
from StringIO import StringIO
38 b5dc1bda Sofia Papagiannaki
from urllib import quote, unquote
39 09fd65c7 Sofia Papagiannaki
from urlparse import urlparse
40 3f5b02c7 Sofia Papagiannaki
41 3f5b02c7 Sofia Papagiannaki
import json
42 ec1b8d3e Sofia Papagiannaki
import types
43 0ea1dcc4 Sofia Papagiannaki
import socket
44 ae75584f Sofia Papagiannaki
import urllib
45 e7b51248 Sofia Papagiannaki
import datetime
46 e3fd7f91 Sofia Papagiannaki
47 e3fd7f91 Sofia Papagiannaki
ERROR_CODES = {304:'Not Modified',
48 e3fd7f91 Sofia Papagiannaki
               400:'Bad Request',
49 e3fd7f91 Sofia Papagiannaki
               401:'Unauthorized',
50 81ed48a5 Sofia Papagiannaki
               403:'Forbidden',
51 e3fd7f91 Sofia Papagiannaki
               404:'Not Found',
52 e3fd7f91 Sofia Papagiannaki
               409:'Conflict',
53 e3fd7f91 Sofia Papagiannaki
               411:'Length Required',
54 e3fd7f91 Sofia Papagiannaki
               412:'Precondition Failed',
55 81ed48a5 Sofia Papagiannaki
               413:'Request Entity Too Large',
56 e3fd7f91 Sofia Papagiannaki
               416:'Range Not Satisfiable',
57 e3fd7f91 Sofia Papagiannaki
               422:'Unprocessable Entity',
58 08de868d Antony Chazapis
               500:'Internal Server Error',
59 08de868d Antony Chazapis
               501:'Not Implemented'}
60 3f5b02c7 Sofia Papagiannaki
61 3f5b02c7 Sofia Papagiannaki
class Fault(Exception):
62 e3fd7f91 Sofia Papagiannaki
    def __init__(self, data='', status=None):
63 e3fd7f91 Sofia Papagiannaki
        if data == '' and status in ERROR_CODES.keys():
64 e3fd7f91 Sofia Papagiannaki
            data = ERROR_CODES[status]
65 3f5b02c7 Sofia Papagiannaki
        Exception.__init__(self, data)
66 3f5b02c7 Sofia Papagiannaki
        self.data = data
67 e3fd7f91 Sofia Papagiannaki
        self.status = status
68 3f5b02c7 Sofia Papagiannaki
69 3f5b02c7 Sofia Papagiannaki
class Client(object):
70 09fd65c7 Sofia Papagiannaki
    def __init__(self, url, token, account, verbose=False, debug=False):
71 09fd65c7 Sofia Papagiannaki
        """`url` can also include a port, e.g '127.0.0.1:8000'."""
72 3f5b02c7 Sofia Papagiannaki
        
73 09fd65c7 Sofia Papagiannaki
        self.url = url
74 3f5b02c7 Sofia Papagiannaki
        self.account = account
75 3f5b02c7 Sofia Papagiannaki
        self.verbose = verbose or debug
76 3f5b02c7 Sofia Papagiannaki
        self.debug = debug
77 bcb7c5a8 Sofia Papagiannaki
        self.token = token
78 f7ab99df Sofia Papagiannaki
    
79 95e92490 Sofia Papagiannaki
    def _req(self, method, path, body=None, headers={}, format='text', params={}):
80 09fd65c7 Sofia Papagiannaki
        p = urlparse(self.url)
81 09fd65c7 Sofia Papagiannaki
        if p.scheme == 'http':
82 09fd65c7 Sofia Papagiannaki
            conn = HTTPConnection(p.netloc)
83 09fd65c7 Sofia Papagiannaki
        elif p.scheme == 'https':
84 09fd65c7 Sofia Papagiannaki
            conn = HTTPSConnection(p.netloc)
85 09fd65c7 Sofia Papagiannaki
        else:
86 09fd65c7 Sofia Papagiannaki
            raise Exception('Unknown URL scheme')
87 09fd65c7 Sofia Papagiannaki
        
88 09fd65c7 Sofia Papagiannaki
        full_path = _prepare_path(p.path + path, format, params)
89 ae75584f Sofia Papagiannaki
        
90 3f5b02c7 Sofia Papagiannaki
        kwargs = {}
91 f1716de7 Sofia Papagiannaki
        kwargs['headers'] = _prepare_headers(headers)
92 bcb7c5a8 Sofia Papagiannaki
        kwargs['headers']['X-Auth-Token'] = self.token
93 3f5b02c7 Sofia Papagiannaki
        if body:
94 3f5b02c7 Sofia Papagiannaki
            kwargs['body'] = body
95 bcd29125 Sofia Papagiannaki
            kwargs['headers'].setdefault('content-type', 'application/octet-stream')
96 25c3841c Sofia Papagiannaki
        kwargs['headers'].setdefault('content-length', len(body) if body else 0)
97 e7b51248 Sofia Papagiannaki
        
98 ae75584f Sofia Papagiannaki
        #print '#', method, full_path, kwargs
99 f1716de7 Sofia Papagiannaki
        #t1 = datetime.datetime.utcnow()
100 ae75584f Sofia Papagiannaki
        conn.request(method, full_path, **kwargs)
101 ae75584f Sofia Papagiannaki
        
102 3f5b02c7 Sofia Papagiannaki
        resp = conn.getresponse()
103 f1716de7 Sofia Papagiannaki
        #t2 = datetime.datetime.utcnow()
104 e7b51248 Sofia Papagiannaki
        #print 'response time:', str(t2-t1)
105 f1716de7 Sofia Papagiannaki
        return _handle_response(resp, self.verbose, self.debug)
106 f7ab99df Sofia Papagiannaki
    
107 633bbb9f Sofia Papagiannaki
    def _chunked_transfer(self, path, method='PUT', f=stdin, headers=None,
108 633bbb9f Sofia Papagiannaki
                          blocksize=1024, params={}):
109 633bbb9f Sofia Papagiannaki
        """perfomrs a chunked request"""
110 09fd65c7 Sofia Papagiannaki
        p = urlparse(self.url)
111 09fd65c7 Sofia Papagiannaki
        if p.scheme == 'http':
112 09fd65c7 Sofia Papagiannaki
            conn = HTTPConnection(p.netloc)
113 09fd65c7 Sofia Papagiannaki
        elif p.scheme == 'https':
114 09fd65c7 Sofia Papagiannaki
            conn = HTTPSConnection(p.netloc)
115 09fd65c7 Sofia Papagiannaki
        else:
116 09fd65c7 Sofia Papagiannaki
            raise Exception('Unknown URL scheme')
117 09fd65c7 Sofia Papagiannaki
        
118 3cdf3070 Antony Chazapis
        full_path = _prepare_path(p.path + path, params=params)
119 633bbb9f Sofia Papagiannaki
        
120 ca3ab617 Sofia Papagiannaki
        headers.setdefault('content-type', 'application/octet-stream')
121 ca3ab617 Sofia Papagiannaki
        
122 f1716de7 Sofia Papagiannaki
        conn.putrequest(method, full_path)
123 f1716de7 Sofia Papagiannaki
        conn.putheader('x-auth-token', self.token)
124 f1716de7 Sofia Papagiannaki
        conn.putheader('transfer-encoding', 'chunked')
125 f1716de7 Sofia Papagiannaki
        for k,v in _prepare_headers(headers).items():
126 f1716de7 Sofia Papagiannaki
            conn.putheader(k, v)
127 f1716de7 Sofia Papagiannaki
        conn.endheaders()
128 633bbb9f Sofia Papagiannaki
        
129 633bbb9f Sofia Papagiannaki
        # write body
130 633bbb9f Sofia Papagiannaki
        data = ''
131 633bbb9f Sofia Papagiannaki
        while True:
132 633bbb9f Sofia Papagiannaki
            if f.closed:
133 633bbb9f Sofia Papagiannaki
                break
134 633bbb9f Sofia Papagiannaki
            block = f.read(blocksize)
135 633bbb9f Sofia Papagiannaki
            if block == '':
136 633bbb9f Sofia Papagiannaki
                break
137 633bbb9f Sofia Papagiannaki
            data = '%x\r\n%s\r\n' % (len(block), block)
138 633bbb9f Sofia Papagiannaki
            try:
139 f1716de7 Sofia Papagiannaki
                conn.send(data)
140 633bbb9f Sofia Papagiannaki
            except:
141 633bbb9f Sofia Papagiannaki
                #retry
142 f1716de7 Sofia Papagiannaki
                conn.send(data)
143 633bbb9f Sofia Papagiannaki
        data = '0\r\n\r\n'
144 633bbb9f Sofia Papagiannaki
        try:
145 f1716de7 Sofia Papagiannaki
            conn.send(data)
146 633bbb9f Sofia Papagiannaki
        except:
147 633bbb9f Sofia Papagiannaki
            #retry
148 f1716de7 Sofia Papagiannaki
            conn.send(data)
149 633bbb9f Sofia Papagiannaki
        
150 f1716de7 Sofia Papagiannaki
        resp = conn.getresponse()
151 f1716de7 Sofia Papagiannaki
        return _handle_response(resp, self.verbose, self.debug)
152 633bbb9f Sofia Papagiannaki
    
153 25c3841c Sofia Papagiannaki
    def delete(self, path, format='text', params={}):
154 25c3841c Sofia Papagiannaki
        return self._req('DELETE', path, format=format, params=params)
155 f7ab99df Sofia Papagiannaki
    
156 95e92490 Sofia Papagiannaki
    def get(self, path, format='text', headers={}, params={}):
157 615e561b Sofia Papagiannaki
        return self._req('GET', path, headers=headers, format=format,
158 95e92490 Sofia Papagiannaki
                        params=params)
159 f7ab99df Sofia Papagiannaki
    
160 25c3841c Sofia Papagiannaki
    def head(self, path, format='text', params={}):
161 ae75584f Sofia Papagiannaki
         return self._req('HEAD', path, format=format, params=params)
162 f7ab99df Sofia Papagiannaki
    
163 25c3841c Sofia Papagiannaki
    def post(self, path, body=None, format='text', headers=None, params={}):
164 615e561b Sofia Papagiannaki
        return self._req('POST', path, body, headers=headers, format=format,
165 6749c3bd Sofia Papagiannaki
                        params=params)
166 f7ab99df Sofia Papagiannaki
    
167 9471fece Sofia Papagiannaki
    def put(self, path, body=None, format='text', headers=None, params={}):
168 9471fece Sofia Papagiannaki
        return self._req('PUT', path, body, headers=headers, format=format,
169 9471fece Sofia Papagiannaki
                         params=params)
170 f7ab99df Sofia Papagiannaki
    
171 95e92490 Sofia Papagiannaki
    def _list(self, path, format='text', params={}, **headers):
172 3f5b02c7 Sofia Papagiannaki
        status, headers, data = self.get(path, format=format, headers=headers,
173 95e92490 Sofia Papagiannaki
                                         params=params)
174 f0eacc2c Sofia Papagiannaki
        if format == 'json':
175 bcb7c5a8 Sofia Papagiannaki
            data = json.loads(data) if data else ''
176 f0eacc2c Sofia Papagiannaki
        elif format == 'xml':
177 f0eacc2c Sofia Papagiannaki
            data = minidom.parseString(data)
178 ec1b8d3e Sofia Papagiannaki
        else:
179 908c6f81 Sofia Papagiannaki
            data = data.split('\n')[:-1] if data else ''
180 3f5b02c7 Sofia Papagiannaki
        return data
181 f7ab99df Sofia Papagiannaki
    
182 25c3841c Sofia Papagiannaki
    def _get_metadata(self, path, prefix=None, params={}):
183 d2d5c360 Sofia Papagiannaki
        status, headers, data = self.head(path, params=params)
184 f7ab99df Sofia Papagiannaki
        prefixlen = len(prefix) if prefix else 0
185 3f5b02c7 Sofia Papagiannaki
        meta = {}
186 3f5b02c7 Sofia Papagiannaki
        for key, val in headers.items():
187 0ea1dcc4 Sofia Papagiannaki
            if prefix and not key.startswith(prefix):
188 0ea1dcc4 Sofia Papagiannaki
                continue
189 0ea1dcc4 Sofia Papagiannaki
            elif prefix and key.startswith(prefix):
190 3f5b02c7 Sofia Papagiannaki
                key = key[prefixlen:]
191 0ea1dcc4 Sofia Papagiannaki
            meta[key] = val
192 3f5b02c7 Sofia Papagiannaki
        return meta
193 f7ab99df Sofia Papagiannaki
    
194 25c3841c Sofia Papagiannaki
    def _filter(self, l, d):
195 f7ab99df Sofia Papagiannaki
        """
196 25c3841c Sofia Papagiannaki
        filter out from l elements having the metadata values provided
197 f7ab99df Sofia Papagiannaki
        """
198 25c3841c Sofia Papagiannaki
        ll = l
199 25c3841c Sofia Papagiannaki
        for elem in l:
200 25c3841c Sofia Papagiannaki
            if type(elem) == types.DictionaryType:
201 25c3841c Sofia Papagiannaki
                for key in d.keys():
202 25c3841c Sofia Papagiannaki
                    k = 'x_object_meta_%s' % key
203 25c3841c Sofia Papagiannaki
                    if k in elem.keys() and elem[k] == d[key]:
204 25c3841c Sofia Papagiannaki
                        ll.remove(elem)
205 25c3841c Sofia Papagiannaki
                        break
206 25c3841c Sofia Papagiannaki
        return ll
207 25c3841c Sofia Papagiannaki
    
208 25c3841c Sofia Papagiannaki
class OOS_Client(Client):
209 f0eacc2c Sofia Papagiannaki
    """Openstack Object Storage Client"""
210 25c3841c Sofia Papagiannaki
    
211 25c3841c Sofia Papagiannaki
    def _update_metadata(self, path, entity, **meta):
212 25c3841c Sofia Papagiannaki
        """adds new and updates the values of previously set metadata"""
213 25c3841c Sofia Papagiannaki
        ex_meta = self.retrieve_account_metadata(restricted=True)
214 25c3841c Sofia Papagiannaki
        ex_meta.update(meta)
215 f7ab99df Sofia Papagiannaki
        headers = {}
216 6749c3bd Sofia Papagiannaki
        prefix = 'x-%s-meta-' % entity
217 25c3841c Sofia Papagiannaki
        for k,v in ex_meta.items():
218 6749c3bd Sofia Papagiannaki
            k = '%s%s' % (prefix, k)
219 6749c3bd Sofia Papagiannaki
            headers[k] = v
220 cd6ada1d Sofia Papagiannaki
        return self.post(path, headers=headers)
221 f7ab99df Sofia Papagiannaki
    
222 b9ca81a0 Sofia Papagiannaki
    def _reset_metadata(self, path, entity, **meta):
223 b9ca81a0 Sofia Papagiannaki
        """
224 b9ca81a0 Sofia Papagiannaki
        overwrites all user defined metadata
225 b9ca81a0 Sofia Papagiannaki
        """
226 b9ca81a0 Sofia Papagiannaki
        headers = {}
227 b9ca81a0 Sofia Papagiannaki
        prefix = 'x-%s-meta-' % entity
228 b9ca81a0 Sofia Papagiannaki
        for k,v in meta.items():
229 b9ca81a0 Sofia Papagiannaki
            k = '%s%s' % (prefix, k)
230 b9ca81a0 Sofia Papagiannaki
            headers[k] = v
231 b9ca81a0 Sofia Papagiannaki
        return self.post(path, headers=headers)
232 b9ca81a0 Sofia Papagiannaki
    
233 f7ab99df Sofia Papagiannaki
    def _delete_metadata(self, path, entity, meta=[]):
234 25c3841c Sofia Papagiannaki
        """delete previously set metadata"""
235 25c3841c Sofia Papagiannaki
        ex_meta = self.retrieve_account_metadata(restricted=True)
236 f7ab99df Sofia Papagiannaki
        headers = {}
237 615e561b Sofia Papagiannaki
        prefix = 'x-%s-meta-' % entity
238 25c3841c Sofia Papagiannaki
        for k in ex_meta.keys():
239 25c3841c Sofia Papagiannaki
            if k in meta:
240 25c3841c Sofia Papagiannaki
                headers['%s%s' % (prefix, k)] = ex_meta[k]
241 615e561b Sofia Papagiannaki
        return self.post(path, headers=headers)
242 f7ab99df Sofia Papagiannaki
    
243 3f5b02c7 Sofia Papagiannaki
    # Storage Account Services
244 f7ab99df Sofia Papagiannaki
    
245 95e92490 Sofia Papagiannaki
    def list_containers(self, format='text', limit=None,
246 95e92490 Sofia Papagiannaki
                        marker=None, params={}, account=None, **headers):
247 25c3841c Sofia Papagiannaki
        """lists containers"""
248 95e92490 Sofia Papagiannaki
        account = account or self.account
249 95e92490 Sofia Papagiannaki
        path = '/%s' % account
250 25c3841c Sofia Papagiannaki
        params.update({'limit':limit, 'marker':marker})
251 95e92490 Sofia Papagiannaki
        return self._list(path, format, params, **headers)
252 f7ab99df Sofia Papagiannaki
    
253 95e92490 Sofia Papagiannaki
    def retrieve_account_metadata(self, restricted=False, account=None, **params):
254 25c3841c Sofia Papagiannaki
        """returns the account metadata"""
255 95e92490 Sofia Papagiannaki
        account = account or self.account
256 95e92490 Sofia Papagiannaki
        path = '/%s' % account
257 f7ab99df Sofia Papagiannaki
        prefix = 'x-account-meta-' if restricted else None
258 95e92490 Sofia Papagiannaki
        return self._get_metadata(path, prefix, params)
259 f7ab99df Sofia Papagiannaki
    
260 95e92490 Sofia Papagiannaki
    def update_account_metadata(self, account=None, **meta):
261 25c3841c Sofia Papagiannaki
        """updates the account metadata"""
262 95e92490 Sofia Papagiannaki
        account = account or self.account
263 95e92490 Sofia Papagiannaki
        path = '/%s' % account
264 95e92490 Sofia Papagiannaki
        return self._update_metadata(path, 'account', **meta)
265 f7ab99df Sofia Papagiannaki
        
266 95e92490 Sofia Papagiannaki
    def delete_account_metadata(self, meta=[], account=None):
267 25c3841c Sofia Papagiannaki
        """deletes the account metadata"""
268 95e92490 Sofia Papagiannaki
        account = account or self.account
269 95e92490 Sofia Papagiannaki
        path = '/%s' % account
270 95e92490 Sofia Papagiannaki
        return self._delete_metadata(path, 'account', meta)
271 f7ab99df Sofia Papagiannaki
    
272 95e92490 Sofia Papagiannaki
    def reset_account_metadata(self, account=None, **meta):
273 b9ca81a0 Sofia Papagiannaki
        """resets account metadata"""
274 95e92490 Sofia Papagiannaki
        account = account or self.account
275 95e92490 Sofia Papagiannaki
        path = '/%s' % account
276 95e92490 Sofia Papagiannaki
        return self._reset_metadata(path, 'account', **meta)
277 b9ca81a0 Sofia Papagiannaki
    
278 3f5b02c7 Sofia Papagiannaki
    # Storage Container Services
279 f7ab99df Sofia Papagiannaki
    
280 a4c10cbc Sofia Papagiannaki
    def _filter_trashed(self, l):
281 a4c10cbc Sofia Papagiannaki
        return self._filter(l, {'trash':'true'})
282 a4c10cbc Sofia Papagiannaki
    
283 95e92490 Sofia Papagiannaki
    def list_objects(self, container, format='text',
284 95e92490 Sofia Papagiannaki
                     limit=None, marker=None, prefix=None, delimiter=None,
285 95e92490 Sofia Papagiannaki
                     path=None, include_trashed=False, params={}, account=None,
286 95e92490 Sofia Papagiannaki
                     **headers):
287 25c3841c Sofia Papagiannaki
        """returns a list with the container objects"""
288 95e92490 Sofia Papagiannaki
        account = account or self.account
289 25c3841c Sofia Papagiannaki
        params.update({'limit':limit, 'marker':marker, 'prefix':prefix,
290 25c3841c Sofia Papagiannaki
                       'delimiter':delimiter, 'path':path})
291 95e92490 Sofia Papagiannaki
        l = self._list('/%s/%s' % (account, container), format, params,
292 95e92490 Sofia Papagiannaki
                       **headers)
293 f0eacc2c Sofia Papagiannaki
        #TODO support filter trashed with xml also
294 f0eacc2c Sofia Papagiannaki
        if format != 'xml' and not include_trashed:
295 a4c10cbc Sofia Papagiannaki
            l = self._filter_trashed(l)
296 a4c10cbc Sofia Papagiannaki
        return l
297 f7ab99df Sofia Papagiannaki
    
298 5a8dc30c Sofia Papagiannaki
    def create_container(self, container, account=None, meta={}, **headers):
299 25c3841c Sofia Papagiannaki
        """creates a container"""
300 95e92490 Sofia Papagiannaki
        account = account or self.account
301 5a8dc30c Sofia Papagiannaki
        if not headers:
302 5a8dc30c Sofia Papagiannaki
            headers = {}
303 bcb7c5a8 Sofia Papagiannaki
        for k,v in meta.items():
304 615e561b Sofia Papagiannaki
            headers['x-container-meta-%s' %k.strip().upper()] = v.strip()
305 95e92490 Sofia Papagiannaki
        status, header, data = self.put('/%s/%s' % (account, container),
306 95e92490 Sofia Papagiannaki
                                        headers=headers)
307 3f5b02c7 Sofia Papagiannaki
        if status == 202:
308 3f5b02c7 Sofia Papagiannaki
            return False
309 3f5b02c7 Sofia Papagiannaki
        elif status != 201:
310 e3fd7f91 Sofia Papagiannaki
            raise Fault(data, int(status))
311 3f5b02c7 Sofia Papagiannaki
        return True
312 f7ab99df Sofia Papagiannaki
    
313 95e92490 Sofia Papagiannaki
    def delete_container(self, container, params={}, account=None):
314 25c3841c Sofia Papagiannaki
        """deletes a container"""
315 95e92490 Sofia Papagiannaki
        account = account or self.account
316 95e92490 Sofia Papagiannaki
        return self.delete('/%s/%s' % (account, container), params=params)
317 f7ab99df Sofia Papagiannaki
    
318 95e92490 Sofia Papagiannaki
    def retrieve_container_metadata(self, container, restricted=False,
319 95e92490 Sofia Papagiannaki
                                    account=None, **params):
320 25c3841c Sofia Papagiannaki
        """returns the container metadata"""
321 95e92490 Sofia Papagiannaki
        account = account or self.account
322 f7ab99df Sofia Papagiannaki
        prefix = 'x-container-meta-' if restricted else None
323 95e92490 Sofia Papagiannaki
        return self._get_metadata('/%s/%s' % (account, container), prefix,
324 95e92490 Sofia Papagiannaki
                                  params)
325 f7ab99df Sofia Papagiannaki
    
326 95e92490 Sofia Papagiannaki
    def update_container_metadata(self, container, account=None, **meta):
327 25c3841c Sofia Papagiannaki
        """unpdates the container metadata"""
328 95e92490 Sofia Papagiannaki
        account = account or self.account
329 95e92490 Sofia Papagiannaki
        return self._update_metadata('/%s/%s' % (account, container),
330 95e92490 Sofia Papagiannaki
                                     'container', **meta)
331 f7ab99df Sofia Papagiannaki
        
332 95e92490 Sofia Papagiannaki
    def delete_container_metadata(self, container, meta=[], account=None):
333 25c3841c Sofia Papagiannaki
        """deletes the container metadata"""
334 95e92490 Sofia Papagiannaki
        account = account or self.account
335 95e92490 Sofia Papagiannaki
        path = '/%s/%s' % (account, container)
336 615e561b Sofia Papagiannaki
        return self._delete_metadata(path, 'container', meta)
337 f7ab99df Sofia Papagiannaki
    
338 3f5b02c7 Sofia Papagiannaki
    # Storage Object Services
339 f7ab99df Sofia Papagiannaki
    
340 f0eacc2c Sofia Papagiannaki
    def request_object(self, container, object, format='text', params={},
341 95e92490 Sofia Papagiannaki
                       account=None, **headers):
342 25c3841c Sofia Papagiannaki
        """returns tuple containing the status, headers and data response for an object request"""
343 95e92490 Sofia Papagiannaki
        account = account or self.account
344 95e92490 Sofia Papagiannaki
        path = '/%s/%s/%s' % (account, container, object)
345 8fe01d72 Sofia Papagiannaki
        status, headers, data = self.get(path, format, headers, params)
346 25c3841c Sofia Papagiannaki
        return status, headers, data
347 25c3841c Sofia Papagiannaki
    
348 f0eacc2c Sofia Papagiannaki
    def retrieve_object(self, container, object, format='text', params={},
349 95e92490 Sofia Papagiannaki
                        account=None, **headers):
350 25c3841c Sofia Papagiannaki
        """returns an object's data"""
351 95e92490 Sofia Papagiannaki
        account = account or self.account
352 95e92490 Sofia Papagiannaki
        t = self.request_object(container, object, format, params, account,
353 95e92490 Sofia Papagiannaki
                                **headers)
354 3078108a Sofia Papagiannaki
        data = t[2]
355 3078108a Sofia Papagiannaki
        if format == 'json':
356 3078108a Sofia Papagiannaki
            data = json.loads(data) if data else ''
357 3078108a Sofia Papagiannaki
        elif format == 'xml':
358 3078108a Sofia Papagiannaki
            data = minidom.parseString(data)
359 3078108a Sofia Papagiannaki
        return data
360 3078108a Sofia Papagiannaki
    
361 f9e723fd Sofia Papagiannaki
    def retrieve_object_hashmap(self, container, object, format='json', params={},
362 3078108a Sofia Papagiannaki
                        account=None, **headers):
363 3078108a Sofia Papagiannaki
        """returns the hashmap representing object's data"""
364 f9e723fd Sofia Papagiannaki
        if not params:
365 f9e723fd Sofia Papagiannaki
            params = {}
366 f9e723fd Sofia Papagiannaki
        params.update({'hashmap':None})
367 f9e723fd Sofia Papagiannaki
        return self.retrieve_object(container, object, params, format, account, **headers)
368 f7ab99df Sofia Papagiannaki
    
369 95e92490 Sofia Papagiannaki
    def create_directory_marker(self, container, object, account=None):
370 25c3841c Sofia Papagiannaki
        """creates a dierectory marker"""
371 95e92490 Sofia Papagiannaki
        account = account or self.account
372 f7ab99df Sofia Papagiannaki
        if not object:
373 f7ab99df Sofia Papagiannaki
            raise Fault('Directory markers have to be nested in a container')
374 7912c553 Sofia Papagiannaki
        h = {'content_type':'application/directory'}
375 95e92490 Sofia Papagiannaki
        return self.create_zero_length_object(container, object, account=account,
376 95e92490 Sofia Papagiannaki
                                              **h)
377 f7ab99df Sofia Papagiannaki
    
378 25c3841c Sofia Papagiannaki
    def create_object(self, container, object, f=stdin, format='text', meta={},
379 9471fece Sofia Papagiannaki
                      params={}, etag=None, content_type=None, content_encoding=None,
380 95e92490 Sofia Papagiannaki
                      content_disposition=None, account=None, **headers):
381 cd6ada1d Sofia Papagiannaki
        """creates a zero-length object"""
382 95e92490 Sofia Papagiannaki
        account = account or self.account
383 95e92490 Sofia Papagiannaki
        path = '/%s/%s/%s' % (account, container, object)
384 25c3841c Sofia Papagiannaki
        for k, v  in headers.items():
385 38bf2cdc Sofia Papagiannaki
            if v == None:
386 25c3841c Sofia Papagiannaki
                headers.pop(k)
387 25c3841c Sofia Papagiannaki
        
388 25c3841c Sofia Papagiannaki
        l = ['etag', 'content_encoding', 'content_disposition', 'content_type']
389 25c3841c Sofia Papagiannaki
        l = [elem for elem in l if eval(elem)]
390 25c3841c Sofia Papagiannaki
        for elem in l:
391 25c3841c Sofia Papagiannaki
            headers.update({elem:eval(elem)})
392 bcd29125 Sofia Papagiannaki
        headers.setdefault('content-type', 'application/octet-stream')
393 bcd29125 Sofia Papagiannaki
        
394 615e561b Sofia Papagiannaki
        for k,v in meta.items():
395 615e561b Sofia Papagiannaki
            headers['x-object-meta-%s' %k.strip()] = v.strip()
396 25c3841c Sofia Papagiannaki
        data = f.read() if f else None
397 9471fece Sofia Papagiannaki
        return self.put(path, data, format, headers=headers, params=params)
398 615e561b Sofia Papagiannaki
    
399 cd6ada1d Sofia Papagiannaki
    def create_zero_length_object(self, container, object, meta={}, etag=None,
400 cd6ada1d Sofia Papagiannaki
                                  content_type=None, content_encoding=None,
401 95e92490 Sofia Papagiannaki
                                  content_disposition=None, account=None,
402 95e92490 Sofia Papagiannaki
                                  **headers):
403 95e92490 Sofia Papagiannaki
        account = account or self.account
404 9471fece Sofia Papagiannaki
        args = locals().copy()
405 95e92490 Sofia Papagiannaki
        for elem in ['self', 'container', 'headers', 'account']:
406 cd6ada1d Sofia Papagiannaki
            args.pop(elem)
407 cd6ada1d Sofia Papagiannaki
        args.update(headers)
408 95e92490 Sofia Papagiannaki
        return self.create_object(container, account=account, f=None, **args)
409 95e92490 Sofia Papagiannaki
    
410 95e92490 Sofia Papagiannaki
    def update_object(self, container, object, f=stdin,
411 633bbb9f Sofia Papagiannaki
                      offset=None, meta={}, params={}, content_length=None,
412 95e92490 Sofia Papagiannaki
                      content_type=None, content_encoding=None,
413 95e92490 Sofia Papagiannaki
                      content_disposition=None,  account=None, **headers):
414 95e92490 Sofia Papagiannaki
        account = account or self.account
415 95e92490 Sofia Papagiannaki
        path = '/%s/%s/%s' % (account, container, object)
416 25c3841c Sofia Papagiannaki
        for k, v  in headers.items():
417 38bf2cdc Sofia Papagiannaki
            if v == None:
418 25c3841c Sofia Papagiannaki
                headers.pop(k)
419 25c3841c Sofia Papagiannaki
        
420 25c3841c Sofia Papagiannaki
        l = ['content_encoding', 'content_disposition', 'content_type',
421 25c3841c Sofia Papagiannaki
             'content_length']
422 25c3841c Sofia Papagiannaki
        l = [elem for elem in l if eval(elem)]
423 25c3841c Sofia Papagiannaki
        for elem in l:
424 25c3841c Sofia Papagiannaki
            headers.update({elem:eval(elem)})
425 48a1abe5 Sofia Papagiannaki
        
426 25c3841c Sofia Papagiannaki
        if 'content_range' not in headers.keys():
427 25c3841c Sofia Papagiannaki
            if offset != None:
428 25c3841c Sofia Papagiannaki
                headers['content_range'] = 'bytes %s-/*' % offset
429 25c3841c Sofia Papagiannaki
            else:
430 25c3841c Sofia Papagiannaki
                headers['content_range'] = 'bytes */*'
431 25c3841c Sofia Papagiannaki
            
432 bcb7c5a8 Sofia Papagiannaki
        for k,v in meta.items():
433 615e561b Sofia Papagiannaki
            headers['x-object-meta-%s' %k.strip()] = v.strip()
434 25c3841c Sofia Papagiannaki
        data = f.read() if f else None
435 633bbb9f Sofia Papagiannaki
        return self.post(path, data, headers=headers, params=params)
436 633bbb9f Sofia Papagiannaki
    
437 633bbb9f Sofia Papagiannaki
    def update_object_using_chunks(self, container, object, f=stdin,
438 633bbb9f Sofia Papagiannaki
                                   blocksize=1024, offset=None, meta={},
439 633bbb9f Sofia Papagiannaki
                                   params={}, content_type=None, content_encoding=None,
440 633bbb9f Sofia Papagiannaki
                                   content_disposition=None, account=None, **headers):
441 633bbb9f Sofia Papagiannaki
        """updates an object (incremental upload)"""
442 633bbb9f Sofia Papagiannaki
        account = account or self.account
443 633bbb9f Sofia Papagiannaki
        path = '/%s/%s/%s' % (account, container, object)
444 633bbb9f Sofia Papagiannaki
        headers = headers if not headers else {}
445 633bbb9f Sofia Papagiannaki
        l = ['content_type', 'content_encoding', 'content_disposition']
446 633bbb9f Sofia Papagiannaki
        l = [elem for elem in l if eval(elem)]
447 633bbb9f Sofia Papagiannaki
        for elem in l:
448 633bbb9f Sofia Papagiannaki
            headers.update({elem:eval(elem)})
449 633bbb9f Sofia Papagiannaki
        
450 633bbb9f Sofia Papagiannaki
        if offset != None:
451 633bbb9f Sofia Papagiannaki
            headers['content_range'] = 'bytes %s-/*' % offset
452 633bbb9f Sofia Papagiannaki
        else:
453 633bbb9f Sofia Papagiannaki
            headers['content_range'] = 'bytes */*'
454 633bbb9f Sofia Papagiannaki
        
455 633bbb9f Sofia Papagiannaki
        for k,v in meta.items():
456 633bbb9f Sofia Papagiannaki
            v = v.strip()
457 633bbb9f Sofia Papagiannaki
            headers['x-object-meta-%s' %k.strip()] = v
458 633bbb9f Sofia Papagiannaki
        return self._chunked_transfer(path, 'POST', f, headers=headers,
459 633bbb9f Sofia Papagiannaki
                                      blocksize=blocksize, params=params)
460 f7ab99df Sofia Papagiannaki
    
461 ec1b8d3e Sofia Papagiannaki
    def _change_obj_location(self, src_container, src_object, dst_container,
462 95e92490 Sofia Papagiannaki
                             dst_object, remove=False, meta={}, account=None,
463 db117cac Sofia Papagiannaki
                             content_type=None, delimiter=None, **headers):
464 95e92490 Sofia Papagiannaki
        account = account or self.account
465 95e92490 Sofia Papagiannaki
        path = '/%s/%s/%s' % (account, dst_container, dst_object)
466 7812e1f9 Sofia Papagiannaki
        headers = {} if not headers else headers
467 53cff70c Antony Chazapis
        params = {}
468 615e561b Sofia Papagiannaki
        for k, v in meta.items():
469 ae75584f Sofia Papagiannaki
            headers['x-object-meta-%s' % k] = v
470 ec1b8d3e Sofia Papagiannaki
        if remove:
471 615e561b Sofia Papagiannaki
            headers['x-move-from'] = '/%s/%s' % (src_container, src_object)
472 ec1b8d3e Sofia Papagiannaki
        else:
473 615e561b Sofia Papagiannaki
            headers['x-copy-from'] = '/%s/%s' % (src_container, src_object)
474 7812e1f9 Sofia Papagiannaki
        headers['content_length'] = 0
475 d4a63b9b Sofia Papagiannaki
        if content_type:
476 53cff70c Antony Chazapis
            headers['content_type'] = content_type
477 53cff70c Antony Chazapis
        else:
478 53cff70c Antony Chazapis
            params['ignore_content_type'] = ''
479 db117cac Sofia Papagiannaki
        if delimiter:
480 db117cac Sofia Papagiannaki
                params['delimiter'] = delimiter
481 53cff70c Antony Chazapis
        return self.put(path, headers=headers, params=params)
482 f7ab99df Sofia Papagiannaki
    
483 7812e1f9 Sofia Papagiannaki
    def copy_object(self, src_container, src_object, dst_container, dst_object,
484 db117cac Sofia Papagiannaki
                   meta={}, account=None, content_type=None, delimiter=None, **headers):
485 7812e1f9 Sofia Papagiannaki
        """copies an object"""
486 95e92490 Sofia Papagiannaki
        account = account or self.account
487 615e561b Sofia Papagiannaki
        return self._change_obj_location(src_container, src_object,
488 95e92490 Sofia Papagiannaki
                                   dst_container, dst_object, account=account,
489 d4a63b9b Sofia Papagiannaki
                                   remove=False, meta=meta,
490 db117cac Sofia Papagiannaki
                                   content_type=content_type, delimiter=delimiter, **headers)
491 f7ab99df Sofia Papagiannaki
    
492 ec1b8d3e Sofia Papagiannaki
    def move_object(self, src_container, src_object, dst_container,
493 95e92490 Sofia Papagiannaki
                             dst_object, meta={}, account=None,
494 d4a63b9b Sofia Papagiannaki
                             content_type=None, **headers):
495 7812e1f9 Sofia Papagiannaki
        """moves an object"""
496 95e92490 Sofia Papagiannaki
        account = account or self.account
497 615e561b Sofia Papagiannaki
        return self._change_obj_location(src_container, src_object,
498 95e92490 Sofia Papagiannaki
                                         dst_container, dst_object,
499 95e92490 Sofia Papagiannaki
                                         account=account, remove=True,
500 d4a63b9b Sofia Papagiannaki
                                         meta=meta, content_type=content_type,
501 d4a63b9b Sofia Papagiannaki
                                         **headers)
502 f7ab99df Sofia Papagiannaki
    
503 95e92490 Sofia Papagiannaki
    def delete_object(self, container, object, params={}, account=None):
504 7812e1f9 Sofia Papagiannaki
        """deletes an object"""
505 95e92490 Sofia Papagiannaki
        account = account or self.account
506 95e92490 Sofia Papagiannaki
        return self.delete('/%s/%s/%s' % (account, container, object),
507 95e92490 Sofia Papagiannaki
                           params=params)
508 f7ab99df Sofia Papagiannaki
    
509 8fe01d72 Sofia Papagiannaki
    def retrieve_object_metadata(self, container, object, restricted=False,
510 95e92490 Sofia Papagiannaki
                                 version=None, account=None):
511 615e561b Sofia Papagiannaki
        """
512 615e561b Sofia Papagiannaki
        set restricted to True to get only user defined metadata
513 615e561b Sofia Papagiannaki
        """
514 95e92490 Sofia Papagiannaki
        account = account or self.account
515 95e92490 Sofia Papagiannaki
        path = '/%s/%s/%s' % (account, container, object)
516 f7ab99df Sofia Papagiannaki
        prefix = 'x-object-meta-' if restricted else None
517 25c3841c Sofia Papagiannaki
        params = {'version':version} if version else {}
518 8fe01d72 Sofia Papagiannaki
        return self._get_metadata(path, prefix, params=params)
519 f7ab99df Sofia Papagiannaki
    
520 95e92490 Sofia Papagiannaki
    def update_object_metadata(self, container, object, account=None,
521 95e92490 Sofia Papagiannaki
                               **meta):
522 e7b51248 Sofia Papagiannaki
        """
523 e7b51248 Sofia Papagiannaki
        updates object's metadata
524 e7b51248 Sofia Papagiannaki
        """
525 95e92490 Sofia Papagiannaki
        account = account or self.account
526 95e92490 Sofia Papagiannaki
        path = '/%s/%s/%s' % (account, container, object)
527 615e561b Sofia Papagiannaki
        return self._update_metadata(path, 'object', **meta)
528 f7ab99df Sofia Papagiannaki
    
529 95e92490 Sofia Papagiannaki
    def delete_object_metadata(self, container, object, meta=[], account=None):
530 e7b51248 Sofia Papagiannaki
        """
531 e7b51248 Sofia Papagiannaki
        deletes object's metadata
532 e7b51248 Sofia Papagiannaki
        """
533 95e92490 Sofia Papagiannaki
        account = account or self.account
534 95e92490 Sofia Papagiannaki
        path = '/%s/%s' % (account, container, object)
535 615e561b Sofia Papagiannaki
        return self._delete_metadata(path, 'object', meta)
536 f7ab99df Sofia Papagiannaki
    
537 25c3841c Sofia Papagiannaki
class Pithos_Client(OOS_Client):
538 25c3841c Sofia Papagiannaki
    """Pithos Storage Client. Extends OOS_Client"""
539 25c3841c Sofia Papagiannaki
    
540 25c3841c Sofia Papagiannaki
    def _update_metadata(self, path, entity, **meta):
541 25c3841c Sofia Papagiannaki
        """
542 25c3841c Sofia Papagiannaki
        adds new and updates the values of previously set metadata
543 25c3841c Sofia Papagiannaki
        """
544 25c3841c Sofia Papagiannaki
        params = {'update':None}
545 25c3841c Sofia Papagiannaki
        headers = {}
546 25c3841c Sofia Papagiannaki
        prefix = 'x-%s-meta-' % entity
547 25c3841c Sofia Papagiannaki
        for k,v in meta.items():
548 25c3841c Sofia Papagiannaki
            k = '%s%s' % (prefix, k)
549 25c3841c Sofia Papagiannaki
            headers[k] = v
550 25c3841c Sofia Papagiannaki
        return self.post(path, headers=headers, params=params)
551 25c3841c Sofia Papagiannaki
    
552 25c3841c Sofia Papagiannaki
    def _delete_metadata(self, path, entity, meta=[]):
553 f7ab99df Sofia Papagiannaki
        """
554 25c3841c Sofia Papagiannaki
        delete previously set metadata
555 f7ab99df Sofia Papagiannaki
        """
556 25c3841c Sofia Papagiannaki
        params = {'update':None}
557 25c3841c Sofia Papagiannaki
        headers = {}
558 25c3841c Sofia Papagiannaki
        prefix = 'x-%s-meta-' % entity
559 25c3841c Sofia Papagiannaki
        for m in meta:
560 f0eacc2c Sofia Papagiannaki
            headers['%s%s' % (prefix, m)] = ''
561 25c3841c Sofia Papagiannaki
        return self.post(path, headers=headers, params=params)
562 25c3841c Sofia Papagiannaki
    
563 25c3841c Sofia Papagiannaki
    # Storage Account Services
564 25c3841c Sofia Papagiannaki
    
565 f0eacc2c Sofia Papagiannaki
    def list_containers(self, format='text', if_modified_since=None,
566 3bceebbe Sofia Papagiannaki
                        if_unmodified_since=None, limit=None, marker=None,
567 2535deff Sofia Papagiannaki
                        shared=False, until=None, account=None, public=False):
568 25c3841c Sofia Papagiannaki
        """returns a list with the account containers"""
569 95e92490 Sofia Papagiannaki
        account = account or self.account
570 ae75584f Sofia Papagiannaki
        params = {'until':until} if until else {}
571 8d964102 Sofia Papagiannaki
        if shared:
572 8d964102 Sofia Papagiannaki
            params['shared'] = None
573 2535deff Sofia Papagiannaki
        if public:
574 2535deff Sofia Papagiannaki
            params['public'] = None
575 25c3841c Sofia Papagiannaki
        headers = {'if-modified-since':if_modified_since,
576 25c3841c Sofia Papagiannaki
                   'if-unmodified-since':if_unmodified_since}
577 95e92490 Sofia Papagiannaki
        return OOS_Client.list_containers(self, account=account, format=format,
578 95e92490 Sofia Papagiannaki
                                          limit=limit, marker=marker,
579 95e92490 Sofia Papagiannaki
                                          params=params, **headers)
580 25c3841c Sofia Papagiannaki
    
581 95e92490 Sofia Papagiannaki
    def retrieve_account_metadata(self, restricted=False, until=None,
582 95e92490 Sofia Papagiannaki
                                  account=None):
583 25c3841c Sofia Papagiannaki
        """returns the account metadata"""
584 95e92490 Sofia Papagiannaki
        account = account or self.account
585 25c3841c Sofia Papagiannaki
        params = {'until':until} if until else {}
586 95e92490 Sofia Papagiannaki
        return OOS_Client.retrieve_account_metadata(self, account=account,
587 95e92490 Sofia Papagiannaki
                                                    restricted=restricted,
588 95e92490 Sofia Papagiannaki
                                                    **params)
589 25c3841c Sofia Papagiannaki
    
590 95e92490 Sofia Papagiannaki
    def set_account_groups(self, account=None, **groups):
591 25c3841c Sofia Papagiannaki
        """create account groups"""
592 95e92490 Sofia Papagiannaki
        account = account or self.account
593 95e92490 Sofia Papagiannaki
        path = '/%s' % account
594 25c3841c Sofia Papagiannaki
        headers = {}
595 ae75584f Sofia Papagiannaki
        for k, v in groups.items():
596 ae75584f Sofia Papagiannaki
            headers['x-account-group-%s' % k] = v
597 25c3841c Sofia Papagiannaki
        params = {'update':None}
598 95e92490 Sofia Papagiannaki
        return self.post(path, headers=headers, params=params)
599 25c3841c Sofia Papagiannaki
    
600 95e92490 Sofia Papagiannaki
    def retrieve_account_groups(self, account=None):
601 b9ca81a0 Sofia Papagiannaki
        """returns the account groups"""
602 95e92490 Sofia Papagiannaki
        account = account or self.account
603 95e92490 Sofia Papagiannaki
        meta = self.retrieve_account_metadata(account=account)
604 b9ca81a0 Sofia Papagiannaki
        prefix = 'x-account-group-'
605 b9ca81a0 Sofia Papagiannaki
        prefixlen = len(prefix)
606 b9ca81a0 Sofia Papagiannaki
        groups = {}
607 b9ca81a0 Sofia Papagiannaki
        for key, val in meta.items():
608 b9ca81a0 Sofia Papagiannaki
            if prefix and not key.startswith(prefix):
609 b9ca81a0 Sofia Papagiannaki
                continue
610 b9ca81a0 Sofia Papagiannaki
            elif prefix and key.startswith(prefix):
611 b9ca81a0 Sofia Papagiannaki
                key = key[prefixlen:]
612 b9ca81a0 Sofia Papagiannaki
            groups[key] = val
613 b9ca81a0 Sofia Papagiannaki
        return groups
614 b9ca81a0 Sofia Papagiannaki
    
615 95e92490 Sofia Papagiannaki
    def unset_account_groups(self, groups=[], account=None):
616 25c3841c Sofia Papagiannaki
        """delete account groups"""
617 95e92490 Sofia Papagiannaki
        account = account or self.account
618 95e92490 Sofia Papagiannaki
        path = '/%s' % account
619 25c3841c Sofia Papagiannaki
        headers = {}
620 25c3841c Sofia Papagiannaki
        for elem in groups:
621 25c3841c Sofia Papagiannaki
            headers['x-account-group-%s' % elem] = ''
622 25c3841c Sofia Papagiannaki
        params = {'update':None}
623 95e92490 Sofia Papagiannaki
        return self.post(path, headers=headers, params=params)
624 25c3841c Sofia Papagiannaki
    
625 95e92490 Sofia Papagiannaki
    def reset_account_groups(self, account=None, **groups):
626 cd6ada1d Sofia Papagiannaki
        """overrides account groups"""
627 95e92490 Sofia Papagiannaki
        account = account or self.account
628 95e92490 Sofia Papagiannaki
        path = '/%s' % account
629 cd6ada1d Sofia Papagiannaki
        headers = {}
630 ae75584f Sofia Papagiannaki
        for k, v in groups.items():
631 ae75584f Sofia Papagiannaki
            v = v.strip()
632 ae75584f Sofia Papagiannaki
            headers['x-account-group-%s' % k] = v
633 e7b51248 Sofia Papagiannaki
        meta = self.retrieve_account_metadata(restricted=True)
634 e7b51248 Sofia Papagiannaki
        prefix = 'x-account-meta-'
635 e7b51248 Sofia Papagiannaki
        for k,v in meta.items():
636 e7b51248 Sofia Papagiannaki
            k = '%s%s' % (prefix, k)
637 e7b51248 Sofia Papagiannaki
            headers[k] = v
638 95e92490 Sofia Papagiannaki
        return self.post(path, headers=headers)
639 cd6ada1d Sofia Papagiannaki
    
640 25c3841c Sofia Papagiannaki
    # Storage Container Services
641 5a8dc30c Sofia Papagiannaki
    def create_container(self, container, account=None, meta={}, policies={}):
642 5a8dc30c Sofia Papagiannaki
        """creates a container"""
643 5a8dc30c Sofia Papagiannaki
        args = {}
644 5a8dc30c Sofia Papagiannaki
        for k, v in policies.items():
645 5a8dc30c Sofia Papagiannaki
            args['X-Container-Policy-%s' % k.capitalize()] = v
646 5a8dc30c Sofia Papagiannaki
        return OOS_Client.create_container(self, container, account, meta, **args)
647 25c3841c Sofia Papagiannaki
    
648 95e92490 Sofia Papagiannaki
    def list_objects(self, container, format='text',
649 95e92490 Sofia Papagiannaki
                     limit=None, marker=None, prefix=None, delimiter=None,
650 8d964102 Sofia Papagiannaki
                     path=None, shared=False, include_trashed=False, params={},
651 95e92490 Sofia Papagiannaki
                     if_modified_since=None, if_unmodified_since=None, meta='',
652 2535deff Sofia Papagiannaki
                     until=None, account=None, public=False):
653 25c3841c Sofia Papagiannaki
        """returns a list with the container objects"""
654 95e92490 Sofia Papagiannaki
        account = account or self.account
655 25c3841c Sofia Papagiannaki
        params = {'until':until, 'meta':meta}
656 8d964102 Sofia Papagiannaki
        if shared:
657 8d964102 Sofia Papagiannaki
            params['shared'] = None
658 2535deff Sofia Papagiannaki
        if public:
659 2535deff Sofia Papagiannaki
            params['public'] = None
660 9471fece Sofia Papagiannaki
        args = locals().copy()
661 25c3841c Sofia Papagiannaki
        for elem in ['self', 'container', 'params', 'until', 'meta']:
662 25c3841c Sofia Papagiannaki
            args.pop(elem)
663 95e92490 Sofia Papagiannaki
        return OOS_Client.list_objects(self, container, params=params, **args)
664 25c3841c Sofia Papagiannaki
    
665 25c3841c Sofia Papagiannaki
    def retrieve_container_metadata(self, container, restricted=False,
666 95e92490 Sofia Papagiannaki
                                    until=None, account=None):
667 25c3841c Sofia Papagiannaki
        """returns container's metadata"""
668 95e92490 Sofia Papagiannaki
        account = account or self.account
669 25c3841c Sofia Papagiannaki
        params = {'until':until} if until else {}
670 25c3841c Sofia Papagiannaki
        return OOS_Client.retrieve_container_metadata(self, container,
671 95e92490 Sofia Papagiannaki
                                                      account=account,
672 25c3841c Sofia Papagiannaki
                                                      restricted=restricted,
673 25c3841c Sofia Papagiannaki
                                                      **params)
674 25c3841c Sofia Papagiannaki
    
675 95e92490 Sofia Papagiannaki
    def set_container_policies(self, container, account=None,
676 95e92490 Sofia Papagiannaki
                               **policies):
677 25c3841c Sofia Papagiannaki
        """sets containers policies"""
678 95e92490 Sofia Papagiannaki
        account = account or self.account
679 95e92490 Sofia Papagiannaki
        path = '/%s/%s' % (account, container)
680 25c3841c Sofia Papagiannaki
        headers = {}
681 25c3841c Sofia Papagiannaki
        for key, val in policies.items():
682 25c3841c Sofia Papagiannaki
            headers['x-container-policy-%s' % key] = val
683 25c3841c Sofia Papagiannaki
        return self.post(path, headers=headers)
684 25c3841c Sofia Papagiannaki
    
685 6d897a63 Antony Chazapis
    def update_container_data(self, container, f=stdin):
686 6d897a63 Antony Chazapis
        """adds blocks of data to the container"""
687 6d897a63 Antony Chazapis
        account = self.account
688 6d897a63 Antony Chazapis
        path = '/%s/%s' % (account, container)
689 6d897a63 Antony Chazapis
        params = {'update': None}
690 6d897a63 Antony Chazapis
        headers = {'content_type': 'application/octet-stream'}
691 6d897a63 Antony Chazapis
        data = f.read() if f else None
692 6d897a63 Antony Chazapis
        headers['content_length'] = len(data)
693 6d897a63 Antony Chazapis
        return self.post(path, data, headers=headers, params=params)
694 6d897a63 Antony Chazapis
    
695 95e92490 Sofia Papagiannaki
    def delete_container(self, container, until=None, account=None):
696 25c3841c Sofia Papagiannaki
        """deletes a container or the container history until the date provided"""
697 95e92490 Sofia Papagiannaki
        account = account or self.account
698 25c3841c Sofia Papagiannaki
        params = {'until':until} if until else {}
699 95e92490 Sofia Papagiannaki
        return OOS_Client.delete_container(self, container, account=account,
700 95e92490 Sofia Papagiannaki
                                           params=params)
701 25c3841c Sofia Papagiannaki
    
702 25c3841c Sofia Papagiannaki
    # Storage Object Services
703 25c3841c Sofia Papagiannaki
    
704 95e92490 Sofia Papagiannaki
    def retrieve_object(self, container, object, params={}, format='text',
705 95e92490 Sofia Papagiannaki
                        range=None, if_range=None,
706 95e92490 Sofia Papagiannaki
                        if_match=None, if_none_match=None,
707 25c3841c Sofia Papagiannaki
                        if_modified_since=None, if_unmodified_since=None,
708 95e92490 Sofia Papagiannaki
                        account=None, **headers):
709 25c3841c Sofia Papagiannaki
        """returns an object"""
710 95e92490 Sofia Papagiannaki
        account = account or self.account
711 25c3841c Sofia Papagiannaki
        headers={}
712 25c3841c Sofia Papagiannaki
        l = ['range', 'if_range', 'if_match', 'if_none_match',
713 25c3841c Sofia Papagiannaki
             'if_modified_since', 'if_unmodified_since']
714 25c3841c Sofia Papagiannaki
        l = [elem for elem in l if eval(elem)]
715 25c3841c Sofia Papagiannaki
        for elem in l:
716 25c3841c Sofia Papagiannaki
            headers.update({elem:eval(elem)})
717 9471fece Sofia Papagiannaki
        if format != 'text':
718 9471fece Sofia Papagiannaki
            params['hashmap'] = None
719 95e92490 Sofia Papagiannaki
        return OOS_Client.retrieve_object(self, container, object,
720 95e92490 Sofia Papagiannaki
                                          account=account, format=format,
721 25c3841c Sofia Papagiannaki
                                          params=params, **headers)
722 25c3841c Sofia Papagiannaki
    
723 95e92490 Sofia Papagiannaki
    def retrieve_object_version(self, container, object, version,
724 7f769d34 Sofia Papagiannaki
                                format='text', range=None, if_range=None,
725 95e92490 Sofia Papagiannaki
                                if_match=None, if_none_match=None,
726 95e92490 Sofia Papagiannaki
                                if_modified_since=None, if_unmodified_since=None,
727 95e92490 Sofia Papagiannaki
                                account=None):
728 25c3841c Sofia Papagiannaki
        """returns a specific object version"""
729 95e92490 Sofia Papagiannaki
        account = account or self.account
730 9471fece Sofia Papagiannaki
        args = locals().copy()
731 25c3841c Sofia Papagiannaki
        l = ['self', 'container', 'object']
732 25c3841c Sofia Papagiannaki
        for elem in l:
733 25c3841c Sofia Papagiannaki
            args.pop(elem)
734 25c3841c Sofia Papagiannaki
        params = {'version':version}
735 95e92490 Sofia Papagiannaki
        return self.retrieve_object(container, object, params=params, **args)
736 25c3841c Sofia Papagiannaki
    
737 25c3841c Sofia Papagiannaki
    def retrieve_object_versionlist(self, container, object, range=None,
738 25c3841c Sofia Papagiannaki
                                    if_range=None, if_match=None,
739 25c3841c Sofia Papagiannaki
                                    if_none_match=None, if_modified_since=None,
740 95e92490 Sofia Papagiannaki
                                    if_unmodified_since=None, account=None):
741 25c3841c Sofia Papagiannaki
        """returns the object version list"""
742 95e92490 Sofia Papagiannaki
        account = account or self.account
743 9471fece Sofia Papagiannaki
        args = locals().copy()
744 25c3841c Sofia Papagiannaki
        l = ['self', 'container', 'object']
745 25c3841c Sofia Papagiannaki
        for elem in l:
746 25c3841c Sofia Papagiannaki
            args.pop(elem)
747 8d964102 Sofia Papagiannaki
        
748 25c3841c Sofia Papagiannaki
        return self.retrieve_object_version(container, object, version='list',
749 7f769d34 Sofia Papagiannaki
                                            format='json', **args)
750 25c3841c Sofia Papagiannaki
    
751 95e92490 Sofia Papagiannaki
    def create_zero_length_object(self, container, object,
752 95e92490 Sofia Papagiannaki
                                  meta={}, etag=None, content_type=None,
753 95e92490 Sofia Papagiannaki
                                  content_encoding=None,
754 95e92490 Sofia Papagiannaki
                                  content_disposition=None,
755 95e92490 Sofia Papagiannaki
                                  x_object_manifest=None, x_object_sharing=None,
756 95e92490 Sofia Papagiannaki
                                  x_object_public=None, account=None):
757 cd6ada1d Sofia Papagiannaki
        """createas a zero length object"""
758 95e92490 Sofia Papagiannaki
        account = account or self.account
759 9471fece Sofia Papagiannaki
        args = locals().copy()
760 cd6ada1d Sofia Papagiannaki
        for elem in ['self', 'container', 'object']:
761 cd6ada1d Sofia Papagiannaki
            args.pop(elem)
762 cd6ada1d Sofia Papagiannaki
        return OOS_Client.create_zero_length_object(self, container, object,
763 cd6ada1d Sofia Papagiannaki
                                                    **args)
764 cd6ada1d Sofia Papagiannaki
    
765 9471fece Sofia Papagiannaki
    def create_object(self, container, object, f=stdin, format='text',
766 9471fece Sofia Papagiannaki
                      meta={}, params={}, etag=None, content_type=None,
767 95e92490 Sofia Papagiannaki
                      content_encoding=None, content_disposition=None,
768 95e92490 Sofia Papagiannaki
                      x_object_manifest=None, x_object_sharing=None,
769 95e92490 Sofia Papagiannaki
                      x_object_public=None, account=None):
770 25c3841c Sofia Papagiannaki
        """creates an object"""
771 95e92490 Sofia Papagiannaki
        account = account or self.account
772 9471fece Sofia Papagiannaki
        args = locals().copy()
773 25c3841c Sofia Papagiannaki
        for elem in ['self', 'container', 'object']:
774 25c3841c Sofia Papagiannaki
            args.pop(elem)
775 e871c3b1 Sofia Papagiannaki
        if format != 'text':
776 e871c3b1 Sofia Papagiannaki
            params.update({'hashmap':None})
777 25c3841c Sofia Papagiannaki
        return OOS_Client.create_object(self, container, object, **args)
778 25c3841c Sofia Papagiannaki
        
779 95e92490 Sofia Papagiannaki
    def create_object_using_chunks(self, container, object,
780 95e92490 Sofia Papagiannaki
                                   f=stdin, blocksize=1024, meta={}, etag=None,
781 95e92490 Sofia Papagiannaki
                                   content_type=None, content_encoding=None,
782 95e92490 Sofia Papagiannaki
                                   content_disposition=None,
783 95e92490 Sofia Papagiannaki
                                   x_object_sharing=None, x_object_manifest=None,
784 95e92490 Sofia Papagiannaki
                                   x_object_public=None, account=None):
785 25c3841c Sofia Papagiannaki
        """creates an object (incremental upload)"""
786 95e92490 Sofia Papagiannaki
        account = account or self.account
787 95e92490 Sofia Papagiannaki
        path = '/%s/%s/%s' % (account, container, object)
788 25c3841c Sofia Papagiannaki
        headers = {}
789 25c3841c Sofia Papagiannaki
        l = ['etag', 'content_type', 'content_encoding', 'content_disposition', 
790 25c3841c Sofia Papagiannaki
             'x_object_sharing', 'x_object_manifest', 'x_object_public']
791 25c3841c Sofia Papagiannaki
        l = [elem for elem in l if eval(elem)]
792 25c3841c Sofia Papagiannaki
        for elem in l:
793 25c3841c Sofia Papagiannaki
            headers.update({elem:eval(elem)})
794 bcd29125 Sofia Papagiannaki
        headers.setdefault('content-type', 'application/octet-stream')
795 25c3841c Sofia Papagiannaki
        
796 25c3841c Sofia Papagiannaki
        for k,v in meta.items():
797 ae75584f Sofia Papagiannaki
            v = v.strip()
798 ae75584f Sofia Papagiannaki
            headers['x-object-meta-%s' %k.strip()] = v
799 25c3841c Sofia Papagiannaki
        
800 25c3841c Sofia Papagiannaki
        return self._chunked_transfer(path, 'PUT', f, headers=headers,
801 25c3841c Sofia Papagiannaki
                                      blocksize=blocksize)
802 25c3841c Sofia Papagiannaki
    
803 9471fece Sofia Papagiannaki
    def create_object_by_hashmap(self, container, object, hashmap={},
804 25c3841c Sofia Papagiannaki
                                 meta={}, etag=None, content_encoding=None,
805 25c3841c Sofia Papagiannaki
                                 content_disposition=None, content_type=None,
806 25c3841c Sofia Papagiannaki
                                 x_object_sharing=None, x_object_manifest=None,
807 95e92490 Sofia Papagiannaki
                                 x_object_public = None, account=None):
808 25c3841c Sofia Papagiannaki
        """creates an object by uploading hashes representing data instead of data"""
809 95e92490 Sofia Papagiannaki
        account = account or self.account
810 9471fece Sofia Papagiannaki
        args = locals().copy()
811 9471fece Sofia Papagiannaki
        for elem in ['self', 'container', 'object', 'hashmap']:
812 25c3841c Sofia Papagiannaki
            args.pop(elem)
813 25c3841c Sofia Papagiannaki
            
814 9471fece Sofia Papagiannaki
        try:
815 9471fece Sofia Papagiannaki
            data = json.dumps(hashmap)
816 9471fece Sofia Papagiannaki
        except SyntaxError:
817 9471fece Sofia Papagiannaki
            raise Fault('Invalid formatting')
818 9471fece Sofia Papagiannaki
        args['params'] = {'hashmap':None}
819 9471fece Sofia Papagiannaki
        args['format'] = 'json'
820 25c3841c Sofia Papagiannaki
        
821 9471fece Sofia Papagiannaki
        return self.create_object(container, object, f=StringIO(data), **args)
822 25c3841c Sofia Papagiannaki
    
823 95e92490 Sofia Papagiannaki
    def create_manifestation(self, container, object, manifest, account=None):
824 25c3841c Sofia Papagiannaki
        """creates a manifestation"""
825 95e92490 Sofia Papagiannaki
        account = account or self.account
826 25c3841c Sofia Papagiannaki
        headers={'x_object_manifest':manifest}
827 95e92490 Sofia Papagiannaki
        return self.create_object(container, object, f=None, account=account,
828 95e92490 Sofia Papagiannaki
                                  **headers)
829 25c3841c Sofia Papagiannaki
    
830 95e92490 Sofia Papagiannaki
    def update_object(self, container, object, f=stdin,
831 633bbb9f Sofia Papagiannaki
                      offset=None, meta={}, replace=False, content_length=None,
832 95e92490 Sofia Papagiannaki
                      content_type=None, content_range=None,
833 25c3841c Sofia Papagiannaki
                      content_encoding=None, content_disposition=None,
834 25c3841c Sofia Papagiannaki
                      x_object_bytes=None, x_object_manifest=None,
835 a5149fd0 Sofia Papagiannaki
                      x_object_sharing=None, x_object_public=None,
836 a5149fd0 Sofia Papagiannaki
                      x_source_object=None, account=None):
837 25c3841c Sofia Papagiannaki
        """updates an object"""
838 95e92490 Sofia Papagiannaki
        account = account or self.account
839 9471fece Sofia Papagiannaki
        args = locals().copy()
840 633bbb9f Sofia Papagiannaki
        for elem in ['self', 'container', 'object', 'replace']:
841 25c3841c Sofia Papagiannaki
            args.pop(elem)
842 633bbb9f Sofia Papagiannaki
        if not replace:
843 633bbb9f Sofia Papagiannaki
            args['params'] = {'update':None}
844 25c3841c Sofia Papagiannaki
        return OOS_Client.update_object(self, container, object, **args)
845 633bbb9f Sofia Papagiannaki
    
846 25c3841c Sofia Papagiannaki
    def update_object_using_chunks(self, container, object, f=stdin,
847 95e92490 Sofia Papagiannaki
                                   blocksize=1024, offset=None, meta={},
848 633bbb9f Sofia Papagiannaki
                                   replace=False, content_type=None, content_encoding=None,
849 95e92490 Sofia Papagiannaki
                                   content_disposition=None, x_object_bytes=None,
850 95e92490 Sofia Papagiannaki
                                   x_object_manifest=None, x_object_sharing=None,
851 95e92490 Sofia Papagiannaki
                                   x_object_public=None, account=None):
852 25c3841c Sofia Papagiannaki
        """updates an object (incremental upload)"""
853 95e92490 Sofia Papagiannaki
        account = account or self.account
854 9471fece Sofia Papagiannaki
        args = locals().copy()
855 633bbb9f Sofia Papagiannaki
        for elem in ['self', 'container', 'object', 'replace']:
856 633bbb9f Sofia Papagiannaki
            args.pop(elem)
857 633bbb9f Sofia Papagiannaki
        if not replace:
858 633bbb9f Sofia Papagiannaki
            args['params'] = {'update':None}
859 633bbb9f Sofia Papagiannaki
        return OOS_Client.update_object_using_chunks(self, container, object, **args)
860 25c3841c Sofia Papagiannaki
    
861 a5149fd0 Sofia Papagiannaki
    def update_from_other_source(self, container, object, source,
862 a5149fd0 Sofia Papagiannaki
                      offset=None, meta={}, content_range=None,
863 a5149fd0 Sofia Papagiannaki
                      content_encoding=None, content_disposition=None,
864 a5149fd0 Sofia Papagiannaki
                      x_object_bytes=None, x_object_manifest=None,
865 a5149fd0 Sofia Papagiannaki
                      x_object_sharing=None, x_object_public=None, account=None):
866 a5149fd0 Sofia Papagiannaki
        """updates an object"""
867 a5149fd0 Sofia Papagiannaki
        account = account or self.account
868 9471fece Sofia Papagiannaki
        args = locals().copy()
869 a5149fd0 Sofia Papagiannaki
        for elem in ['self', 'container', 'object', 'source']:
870 a5149fd0 Sofia Papagiannaki
            args.pop(elem)
871 a5149fd0 Sofia Papagiannaki
        
872 a5149fd0 Sofia Papagiannaki
        args['x_source_object'] = source
873 a5149fd0 Sofia Papagiannaki
        return self.update_object(container, object, f=None, **args)
874 a5149fd0 Sofia Papagiannaki
    
875 db117cac Sofia Papagiannaki
    def delete_object(self, container, object, until=None, account=None, delimiter=None):
876 25c3841c Sofia Papagiannaki
        """deletes an object or the object history until the date provided"""
877 95e92490 Sofia Papagiannaki
        account = account or self.account
878 25c3841c Sofia Papagiannaki
        params = {'until':until} if until else {}
879 db117cac Sofia Papagiannaki
        if delimiter:
880 db117cac Sofia Papagiannaki
                params['delimiter'] = delimiter
881 95e92490 Sofia Papagiannaki
        return OOS_Client.delete_object(self, container, object, params, account)
882 25c3841c Sofia Papagiannaki
    
883 25c3841c Sofia Papagiannaki
    def trash_object(self, container, object):
884 25c3841c Sofia Papagiannaki
        """trashes an object"""
885 95e92490 Sofia Papagiannaki
        account = account or self.account
886 f7ab99df Sofia Papagiannaki
        path = '/%s/%s' % (container, object)
887 f7ab99df Sofia Papagiannaki
        meta = {'trash':'true'}
888 615e561b Sofia Papagiannaki
        return self._update_metadata(path, 'object', **meta)
889 f7ab99df Sofia Papagiannaki
    
890 95e92490 Sofia Papagiannaki
    def restore_object(self, container, object, account=None):
891 25c3841c Sofia Papagiannaki
        """restores a trashed object"""
892 95e92490 Sofia Papagiannaki
        account = account or self.account
893 95e92490 Sofia Papagiannaki
        return self.delete_object_metadata(container, object, account, ['trash'])
894 f89e3cf4 Sofia Papagiannaki
    
895 95e92490 Sofia Papagiannaki
    def publish_object(self, container, object, account=None):
896 25c3841c Sofia Papagiannaki
        """sets a previously created object publicly accessible"""
897 95e92490 Sofia Papagiannaki
        account = account or self.account
898 35d50a81 Antony Chazapis
        path = '/%s/%s/%s' % (account, container, object)
899 88e015a3 Antony Chazapis
        headers = {}
900 7812e1f9 Sofia Papagiannaki
        headers['x_object_public'] = True
901 88e015a3 Antony Chazapis
        params = {'update':None}
902 88e015a3 Antony Chazapis
        return self.post(path, headers=headers, params=params)
903 f89e3cf4 Sofia Papagiannaki
    
904 95e92490 Sofia Papagiannaki
    def unpublish_object(self, container, object, account=None):
905 25c3841c Sofia Papagiannaki
        """unpublish an object"""
906 95e92490 Sofia Papagiannaki
        account = account or self.account
907 95e92490 Sofia Papagiannaki
        path = '/%s/%s/%s' % (account, container, object)
908 88e015a3 Antony Chazapis
        headers = {}
909 7812e1f9 Sofia Papagiannaki
        headers['x_object_public'] = False
910 88e015a3 Antony Chazapis
        params = {'update':None}
911 88e015a3 Antony Chazapis
        return self.post(path, headers=headers, params=params)
912 7812e1f9 Sofia Papagiannaki
    
913 7812e1f9 Sofia Papagiannaki
    def copy_object(self, src_container, src_object, dst_container, dst_object,
914 d4a63b9b Sofia Papagiannaki
                    meta={}, public=False, version=None, account=None,
915 db117cac Sofia Papagiannaki
                    content_type=None, delimiter=None):
916 7812e1f9 Sofia Papagiannaki
        """copies an object"""
917 95e92490 Sofia Papagiannaki
        account = account or self.account
918 7812e1f9 Sofia Papagiannaki
        headers = {}
919 7812e1f9 Sofia Papagiannaki
        headers['x_object_public'] = public
920 7812e1f9 Sofia Papagiannaki
        if version:
921 97d45f69 Antony Chazapis
            headers['x_source_version'] = version
922 7812e1f9 Sofia Papagiannaki
        return OOS_Client.copy_object(self, src_container, src_object,
923 7812e1f9 Sofia Papagiannaki
                                      dst_container, dst_object, meta=meta,
924 d4a63b9b Sofia Papagiannaki
                                      account=account, content_type=content_type,
925 db117cac Sofia Papagiannaki
                                      delimiter=delimiter,
926 d4a63b9b Sofia Papagiannaki
                                      **headers)
927 7812e1f9 Sofia Papagiannaki
    
928 7812e1f9 Sofia Papagiannaki
    def move_object(self, src_container, src_object, dst_container,
929 97d45f69 Antony Chazapis
                             dst_object, meta={}, public=False,
930 db117cac Sofia Papagiannaki
                             account=None, content_type=None, delimiter=None):
931 7812e1f9 Sofia Papagiannaki
        """moves an object"""
932 7812e1f9 Sofia Papagiannaki
        headers = {}
933 7812e1f9 Sofia Papagiannaki
        headers['x_object_public'] = public
934 7812e1f9 Sofia Papagiannaki
        return OOS_Client.move_object(self, src_container, src_object,
935 7812e1f9 Sofia Papagiannaki
                                      dst_container, dst_object, meta=meta,
936 d4a63b9b Sofia Papagiannaki
                                      account=account, content_type=content_type,
937 db117cac Sofia Papagiannaki
                                      delimiter=delimiter,
938 d4a63b9b Sofia Papagiannaki
                                      **headers)
939 ae75584f Sofia Papagiannaki
    
940 ae75584f Sofia Papagiannaki
    def list_shared_by_others(self, limit=None, marker=None, format='text'):
941 95e92490 Sofia Papagiannaki
        """lists other accounts that share objects to the user"""
942 95e92490 Sofia Papagiannaki
        l = ['limit', 'marker']
943 95e92490 Sofia Papagiannaki
        params = {}
944 95e92490 Sofia Papagiannaki
        for elem in [elem for elem in l if eval(elem)]:
945 95e92490 Sofia Papagiannaki
            params[elem] = eval(elem)
946 95e92490 Sofia Papagiannaki
        return self._list('', format, params)
947 ae75584f Sofia Papagiannaki
    
948 ae75584f Sofia Papagiannaki
    def share_object(self, container, object, l, read=True):
949 e7b51248 Sofia Papagiannaki
        """gives access(read by default) to an object to a user/group list"""
950 ae75584f Sofia Papagiannaki
        action = 'read' if read else 'write'
951 ae75584f Sofia Papagiannaki
        sharing = '%s=%s' % (action, ','.join(l))
952 ae75584f Sofia Papagiannaki
        self.update_object(container, object, f=None, x_object_sharing=sharing)
953 f1716de7 Sofia Papagiannaki
954 09fd65c7 Sofia Papagiannaki
def _prepare_path(path, format='text', params={}):
955 09fd65c7 Sofia Papagiannaki
    full_path = '%s?format=%s' % (quote(path), format)
956 f1716de7 Sofia Papagiannaki
    
957 f1716de7 Sofia Papagiannaki
    for k,v in params.items():
958 f1716de7 Sofia Papagiannaki
        value = quote(str(v)) if v else ''
959 f1716de7 Sofia Papagiannaki
        full_path = '%s&%s=%s' %(full_path, quote(k), value)
960 f1716de7 Sofia Papagiannaki
    return full_path
961 f1716de7 Sofia Papagiannaki
962 f1716de7 Sofia Papagiannaki
def _prepare_headers(headers):
963 f1716de7 Sofia Papagiannaki
    for k,v in headers.items():
964 f1716de7 Sofia Papagiannaki
        headers.pop(k)
965 f1716de7 Sofia Papagiannaki
        k = k.replace('_', '-')
966 f1716de7 Sofia Papagiannaki
        headers[quote(k)] = quote(v, safe='/=,:@ *"') if type(v) == types.StringType else v
967 f1716de7 Sofia Papagiannaki
    return headers
968 f1716de7 Sofia Papagiannaki
969 35c82779 Sofia Papagiannaki
def _handle_response(response, verbose=False, debug=False):
970 f1716de7 Sofia Papagiannaki
    headers = response.getheaders()
971 f1716de7 Sofia Papagiannaki
    headers = dict((unquote(h), unquote(v)) for h,v in headers)
972 f1716de7 Sofia Papagiannaki
    
973 f1716de7 Sofia Papagiannaki
    if verbose:
974 f1716de7 Sofia Papagiannaki
        print '%d %s' % (response.status, response.reason)
975 f1716de7 Sofia Papagiannaki
        for key, val in headers.items():
976 f1716de7 Sofia Papagiannaki
            print '%s: %s' % (key.capitalize(), val)
977 f1716de7 Sofia Papagiannaki
        print
978 f1716de7 Sofia Papagiannaki
    
979 f1716de7 Sofia Papagiannaki
    length = response.getheader('content-length', None)
980 f1716de7 Sofia Papagiannaki
    data = response.read(length)
981 f1716de7 Sofia Papagiannaki
    if debug:
982 f1716de7 Sofia Papagiannaki
        print data
983 f1716de7 Sofia Papagiannaki
        print
984 f1716de7 Sofia Papagiannaki
    
985 f1716de7 Sofia Papagiannaki
    if int(response.status) in ERROR_CODES.keys():
986 f1716de7 Sofia Papagiannaki
        raise Fault(data, int(response.status))
987 f1716de7 Sofia Papagiannaki
    
988 f1716de7 Sofia Papagiannaki
    #print '**',  response.status, headers, data, '\n'
989 35c82779 Sofia Papagiannaki
    return response.status, headers, data