Idle timeout for SFTP plugin
This commit is contained in:
parent
9fc9e72374
commit
c90eebd489
5 changed files with 369 additions and 89 deletions
|
@ -26,6 +26,7 @@
|
||||||
#include <KSharedConfig>
|
#include <KSharedConfig>
|
||||||
#include <KStandardDirs>
|
#include <KStandardDirs>
|
||||||
|
|
||||||
|
#include "sftpplugin.h"
|
||||||
#include "../../kdebugnamespace.h"
|
#include "../../kdebugnamespace.h"
|
||||||
|
|
||||||
#include "ui_sftp_config.h"
|
#include "ui_sftp_config.h"
|
||||||
|
@ -35,57 +36,67 @@ K_EXPORT_PLUGIN(SftpConfigFactory("kdeconnect_sftp_config", "kdeconnect_sftp_con
|
||||||
|
|
||||||
SftpConfig::SftpConfig(QWidget *parent, const QVariantList& )
|
SftpConfig::SftpConfig(QWidget *parent, const QVariantList& )
|
||||||
: KCModule(SftpConfigFactory::componentData(), parent)
|
: KCModule(SftpConfigFactory::componentData(), parent)
|
||||||
, ui(new Ui::SftpConfigUi())
|
, m_ui(new Ui::SftpConfigUi())
|
||||||
, cfg(KSharedConfig::openConfig("kdeconnect/plugins/sftp"))
|
, m_cfg(SftpConfig::config())
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
|
|
||||||
ui->check->setIcon(KIconLoader::global()->loadIcon("view-refresh", KIconLoader::Dialog));
|
m_ui->refresh->setIcon(KIconLoader::global()->loadIcon("view-refresh", KIconLoader::Dialog));
|
||||||
connect(ui->check, SIGNAL(clicked(bool)), this, SLOT(refresh()));
|
m_ui->pixmap->setPixmap(KIconLoader::global()->loadIcon("dialog-error", KIconLoader::Dialog));
|
||||||
refresh();
|
|
||||||
|
connect(m_ui->refresh, SIGNAL(clicked(bool)), this, SLOT(checkSshfs()));
|
||||||
|
|
||||||
|
connect(m_ui->mountpoint, SIGNAL(textChanged(QString)), this, SLOT(changed()));
|
||||||
|
connect(m_ui->idle, SIGNAL(toggled(bool)), this, SLOT(changed()));
|
||||||
|
connect(m_ui->timeout, SIGNAL(valueChanged(int)), this, SLOT(changed()));
|
||||||
}
|
}
|
||||||
|
|
||||||
SftpConfig::~SftpConfig()
|
SftpConfig::~SftpConfig()
|
||||||
{
|
{
|
||||||
delete ui;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SftpConfig::refresh()
|
void SftpConfig::checkSshfs()
|
||||||
{
|
{
|
||||||
const QString sshfs = KStandardDirs::findExe("sshfs");
|
m_ui->error->setVisible(KStandardDirs::findExe("sshfs").isEmpty());
|
||||||
|
|
||||||
if (sshfs.isEmpty())
|
|
||||||
{
|
|
||||||
ui->label->setText(i18n("sshfs not found in PATH"));
|
|
||||||
ui->pixmap->setPixmap(KIconLoader::global()->loadIcon("dialog-error", KIconLoader::Dialog));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ui->label->setText(i18n("sshfs found at %1").arg(sshfs));
|
|
||||||
ui->pixmap->setPixmap(KIconLoader::global()->loadIcon("dialog-ok", KIconLoader::Dialog));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SftpConfig::defaults()
|
void SftpConfig::defaults()
|
||||||
{
|
{
|
||||||
KCModule::defaults();
|
KCModule::defaults();
|
||||||
refresh();
|
|
||||||
//Q_EMIT changed(true);
|
checkSshfs();
|
||||||
|
m_ui->mountpoint->setUrl(m_cfg->group("main").readEntry("mountpoint"
|
||||||
|
, KStandardDirs::locateLocal("appdata", "", true, SftpPlugin::componentData())));
|
||||||
|
m_ui->idle->setChecked(m_cfg->group("main").readEntry("idle", true));
|
||||||
|
m_ui->timeout->setValue(m_cfg->group("main").readEntry("idletimeout", 10));
|
||||||
|
|
||||||
|
Q_EMIT changed(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SftpConfig::load()
|
void SftpConfig::load()
|
||||||
{
|
{
|
||||||
KCModule::load();
|
KCModule::load();
|
||||||
refresh() ;
|
|
||||||
//Q_EMIT changed(false);
|
checkSshfs();
|
||||||
|
m_ui->mountpoint->setUrl(m_cfg->group("main").readEntry("mountpoint"
|
||||||
|
, KStandardDirs::locateLocal("appdata", "", true, SftpPlugin::componentData())));
|
||||||
|
m_ui->idle->setChecked(m_cfg->group("main").readEntry("idle", true));
|
||||||
|
m_ui->timeout->setValue(m_cfg->group("main").readEntry("idletimeout", 10));
|
||||||
|
|
||||||
|
Q_EMIT changed(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SftpConfig::save()
|
void SftpConfig::save()
|
||||||
{
|
{
|
||||||
refresh();
|
checkSshfs();
|
||||||
|
m_cfg->group("main").writeEntry("idle", m_ui->idle->isChecked());
|
||||||
|
m_cfg->group("main").writeEntry("idletimeout", m_ui->timeout->value());
|
||||||
|
m_cfg->group("main").writeEntry("mountpoint", m_ui->mountpoint->url().url());
|
||||||
|
|
||||||
KCModule::save();
|
KCModule::save();
|
||||||
//Q_EMIT changed(false);
|
Q_EMIT changed(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -36,17 +36,22 @@ public:
|
||||||
SftpConfig(QWidget *parent, const QVariantList&);
|
SftpConfig(QWidget *parent, const QVariantList&);
|
||||||
virtual ~SftpConfig();
|
virtual ~SftpConfig();
|
||||||
|
|
||||||
|
static inline KSharedConfigPtr config()
|
||||||
|
{
|
||||||
|
return KSharedConfig::openConfig("kdeconnect/plugins/sftp");
|
||||||
|
}
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
virtual void save();
|
virtual void save();
|
||||||
virtual void load();
|
virtual void load();
|
||||||
virtual void defaults();
|
virtual void defaults();
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void refresh();
|
void checkSshfs();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::SftpConfigUi* ui;
|
QScopedPointer<Ui::SftpConfigUi> m_ui;
|
||||||
KSharedConfigPtr cfg;
|
KSharedConfigPtr m_cfg;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,41 +9,28 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>353</width>
|
<width>303</width>
|
||||||
<height>68</height>
|
<height>155</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Share plugin settings</string>
|
<string>Share plugin settings</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item row="0" column="0">
|
<item row="1" column="2">
|
||||||
<widget class="QLabel" name="pixmap">
|
<widget class="KUrlRequester" name="mountpoint">
|
||||||
<property name="sizePolicy">
|
<property name="acceptDrops">
|
||||||
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="scaledContents">
|
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<property name="mode">
|
||||||
</item>
|
<set>KFile::Directory|KFile::ExistingOnly|KFile::LocalOnly</set>
|
||||||
<item row="0" column="1">
|
</property>
|
||||||
<widget class="QLabel" name="label">
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0" colspan="2">
|
<item row="4" column="1" colspan="3">
|
||||||
<spacer name="verticalSpacer">
|
<spacer name="verticalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Vertical</enum>
|
<enum>Qt::Vertical</enum>
|
||||||
|
@ -56,15 +43,182 @@
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="2">
|
<item row="2" column="1" colspan="2">
|
||||||
<widget class="QPushButton" name="check">
|
<widget class="QCheckBox" name="idle">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string>Disconnect when idle</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1" colspan="2">
|
||||||
|
<widget class="QGroupBox" name="error">
|
||||||
|
<property name="title">
|
||||||
|
<string>Error</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="pixmap">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="scaledContents">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>sshfsf not found in PATH</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="refresh">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Mountpoint:</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1" colspan="2">
|
||||||
|
<widget class="QFrame" name="frame">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>16</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Timeout:</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="timeout">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="suffix">
|
||||||
|
<string> min</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>99999999</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>53</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QToolButton" name="toolButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>KUrlRequester</class>
|
||||||
|
<extends>QFrame</extends>
|
||||||
|
<header>kurlrequester.h</header>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>idle</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>frame</receiver>
|
||||||
|
<slot>setEnabled(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>20</x>
|
||||||
|
<y>98</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>14</x>
|
||||||
|
<y>127</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
</ui>
|
</ui>
|
||||||
|
|
|
@ -21,40 +21,66 @@
|
||||||
#include "sftpplugin.h"
|
#include "sftpplugin.h"
|
||||||
|
|
||||||
#include <QDBusConnection>
|
#include <QDBusConnection>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QTimerEvent>
|
||||||
|
|
||||||
|
#include <KConfig>
|
||||||
|
#include <KConfigGroup>
|
||||||
#include <KIconLoader>
|
#include <KIconLoader>
|
||||||
#include <KLocalizedString>
|
#include <KLocalizedString>
|
||||||
#include <KNotification>
|
#include <KNotification>
|
||||||
#include <KProcess>
|
#include <KProcess>
|
||||||
#include <KRun>
|
#include <KRun>
|
||||||
#include <KStandardDirs>
|
#include <KStandardDirs>
|
||||||
|
#include <kde_file.h>
|
||||||
|
|
||||||
|
#include "sftp_config.h"
|
||||||
#include "../../kdebugnamespace.h"
|
#include "../../kdebugnamespace.h"
|
||||||
|
|
||||||
K_PLUGIN_FACTORY( KdeConnectPluginFactory, registerPlugin< SftpPlugin >(); )
|
K_PLUGIN_FACTORY( KdeConnectPluginFactory, registerPlugin< SftpPlugin >(); )
|
||||||
K_EXPORT_PLUGIN( KdeConnectPluginFactory("kdeconnect_sftp", "kdeconnect_sftp") )
|
K_EXPORT_PLUGIN( KdeConnectPluginFactory("kdeconnect_sftp", "kdeconnect_sftp") )
|
||||||
|
|
||||||
static const char* passwd_c = "sftppassword";
|
static const char* passwd_c = "sftppassword";
|
||||||
|
static const char* mountpoint_c = "sftpmountpoint";
|
||||||
|
static const char* timestamp_c = "timestamp";
|
||||||
|
|
||||||
static const QSet<QString> fields_c = QSet<QString>() <<
|
static const QSet<QString> fields_c = QSet<QString>() <<
|
||||||
"ip" << "port" << "user" << "port" << "password" << "path";
|
"ip" << "port" << "user" << "port" << "password" << "path";
|
||||||
|
|
||||||
|
|
||||||
|
inline bool isTimeout(QObject* o, const KConfigGroup& cfg)
|
||||||
|
{
|
||||||
|
int duration = o->property(timestamp_c).toDateTime().secsTo(QDateTime::currentDateTime());
|
||||||
|
return cfg.readEntry("idle", true) && duration > (cfg.readEntry("idletimeout", 60) * 60);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline QString mountpoint(QObject* o)
|
||||||
|
{
|
||||||
|
return o->property(mountpoint_c).toString();
|
||||||
|
}
|
||||||
|
|
||||||
struct SftpPlugin::Pimpl
|
struct SftpPlugin::Pimpl
|
||||||
{
|
{
|
||||||
Pimpl() {};
|
Pimpl() : waitForMount(false)
|
||||||
|
{
|
||||||
|
mountTimer.setSingleShot(true);
|
||||||
|
};
|
||||||
|
|
||||||
QString mountPoint;
|
|
||||||
QPointer<KProcess> mountProc;
|
QPointer<KProcess> mountProc;
|
||||||
|
QTimer mountTimer;
|
||||||
|
int idleTimer;
|
||||||
|
bool waitForMount;
|
||||||
};
|
};
|
||||||
|
|
||||||
SftpPlugin::SftpPlugin(QObject *parent, const QVariantList &args)
|
SftpPlugin::SftpPlugin(QObject *parent, const QVariantList &args)
|
||||||
: KdeConnectPlugin(parent, args)
|
: KdeConnectPlugin(parent, args)
|
||||||
, m_d(new Pimpl)
|
, m_d(new Pimpl)
|
||||||
{
|
{
|
||||||
m_d->mountPoint = KStandardDirs::locateLocal("appdata", device()->name() + "/", true,
|
|
||||||
KComponentData("kdeconnect", "kdeconnect"));
|
|
||||||
QDBusConnection::sessionBus().registerObject(dbusPath(), this, QDBusConnection::ExportScriptableContents);
|
QDBusConnection::sessionBus().registerObject(dbusPath(), this, QDBusConnection::ExportScriptableContents);
|
||||||
|
|
||||||
|
m_d->idleTimer = startTimer(20 * 1000);
|
||||||
|
|
||||||
|
connect(&m_d->mountTimer, SIGNAL(timeout()), this, SLOT(mountTimeout()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SftpPlugin::connected()
|
void SftpPlugin::connected()
|
||||||
|
@ -64,24 +90,49 @@ void SftpPlugin::connected()
|
||||||
SftpPlugin::~SftpPlugin()
|
SftpPlugin::~SftpPlugin()
|
||||||
{
|
{
|
||||||
QDBusConnection::sessionBus().unregisterObject(dbusPath(), QDBusConnection::UnregisterTree);
|
QDBusConnection::sessionBus().unregisterObject(dbusPath(), QDBusConnection::UnregisterTree);
|
||||||
stopBrowsing();
|
umount();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SftpPlugin::startBrowsing()
|
void SftpPlugin::mount()
|
||||||
{
|
{
|
||||||
|
if (m_d->mountTimer.isActive() || m_d->mountProc)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_d->mountTimer.start(10000);
|
||||||
|
}
|
||||||
|
|
||||||
NetworkPackage np(PACKAGE_TYPE_SFTP);
|
NetworkPackage np(PACKAGE_TYPE_SFTP);
|
||||||
np.set("startBrowsing", true);
|
np.set("startBrowsing", true);
|
||||||
device()->sendPackage(np);
|
device()->sendPackage(np);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SftpPlugin::stopBrowsing()
|
void SftpPlugin::umount()
|
||||||
{
|
{
|
||||||
cleanMountPoint();
|
|
||||||
if (m_d->mountProc)
|
if (m_d->mountProc)
|
||||||
{
|
{
|
||||||
m_d->mountProc->terminate();
|
cleanMountPoint(m_d->mountProc);
|
||||||
QTimer::singleShot(5000, m_d->mountProc, SLOT(kill()));
|
if (m_d->mountProc)
|
||||||
m_d->mountProc->waitForFinished();
|
{
|
||||||
|
m_d->mountProc->terminate();
|
||||||
|
QTimer::singleShot(5000, m_d->mountProc, SLOT(kill()));
|
||||||
|
m_d->mountProc->waitForFinished();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SftpPlugin::startBrowsing()
|
||||||
|
{
|
||||||
|
if (m_d->mountProc)
|
||||||
|
{
|
||||||
|
new KRun(KUrl::fromLocalFile(mountpoint(m_d->mountProc)), 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_d->waitForMount = true;
|
||||||
|
mount();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,9 +146,11 @@ bool SftpPlugin::receivePackage(const NetworkPackage& np)
|
||||||
|
|
||||||
if (!m_d->mountProc.isNull())
|
if (!m_d->mountProc.isNull())
|
||||||
{
|
{
|
||||||
return new KRun(KUrl::fromLocalFile(m_d->mountPoint), 0);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_d->mountTimer.stop();
|
||||||
|
|
||||||
m_d->mountProc = new KProcess(this);
|
m_d->mountProc = new KProcess(this);
|
||||||
m_d->mountProc->setOutputChannelMode(KProcess::SeparateChannels);
|
m_d->mountProc->setOutputChannelMode(KProcess::SeparateChannels);
|
||||||
|
|
||||||
|
@ -106,6 +159,10 @@ bool SftpPlugin::receivePackage(const NetworkPackage& np)
|
||||||
connect(m_d->mountProc, SIGNAL(finished(int,QProcess::ExitStatus)), SLOT(onFinished(int,QProcess::ExitStatus)));
|
connect(m_d->mountProc, SIGNAL(finished(int,QProcess::ExitStatus)), SLOT(onFinished(int,QProcess::ExitStatus)));
|
||||||
connect(m_d->mountProc, SIGNAL(finished(int,QProcess::ExitStatus)), m_d->mountProc, SLOT(deleteLater()));
|
connect(m_d->mountProc, SIGNAL(finished(int,QProcess::ExitStatus)), m_d->mountProc, SLOT(deleteLater()));
|
||||||
|
|
||||||
|
const QString mpoint = KConfig("kdeconnect/plugins/sftp").group("main").readEntry("mountpoint"
|
||||||
|
, KStandardDirs::locateLocal("appdata", "", true, componentData())) + "/" + device()->name() + "/";
|
||||||
|
QDir().mkpath(mpoint);
|
||||||
|
|
||||||
const QString program = "sshfs";
|
const QString program = "sshfs";
|
||||||
const QStringList arguments = QStringList()
|
const QStringList arguments = QStringList()
|
||||||
<< QString("%1@%2:%3")
|
<< QString("%1@%2:%3")
|
||||||
|
@ -116,29 +173,49 @@ bool SftpPlugin::receivePackage(const NetworkPackage& np)
|
||||||
<< "-d"
|
<< "-d"
|
||||||
<< "-f"
|
<< "-f"
|
||||||
<< "-o" << "password_stdin"
|
<< "-o" << "password_stdin"
|
||||||
<< m_d->mountPoint;
|
<< mpoint;
|
||||||
|
|
||||||
m_d->mountProc->setProgram(program, arguments);
|
m_d->mountProc->setProgram(program, arguments);
|
||||||
m_d->mountProc->setProperty(passwd_c, np.get<QString>("password"));
|
m_d->mountProc->setProperty(passwd_c, np.get<QString>("password"));
|
||||||
|
m_d->mountProc->setProperty(mountpoint_c, mpoint);
|
||||||
|
|
||||||
cleanMountPoint();
|
cleanMountPoint(m_d->mountProc);
|
||||||
m_d->mountProc->start();
|
m_d->mountProc->start();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SftpPlugin::timerEvent(QTimerEvent* event)
|
||||||
|
{
|
||||||
|
if (event->timerId() == m_d->idleTimer)
|
||||||
|
{
|
||||||
|
if (isTimeout(m_d->mountProc, SftpConfig::config()->group("main")))
|
||||||
|
{
|
||||||
|
umount();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QObject::timerEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
void SftpPlugin::onStarted()
|
void SftpPlugin::onStarted()
|
||||||
{
|
{
|
||||||
|
m_d->mountProc->setProperty(timestamp_c, QDateTime::currentDateTime());
|
||||||
|
|
||||||
m_d->mountProc->write(m_d->mountProc->property(passwd_c).toString().toLocal8Bit() + "\n");
|
m_d->mountProc->write(m_d->mountProc->property(passwd_c).toString().toLocal8Bit() + "\n");
|
||||||
m_d->mountProc->closeWriteChannel();
|
m_d->mountProc->closeWriteChannel();
|
||||||
|
|
||||||
knotify(KNotification::Notification
|
knotify(KNotification::Notification
|
||||||
, i18n("Device %1").arg(device()->name())
|
, i18n("Filesystem mounted at %1").arg(mountpoint(sender()))
|
||||||
, i18n("Filesystem mounted at %1").arg(m_d->mountPoint)
|
|
||||||
, KIconLoader::global()->loadIcon("drive-removable-media", KIconLoader::Desktop)
|
, KIconLoader::global()->loadIcon("drive-removable-media", KIconLoader::Desktop)
|
||||||
);
|
);
|
||||||
|
|
||||||
new KRun(KUrl::fromLocalFile(m_d->mountPoint), 0);
|
if (m_d->waitForMount)
|
||||||
|
{
|
||||||
|
m_d->waitForMount = false;
|
||||||
|
new KRun(KUrl::fromLocalFile(mountpoint(sender())), 0);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SftpPlugin::onError(QProcess::ProcessError error)
|
void SftpPlugin::onError(QProcess::ProcessError error)
|
||||||
|
@ -146,11 +223,10 @@ void SftpPlugin::onError(QProcess::ProcessError error)
|
||||||
if (error == QProcess::FailedToStart)
|
if (error == QProcess::FailedToStart)
|
||||||
{
|
{
|
||||||
knotify(KNotification::Error
|
knotify(KNotification::Error
|
||||||
, i18n("Device %1").arg(device()->name())
|
|
||||||
, i18n("Failed to start sshfs")
|
, i18n("Failed to start sshfs")
|
||||||
, KIconLoader::global()->loadIcon("dialog-error", KIconLoader::Desktop)
|
, KIconLoader::global()->loadIcon("dialog-error", KIconLoader::Desktop)
|
||||||
);
|
);
|
||||||
cleanMountPoint();
|
cleanMountPoint(sender());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,34 +236,57 @@ void SftpPlugin::onFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
||||||
|
|
||||||
if (exitStatus == QProcess::NormalExit)
|
if (exitStatus == QProcess::NormalExit)
|
||||||
{
|
{
|
||||||
knotify(KNotification::Notification
|
if (isTimeout(sender(), SftpConfig::config()->group("main")))
|
||||||
, i18n("Device %1").arg(device()->name())
|
{
|
||||||
, i18n("Filesystem unmounted")
|
knotify(KNotification::Notification
|
||||||
, KIconLoader::global()->loadIcon("dialog-ok", KIconLoader::Desktop)
|
, i18n("Filesystem unmounted by idle timeout")
|
||||||
);
|
, KIconLoader::global()->loadIcon("clock", KIconLoader::Desktop)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
knotify(KNotification::Notification
|
||||||
|
, i18n("Filesystem unmounted")
|
||||||
|
, KIconLoader::global()->loadIcon("dialog-ok", KIconLoader::Desktop)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
knotify(KNotification::Error
|
knotify(KNotification::Error
|
||||||
, i18n("Device %1").arg(device()->name())
|
|
||||||
, i18n("Error when accessing to filesystem")
|
, i18n("Error when accessing to filesystem")
|
||||||
, KIconLoader::global()->loadIcon("dialog-error", KIconLoader::Desktop)
|
, KIconLoader::global()->loadIcon("dialog-error", KIconLoader::Desktop)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanMountPoint();
|
cleanMountPoint(sender());
|
||||||
m_d->mountProc = 0;
|
m_d->mountProc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SftpPlugin::knotify(int type, const QString& title, const QString& text, const QPixmap& icon) const
|
void SftpPlugin::knotify(int type, const QString& text, const QPixmap& icon) const
|
||||||
{
|
{
|
||||||
KNotification::event(KNotification::StandardEvent(type), title, text, icon, 0
|
KNotification::event(KNotification::StandardEvent(type)
|
||||||
|
, i18n("Device %1").arg(device()->name()), text, icon, 0
|
||||||
, KNotification::CloseOnTimeout);
|
, KNotification::CloseOnTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SftpPlugin::cleanMountPoint()
|
void SftpPlugin::cleanMountPoint(QObject* mounter)
|
||||||
{
|
{
|
||||||
if (m_d->mountProc.isNull()) return;
|
if (!mounter || mountpoint(mounter).isEmpty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
KProcess::execute(QStringList() << "fusermount" << "-u" << m_d->mountPoint, 10000);
|
KProcess::execute(QStringList()
|
||||||
|
<< "fusermount" << "-u"
|
||||||
|
<< mountpoint(mounter), 10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SftpPlugin::mountTimeout()
|
||||||
|
{
|
||||||
|
knotify(KNotification::Error
|
||||||
|
, i18n("Failed to mount filesystem: device not responding")
|
||||||
|
, KIconLoader::global()->loadIcon("dialog-error", KIconLoader::Desktop)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,22 +39,33 @@ public:
|
||||||
explicit SftpPlugin(QObject *parent, const QVariantList &args);
|
explicit SftpPlugin(QObject *parent, const QVariantList &args);
|
||||||
virtual ~SftpPlugin();
|
virtual ~SftpPlugin();
|
||||||
|
|
||||||
|
inline static KComponentData componentData()
|
||||||
|
{
|
||||||
|
return KComponentData("kdeconnect", "kdeconnect");
|
||||||
|
}
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
virtual bool receivePackage(const NetworkPackage& np);
|
virtual bool receivePackage(const NetworkPackage& np);
|
||||||
virtual void connected();
|
virtual void connected();
|
||||||
|
|
||||||
|
Q_SCRIPTABLE void mount();
|
||||||
|
Q_SCRIPTABLE void umount();
|
||||||
|
|
||||||
Q_SCRIPTABLE void startBrowsing();
|
Q_SCRIPTABLE void startBrowsing();
|
||||||
Q_SCRIPTABLE void stopBrowsing();
|
|
||||||
|
protected:
|
||||||
|
void timerEvent(QTimerEvent *event);
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void onStarted();
|
void onStarted();
|
||||||
void onError(QProcess::ProcessError error);
|
void onError(QProcess::ProcessError error);
|
||||||
void onFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
void onFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||||
|
void mountTimeout();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString dbusPath() const { return "/modules/kdeconnect/devices/" + device()->id() + "/sftp"; }
|
QString dbusPath() const { return "/modules/kdeconnect/devices/" + device()->id() + "/sftp"; }
|
||||||
void knotify(int type, const QString& title, const QString& text, const QPixmap& icon) const;
|
void knotify(int type, const QString& text, const QPixmap& icon) const;
|
||||||
void cleanMountPoint();
|
void cleanMountPoint(QObject* mounter);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Pimpl;
|
struct Pimpl;
|
||||||
|
|
Loading…
Reference in a new issue