+ self.scanning = []
+
+ # Init the database, remove old files, init the HTTP dirs
+ self.db.removeUntrackedFiles([self.cache_dir])
+ self.db.reconcileDirectories()
+ self.manager.setDirectories(self.db.getAllDirectories())
+
+
+ def scanDirectories(self):
+ """Scan the cache directories, hashing new and rehashing changed files."""
+ assert not self.scanning, "a directory scan is already under way"
+ self.scanning.append(self.cache_dir)
+ self._scanDirectories()
+
+ def _scanDirectories(self, walker = None):
+ # Need to start waling a new directory
+ if walker is None:
+ # If there are any left, get them
+ if self.scanning:
+ log.msg('started scanning directory: %s' % self.scanning[0].path)
+ walker = self.scanning[0].walk()
+ else:
+ # Done, just check if the HTTP directories need updating
+ log.msg('cache directory scan complete')
+ if self.db.reconcileDirectories():
+ self.manager.setDirectories(self.db.getAllDirectories())
+ return
+
+ try:
+ # Get the next file in the directory
+ file = walker.next()
+ except StopIteration:
+ # No files left, go to the next directory
+ log.msg('done scanning directory: %s' % self.scanning[0].path)
+ self.scanning.pop(0)
+ reactor.callLater(0, self._scanDirectories)
+ return
+
+ # If it's not a file, or it's already properly in the DB, ignore it
+ if not file.isfile() or self.db.isUnchanged(file):
+ if not file.isfile():
+ log.msg('entering directory: %s' % file.path)
+ else:
+ log.msg('file is unchanged: %s' % file.path)
+ reactor.callLater(0, self._scanDirectories, walker)
+ return
+
+ # Otherwise hash it
+ log.msg('start hash checking file: %s' % file.path)
+ hash = HashObject()
+ df = hash.hashInThread(file)
+ df.addBoth(self._doneHashing, file, walker)
+ df.addErrback(log.err)
+
+ def _doneHashing(self, result, file, walker):
+ reactor.callLater(0, self._scanDirectories, walker)