commit e888608281b442295196449c6397f0a76134c287
Author: Antony Chazapis <chazapis@gmail.com>
Date:   Wed Jun 22 16:38:55 2011 +0300

    Fix version list and copy from version when the object is deleted.
    Remove 'public' from permissions.

diff --git a/pithos/api/functions.py b/pithos/api/functions.py
index 697cd7d..e62cf12 100644
--- a/pithos/api/functions.py
+++ b/pithos/api/functions.py
@@ -348,7 +348,10 @@ def object_list(request, v_account, v_container):
         else:
             try:
                 meta = backend.get_object_meta(request.user, v_account, v_container, x[0], x[1])
-                permissions = backend.get_object_permissions(request.user, v_account, v_container, x[0])
+                if until is None:
+                    permissions = backend.get_object_permissions(request.user, v_account, v_container, x[0])
+                else:
+                    permissions = None
             except NameError:
                 pass
             if permissions:
@@ -373,7 +376,10 @@ def object_meta(request, v_account, v_container, v_object):
     version = get_int_parameter(request, 'version')
     try:
         meta = backend.get_object_meta(request.user, v_account, v_container, v_object, version)
-        permissions = backend.get_object_permissions(request.user, v_account, v_container, v_object)
+        if version is None:
+            permissions = backend.get_object_permissions(request.user, v_account, v_container, v_object)
+        else:
+            permissions = None
     except NameError:
         raise ItemNotFound('Object does not exist')
     except IndexError:
@@ -399,12 +405,29 @@ def object_read(request, v_account, v_container, v_object):
     #                       notModified (304)
     
     version = get_int_parameter(request, 'version')
-    version_list = False
+    
+    # Reply with the version list. Do this first, as the object may be deleted.
     if version is None and request.GET.get('version') == 'list':
-        version_list = True
+        if request.serialization == 'text':
+            raise BadRequest('No format specified for version list.')
+        
+        d = {'versions': backend.list_versions(request.user, v_account, v_container, v_object)}
+        if request.serialization == 'xml':
+            d['object'] = v_object
+            data = render_to_string('versions.xml', d)
+        elif request.serialization  == 'json':
+            data = json.dumps(d)
+        
+        response = HttpResponse(data, status=200)
+        response['Content-Length'] = len(data)
+        return response
+    
     try:
         meta = backend.get_object_meta(request.user, v_account, v_container, v_object, version)
-        permissions = backend.get_object_permissions(request.user, v_account, v_container, v_object)
+        if version is None:
+            permissions = backend.get_object_permissions(request.user, v_account, v_container, v_object)
+        else:
+            permissions = None
     except NameError:
         raise ItemNotFound('Object does not exist')
     except IndexError:
@@ -423,23 +446,6 @@ def object_read(request, v_account, v_container, v_object):
         response['ETag'] = meta['hash']
         return response
     
-    # Reply with the version list.
-    if version_list:
-        if request.serialization == 'text':
-            raise BadRequest('No format specified for version list.')
-        
-        d = {'versions': backend.list_versions(request.user, v_account, v_container, v_object)}
-        if request.serialization == 'xml':
-            d['object'] = v_object
-            data = render_to_string('versions.xml', d)
-        elif request.serialization  == 'json':
-            data = json.dumps(d)
-        
-        response = HttpResponse(data, status=200)
-        put_object_meta(response, meta)
-        response['Content-Length'] = len(data)
-        return response
-    
     sizes = []
     hashmaps = []
     if 'X-Object-Manifest' in meta:
diff --git a/pithos/api/util.py b/pithos/api/util.py
index fd683f1..7c967bf 100644
--- a/pithos/api/util.py
+++ b/pithos/api/util.py
@@ -174,8 +174,6 @@ def update_manifest_meta(request, v_account, meta):
 
 def format_permissions(permissions):
     ret = []
-    if 'public' in permissions:
-        ret.append('public')
     if 'private' in permissions:
         ret.append('private')
     r = ','.join(permissions.get('read', []))
