KIO::Error toKioError(const QDBusError::ErrorType type)
{
switch (type) {
case QDBusError::NoError:
return KIO::Error(KJob::NoError);
case QDBusError::NoMemory:
return KIO::ERR_OUT_OF_MEMORY;
case QDBusError::Timeout:
return KIO::ERR_SERVER_TIMEOUT;
case QDBusError::TimedOut:
return KIO::ERR_SERVER_TIMEOUT;
default:
return KIO::ERR_WORKER_DEFINED;
};
}
KioKdeconnect::KioKdeconnect(const QByteArray &pool, const QByteArray &app)
: WorkerBase("kdeconnect", pool, app)
, m_dbusInterface(new DaemonDbusInterface(this))
{
}
KIO::WorkerResult KioKdeconnect::listAllDevices()
{
infoMessage(i18n("Listing devices..."));
// TODO: Change to all devices and show different icons for connected and disconnected?
const QStringList devices = m_dbusInterface->devices(true, true);
for (const QString &deviceId : devices) {
DeviceDbusInterface interface(deviceId);
if (!interface.hasPlugin(QStringLiteral("kdeconnect_sftp")))
continue;
const QString path = QStringLiteral("kdeconnect://").append(deviceId).append(QStringLiteral("/"));
const QString name = interface.name();
const QString icon = QStringLiteral("kdeconnect");
KIO::UDSEntry entry;
entry.reserve(6);
entry.fastInsert(KIO::UDSEntry::UDS_NAME, name);
entry.fastInsert(KIO::UDSEntry::UDS_ICON_NAME, icon);
entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, QT_STAT_DIR);
entry.fastInsert(KIO::UDSEntry::UDS_ACCESS,
QFileDevice::ReadOwner | QFileDevice::ExeOwner | QFileDevice::ReadGroup | QFileDevice::ExeGroup | QFileDevice::ReadOther
| QFileDevice::ExeOther);
entry.fastInsert(KIO::UDSEntry::UDS_MIME_TYPE, QLatin1String(""));
entry.fastInsert(KIO::UDSEntry::UDS_URL, path);
listEntry(entry);
}
// We also need a non-null and writable UDSentry for "."
KIO::UDSEntry entry;
entry.reserve(4);
entry.fastInsert(KIO::UDSEntry::UDS_NAME, QStringLiteral("."));
entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, QT_STAT_DIR);
entry.fastInsert(KIO::UDSEntry::UDS_SIZE, 0);
entry.fastInsert(KIO::UDSEntry::UDS_ACCESS,
QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ExeOwner | QFileDevice::ReadGroup | QFileDevice::WriteGroup
| QFileDevice::ExeGroup | QFileDevice::ReadOther | QFileDevice::ExeOther);
listEntry(entry);
infoMessage(QLatin1String(""));
return KIO::WorkerResult::pass();
}
KIO::WorkerResult KioKdeconnect::listDevice(const QString &device)
{
infoMessage(i18n("Accessing device..."));
qCDebug(KDECONNECT_KIO) << "ListDevice" << device;
SftpDbusInterface interface(device);
QDBusReply mountreply = interface.mountAndWait();
if (mountreply.error().type() == QDBusError::UnknownObject) {
DaemonDbusInterface daemon;
auto devsRepl = daemon.devices(false, false);
devsRepl.waitForFinished();
if (!devsRepl.value().contains(device)) {
return KIO::WorkerResult::fail(KIO::ERR_WORKER_DEFINED, i18n("No such device: %0").arg(device));
}
DeviceDbusInterface dev(device);
if (!dev.isTrusted()) {
return KIO::WorkerResult::fail(KIO::ERR_WORKER_DEFINED, i18n("%0 is not paired").arg(dev.name()));
}
if (!dev.isReachable()) {
return KIO::WorkerResult::fail(KIO::ERR_WORKER_DEFINED, i18n("%0 is not connected").arg(dev.name()));
}
if (!dev.hasPlugin(QStringLiteral("kdeconnect_sftp"))) {
return KIO::WorkerResult::fail(KIO::ERR_WORKER_DEFINED, i18n("%0 has no Remote Filesystem plugin").arg(dev.name()));
}
}
if (auto result = handleDBusError(mountreply); !result.success()) {
return result;
}
if (!mountreply.value()) {
return KIO::WorkerResult::fail(KIO::ERR_WORKER_DEFINED, interface.getMountError());
}
QDBusReply urlreply = interface.getDirectories();
if (auto result = handleDBusError(urlreply); !result.success()) {
return result;
}
QVariantMap urls = urlreply.value();
for (QVariantMap::iterator it = urls.begin(); it != urls.end(); ++it) {
const QString path = it.key();
const QString name = it.value().toString();
const QString icon = QStringLiteral("folder");
KIO::UDSEntry entry;
entry.reserve(6);
entry.fastInsert(KIO::UDSEntry::UDS_NAME, name);
entry.fastInsert(KIO::UDSEntry::UDS_ICON_NAME, icon);
entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, QT_STAT_DIR);
entry.fastInsert(KIO::UDSEntry::UDS_ACCESS,
QFileDevice::ReadOwner | QFileDevice::ExeOwner | QFileDevice::ReadGroup | QFileDevice::ExeGroup | QFileDevice::ReadOther
| QFileDevice::ExeOther);
entry.fastInsert(KIO::UDSEntry::UDS_MIME_TYPE, QLatin1String(""));
entry.fastInsert(KIO::UDSEntry::UDS_URL, QUrl::fromLocalFile(path).toString());
listEntry(entry);
}
// We also need a non-null and writable UDSentry for "."
KIO::UDSEntry entry;
entry.reserve(4);
entry.fastInsert(KIO::UDSEntry::UDS_NAME, QStringLiteral("."));
entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, QT_STAT_DIR);
entry.fastInsert(KIO::UDSEntry::UDS_SIZE, 0);
entry.fastInsert(KIO::UDSEntry::UDS_ACCESS,
QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ExeOwner | QFileDevice::ReadGroup | QFileDevice::WriteGroup
| QFileDevice::ExeGroup | QFileDevice::ReadOther | QFileDevice::ExeOther);
listEntry(entry);
infoMessage(QLatin1String(""));
return KIO::WorkerResult::pass();
}
KIO::WorkerResult KioKdeconnect::listDir(const QUrl &url)
{
qCDebug(KDECONNECT_KIO) << "Listing..." << url;
if (!m_dbusInterface->isValid()) {
return KIO::WorkerResult::fail(KIO::Error::ERR_WORKER_DEFINED, i18n("Could not contact background service."));
}
QString currentDevice = url.host();
if (currentDevice.isEmpty()) {
return listAllDevices();
} else {
return listDevice(currentDevice);
}
}
KIO::WorkerResult KioKdeconnect::stat(const QUrl &url)
{
qCDebug(KDECONNECT_KIO) << "Stat: " << url;
KIO::UDSEntry entry;
entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, QT_STAT_DIR);
QString currentDevice = url.host();
if (!currentDevice.isEmpty()) {
SftpDbusInterface interface(currentDevice);
if (interface.isValid()) {
entry.fastInsert(KIO::UDSEntry::UDS_LOCAL_PATH, interface.mountPoint());
if (!interface.isMounted()) {
interface.mount();
}
}
}
statEntry(entry);
return KIO::WorkerResult::pass();
}
KIO::WorkerResult KioKdeconnect::get(const QUrl &url)
{
qCDebug(KDECONNECT_KIO) << "Get: " << url;
mimeType(QLatin1String(""));
return KIO::WorkerResult::pass();
}