First iteration of filetransfer plugin

Now it just downloads to the user desktop payloads received in packages
with type kdeconnect.filetransfer.
Added the package type define.
Created an an auxiliar QFile-like class with a small needed modification.
Added a commented test in the filetransfer plugin code (to be moved).
This commit is contained in:
Albert Vaca 2013-09-10 19:01:46 +02:00
parent 5837fa15db
commit 111ee7f054
10 changed files with 290 additions and 9 deletions

View file

@ -30,13 +30,12 @@ LoopbackDeviceLink::LoopbackDeviceLink(const QString& deviceId, LoopbackLinkProv
bool LoopbackDeviceLink::sendPackage(const NetworkPackage& input)
{
NetworkPackage output("");
NetworkPackage output(QString::null);
NetworkPackage::unserialize(input.serialize(), &output);
//LoopbackDeviceLink does not need deviceTransferInfo
if (input.hasPayload()) {
QIODevice* device = input.payload();
device->open(QIODevice::ReadOnly);
output.setPayload(device);
}

View file

@ -30,6 +30,7 @@
#define PACKAGE_TYPE_TELEPHONY QString("kdeconnect.telephony")
#define PACKAGE_TYPE_CLIPBOARD QString("kdeconnect.clipboard")
#define PACKAGE_TYPE_MPRIS QString("kdeconnect.mpris")
#define PACKAGE_TYPE_FILETRANSFER QString("kdeconnect.filetransfer")
#endif // NETWORKPACKAGETYPES_H

View file

@ -4,6 +4,7 @@ find_package(QCA2 REQUIRED)
include_directories(
${QJSON_INCLUDE_DIR}
${KIO_INCLUDE_DIR}
${QCA2_INCLUDE_DIR}
)
@ -12,6 +13,8 @@ include_directories(${KDE4_INCLUDES})
set(kdeconnect_filetransfer_SRCS
filetransferplugin.cpp
filetransferjob.cpp
autoclosingqfile.cpp
../kdeconnectplugin.cpp
../pluginloader.cpp
../../networkpackage.cpp
@ -23,6 +26,7 @@ kde4_add_plugin(kdeconnect_filetransfer ${kdeconnect_filetransfer_SRCS})
target_link_libraries(kdeconnect_filetransfer
${KDE4_KDECORE_LIBS}
${KDE4_KDEUI_LIBS}
${KDE4_KIO_LIBS}
${QT_QTNETWORK_LIBRARY}
${QJSON_LIBRARIES}
${QCA2_LIBRARIES}

View file

@ -0,0 +1,27 @@
/*
* Copyright 2013 Albert Vaca <albertvaka@gmail.com>
*
* 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) 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 14 of version 3 of the license.
*
* 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, see <http://www.gnu.org/licenses/>.
*/
#include "autoclosingqfile.h"
AutoClosingQFile::AutoClosingQFile(const QString& name)
: QFile(name)
{
}

View file

@ -0,0 +1,43 @@
/*
* Copyright 2013 Albert Vaca <albertvaka@gmail.com>
*
* 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) 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 14 of version 3 of the license.
*
* 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, see <http://www.gnu.org/licenses/>.
*/
#ifndef AUTOCLOSINGQFILE_H
#define AUTOCLOSINGQFILE_H
#include <QFile>
#include <QDebug>
class AutoClosingQFile : public QFile
{
Q_OBJECT
public:
AutoClosingQFile(const QString &name);
virtual qint64 readData(char* data, qint64 maxlen) {
qint64 read = QFile::readData(data, maxlen);
if (read == -1 || read == bytesAvailable()) {
close();
}
return read;
}
};
#endif // AUTOCLOSINGQFILE_H

View file

@ -0,0 +1,96 @@
/*
* Copyright 2013 Albert Vaca <albertvaka@gmail.com>
*
* 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) 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 14 of version 3 of the license.
*
* 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, see <http://www.gnu.org/licenses/>.
*/
#include "filetransferjob.h"
#include <QDebug>
#include <qalgorithms.h>
FileTransferJob::FileTransferJob(QIODevice* origin, const KUrl& destination): KJob()
{
mDestination = destination;
mOrigin = origin;
}
void FileTransferJob::start()
{
//Open destination file
QTemporaryFile tmp;
tmp.setAutoRemove(false);
tmp.open();
mTempDestination = KIO::open(tmp.fileName(), QIODevice::WriteOnly);
connect(mTempDestination, SIGNAL(open(KIO::Job*)), this, SLOT(open(KIO::Job*)));
mTempDestination->start();
}
void FileTransferJob::open(KIO::Job* job)
{
Q_UNUSED(job);
//Open source file
mOrigin->open(QIODevice::ReadOnly);
Q_ASSERT(mOrigin->isOpen());
connect(mOrigin, SIGNAL(readyRead()),this, SLOT(readyRead()));
connect(mOrigin, SIGNAL(aboutToClose()),this, SLOT(sourceFinished()));
if (mOrigin->bytesAvailable() > 0) readyRead();
}
void FileTransferJob::readyRead()
{
//Copy a chunk of data
int bytes = qMin(qint64(4096), mOrigin->bytesAvailable());
QByteArray data = mOrigin->read(bytes);
mTempDestination->write(data);
if(!mOrigin->atEnd())
QMetaObject::invokeMethod(this, "readyRead", Qt::QueuedConnection);
}
void FileTransferJob::sourceFinished()
{
qDebug() << "sourceFinished";
readyRead(); //Read the last chunk of data, if any
qDebug() << "Finished" << mTempDestination->url();
KIO::FileCopyJob* job = KIO::file_move(mTempDestination->url(), mDestination);
connect(job, SIGNAL(result(KJob*)), this, SLOT(moveResult(KJob*)));
job->start();
delete mOrigin; //TODO: Use shared pointers
}
void FileTransferJob::moveResult(KJob* job)
{
//TODO: Error handling, cleanup
qDebug() << "Move result";
qDebug() << job->errorString();
qDebug() << job->errorText();
emitResult();
}

View file

@ -0,0 +1,55 @@
/*
* Copyright 2013 Albert Vaca <albertvaka@gmail.com>
*
* 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) 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 14 of version 3 of the license.
*
* 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, see <http://www.gnu.org/licenses/>.
*/
#ifndef FILETRANSFERJOB_H
#define FILETRANSFERJOB_H
#include <QIODevice>
#include <QTemporaryFile>
#include <KJob>
#include <KUrl>
#include <KIO/FileJob>
#include <KIO/Job>
#include <KSharedPtr>
class FileTransferJob : public KJob
{
Q_OBJECT
public:
FileTransferJob(QIODevice* origin, const KUrl& destination);
virtual void start();
KUrl destination() { return mDestination; }
public Q_SLOTS:
void readyRead();
void moveResult(KJob*);
void open(KIO::Job*);
void sourceFinished();
private:
KIO::FileJob* mTempDestination;
KUrl mDestination;
QIODevice* mOrigin;
};
#endif // FILETRANSFERJOB_H

View file

@ -20,21 +20,72 @@
#include "filetransferplugin.h"
#include <KIcon>
#include <KLocalizedString>
#include <KStandardDirs>
#include <QDebug>
#include <QFile>
#include <QDesktopServices>
#include "filetransferjob.h"
#include "autoclosingqfile.h"
K_PLUGIN_FACTORY( KdeConnectPluginFactory, registerPlugin< FileTransferPlugin >(); )
K_EXPORT_PLUGIN( KdeConnectPluginFactory("kdeconnect_filetransfer", "kdeconnect_filetransfer") )
FileTransferPlugin::FileTransferPlugin(QObject* parent, const QVariantList& args)
: KdeConnectPlugin(parent, args)
{
//TODO: Use downloads user path
//TODO: Be able to change this from config
mDestinationDir = QDesktopServices::DesktopLocation;
}
bool FileTransferPlugin::receivePackage(const NetworkPackage& np)
{
Q_UNUSED(np);
return false;
//TODO: Move this code to a test and do a diff between files
/*
if (np.type() == PACKAGE_TYPE_PING) {
NetworkPackage np(PACKAGE_TYPE_FILETRANSFER);
np.set("filename", mDestinationDir + "/itworks.txt");
//TODO: Use shared pointers
AutoClosingQFile* file = new AutoClosingQFile("/home/vaka/KdeConnect.apk"); //Test file to transfer
np.setPayload(file);
device()->sendPackage(np);
return true;
}
*/
if (np.type() != PACKAGE_TYPE_FILETRANSFER) return false;
if (np.hasPayload()) {
QString filename = np.get<QString>("filename");
QIODevice* incoming = np.payload();
FileTransferJob* job = new FileTransferJob(incoming,filename);
connect(job,SIGNAL(result(KJob*)), this, SLOT(finished(KJob*)));
job->start();
}
return true;
}
void FileTransferPlugin::finished(KJob* job)
{
qDebug() << "File transfer finished";
FileTransferJob* transferJob = (FileTransferJob*)job;
KNotification* notification = new KNotification("pingReceived"); //KNotification::Persistent
notification->setPixmap(KIcon("dialog-ok").pixmap(48, 48));
notification->setComponentData(KComponentData("kdeconnect", "kdeconnect"));
notification->setTitle(i18n("Transfer finished"));
notification->setText(transferJob->destination().fileName());
//TODO: Add action "open destination folder"
notification->sendEvent();
}

View file

@ -21,7 +21,8 @@
#ifndef FILETRANFERPLUGIN_H
#define FILETRANFERPLUGIN_H
#include <knotification.h>
#include <KNotification>
#include <KIO/Job>
#include "../kdeconnectplugin.h"
@ -36,6 +37,10 @@ public:
public Q_SLOTS:
virtual bool receivePackage(const NetworkPackage& np);
virtual void connected() { }
void finished(KJob*);
private:
QString mDestinationDir;
};

View file

@ -11,5 +11,5 @@ X-KDE-PluginInfo-Website=http://albertvaka.wordpress.com
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
Icon=folder-downloads
Name=(Stub) File transfer
Name=File transfer
Comment=Send and receive files from dolphin