@@ -234,11 +232,17 @@ def copy_or_move_object(request, v_account, src_container, src_name, dest_contai
     
     meta = get_object_meta(request)
     permissions = get_sharing(request)
-    # Keep previous values of 'Content-Type' (if a new one is absent) and 'hash'.
+    src_version = request.META.get('HTTP_X_SOURCE_VERSION')
+    
     try:
-        src_meta = backend.get_object_meta(request.user, v_account, src_container, src_name)
-    except NameError:
+        if move:
+            src_meta = backend.get_object_meta(request.user, v_account, src_container, src_name)
+        else:
+            src_meta = backend.get_object_meta(request.user, v_account, src_container, src_name, src_version)
+    except NameError, IndexError:
         raise ItemNotFound('Container or object does not exist')
+    
+    # Keep previous values of 'Content-Type' (if a new one is absent) and 'hash'.
     if 'Content-Type' in meta and 'Content-Type' in src_meta:
         del(src_meta['Content-Type'])
     for k in ('Content-Type', 'hash'):
@@ -249,9 +253,8 @@ def copy_or_move_object(request, v_account, src_container, src_name, dest_contai
         if move:
             backend.move_object(request.user, v_account, src_container, src_name, dest_container, dest_name, meta, True, permissions)
         else:
-            src_version = request.META.get('HTTP_X_SOURCE_VERSION')
             backend.copy_object(request.user, v_account, src_container, src_name, dest_container, dest_name, meta, True, permissions, src_version)
-    except NameError:
+    except NameError, IndexError:
         raise ItemNotFound('Container or object does not exist')
     except ValueError:
         raise BadRequest('Invalid sharing header')
@@ -370,22 +373,28 @@ def get_sharing(request):
     
     ret = {}
     for perm in (x.replace(' ','') for x in permissions.split(';')):
-        if perm == 'public':
-            ret['public'] = True
-            continue
-        elif perm == 'private':
+        if perm == 'private':
             ret['private'] = True
             continue
         elif perm.startswith('read='):
             ret['read'] = [v.replace(' ','') for v in perm[5:].split(',')]
+            if '*' in ret['read']:
+                ret['read'] = ['*']
             if len(ret['read']) == 0:
                 raise BadRequest('Bad X-Object-Sharing header value')
         elif perm.startswith('write='):
             ret['write'] = [v.replace(' ','') for v in perm[6:].split(',')]
+            if '*' in ret['write']:
+                ret['write'] = ['*']
             if len(ret['write']) == 0:
                 raise BadRequest('Bad X-Object-Sharing header value')
         else:
             raise BadRequest('Bad X-Object-Sharing header value')
+    if 'private' in ret:
+        if 'read' in ret:
+            del(ret['read'])
+        if 'write' in ret:
+            del(ret['write'])
     return ret
 
 def raw_input_socket(request):
diff --git a/pithos/backends/simple.py b/pithos/backends/simple.py
index cd1fd00..b0887bc 100644
--- a/pithos/backends/simple.py
+++ b/pithos/backends/simple.py
@@ -217,7 +217,7 @@ class SimpleBackend(BaseBackend):
         if version is None:
             modified = mtime
         else:
-            modified = self._get_version(path)[1] # Overall last modification
+            modified = self._get_version(path, version)[1] # Overall last modification
         
         meta = self._get_metadata(path, version_id)
         meta.update({'name': name, 'bytes': size, 'version': version_id, 'version_timestamp': mtime, 'modified': modified})
@@ -323,7 +323,7 @@ class SimpleBackend(BaseBackend):
         logger.debug("list_versions: %s %s %s", account, container, name)
         # This will even show deleted versions.
         path = os.path.join(account, container, name)
-        sql = '''select distinct version_id, strftime('%s', tstamp) from versions where name = ?'''
+        sql = '''select distinct version_id, strftime('%s', tstamp) from versions where name = ? and hide = 0'''
         c = self.con.execute(sql, (path,))
         return [(int(x[0]), int(x[1])) for x in c.fetchall()]
     
@@ -491,20 +491,19 @@ class SimpleBackend(BaseBackend):
         sql = '''select name from permissions
                     where name != ? and (name like ? or ? like name || ?)'''
         c = self.con.execute(sql, (path, path + '%', path, '%'))
-        if c.fetchall() is not None:
+        rows = c.fetchall()
+        if rows:
             raise AttributeError('Permissions already set')
         
         # Format given permissions set.
         r = permissions.get('read', [])
         w = permissions.get('write', [])
-        if True in [False or '*' in x or ',' in x for x in r]:
+        if True in [False or ',' in x for x in r]:
             raise ValueError('Bad characters in read permissions')
-        if True in [False or '*' in x or ',' in x for x in w]:
+        if True in [False or ',' in x for x in w]:
             raise ValueError('Bad characters in write permissions')
         r = ','.join(r)
         w = ','.join(w)
-        if 'public' in permissions:
-            r = '*'
         if 'private' in permissions:
             r = ''
             w = ''
@@ -524,10 +523,7 @@ class SimpleBackend(BaseBackend):
         if w != '':
             ret['write'] = w.split(',')
         if r != '':
-            if r == '*':
-                ret['public'] = True
-            else:
-                ret['read'] = r.split(',')        
+            ret['read'] = r.split(',')        
         return ret
     
     def _put_permissions(self, path, r, w):
