Commit e6834c21 by willmcgugan

Work in progress for memoryfs, cleaned up exception error codes

parent 9408f48d
...@@ -58,7 +58,13 @@ class BrowseFrame(wx.Frame): ...@@ -58,7 +58,13 @@ class BrowseFrame(wx.Frame):
for is_dir, new_path in paths: 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})) new_item = self.tree.AppendItem(item_id, name, data=wx.TreeItemData({'path':new_path, 'expanded':False}))
if is_dir: if is_dir:
......
...@@ -4,6 +4,36 @@ import fnmatch ...@@ -4,6 +4,36 @@ import fnmatch
from itertools import chain 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: class NullFile:
def __init__(self): def __init__(self):
...@@ -47,23 +77,9 @@ class NullFile: ...@@ -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: if path:
return path[1] in '\\/' return path[1] in '\\/'
return False return False
...@@ -89,7 +105,7 @@ def pathjoin(*paths): ...@@ -89,7 +105,7 @@ def pathjoin(*paths):
for component in chain(*(normpath(path).split('/') for path in relpaths)): for component in chain(*(normpath(path).split('/') for path in relpaths)):
if component == "..": if component == "..":
if not pathstack: if not pathstack:
raise PathError("INVALID_PATH", "Relative path is invalid: %(path)s", str(paths)) raise PathError("INVALID_PATH", str(paths))
sub = pathstack.pop() sub = pathstack.pop()
elif component == ".": elif component == ".":
pass pass
...@@ -172,14 +188,14 @@ class FS(object): ...@@ -172,14 +188,14 @@ class FS(object):
return pathname return pathname
def open(self, pathname, mode, **kwargs): def open(self, pathname, mode="r", buffering=-1, **kwargs):
pass pass
def open_dir(self, dirname): def open_dir(self, dirname):
if not self.exists(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) sub_fs = SubFS(self, dirname)
return sub_fs return sub_fs
...@@ -233,7 +249,7 @@ class SubFS(FS): ...@@ -233,7 +249,7 @@ class SubFS(FS):
return self.parent.getsyspath(self._delegate(pathname)) 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) return self.parent.open(self._delegate(pathname), mode, buffering)
...@@ -253,9 +269,9 @@ class OSFS(FS): ...@@ -253,9 +269,9 @@ class OSFS(FS):
expanded_path = normpath(os.path.expanduser(root_path)) expanded_path = normpath(os.path.expanduser(root_path))
if not os.path.exists(expanded_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): 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)) self.root_path = normpath(os.path.abspath(expanded_path))
#print "Root path", self.root_path #print "Root path", self.root_path
...@@ -272,12 +288,12 @@ class OSFS(FS): ...@@ -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: try:
f = open(self.getsyspath(pathname), mode, buffering) f = open(self.getsyspath(pathname), mode, buffering)
except IOError, e: except IOError, e:
raise FSError("OPEN_FAILED", str(e), pathname, details=e) raise FSError("OPEN_FAILED", pathname, details=e, msg=str(details))
return f return f
...@@ -305,7 +321,7 @@ class OSFS(FS): ...@@ -305,7 +321,7 @@ class OSFS(FS):
try: try:
paths = os.listdir(self.getsyspath(path)) paths = os.listdir(self.getsyspath(path))
except IOError, e: 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) return self._listdir_helper(path, paths, wildcard, full, absolute, hidden, dirs_only, files_only)
...@@ -361,7 +377,7 @@ class MountFS(FS): ...@@ -361,7 +377,7 @@ class MountFS(FS):
def mkdir(self, dirpath, recursive=True): def mkdir(self, dirpath, recursive=True):
if recursive and '/' in dirpath: 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): def do_mkdir(dirname):
...@@ -375,7 +391,7 @@ class MountFS(FS): ...@@ -375,7 +391,7 @@ class MountFS(FS):
if path_component in current_dir: if path_component in current_dir:
if not current_dir[path_component].isdir(): 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[path_component] = DirEntry(TYPE_DIR, path_component, {})
current_dir = current_dir[path_component].contents current_dir = current_dir[path_component].contents
...@@ -386,7 +402,7 @@ class MountFS(FS): ...@@ -386,7 +402,7 @@ class MountFS(FS):
def mountdir(self, dirname, dirfs, params=None, create_path=True): def mountdir(self, dirname, dirfs, params=None, create_path=True):
if dirname in self.dir_mounts: 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) success, code = dirfs._onmount(self)
if success: if success:
......
...@@ -37,8 +37,13 @@ class MemoryFile(object): ...@@ -37,8 +37,13 @@ class MemoryFile(object):
if check_mode('a'): if check_mode('a'):
self.mem_file.seek(0, os.SEEK_END) 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): def flush(self):
pass pass
...@@ -53,9 +58,11 @@ class MemoryFile(object): ...@@ -53,9 +58,11 @@ class MemoryFile(object):
return self.mem_file.readline(*args, **kwargs) return self.mem_file.readline(*args, **kwargs)
def close(self): def close(self):
value = self.get_vale() value = self.mem_file.getvalue()
self.memory_fs._on_close_memory_file(path, value) if 'w' in self.mode:
StringIO.close(self) self.memory_fs._on_close_memory_file(self.path, value)
self.mem_file.close()
self.closed = True
def read(self, size=None): def read(self, size=None):
return self.mem_file.read(size) return self.mem_file.read(size)
...@@ -100,9 +107,11 @@ class MemoryFS(FS): ...@@ -100,9 +107,11 @@ class MemoryFS(FS):
self.locks = 0 self.locks = 0
def lock(self): def lock(self):
return
self.locks += 1 self.locks += 1
def unlock(self): def unlock(self):
return
self.locks -=1 self.locks -=1
assert self.locks >=0, "Lock / Unlock mismatch!" assert self.locks >=0, "Lock / Unlock mismatch!"
...@@ -144,21 +153,18 @@ class MemoryFS(FS): ...@@ -144,21 +153,18 @@ class MemoryFS(FS):
def _get_dir_entry(self, dirpath): def _get_dir_entry(self, dirpath):
current_dir = self.root current_dir = self.root
#print _iteratepath(dirpath)
for path_component in _iteratepath(dirpath): for path_component in _iteratepath(dirpath):
dir_entry = current_dir.contents.get(path_component, None) dir_entry = current_dir.contents.get(path_component, None)
if dir_entry is None: if dir_entry is None:
return None return None
if not dir_entry.isdir():
return None
current_dir = dir_entry current_dir = dir_entry
return current_dir return current_dir
def getsyspath(self, pathname): 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): def isdir(self, path):
...@@ -188,11 +194,11 @@ class MemoryFS(FS): ...@@ -188,11 +194,11 @@ class MemoryFS(FS):
parent_dir = self._get_dir_entry(dirpath) parent_dir = self._get_dir_entry(dirpath)
if parent_dir is not None: if parent_dir is not None:
if parent_dir.isfile(): 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: else:
if not allow_recreate: if not allow_recreate:
if dirname in parent_dir.contents: 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 current_dir = self.root
for path_component in _iteratepath(dirpath)[:-1]: for path_component in _iteratepath(dirpath)[:-1]:
...@@ -200,7 +206,7 @@ class MemoryFS(FS): ...@@ -200,7 +206,7 @@ class MemoryFS(FS):
if dir_item is None: if dir_item is None:
break break
if not dir_item.isdir(): 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 = dir_item.contents
current_dir = self.root current_dir = self.root
...@@ -218,15 +224,15 @@ class MemoryFS(FS): ...@@ -218,15 +224,15 @@ class MemoryFS(FS):
else: else:
parent_dir = self._get_dir_entry(dirpath) parent_dir = self._get_dir_entry(dirpath)
if parent_dir is None: 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) dir_item = parent_dir.contents.get(dirname, None)
if dir_item is not None: if dir_item is not None:
if dir_item.isdir(): if dir_item.isdir():
if not allow_recreate: 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: 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: if dir_item is None:
parent_dir.contents[dirname] = self._make_dir_entry("dir", dirname) parent_dir.contents[dirname] = self._make_dir_entry("dir", dirname)
...@@ -236,51 +242,62 @@ class MemoryFS(FS): ...@@ -236,51 +242,62 @@ class MemoryFS(FS):
def _lock_dir(self, dirpath): def _lock_dir(self, dirpath):
dir_entry = self._get_dir_entry(path) dir_entry = self._get_dir_entry(dirpath)
dir_entry.lock() dir_entry.lock()
def _unlock_dir(self, dirpath): def _unlock_dir(self, dirpath):
dir_entry = self._get_dir_entry(path) dir_entry = self._get_dir_entry(dirpath)
dir_entry.unlock() 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() return dir_entry.islocked()
def open(self, path, mode, **kwargs): def open(self, path, mode="r", **kwargs):
dir_entry = self._get_dir_entry(path) filepath, filename = pathsplit(path)
if dir_entry is None: dir_entry = self._get_dir_entry(path)
dirpath, filename = pathsplit(path)
parent_dir_entry = self._get_dir_entry(filepath) 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 'r' in mode or 'a' in mode:
if filename not in parent_dir_entry: if filename not in parent_dir_entry.contents:
raise FSError("FILE_DOES_NOT_EXIST", "Can not open file that does not exist: %(path)s", path) raise FSError("NO_FILE", path)
parent_dir.lock() self._lock_dir(filepath)
file_dir_entry = parent_dir_entry[filename] file_dir_entry = parent_dir_entry.contents[filename]
mem_file = MemoryFile(path, self, file_dir_entry.value, mode) mem_file = MemoryFile(path, self, file_dir_entry.data, mode)
file_dir_entry.num_reading += 1 file_dir_entry.num_reading += 1
return mem_file return mem_file
else: elif 'w' in mode:
self._make_dir_entry("file", filename)
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: 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): def _on_close_memory_file(self, path, value):
self._unlock_dir(path) filepath, filename = pathsplit(path)
self._unlock_dir(filepath)
dir_entry = self._get_dir_entry(path) dir_entry = self._get_dir_entry(path)
dir_entry.data = value dir_entry.data = value
...@@ -302,6 +319,9 @@ if __name__ == "__main__": ...@@ -302,6 +319,9 @@ if __name__ == "__main__":
mem_fs.mkdir('test/test2', recursive=True) mem_fs.mkdir('test/test2', recursive=True)
mem_fs.mkdir('test/A', recursive=True) mem_fs.mkdir('test/A', recursive=True)
mem_fs.mkdir('test/A/B', 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.listdir('test')
#print mem_fs.isdir("test/test2") #print mem_fs.isdir("test/test2")
#print mem_fs.root #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