def __init__(self):
     QObject.__init__(self)
     self.cache = {}
     self.kio = KDirLister()
     self.kio.newItems.connect(self.kioFiles)
     self.kio.completed.connect(self.kioCompleted)
     self.includeFilters = []
     self.excludeFilters = []
class DirLister(QObject):
    fileFound = pyqtSignal("KUrl")
    directoryChanged = pyqtSignal("KUrl")
    completed = pyqtSignal()

    recursion = 0
    maxRecursion = 10

    def __init__(self):
        QObject.__init__(self)
        self.cache = {}
        self.kio = KDirLister()
        self.kio.newItems.connect(self.kioFiles)
        self.kio.completed.connect(self.kioCompleted)
        self.includeFilters = []
        self.excludeFilters = []

    def stop(self):
        self.kio.stop()

    def setIncludeFilters(self, filters):
        self.includeFilters = []
        for filter in filters.splitlines():
            if filter:
                try:
                    self.includeFilters.append(re.compile(filter))
                except re.error:
                    pass

    def setExcludeFilters(self, filters):
        self.excludeFilters = []
        for filter in filters.splitlines():
            if filter:
                try:
                    self.excludeFilters.append(re.compile(filter))
                except re.error:
                    pass

    def validMime(self, mime):
        if mime.name() == "application/octet-stream":
            return True

        if mime.name().startswith("text/"):
            return True

        for parentMime in mime.parentMimeTypes():
            if parentMime.startswith("text/"):
                return True

        return False

    def list(self, url, recurse=True):
        self.recursion = 0 if recurse else self.maxRecursion
        self.dirStack = []
        self.cachedOpenUrl(url)

    def cachedOpenUrl(self, url):
        self.cacheUrl = url.url()
        if self.cacheUrl in self.cache:
            self.kioFiles(self.cache[self.cacheUrl])
            self.kioCompleted()
        else:
            self.directoryChanged.emit(url)
            self.kio.openUrl(url)

    def kioCompleted(self):
        if self.dirStack:
            self.recursion, url = self.dirStack.pop()
            self.cachedOpenUrl(url)
        else:
            self.completed.emit()

    def kioFiles(self, itemlist):
        if type(itemlist) != list:
            urlList = []
            for item in itemlist:
                urlList.append(dict(url=item.url().url(), isDir=item.isDir()))
            self.cache[self.cacheUrl] = urlList

        urls = []

        for ifile in itemlist:
            if type(ifile) == dict:
                url = KUrl(ifile["url"])
                isDir = ifile["isDir"]
            else:
                url = ifile.url()
                isDir = ifile.isDir()

            path = url.url()
            if isDir and not path.endswith("/"):
                path += "/"

            if self.includeFilters:
                matched = False
                i = 0
                while not matched and i < len(self.includeFilters):
                    if self.includeFilters[i].search(path):
                        matched = True
                    i += 1
                if not matched:
                    continue

            if self.excludeFilters:
                matched = False
                for excludeFilter in self.excludeFilters:
                    if excludeFilter.search(path):
                        matched = True
                        break
                if matched:
                    continue

            if isDir:
                if self.recursion < self.maxRecursion:
                    self.dirStack.append((self.recursion + 1, url))
            else:
                mime = KMimeType.findByUrl(url)[0]
                if self.validMime(mime):
                    urls.append(url)

        urls = sorted(urls, lambda a, b: -1 if len(a.url()) < len(b.url()) else 1)

        for url in urls:
            self.fileFound.emit(url)