diff --git a/data/ukui-search-service-dir-manager.desktop b/data/ukui-search-service-dir-manager.desktop new file mode 100644 index 0000000..ce75ff8 --- /dev/null +++ b/data/ukui-search-service-dir-manager.desktop @@ -0,0 +1,15 @@ +[Desktop Entry] +Name=ukui-search-service-dir-manager +Name[zh_CN]=搜索服务目录管理 +GenericName=ukui-search-service-dir-manager +GenericName[zh_CN]=搜索服务目录管理 +Comment=ukui-search-service-dir-manager +Comment[zh_CN]=搜索服务目录管理 +Exec=/usr/bin/ukui-search-service-dir-manager %U +Type=Application +Icon=kylin-search +X-UKUI-AutoRestart=true +OnlyShowIn=UKUI +NoDisplay=true +X-UKUI-Autostart-Phase=Application +Terminal=false diff --git a/libsearch/dirwatcher/dir-watcher.cpp b/libsearch/dirwatcher/dir-watcher.cpp index a1de484..b9322fb 100644 --- a/libsearch/dirwatcher/dir-watcher.cpp +++ b/libsearch/dirwatcher/dir-watcher.cpp @@ -1,37 +1,19 @@ #include "dir-watcher.h" #include -#include -#include -#include #include -#include -#include - -#define CURRENT_INDEXABLE_DIR_SETTINGS QDir::homePath() + "/.config/org.ukui/ukui-search/ukui-search-current-indexable-dir.conf" -#define INDEXABLE_DIR_VALUE "IndexableDir" static std::once_flag flag; static DirWatcher *global_intance = nullptr; -QMutex DirWatcher::s_mutex; DirWatcher::DirWatcher(QObject *parent) : QObject(parent) { - m_qSettings = new QSettings(CURRENT_INDEXABLE_DIR_SETTINGS, QSettings::IniFormat); - initData(); - initDiskWatcher(); - m_adaptor = new DirWatcherAdaptor(this); -} - -DirWatcher::~DirWatcher() -{ - if (m_volumeMonitor) { - g_signal_handler_disconnect(m_volumeMonitor, m_mountAddHandle); - g_signal_handler_disconnect(m_volumeMonitor, m_mountRemoveHandle); - m_volumeMonitor = nullptr; - } - if(m_qSettings){ - delete m_qSettings; + m_dbusInterface = new QDBusInterface("com.ukui.search.fileindex.service", + "/org/ukui/search/privateDirWatcher", + "org.ukui.search.fileindex"); + if (!m_dbusInterface->isValid()) { + qCritical() << "Create privateDirWatcher Interface Failed Because: " << QDBusConnection::sessionBus().lastError(); + return; } } @@ -45,54 +27,31 @@ DirWatcher *DirWatcher::getDirWatcher() void DirWatcher::initDbusService() { - //注册服务 - QDBusConnection sessionBus = QDBusConnection::sessionBus(); - if (!sessionBus.registerService("com.ukui.search.fileindex.service")) { - qWarning() << "ukui-search-fileindex dbus register service failed reason:" << sessionBus.lastError(); - } - - if(!sessionBus.registerObject("/org/ukui/search/fileindex", this, QDBusConnection::ExportAdaptors)){ - qWarning() << "ukui-search-fileindex dbus register object failed reason:" << sessionBus.lastError(); + QDBusReply reply = m_dbusInterface->call("initDbusService"); + if (!reply.isValid()) { + qCritical() << "initDbusService call filed!"; } } -QStringList DirWatcher::currentindexableDir() +QStringList DirWatcher::currentIndexableDir() { - QMutexLocker locker(&s_mutex); - m_qSettings->beginGroup(INDEXABLE_DIR_VALUE); - m_indexableDirList = m_qSettings->value(INDEXABLE_DIR_VALUE).toStringList(); - m_qSettings->endGroup(); - QStringList indexableDirs = m_indexableDirList; - return indexableDirs; + + QDBusReply reply = m_dbusInterface->call("currentIndexableDir"); + if (!reply.isValid()) { + qCritical() << "currentIndexableDir call filed!"; + return QStringList(); + } + return reply.value(); } QStringList DirWatcher::currentBlackListOfIndex() { - QMutexLocker locker(&s_mutex); - QStringList blackListOfIndex = m_blackListOfIndex; - return blackListOfIndex; -} - -void DirWatcher::handleIndexItemAppend(const QString &path, QStringList &blackList) -{ - if (m_indexableDirList.contains(path)) { - qDebug() << QString("index path %1 is already added.").arg(path); - return; + QDBusReply reply = m_dbusInterface->call("currentBlackListOfIndex"); + if (!reply.isValid()) { + qCritical() << "currentBlackListOfIndex call filed!"; + return QStringList(); } - m_indexableDirList << path; - m_qSettings->beginGroup(INDEXABLE_DIR_VALUE); - m_qSettings->setValue(INDEXABLE_DIR_VALUE, m_indexableDirList); - m_qSettings->endGroup(); - Q_EMIT this->appendIndexItem(path, blackList); - qDebug() << "index path:" << path << "blacklist:" << blackList; -} - -void DirWatcher::handleIndexItemRemove(const QString &path) -{ - m_indexableDirList.removeAll(path); - m_qSettings->beginGroup(INDEXABLE_DIR_VALUE); - m_qSettings->setValue(INDEXABLE_DIR_VALUE, m_indexableDirList); - m_qSettings->endGroup(); + return reply.value(); } /** @@ -101,322 +60,46 @@ void DirWatcher::handleIndexItemRemove(const QString &path) */ QStringList DirWatcher::blackListOfDir(const QString &dirPath) { - //new TODO: Optimize the search algorithm. - //There is no processing for the subvolumes.May be a bug. - QStringList blackListOfDir; - QMutexLocker locker(&s_mutex); - for (auto t = m_repeatedlyMountedDeviceInfo.constBegin(); t != m_repeatedlyMountedDeviceInfo.constEnd(); t++) { - QString topRepeatedMountPoint; - for (QString mountPoint: t.value()) { - if (mountPoint.startsWith(dirPath)) { - if (topRepeatedMountPoint.isEmpty()) { - topRepeatedMountPoint = mountPoint; - continue; - } else if (topRepeatedMountPoint.startsWith(mountPoint)) { - blackListOfDir.append(topRepeatedMountPoint); - topRepeatedMountPoint = mountPoint; - } else { - blackListOfDir.append(mountPoint); - } - } - } - } - for (auto i = m_infoOfSubvolume.constBegin(); i != m_infoOfSubvolume.constEnd(); i++) { - QString mountPoint = i.value(); - QString spec = i.key(); - //排除搜索列表指定多个目录时子卷会重复包含的情况,比如同时指定/home和/data/home - QString tmp = dirPath; - if (dirPath.startsWith(mountPoint)) { - blackListOfDir.append(tmp.replace(0, mountPoint.length(), spec)); - } - if (dirPath.startsWith(spec)) { - blackListOfDir.append(tmp.replace(0, spec.length(), mountPoint)); - } - } - return blackListOfDir; -} - -void DirWatcher::appendBlackListItemOfIndex(const QString &path) -{ - QMutexLocker locker(&s_mutex); - m_blackListOfIndex.append(path); - m_blackListOfIndex = m_blackListOfIndex.toSet().toList(); -} - -void DirWatcher::appendBlackListItemOfIndex(const QStringList &pathList) -{ - QMutexLocker locker(&s_mutex); - m_blackListOfIndex.append(pathList); - m_blackListOfIndex = m_blackListOfIndex.toSet().toList(); -} - -void DirWatcher::removeBlackListItemOfIndex(const QString &path) -{ - QMutexLocker locker(&s_mutex); - m_blackListOfIndex.removeAll(path); -} - -void DirWatcher::removeBlackListItemOfIndex(const QStringList &pathList) -{ - QMutexLocker locker(&s_mutex); - for (QString path: pathList) { - m_blackListOfIndex.removeAll(path); + QDBusReply reply = m_dbusInterface->call("blackListOfDir", dirPath); + if (!reply.isValid()) { + qCritical() << "blackListOfDir call filed!"; + return QStringList(); } + return reply.value(); } QStringList DirWatcher::currentSearchableDir() { - QMutexLocker locker(&s_mutex); - return m_searchableDirList; + QDBusReply reply = m_dbusInterface->call("currentSearchableDir"); + if (!reply.isValid()) { + qCritical() << "currentSearchableDir call filed!"; + return QStringList(); + } + return reply.value(); } QStringList DirWatcher::searchableDirForSearchApplication() { - QMutexLocker locker(&s_mutex); - return m_searchableListForApplication; -} - -void DirWatcher::mountAddCallback(GVolumeMonitor *monitor, GMount *gmount, DirWatcher *pThis) -{ - qDebug() << "Mount Added"; - pThis->handleDisk(); -} - -void DirWatcher::mountRemoveCallback(GVolumeMonitor *monitor, GMount *gmount, DirWatcher *pThis) -{ - qDebug() << "Mount Removed"; - QMutexLocker locker(&s_mutex); - //处理u盘设备 - if (pThis->m_removedUDiskDevice != NULL) { - pThis->m_currentUDiskDeviceInfo.remove(pThis->m_removedUDiskDevice); - qDebug() << "m_currentMountedDeviceInfo:" << pThis->m_currentMountedDeviceInfo; - qDebug() << "m_repeatedlyMountedDeviceInfo:" << pThis->m_repeatedlyMountedDeviceInfo; - qDebug() << "m_currentUDiskDeviceInfo:" << pThis->m_currentUDiskDeviceInfo; - qDebug() << "m_blackListOfIndex:" << pThis->m_blackListOfIndex; - pThis->m_removedUDiskDevice = ""; - return; + QDBusReply reply = m_dbusInterface->call("searchableDirForSearchApplication"); + if (!reply.isValid()) { + qCritical() << "searchableDirForSearchApplication call filed!"; + return QStringList(); } - - GMount* mount = (GMount*)g_object_ref(gmount); - GFile* rootFile; - rootFile = g_mount_get_root(mount); - if (!rootFile) { - return; - } - QString mountPoint = g_file_get_uri(rootFile); - if (mountPoint.isEmpty()) { - return; - } - //处理uri转码,处理子卷情况 - if (mountPoint.startsWith("file:///")) { - QString removedMountPoint = g_filename_from_uri(mountPoint.toUtf8().constData(), nullptr, nullptr); - pThis->m_blackListOfIndex.removeAll(removedMountPoint); - for (auto t = pThis->m_infoOfSubvolume.constBegin(); t != pThis->m_infoOfSubvolume.constEnd(); t++) { - if (removedMountPoint.startsWith(t.value())) { - pThis->m_blackListOfIndex.removeAll(removedMountPoint.replace(t.value(), t.key())); - } - if (removedMountPoint.startsWith(t.key())) { - pThis->m_blackListOfIndex.removeAll(removedMountPoint.replace(t.key(), t.value())); - } - } - qDebug() << "m_currentMountedDeviceInfo:" << pThis->m_currentMountedDeviceInfo; - qDebug() << "m_repeatedlyMountedDeviceInfo:" << pThis->m_repeatedlyMountedDeviceInfo; - qDebug() << "m_currentUDiskDeviceInfo:" << pThis->m_currentUDiskDeviceInfo; - qDebug() << "m_blackListOfIndex:" << pThis->m_blackListOfIndex; - } else { - qWarning() << "There's someting wrong with the MountPoint!"; - } - g_object_unref(rootFile); + return reply.value(); } void DirWatcher::appendIndexableListItem(const QString &path) { - QFile file(path); - if (!file.exists()) { - qWarning() << QString("target path:%1 is not exists!").arg(path); - return; + QDBusReply reply = m_dbusInterface->call("appendIndexableListItem", path); + if (!reply.isValid()) { + qCritical() << "appendIndexableListItem call filed!"; } - if (path == "/") { - this->currentindexableDir(); - this->handleIndexItemAppend(path, m_blackListOfIndex); - return; - } - - QStringList blackList = this->blackListOfDir(path); - //处理要添加索引的路径与索引黑名单中路径为父子关系的情况 - for (const QString& blackListPath : m_blackListOfIndex) { - if (path.startsWith(blackListPath + "/")) { - return; - } - if (blackListPath.startsWith(path + "/")) { - blackList.append(blackListPath); - } - } - - this->currentindexableDir(); - qDebug() << "m_indexableDirList:" << m_indexableDirList; - //处理要添加索引的路径与已索引路径为父子关系的情况 - for (int i = 0; i < m_indexableDirList.length(); i++) { - const QString indexablePath = m_indexableDirList.at(i); - if (path.startsWith(indexablePath + "/")) { - qDebug() << "return in:" << __FILE__ << ":" << __LINE__; - return; - } - if (blackList.contains(indexablePath)) { - qDebug() << "return in:" << __FILE__ << ":" << __LINE__; - return; - } - if (indexablePath.startsWith(path + "/")) { - m_indexableDirList.removeAll(indexablePath); - blackList.append(indexablePath); - } - } - this->handleIndexItemAppend(path, blackList); } void DirWatcher::removeIndexableListItem(const QString &path) { - this->currentindexableDir(); - this->handleIndexItemRemove(path); - Q_EMIT this->removeIndexItem(path); -} - -void DirWatcher::initData() -{ - //适配需求,可索引目录为用户指定。 -// m_indexableDirList << "/data" << QDir::homePath(); - /* boot里面存放Linux核心文件,开机选单与开机所需配置文件等 - * backup里面是系统备份文件 - * bin放置的是在单人维护模式下还能够被操作的指令,在bin底下的指令可以被root与一般账号所使用。 - * dev里面存放设备文件 - * etc里面存放了几乎所有的系统主要配置文件,包括人员的账号密码文件,各种服务的起始档等 - * lib放置最基本的共享库和内核模块,lib32,lib64,libx32分别面向32位,64位以及x32 ABI。他们都分别连接到usr下的lib*中 - * media一般放置可移除的装置,包括软盘,光盘和一些移动存储设备都自动挂载到这里 - * mnt原本和media用途相同,现用来放置暂时挂载一些额外装置 - * usr是Unix操作系统软件资源所放置的目录,所有系统默认的软件(distribution发布者提供的软件)都会放置到usr底下 - * var目录主要针对常态性变动的文件,包括缓存(cache)、登录档(log file)以及某些软件运作所产生的文件,包括程序文件(lock file, run file),或者如MySQL数据库的文件等 - */ - m_blackListOfIndex << "/boot" << "backup" << "bin" << "/dev" << "/etc" << "/usr" << "/var" - << "/lib" << "lib32" << "lib64" << "libx32" << "/media" << "/mnt" << "cdrom" - << "/sys" << "/proc" << "tmp" << "/srv" << "/sbin" << "/run" << "/opt"; - - //目前方案:可搜索目录(服务)默认根目录,可搜索目录(应用)默认家目录和/data目录 - m_searchableListForApplication << "/data" << QDir::homePath(); - m_searchableDirList << "/"; - - //init auto mounted device list - setfsent(); - while (1) { - fstab *myFstab = getfsent(); - if (!myFstab) { - endfsent(); - break; - } - QString automaticMountPoint = myFstab->fs_file; - QString spec = myFstab->fs_spec; - - //目前只索引data和home,因此只存这两个文件夹下的挂载点 - if (automaticMountPoint.contains("/data") || automaticMountPoint.contains("/home")) { - m_autoMountList.append(automaticMountPoint); - } - if (!spec.startsWith("UUID")) { - m_infoOfSubvolume.insert(spec, automaticMountPoint); - } - } - - //init disk data, refresh the black list - handleDisk(); -} - -void DirWatcher::initDiskWatcher() -{ - //use Dbus to monitor the hot plug of Udisk. - QDBusConnection::systemBus().connect("org.freedesktop.UDisks2", - "/org/freedesktop/UDisks2", - "org.freedesktop.DBus.ObjectManager", - "InterfacesAdded", - this, SLOT(handleAddedUDiskDevice(QDBusMessage))); - QDBusConnection::systemBus().connect("org.freedesktop.UDisks2", - "/org/freedesktop/UDisks2", - "org.freedesktop.DBus.ObjectManager", - "InterfacesRemoved", - this, SLOT(handleRemovedUDiskDevice(QDBusMessage))); - - m_volumeMonitor = g_volume_monitor_get(); - if (!m_volumeMonitor) { - return; - } - m_mountAddHandle = g_signal_connect(m_volumeMonitor, "mount-added", G_CALLBACK(mountAddCallback), this); - m_mountRemoveHandle = g_signal_connect(m_volumeMonitor, "mount-removed", G_CALLBACK(mountRemoveCallback), this); -} - -void DirWatcher::handleDisk() -{ - //init current mounted device info - QMutexLocker locker(&s_mutex); - m_currentMountedDeviceInfo.clear(); - for (QStorageInfo &storage: QStorageInfo::mountedVolumes()) { - if (storage.isValid() && storage.isReady() && QString(storage.device()).contains(QRegExp("/sd[a-z][1-9]"))) { - m_currentMountedDeviceInfo[storage.device()].append(storage.rootPath()); - - if (m_currentMountedDeviceInfo.value(storage.device()).length() > 1) { - m_repeatedlyMountedDeviceInfo.insert(storage.device(), m_currentMountedDeviceInfo.value(storage.device())); - } - if (storage.rootPath().startsWith("/data") || storage.rootPath().startsWith("/home")) { - m_blackListOfIndex.append(storage.rootPath()); - } - } - } - - //init udisk info - if (!m_addedUDiskDeviceList.isEmpty()) { - for (QString addedUDiskDevice: m_addedUDiskDeviceList) { - m_currentUDiskDeviceInfo.insert(addedUDiskDevice, m_currentMountedDeviceInfo.value("/dev/" + addedUDiskDevice)); - } - } - - //将u盘设备在/data和/home下的所有挂载点添加到索引黑名单 - if (!m_currentUDiskDeviceInfo.isEmpty()) { - for (auto t = m_currentUDiskDeviceInfo.constBegin(); t != m_currentUDiskDeviceInfo.constEnd(); t++) { - for (QString udiskDevice: t.value()) { - if (udiskDevice.startsWith("/data") || udiskDevice.startsWith("/home")) { - m_blackListOfIndex.append(udiskDevice); - } - } - } - } - - //从黑名单中移除所有自动挂载设备(目前只包含自动挂载到/data和/home目录下的设备) - for (QString autoMountDevice: m_autoMountList) { - m_blackListOfIndex.removeAll(autoMountDevice); - } - m_blackListOfIndex.removeDuplicates(); - - qDebug() << "autoMountList:" << m_autoMountList; - qDebug() << "m_currentMountedDeviceInfo:" << m_currentMountedDeviceInfo; - qDebug() << "m_repeatedlyMountedDeviceInfo:" << m_repeatedlyMountedDeviceInfo; - qDebug() << "m_currentUDiskDeviceInfo:" << m_currentUDiskDeviceInfo; - qDebug() << "m_blackListOfIndex:" << m_blackListOfIndex; - -} - -void DirWatcher::handleAddedUDiskDevice(QDBusMessage msg) -{ - QDBusObjectPath objPath = msg.arguments().at(0).value(); - if (objPath.path().contains(QRegExp("/sd[a-z][1-9]"))) { - QMutexLocker locker(&s_mutex); - m_addedUDiskDeviceList.append(objPath.path().section("/",-1)); - qDebug() << "Add Udisk:" << m_addedUDiskDeviceList; - } -} - -void DirWatcher::handleRemovedUDiskDevice(QDBusMessage msg) -{ - Q_EMIT this->udiskRemoved(); - QDBusObjectPath objPath = msg.arguments().at(0).value(); - if (objPath.path().contains(QRegExp("/sd[a-z][1-9]"))) { - QMutexLocker locker(&s_mutex); - m_removedUDiskDevice = objPath.path().section("/",-1); - m_addedUDiskDeviceList.removeAll(m_removedUDiskDevice); + QDBusReply reply = m_dbusInterface->call("removeIndexableListItem", path); + if (!reply.isValid()) { + qCritical() << "removeIndexableListItem call filed!"; } } diff --git a/libsearch/dirwatcher/dir-watcher.h b/libsearch/dirwatcher/dir-watcher.h index c362d93..83bf5cb 100644 --- a/libsearch/dirwatcher/dir-watcher.h +++ b/libsearch/dirwatcher/dir-watcher.h @@ -1,89 +1,35 @@ #ifndef MOUNTDISKLISTENER_H #define MOUNTDISKLISTENER_H -#include "dir-watcher-adaptor.h" - #include -#include -#include -#include -#include -#include -#include -#include +#include +#include -#undef slots -#undef signals -#undef emit - -#include -#include class DirWatcher : public QObject { Q_OBJECT - - Q_CLASSINFO("D-Bus Interface","org.ukui.search.fileindex") - public: static DirWatcher *getDirWatcher(); + +public Q_SLOTS: void initDbusService(); - QStringList currentindexableDir(); + + QStringList currentIndexableDir(); QStringList currentBlackListOfIndex(); - void appendBlackListItemOfIndex(const QString &path); - void appendBlackListItemOfIndex(const QStringList &pathList); - void removeBlackListItemOfIndex(const QString &path); - void removeBlackListItemOfIndex(const QStringList &pathList); QStringList currentSearchableDir(); QStringList searchableDirForSearchApplication(); QStringList blackListOfDir(const QString &dirPath); - static void mountAddCallback(GVolumeMonitor *monitor, GMount *gmount, DirWatcher *pThis); - static void mountRemoveCallback(GVolumeMonitor *monitor, GMount *gmount, DirWatcher *pThis); -public Q_SLOTS: void appendIndexableListItem(const QString &path); void removeIndexableListItem(const QString &path); - void handleDisk(); - void handleAddedUDiskDevice(QDBusMessage msg); - void handleRemovedUDiskDevice(QDBusMessage msg); private: DirWatcher(QObject *parent = nullptr); - ~DirWatcher(); - void initData(); - void initDiskWatcher(); + ~DirWatcher() = default; - void handleIndexItemAppend(const QString &path, QStringList &blackList); - void handleIndexItemRemove(const QString &path); - - static QMutex s_mutex; - - GVolumeMonitor *m_volumeMonitor = nullptr; - - DirWatcherAdaptor *m_adaptor = nullptr; - - quint64 m_mountAddHandle; - quint64 m_mountRemoveHandle; - - QSettings *m_qSettings = nullptr; - QStringList m_blackListOfIndex; - QStringList m_indexableDirList; - - QStringList m_searchableDirList; - QStringList m_searchableListForApplication; - QStringList m_autoMountList; - QMultiMap m_infoOfSubvolume; - QMap m_currentMountedDeviceInfo; - QMap m_repeatedlyMountedDeviceInfo; - - QStringList m_addedUDiskDeviceList; - QString m_removedUDiskDevice; - QMap m_currentUDiskDeviceInfo; -Q_SIGNALS: - void udiskRemoved(); - void appendIndexItem(const QString&, const QStringList&); - void removeIndexItem(const QString&); + QDBusInterface *m_dbusInterface = nullptr; }; #endif // MOUNTDISKLISTENER_H diff --git a/libsearch/dirwatcher/dirwatcher.pri b/libsearch/dirwatcher/dirwatcher.pri index 9661b77..4558940 100644 --- a/libsearch/dirwatcher/dirwatcher.pri +++ b/libsearch/dirwatcher/dirwatcher.pri @@ -1,9 +1,7 @@ INCLUDEPATH += $$PWD HEADERS += \ - $$PWD/dir-watcher-adaptor.h \ $$PWD/dir-watcher.h SOURCES += \ - $$PWD/dir-watcher-adaptor.cpp \ $$PWD/dir-watcher.cpp diff --git a/libsearch/index/file-index-manager.cpp b/libsearch/index/file-index-manager.cpp index 0a98fbf..219138f 100644 --- a/libsearch/index/file-index-manager.cpp +++ b/libsearch/index/file-index-manager.cpp @@ -54,13 +54,22 @@ void FileIndexManager::initIndexPathSetFunction() return; } - connect(DirWatcher::getDirWatcher(), &DirWatcher::appendIndexItem, this, &FileIndexManager::handleIndexPathAppend, Qt::QueuedConnection); + QDBusInterface *interface = new QDBusInterface("com.ukui.search.fileindex.service", + "/org/ukui/search/privateDirWatcher", + "org.ukui.search.fileindex"); + + if (interface->isValid()) { + connect(interface, SIGNAL(appendIndexItem(QString, QStringList)), this, SLOT(handleIndexPathAppend(QString, QStringList)), Qt::QueuedConnection); + } +// connect(DirWatcher::getDirWatcher(), &DirWatcher::appendIndexItem, this, &FileIndexManager::handleIndexPathAppend, Qt::QueuedConnection); DirWatcher::getDirWatcher()->initDbusService(); } void FileIndexManager::handleIndexPathAppend(const QString path, const QStringList blockList) { + qDebug() << "I'm in handleIndexPathAppend"; + qDebug() << "path" << path << "blockList" << blockList; if(!m_searchSettings->get(SEARCH_METHOD_KEY).toBool()) { m_searchSettings->set(SEARCH_METHOD_KEY, true); } else { diff --git a/libsearch/index/first-index.cpp b/libsearch/index/first-index.cpp index 9186a6f..2ae1720 100644 --- a/libsearch/index/first-index.cpp +++ b/libsearch/index/first-index.cpp @@ -147,7 +147,7 @@ void FirstIndex::run() { return; } } else { - setPath(DirWatcher::getDirWatcher()->currentindexableDir()); + setPath(DirWatcher::getDirWatcher()->currentIndexableDir()); setBlockPath(DirWatcher::getDirWatcher()->currentBlackListOfIndex()); } @@ -171,8 +171,11 @@ void FirstIndex::run() { mutex2.lock(); // mutex3.lock(); - qInfo() << "index dir" << DirWatcher::getDirWatcher()->currentindexableDir(); - qInfo() << "index block dir" << DirWatcher::getDirWatcher()->currentBlackListOfIndex(); + //FIXME:在子进程里使用和父进程同样的dbus接口会出问题。 +// qInfo() << "index dir" << DirWatcher::getDirWatcher()->currentIndexableDir(); +// qInfo() << "index block dir" << DirWatcher::getDirWatcher()->currentBlackListOfIndex(); + qInfo() << "index dir" << m_pathList; + qInfo() << "index block dir" << m_blockList; this->Traverse(); FileUtils::maxIndexCount = this->m_indexData->length(); diff --git a/libsearch/index/inotify-watch.cpp b/libsearch/index/inotify-watch.cpp index 83ca6fd..ed198f0 100644 --- a/libsearch/index/inotify-watch.cpp +++ b/libsearch/index/inotify-watch.cpp @@ -188,7 +188,7 @@ void InotifyWatch::run() } } - setPath(DirWatcher::getDirWatcher()->currentindexableDir()); + setPath(DirWatcher::getDirWatcher()->currentIndexableDir()); setBlockPath(DirWatcher::getDirWatcher()->currentBlackListOfIndex()); firstTraverse(); diff --git a/ukui-search-service-dir-manager/conf/com.ukui.search.fileindex.service b/ukui-search-service-dir-manager/conf/com.ukui.search.fileindex.service new file mode 100644 index 0000000..c5c5696 --- /dev/null +++ b/ukui-search-service-dir-manager/conf/com.ukui.search.fileindex.service @@ -0,0 +1,3 @@ +[D-BUS Service] +Name=com.ukui.search.fileindex.service +Exec=/usr/bin/ukui-search-service-dir-manager diff --git a/ukui-search-service-dir-manager/dirwatcher/com.ukui.search.fileindex.server.xml b/ukui-search-service-dir-manager/dirwatcher/com.ukui.search.fileindex.server.xml new file mode 100644 index 0000000..6ee254f --- /dev/null +++ b/ukui-search-service-dir-manager/dirwatcher/com.ukui.search.fileindex.server.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/libsearch/dirwatcher/dir-watcher-adaptor.cpp b/ukui-search-service-dir-manager/dirwatcher/dir-watcher-adaptor.cpp similarity index 80% rename from libsearch/dirwatcher/dir-watcher-adaptor.cpp rename to ukui-search-service-dir-manager/dirwatcher/dir-watcher-adaptor.cpp index 4bde5e4..953db27 100644 --- a/libsearch/dirwatcher/dir-watcher-adaptor.cpp +++ b/ukui-search-service-dir-manager/dirwatcher/dir-watcher-adaptor.cpp @@ -1,6 +1,6 @@ /* * This file was generated by qdbusxml2cpp version 0.8 - * Command line was: qdbusxml2cpp com.ukui.search.fileindex.server.xml -i dir-watcher.h -a valueAdaptor + * Command line was: qdbusxml2cpp com.ukui.search.fileindex.server.xml -a dir-watcher-adaptor * * qdbusxml2cpp is Copyright (C) 2020 The Qt Company Ltd. * @@ -18,7 +18,7 @@ #include /* - * Implementation of adaptor class DirWatcherAdaptor + * Implementation of adaptor class FileindexAdaptor */ DirWatcherAdaptor::DirWatcherAdaptor(QObject *parent) @@ -35,13 +35,13 @@ DirWatcherAdaptor::~DirWatcherAdaptor() void DirWatcherAdaptor::appendIndexableListItem(const QString &path) { - // handle method call org.ukui.search.fileindex.service.appendIndexableListItem + // handle method call org.ukui.search.fileindex.appendIndexableListItem QMetaObject::invokeMethod(parent(), "appendIndexableListItem", Q_ARG(QString, path)); } void DirWatcherAdaptor::removeIndexableListItem(const QString &path) { - // handle method call org.ukui.search.fileindex.service.removeIndexableListItem + // handle method call org.ukui.search.fileindex.removeIndexableListItem QMetaObject::invokeMethod(parent(), "removeIndexableListItem", Q_ARG(QString, path)); } diff --git a/libsearch/dirwatcher/dir-watcher-adaptor.h b/ukui-search-service-dir-manager/dirwatcher/dir-watcher-adaptor.h similarity index 72% rename from libsearch/dirwatcher/dir-watcher-adaptor.h rename to ukui-search-service-dir-manager/dirwatcher/dir-watcher-adaptor.h index 3e00a26..062a383 100644 --- a/libsearch/dirwatcher/dir-watcher-adaptor.h +++ b/ukui-search-service-dir-manager/dirwatcher/dir-watcher-adaptor.h @@ -1,6 +1,6 @@ /* * This file was generated by qdbusxml2cpp version 0.8 - * Command line was: qdbusxml2cpp com.ukui.search.fileindex.server.xml -i dir-watcher.h -a valueAdaptor + * Command line was: qdbusxml2cpp com.ukui.search.fileindex.server.xml -a dir-watcher-adaptor * * qdbusxml2cpp is Copyright (C) 2020 The Qt Company Ltd. * @@ -9,8 +9,8 @@ * before re-generating it. */ -#ifndef VALUEADAPTOR_H -#define VALUEADAPTOR_H +#ifndef DIR_WATCHER_ADAPTOR_H +#define DIR_WATCHER_ADAPTOR_H #include #include @@ -31,14 +31,14 @@ class DirWatcherAdaptor: public QDBusAbstractAdaptor Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.ukui.search.fileindex") Q_CLASSINFO("D-Bus Introspection", "" -" " -" " -" " -" " -" " -" " -" " -" " +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" "") public: DirWatcherAdaptor(QObject *parent); diff --git a/ukui-search-service-dir-manager/dirwatcher/dir-watcher-dbus.pri b/ukui-search-service-dir-manager/dirwatcher/dir-watcher-dbus.pri new file mode 100644 index 0000000..9661b77 --- /dev/null +++ b/ukui-search-service-dir-manager/dirwatcher/dir-watcher-dbus.pri @@ -0,0 +1,9 @@ +INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/dir-watcher-adaptor.h \ + $$PWD/dir-watcher.h + +SOURCES += \ + $$PWD/dir-watcher-adaptor.cpp \ + $$PWD/dir-watcher.cpp diff --git a/ukui-search-service-dir-manager/dirwatcher/dir-watcher.cpp b/ukui-search-service-dir-manager/dirwatcher/dir-watcher.cpp new file mode 100644 index 0000000..02e79c8 --- /dev/null +++ b/ukui-search-service-dir-manager/dirwatcher/dir-watcher.cpp @@ -0,0 +1,422 @@ +#include "dir-watcher.h" + +#include +#include +#include +#include +#include +#include +#include + +#define CURRENT_INDEXABLE_DIR_SETTINGS QDir::homePath() + "/.config/org.ukui/ukui-search/ukui-search-current-indexable-dir.conf" +#define INDEXABLE_DIR_VALUE "IndexableDir" + +static std::once_flag flag; +static DirWatcher *global_intance = nullptr; +QMutex DirWatcher::s_mutex; + +DirWatcher::DirWatcher(QObject *parent) : QObject(parent) +{ + m_qSettings = new QSettings(CURRENT_INDEXABLE_DIR_SETTINGS, QSettings::IniFormat); + initData(); + initDiskWatcher(); + m_adaptor = new DirWatcherAdaptor(this); +} + +DirWatcher::~DirWatcher() +{ + if (m_volumeMonitor) { + g_signal_handler_disconnect(m_volumeMonitor, m_mountAddHandle); + g_signal_handler_disconnect(m_volumeMonitor, m_mountRemoveHandle); + m_volumeMonitor = nullptr; + } + if(m_qSettings){ + delete m_qSettings; + } +} + +DirWatcher *DirWatcher::getDirWatcher() +{ + std::call_once(flag, [ & ] { + global_intance = new DirWatcher(); + }); + return global_intance; +} + +QStringList DirWatcher::currentIndexableDir() +{ + QMutexLocker locker(&s_mutex); + m_qSettings->beginGroup(INDEXABLE_DIR_VALUE); + m_indexableDirList = m_qSettings->value(INDEXABLE_DIR_VALUE).toStringList(); + m_qSettings->endGroup(); + QStringList indexableDirs = m_indexableDirList; + return indexableDirs; +} + +QStringList DirWatcher::currentBlackListOfIndex() +{ + QMutexLocker locker(&s_mutex); + QStringList blackListOfIndex = m_blackListOfIndex; + return blackListOfIndex; +} + +void DirWatcher::handleIndexItemAppend(const QString &path, QStringList &blackList) +{ + if (m_indexableDirList.contains(path)) { + qDebug() << QString("index path %1 is already added.").arg(path); + return; + } + m_indexableDirList << path; + m_qSettings->beginGroup(INDEXABLE_DIR_VALUE); + m_qSettings->setValue(INDEXABLE_DIR_VALUE, m_indexableDirList); + m_qSettings->endGroup(); + Q_EMIT this->appendIndexItem(path, blackList); + qDebug() << "index path:" << path << "blacklist:" << blackList; +} + +void DirWatcher::handleIndexItemRemove(const QString &path) +{ + m_indexableDirList.removeAll(path); + m_qSettings->beginGroup(INDEXABLE_DIR_VALUE); + m_qSettings->setValue(INDEXABLE_DIR_VALUE, m_indexableDirList); + m_qSettings->endGroup(); +} + +/** + * @brief DirWatcher::blackListOfDir 根据传入目录返回当前目录下的所有不可搜索目录,没有则返回空列表 + * @param dirPath 要搜索的目录 + */ +QStringList DirWatcher::blackListOfDir(const QString &dirPath) +{ + //new TODO: Optimize the search algorithm. + //There is no processing for the subvolumes.May be a bug. + QStringList blackListOfDir; + QMutexLocker locker(&s_mutex); + for (auto t = m_repeatedlyMountedDeviceInfo.constBegin(); t != m_repeatedlyMountedDeviceInfo.constEnd(); t++) { + QString topRepeatedMountPoint; + for (QString mountPoint: t.value()) { + if (mountPoint.startsWith(dirPath)) { + if (topRepeatedMountPoint.isEmpty()) { + topRepeatedMountPoint = mountPoint; + continue; + } else if (topRepeatedMountPoint.startsWith(mountPoint)) { + blackListOfDir.append(topRepeatedMountPoint); + topRepeatedMountPoint = mountPoint; + } else { + blackListOfDir.append(mountPoint); + } + } + } + } + for (auto i = m_infoOfSubvolume.constBegin(); i != m_infoOfSubvolume.constEnd(); i++) { + QString mountPoint = i.value(); + QString spec = i.key(); + //排除搜索列表指定多个目录时子卷会重复包含的情况,比如同时指定/home和/data/home + QString tmp = dirPath; + if (dirPath.startsWith(mountPoint)) { + blackListOfDir.append(tmp.replace(0, mountPoint.length(), spec)); + } + if (dirPath.startsWith(spec)) { + blackListOfDir.append(tmp.replace(0, spec.length(), mountPoint)); + } + } + return blackListOfDir; +} + +void DirWatcher::appendBlackListItemOfIndex(const QString &path) +{ + QMutexLocker locker(&s_mutex); + m_blackListOfIndex.append(path); + m_blackListOfIndex = m_blackListOfIndex.toSet().toList(); +} + +void DirWatcher::appendBlackListItemOfIndex(const QStringList &pathList) +{ + QMutexLocker locker(&s_mutex); + m_blackListOfIndex.append(pathList); + m_blackListOfIndex = m_blackListOfIndex.toSet().toList(); +} + +void DirWatcher::removeBlackListItemOfIndex(const QString &path) +{ + QMutexLocker locker(&s_mutex); + m_blackListOfIndex.removeAll(path); +} + +void DirWatcher::removeBlackListItemOfIndex(const QStringList &pathList) +{ + QMutexLocker locker(&s_mutex); + for (QString path: pathList) { + m_blackListOfIndex.removeAll(path); + } +} + +void DirWatcher::initDbusService() +{ + QDBusConnection sessionBus = QDBusConnection::sessionBus(); + if (!sessionBus.registerObject("/org/ukui/search/fileindex", this, QDBusConnection::ExportAdaptors)){ + qWarning() << "ukui-search-fileindex dbus register object failed reason:" << sessionBus.lastError(); + } +} + +QStringList DirWatcher::currentSearchableDir() +{ + QMutexLocker locker(&s_mutex); + return m_searchableDirList; +} + +QStringList DirWatcher::searchableDirForSearchApplication() +{ + QMutexLocker locker(&s_mutex); + return m_searchableListForApplication; +} + +void DirWatcher::mountAddCallback(GVolumeMonitor *monitor, GMount *gmount, DirWatcher *pThis) +{ + qDebug() << "Mount Added"; + pThis->handleDisk(); +} + +void DirWatcher::mountRemoveCallback(GVolumeMonitor *monitor, GMount *gmount, DirWatcher *pThis) +{ + qDebug() << "Mount Removed"; + QMutexLocker locker(&s_mutex); + //处理u盘设备 + if (pThis->m_removedUDiskDevice != NULL) { + pThis->m_currentUDiskDeviceInfo.remove(pThis->m_removedUDiskDevice); + qDebug() << "m_currentMountedDeviceInfo:" << pThis->m_currentMountedDeviceInfo; + qDebug() << "m_repeatedlyMountedDeviceInfo:" << pThis->m_repeatedlyMountedDeviceInfo; + qDebug() << "m_currentUDiskDeviceInfo:" << pThis->m_currentUDiskDeviceInfo; + qDebug() << "m_blackListOfIndex:" << pThis->m_blackListOfIndex; + pThis->m_removedUDiskDevice = ""; + return; + } + + GMount* mount = (GMount*)g_object_ref(gmount); + GFile* rootFile; + rootFile = g_mount_get_root(mount); + if (!rootFile) { + return; + } + QString mountPoint = g_file_get_uri(rootFile); + if (mountPoint.isEmpty()) { + return; + } + //处理uri转码,处理子卷情况 + if (mountPoint.startsWith("file:///")) { + QString removedMountPoint = g_filename_from_uri(mountPoint.toUtf8().constData(), nullptr, nullptr); + pThis->m_blackListOfIndex.removeAll(removedMountPoint); + for (auto t = pThis->m_infoOfSubvolume.constBegin(); t != pThis->m_infoOfSubvolume.constEnd(); t++) { + if (removedMountPoint.startsWith(t.value())) { + pThis->m_blackListOfIndex.removeAll(removedMountPoint.replace(t.value(), t.key())); + } + if (removedMountPoint.startsWith(t.key())) { + pThis->m_blackListOfIndex.removeAll(removedMountPoint.replace(t.key(), t.value())); + } + } + qDebug() << "m_currentMountedDeviceInfo:" << pThis->m_currentMountedDeviceInfo; + qDebug() << "m_repeatedlyMountedDeviceInfo:" << pThis->m_repeatedlyMountedDeviceInfo; + qDebug() << "m_currentUDiskDeviceInfo:" << pThis->m_currentUDiskDeviceInfo; + qDebug() << "m_blackListOfIndex:" << pThis->m_blackListOfIndex; + } else { + qWarning() << "There's someting wrong with the MountPoint!"; + } + g_object_unref(rootFile); +} + +void DirWatcher::appendIndexableListItem(const QString &path) +{ + QFile file(path); + if (!file.exists()) { + qWarning() << QString("target path:%1 is not exists!").arg(path); + return; + } + if (path == "/") { + this->currentIndexableDir(); + this->handleIndexItemAppend(path, m_blackListOfIndex); + return; + } + + QStringList blackList = this->blackListOfDir(path); + //处理要添加索引的路径与索引黑名单中路径为父子关系的情况 + for (const QString& blackListPath : m_blackListOfIndex) { + if (path.startsWith(blackListPath + "/")) { + return; + } + if (blackListPath.startsWith(path + "/")) { + blackList.append(blackListPath); + } + } + + this->currentIndexableDir(); + qDebug() << "current indexable dirs:" << m_indexableDirList; + //处理要添加索引的路径与已索引路径为父子关系的情况 + for (int i = 0; i < m_indexableDirList.length(); i++) { + const QString indexablePath = m_indexableDirList.at(i); + if (path.startsWith(indexablePath + "/")) { + qCritical() << QString("The parent of the path:%1 has been added.").arg(path); + return; + } + if (blackList.contains(indexablePath)) { + qCritical() << "current path is in repeat mounted devices and another path which is in the device that has the same dev num has been added to the indexable list."; + return; + } + if (indexablePath.startsWith(path + "/")) { + m_indexableDirList.removeAll(indexablePath); + blackList.append(indexablePath); + } + } + this->handleIndexItemAppend(path, blackList); +} + +void DirWatcher::removeIndexableListItem(const QString &path) +{ + this->currentIndexableDir(); + this->handleIndexItemRemove(path); + Q_EMIT this->removeIndexItem(path); +} + +void DirWatcher::initData() +{ + //适配需求,可索引目录为用户指定。 +// m_indexableDirList << "/data" << QDir::homePath(); + /* boot里面存放Linux核心文件,开机选单与开机所需配置文件等 + * backup里面是系统备份文件 + * bin放置的是在单人维护模式下还能够被操作的指令,在bin底下的指令可以被root与一般账号所使用。 + * dev里面存放设备文件 + * etc里面存放了几乎所有的系统主要配置文件,包括人员的账号密码文件,各种服务的起始档等 + * lib放置最基本的共享库和内核模块,lib32,lib64,libx32分别面向32位,64位以及x32 ABI。他们都分别连接到usr下的lib*中 + * media一般放置可移除的装置,包括软盘,光盘和一些移动存储设备都自动挂载到这里 + * mnt原本和media用途相同,现用来放置暂时挂载一些额外装置 + * usr是Unix操作系统软件资源所放置的目录,所有系统默认的软件(distribution发布者提供的软件)都会放置到usr底下 + * var目录主要针对常态性变动的文件,包括缓存(cache)、登录档(log file)以及某些软件运作所产生的文件,包括程序文件(lock file, run file),或者如MySQL数据库的文件等 + */ + m_blackListOfIndex << "/boot" << "backup" << "bin" << "/dev" << "/etc" << "/usr" << "/var" + << "/lib" << "lib32" << "lib64" << "libx32" << "/media" << "/mnt" << "cdrom" + << "/sys" << "/proc" << "tmp" << "/srv" << "/sbin" << "/run" << "/opt"; + + //目前方案:可搜索目录(服务)默认根目录,可搜索目录(应用)默认家目录和/data目录 + m_searchableListForApplication << "/data" << QDir::homePath(); + m_searchableDirList << "/"; + + //init auto mounted device list + setfsent(); + while (1) { + fstab *myFstab = getfsent(); + if (!myFstab) { + endfsent(); + break; + } + QString automaticMountPoint = myFstab->fs_file; + QString spec = myFstab->fs_spec; + + //目前只索引data和home,因此只存这两个文件夹下的挂载点 + if (automaticMountPoint.contains("/data") || automaticMountPoint.contains("/home")) { + m_autoMountList.append(automaticMountPoint); + } + if (!spec.startsWith("UUID")) { + m_infoOfSubvolume.insert(spec, automaticMountPoint); + } + } + + //init disk data, refresh the black list + handleDisk(); +} + +void DirWatcher::initDiskWatcher() +{ + //use Dbus to monitor the hot plug of Udisk. + + + QDBusConnection dbc = QDBusConnection::systemBus(); + + qDebug() << dbc.connect("org.freedesktop.UDisks2", + "/org/freedesktop/UDisks2", + "org.freedesktop.DBus.ObjectManager", + "InterfacesAdded", + this, SLOT(handleAddedUDiskDevice(QDBusMessage))); + qDebug() << dbc.lastError(); + qDebug() << dbc.connect("org.freedesktop.UDisks2", + "/org/freedesktop/UDisks2", + "org.freedesktop.DBus.ObjectManager", + "InterfacesRemoved", + this, SLOT(handleRemovedUDiskDevice(QDBusMessage))); + + m_volumeMonitor = g_volume_monitor_get(); + if (!m_volumeMonitor) { + return; + } + m_mountAddHandle = g_signal_connect(m_volumeMonitor, "mount-added", G_CALLBACK(mountAddCallback), this); + m_mountRemoveHandle = g_signal_connect(m_volumeMonitor, "mount-removed", G_CALLBACK(mountRemoveCallback), this); +} + +void DirWatcher::handleDisk() +{ + //init current mounted device info + QMutexLocker locker(&s_mutex); + m_currentMountedDeviceInfo.clear(); + for (QStorageInfo &storage: QStorageInfo::mountedVolumes()) { + if (storage.isValid() && storage.isReady() && QString(storage.device()).contains(QRegExp("/sd[a-z][1-9]"))) { + m_currentMountedDeviceInfo[storage.device()].append(storage.rootPath()); + + if (m_currentMountedDeviceInfo.value(storage.device()).length() > 1) { + m_repeatedlyMountedDeviceInfo.insert(storage.device(), m_currentMountedDeviceInfo.value(storage.device())); + } + if (storage.rootPath().startsWith("/data") || storage.rootPath().startsWith("/home")) { + m_blackListOfIndex.append(storage.rootPath()); + } + } + } + + //init udisk info + if (!m_addedUDiskDeviceList.isEmpty()) { + for (QString addedUDiskDevice: m_addedUDiskDeviceList) { + m_currentUDiskDeviceInfo.insert(addedUDiskDevice, m_currentMountedDeviceInfo.value("/dev/" + addedUDiskDevice)); + } + } + + //将u盘设备在/data和/home下的所有挂载点添加到索引黑名单 + if (!m_currentUDiskDeviceInfo.isEmpty()) { + for (auto t = m_currentUDiskDeviceInfo.constBegin(); t != m_currentUDiskDeviceInfo.constEnd(); t++) { + for (QString udiskDevice: t.value()) { + if (udiskDevice.startsWith("/data") || udiskDevice.startsWith("/home")) { + m_blackListOfIndex.append(udiskDevice); + } + } + } + } + + //从黑名单中移除所有自动挂载设备(目前只包含自动挂载到/data和/home目录下的设备) + for (QString autoMountDevice: m_autoMountList) { + m_blackListOfIndex.removeAll(autoMountDevice); + } + m_blackListOfIndex.removeDuplicates(); + + qDebug() << "autoMountList:" << m_autoMountList; + qDebug() << "m_currentMountedDeviceInfo:" << m_currentMountedDeviceInfo; + qDebug() << "m_repeatedlyMountedDeviceInfo:" << m_repeatedlyMountedDeviceInfo; + qDebug() << "m_currentUDiskDeviceInfo:" << m_currentUDiskDeviceInfo; + qDebug() << "m_blackListOfIndex:" << m_blackListOfIndex; + +} + +void DirWatcher::handleAddedUDiskDevice(QDBusMessage msg) +{ + QDBusObjectPath objPath = msg.arguments().at(0).value(); + if (objPath.path().contains(QRegExp("/sd[a-z][1-9]"))) { + QMutexLocker locker(&s_mutex); + m_addedUDiskDeviceList.append(objPath.path().section("/",-1)); + qDebug() << "Add Udisk:" << m_addedUDiskDeviceList; + } +} + +void DirWatcher::handleRemovedUDiskDevice(QDBusMessage msg) +{ + Q_EMIT this->udiskRemoved(); + QDBusObjectPath objPath = msg.arguments().at(0).value(); + if (objPath.path().contains(QRegExp("/sd[a-z][1-9]"))) { + QMutexLocker locker(&s_mutex); + m_removedUDiskDevice = objPath.path().section("/",-1); + m_addedUDiskDeviceList.removeAll(m_removedUDiskDevice); + } +} diff --git a/ukui-search-service-dir-manager/dirwatcher/dir-watcher.h b/ukui-search-service-dir-manager/dirwatcher/dir-watcher.h new file mode 100644 index 0000000..73fa234 --- /dev/null +++ b/ukui-search-service-dir-manager/dirwatcher/dir-watcher.h @@ -0,0 +1,96 @@ +#ifndef MOUNTDISKLISTENER_H +#define MOUNTDISKLISTENER_H + +#include "dir-watcher-adaptor.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef slots +#undef signals +#undef emit + +#include +#include + +class DirWatcher : public QObject +{ + Q_OBJECT + + Q_CLASSINFO("D-Bus Interface","org.ukui.search.fileindex") + +public: + static DirWatcher *getDirWatcher(); + static void mountAddCallback(GVolumeMonitor *monitor, GMount *gmount, DirWatcher *pThis); + static void mountRemoveCallback(GVolumeMonitor *monitor, GMount *gmount, DirWatcher *pThis); + + void appendBlackListItemOfIndex(const QString &path); + void appendBlackListItemOfIndex(const QStringList &pathList); + void removeBlackListItemOfIndex(const QString &path); + void removeBlackListItemOfIndex(const QStringList &pathList); + +public Q_SLOTS: + + void initDbusService(); + + QStringList currentIndexableDir(); + QStringList currentBlackListOfIndex(); + + QStringList currentSearchableDir(); + QStringList searchableDirForSearchApplication(); + QStringList blackListOfDir(const QString &dirPath); + + Q_SCRIPTABLE void appendIndexableListItem(const QString &path); + Q_SCRIPTABLE void removeIndexableListItem(const QString &path); + +private: + DirWatcher(QObject *parent = nullptr); + ~DirWatcher(); + void initData(); + void initDiskWatcher(); + + void handleDisk(); + void handleAddedUDiskDevice(QDBusMessage msg); + void handleRemovedUDiskDevice(QDBusMessage msg); + + void handleIndexItemAppend(const QString &path, QStringList &blackList); + void handleIndexItemRemove(const QString &path); + + static QMutex s_mutex; + + DirWatcherAdaptor *m_adaptor = nullptr; + + GVolumeMonitor *m_volumeMonitor = nullptr; + quint64 m_mountAddHandle; + quint64 m_mountRemoveHandle; + + QSettings *m_qSettings = nullptr; + QStringList m_blackListOfIndex; + QStringList m_indexableDirList; + + QStringList m_searchableDirList; + QStringList m_searchableListForApplication; + QStringList m_autoMountList; + QMultiMap m_infoOfSubvolume; + QMap m_currentMountedDeviceInfo; + QMap m_repeatedlyMountedDeviceInfo; + + QStringList m_addedUDiskDeviceList; + QString m_removedUDiskDevice; + QMap m_currentUDiskDeviceInfo; +Q_SIGNALS: + void udiskRemoved(); + void appendIndexItem(const QString&, const QStringList&); + void removeIndexItem(const QString&); +}; + +#endif // MOUNTDISKLISTENER_H + diff --git a/ukui-search-service-dir-manager/main.cpp b/ukui-search-service-dir-manager/main.cpp new file mode 100644 index 0000000..89cdd05 --- /dev/null +++ b/ukui-search-service-dir-manager/main.cpp @@ -0,0 +1,109 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "ukui-search-dir-manager-dbus.h" +void messageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) +{ + QByteArray localMsg = msg.toLocal8Bit(); + QByteArray currentTime = QTime::currentTime().toString().toLocal8Bit(); + + bool showDebug = true; + QString logFilePath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/.config/org.ukui/ukui-search-service-dir-manager.log"; + if (!QFile::exists(logFilePath)) { + showDebug = false; + } + FILE *log_file = nullptr; + + if (showDebug) { + log_file = fopen(logFilePath.toLocal8Bit().constData(), "a+"); + } + + const char *file = context.file ? context.file : ""; + const char *function = context.function ? context.function : ""; + switch (type) { + case QtDebugMsg: + if (!log_file) { + break; + } + fprintf(log_file, "Debug: %s: %s (%s:%u, %s)\n", currentTime.constData(), localMsg.constData(), file, context.line, function); + break; + case QtInfoMsg: + fprintf(log_file? log_file: stdout, "Info: %s: %s (%s:%u, %s)\n", currentTime.constData(), localMsg.constData(), file, context.line, function); + break; + case QtWarningMsg: + fprintf(log_file? log_file: stderr, "Warning: %s: %s (%s:%u, %s)\n", currentTime.constData(), localMsg.constData(), file, context.line, function); + break; + case QtCriticalMsg: + fprintf(log_file? log_file: stderr, "Critical: %s: %s (%s:%u, %s)\n", currentTime.constData(), localMsg.constData(), file, context.line, function); + break; + case QtFatalMsg: + fprintf(log_file? log_file: stderr, "Fatal: %s: %s (%s:%u, %s)\n", currentTime.constData(), localMsg.constData(), file, context.line, function); + break; + } + + if (log_file) + fclose(log_file); +} + +int main(int argc, char *argv[]) +{ + char *p_home = NULL; + unsigned int i = 0; + while(p_home == NULL) { + ::sleep(1); + ++i; + p_home = getenv("HOME"); + if(i % 5 == 0) { + qWarning() << "I can't find home! I'm done here!!"; + printf("I can't find home! I'm done here!!"); + syslog(LOG_ERR, "I can't find home! I'm done here!!\n"); + } + } + p_home = NULL; + while(!QDir(QDir::homePath()).exists()) { + qWarning() << "Home is not exits!!"; + printf("Home is not exits!!"); + syslog(LOG_ERR, "Home is not exits!!\n"); + ::sleep(1); + } + + // Output log to file + qInstallMessageHandler(messageOutput); +#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) + QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); +#endif +#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) + QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); +#endif + UkuiSearchDirManagerDbus dirDbus(argc, argv, "ukui-search-service-dir-manager"); + + if (dirDbus.isRunning()) { + return 0; + } + return dirDbus.exec(); +} diff --git a/ukui-search-service-dir-manager/ukui-search-dir-manager-dbus.cpp b/ukui-search-service-dir-manager/ukui-search-dir-manager-dbus.cpp new file mode 100644 index 0000000..ca327e0 --- /dev/null +++ b/ukui-search-service-dir-manager/ukui-search-dir-manager-dbus.cpp @@ -0,0 +1,59 @@ +#include "ukui-search-dir-manager-dbus.h" +#include "dir-watcher.h" + +#include +#include +#include + +UkuiSearchDirManagerDbus::UkuiSearchDirManagerDbus(int &argc, char *argv[], const QString &applicationName) : QtSingleApplication (applicationName, argc, argv) +{ + setQuitOnLastWindowClosed(false); + setApplicationVersion(QString("v%1").arg(VERSION)); + + if (!this->isRunning()) { + qDebug() << "I'm in dir manager dbus rigister"; + QDBusConnection sessionBus = QDBusConnection::sessionBus(); + if(!sessionBus.registerService("com.ukui.search.fileindex.service")) { + qCritical() << "QDbus register service failed reason:" << sessionBus.lastError(); + } + + if(!sessionBus.registerObject("/org/ukui/search/privateDirWatcher", DirWatcher::getDirWatcher(), QDBusConnection::ExportNonScriptableSlots | QDBusConnection::ExportAllSignals)) { + qCritical() << "ukui-search-fileindex dbus register object failed reason:" << sessionBus.lastError(); + } + + connect(this, &QtSingleApplication::messageReceived, [=](QString msg) { + this->parseCmd(msg, true); + }); + } else { + qWarning() << "Ukui search dir manager is running!"; + } + //parse cmd + qDebug()<<"parse cmd"; + auto message = this->arguments().join(' ').toUtf8(); + parseCmd(message, !isRunning()); +} + +void UkuiSearchDirManagerDbus::parseCmd(QString msg, bool isPrimary) +{ + QCommandLineParser parser; + + parser.addHelpOption(); + parser.addVersionOption(); + + QCommandLineOption quitOption(QStringList()<<"q"<<"quit", tr("Quit DBus service")); + parser.addOption(quitOption); + + if (isPrimary) { + if (parser.isSet(quitOption)) { + qApp->quit(); + return; + } + } else { + if (arguments().count() < 2) { + parser.showHelp(); + } + parser.process(arguments()); + sendMessage(msg); + } + +} diff --git a/ukui-search-service-dir-manager/ukui-search-dir-manager-dbus.h b/ukui-search-service-dir-manager/ukui-search-dir-manager-dbus.h new file mode 100644 index 0000000..d8f7f96 --- /dev/null +++ b/ukui-search-service-dir-manager/ukui-search-dir-manager-dbus.h @@ -0,0 +1,15 @@ +#ifndef UKUISEARCHDIRWATCHERDBUS_H +#define UKUISEARCHDIRWATCHERDBUS_H + +#include "qtsingleapplication.h" + +class UkuiSearchDirManagerDbus : public QtSingleApplication +{ + Q_OBJECT +public: + UkuiSearchDirManagerDbus(int &argc, char *argv[], const QString &applicationName = "ukui-search-service-dir-manager"); +protected Q_SLOTS: + void parseCmd(QString msg, bool isPrimary); +}; + +#endif // UKUISEARCHDIRWATCHERDBUS_H diff --git a/ukui-search-service-dir-manager/ukui-search-service-dir-manager.pro b/ukui-search-service-dir-manager/ukui-search-service-dir-manager.pro new file mode 100644 index 0000000..7e1f308 --- /dev/null +++ b/ukui-search-service-dir-manager/ukui-search-service-dir-manager.pro @@ -0,0 +1,45 @@ +QT += core dbus +QT -= gui + +TARGET = ukui-search-service-dir-manager +VERSION = 1.0.0 +DEFINES += VERSION='\\"$${VERSION}\\"' +TEMPLATE = app + +CONFIG += c++11 link_pkgconfig +#CONFIG -= app_bundle +PKGCONFIG += gio-2.0 gio-unix-2.0 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +include(dirwatcher/dir-watcher-dbus.pri) +include(../3rd-parties/qtsingleapplication/qtsingleapplication.pri) + +inst1.files += conf/com.ukui.search.fileindex.service +inst1.path = /usr/share/dbus-1/services/ + +target.source += $$TARGET +target.path = /usr/bin +INSTALLS += \ + target \ + inst1 + +desktop.path = /etc/xdg/autostart +desktop.files += ../data/ukui-search-service-dir-manager.desktop +INSTALLS += desktop + +SOURCES += \ + main.cpp \ + ukui-search-dir-manager-dbus.cpp + +HEADERS += \ + ukui-search-dir-manager-dbus.h diff --git a/ukui-search-service/ukui-search-service.cpp b/ukui-search-service/ukui-search-service.cpp index 0d1b9f6..f1d4abd 100644 --- a/ukui-search-service/ukui-search-service.cpp +++ b/ukui-search-service/ukui-search-service.cpp @@ -1,7 +1,6 @@ #include #include "ukui-search-service.h" #include "dir-watcher.h" -#include "dir-watcher-adaptor.h" #include "common.h" #include @@ -16,7 +15,7 @@ UkuiSearchService::UkuiSearchService(int &argc, char *argv[], const QString &app connect(this, &QtSingleApplication::messageReceived, [=](QString msg) { this->parseCmd(msg, true); }); - + DirWatcher::getDirWatcher(); initGsettings(); FileIndexManager::getInstance()->initIndexPathSetFunction(); } diff --git a/ukui-search.pro b/ukui-search.pro index 508dbfb..31b885b 100644 --- a/ukui-search.pro +++ b/ukui-search.pro @@ -5,7 +5,8 @@ SUBDIRS += $$PWD/libchinese-segmentation \ $$PWD/ukuisearch-systemdbus \ $$PWD/search-ukcc-plugin \ $$PWD/ukui-search-service \ - ukui-search-app-data-service + $$PWD/ukui-search-app-data-service \ + $$PWD/ukui-search-service-dir-manager # The following define makes your compiler emit warnings if you use # any Qt feature that has been marked deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the