#!/usr/bin/env python # Copyright 2006 John-Mark Gurney # # $Id$ # import os.path import zipfile from DIDLLite import StorageFolder, Item, VideoItem, AudioItem, TextItem, ImageItem, Resource from FSStorage import FSObject, registerklassfun def isatpath(f, p): if f[:len(p)] != p: # First part of path doesn't match, it's not return False slash = f[len(p):].find('/') if slash != -1 and slash != len(f) - len(p) + 1: # Another path component, skip it, as long as it's not the char return False # otherwise, it is at this level endtrim = len(f) if slash: endtrip -= 1 return f[len(p):endtrim] class ZipChildDir(StorageFolder): '''This is to represent a child dir of the zip file.''' class ZipFile(FSObject, StorageFolder): def __init__(self, *args, **kwargs): '''If a zip argument is passed it, use that as the zip archive.''' path = kwargs['path'] del kwargs['path'] StorageFolder.__init__(self, *args, **kwargs) FSObject.__init__(self, path) # mapping from path to objectID self.pathObjmap = {} def getdirents(path): '''Returns the list of entires for the path, '' is the root path.''' lst = self.zip.namelist() if path: path += '/' return filter(lambda x, p = path: isatpath(x, p), lst) def doUpdate(self): # open the zipfile as necessary. self.zip = zipfile.ZipFile(self.FSpath) allzipfiles = sets.Set(self.zip.namelist()) children = sets.Set(getdirents('')) for i in self.pathObjmap.keys(): if i not in children: # delete self.cd.delItem(self.pathObjmap[i]) del self.pathObjmap[i] for i in children: if i in self.pathObjmap: continue # new object if i not in allzipfiles: # must be a dir else: ZipChild(self, i) def detectzipfile(path, fobj): try: z = zipfile.ZipFile(fobj) except: return None, None return ZipFile, {} registerklassfun(detectzipfile)