kde-playground/kdepim/pimcommon/storageservice/gdrive/gdrivejob.cpp
2015-04-14 21:49:29 +00:00

476 lines
16 KiB
C++

/*
Copyright (c) 2014 Montel Laurent <montel@kde.org>
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License, version 2, as
published by the Free Software Foundation.
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 Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "gdrivejob.h"
#include "storageservice/authdialog/storageauthviewdialog.h"
#include "pimcommon/storageservice/storageservicejobconfig.h"
#include <libkgapi2/authjob.h>
#include <libkgapi2/account.h>
#include <libkgapi2/drive/aboutfetchjob.h>
#include <libkgapi2/drive/about.h>
#include <libkgapi2/drive/filecreatejob.h>
#include <libkgapi2/drive/filedeletejob.h>
#include <libkgapi2/drive/filefetchjob.h>
#include <libkgapi2/drive/filefetchcontentjob.h>
#include <libkgapi2/types.h>
#include <libkgapi2/drive/childreferencefetchjob.h>
#include <libkgapi2/drive/childreference.h>
#include <libkgapi2/drive/file.h>
#include <libkgapi2/drive/filecopyjob.h>
#include <LibKGAPI2/Drive/ParentReference>
#include <KLocalizedString>
#include <qjson/parser.h>
#include <QNetworkAccessManager>
#include <QDebug>
#include <QNetworkReply>
#include <QPointer>
#include <QDebug>
#include <QFile>
#include <QPointer>
#include <QDateTime>
using namespace PimCommon;
GDriveJob::GDriveJob(QObject *parent)
: PimCommon::StorageServiceAbstractJob(parent)
{
mClientId = PimCommon::StorageServiceJobConfig::self()->gdriveClientId();
mClientSecret = PimCommon::StorageServiceJobConfig::self()->gdriveClientSecret();
}
GDriveJob::~GDriveJob()
{
}
bool GDriveJob::handleError( KGAPI2::Job *job )
{
qDebug() << job->error() << job->errorString();
switch ( job->error() ) {
case KGAPI2::OK:
case KGAPI2::NoError:
return false;
case KGAPI2::AuthCancelled:
case KGAPI2::AuthError:
case KGAPI2::Unauthorized:
case KGAPI2::Forbidden:
case KGAPI2::NotFound:
case KGAPI2::NoContent:
case KGAPI2::QuotaExceeded:
default:
return true;
}
return true;
}
QString GDriveJob::lastPathComponent( const QUrl &url ) const
{
QString path = url.toString( QUrl::StripTrailingSlash );
if ( path.indexOf( QLatin1Char( '/' ) ) == -1 ) {
return QLatin1String( "root" );
} else {
return path.mid( path.lastIndexOf( QLatin1Char('/') ) + 1 );
}
}
void GDriveJob::listFolder(const QString &folder)
{
mActionType = PimCommon::StorageServiceAbstract::ListFolderAction;
mError = false;
const QString folderId = folder.isEmpty() ? QLatin1String("root") : folder;
KGAPI2::Drive::ChildReferenceFetchJob *fetchJob = new KGAPI2::Drive::ChildReferenceFetchJob( folderId, mAccount );
connect(fetchJob, SIGNAL(finished(KGAPI2::Job*)), this, SLOT(slotChildReferenceFetchJobFinished(KGAPI2::Job*)));
}
void GDriveJob::slotChildReferenceFetchJobFinished(KGAPI2::Job *job)
{
KGAPI2::Drive::ChildReferenceFetchJob *childRef = qobject_cast<KGAPI2::Drive::ChildReferenceFetchJob *>(job);
if (childRef) {
KGAPI2::ObjectsList objects = childRef->items();
QStringList filesIds;
Q_FOREACH ( const KGAPI2::ObjectPtr &object, objects ) {
const KGAPI2::Drive::ChildReferencePtr ref = object.dynamicCast<KGAPI2::Drive::ChildReference>();
filesIds << ref->id();
}
KGAPI2::Drive::FileFetchJob *fileFetchJob = new KGAPI2::Drive::FileFetchJob( filesIds, mAccount );
connect(fileFetchJob, SIGNAL(finished(KGAPI2::Job*)), this, SLOT(slotFileFetchFinished(KGAPI2::Job*)));
childRef->deleteLater();
} else {
//TODO emit error
deleteLater();
}
}
void GDriveJob::slotFileFetchFinished(KGAPI2::Job* job)
{
KGAPI2::Drive::FileFetchJob *fileFetchJob = qobject_cast<KGAPI2::Drive::FileFetchJob*>(job);
Q_ASSERT(fileFetchJob);
QStringList listFolder;
KGAPI2::ObjectsList objects = fileFetchJob->items();
Q_FOREACH ( const KGAPI2::ObjectPtr &object, objects ) {
const KGAPI2::Drive::FilePtr file = object.dynamicCast<KGAPI2::Drive::File>();
qDebug()<<" file "<<file;
if ( !file->labels() || file->labels()->trashed() ) {
continue;
}
const QString value = QString::fromLatin1(KGAPI2::Drive::File::toJSON(file));
listFolder<<value;
}
fileFetchJob->deleteLater();
Q_EMIT listFolderDone(QVariant(listFolder));
deleteLater();
}
void GDriveJob::requestTokenAccess()
{
mError = false;
mActionType = PimCommon::StorageServiceAbstract::RequestTokenAction;
KGAPI2::AuthJob *authJob = new KGAPI2::AuthJob(
mAccount,
mClientId,
mClientSecret);
connect(authJob, SIGNAL(finished(KGAPI2::Job*)),
this, SLOT(slotAuthJobFinished(KGAPI2::Job*)));
}
void GDriveJob::slotAuthJobFinished(KGAPI2::Job *job)
{
KGAPI2::AuthJob *authJob = qobject_cast<KGAPI2::AuthJob*>(job);
Q_ASSERT(authJob);
if (handleError(job)) {
Q_EMIT authorizationFailed(authJob->errorString());
deleteLater();
return;
}
KGAPI2::AccountPtr account = authJob->account();
//qDebug()<<" account->expireDateTime()"<<account->expireDateTime();
Q_EMIT authorizationDone(account->refreshToken(),account->accessToken(), account->expireDateTime(), account->accountName());
/* Always remember to delete the jobs, otherwise your application will
* leak memory. */
authJob->deleteLater();
deleteLater();
}
void GDriveJob::initializeToken(KGAPI2::AccountPtr account)
{
mError = false;
mAccount = account;
}
void GDriveJob::accountInfo()
{
mActionType = PimCommon::StorageServiceAbstract::AccountInfoAction;
mError = false;
KGAPI2::Drive::AboutFetchJob *aboutFetchJob = new KGAPI2::Drive::AboutFetchJob(mAccount, this);
connect(aboutFetchJob, SIGNAL(finished(KGAPI2::Job*)), this, SLOT(slotAboutFetchJobFinished(KGAPI2::Job*)));
}
void GDriveJob::slotAboutFetchJobFinished(KGAPI2::Job *job)
{
KGAPI2::Drive::AboutFetchJob *aboutFetchJob = qobject_cast<KGAPI2::Drive::AboutFetchJob*>(job);
Q_ASSERT(aboutFetchJob);
if (handleError(job)) {
Q_EMIT actionFailed(aboutFetchJob->errorString());
aboutFetchJob->deleteLater();
deleteLater();
return;
}
KGAPI2::Drive::AboutPtr about = aboutFetchJob->aboutData();
PimCommon::AccountInfo accountInfo;
accountInfo.shared = about->quotaBytesUsed();
accountInfo.quota = about->quotaBytesTotal();
Q_EMIT accountInfoDone(accountInfo);
aboutFetchJob->deleteLater();
deleteLater();
}
QNetworkReply *GDriveJob::uploadFile(const QString &filename, const QString &uploadAsName, const QString &destination)
{
mActionType = PimCommon::StorageServiceAbstract::UploadFileAction;
mError = false;
KGAPI2::Drive::FilePtr file( new KGAPI2::Drive::File() );
file->setTitle( uploadAsName );
KGAPI2::Drive::ParentReferencePtr parent( new KGAPI2::Drive::ParentReference( destination ) );
file->setParents( KGAPI2::Drive::ParentReferencesList() << parent );
//TODO destination
KGAPI2::Drive::FileCreateJob *createJob = new KGAPI2::Drive::FileCreateJob( filename/*, file*/, mAccount);
connect(createJob, SIGNAL(finished(KGAPI2::Job*)), this, SLOT(slotUploadJobFinished(KGAPI2::Job*)));
connect(createJob, SIGNAL(progress(KGAPI2::Job*,int,int)), this, SLOT(slotUploadDownLoadProgress(KGAPI2::Job*,int,int)));
return 0;
}
void GDriveJob::slotUploadDownLoadProgress(KGAPI2::Job *job, int progress, int total)
{
Q_UNUSED(job);
qDebug()<<" progress "<<progress<<" total"<<total;
Q_EMIT uploadDownloadFileProgress(progress, total);
}
void GDriveJob::slotUploadJobFinished(KGAPI2::Job* job)
{
if (handleError(job)) {
Q_EMIT errorMessage(mActionType, job->errorString());
} else {
Q_EMIT uploadFileDone(QString());
}
job->deleteLater();
deleteLater();
}
void GDriveJob::deleteFile(const QString &filename)
{
mActionType = PimCommon::StorageServiceAbstract::DeleteFileAction;
mError = false;
const QString folderId = filename;
KGAPI2::Drive::FileDeleteJob *fileDeleteJob = new KGAPI2::Drive::FileDeleteJob(folderId, mAccount, this);
connect(fileDeleteJob, SIGNAL(finished(KGAPI2::Job*)), this, SLOT(slotDeleteFileFinished(KGAPI2::Job*)));
}
void GDriveJob::deleteFolder(const QString &foldername)
{
mActionType = PimCommon::StorageServiceAbstract::DeleteFolderAction;
mError = false;
const QString folderId = foldername;
KGAPI2::Drive::FileDeleteJob *fileDeleteJob = new KGAPI2::Drive::FileDeleteJob(folderId, mAccount, this);
connect(fileDeleteJob, SIGNAL(finished(KGAPI2::Job*)), this, SLOT(slotDeleteFolderFinished(KGAPI2::Job*)));
}
void GDriveJob::slotDeleteFolderFinished(KGAPI2::Job*job)
{
if (handleError(job)) {
Q_EMIT errorMessage(mActionType, job->errorString());
} else {
Q_EMIT deleteFolderDone(QString());
}
job->deleteLater();
deleteLater();
}
void GDriveJob::slotDeleteFileFinished(KGAPI2::Job*job)
{
if (handleError(job)) {
Q_EMIT errorMessage(mActionType, job->errorString());
} else {
Q_EMIT deleteFileDone(QString());
}
job->deleteLater();
deleteLater();
}
QNetworkReply * GDriveJob::downloadFile(const QString &name, const QString &fileId, const QString &destination)
{
mActionType = PimCommon::StorageServiceAbstract::DownLoadFileAction;
mError = false;
const QString defaultDestination = (destination.isEmpty() ? PimCommon::StorageServiceJobConfig::self()->defaultUploadFolder() : destination);
delete mDownloadFile;
mDownloadFile = new QFile(defaultDestination+ QLatin1Char('/') + name);
if (mDownloadFile->open(QIODevice::WriteOnly)) {
KGAPI2::Drive::FilePtr file( new KGAPI2::Drive::File() );
KGAPI2::Drive::FileFetchContentJob *fileFetchContentJob = new KGAPI2::Drive::FileFetchContentJob(file, mAccount, this);
//TODO
return 0;
} else {
delete mDownloadFile;
}
return 0;
}
void GDriveJob::refreshToken()
{
mActionType = PimCommon::StorageServiceAbstract::AccessTokenAction;
KGAPI2::AuthJob *authJob = new KGAPI2::AuthJob(
mAccount,
mClientId,
mClientSecret);
connect(authJob, SIGNAL(finished(KGAPI2::Job*)), this, SLOT(slotAuthJobFinished(KGAPI2::Job*)));
}
void GDriveJob::createFolder(const QString &foldername, const QString &destination)
{
mActionType = PimCommon::StorageServiceAbstract::CreateFolderAction;
mError = false;
KGAPI2::Drive::FilePtr file( new KGAPI2::Drive::File() );
file->setTitle( foldername );
file->setMimeType( KGAPI2::Drive::File::folderMimeType() );
KGAPI2::Drive::ParentReferencePtr parent( new KGAPI2::Drive::ParentReference( destination ) );
file->setParents( KGAPI2::Drive::ParentReferencesList() << parent );
KGAPI2::Drive::FileCreateJob *createJob = new KGAPI2::Drive::FileCreateJob( file, mAccount);
connect(createJob, SIGNAL(finished(KGAPI2::Job*)), this, SLOT(slotCreateJobFinished(KGAPI2::Job*)));
}
void GDriveJob::slotCreateJobFinished(KGAPI2::Job *job)
{
if (handleError(job)) {
Q_EMIT errorMessage(mActionType, job->errorString());
} else {
Q_EMIT createFolderDone(QString());
}
job->deleteLater();
deleteLater();
}
void GDriveJob::createServiceFolder()
{
mActionType = PimCommon::StorageServiceAbstract::CreateServiceFolderAction;
mError = false;
const QString folderName = lastPathComponent( QString() );
KGAPI2::Drive::FilePtr file( new KGAPI2::Drive::File() );
file->setTitle( PimCommon::StorageServiceJobConfig::self()->defaultUploadFolder() );
file->setMimeType( KGAPI2::Drive::File::folderMimeType() );
KGAPI2::Drive::ParentReferencePtr parent( new KGAPI2::Drive::ParentReference( folderName ) );
file->setParents( KGAPI2::Drive::ParentReferencesList() << parent );
KGAPI2::Drive::FileCreateJob *createJob = new KGAPI2::Drive::FileCreateJob( file, mAccount);
connect(createJob, SIGNAL(finished(KGAPI2::Job*)), this, SLOT(slotCreateJobFinished(KGAPI2::Job*)));
}
void GDriveJob::copyFile(const QString &source, const QString &destination)
{
qDebug()<<"source "<<source<<" destination"<<destination;
mActionType = PimCommon::StorageServiceAbstract::CopyFileAction;
mError = false;
KGAPI2::Drive::FilePtr file( new KGAPI2::Drive::File() );
file->setTitle( QLatin1String("copy") );
file->setMimeType( KGAPI2::Drive::File::folderMimeType() );
KGAPI2::Drive::ParentReferencePtr parent( new KGAPI2::Drive::ParentReference( destination ) );
file->setParents( KGAPI2::Drive::ParentReferencesList() << parent );
KGAPI2::Drive::FileCopyJob *copyJob = new KGAPI2::Drive::FileCopyJob( source, file, mAccount);
connect(copyJob, SIGNAL(finished(KGAPI2::Job*)), this, SLOT(slotCopyJobFinished(KGAPI2::Job*)));
}
void GDriveJob::slotCopyJobFinished(KGAPI2::Job *job)
{
if (handleError(job)) {
Q_EMIT errorMessage(mActionType, job->errorString());
} else {
Q_EMIT copyFileDone(QString());
}
job->deleteLater();
deleteLater();
}
void GDriveJob::copyFolder(const QString &source, const QString &destination)
{
mActionType = PimCommon::StorageServiceAbstract::CopyFolderAction;
mError = false;
KGAPI2::Drive::FilePtr file( new KGAPI2::Drive::File() );
file->setTitle( QLatin1String("copy") );
file->setMimeType( KGAPI2::Drive::File::folderMimeType() );
KGAPI2::Drive::ParentReferencePtr parent( new KGAPI2::Drive::ParentReference( destination ) );
file->setParents( KGAPI2::Drive::ParentReferencesList() << parent );
KGAPI2::Drive::FileCopyJob *copyJob = new KGAPI2::Drive::FileCopyJob( source, file, mAccount);
connect(copyJob, SIGNAL(finished(KGAPI2::Job*)), this, SLOT(slotCopyFolderJobFinished(KGAPI2::Job*)));
}
void GDriveJob::slotCopyFolderJobFinished(KGAPI2::Job *job)
{
if (handleError(job)) {
Q_EMIT errorMessage(mActionType, job->errorString());
} else {
Q_EMIT copyFolderDone(QString());
}
job->deleteLater();
deleteLater();
}
void GDriveJob::renameFolder(const QString &source, const QString &destination)
{
mActionType = PimCommon::StorageServiceAbstract::RenameFolderAction;
qDebug()<<" source "<<source<<" destination "<<destination;
mError = false;
qDebug()<<" not implemented";
Q_EMIT actionFailed(QLatin1String("Not Implemented"));
//TODO
deleteLater();
}
void GDriveJob::renameFile(const QString &oldName, const QString &newName)
{
mActionType = PimCommon::StorageServiceAbstract::RenameFileAction;
qDebug()<<" oldName "<<oldName<<" newName "<<newName;
mError = false;
qDebug()<<" not implemented";
Q_EMIT actionFailed(QLatin1String("Not Implemented"));
//TODO
deleteLater();
}
/*old **********************/
void GDriveJob::moveFolder(const QString &source, const QString &destination)
{
mActionType = PimCommon::StorageServiceAbstract::MoveFolderAction;
mError = false;
qDebug()<<" not implemented";
Q_EMIT actionFailed(QLatin1String("Not Implemented"));
//TODO
deleteLater();
}
void GDriveJob::moveFile(const QString &source, const QString &destination)
{
mActionType = PimCommon::StorageServiceAbstract::MoveFileAction;
mError = false;
qDebug()<<" not implemented";
Q_EMIT actionFailed(QLatin1String("Not Implemented"));
//TODO
deleteLater();
}
void GDriveJob::shareLink(const QString &root, const QString &path)
{
mActionType = PimCommon::StorageServiceAbstract::ShareLinkAction;
mError = false;
QUrl url;
QString fileId; //TODO
url.setUrl(mApiUrl + mFileInfoPath + fileId);
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("application/x-www-form-urlencoded"));
request.setRawHeader("Authorization", "Bearer "+ mToken.toLatin1());
QNetworkReply *reply = mNetworkAccessManager->get(request);
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(slotError(QNetworkReply::NetworkError)));
}