File indexing completed on 2024-05-12 15:51:17
0001 // SPDX-FileCopyrightText: 2015 Dan Leinir Turthra Jensen <admin@leinir.dk> 0002 // SPDX-FileCopyrightText: 2022 Carl Schwan <carl@carlschwan.eu> 0003 // SPDX-License-Identifier: LGPL-2.1-only or LGPL-3.0-only or LicenseRef-KDE-Accepted-LGPL 0004 0005 #include "filesystemcontentlister.h" 0006 0007 #include <KFileMetaData/UserMetaData> 0008 0009 #include <QCoreApplication> 0010 #include <QDateTime> 0011 #include <QDirIterator> 0012 #include <QMimeDatabase> 0013 #include <QRunnable> 0014 #include <QThreadPool> 0015 #include <QTimer> 0016 #include <QVariantHash> 0017 0018 #include "contentquery.h" 0019 0020 class FileSystemSearcher : public QObject, public QRunnable 0021 { 0022 Q_OBJECT 0023 public: 0024 FileSystemSearcher(ContentQuery *query) 0025 : QObject() 0026 { 0027 m_query = query; 0028 } 0029 0030 void run() override 0031 { 0032 QMimeDatabase mimeDb; 0033 0034 auto locations = m_query->locations(); 0035 if (locations.isEmpty()) 0036 locations.append(QDir::homePath()); 0037 0038 for (const auto &location : locations) { 0039 QDirIterator it(location, QDirIterator::Subdirectories); 0040 while (it.hasNext()) { 0041 auto filePath = it.next(); 0042 0043 if (it.fileInfo().isDir()) 0044 continue; 0045 0046 if (!m_query->mimeTypes().isEmpty()) { 0047 QString mimeType = mimeDb.mimeTypeForFile(filePath).name(); 0048 if (!m_query->mimeTypes().contains(mimeType)) { 0049 continue; 0050 } 0051 } 0052 0053 auto metadata = ContentListerBase::metaDataForFile(filePath); 0054 0055 Q_EMIT fileFound(filePath, metadata); 0056 } 0057 } 0058 0059 Q_EMIT finished(this); 0060 } 0061 0062 Q_SIGNALS: 0063 void fileFound(const QString &path, const QVariantMap &metaData); 0064 void finished(FileSystemSearcher *searcher); 0065 0066 private: 0067 ContentQuery *m_query; 0068 }; 0069 0070 class FilesystemContentLister::Private 0071 { 0072 public: 0073 Private() 0074 { 0075 } 0076 0077 QList<FileSystemSearcher *> runnables; 0078 }; 0079 0080 FilesystemContentLister::FilesystemContentLister(QObject *parent) 0081 : ContentListerBase(parent) 0082 , d(std::make_unique<Private>()) 0083 { 0084 } 0085 0086 FilesystemContentLister::~FilesystemContentLister() 0087 { 0088 QThreadPool::globalInstance()->waitForDone(); 0089 } 0090 0091 void FilesystemContentLister::startSearch(const QList<ContentQuery *> &queries) 0092 { 0093 for (const auto &query : queries) { 0094 auto runnable = new FileSystemSearcher{query}; 0095 connect(runnable, &FileSystemSearcher::fileFound, this, &FilesystemContentLister::fileFound); 0096 connect(runnable, &FileSystemSearcher::finished, this, &FilesystemContentLister::queryFinished); 0097 0098 d->runnables.append(runnable); 0099 } 0100 0101 if (!d->runnables.isEmpty()) { 0102 QThreadPool::globalInstance()->start(d->runnables.first()); 0103 } 0104 } 0105 0106 void FilesystemContentLister::queryFinished(QRunnable *runnable) 0107 { 0108 d->runnables.removeAll(static_cast<FileSystemSearcher *>(runnable)); 0109 0110 if (!d->runnables.isEmpty()) { 0111 QThreadPool::globalInstance()->start(d->runnables.first()); 0112 } else { 0113 Q_EMIT searchCompleted(); 0114 } 0115 } 0116 0117 #include "filesystemcontentlister.moc" 0118 0119 #include "moc_filesystemcontentlister.cpp"