Commit aece1874 by willmcgugan

Refinements to the memoryfs class, and added a 'walk' generator to the base class

parent 36b626d8
......@@ -62,7 +62,7 @@ class BrowseFrame(wx.Frame):
if not is_dir and name.endswith('.txt'):
txt = self.fs.open(new_path).read(50)
txt = self.fs.open(new_path).readline()[:50].rstrip()
name += " - "+txt
new_item = self.tree.AppendItem(item_id, name, data=wx.TreeItemData({'path':new_path, 'expanded':False}))
......
......@@ -13,7 +13,8 @@ error_msgs = {
"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"
"OPEN_FAILED" : "Unable to open file: %(path)s",
"FILE_LOCKED" : "File is locked: %(path)s",
}
error_codes = error_msgs.keys()
......@@ -29,9 +30,9 @@ class FSError(Exception):
def __str__(self):
msg = self.msg % dict((k, str(v)) for k,v in self.__dict__.iteritems())
msg = self.msg % dict((k, str(v)) for k, v in self.__dict__.iteritems())
return '%s %s' % (self.code, msg)
return '%s. %s' % (self.code, msg)
class NullFile:
......@@ -224,17 +225,40 @@ class FS(object):
elif absolute:
paths = [self.abspath(pathjoin(path, p)) for p in paths]
return paths
def walk_files(self, path="/", wildcard=None, dir_wildcard=None):
dirs = [path]
files = []
while dirs:
path = dirs.pop()
for path in self.listdir(path, full=True):
if self.isdir(path):
if dir_wildcard is not None:
if fnmatch.fnmatch(path, dir_wilcard):
dirs.append(path)
else:
dirs.append(path)
else:
if wildcard is not None:
if fnmatch.fnmatch(path, wildcard):
yield path
else:
yield path
class SubFS(FS):
def __init__(self, parent, sub_dir):
self.parent = parent
self.sub_dir = parent.abspath(sub_dir)
#print "sub_dir", self.sub_dir
def __str__(self):
return "<SubFS \"%s\" of %s>" % (self.sub_dir, self.parent)
......@@ -242,7 +266,6 @@ class SubFS(FS):
def _delegate(self, dirname):
delegate_path = pathjoin(self.sub_dir, resolvepath(makerelative(dirname)))
#print "delegate path", delegate_path
return delegate_path
def getsyspath(self, pathname):
......@@ -274,7 +297,6 @@ class OSFS(FS):
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
def __str__(self):
return "<OSFS \"%s\">" % self.root_path
......@@ -320,7 +342,7 @@ class OSFS(FS):
try:
paths = os.listdir(self.getsyspath(path))
except IOError, e:
except (OSError, IOError), 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)
......@@ -470,9 +492,11 @@ class MountFS(FS):
if __name__ == "__main__":
osfs = OSFS("~/")
osfs = OSFS("~/projects")
print osfs
#print osfs
for filename in osfs.walk_files("/prettycharts", "*.pov"):
print filename
import browsewin
browsewin.browse(osfs)
......
#!/usr/bin/env python
import os
from fs import FS, pathsplit, _iteratepath, FSError, print_fs
try:
......@@ -7,6 +8,12 @@ try:
except ImportError:
from StringIO import StringIO
def _check_mode(mode, mode_chars):
for c in mode_chars:
if c not in mode:
return False
return True
class MemoryFile(object):
def __init__(self, path, memory_fs, value, mode):
......@@ -15,32 +22,38 @@ class MemoryFile(object):
self.memory_fs = memory_fs
self.mode = mode
def check_mode(mode_chars):
for c in mode_chars:
if c not in mode:
return False
return True
self.mem_file = None
if check_mode('w'):
if check_mode('+'):
self.mem_file = StringIO(value)
else:
if _check_mode(mode, 'wa'):
self.mem_file = StringIO()
self.mem_file.write(value)
elif _check_mode(mode, 'w'):
self.mem_file = StringIO()
elif _check_mode(mode, 'ra'):
self.mem_file = StringIO()
self.mem_file.write(value)
elif _check_mode(mode, 'r'):
elif check_mode('r'):
if check_mode('+'):
self.mem_file = StringIO(value)
else:
if value is not None:
self.mem_file = StringIO(value)
else:
self.mem_file = StringIO()
if check_mode('a'):
self.mem_file.seek(0, os.SEEK_END)
assert self.mem_file is not None, "self.mem_file should have a value"
self.closed = False
def __del__(self):
if not self.closed:
self.close()
......@@ -58,13 +71,15 @@ class MemoryFile(object):
return self.mem_file.readline(*args, **kwargs)
def close(self):
if not self.closed:
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):
if size is None:
size = -1
return self.mem_file.read(size)
def seek(self, *args, **kwargs):
......@@ -100,18 +115,14 @@ class MemoryFS(FS):
self.contents = contents
self.num_reading = 0
self.num_writing = 0
self.data = None
self.locks = 0
def lock(self):
return
self.locks += 1
def unlock(self):
return
self.locks -=1
assert self.locks >=0, "Lock / Unlock mismatch!"
......@@ -240,27 +251,26 @@ class MemoryFS(FS):
return self
def _lock_dir(self, dirpath):
def _lock_dir_entry(self, path):
dir_entry = self._get_dir_entry(dirpath)
dir_entry = self._get_dir_entry(path)
dir_entry.lock()
def _unlock_dir(self, dirpath):
def _unlock_dir_entry(self, path):
dir_entry = self._get_dir_entry(dirpath)
dir_entry = self._get_dir_entry(path)
dir_entry.unlock()
def _is_dir_locked(self, dirpath):
def _is_dir_locked(self, path):
dir_entry = self._get_dir_entry(dirpath)
dir_entry = self._get_dir_entry(path)
return dir_entry.islocked()
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():
......@@ -270,22 +280,30 @@ class MemoryFS(FS):
if filename not in parent_dir_entry.contents:
raise FSError("NO_FILE", path)
self._lock_dir(filepath)
file_dir_entry = parent_dir_entry.contents[filename]
if 'a' in mode and file_dir_entry.islocked():
raise FSError("FILE_LOCKED", path)
self._lock_dir_entry(path)
mem_file = MemoryFile(path, self, file_dir_entry.data, mode)
file_dir_entry.num_reading += 1
return mem_file
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]
file_dir_entry = parent_dir_entry.contents[filename]
if file_dir_entry.islocked():
raise FSError("FILE_LOCKED", path)
self._lock_dir_entry(path)
mem_file = MemoryFile(path, self, None, mode)
file_dir_entry.num_writing = 1
return mem_file
if parent_dir_entry is None:
......@@ -296,9 +314,9 @@ class MemoryFS(FS):
def _on_close_memory_file(self, path, value):
filepath, filename = pathsplit(path)
self._unlock_dir(filepath)
dir_entry = self._get_dir_entry(path)
dir_entry.data = value
self._unlock_dir_entry(path)
......@@ -313,15 +331,34 @@ class MemoryFS(FS):
def ishidden(self, pathname):
return False
if __name__ == "__main__":
def main():
mem_fs = MemoryFS()
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!")
mem_fs.open("test/readme.txt", 'wa').write("\nSecond Line")
print mem_fs.open("test/readme.txt", 'r').read()
f1 = mem_fs.open("/test/readme.txt", 'r')
f2 = mem_fs.open("/test/readme.txt", 'r')
print f1.read(10)
print f2.read(10)
f1.close()
f2.close()
f3 = mem_fs.open("/test/readme.txt", 'w')
#print mem_fs.listdir('test')
#print mem_fs.isdir("test/test2")
#print mem_fs.root
......@@ -329,3 +366,8 @@ if __name__ == "__main__":
from browsewin import browse
browse(mem_fs)
if __name__ == "__main__":
main()
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