Commit 54cc60af by rfkelly0

new FS wrapper to limit size of underlying filesystem

parent c0cc55c5
......@@ -81,7 +81,13 @@ def handle_fs_errors(func):
func = convert_fs_errors(func)
@wraps(func)
def wrapper(*args,**kwds):
res = func(*args,**kwds)
print func.__name__, args[1:]
try:
res = func(*args,**kwds)
except Exception, e:
print func.__name__, args[1:]
print e
raise
if res is None:
return 0
return res
......
......@@ -13,11 +13,10 @@ directory listings.
"""
from fs.base import FS
from fs.base import FS, threading, synchronize
from fs.errors import *
from fs.errors import wraps, ResourceError
def rewrite_errors(func):
@wraps(func)
def wrapper(self,*args,**kwds):
......@@ -57,6 +56,10 @@ class WrapFS(FS):
def __init__(self,fs):
super(WrapFS,self).__init__()
try:
self._lock = fs._lock
except AttributeError:
self._lock = None
self.wrapped_fs = fs
def _file_wrap(self,f,mode):
......@@ -255,3 +258,103 @@ class HideDotFiles(WrapFS):
return True
return False
class LimitSize(WrapFS):
def __init__(self,fs,max_size):
self.max_size = max_size
super(LimitSize,self).__init__(fs)
self.cur_size = sum(self.getsize(f) for f in self.walkfiles())
@synchronize
def open(self,path,mode="r"):
try:
size = self.getsize(path)
except ResourceNotFoundError:
size = 0
f = super(LimitSize,self).open(path,mode)
if "w" in mode:
self.cur_size -= size
size = 0
return LimitSizeFile(self,f,mode,size)
def _acquire_space(self,size):
new_size = self.cur_size + size
if new_size > self.max_size:
raise StorageSpaceError("write")
self.cur_size = new_size
# Disable use of system-level paths, so that copy/copydir have to
# fall back to manual writes and pass through _acquire_space.
getsyspath = FS.getsyspath
copy = FS.copy
copydir = FS.copydir
@synchronize
def remove(self,path):
size = self.getsize(path)
super(LimitSize,self).remove(path)
self.cur_size -= size
@synchronize
def removedir(self,path,recursive=False,force=False):
size = sum(self.getsize(f) for f in self.walkfiles(path))
super(LimitSize,self).removedir(path,recursive=recursive,force=force)
self.cur_size -= size
class LimitSizeFile(object):
def __init__(self,fs,file,mode,size):
self._lock = fs._lock
self.fs = fs
self.file = file
self.mode = mode
self.size = size
self.closed = False
@synchronize
def write(self,data):
pos = self.file.tell()
if pos > self.size:
self.size = pos
diff = pos + len(data) - self.size
if diff <= 0:
self.file.write(data)
else:
self.fs._acquire_space(diff)
self.file.write(data)
self.size += diff
def writelines(self,lines):
for line in lines:
self.write(line)
@synchronize
def truncate(self,size=None):
pos = self.file.tell()
if size is None:
size = pos
self.fs._acquire_space(size - self.size)
self.file.truncate(size)
self.size = size
# This is lifted straight from the stdlib's tempfile.py
def __getattr__(self,name):
file = self.__dict__['file']
a = getattr(file, name)
if not issubclass(type(a), type(0)):
setattr(self, name, a)
return a
def __enter__(self):
self.file.__enter__()
return self
def __exit__(self,exc,value,tb):
self.close()
return False
def __iter__(self):
return iter(self.file)
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