diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -16,6 +16,7 @@ add_subdirectory(kioexec) add_subdirectory(urifilters) add_subdirectory(kcms) +add_subdirectory(mountserviced) if(NOT WIN32 AND NOT ANDROID) # arpa/nameser.h diff --git a/src/mountserviced/CMakeLists.txt b/src/mountserviced/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/src/mountserviced/CMakeLists.txt @@ -0,0 +1,18 @@ +set(mountservicemanager_SRCS mountservicemanager.cpp) + +find_package(KDED CONFIG REQUIRED) + +qt5_add_dbus_adaptor(mountservicemanager_SRCS org.kde.kio.MountServiceManager.xml mountservicemanager.h MountServiceManager) +qt5_add_dbus_interface(mountservicemanager_SRCS ${KDED_DBUS_INTERFACE} kded_interface) + +add_library(mountservicemanager MODULE ${mountservicemanager_SRCS}) + +kcoreaddons_desktop_to_json(mountservicemanager mountservicemanager.desktop) + +target_link_libraries(mountservicemanager + KF5::CoreAddons + KF5::DBusAddons + KF5::KIOCore +) + +install(TARGETS mountservicemanager DESTINATION ${PLUGIN_INSTALL_DIR}/kf5/kded) diff --git a/src/mountserviced/mountservicemanager.h b/src/mountserviced/mountservicemanager.h new file mode 100644 --- /dev/null +++ b/src/mountserviced/mountservicemanager.h @@ -0,0 +1,50 @@ +/* This file is part of the KDE libraries + Copyright (C) 2019 by Chinmoy Ranjan Pradhan + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef MOUNTSERVICEMANAGER_H +#define MOUNTSERVICEMANAGER_H + +#include +#include + +class Private; +class KPluginMetaData; + +class MountServiceManager : public KDEDModule +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.kde.kio.MountServiceManager") + + public: + MountServiceManager(QObject* parent, const QList ¶meters); + ~MountServiceManager(); + + public Q_SLOTS: + Q_SCRIPTABLE QStringList availableServices() const; + Q_SCRIPTABLE void mountURL(const QString &remoteURL); + Q_SCRIPTABLE QString localURL(const QString &remoteURL); + + private Q_SLOTS: + void dirty(const QString &path); + + private: + Private *d; +}; + +#endif diff --git a/src/mountserviced/mountservicemanager.cpp b/src/mountserviced/mountservicemanager.cpp new file mode 100644 --- /dev/null +++ b/src/mountserviced/mountservicemanager.cpp @@ -0,0 +1,136 @@ +/* This file is part of the KDE libraries + Copyright (C) 2019 by Chinmoy Ranjan Pradhan + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "mountservicemanager.h" +#include "kded_interface.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + + +K_PLUGIN_FACTORY_WITH_JSON(MountServiceManagerFactory, + "mountservicemanager.json", + registerPlugin();) + +static QString getMountService(const QUrl &url) +{ + KConfigGroup cfg = KConfigGroup(KSharedConfig::openConfig(QStringLiteral("fusemanagerrc")), QStringLiteral("Fuse Services")); + return cfg.readEntry(url.scheme(), QString()); +} + +static void loadModule(const QString &mountService) +{ + org::kde::kded5 kded(QStringLiteral("org.kde.kded5"), QStringLiteral("/kded"), QDBusConnection::sessionBus()); + kded.loadModule(mountService).waitForFinished(); +} + +class Private +{ + public: + void addMountService(const QString &pluginPath) + { + if (QLibrary::isLibrary(pluginPath)) { + KPluginMetaData metadata(pluginPath); + if (metadata.isValid() && metadata.category().startsWith(QLatin1String("MountService"))) { + mountServices.insert(pluginPath, metadata); + } + } + } + + KDirWatch *dirWatch; + QMap mountServices; +}; + +MountServiceManager::MountServiceManager(QObject *parent, const QList ¶meters) + : KDEDModule(parent) + , d(new Private) +{ + Q_UNUSED(parameters); + + d->dirWatch = new KDirWatch(this); + QSet dirsToWatch; + const QString subdir = QLatin1String("kf5/kded"); + const QStringList listPaths = QCoreApplication::libraryPaths(); + for (const QString &libDir : listPaths) { + dirsToWatch << libDir + QLatin1Char('/') + subdir; + } + + for (const QString &dir : dirsToWatch) { + d->dirWatch->addDir(dir); + QDirIterator it(dir, QDir::Files); + while (it.hasNext()) { + it.next(); + d->addMountService(it.fileInfo().absoluteFilePath()); + } + } + connect(d->dirWatch, &KDirWatch::dirty, this, &MountServiceManager::dirty); +} + +MountServiceManager::~MountServiceManager() +{ + delete d; +} + +QStringList MountServiceManager::availableServices() const +{ + QStringList mountServices; + foreach (auto service, d->mountServices) { + mountServices << service.pluginId(); + } + return mountServices; +} + +void MountServiceManager::mountURL(const QString &remoteURL) +{ + const QUrl url = QUrl::fromUserInput(remoteURL); + const QString mountService = getMountService(url); + loadModule(mountService); + QDBusInterface iface(QStringLiteral("org.kde.kded5"), QStringLiteral("/modules/%1").arg(mountService)); + iface.call(QDBus::NoBlock, QStringLiteral("mount"), remoteURL); +} + +QString MountServiceManager::localURL(const QString &remoteURL) +{ + const QUrl url = QUrl::fromUserInput(remoteURL); + const QString mountService = getMountService(url); + QDBusInterface iface(QStringLiteral("org.kde.kded5"), QStringLiteral("/modules/%1").arg(mountService)); + QDBusReply reply = iface.call(QStringLiteral("localUrl"), remoteURL); + return reply.value(); +} + +void MountServiceManager::dirty(const QString &path) +{ + if (QFile::exists(path)) { + d->addMountService(path); + } else { + d->mountServices.remove(path); + } +} + + +#include "mountservicemanager.moc" diff --git a/src/mountserviced/mountservicemanager.desktop b/src/mountserviced/mountservicemanager.desktop new file mode 100644 --- /dev/null +++ b/src/mountserviced/mountservicemanager.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Type=Service +Name=Mount Service Manager +X-KDE-ServiceTypes=KDEDModule +X-KDE-Library=mountservicemanager +X-KDE-FactoryName=mountservicemanager +X-KDE-Kded-load-on-demand=true +X-KDE-Kded-autoload=true +Comment=Manages kded modules that provide mounting capabilities for remote protocols. diff --git a/src/mountserviced/org.kde.kio.MountServiceManager.xml b/src/mountserviced/org.kde.kio.MountServiceManager.xml new file mode 100644 --- /dev/null +++ b/src/mountserviced/org.kde.kio.MountServiceManager.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + +