X-Git-Url: https://code.delx.au/bg-scripts/blobdiff_plain/b90108b29cbac4325a1927069ef13ca475cd61eb..437cc3ef42a0038caa22c4676c4e25831697f258:/lib/FileLists.py diff --git a/lib/FileLists.py b/lib/FileLists.py new file mode 100644 index 0000000..6c769f6 --- /dev/null +++ b/lib/FileLists.py @@ -0,0 +1,195 @@ +#! python + +import sys, os, os.path, random +import cPickle + +try: + import GregDebug + from GregDebug import debug, DEBUG_LEVEL_DEBUG, DEBUG_LEVEL_LOW, DEBUG_LEVEL_MEDIUM, DEBUG_LEVEL_HIGH + if __name__ == "__main__": + GregDebug.DEBUG_LEVEL = -10 +except ImportError: + print >>sys.stderr, "WARNING: debugging disabled as GregDebug could not be found" + DEBUG_LEVEL_DEBUG = DEBUG_LEVEL_LOW = DEBUG_LEVEL_MEDIUM = DEBUG_LEVEL_HIGH = None + def debug(message, level=None, indent_level = None): + pass + +class FileListNotImplemented(Exception): + pass + +def filterImageFiles(imageList): + IMAGE_EXT_LIST = ('.jpg', '.jpe', '.jpeg', '.png', '.gif', '.bmp') + def isImageFile(fname): + filebase, fileext = os.path.splitext(fname) + fileext = fileext.lower() + return fileext in IMAGE_EXT_LIST + return [fname for fname in imageList if isImageFile(fname)] + + +class BaseFileList(object): + """Base file list implementation""" + def doScanPaths(self): + raise FileListNotImplemented() + def doAddPaths(self, paths): + for path in paths: + self.doAddPath(path) + def doAddPath(self, path): + raise FileListNotImplemented() + def doStoreCache(self, path): + return False + def getNextRandomImage(self): + raise FileListNotImplemented() + def getPrevRandomImage(self): + raise FileListNotImplemented() + def getCurrentImage(self): + raise FileListNotImplemented() + def attemptCacheLoad(self, filename, rescanPaths = False): + return False + def hasImages(self): + return False + +class RandomFileList(BaseFileList): + def __init__(self): + self.list = [] + self.paths = [] + self.lastImage = None + + def doScanPaths(self): + for path in self.paths: + for dirpath, dirsnames, filenames in os.walk(path): + for filename in filterImageFiles(filenames): + self.list.append(os.path.join(dirpath, filename)) + + def doAddPath(self, path): + self.paths.append(path) + debug('Added path "%s" to the list' % path, DEBUG_LEVEL_DEBUG) + + def doStoreCache(self, filename): + pass + + def getLastImage(self): + return self.lastImage + + def getNextRandomImage(self): + n = random.randint(0, len(self.list)-1) + self.lastImage = self.list[n] + debug("Picked file '%s' from list" % self.lastImage) + return self.lastImage + + def attemptCacheLoad(self, filename, rescanPaths = False): + return False + + def hasImages(self): + return len(self.list) > 0 + + +class AllRandomFileList(BaseFileList): + def __init__(self): + self.list = None + self.paths = [] + self.imagePointer = 0 + + # Scan the input directory, and then randomize the file list + def doScanPaths(self): + debug("Scanning paths", DEBUG_LEVEL_DEBUG) + + self.list = [] + for path in self.paths: + debug('Scanning "%s"' % path, DEBUG_LEVEL_DEBUG) + print os.path.exists(path) + for dirpath, dirsnames, filenames in os.walk(path): + for filename in filterImageFiles(filenames): + debug('Adding file "%s"' % filename, DEBUG_LEVEL_DEBUG - 2*GregDebug.DEBUG_INCREMENT) + self.list.append(os.path.join(dirpath, filename)) + + random.shuffle(self.list) + + def doAddPath(self, path): + self.paths.append(path) + debug('Added path "%s" to the list' % path, DEBUG_LEVEL_DEBUG) + + def doStoreCache(self, filename): + fd = open(filename, 'wb') + cPickle.dump(obj = self, file = fd, protocol = 2) + debug("Cache successfully stored", DEBUG_LEVEL_LOW) + return True + + def getCurrentImage(self): + return self.list[self.imagePointer] + + def __incrementInRange(self, n, amount = 1, rangeMax = None, rangeMin = 0): + if rangeMax == None: rangeMax = len(self.list) + assert rangeMax > 0 + return (n + amount) % rangeMax + + def getNextRandomImage(self): + self.imagePointer = self.__incrementInRange(self.imagePointer) + imageName = self.list[self.imagePointer] + debug("Picked file '%s' (pointer=%d) from list" % (imageName, self.imagePointer)) + return imageName + + def getPrevRandomImage(self): + self.imagePointer = self.__incrementInRange(self.imagePointer, amount=-1) + imageName = self.list[self.imagePointer] + debug("Picked file '%s' (pointer=%d) from list" % (imageName, self.imagePointer)) + return imageName + + def attemptCacheLoad(self, filename, rescanPaths = False): + debug('Attempting to load cache from "%s"' % filename, DEBUG_LEVEL_DEBUG) + self.paths.sort() + try: + return self._attemptCacheLoad(filename) + except Exception, e: + debug("Exception while loading cache: '%s'" % e) + + def _attemptCacheLoad(self, filename): + try: + fd = open(filename, 'rb') + tmp = cPickle.load(fd) + if self.paths == tmp.paths: + debug("Path lists match, copying properties", DEBUG_LEVEL_DEBUG) + # Overwrite this object with the other + for attr in ('list', 'imagePointer'): + setattr(self, attr, getattr(tmp, attr)) + return True + else: + debug("Ignoring cache, path lists do not match", DEBUG_LEVEL_LOW) + return False + except IOError, e: + debug("Exception raised while trying to load cache: '%s'" % e) + return False + + def hasImages(self): + return self.list + +class FolderRandomFileList(BaseFileList): + """A file list that will pick a file randomly within a directory. Each directory + has the same chance of being chosen.""" + def __init__(self): + self.directories = {} + + def doScanPaths(self): + return True # Since it is already done + + def doAddPath(self, path): + debug('Added path "%s" to the list' % path, DEBUG_LEVEL_DEBUG) + for dirpath, dirs, filenames in os.walk(path): + debug('Scanning "%s" for images' % dirpath) + if self.directories.has_key(dirpath): + continue + filenames = filterImageFiles(filenames) + if len(filenames): + self.directories[dirpath] = filenames + debug('Adding "%s" to "%s"' % (filenames, dirpath)) + else: + debug("No images found in '%s'" % dirpath) + + def getNextRandomImage(self): + directory = random.choice(self.directories.keys()) + debug('directory: "%s"' % directory) + filename = random.choice(self.directories[directory]) + debug('filename: "%s"' % filename) + return os.path.join(directory, filename) + + def hasImages(self): + return len(self.directories.values())