Commit e6834c21 by willmcgugan

Work in progress for memoryfs, cleaned up exception error codes

parent 9408f48d
......@@ -58,7 +58,13 @@ class BrowseFrame(wx.Frame):
for is_dir, new_path in paths:
name = fs.pathsplit(new_path)[-1]
name = fs.pathsplit(new_path)[-1]
if not is_dir and name.endswith('.txt'):
txt = self.fs.open(new_path).read(50)
name += " - "+txt
new_item = self.tree.AppendItem(item_id, name, data=wx.TreeItemData({'path':new_path, 'expanded':False}))
if is_dir:
......
......@@ -4,6 +4,36 @@ import fnmatch
from itertools import chain
error_msgs = {
"UNKNOWN_ERROR" : "No information on error: %(path)s",
"INVALID_PATH" : "Path is invalid: %(path)s",
"NO_DIR" : "Directory does not exist: %(path)s",
"NO_FILE" : "No such file: %(path)s",
"LISTDIR_FAILED" : "Unable to get directory listing: %(path)s",
"NO_SYS_PATH" : "No mapping to OS filesytem: %(path)s,",
"DIR_EXISTS" : "Directory exists (try allow_recreate=True): %(path)s",
"OPEN_FAILED" : "Unable to open file: %(path)s"
}
error_codes = error_msgs.keys()
class FSError(Exception):
def __init__(self, code, path=None, msg=None, details=None):
self.code = code
self.msg = msg or error_msgs.get(code, error_msgs['UNKNOWN_ERROR'])
self.path = path
self.details = details
def __str__(self):
msg = self.msg % dict((k, str(v)) for k,v in self.__dict__.iteritems())
return '%s %s' % (self.code, msg)
class NullFile:
def __init__(self):
......@@ -47,23 +77,9 @@ class NullFile:
class FSError(Exception):
def __init__(self, code, msg, path=None, details=None):
self.code = code
self.msg = msg
self.path = path
self.details = details
def __str__(self):
msg = self.msg % self.__dict__
return '%s - %s' % (self.code, msg)
def _isabsolute(path):
def isabsolutepath(path):
if path:
return path[1] in '\\/'
return False
......@@ -89,7 +105,7 @@ def pathjoin(*paths):
for component in chain(*(normpath(path).split('/') for path in relpaths)):
if component == "..":
if not pathstack:
raise PathError("INVALID_PATH", "Relative path is invalid: %(path)s", str(paths))
raise PathError("INVALID_PATH", str(paths))
sub = pathstack.pop()
elif component == ".":
pass
......@@ -172,14 +188,14 @@ class FS(object):
return pathname
def open(self, pathname, mode, **kwargs):
def open(self, pathname, mode="r", buffering=-1, **kwargs):
pass
def open_dir(self, dirname):
if not self.exists(dirname):
raise FSError("NO_DIR", "Directory does not exist: %(path)s", dirname)
raise FSError("NO_DIR", dirname)
sub_fs = SubFS(self, dirname)
return sub_fs
......@@ -233,7 +249,7 @@ class SubFS(FS):
return self.parent.getsyspath(self._delegate(pathname))
def open(self, pathname, mode="r", buffering=-1):
def open(self, pathname, mode="r", buffering=-1, **kwargs):
return self.parent.open(self._delegate(pathname), mode, buffering)
......@@ -253,9 +269,9 @@ class OSFS(FS):
expanded_path = normpath(os.path.expanduser(root_path))
if not os.path.exists(expanded_path):
raise FSError("PATH_NOT_EXIST", "Root path does not exist: %(path)s", expanded_path)
raise FSError("NO_DIR", expanded_path, msg="Root directory does not exist: %(path)s")
if not os.path.isdir(expanded_path):
raise FSError("PATH_NOT_DIR", "Root path is not a directory: %(path)s", expanded_path)
raise FSError("NO_DIR", expanded_path, msg="Root path is not a directory: %(path)s")
self.root_path = normpath(os.path.abspath(expanded_path))
#print "Root path", self.root_path
......@@ -272,12 +288,12 @@ class OSFS(FS):
def open(self, pathname, mode="r", buffering=-1):
def open(self, pathname, mode="r", buffering=-1, **kwargs):
try:
f = open(self.getsyspath(pathname), mode, buffering)
except IOError, e:
raise FSError("OPEN_FAILED", str(e), pathname, details=e)
raise FSError("OPEN_FAILED", pathname, details=e, msg=str(details))
return f
......@@ -305,7 +321,7 @@ class OSFS(FS):
try:
paths = os.listdir(self.getsyspath(path))
except IOError, e:
raise FSError("LIST_FAILED", str(e), path, details=e)
raise FSError("LISTDIR_FAILED", path, details=e, msg="Unable to get directory listing: %(path)s - (%(details)s)")
return self._listdir_helper(path, paths, wildcard, full, absolute, hidden, dirs_only, files_only)
......@@ -361,7 +377,7 @@ class MountFS(FS):
def mkdir(self, dirpath, recursive=True):
if recursive and '/' in dirpath:
raise PathError("INVALID_PATH", "Use recursive=True to create this path", dirpath)
raise PathError("NO_DIR", dirpath, msg="Use recursive=True to create this path: %(path)s")
def do_mkdir(dirname):
......@@ -375,7 +391,7 @@ class MountFS(FS):
if path_component in current_dir:
if not current_dir[path_component].isdir():
raise PathError("INVALID_PATH", "Can not create path here", dirpath)
raise PathError("NO_DIR", dirpath, msg="Path references a file, not a dir: %(path)s")
current_dir[path_component] = DirEntry(TYPE_DIR, path_component, {})
current_dir = current_dir[path_component].contents
......@@ -386,7 +402,7 @@ class MountFS(FS):
def mountdir(self, dirname, dirfs, params=None, create_path=True):
if dirname in self.dir_mounts:
raise FSError("MOUNT_NOT_FREE", "A directory of this name is already mounted", dirname)
raise FSError("MOUNT_NOT_FREE", dirname, msg="A directory of this name is already mounted")
success, code = dirfs._onmount(self)
if success:
......
......@@ -37,8 +37,13 @@ class MemoryFile(object):
if check_mode('a'):
self.mem_file.seek(0, os.SEEK_END)
self.mem_file = None
self.closed = False
def __del__(self):
if not self.closed:
self.close()
def flush(self):
pass
......@@ -53,9 +58,11 @@ class MemoryFile(object):
return self.mem_file.readline(*args, **kwargs)
def close(self):
value = self.get_vale()
self.memory_fs._on_close_memory_file(path, value)
StringIO.close(self)
value = self.mem_file.getvalue()
if 'w' in self.mode:
self.memory_fs._on_close_memory_file(self.path, value)
self.mem_file.close()
self.closed = True
def read(self, size=None):
return self.mem_file.read(size)
......@@ -100,9 +107,11 @@ class MemoryFS(FS):
self.locks = 0
def lock(self):
return
self.locks += 1
def unlock(self):
return
self.locks -=1
assert self.locks >=0, "Lock / Unlock mismatch!"
......@@ -144,21 +153,18 @@ class MemoryFS(FS):
def _get_dir_entry(self, dirpath):
current_dir = self.root
#print _iteratepath(dirpath)
for path_component in _iteratepath(dirpath):
dir_entry = current_dir.contents.get(path_component, None)
if dir_entry is None:
return None
if not dir_entry.isdir():
return None
return None
current_dir = dir_entry
return current_dir
def getsyspath(self, pathname):
raise FSError("NO_SYS_PATH", "This file-system has no syspath", pathname)
raise FSError("NO_SYS_PATH", pathname, msg="This file-system has no syspath")
def isdir(self, path):
......@@ -188,11 +194,11 @@ class MemoryFS(FS):
parent_dir = self._get_dir_entry(dirpath)
if parent_dir is not None:
if parent_dir.isfile():
raise FSError("CANNOT_CREATE_DIR", "Can not create a directory, because path references a file: %(path)s", dirname)
raise FSError("NO_DIR", dirname, msg="Can not create a directory, because path references a file: %(path)s")
else:
if not allow_recreate:
if dirname in parent_dir.contents:
raise FSError("CANNOT_RECREATE_DIR", "Can not create a directory that already exists (try allow_recreate=True): %(path)s", dirname)
raise FSError("NO_DIR", dirname, msg="Can not create a directory that already exists (try allow_recreate=True): %(path)s")
current_dir = self.root
for path_component in _iteratepath(dirpath)[:-1]:
......@@ -200,7 +206,7 @@ class MemoryFS(FS):
if dir_item is None:
break
if not dir_item.isdir():
raise FSError("CANNOT_CREATE_DIR", "Can not create a directory, because path references a file: %(path)s", dirname)
raise FSError("NO_DIR", dirname, msg="Can not create a directory, because path references a file: %(path)s")
current_dir = dir_item.contents
current_dir = self.root
......@@ -218,15 +224,15 @@ class MemoryFS(FS):
else:
parent_dir = self._get_dir_entry(dirpath)
if parent_dir is None:
raise FSError("NO_DIR", "Could not make dir, as parent dir does not exist: %(path)s", dirname )
raise FSError("NO_DIR", dirname, msg="Could not make dir, as parent dir does not exist: %(path)s")
dir_item = parent_dir.contents.get(dirname, None)
if dir_item is not None:
if dir_item.isdir():
if not allow_recreate:
raise FSError("CANNOT_RECREATE_DIR", "Can not create a directory that already exists (try allow_recreate=True): %(path)s", dirname)
raise FSError("DIR_EXISTS", dirname)
else:
raise FSError("CANNOT_CREATE_DIR", "Can not create a directory, because path references a file: %(path)s", dirname)
raise FSError("NO_DIR", dirname, msg="Can not create a directory, because path references a file: %(path)s")
if dir_item is None:
parent_dir.contents[dirname] = self._make_dir_entry("dir", dirname)
......@@ -236,51 +242,62 @@ class MemoryFS(FS):
def _lock_dir(self, dirpath):
dir_entry = self._get_dir_entry(path)
dir_entry = self._get_dir_entry(dirpath)
dir_entry.lock()
def _unlock_dir(self, dirpath):
dir_entry = self._get_dir_entry(path)
dir_entry = self._get_dir_entry(dirpath)
dir_entry.unlock()
def is_dir_locked(self, dirpath):
def _is_dir_locked(self, dirpath):
dir_entry = self._get_dir_entry(path)
dir_entry = self._get_dir_entry(dirpath)
return dir_entry.islocked()
def open(self, path, mode, **kwargs):
dir_entry = self._get_dir_entry(path)
if dir_entry is None:
dirpath, filename = pathsplit(path)
def open(self, path, mode="r", **kwargs):
filepath, filename = pathsplit(path)
dir_entry = self._get_dir_entry(path)
parent_dir_entry = self._get_dir_entry(filepath)
if parent_dir_entry is None or not parent_dir_entry.isdir():
raise FSError("NO_FILE", path)
if 'r' in mode or 'a' in mode:
if filename not in parent_dir_entry:
raise FSError("FILE_DOES_NOT_EXIST", "Can not open file that does not exist: %(path)s", path)
if filename not in parent_dir_entry.contents:
raise FSError("NO_FILE", path)
parent_dir.lock()
file_dir_entry = parent_dir_entry[filename]
mem_file = MemoryFile(path, self, file_dir_entry.value, mode)
self._lock_dir(filepath)
file_dir_entry = parent_dir_entry.contents[filename]
mem_file = MemoryFile(path, self, file_dir_entry.data, mode)
file_dir_entry.num_reading += 1
return mem_file
else:
self._make_dir_entry("file", filename)
elif 'w' in mode:
if filename not in parent_dir_entry.contents:
file_dir_entry = self._make_dir_entry("file", filename)
parent_dir_entry.contents[filename] = file_dir_entry
else:
file_dir_entry = parent_dir_entry.contents[fielname]
mem_file = MemoryFile(path, self, None, mode)
file_dir_entry.num_writing = 1
return mem_file
if parent_dir_entry is None:
raise FSError("DOES_NOT_EXIST", "File does not exist", path)
raise FSError("NO_FILE", path)
def _on_close_memory_file(self, path, value):
self._unlock_dir(path)
dir_entry = self._get_dir_entry(path)
filepath, filename = pathsplit(path)
self._unlock_dir(filepath)
dir_entry = self._get_dir_entry(path)
dir_entry.data = value
......@@ -302,6 +319,9 @@ if __name__ == "__main__":
mem_fs.mkdir('test/test2', recursive=True)
mem_fs.mkdir('test/A', recursive=True)
mem_fs.mkdir('test/A/B', recursive=True)
mem_fs.open("test/readme.txt", 'w').write("Hello, World!")
#print mem_fs.listdir('test')
#print mem_fs.isdir("test/test2")
#print mem_fs.root
......
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