Commit 9284f4e2 by willmcgugan

Expanded on ZipFS and fixed a few bugs.

parent 0b8d5041
...@@ -24,7 +24,7 @@ class InfoFrame(wx.Frame): ...@@ -24,7 +24,7 @@ class InfoFrame(wx.Frame):
self.list_ctrl.SetColumnWidth(1, 300) self.list_ctrl.SetColumnWidth(1, 300)
for key in keys: for key in keys:
self.list_ctrl.Append((key, str(info[key]))) self.list_ctrl.Append((key, repr(info[key])))
...@@ -38,7 +38,7 @@ class BrowseFrame(wx.Frame): ...@@ -38,7 +38,7 @@ class BrowseFrame(wx.Frame):
self.SetTitle("FS Browser - "+str(fs)) self.SetTitle("FS Browser - "+str(fs))
self.tree = wx.gizmos.TreeListCtrl(self, -1, style=wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT) self.tree = wx.gizmos.TreeListCtrl(self, -1, style=wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT)
self.tree.AddColumn("FS", 300) self.tree.AddColumn("File System", 300)
self.tree.AddColumn("Description", 250) self.tree.AddColumn("Description", 250)
self.tree.AddColumn("Size", 150) self.tree.AddColumn("Size", 150)
self.tree.AddColumn("Created", 250) self.tree.AddColumn("Created", 250)
......
...@@ -156,6 +156,9 @@ class MemoryFS(FS): ...@@ -156,6 +156,9 @@ class MemoryFS(FS):
def __str__(self): def __str__(self):
return "<MemoryFS>" return "<MemoryFS>"
def __unicode__(self):
return unicode(self.__str__())
def _get_dir_entry(self, dirpath): def _get_dir_entry(self, dirpath):
self._lock.acquire() self._lock.acquire()
try: try:
...@@ -212,6 +215,8 @@ class MemoryFS(FS): ...@@ -212,6 +215,8 @@ class MemoryFS(FS):
self._lock.release() self._lock.release()
def makedir(self, dirname, mode=0777, recursive=False, allow_recreate=False): def makedir(self, dirname, mode=0777, recursive=False, allow_recreate=False):
if not dirname:
raise PathError("INVALID_PATH", "Path is empty")
self._lock.acquire() self._lock.acquire()
try: try:
fullpath = dirname fullpath = dirname
...@@ -234,7 +239,7 @@ class MemoryFS(FS): ...@@ -234,7 +239,7 @@ class MemoryFS(FS):
break break
if not dir_item.isdir(): if not dir_item.isdir():
raise ResourceNotFoundError("NO_DIR", dirname, msg="Can not create a directory, because path references a file: %(path)s") raise ResourceNotFoundError("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
current_dir = self.root current_dir = self.root
for path_component in _iteratepath(dirpath): for path_component in _iteratepath(dirpath):
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
from fs import * from fs import *
from zipfile import ZipFile, ZIP_DEFLATED, ZIP_STORED from zipfile import ZipFile, ZIP_DEFLATED, ZIP_STORED
from memoryfs import MemoryFS
try: try:
from cStringIO import StringIO from cStringIO import StringIO
...@@ -44,7 +45,7 @@ class _ExceptionProxy(object): ...@@ -44,7 +45,7 @@ class _ExceptionProxy(object):
class ZipFS(FS): class ZipFS(FS):
def __init__(self, zip_file, mode="r", compression="deflated", allowZip64=False): def __init__(self, zip_file, mode="r", compression="deflated", allowZip64=False):
FS.__init__(self) FS.__init__(self, thread_syncronize=True)
if compression == "deflated": if compression == "deflated":
compression_type = ZIP_DEFLATED compression_type = ZIP_DEFLATED
elif compression == "stored": elif compression == "stored":
...@@ -57,34 +58,58 @@ class ZipFS(FS): ...@@ -57,34 +58,58 @@ class ZipFS(FS):
self.zip_mode = mode self.zip_mode = mode
self.zf = ZipFile(zip_file, mode, compression_type, allowZip64) self.zf = ZipFile(zip_file, mode, compression_type, allowZip64)
self.zip_path = str(zip_file)
self.temp_fs = None self.temp_fs = None
if mode in 'wa': if mode in 'wa':
self.temp_fs = tempfs.TempFS() self.temp_fs = tempfs.TempFS()
self.resource_list = None self._path_fs = MemoryFS()
if mode == 'r': if mode in 'ra':
self.resource_list = self.zf.namelist() self._parse_resource_list()
def __str__(self):
return "<ZipFS: %s>" % self.zip_path
def __unicode__(self):
return unicode(self.__str__())
def _parse_resource_list(self):
for path in self.zf.namelist():
self._add_resource(path)
def _add_resource(self, path):
if path.endswith('/'):
path = path[:-1]
self._path_fs.makedir(path, recursive=True, allow_recreate=True)
else:
dirpath, filename = pathsplit(path)
if dirpath:
self._path_fs.makedir(dirpath, recursive=True, allow_recreate=True)
f = self._path_fs.open(path, 'w')
f.close()
def _get_resource_list(self):
if not self.zf:
raise ValueError("Zip file has been closed")
return self.resource_list or self.zf.namelist()
def close(self): def close(self):
"""Finalizes the zip file so that it can be read. """Finalizes the zip file so that it can be read.
No further operations will work after this method is called.""" No further operations will work after this method is called."""
self._lock.acquire()
try:
if self.zf: if self.zf:
self.zf.close() self.zf.close()
self.zf = _ExceptionProxy() self.zf = _ExceptionProxy()
finally:
self._lock.release()
def __del__(self): def __del__(self):
self.close() self.close()
def open(self, path, mode="r", **kwargs): def open(self, path, mode="r", **kwargs):
self._lock.acquire()
try:
path = normpath(path) path = normpath(path)
self.zip_path = path
if 'r' in mode: if 'r' in mode:
if self.zip_mode not in 'ra': if self.zip_mode not in 'ra':
...@@ -100,30 +125,67 @@ class ZipFS(FS): ...@@ -100,30 +125,67 @@ class ZipFS(FS):
if dirname: if dirname:
self.temp_fs.makedir(dirname, recursive=True, allow_recreate=True) self.temp_fs.makedir(dirname, recursive=True, allow_recreate=True)
self._add_resource(path)
f = _TempWriteFile(self.temp_fs, path, self._on_write_close) f = _TempWriteFile(self.temp_fs, path, self._on_write_close)
return f return f
raise ValueError("Mode must contain be 'r' or 'w'") raise ValueError("Mode must contain be 'r' or 'w'")
finally:
self._lock.release()
def _on_write_close(self, filename): def _on_write_close(self, filename):
self._lock.acquire()
try:
sys_path = self.temp_fs.getsyspath(filename) sys_path = self.temp_fs.getsyspath(filename)
self.zf.write(sys_path, filename) self.zf.write(sys_path, filename)
except:
self._lock.release()
def desc(self, path):
if self.isdir(path):
return "Dir in zip file: %s" % self.zip_path
else:
return "File in zip file: %s" % self.zip_path
def listdir(self, path="/", wildcard=None, full=False, absolute=False, hidden=False, dirs_only=False, files_only=False): def isdir(self, path):
return self._path_fs.isdir(path)
path = normpath(path) def isfile(self, path):
return self._path_fs.isdir(path)
def indir(p): def exists(self, path):
p = makeabsolute(p) return self._path_fs.exists(path)
list_dir = makeabsolute(path)
sub_path = normpath(p[len(list_dir)+1:])
return sub_path and '/' not in sub_path
paths = [getresourcename(p.rstrip('/')) for p in self._get_resource_list() if indir(p.rstrip('/'))] def makedir(self, dirname, mode=0777, recursive=False, allow_recreate=False):
dirname = normpath(dirname)
if self.zip_mode not in "wa":
raise OperationFailedError("MAKEDIR_FAILED", dirname, "Zip file must be opened for writing ('w') or appending ('a')")
if not dirname.endswith('/'):
dirname += '/'
self._add_resource(dirname)
return self._listdir_helper(path, paths, wildcard, full, absolute, hidden, dirs_only, files_only) def listdir(self, path="/", wildcard=None, full=False, absolute=False, hidden=False, dirs_only=False, files_only=False):
return self._path_fs.listdir(path, wildcard, full, absolute, hidden, dirs_only, files_only)
def getinfo(self, path):
self._lock.acquire()
try:
if not self.exists(path):
return ResourceNotFoundError("NO_RESOURCE", path)
path = normpath(path).lstrip('/')
try:
zi = self.zf.getinfo(path)
zinfo = dict((attrib, getattr(zi, attrib)) for attrib in dir(zi) if not attrib.startswith('_'))
except KeyError:
zinfo = {'file_size':0}
info = {'size' : zinfo['file_size']}
info.update(zinfo)
return info
finally:
self._lock.release()
if __name__ == "__main__": if __name__ == "__main__":
def test(): def test():
...@@ -138,9 +200,31 @@ if __name__ == "__main__": ...@@ -138,9 +200,31 @@ if __name__ == "__main__":
zfs = ZipFS("t2.zip", "r") zfs = ZipFS("t2.zip", "r")
print zfs.listdir("/tagging-trunk") print zfs.listdir("/tagging-trunk")
print zfs.listdir("/") print zfs.listdir("/")
import browsewin
browsewin.browse(zfs)
zfs.close() zfs.close()
zfs.open("t.txt") #zfs.open("t.txt")
print zfs.listdir("/") #print zfs.listdir("/")
test2() test2()
zfs = ZipFS("t3.zip", "w")
zfs.createfile("t.txt", "Hello, World!")
zfs.createfile("foo/bar/baz/t.txt", "Hello, World!")
#print zfs.isdir("t.txt")
#print zfs.isfile("t.txt")
#print zfs.isfile("foo/bar")
zfs.close()
zfs = ZipFS("t3.zip", "r")
print "--"
print zfs.listdir("foo")
print zfs.isdir("foo/bar")
print zfs.listdir("foo/bar")
print zfs.listdir("foo/bar/baz")
print_fs(zfs)
#zfs = ZipFS("t3.zip", "r")
#print zfs.zf.getinfo("asd.txt")
#zfs.close() #zfs.close()
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