]> code.delx.au - bg-scripts/blob - lib/FileLists.py
Major updates to randombg - stdlib is good :)
[bg-scripts] / lib / FileLists.py
1 #! python
2
3 import sys, os, os.path, random
4 import cPickle
5
6 try:
7 import GregDebug
8 from GregDebug import debug, DEBUG_LEVEL_DEBUG, DEBUG_LEVEL_LOW, DEBUG_LEVEL_MEDIUM, DEBUG_LEVEL_HIGH
9 if __name__ == "__main__":
10 GregDebug.DEBUG_LEVEL = -10
11 except ImportError:
12 print >>sys.stderr, "WARNING: debugging disabled as GregDebug could not be found"
13 DEBUG_LEVEL_DEBUG = DEBUG_LEVEL_LOW = DEBUG_LEVEL_MEDIUM = DEBUG_LEVEL_HIGH = None
14 def debug(message, level=None, indent_level = None):
15 pass
16
17 class FileListNotImplemented(Exception):
18 pass
19
20 def filterImageFiles(imageList):
21 IMAGE_EXT_LIST = ('.jpg', '.jpe', '.jpeg', '.png', '.gif', '.bmp')
22 def isImageFile(fname):
23 filebase, fileext = os.path.splitext(fname)
24 fileext = fileext.lower()
25 return fileext in IMAGE_EXT_LIST
26 return [fname for fname in imageList if isImageFile(fname)]
27
28
29 class BaseFileList(object):
30 """Base file list implementation"""
31 def doScanPaths(self):
32 raise FileListNotImplemented()
33 def doAddPaths(self, paths):
34 for path in paths:
35 self.doAddPath(path)
36 def doAddPath(self, path):
37 raise FileListNotImplemented()
38 def doStoreCache(self, path):
39 return False
40 def getNextRandomImage(self):
41 raise FileListNotImplemented()
42 def getPrevRandomImage(self):
43 raise FileListNotImplemented()
44 def getCurrentImage(self):
45 raise FileListNotImplemented()
46 def attemptCacheLoad(self, filename, rescanPaths = False):
47 return False
48 def hasImages(self):
49 return False
50
51 class RandomFileList(BaseFileList):
52 def __init__(self):
53 self.list = []
54 self.paths = []
55 self.lastImage = None
56
57 def doScanPaths(self):
58 for path in self.paths:
59 for dirpath, dirsnames, filenames in os.walk(path):
60 for filename in filterImageFiles(filenames):
61 self.list.append(os.path.join(dirpath, filename))
62
63 def doAddPath(self, path):
64 self.paths.append(path)
65 debug('Added path "%s" to the list' % path, DEBUG_LEVEL_DEBUG)
66
67 def doStoreCache(self, filename):
68 pass
69
70 def getLastImage(self):
71 return self.lastImage
72
73 def getNextRandomImage(self):
74 n = random.randint(0, len(self.list)-1)
75 self.lastImage = self.list[n]
76 debug("Picked file '%s' from list" % self.lastImage)
77 return self.lastImage
78
79 def attemptCacheLoad(self, filename, rescanPaths = False):
80 return False
81
82 def hasImages(self):
83 return len(self.list) > 0
84
85
86 class AllRandomFileList(BaseFileList):
87 def __init__(self):
88 self.list = None
89 self.paths = []
90 self.imagePointer = 0
91
92 # Scan the input directory, and then randomize the file list
93 def doScanPaths(self):
94 debug("Scanning paths", DEBUG_LEVEL_DEBUG)
95
96 self.list = []
97 for path in self.paths:
98 debug('Scanning "%s"' % path, DEBUG_LEVEL_DEBUG)
99 print os.path.exists(path)
100 for dirpath, dirsnames, filenames in os.walk(path):
101 for filename in filterImageFiles(filenames):
102 debug('Adding file "%s"' % filename, DEBUG_LEVEL_DEBUG - 2*GregDebug.DEBUG_INCREMENT)
103 self.list.append(os.path.join(dirpath, filename))
104
105 random.shuffle(self.list)
106
107 def doAddPath(self, path):
108 self.paths.append(path)
109 debug('Added path "%s" to the list' % path, DEBUG_LEVEL_DEBUG)
110
111 def doStoreCache(self, filename):
112 fd = open(filename, 'wb')
113 cPickle.dump(obj = self, file = fd, protocol = 2)
114 debug("Cache successfully stored", DEBUG_LEVEL_LOW)
115 return True
116
117 def getCurrentImage(self):
118 return self.list[self.imagePointer]
119
120 def __incrementInRange(self, n, amount = 1, rangeMax = None, rangeMin = 0):
121 if rangeMax == None: rangeMax = len(self.list)
122 assert rangeMax > 0
123 return (n + amount) % rangeMax
124
125 def getNextRandomImage(self):
126 self.imagePointer = self.__incrementInRange(self.imagePointer)
127 imageName = self.list[self.imagePointer]
128 debug("Picked file '%s' (pointer=%d) from list" % (imageName, self.imagePointer))
129 return imageName
130
131 def getPrevRandomImage(self):
132 self.imagePointer = self.__incrementInRange(self.imagePointer, amount=-1)
133 imageName = self.list[self.imagePointer]
134 debug("Picked file '%s' (pointer=%d) from list" % (imageName, self.imagePointer))
135 return imageName
136
137 def attemptCacheLoad(self, filename, rescanPaths = False):
138 debug('Attempting to load cache from "%s"' % filename, DEBUG_LEVEL_DEBUG)
139 self.paths.sort()
140 try:
141 return self._attemptCacheLoad(filename)
142 except Exception, e:
143 debug("Exception while loading cache: '%s'" % e)
144
145 def _attemptCacheLoad(self, filename):
146 try:
147 fd = open(filename, 'rb')
148 tmp = cPickle.load(fd)
149 if self.paths == tmp.paths:
150 debug("Path lists match, copying properties", DEBUG_LEVEL_DEBUG)
151 # Overwrite this object with the other
152 for attr in ('list', 'imagePointer'):
153 setattr(self, attr, getattr(tmp, attr))
154 return True
155 else:
156 debug("Ignoring cache, path lists do not match", DEBUG_LEVEL_LOW)
157 return False
158 except IOError, e:
159 debug("Exception raised while trying to load cache: '%s'" % e)
160 return False
161
162 def hasImages(self):
163 return self.list
164
165 class FolderRandomFileList(BaseFileList):
166 """A file list that will pick a file randomly within a directory. Each directory
167 has the same chance of being chosen."""
168 def __init__(self):
169 self.directories = {}
170
171 def doScanPaths(self):
172 return True # Since it is already done
173
174 def doAddPath(self, path):
175 debug('Added path "%s" to the list' % path, DEBUG_LEVEL_DEBUG)
176 for dirpath, dirs, filenames in os.walk(path):
177 debug('Scanning "%s" for images' % dirpath)
178 if self.directories.has_key(dirpath):
179 continue
180 filenames = filterImageFiles(filenames)
181 if len(filenames):
182 self.directories[dirpath] = filenames
183 debug('Adding "%s" to "%s"' % (filenames, dirpath))
184 else:
185 debug("No images found in '%s'" % dirpath)
186
187 def getNextRandomImage(self):
188 directory = random.choice(self.directories.keys())
189 debug('directory: "%s"' % directory)
190 filename = random.choice(self.directories[directory])
191 debug('filename: "%s"' % filename)
192 return os.path.join(directory, filename)
193
194 def hasImages(self):
195 return len(self.directories.values())