Merge account policy in api. Document.
[pithos] / pithos / api / functions.py
index f1c569c..8255772 100644 (file)
@@ -49,7 +49,7 @@ from pithos.api.util import (rename_meta_key, format_header_key, printable_heade
     update_manifest_meta, update_sharing_meta, update_public_meta, validate_modification_preconditions,
     validate_matching_preconditions, split_container_object_string, copy_or_move_object,
     get_int_parameter, get_content_length, get_content_range, socket_read_iterator,
-    object_data_response, put_object_block, hashmap_hash, api_method)
+    object_data_response, put_object_block, hashmap_hash, api_method, json_encode_decimal)
 from pithos.backends import connect_backend
 from pithos.backends.base import NotAllowedError
 
@@ -186,13 +186,14 @@ def account_meta(request, v_account):
     try:
         meta = request.backend.get_account_meta(request.user, v_account, until)
         groups = request.backend.get_account_groups(request.user, v_account)
+        policy = request.backend.get_account_policy(request.user, v_account)
     except NotAllowedError:
         raise Unauthorized('Access denied')
     
     validate_modification_preconditions(request, meta)
     
     response = HttpResponse(status=204)
-    put_account_headers(response, meta, groups)
+    put_account_headers(response, meta, groups, policy)
     return response
 
 @api_method('POST')
@@ -234,13 +235,14 @@ def container_list(request, v_account):
     try:
         meta = request.backend.get_account_meta(request.user, v_account, until)
         groups = request.backend.get_account_groups(request.user, v_account)
+        policy = request.backend.get_account_policy(request.user, v_account)
     except NotAllowedError:
         raise Unauthorized('Access denied')
     
     validate_modification_preconditions(request, meta)
     
     response = HttpResponse()
-    put_account_headers(response, meta, groups)
+    put_account_headers(response, meta, groups, policy)
     
     marker = request.GET.get('marker')
     limit = get_int_parameter(request.GET.get('limit'))
@@ -331,8 +333,7 @@ def container_create(request, v_account, v_container):
     meta, policy = get_container_headers(request)
     
     try:
-        request.backend.put_container(request.user, v_account, v_container,
-                                        policy)
+        request.backend.put_container(request.user, v_account, v_container, policy)
         ret = 201
     except NotAllowedError:
         raise Unauthorized('Access denied')
@@ -392,7 +393,23 @@ def container_update(request, v_account, v_container):
             raise Unauthorized('Access denied')
         except NameError:
             raise ItemNotFound('Container does not exist')
-    return HttpResponse(status=202)
+    
+    content_length = -1
+    if request.META.get('HTTP_TRANSFER_ENCODING') != 'chunked':
+        content_length = get_int_parameter(request.META.get('CONTENT_LENGTH', 0))
+    content_type = request.META.get('CONTENT_TYPE')
+    hashmap = []
+    if content_type and content_type == 'application/octet-stream' and content_length != 0:
+        for data in socket_read_iterator(request, content_length,
+                                            request.backend.block_size):
+            # TODO: Raise 408 (Request Timeout) if this takes too long.
+            # TODO: Raise 499 (Client Disconnect) if a length is defined and we stop before getting this much data.
+            hashmap.append(request.backend.put_block(data))
+    
+    response = HttpResponse(status=202)
+    if hashmap:
+        response.content = '\n'.join(hashmap) + '\n'
+    return response
 
 @api_method('DELETE')
 def container_delete(request, v_account, v_container):
@@ -526,7 +543,7 @@ def object_list(request, v_account, v_container):
     if request.serialization == 'xml':
         data = render_to_string('objects.xml', {'container': v_container, 'objects': object_meta})
     elif request.serialization  == 'json':
-        data = json.dumps(object_meta)
+        data = json.dumps(object_meta, default=json_encode_decimal)
     response.status_code = 200
     response.content = data
     return response
@@ -603,7 +620,7 @@ def object_read(request, v_account, v_container, v_object):
             d['object'] = v_object
             data = render_to_string('versions.xml', d)
         elif request.serialization  == 'json':
-            data = json.dumps(d)
+            data = json.dumps(d, default=json_encode_decimal)
         
         response = HttpResponse(data, status=200)
         response['Content-Length'] = len(data)
@@ -699,6 +716,7 @@ def object_read(request, v_account, v_container, v_object):
         response['Content-Length'] = len(data)
         return response
     
+    request.serialization = 'text' # Unset.
     return object_data_response(request, sizes, hashmaps, meta)
 
 @api_method('PUT', format_allowed=True)
@@ -1041,13 +1059,16 @@ def object_update(request, v_account, v_container, v_object):
     elif offset > size:
         raise RangeNotSatisfiable('Supplied offset is beyond object limits')
     if src_object:
+        src_account = smart_unicode(request.META.get('HTTP_X_SOURCE_ACCOUNT'), strings_only=True)
+        if not src_account:
+            src_account = request.user
         src_container, src_name = split_container_object_string(src_object)
         src_container = smart_unicode(src_container, strings_only=True)
         src_name = smart_unicode(src_name, strings_only=True)
         src_version = request.META.get('HTTP_X_SOURCE_VERSION')
         try:
-            src_size, src_hashmap = request.backend.get_object_hashmap(
-                request.user, v_account, src_container, src_name, src_version)
+            src_size, src_hashmap = request.backend.get_object_hashmap(request.user,
+                                        src_account, src_container, src_name, src_version)
         except NotAllowedError:
             raise Unauthorized('Access denied')
         except NameError: