From 338a090081a886fdf2e4d32eadcbd724a8f70fce Mon Sep 17 00:00:00 2001 From: hewenfei Date: Mon, 25 Apr 2022 11:16:25 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=86=85=E5=AE=B9=E6=90=9C=E7=B4=A2=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libsearch/common.h | 3 + .../search-task-plugin-manager.cpp | 14 +- .../searchtasks/file-content-search-task.cpp | 194 ++++++++++++++++++ .../searchtasks/file-content-search-task.h | 78 +++++++ .../searchtasks/search-tasks.pri | 6 +- 5 files changed, 290 insertions(+), 5 deletions(-) create mode 100644 libsearch/searchinterface/searchtasks/file-content-search-task.cpp create mode 100644 libsearch/searchinterface/searchtasks/file-content-search-task.h diff --git a/libsearch/common.h b/libsearch/common.h index 83dac72..56cbc96 100644 --- a/libsearch/common.h +++ b/libsearch/common.h @@ -4,6 +4,9 @@ #include #include +#define CONTENT_DATABASE_PATH_SLOT 1 +#define CONTENT_DATABASE_SUFFIX_SLOT 2 + static const int LABEL_MAX_WIDTH = 300; static const QString HOME_PATH = QDir::homePath(); diff --git a/libsearch/pluginmanage/search-task-plugin-manager.cpp b/libsearch/pluginmanage/search-task-plugin-manager.cpp index 3678d26..19e21ef 100644 --- a/libsearch/pluginmanage/search-task-plugin-manager.cpp +++ b/libsearch/pluginmanage/search-task-plugin-manager.cpp @@ -2,6 +2,8 @@ #include #include "file-search-task.h" +#include "file-content-search-task.h" + using namespace UkuiSearch; static SearchTaskPluginManager *global_instance = nullptr; SearchTaskPluginManager *SearchTaskPluginManager::getInstance() @@ -14,9 +16,15 @@ SearchTaskPluginManager *SearchTaskPluginManager::getInstance() void SearchTaskPluginManager::initPlugins(SearchType searchType) { - size_t type = static_cast(searchType); - if (type & static_cast(SearchType::File)) { - registerBuildinPlugin(new FileSearchTask(this)); + switch (searchType) { + case SearchType::File: + registerBuildinPlugin(new FileSearchTask(this)); + break; + case SearchType::FileContent: + registerBuildinPlugin(new FileContentSearchTask(this)); + break; + default: + break; } } diff --git a/libsearch/searchinterface/searchtasks/file-content-search-task.cpp b/libsearch/searchinterface/searchtasks/file-content-search-task.cpp new file mode 100644 index 0000000..c6507c3 --- /dev/null +++ b/libsearch/searchinterface/searchtasks/file-content-search-task.cpp @@ -0,0 +1,194 @@ +// +// Created by hxf on 2022/4/18. +// + +//ukui-search +#include "file-content-search-task.h" +#include "index-status-recorder.h" +#include "chinese-segmentation.h" +#include "result-item.h" +#include "common.h" +#include "file-utils.h" + +//Qt +#include +#include +#include + +using namespace UkuiSearch; + +FileContentSearchTask::FileContentSearchTask(QObject *parent) +{ + this->setParent(parent); + qRegisterMetaType("size_t"); + m_pool = new QThreadPool(this); + m_pool->setMaxThreadCount(1); +} + +FileContentSearchTask::~FileContentSearchTask() +{ + +} + +PluginInterface::PluginType FileContentSearchTask::pluginType() +{ + return PluginType::SearchTaskPlugin; +} + +const QString FileContentSearchTask::name() +{ + return "File Content"; +} + +const QString FileContentSearchTask::description() +{ + return "File Content Search"; +} + +const QIcon FileContentSearchTask::icon() +{ + return QIcon::fromTheme("folder"); +} + +void FileContentSearchTask::setEnable(bool enable) +{ + +} + +bool FileContentSearchTask::isEnable() +{ + return true; +} + +QString FileContentSearchTask::getCustomSearchType() +{ + return "File Content"; +} + +SearchType FileContentSearchTask::getSearchType() +{ + return SearchType::FileContent; +} + +void FileContentSearchTask::startSearch(std::shared_ptr searchController) +{ + FileContentSearchWorker *worker = new FileContentSearchWorker(this, searchController); + m_pool->start(worker); +} + +void FileContentSearchTask::stop() +{ + +} + +void FileContentSearchTask::sendFinishSignal(size_t searchId) +{ + Q_EMIT sendFinishSignal(searchId); +} + +FileContentSearchWorker::FileContentSearchWorker(FileContentSearchTask *fileContentSearchTask, std::shared_ptr searchController) +{ + m_fileContentSearchTask = fileContentSearchTask; + m_searchController = std::move(searchController); + m_currentSearchId = m_searchController->getCurrentSearchId(); +} + +void FileContentSearchWorker::run() +{ + QStringList searchDirs = m_searchController->getSearchDir(); + searchDirs.removeDuplicates(); + + for (QString &dir : searchDirs) { + if (dir.endsWith("/")) { + dir = dir.mid(0, dir.length() - 1); + } + + //TODO 指定黑名单 + m_validDirectories.append(dir); + } + + bool finished = true; + if (IndexStatusRecorder::getInstance()->contentIndexDatabaseEnable()) { + qDebug() << "content index ready"; + finished = execSearch(); + + } else { + qWarning() << "content index incomplete"; + } + + if (finished) QMetaObject::invokeMethod(m_fileContentSearchTask, "searchFinished", Q_ARG(size_t, m_currentSearchId)); +} + +bool FileContentSearchWorker::execSearch() +{ + try { + Xapian::Database db(CONTENT_INDEX_PATH.toStdString()); + Xapian::Enquire enquire(db); + + enquire.set_query(createQuery()); + + FileContentSearchFilter filter(this); + + Xapian::MSet result = enquire.get_mset(m_searchController->first(), m_searchController->maxResults(), 0, &filter); + + for (auto it = result.begin(); it != result.end(); ++it) { + if (m_searchController->beginSearchIdCheck(m_currentSearchId)) { + QString path = QString::fromStdString(it.get_document().get_value(CONTENT_DATABASE_PATH_SLOT)); + + ResultItem resultItem(m_currentSearchId, path); + m_searchController->getDataQueue()->enqueue(resultItem); + m_searchController->finishSearchIdCheck(); + + } else { + qDebug() << "Search id changed!"; + m_searchController->finishSearchIdCheck(); + return false; + } + } + + return true; + + } catch (const Xapian::Error &e) { + qWarning() << QString::fromStdString(e.get_description()); + return false; + } +} + +inline Xapian::Query FileContentSearchWorker::createQuery() +{ + std::vector v; + + for (const auto &keyword : m_searchController->getKeyword()) { + QVector sKeyWord = ChineseSegmentation::getInstance()->callSegement(keyword.toStdString()); + + for(const auto & c : sKeyWord) { + v.emplace_back(c.word); + } + } + + return {Xapian::Query::OP_AND, v.begin(), v.end()}; +} + + +FileContentSearchFilter::FileContentSearchFilter(FileContentSearchWorker *worker) : m_worker(worker) +{ + +} + +bool FileContentSearchFilter::operator()(const Xapian::Document &doc) const +{ + //在此处对搜索结果进行过滤 + QString path = QString::fromStdString(doc.get_value(CONTENT_DATABASE_PATH_SLOT)); + bool isExists = QFileInfo::exists(path); + bool inSearchDir = true; + + //如果不指定搜索目录,那么搜索整个数据库 + if (m_worker && !m_worker->m_validDirectories.empty()) { + inSearchDir = std::any_of(m_worker->m_validDirectories.begin(), m_worker->m_validDirectories.end(), [=] (const QString& dir) { + return path.startsWith(dir); + }); + //TODO 黑名单 + } + + return isExists && inSearchDir; +} diff --git a/libsearch/searchinterface/searchtasks/file-content-search-task.h b/libsearch/searchinterface/searchtasks/file-content-search-task.h new file mode 100644 index 0000000..a8fc358 --- /dev/null +++ b/libsearch/searchinterface/searchtasks/file-content-search-task.h @@ -0,0 +1,78 @@ +// +// Created by hxf on 2022/4/18. +// + +#ifndef UKUI_SEARCH_FILE_CONTENT_SEARCH_TASK_H +#define UKUI_SEARCH_FILE_CONTENT_SEARCH_TASK_H + +//ukui-search +#include "search-task-plugin-iface.h" + +//Qt +#include +#include + +//Xapian +#include + +namespace UkuiSearch { + +class FileContentSearchTask : public SearchTaskPluginIface +{ +public: + explicit FileContentSearchTask(QObject *parent = nullptr); + + ~FileContentSearchTask() override; + + PluginType pluginType() override; + const QString name() override; + const QString description() override; + const QIcon icon() override; + void setEnable(bool enable) override; + bool isEnable() override; + + QString getCustomSearchType() override; + SearchType getSearchType() override; + void startSearch(std::shared_ptr searchController) override; + void stop() override; + + Q_INVOKABLE void sendFinishSignal(size_t searchId); + +private: + QThreadPool *m_pool = nullptr; +}; + +class FileContentSearchWorker : public QRunnable +{ + friend class FileContentSearchFilter; + +public: + explicit FileContentSearchWorker(FileContentSearchTask *fileContentSearchTask, std::shared_ptr searchController); + + void run() override; + +private: + bool execSearch(); + inline Xapian::Query createQuery(); + +private: + FileContentSearchTask *m_fileContentSearchTask = nullptr; + std::shared_ptr m_searchController; + + QStringList m_validDirectories; + + size_t m_currentSearchId = 0; +}; + +class FileContentSearchFilter : public Xapian::MatchDecider { +public: + explicit FileContentSearchFilter(FileContentSearchWorker*); + bool operator ()(const Xapian::Document &doc) const override; + +private: + FileContentSearchWorker *m_worker; +}; + +} + +#endif //UKUI_SEARCH_FILE_CONTENT_SEARCH_TASK_H diff --git a/libsearch/searchinterface/searchtasks/search-tasks.pri b/libsearch/searchinterface/searchtasks/search-tasks.pri index b1f5c08..7bf36a7 100644 --- a/libsearch/searchinterface/searchtasks/search-tasks.pri +++ b/libsearch/searchinterface/searchtasks/search-tasks.pri @@ -1,9 +1,11 @@ INCLUDEPATH += $$PWD HEADERS += \ - $$PWD/file-search-task.h + $$PWD/file-search-task.h \ + $$PWD/file-content-search-task.h SOURCES += \ - $$PWD/file-search-task.cpp + $$PWD/file-search-task.cpp \ + $$PWD/file-content-search-task.cpp From d5ddceee51d50c3e6de282648d789f61bd9595e9 Mon Sep 17 00:00:00 2001 From: hewenfei Date: Tue, 26 Apr 2022 10:43:02 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=90=9C=E7=B4=A2?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E4=BF=A1=E5=8F=B7=EF=BC=8C=E9=80=9A=E7=9F=A5?= =?UTF-8?q?=E8=B0=83=E7=94=A8=E8=80=85=E6=90=9C=E7=B4=A2=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=E7=9A=84=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugininterface/search-task-plugin-iface.h | 1 + .../pluginmanage/search-task-plugin-manager.cpp | 10 ++++++++-- .../pluginmanage/search-task-plugin-manager.h | 3 ++- .../searchtasks/file-content-search-task.cpp | 16 +++++++++++----- .../searchtasks/file-content-search-task.h | 4 ++-- .../searchtasks/file-search-task.cpp | 9 +++++++++ .../searchtasks/file-search-task.h | 1 + libsearch/searchinterface/ukui-search-task.cpp | 1 + libsearch/searchinterface/ukui-search-task.h | 1 + 9 files changed, 36 insertions(+), 10 deletions(-) diff --git a/libsearch/plugininterface/search-task-plugin-iface.h b/libsearch/plugininterface/search-task-plugin-iface.h index c905355..24ee89f 100644 --- a/libsearch/plugininterface/search-task-plugin-iface.h +++ b/libsearch/plugininterface/search-task-plugin-iface.h @@ -21,6 +21,7 @@ public: virtual void stop() = 0; Q_SIGNALS: void searchFinished(size_t searchId); + void searchError(size_t searchId, QString msg = {}); }; } Q_DECLARE_INTERFACE(UkuiSearch::SearchTaskPluginIface, SearchTaskPluginIface_iid) diff --git a/libsearch/pluginmanage/search-task-plugin-manager.cpp b/libsearch/pluginmanage/search-task-plugin-manager.cpp index 19e21ef..7867137 100644 --- a/libsearch/pluginmanage/search-task-plugin-manager.cpp +++ b/libsearch/pluginmanage/search-task-plugin-manager.cpp @@ -39,6 +39,7 @@ bool SearchTaskPluginManager::registerPlugin(SearchTaskPluginIface *plugin) } m_loadedPlugin.insert(plugin->getCustomSearchType(), plugin); connect(plugin, &SearchTaskPluginIface::searchFinished, this, &SearchTaskPluginManager::searchFinished); + connect(plugin, &SearchTaskPluginIface::searchError, this, &SearchTaskPluginManager::searchError); return true; } @@ -46,6 +47,7 @@ bool SearchTaskPluginManager::registerBuildinPlugin(SearchTaskPluginIface *plugi { m_buildinPlugin.insert(static_cast(plugin->getSearchType()), plugin); connect(plugin, &SearchTaskPluginIface::searchFinished, this, &SearchTaskPluginManager::searchFinished); + connect(plugin, &SearchTaskPluginIface::searchError, this, &SearchTaskPluginManager::searchError); return true; } @@ -59,11 +61,13 @@ void SearchTaskPluginManager::pluginSearch(SearchType searchType, std::shared_pt qDebug() << "search type" << type; if(m_buildinPlugin.contains(type)) { if(!m_buildinPlugin.value(type)->isEnable()) { - Q_EMIT this->pluginDisable(searchController.get()->getCurrentSearchId()); + Q_EMIT this->searchError(searchController.get()->getCurrentSearchId(), tr("plugin type: %1, is disabled!").arg(type)); return; } qDebug() << "start search"; m_buildinPlugin.value(type)->startSearch(searchController); + } else { + Q_EMIT this->searchError(searchController.get()->getCurrentSearchId(), tr("plugin type: %1, is not registered!").arg(type)); } } @@ -71,9 +75,11 @@ void SearchTaskPluginManager::pluginSearch(QString customSearchType, std::shared { if(m_loadedPlugin.contains(customSearchType)) { if(!m_loadedPlugin.value(customSearchType)->isEnable()) { - Q_EMIT this->pluginDisable(searchController.get()->getCurrentSearchId()); + Q_EMIT this->searchError(searchController.get()->getCurrentSearchId(), tr("plugin type: %1, is disabled!").arg(customSearchType)); return; } m_loadedPlugin.value(customSearchType)->startSearch(searchController); + } else { + Q_EMIT this->searchError(searchController.get()->getCurrentSearchId(), tr("plugin type: %1, is not registered!").arg(customSearchType)); } } diff --git a/libsearch/pluginmanage/search-task-plugin-manager.h b/libsearch/pluginmanage/search-task-plugin-manager.h index 0c6f751..d94087f 100644 --- a/libsearch/pluginmanage/search-task-plugin-manager.h +++ b/libsearch/pluginmanage/search-task-plugin-manager.h @@ -17,7 +17,8 @@ public: void pluginSearch(QString customSearchType, std::shared_ptr searchController); Q_SIGNALS: void searchFinished(size_t searchId); - void pluginDisable(size_t searchId); + void searchError(size_t searchId, QString msg); + private: explicit SearchTaskPluginManager(QObject *parent = nullptr); diff --git a/libsearch/searchinterface/searchtasks/file-content-search-task.cpp b/libsearch/searchinterface/searchtasks/file-content-search-task.cpp index c6507c3..ea9e272 100644 --- a/libsearch/searchinterface/searchtasks/file-content-search-task.cpp +++ b/libsearch/searchinterface/searchtasks/file-content-search-task.cpp @@ -81,11 +81,6 @@ void FileContentSearchTask::stop() } -void FileContentSearchTask::sendFinishSignal(size_t searchId) -{ - Q_EMIT sendFinishSignal(searchId); -} - FileContentSearchWorker::FileContentSearchWorker(FileContentSearchTask *fileContentSearchTask, std::shared_ptr searchController) { m_fileContentSearchTask = fileContentSearchTask; @@ -114,11 +109,21 @@ void FileContentSearchWorker::run() } else { qWarning() << "content index incomplete"; + sendErrorMsg(QObject::tr("Content index incomplete.")); + + finished = false; } if (finished) QMetaObject::invokeMethod(m_fileContentSearchTask, "searchFinished", Q_ARG(size_t, m_currentSearchId)); } +void FileContentSearchWorker::sendErrorMsg(const QString &msg) +{ + QMetaObject::invokeMethod(m_fileContentSearchTask, "searchError", + Q_ARG(size_t, m_currentSearchId), + Q_ARG(QString, msg)); +} + bool FileContentSearchWorker::execSearch() { try { @@ -150,6 +155,7 @@ bool FileContentSearchWorker::execSearch() } catch (const Xapian::Error &e) { qWarning() << QString::fromStdString(e.get_description()); + sendErrorMsg("Xapian Error: " + QString::fromStdString(e.get_description())); return false; } } diff --git a/libsearch/searchinterface/searchtasks/file-content-search-task.h b/libsearch/searchinterface/searchtasks/file-content-search-task.h index a8fc358..a77d9f2 100644 --- a/libsearch/searchinterface/searchtasks/file-content-search-task.h +++ b/libsearch/searchinterface/searchtasks/file-content-search-task.h @@ -36,8 +36,6 @@ public: void startSearch(std::shared_ptr searchController) override; void stop() override; - Q_INVOKABLE void sendFinishSignal(size_t searchId); - private: QThreadPool *m_pool = nullptr; }; @@ -55,6 +53,8 @@ private: bool execSearch(); inline Xapian::Query createQuery(); + void sendErrorMsg(const QString &msg); + private: FileContentSearchTask *m_fileContentSearchTask = nullptr; std::shared_ptr m_searchController; diff --git a/libsearch/searchinterface/searchtasks/file-search-task.cpp b/libsearch/searchinterface/searchtasks/file-search-task.cpp index a332bb7..241d019 100644 --- a/libsearch/searchinterface/searchtasks/file-search-task.cpp +++ b/libsearch/searchinterface/searchtasks/file-search-task.cpp @@ -144,11 +144,20 @@ bool FileSearchWorker::searchWithIndex() } catch(const Xapian::Error &e) { qWarning() << QString::fromStdString(e.get_description()); + sendErrorMsg("Xapian Error: " + QString::fromStdString(e.get_description())); + return false; } return true; } +void FileSearchWorker::sendErrorMsg(const QString &msg) +{ + QMetaObject::invokeMethod(m_FileSearchTask, "searchError", + Q_ARG(size_t, m_currentSearchId), + Q_ARG(QString, msg)); +} + bool FileSearchWorker::directSearch() { unsigned int maxResults = m_searchController->maxResults(); diff --git a/libsearch/searchinterface/searchtasks/file-search-task.h b/libsearch/searchinterface/searchtasks/file-search-task.h index bbbe18a..428b603 100644 --- a/libsearch/searchinterface/searchtasks/file-search-task.h +++ b/libsearch/searchinterface/searchtasks/file-search-task.h @@ -57,6 +57,7 @@ private: //同上 bool directSearch(); Xapian::Query creatQueryForFileSearch(); + void sendErrorMsg(const QString &msg); private: FileSearchTask *m_FileSearchTask; diff --git a/libsearch/searchinterface/ukui-search-task.cpp b/libsearch/searchinterface/ukui-search-task.cpp index 312256b..e272667 100644 --- a/libsearch/searchinterface/ukui-search-task.cpp +++ b/libsearch/searchinterface/ukui-search-task.cpp @@ -9,6 +9,7 @@ UkuiSearchTaskPrivate::UkuiSearchTaskPrivate(UkuiSearchTask *parent) { m_searchCotroller = std::shared_ptr(new SearchController()); connect(SearchTaskPluginManager::getInstance(), &SearchTaskPluginManager::searchFinished, this, &UkuiSearchTaskPrivate::searchFinished); + connect(SearchTaskPluginManager::getInstance(), &SearchTaskPluginManager::searchError, q, &UkuiSearchTask::searchError); } UkuiSearchTaskPrivate::~UkuiSearchTaskPrivate() diff --git a/libsearch/searchinterface/ukui-search-task.h b/libsearch/searchinterface/ukui-search-task.h index 7b27ca8..e9ed5eb 100644 --- a/libsearch/searchinterface/ukui-search-task.h +++ b/libsearch/searchinterface/ukui-search-task.h @@ -31,6 +31,7 @@ public: Q_SIGNALS: void searchFinished(size_t searchId); + void searchError(size_t searchId, QString msg); private: UkuiSearchTaskPrivate* d = nullptr; From 95ccbf787f36e2350d1222a425839a9922d2fde6 Mon Sep 17 00:00:00 2001 From: hewenfei Date: Tue, 26 Apr 2022 14:33:06 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E6=A0=B9=E6=8D=AEreview=E6=84=8F=E8=A7=81?= =?UTF-8?q?=E6=9B=B4=E6=94=B9=E9=83=A8=E5=88=86=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../searchtasks/file-content-search-task.cpp | 12 ++++++------ .../searchtasks/file-content-search-task.h | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/libsearch/searchinterface/searchtasks/file-content-search-task.cpp b/libsearch/searchinterface/searchtasks/file-content-search-task.cpp index ea9e272..b855d18 100644 --- a/libsearch/searchinterface/searchtasks/file-content-search-task.cpp +++ b/libsearch/searchinterface/searchtasks/file-content-search-task.cpp @@ -37,32 +37,32 @@ PluginInterface::PluginType FileContentSearchTask::pluginType() const QString FileContentSearchTask::name() { - return "File Content"; + return tr("File Content"); } const QString FileContentSearchTask::description() { - return "File Content Search"; + return tr("File Content Search"); } const QIcon FileContentSearchTask::icon() { - return QIcon::fromTheme("folder"); + return QIcon::fromTheme("folder", QIcon(":/unknown.svg")); } void FileContentSearchTask::setEnable(bool enable) { - + e_enable = enable; } bool FileContentSearchTask::isEnable() { - return true; + return e_enable && IndexStatusRecorder::getInstance()->contentIndexDatabaseEnable(); } QString FileContentSearchTask::getCustomSearchType() { - return "File Content"; + return tr("File Content"); } SearchType FileContentSearchTask::getSearchType() diff --git a/libsearch/searchinterface/searchtasks/file-content-search-task.h b/libsearch/searchinterface/searchtasks/file-content-search-task.h index a77d9f2..82ff757 100644 --- a/libsearch/searchinterface/searchtasks/file-content-search-task.h +++ b/libsearch/searchinterface/searchtasks/file-content-search-task.h @@ -38,6 +38,7 @@ public: private: QThreadPool *m_pool = nullptr; + bool e_enable = true; }; class FileContentSearchWorker : public QRunnable