Commit 991cf3e8 by willmcgugan

More work on xattr support

parent bd63700f
...@@ -36,6 +36,7 @@ error_msgs = { ...@@ -36,6 +36,7 @@ error_msgs = {
"GETSIZE_FAILED" : "Unable to retrieve size of resource: %(path)s", "GETSIZE_FAILED" : "Unable to retrieve size of resource: %(path)s",
"COPYFILE_FAILED" : "Unable to copy file: %(path)s", "COPYFILE_FAILED" : "Unable to copy file: %(path)s",
"READ_FAILED" : "Unable to read from file: %(path)s", "READ_FAILED" : "Unable to read from file: %(path)s",
"XATTR_FAILED" : "Unable to access extended-attribute: %(path)s",
# NoSysPathError # NoSysPathError
"NO_SYS_PATH" : "No mapping to OS filesytem: %(path)s,", "NO_SYS_PATH" : "No mapping to OS filesytem: %(path)s,",
...@@ -621,10 +622,10 @@ class FS(object): ...@@ -621,10 +622,10 @@ class FS(object):
def _get_attr_path(self, path): def _get_attr_path(self, path):
if self.isdir(path): if self.isdir(path):
return pathjoin(path, '.dirattrs') return pathjoin(path, '.dirxattrs')
else: else:
dir_path, file_path = pathsplit(path) 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): def _get_attr_dict(self, path):
attr_path = self._get_attr_path(path) attr_path = self._get_attr_path(path)
...@@ -633,27 +634,38 @@ class FS(object): ...@@ -633,27 +634,38 @@ class FS(object):
else: else:
return {} return {}
def _set_attr_dict(self, path, attrs): def _set_attr_dict(self, path, attrs):
attr_path = self._get_attr_path(path) 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 = self._get_attr_dict(path)
attrs[key] = value attrs[key] = value
self._set_attr_dict(path, attrs) self._set_attr_dict(path, attrs)
def getattr(self, path, key, default): def getxattr(self, path, key, default):
return self._get_attr_dict(path).get(key, default) attrs = self._get_attr_dict(path)
return attrs.get(key, default)
def removeattr(self, path, key): def removexattr(self, path, key):
attrs = self._get_attrs() attrs = self._get_attr_dict(path)
if path in self._get_attrs(): try:
del attrs[key] 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() 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): def movedir(self, src, dst, overwrite=False, ignore_errors=False, chunk_size=16384):
"""Moves a directory from one location to another. """Moves a directory from one location to another.
......
...@@ -3,6 +3,11 @@ ...@@ -3,6 +3,11 @@
from base import * from base import *
from helpers import * from helpers import *
try:
import xattr
except ImportError:
xattr = None
class OSFS(FS): class OSFS(FS):
"""The most basic of filesystems. Simply shadows the underlaying filesytem """The most basic of filesystems. Simply shadows the underlaying filesytem
...@@ -171,39 +176,122 @@ class OSFS(FS): ...@@ -171,39 +176,122 @@ class OSFS(FS):
return stats.st_size 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()
if __name__ == "__main__": def getxattr(self, path, key, default=None):
self._lock.acquire()
osfs = OSFS("~/projects") try:
if xattr is None:
return FS.getxattr(self, path, key, default)
for p in osfs.walk("tagging-trunk", search='depth'): try:
print p return xattr.xattr(self.getsyspath(path)).get(key)
except IOError, e:
import browsewin if e.errno == 95:
browsewin.browse(osfs) return FS.getxattr(self, path, key, default)
else:
print_fs(osfs) raise OperationFailedError('XATTR_FAILED', path, details=e)
finally:
#print osfs.listdir("/projects/fs") self._lock.release()
#sub_fs = osfs.open_dir("projects/")
#print sub_fs
#sub_fs.open('test.txt') 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()
#print sub_fs.listdir(dirs_only=True) def listxattrs(self, path):
#print sub_fs.listdir() self._lock.acquire()
#print_fs(sub_fs, max_levels=2) 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()
#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')
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