Commit 991cf3e8 by willmcgugan

More work on xattr support

parent bd63700f
......@@ -36,6 +36,7 @@ error_msgs = {
"GETSIZE_FAILED" : "Unable to retrieve size of resource: %(path)s",
"COPYFILE_FAILED" : "Unable to copy file: %(path)s",
"READ_FAILED" : "Unable to read from file: %(path)s",
"XATTR_FAILED" : "Unable to access extended-attribute: %(path)s",
# NoSysPathError
"NO_SYS_PATH" : "No mapping to OS filesytem: %(path)s,",
......@@ -621,10 +622,10 @@ class FS(object):
def _get_attr_path(self, path):
if self.isdir(path):
return pathjoin(path, '.dirattrs')
return pathjoin(path, '.dirxattrs')
else:
dir_path, file_path = pathsplit(path)
return pathjoin(path, '.attrs.'+file_path)
return pathjoin(dir_path, '.xattrs.'+file_path)
def _get_attr_dict(self, path):
attr_path = self._get_attr_path(path)
......@@ -633,27 +634,38 @@ class FS(object):
else:
return {}
def _set_attr_dict(self, path, attrs):
attr_path = self._get_attr_path(path)
self.setcontents(path, self.pickle.dumps(attrs))
self.setcontents(self._get_attr_path(path), pickle.dumps(attrs))
def setattr(self, path, key, value):
def setxattr(self, path, key, value):
attrs = self._get_attr_dict(path)
attrs[key] = value
self._set_attr_dict(path, attrs)
def getattr(self, path, key, default):
return self._get_attr_dict(path).get(key, default)
def getxattr(self, path, key, default):
attrs = self._get_attr_dict(path)
return attrs.get(key, default)
def removeattr(self, path, key):
attrs = self._get_attrs()
if path in self._get_attrs():
def removexattr(self, path, key):
attrs = self._get_attr_dict(path)
try:
del attrs[key]
except KeyError:
pass
self._set_attr_dict(path, attrs)
def listattrs(self, path):
def listxattrs(self, path):
attrs = self._get_attr_dict(path)
return self._get_attr_dict(path).keys()
def updatexattrs(self, path, update_dict):
d = self._get_attr_dict()
d.update( dict([(k, v) for k,v in update_dict.iteritems()]) )
self.set_attr_dict(self, path, d)
def getxattrs(self, path):
return dict( [(k, self.getxattr(path, k)) for k in self.listxattrs(path)] )
def movedir(self, src, dst, overwrite=False, ignore_errors=False, chunk_size=16384):
"""Moves a directory from one location to another.
......
......@@ -3,6 +3,11 @@
from base import *
from helpers import *
try:
import xattr
except ImportError:
xattr = None
class OSFS(FS):
"""The most basic of filesystems. Simply shadows the underlaying filesytem
......@@ -87,7 +92,7 @@ class OSFS(FS):
raise OperationFailedError("MAKEDIR_FAILED", path)
else:
raise OperationFailedError("MAKEDIR_FAILED", path)
except OSError, e:
if e.errno == 17:
return
......@@ -171,39 +176,122 @@ class OSFS(FS):
return stats.st_size
def setxattr(self, path, key, value):
self._lock.acquire()
try:
if xattr is None:
return FS.setxattr(self, path, key, value)
try:
xattr.xattr(self.getsyspath(path))[key]=value
except IOError, e:
if e.errno == 95:
return FS.setxattr(self, path, key, value)
else:
raise OperationFailedError('XATTR_FAILED', path, details=e)
finally:
self._lock.release()
def getxattr(self, path, key, default=None):
self._lock.acquire()
try:
if xattr is None:
return FS.getxattr(self, path, key, default)
try:
return xattr.xattr(self.getsyspath(path)).get(key)
except IOError, e:
if e.errno == 95:
return FS.getxattr(self, path, key, default)
else:
raise OperationFailedError('XATTR_FAILED', path, details=e)
finally:
self._lock.release()
def removexattr(self, path, key):
self._lock.acquire()
try:
if xattr is None:
return FS.removexattr(self, path, key)
try:
del xattr.xattr(self.getsyspath(path))[key]
except KeyError:
pass
except IOError, e:
if e.errono == 95:
return FS.removexattr(self, path, key)
else:
raise OperationFailedError('XATTR_FAILED', path, details=e)
finally:
self._lock.release()
def listxattrs(self, path):
self._lock.acquire()
try:
if xattr is None:
return FS.listxattrs(self, path)
try:
return xattr.xattr(self.getsyspath(path)).keys()
except IOError, e:
if errono == 95:
return FS.listxattrs(self, path)
else:
raise OperationFailedError('XATTR_FAILED', path, details=e)
finally:
self._lock.release()
if __name__ == "__main__":
osfs = OSFS("~/projects")
for p in osfs.walk("tagging-trunk", search='depth'):
print p
import browsewin
browsewin.browse(osfs)
print_fs(osfs)
#print osfs.listdir("/projects/fs")
#sub_fs = osfs.open_dir("projects/")
#print sub_fs
#sub_fs.open('test.txt')
#print sub_fs.listdir(dirs_only=True)
#print sub_fs.listdir()
#print_fs(sub_fs, max_levels=2)
#for f in osfs.listdir():
# print f
#print osfs.listdir('projects', dirs_only=True, wildcard="d*")
#print_fs(osfs, 'projects/')
if __name__ == "__main__":
print pathjoin('/', 'a')
print pathjoin('a/b/c', '../../e/f')
osfs = OSFS('testfs')
#a = xattr.xattr('/home/will/projects/pyfilesystem/fs/testfs/test.txt')
#a['user.comment'] = 'world'
#print xattr.xattr('/home/will/projects/pyfilesystem/fs/testfs/test.txt').keys()
print osfs.listxattrs('test.txt')
osfs.removexattr('test.txt', 'user.foo')
#print osfs.listxattrs('test.txt')
osfs.setxattr('test.txt', 'user.foo', 'bar')
print osfs.getxattr('test.txt', 'user.foo')
print osfs.listxattrs('test.txt')
print osfs.getxattrs('test.txt')
#
#osfs = OSFS("~/projects")
#
#
##for p in osfs.walk("tagging-trunk", search='depth'):
## print p
#
#import browsewin
#browsewin.browse(osfs)
#
#print_fs(osfs)
#
##print osfs.listdir("/projects/fs")
#
##sub_fs = osfs.open_dir("projects/")
#
##print sub_fs
#
##sub_fs.open('test.txt')
#
##print sub_fs.listdir(dirs_only=True)
##print sub_fs.listdir()
##print_fs(sub_fs, max_levels=2)
#
##for f in osfs.listdir():
## print f
#
##print osfs.listdir('projects', dirs_only=True, wildcard="d*")
#
##print_fs(osfs, 'projects/')
#
#print pathjoin('/', 'a')
#
#print pathjoin('a/b/c', '../../e/f')
......@@ -145,7 +145,7 @@ class TestOSFS(unittest.TestCase):
self.fs = osfs.OSFS(self.temp_dir)
print "Temp dir is", self.temp_dir
def tearDown(self):
def tearDown(self):
shutil.rmtree(self.temp_dir)
def check(self, p):
......@@ -349,7 +349,7 @@ class TestOSFS(unittest.TestCase):
self.assert_(check("a/2.txt"))
self.assert_(check("a/3.txt"))
self.assert_(check("a/foo/bar/baz.txt"))
def test_copyfile(self):
check = self.check
......@@ -420,7 +420,7 @@ class TestOSFS(unittest.TestCase):
self.assert_(check("b/2.txt"))
self.assert_(check("b/3.txt"))
self.assert_(check("b/foo/bar/baz.txt"))
def test_copydir_with_hidden(self):
check = self.check
......@@ -489,7 +489,7 @@ class TestOSFS(unittest.TestCase):
for s in test_strings:
f5.write(s+"\n")
f5.close()
f6 = self.fs.open("c.txt", "rb")
f6 = self.fs.open("c.txt", "rb")
for s, t in zip(f6, test_strings):
self.assertEqual(s, t+"\n")
f6.close()
......@@ -504,7 +504,7 @@ class TestOSFS(unittest.TestCase):
word = f7.read(7)
self.assertEqual(word, "complex")
f7.close()
self.assertEqual(self.fs.getcontents("a.txt"), all_strings)
self.assertEqual(self.fs.getcontents("a.txt"), all_strings)
......@@ -753,7 +753,7 @@ class TestS3FS(TestOSFS):
code = compile(code,"<string>",'exec')
self.assertRaises(ValueError,eval,code,globals(),locals())
self.assertEquals(self.fs.getcontents('f.txt'),contents)
import rpcfs
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment