def __init__(self): fso.__init__(self, "unzip") self.name = "unzip" self.VFS = VFS.Get() self.vfs = vfs.vfs() self.fdm = FdManager() self.origin = None self.zipcontent = None self.file = None self.mapped_files = {}
class UNZIP(fso): def __init__(self): fso.__init__(self, "unzip") self.name = "unzip" self.VFS = VFS.Get() self.vfs = vfs.vfs() self.fdm = FdManager() self.origin = None self.zipcontent = None self.file = None self.mapped_files = {} def start(self, args): origin = args['file'].value() self.makeZipTree(origin) def makeZipTree(self, origin): self.origin = origin self.file = self.origin.open() self.zipcontent = mzipfile.ZipFile(self.file) for zipfile in self.zipcontent.namelist(): idx = zipfile.rfind("/") if idx != -1: path = zipfile[:idx] filename = zipfile[idx+1:] else: path = "" filename = zipfile parent = self.vfs.getnode(self.origin.absolute() + "/" + path) if parent == None: parent = self.makeDirs(path) attr = self.zipcontent.getinfo(zipfile) node = ZipNode(filename, attr.file_size, parent, self, zipfile) node.__disown__() e = event() e.value = Variant(self.origin) self.VFS.notify(e) def makeDirs(self, folders): sfolders = folders.split("/") prev = self.origin for folder in sfolders: node = self.vfs.getnode(prev.absolute() + "/" + folder) if node == None: node = Node(folder, 0, prev, self) node.setDir() node.__disown__() prev = node return node def mappedFile(self, zipfile): info = self.zipcontent.getinfo(zipfile) buff = "" if info.file_size > 0: buff = self.zipcontent.read(zipfile) return buff def nodeToZipFile(self, node): abs = node.absolute() orig = self.origin.absolute() zipfile = abs.replace(orig, "")[1:] return zipfile def vopen(self, node): if not node.size(): return 0 zipfile = self.nodeToZipFile(node) if zipfile in self.mapped_files.keys(): buff = self.mapped_files[zipfile]["buff"] self.mapped_files[zipfile]["opened"] += 1 else: buff = self.mappedFile(zipfile) self.mapped_files[zipfile] = {} self.mapped_files[zipfile]["buff"] = buff self.mapped_files[zipfile]["opened"] = 1 fi = fdinfo() fi.thisown = False fi.node = node fi.offset = 0 fd = self.fdm.push(fi) return fd def vread(self, fd, buff, size): fi = self.fdm.get(fd) zipfile = self.nodeToZipFile(fi.node) buff = self.mapped_files[zipfile]["buff"] if fi.node.size() < fi.offset + size: size = fi.node.size() - fi.offset if size <= 0: return (0, "") else: res = (size, buff[fi.offset:fi.offset+size]) fi.offset += size return res def vseek(self, fd, offset, whence): fi = self.fdm.get(fd) if whence == 0: if offset <= fi.node.size(): fi.offset = offset else: formatted_lines = traceback.format_exc().splitlines() raise vfsError("[unzip::vseek]" + formatted_lines[-1]) if whence == 1: if fi.offset + offset > fi.node.size(): fi.offset += offset else: formatted_lines = traceback.format_exc().splitlines() raise vfsError("[unzip::vseek]" + formatted_lines[-1]) if whence == 2: fi.offset = fi.node.size() return fi.offset def vclose(self, fd): try: fi = self.fdm.get(fd) zipfile = self.nodeToZipFile(fi.node) self.fdm.remove(fd) if self.mapped_files[zipfile]["opened"] == 1: del self.mapped_files[zipfile] else: self.mapped_files[zipfile]["opened"] -= 1 return 0 except: return 0 def vtell(self, fd): fi = self.fdm.get(fd) return fi.offset def status(self): return len(self.mapped_files)