diff --git a/autotests/drive/data/change1_fetch_request.txt b/autotests/drive/data/change1_fetch_request.txt index 69d7072..008a8de 100644 --- a/autotests/drive/data/change1_fetch_request.txt +++ b/autotests/drive/data/change1_fetch_request.txt @@ -1 +1 @@ -GET https://www.googleapis.com/drive/v2/changes/194 +GET https://www.googleapis.com/drive/v2/changes/194?supportsAllDrives=true diff --git a/autotests/drive/data/changes_fetch_page1_request.txt b/autotests/drive/data/changes_fetch_page1_request.txt index 3f651ae..3721b1f 100644 --- a/autotests/drive/data/changes_fetch_page1_request.txt +++ b/autotests/drive/data/changes_fetch_page1_request.txt @@ -1 +1 @@ -GET https://www.googleapis.com/drive/v2/changes?includeDeleted=true&includeSubscribed=true +GET https://www.googleapis.com/drive/v2/changes?includeDeleted=true&includeSubscribed=true&includeItemsFromAllDrives=true&supportsAllDrives=true diff --git a/autotests/drive/data/file1_create_request.txt b/autotests/drive/data/file1_create_request.txt index 03d8712..cdfdbf2 100644 --- a/autotests/drive/data/file1_create_request.txt +++ b/autotests/drive/data/file1_create_request.txt @@ -1,40 +1,40 @@ -POST https://www.googleapis.com/drive/v2/files?convert=false&ocr=false&pinned=false&useContentAsIndexableText=false +POST https://www.googleapis.com/drive/v2/files?convert=false&ocr=false&pinned=false&useContentAsIndexableText=false&supportsAllDrives=true Content-Type: application/json { - "mimeType": "application/vnd.google-apps.spreadsheet", - "thumbnailLink": "https://docs.google.com/feeds/vt?gd=true&id=someid&v=480&s=otherid&sz=s220", + "mimeType": "application/vnd.google-apps.spreadsheet", + "thumbnailLink": "https://docs.google.com/feeds/vt?gd=true&id=someid&v=480&s=otherid&sz=s220", "labels": { - "restricted": false, - "starred": false, - "viewed": false, - "hidden": false, + "restricted": false, + "starred": false, + "viewed": false, + "hidden": false, "trashed": false - }, - "etag": "\"bX7M5zOlGcEthti1qPHKQWp6SJA/MTUyMzM1MTc5MDUyNA\"", - "lastModifyingUserName": "John Doe", - "writersCanShare": true, - "sharedWithMeDate": "2018-03-14T13:35:25Z", - "title": "Super mega secret KDE PIM plans for world domination", + }, + "etag": "\"bX7M5zOlGcEthti1qPHKQWp6SJA/MTUyMzM1MTc5MDUyNA\"", + "lastModifyingUserName": "John Doe", + "writersCanShare": true, + "sharedWithMeDate": "2018-03-14T13:35:25Z", + "title": "Super mega secret KDE PIM plans for world domination", "ownerNames": [ "Konqui Dev" - ], - "id": "abcdefghijklmnopqrstuvwxyz", + ], + "id": "abcdefghijklmnopqrstuvwxyz", "parents": [ { - "id": "zyxwvutsrqponmlkjihgfedcba", - "selfLink": "https://www.googleapis.com/drive/v2/files/abcdefghijklmnopqrstuvwxyz/parents/zyxwvutsrqponmlkjihgfedcba", + "id": "zyxwvutsrqponmlkjihgfedcba", + "selfLink": "https://www.googleapis.com/drive/v2/files/abcdefghijklmnopqrstuvwxyz/parents/zyxwvutsrqponmlkjihgfedcba", "parentLink": "https://www.googleapis.com/drive/v2/files/zyxwvutsrqponmlkjihgfedcba" } - ], - "shared": true, - "editable": false, - "kind": "drive#file", - "modifiedDate": "2018-04-10T09:16:30Z", - "createdDate": "2018-01-05T11:35:58Z", - "iconLink": "https://drive-thirdparty.googleusercontent.com/16/type/application/vnd.google-apps.spreadsheet", - "embedLink": "https://docs.google.com/spreadsheets/d/abcdefghijklmnopqrstuvwxyz/htmlembed?ouid=116901758143213967333", - "alternateLink": "https://docs.google.com/spreadsheets/d/abcdefghijklmnopqrstuvwxyz/edit?usp=drivesdk", + ], + "shared": true, + "editable": false, + "kind": "drive#file", + "modifiedDate": "2018-04-10T09:16:30Z", + "createdDate": "2018-01-05T11:35:58Z", + "iconLink": "https://drive-thirdparty.googleusercontent.com/16/type/application/vnd.google-apps.spreadsheet", + "embedLink": "https://docs.google.com/spreadsheets/d/abcdefghijklmnopqrstuvwxyz/htmlembed?ouid=116901758143213967333", + "alternateLink": "https://docs.google.com/spreadsheets/d/abcdefghijklmnopqrstuvwxyz/edit?usp=drivesdk", "selfLink": "https://www.googleapis.com/drive/v2/files/abcdefghijklmnopqrstuvwxyz" } diff --git a/autotests/drive/data/file2_create_request.txt b/autotests/drive/data/file2_create_request.txt index b02b6ce..5574ece 100644 Binary files a/autotests/drive/data/file2_create_request.txt and b/autotests/drive/data/file2_create_request.txt differ diff --git a/examples/teamdrive/mainwindow.cpp b/examples/teamdrive/mainwindow.cpp index ac4a951..6a9eb49 100644 --- a/examples/teamdrive/mainwindow.cpp +++ b/examples/teamdrive/mainwindow.cpp @@ -1,295 +1,344 @@ /* Copyright (C) 2019 David Barchiesi 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 "mainwindow.h" #include "ui_main.h" #include #include #include #include #include #include #include #include #include #include #include #include #include MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), m_ui(new Ui::MainWindow) { /* Initialize GUI */ m_ui->setupUi(this); m_ui->errorLabel->setVisible(false); connect(m_ui->authButton, &QAbstractButton::clicked, this, &MainWindow::authenticate); connect(m_ui->newTeamdriveButton, &QAbstractButton::clicked, this, &MainWindow::createTeamdrive); connect(m_ui->teamdriveListButton, &QAbstractButton::clicked, this, &MainWindow::fetchTeamdriveList); connect(m_ui->teamdriveSelectedDeleteButton, &QAbstractButton::clicked, this, &MainWindow::deleteSelectedTeamdrive); connect(m_ui->renameTeamdriveButton, &QAbstractButton::clicked, this, &MainWindow::renameSelectedTeamdrive); connect(m_ui->teamdriveList, &QListWidget::itemSelectionChanged, this, &MainWindow::teamdriveSelected); + connect(m_ui->teamdrivePreviewList, &QListWidget::itemSelectionChanged, + this, &MainWindow::teamdriveItemSelected); } MainWindow::~MainWindow() { delete m_ui; } void MainWindow::authenticate() { KGAPI2::AccountPtr account(new KGAPI2::Account); account->setScopes( QList() << KGAPI2::Account::driveScopeUrl() ); /* Create AuthJob to retrieve OAuth tokens for the account */ KGAPI2::AuthJob *authJob = new KGAPI2::AuthJob( account, QStringLiteral("554041944266.apps.googleusercontent.com"), QStringLiteral("mdT1DjzohxN3npUUzkENT0gO")); connect(authJob, &KGAPI2::Job::finished, this, &MainWindow::slotAuthJobFinished); } void MainWindow::slotAuthJobFinished(KGAPI2::Job *job) { KGAPI2::AuthJob *authJob = qobject_cast(job); Q_ASSERT(authJob); /* Always remember to delete the jobs, otherwise your application will * leak memory. */ authJob->deleteLater(); if (authJob->error() != KGAPI2::NoError) { m_ui->errorLabel->setText(QStringLiteral("Error: %1").arg(authJob->errorString())); m_ui->errorLabel->setVisible(true); return; } m_account = authJob->account(); m_ui->authStatusLabel->setText(QStringLiteral("Authenticated")); m_ui->teamdriveListButton->setEnabled(true); m_ui->newTeamdriveEdit->setEnabled(true); m_ui->newTeamdriveButton->setEnabled(true); m_ui->authButton->setEnabled(false); } void MainWindow::createTeamdrive() { QString teamdriveName = m_ui->newTeamdriveEdit->text(); if (teamdriveName.isEmpty()) { return; } QString requestId = QUuid::createUuid().toString(); KGAPI2::Drive::TeamdrivePtr teamdrive = KGAPI2::Drive::TeamdrivePtr::create(); teamdrive->setName(teamdriveName); KGAPI2::Drive::TeamdriveCreateJob *createJob = new KGAPI2::Drive::TeamdriveCreateJob(requestId, teamdrive, m_account, this); connect(createJob, &KGAPI2::Job::finished, this, &MainWindow::slotTeamdriveCreateJobFinished); } void MainWindow::slotTeamdriveCreateJobFinished(KGAPI2::Job *job) { KGAPI2::Drive::TeamdriveCreateJob *createJob = qobject_cast(job); Q_ASSERT(createJob); createJob->deleteLater(); if (createJob->error() != KGAPI2::NoError) { m_ui->errorLabel->setText(QStringLiteral("Error: %1").arg(createJob->errorString())); m_ui->errorLabel->setVisible(true); m_ui->teamdriveListButton->setEnabled(true); return; } m_ui->newTeamdriveEdit->clear(); fetchTeamdriveList(); } void MainWindow::renameSelectedTeamdrive() { QString teamdriveName = m_ui->renameTeamdriveEdit->text(); if (teamdriveName.isEmpty()) { return; } QString teamdriveId = m_ui->teamdriveList->selectedItems().at(0)->data(Qt::UserRole).toString(); KGAPI2::Drive::TeamdrivePtr teamdrive = KGAPI2::Drive::TeamdrivePtr::create(); teamdrive->setId(teamdriveId); teamdrive->setName(teamdriveName); KGAPI2::Drive::TeamdriveModifyJob *modifyJob = new KGAPI2::Drive::TeamdriveModifyJob(teamdrive, m_account, this); connect(modifyJob, &KGAPI2::Job::finished, this, &MainWindow::slotTeamdriveModifyJobFinished); } void MainWindow::slotTeamdriveModifyJobFinished(KGAPI2::Job *job) { KGAPI2::Drive::TeamdriveModifyJob *modifyJob = qobject_cast(job); Q_ASSERT(modifyJob); modifyJob->deleteLater(); if (modifyJob->error() != KGAPI2::NoError) { m_ui->errorLabel->setText(QStringLiteral("Error: %1").arg(modifyJob->errorString())); m_ui->errorLabel->setVisible(true); m_ui->teamdriveListButton->setEnabled(true); return; } fetchTeamdriveList(); } void MainWindow::fetchTeamdriveList() { if (m_account.isNull()) { m_ui->errorLabel->setText(QStringLiteral("Error: Please authenticate first")); m_ui->errorLabel->setVisible(true); m_ui->authButton->setVisible(true); return; } KGAPI2::Drive::TeamdriveFetchJob *fetchJob = new KGAPI2::Drive::TeamdriveFetchJob(m_account, this); connect(fetchJob, &KGAPI2::Job::finished, this, &MainWindow::slotFetchJobFinished); m_ui->teamdriveListButton->setEnabled(false); } void MainWindow::slotFetchJobFinished(KGAPI2::Job *job) { KGAPI2::Drive::TeamdriveFetchJob *fetchJob = qobject_cast(job); Q_ASSERT(fetchJob); fetchJob->deleteLater(); if (fetchJob->error() != KGAPI2::NoError) { m_ui->errorLabel->setText(QStringLiteral("Error: %1").arg(fetchJob->errorString())); m_ui->errorLabel->setVisible(true); m_ui->teamdriveListButton->setEnabled(true); return; } /* Get all items the job has retrieved */ const KGAPI2::ObjectsList objects = fetchJob->items(); m_ui->teamdriveList->clear(); for (const KGAPI2::ObjectPtr &object : objects) { const KGAPI2::Drive::TeamdrivePtr teamdrive = object.dynamicCast(); /* Convert the teamdrive to QListWidget item */ QListWidgetItem *item = new QListWidgetItem(m_ui->teamdriveList); item->setText(teamdrive->name()); item->setData(Qt::UserRole, teamdrive->id()); m_ui->teamdriveList->addItem(item); } m_ui->teamdriveListButton->setEnabled(true); } void MainWindow::deleteSelectedTeamdrive() { const QString teamdrive_id = m_ui->teamdriveList->selectedItems().at(0)->data(Qt::UserRole).toString(); KGAPI2::Drive::TeamdriveDeleteJob *deleteJob = new KGAPI2::Drive::TeamdriveDeleteJob(teamdrive_id, m_account, this); connect(deleteJob, &KGAPI2::Job::finished, this, &MainWindow::slotTeamdriveDeleteJobFinished); } void MainWindow::slotTeamdriveDeleteJobFinished(KGAPI2::Job *job) { KGAPI2::Drive::TeamdriveDeleteJob *deleteJob = qobject_cast(job); Q_ASSERT(deleteJob); deleteJob->deleteLater(); if (deleteJob->error() != KGAPI2::NoError) { m_ui->errorLabel->setText(QStringLiteral("Error: %1").arg(deleteJob->errorString())); m_ui->errorLabel->setVisible(true); m_ui->teamdriveListButton->setEnabled(true); return; } fetchTeamdriveList(); } void MainWindow::teamdriveSelected() { bool hasSelection = (m_ui->teamdriveList->selectedItems().count() != 0); m_ui->teamdriveSelectedDeleteButton->setEnabled(hasSelection); m_ui->renameTeamdriveButton->setEnabled(hasSelection); m_ui->renameTeamdriveEdit->setEnabled(hasSelection); + m_ui->teamdrivePreviewList->clear(); + if (!hasSelection) { - m_ui->teamdrivePreview->clear(); m_ui->renameTeamdriveEdit->clear(); return; } const QString id = m_ui->teamdriveList->selectedItems().at(0)->data(Qt::UserRole).toString(); const QString name = m_ui->teamdriveList->selectedItems().at(0)->data(Qt::DisplayRole).toString(); + m_ui->renameTeamdriveEdit->setText(name); KGAPI2::Drive::FileSearchQuery query; query.addQuery(KGAPI2::Drive::FileSearchQuery::Trashed, KGAPI2::Drive::FileSearchQuery::Equals, false); query.addQuery(KGAPI2::Drive::FileSearchQuery::Parents, KGAPI2::Drive::FileSearchQuery::In, id); KGAPI2::Drive::FileFetchJob *fileFetchJob = new KGAPI2::Drive::FileFetchJob(query, m_account, nullptr); - fileFetchJob->setIncludeTeamDriveItems(true); fileFetchJob->setFields((KGAPI2::Drive::FileFetchJob::BasicFields & ~KGAPI2::Drive::FileFetchJob::Permissions) | KGAPI2::Drive::FileFetchJob::Labels | KGAPI2::Drive::FileFetchJob::ExportLinks | KGAPI2::Drive::FileFetchJob::LastViewedByMeDate); connect(fileFetchJob, &KGAPI2::Job::finished, this, &MainWindow::slotTeamdriveFetchJobFinished); } void MainWindow::slotTeamdriveFetchJobFinished(KGAPI2::Job *job) { KGAPI2::Drive::FileFetchJob *fetchJob = qobject_cast(job); Q_ASSERT(fetchJob); fetchJob->deleteLater(); if (fetchJob->error() != KGAPI2::NoError) { m_ui->errorLabel->setText(QStringLiteral("Error: %1").arg(fetchJob->errorString())); m_ui->errorLabel->setVisible(true); m_ui->teamdriveListButton->setEnabled(true); return; } - /* Get all items we have received from Google (should be just one) */ + /* Get all items we have received from Google */ KGAPI2::ObjectsList objects = fetchJob->items(); - QString text; Q_FOREACH (const KGAPI2::ObjectPtr &object, objects) { const KGAPI2::Drive::FilePtr file = object.dynamicCast(); - text += QStringLiteral("%1").arg(file->title()); - text += QLatin1Char('\n'); + + /* Convert the teamdrive to QListWidget item */ + QListWidgetItem *item = new QListWidgetItem(m_ui->teamdrivePreviewList); + item->setText(file->title()); + item->setData(Qt::UserRole, file->id()); + + m_ui->teamdrivePreviewList->addItem(item); + } +} + +void MainWindow::teamdriveItemSelected() +{ + bool hasSelection = (m_ui->teamdrivePreviewList->selectedItems().count() != 0); + if (!hasSelection) { + return; + } + + const QString id = m_ui->teamdrivePreviewList->selectedItems().at(0)->data(Qt::UserRole).toString(); + + KGAPI2::Drive::FileFetchJob *fileFetchJob = new KGAPI2::Drive::FileFetchJob(id, m_account, nullptr); + fileFetchJob->setFields((KGAPI2::Drive::FileFetchJob::BasicFields & ~KGAPI2::Drive::FileFetchJob::Permissions) + | KGAPI2::Drive::FileFetchJob::Labels + | KGAPI2::Drive::FileFetchJob::ExportLinks + | KGAPI2::Drive::FileFetchJob::LastViewedByMeDate); + connect(fileFetchJob, &KGAPI2::Job::finished, + this, &MainWindow::slotTeamdriveItemFetchJobFinished); +} + +void MainWindow::slotTeamdriveItemFetchJobFinished(KGAPI2::Job *job) +{ + KGAPI2::Drive::FileFetchJob *fetchJob = qobject_cast(job); + Q_ASSERT(fetchJob); + fetchJob->deleteLater(); + + if (fetchJob->error() != KGAPI2::NoError) { + m_ui->errorLabel->setText(QStringLiteral("Error: %1").arg(fetchJob->errorString())); + m_ui->errorLabel->setVisible(true); + return; + } + + KGAPI2::ObjectsList objects = fetchJob->items(); + if (objects.size() != 1) { + return; } - m_ui->teamdrivePreview->setText(text); + KGAPI2::ObjectPtr object = objects.at(0); + const KGAPI2::Drive::FilePtr file = object.dynamicCast(); + QStringList msgBuilder; + msgBuilder << file->title(); + msgBuilder << QString::number(file->fileSize()) + QStringLiteral(" bytes"); + QString msg = msgBuilder.join(QStringLiteral(", ")); + m_ui->statusbar->showMessage(msg); } diff --git a/examples/teamdrive/mainwindow.h b/examples/teamdrive/mainwindow.h index 9ff23f6..6735e1e 100644 --- a/examples/teamdrive/mainwindow.h +++ b/examples/teamdrive/mainwindow.h @@ -1,117 +1,128 @@ /* Copyright (C) 2019 David Barchiesi 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 MAINWINDOW_H #define MAINWINDOW_H #include #include namespace Ui { class MainWindow; } namespace KGAPI2 { class Job; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow() override; private Q_SLOTS: /** * Retrieves tokens from Google that we will use to authenticate * fursther requests */ void authenticate(); /** * Authentication has finished */ void slotAuthJobFinished(KGAPI2::Job *job); /** * Creates the Team Drive with name in newTeamdriveEdit */ void createTeamdrive(); /** * Team Drive was created. */ void slotTeamdriveCreateJobFinished(KGAPI2::Job *job); /** * Rename the selected Team Drive with name in renameTeamdriveEdit */ void renameSelectedTeamdrive(); /** * Team Drive was modified. */ void slotTeamdriveModifyJobFinished(KGAPI2::Job *job); /** * All Team Drives were fetched. */ void slotFetchJobFinished(KGAPI2::Job *job); /** * Team Drive listing was fetched. */ void slotTeamdriveFetchJobFinished(KGAPI2::Job *job); /** * Retrieves list of all teamdrive from user's Google teamdrive * addressbook */ void fetchTeamdriveList(); /** * Deletes the selected Team Drive */ void deleteSelectedTeamdrive(); /** * Team Drive was deleted. */ void slotTeamdriveDeleteJobFinished(KGAPI2::Job *job); /** - * A specific contact in contact list has been selected. Sends a request - * to Google to retrieve full details about the specific contact + * A specific team drive in teamdrive list has been selected. Sends a request + * to Google to retrieve teh team drive file list. */ void teamdriveSelected(); + /** + * A specific item in the teamdrive list has been selected. Sends a request + * to Google to retrieve full details about the specific file + */ + void teamdriveItemSelected(); + + /** + * Team Drive item detail was fetched. + */ + void slotTeamdriveItemFetchJobFinished(KGAPI2::Job *job); + private: Ui::MainWindow *m_ui; KGAPI2::AccountPtr m_account; }; #endif // MAINWINDOW_H diff --git a/examples/teamdrive/ui/main.ui b/examples/teamdrive/ui/main.ui index 396ddf3..502bcc7 100644 --- a/examples/teamdrive/ui/main.ui +++ b/examples/teamdrive/ui/main.ui @@ -1,222 +1,222 @@ MainWindow 0 0 640 486 MainWindow Authenticate Not authenticated Qt::Horizontal false false Create false false Rename false Get Team Drive list false Delete selected Team Drive 12 75 true Qt::RightToLeft Team Drive list Qt::AlignCenter 12 75 true Qt::RightToLeft Team Drive folder preview Qt::AlignCenter - + true 0 0 640 30 File Quit actionQuit activated() MainWindow close() -1 -1 319 206 diff --git a/src/drive/changefetchjob.cpp b/src/drive/changefetchjob.cpp index 005dd54..9862e21 100644 --- a/src/drive/changefetchjob.cpp +++ b/src/drive/changefetchjob.cpp @@ -1,208 +1,237 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * 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 "changefetchjob.h" #include "account.h" #include "change.h" #include "../debug.h" #include "driveservice.h" #include "utils.h" #include #include #include using namespace KGAPI2; using namespace KGAPI2::Drive; class Q_DECL_HIDDEN ChangeFetchJob::Private { public: Private(ChangeFetchJob *parent); QNetworkRequest createRequest(const QUrl &url); QString changeId; bool includeDeleted; bool includeSubscribed; int maxResults; qlonglong startChangeId; + bool includeItemsFromAllDrives; + bool supportsAllDrives; private: ChangeFetchJob *q; }; ChangeFetchJob::Private::Private(ChangeFetchJob *parent): includeDeleted(true), includeSubscribed(true), maxResults(0), startChangeId(0), + includeItemsFromAllDrives(true), + supportsAllDrives(true), q(parent) { } QNetworkRequest ChangeFetchJob::Private::createRequest(const QUrl &url) { QNetworkRequest request; request.setRawHeader("Authorization", "Bearer " + q->account()->accessToken().toLatin1()); request.setUrl(url); return request; } ChangeFetchJob::ChangeFetchJob(const QString &changeId, const AccountPtr &account, QObject *parent): FetchJob(account, parent), d(new Private(this)) { d->changeId = changeId; } ChangeFetchJob::ChangeFetchJob(const AccountPtr &account, QObject *parent): FetchJob(account, parent), d(new Private(this)) { } ChangeFetchJob::~ChangeFetchJob() { delete d; } void ChangeFetchJob::setIncludeDeleted(bool includeDeleted) { if (isRunning()) { qCWarning(KGAPIDebug) << "Can't modify includeDeleted property when job is running"; return; } d->includeDeleted = includeDeleted; } bool ChangeFetchJob::includeDeleted() const { return d->includeDeleted; } void ChangeFetchJob::setIncludeSubscribed(bool includeSubscribed) { if (isRunning()) { qCWarning(KGAPIDebug) << "Can't modify includeSubscribed property when job is running"; return; } d->includeSubscribed = includeSubscribed; } bool ChangeFetchJob::includeSubscribed() const { return d->includeSubscribed; } void ChangeFetchJob::setMaxResults(int maxResults) { if (isRunning()) { qCWarning(KGAPIDebug) << "Can't modify maxResults property when job is running"; return; } d->maxResults = maxResults; } int ChangeFetchJob::maxResults() const { return d->maxResults; } void ChangeFetchJob::setStartChangeId(qlonglong startChangeId) { if (isRunning()) { qCWarning(KGAPIDebug) << "Can't modify startChangeId property when job is running"; } d->startChangeId = startChangeId; } qlonglong ChangeFetchJob::startChangeId() const { return d->startChangeId; } +bool ChangeFetchJob::includeItemsFromAllDrives() const +{ + return d->includeItemsFromAllDrives; +} + +void ChangeFetchJob::setIncludeItemsFromAllDrives(bool includeItemsFromAllDrives) +{ + d->includeItemsFromAllDrives = includeItemsFromAllDrives; +} + +bool ChangeFetchJob::supportsAllDrives() const +{ + return d->supportsAllDrives; +} + +void ChangeFetchJob::setSupportsAllDrives(bool supportsAllDrives) +{ + d->supportsAllDrives = supportsAllDrives; +} + void ChangeFetchJob::start() { QUrl url; if (d->changeId.isEmpty()) { url = DriveService::fetchChangesUrl(); QUrlQuery query(url); query.addQueryItem(QStringLiteral("includeDeleted"), Utils::bool2Str(d->includeDeleted)); query.addQueryItem(QStringLiteral("includeSubscribed"), Utils::bool2Str(d->includeSubscribed)); if (d->maxResults > 0) { query.addQueryItem(QStringLiteral("maxResults"), QString::number(d->maxResults)); } if (d->startChangeId > 0) { query.addQueryItem(QStringLiteral("startChangeId"), QString::number(d->startChangeId)); } + query.addQueryItem(QStringLiteral("includeItemsFromAllDrives"), d->includeItemsFromAllDrives ? QStringLiteral("true") : QStringLiteral("false")); url.setQuery(query); } else { url = DriveService::fetchChangeUrl(d->changeId); } + QUrlQuery query(url); + query.addQueryItem(QStringLiteral("supportsAllDrives"), d->supportsAllDrives ? QStringLiteral("true") : QStringLiteral("false")); + url.setQuery(query); + const QNetworkRequest request = d->createRequest(url); enqueueRequest(request); } ObjectsList ChangeFetchJob::handleReplyWithItems(const QNetworkReply *reply, const QByteArray &rawData) { FeedData feedData; feedData.requestUrl = reply->url(); ObjectsList items; QString itemId; const QString contentType = reply->header(QNetworkRequest::ContentTypeHeader).toString(); ContentType ct = Utils::stringToContentType(contentType); if (ct == KGAPI2::JSON) { if (d->changeId.isEmpty()) { items << Change::fromJSONFeed(rawData, feedData); } else { items << Change::fromJSON(rawData); } } else { setError(KGAPI2::InvalidResponse); setErrorString(tr("Invalid response content type")); emitFinished(); return items; } if (feedData.nextPageUrl.isValid()) { const QNetworkRequest request = d->createRequest(feedData.nextPageUrl); enqueueRequest(request); } return items; } diff --git a/src/drive/changefetchjob.h b/src/drive/changefetchjob.h index a407069..2d9fc45 100644 --- a/src/drive/changefetchjob.h +++ b/src/drive/changefetchjob.h @@ -1,123 +1,159 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * 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 KGAPI2_DRIVECHANGEFETCHJOB_H #define KGAPI2_DRIVECHANGEFETCHJOB_H #include "fetchjob.h" #include "kgapidrive_export.h" namespace KGAPI2 { namespace Drive { class KGAPIDRIVE_EXPORT ChangeFetchJob : public KGAPI2::FetchJob { Q_OBJECT /** * Whether to include deleted items. * * By default deletes items are included. * * This property does not have any effect when fetching a specific change and * can be modified only when the job is not running. */ Q_PROPERTY(bool includeDeleted READ includeDeleted WRITE setIncludeDeleted) /** * Whether to include shared files and public files the user has opened. * When set to false, the list will include owned files plus any shared or * public files the user has explicitly added to a folder in Drive. * * Default is to include subscribed files. * * This property does not have any effect when fetching a specific event and * can be modified only when the job is not running. */ Q_PROPERTY(bool includeSubscribed READ includeSubscribed WRITE setIncludeSubscribed) /** * Maximum number of changes to return. * * Default value is 0, i.e. no limit. * * This property does not have any effect when fetching a specific event and * can be modified only when the job is not running. */ Q_PROPERTY(int maxResults READ maxResults WRITE setMaxResults) /** * Change ID to start listing changes from. * * Default value is 0, i.e. all changes. * * This property does not have any effect when fetching a specific event and * can be modified only when the job is not running. */ Q_PROPERTY(qlonglong startChangeId READ startChangeId WRITE setStartChangeId) public: explicit ChangeFetchJob(const AccountPtr &account, QObject *parent = nullptr); explicit ChangeFetchJob(const QString &changeId, const AccountPtr &account, QObject *parent = nullptr); ~ChangeFetchJob() override; bool includeSubscribed() const; void setIncludeSubscribed(bool includeSubscribed); bool includeDeleted() const; void setIncludeDeleted(bool includeDeleted); int maxResults() const; void setMaxResults(int maxResults); qlonglong startChangeId() const; void setStartChangeId(qlonglong startChangeId); + /** + * @brief Whether both My Drive and shared drive items should be included in results. + * + * @deprecated This parameter will only be effective until June 1, 2020. Afterwards shared drive items will be included in the results. + */ + KGAPIDRIVE_DEPRECATED bool includeItemsFromAllDrives() const; + + /** + * @brief Sets whether both My Drive and shared drive items should be included in results. + * + * Set to true by default as LibKGAPI supports Team Drives. + * + * @deprecated This parameter will only be effective until June 1, 2020. Afterwards shared drive items will be included in the results. + */ + KGAPIDRIVE_DEPRECATED void setIncludeItemsFromAllDrives(bool includeItemsFromAllDrives); + + /** + * @brief Whether the request supports both My Drives and shared drives. + * + * Set to true by default as LibKGAPI supports Team Drives. + * + * @deprecated This parameter will only be effective until June 1, 2020. Afterwards all applications + * are assumed to support shared drives. + */ + KGAPIDRIVE_DEPRECATED bool supportsAllDrives() const; + + /** + * @brief Sets whether the request supports both My Drives and shared drives. + * + * Set to true by default as LibKGAPI supports Team Drives. + * + * @deprecated This parameter will only be effective until June 1, 2020. Afterwards all applications + * are assumed to support shared drives. + */ + KGAPIDRIVE_DEPRECATED void setSupportsAllDrives(bool supportsAllDrives); + protected: void start() override; KGAPI2::ObjectsList handleReplyWithItems(const QNetworkReply *reply, const QByteArray &rawData) override; private: class Private; Private *const d; friend class Private; }; } // namespace Drive } // namespace KGAPI2 #endif // KGAPI2_DRIVECHANGEFETCHJOB_H diff --git a/src/drive/childreferencecreatejob.cpp b/src/drive/childreferencecreatejob.cpp index b302894..7dba704 100644 --- a/src/drive/childreferencecreatejob.cpp +++ b/src/drive/childreferencecreatejob.cpp @@ -1,148 +1,165 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * 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 "childreferencecreatejob.h" #include "account.h" #include "childreference.h" #include "driveservice.h" #include "utils.h" #include #include +#include using namespace KGAPI2; using namespace KGAPI2::Drive; class Q_DECL_HIDDEN ChildReferenceCreateJob::Private { public: Private(ChildReferenceCreateJob *parent); void processNext(); QString folderId; ChildReferencesList references; + bool supportsAllDrives; private: ChildReferenceCreateJob *q; }; ChildReferenceCreateJob::Private::Private(ChildReferenceCreateJob *parent): + supportsAllDrives(true), q(parent) { } void ChildReferenceCreateJob::Private::processNext() { if (references.isEmpty()) { q->emitFinished(); return; } const ChildReferencePtr reference = references.takeFirst(); - const QUrl url = DriveService::createChildReference(folderId); + QUrl url = DriveService::createChildReference(folderId); + + QUrlQuery withDriveSupportQuery(url); + withDriveSupportQuery.addQueryItem(QStringLiteral("supportsAllDrives"), supportsAllDrives ? QStringLiteral("true") : QStringLiteral("false")); + url.setQuery(withDriveSupportQuery); QNetworkRequest request; request.setRawHeader("Authorization", "Bearer " + q->account()->accessToken().toLatin1()); request.setUrl(url); const QByteArray rawData = ChildReference::toJSON(reference); q->enqueueRequest(request, rawData, QStringLiteral("application/json")); } ChildReferenceCreateJob::ChildReferenceCreateJob(const QString &folderId, const QString &childId, const AccountPtr &account, QObject *parent): CreateJob(account, parent), d(new Private(this)) { d->folderId = folderId; d->references << ChildReferencePtr(new ChildReference(childId)); } ChildReferenceCreateJob::ChildReferenceCreateJob(const QString &folderId, const QStringList &childrenIds, const AccountPtr &account, QObject *parent): CreateJob(account, parent), d(new Private(this)) { d->folderId = folderId; for (const QString & childId : qAsConst(childrenIds)) { d->references << ChildReferencePtr(new ChildReference(childId)); } } ChildReferenceCreateJob::ChildReferenceCreateJob(const QString &folderId, const ChildReferencePtr &reference, const AccountPtr &account, QObject *parent): CreateJob(account, parent), d(new Private(this)) { d->folderId = folderId; d->references << reference; } ChildReferenceCreateJob::ChildReferenceCreateJob(const QString &folderId, const ChildReferencesList &references, const AccountPtr &account, QObject *parent): CreateJob(account, parent), d(new Private(this)) { d->folderId = folderId; d->references << references; } ChildReferenceCreateJob::~ChildReferenceCreateJob() { delete d; } +bool ChildReferenceCreateJob::supportsAllDrives() const +{ + return d->supportsAllDrives; +} + +void ChildReferenceCreateJob::setSupportsAllDrives(bool supportsAllDrives) +{ + d->supportsAllDrives = supportsAllDrives; +} + void ChildReferenceCreateJob::start() { d->processNext(); } ObjectsList ChildReferenceCreateJob::handleReplyWithItems(const QNetworkReply *reply, const QByteArray &rawData) { const QString contentType = reply->header(QNetworkRequest::ContentTypeHeader).toString(); ContentType ct = Utils::stringToContentType(contentType); ObjectsList items; if (ct == KGAPI2::JSON) { items << ChildReference::fromJSON(rawData); } else { setError(KGAPI2::InvalidResponse); setErrorString(tr("Invalid response content type")); emitFinished(); } // Enqueue next item or finish d->processNext(); return items; } diff --git a/src/drive/childreferencecreatejob.h b/src/drive/childreferencecreatejob.h index f116116..cd6d0e1 100644 --- a/src/drive/childreferencecreatejob.h +++ b/src/drive/childreferencecreatejob.h @@ -1,75 +1,95 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * 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 KGAPI2_DRIVECHILDREFERENCECREATEJOB_H #define KGAPI2_DRIVECHILDREFERENCECREATEJOB_H #include "createjob.h" #include "kgapidrive_export.h" #include namespace KGAPI2 { namespace Drive { class KGAPIDRIVE_EXPORT ChildReferenceCreateJob : public KGAPI2::CreateJob { Q_OBJECT public: explicit ChildReferenceCreateJob(const QString &folderId, const QString &childId, const AccountPtr &account, QObject *parent = nullptr); explicit ChildReferenceCreateJob(const QString &folderId, const QStringList &childrenIds, const AccountPtr &account, QObject *parent = nullptr); explicit ChildReferenceCreateJob(const QString &folderId, const ChildReferencePtr &reference, const AccountPtr &account, QObject *parent = nullptr); explicit ChildReferenceCreateJob(const QString &folderId, const ChildReferencesList &references, const AccountPtr &account, QObject *parent = nullptr); ~ChildReferenceCreateJob() override; + /** + * @brief Whether the request supports both My Drives and shared drives. + * + * Set to true by default as LibKGAPI supports Team Drives. + * + * @deprecated This parameter will only be effective until June 1, 2020. Afterwards all applications + * are assumed to support shared drives. + */ + KGAPIDRIVE_DEPRECATED bool supportsAllDrives() const; + + /** + * @brief Sets whether the request supports both My Drives and shared drives. + * + * Set to true by default as LibKGAPI supports Team Drives. + * + * @deprecated This parameter will only be effective until June 1, 2020. Afterwards all applications + * are assumed to support shared drives. + */ + KGAPIDRIVE_DEPRECATED void setSupportsAllDrives(bool supportsAllDrives); + protected: void start() override; ObjectsList handleReplyWithItems(const QNetworkReply *reply, const QByteArray &rawData) override; private: class Private; Private *const d; friend class Private; }; } // namespace Drive } // namespace KGAPI2 #endif // KGAPI2_DRIVECHILDREFERENCECREATEJOB_H diff --git a/src/drive/fileabstractuploadjob.cpp b/src/drive/fileabstractuploadjob.cpp index e7741ea..a3c0c9c 100644 --- a/src/drive/fileabstractuploadjob.cpp +++ b/src/drive/fileabstractuploadjob.cpp @@ -1,354 +1,368 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * 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 "fileabstractuploadjob.h" #include "account.h" #include "../debug.h" #include "driveservice.h" #include "file.h" #include "utils.h" #include #include #include #include #include #include #include #include using namespace KGAPI2; using namespace KGAPI2::Drive; class Q_DECL_HIDDEN FileAbstractUploadJob::Private { public: Private(FileAbstractUploadJob *parent); void processNext(); QByteArray buildMultipart(const QString &filePath, const FilePtr &metaData, QString &boundary); QByteArray readFile(const QString &filePath, QString &contentType); void _k_uploadProgress(qint64 bytesSent, qint64 totalBytes); int originalFilesCount; QMap files; QMap uploadedFiles; + bool supportsAllDrives; bool useContentAsIndexableText; File::SerializationOptions serializationOptions = File::NoOptions; private: FileAbstractUploadJob *const q; }; FileAbstractUploadJob::Private::Private(FileAbstractUploadJob *parent): originalFilesCount(0), + supportsAllDrives(true), useContentAsIndexableText(false), q(parent) { } QByteArray FileAbstractUploadJob::Private::readFile(const QString &filePath, QString &contentType) { QFile file(filePath); if (!file.open(QIODevice::ReadOnly)) { qCWarning(KGAPIDebug) << "Failed to access" << filePath; return QByteArray(); } const QMimeDatabase db; const QMimeType mime = db.mimeTypeForFileNameAndData(filePath, &file); contentType = mime.name(); file.reset(); QByteArray output = file.readAll(); file.close(); return output; } QByteArray FileAbstractUploadJob::Private::buildMultipart(const QString &filePath, const FilePtr &metaData, QString &boundary) { QString fileContentType; QByteArray fileContent; fileContent = readFile(filePath, fileContentType); if (fileContent.isEmpty()) { return QByteArray(); } // Wannabe implementation of RFC2387, i.e. multipart/related QByteArray body; QFileInfo finfo(filePath); const QByteArray md5 = QCryptographicHash::hash(finfo.fileName().toLatin1(), QCryptographicHash::Md5); boundary = QString::fromLatin1(md5.toHex()); body += "--" + boundary.toLatin1() + '\n'; body += "Content-Type: application/json; charset=UTF-8\n"; body += '\n'; body += File::toJSON(metaData); body += '\n'; body += '\n'; body += "--" + boundary.toLatin1() + '\n'; body += "Content-Type: " + fileContentType.toLatin1() + '\n'; body += '\n'; body += fileContent; body += '\n'; body += "--" + boundary.toLatin1() + "--"; return body; } void FileAbstractUploadJob::Private::processNext() { if (files.isEmpty()) { q->emitFinished(); return; } const QString filePath = files.cbegin().key(); if (!filePath.startsWith(QLatin1String("?=")) && !QFile::exists(filePath)) { qCWarning(KGAPIDebug) << filePath << "is not a valid file path"; processNext(); return; } const FilePtr metaData = files.take(filePath); QUrl url; if (filePath.startsWith(QLatin1String("?="))) { url = q->createUrl(QString(), metaData); } else { url = q->createUrl(filePath, metaData); } q->updateUrl(url); QUrlQuery query(url); query.addQueryItem(QStringLiteral("useContentAsIndexableText"), Utils::bool2Str(useContentAsIndexableText)); QNetworkRequest request; QByteArray rawData; QString contentType; // just to be sure query.removeQueryItem(QStringLiteral("uploadType")); if (metaData.isNull()) { query.addQueryItem(QStringLiteral("uploadType"), QStringLiteral("media")); rawData = readFile(filePath, contentType); if (rawData.isEmpty()) { processNext(); return; } } else if (!filePath.startsWith(QLatin1String("?="))) { query.addQueryItem(QStringLiteral("uploadType"), QStringLiteral("multipart")); QString boundary; rawData = buildMultipart(filePath, metaData, boundary); contentType = QStringLiteral("multipart/related; boundary=%1").arg(boundary); if (rawData.isEmpty()) { processNext(); return; } } else { rawData = File::toJSON(metaData, q->serializationOptions()); contentType = QStringLiteral("application/json"); } + + query.addQueryItem(QStringLiteral("supportsAllDrives"), supportsAllDrives ? QStringLiteral("true") : QStringLiteral("false")); url.setQuery(query); request.setUrl(url); request.setRawHeader("Authorization", "Bearer " + q->account()->accessToken().toLatin1()); request.setHeader(QNetworkRequest::ContentLengthHeader, rawData.length()); request.setHeader(QNetworkRequest::ContentTypeHeader, contentType); request.setAttribute(QNetworkRequest::User, filePath); q->enqueueRequest(request, rawData, contentType); } void FileAbstractUploadJob::Private::_k_uploadProgress(qint64 bytesSent, qint64 totalBytes) { // Each file consists of 100 units, so if we have two files, one already // uploaded and the other one uploaded from 50%, the values are (150, 200) int processedParts = (originalFilesCount - files.count()) * 100; int currentFileParts = 100.0 * ((qreal) bytesSent / (qreal) totalBytes); q->emitProgress(processedParts + currentFileParts, originalFilesCount * 100); } FileAbstractUploadJob::FileAbstractUploadJob(const FilePtr &metadata, const AccountPtr &account, QObject *parent): FileAbstractDataJob(account, parent), d(new Private(this)) { d->files.insert(QStringLiteral("?=0"), metadata); d->originalFilesCount = 1; } FileAbstractUploadJob::FileAbstractUploadJob(const FilesList &metadata, const AccountPtr &account, QObject *parent): FileAbstractDataJob(account, parent), d(new Private(this)) { int i = 0; for (const FilePtr &file : metadata) { d->files.insert(QStringLiteral("?=%1").arg(i), file); ++i; } d->originalFilesCount = d->files.count(); } FileAbstractUploadJob::FileAbstractUploadJob(const QString &filePath, const AccountPtr &account, QObject *parent): FileAbstractDataJob(account, parent), d(new Private(this)) { d->files.insert(filePath, FilePtr()); d->originalFilesCount = 1; } FileAbstractUploadJob::FileAbstractUploadJob(const QString &filePath, const FilePtr &metaData, const AccountPtr &account, QObject *parent): FileAbstractDataJob(account, parent), d(new Private(this)) { d->files.insert(filePath, metaData); d->originalFilesCount = 1; } FileAbstractUploadJob::FileAbstractUploadJob(const QStringList &filePaths, const AccountPtr &account, QObject *parent): FileAbstractDataJob(account, parent), d(new Private(this)) { for (const QString & filePath : filePaths) { d->files.insert(filePath, FilePtr()); } d->originalFilesCount = d->files.count(); } FileAbstractUploadJob::FileAbstractUploadJob(const QMap< QString, FilePtr > &files, const AccountPtr &account, QObject *parent): FileAbstractDataJob(account, parent), d(new Private(this)) { d->files = files; d->originalFilesCount = d->files.count(); } FileAbstractUploadJob::~FileAbstractUploadJob() { delete d; } void FileAbstractUploadJob::setUseContentAsIndexableText(bool useContentAsIndexableText) { if (isRunning()) { qCWarning(KGAPIDebug) << "Can't modify useContentAsIndexableText property when job is running"; return; } d->useContentAsIndexableText = useContentAsIndexableText; } bool FileAbstractUploadJob::useContentAsIndexableText() const { return d->useContentAsIndexableText; } void FileAbstractUploadJob::start() { d->processNext(); } QMap FileAbstractUploadJob::files() const { return d->uploadedFiles; } +bool FileAbstractUploadJob::supportsAllDrives() const +{ + return d->supportsAllDrives; +} + +void FileAbstractUploadJob::setSupportsAllDrives(bool supportsAllDrives) +{ + d->supportsAllDrives = supportsAllDrives; +} + void FileAbstractUploadJob::dispatchRequest(QNetworkAccessManager *accessManager, const QNetworkRequest &request, const QByteArray &data, const QString &contentType) { Q_UNUSED(contentType) QNetworkReply *reply = dispatch(accessManager, request, data); connect(reply, &QNetworkReply::uploadProgress, this, [this](qint64 bytesSent, qint64 totalBytes) {d->_k_uploadProgress(bytesSent, totalBytes); }); } void FileAbstractUploadJob::handleReply(const QNetworkReply *reply, const QByteArray &rawData) { const QString contentType = reply->header(QNetworkRequest::ContentTypeHeader).toString(); ContentType ct = Utils::stringToContentType(contentType); if (ct == KGAPI2::JSON) { const QNetworkRequest request = reply->request(); const QString filePath = request.attribute(QNetworkRequest::User).toString(); FilePtr file = File::fromJSON(rawData); d->uploadedFiles.insert(filePath, file); } else { setError(KGAPI2::InvalidResponse); setErrorString(tr("Invalid response content type")); emitFinished(); return; } d->processNext(); } void FileAbstractUploadJob::setSerializationOptions(File::SerializationOptions options) { d->serializationOptions = options; } File::SerializationOptions FileAbstractUploadJob::serializationOptions() const { return d->serializationOptions; } #include "moc_fileabstractuploadjob.cpp" diff --git a/src/drive/fileabstractuploadjob.h b/src/drive/fileabstractuploadjob.h index 1d88af2..639899b 100644 --- a/src/drive/fileabstractuploadjob.h +++ b/src/drive/fileabstractuploadjob.h @@ -1,110 +1,130 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * 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 KGAPI2_DRIVEFILEABSTRACTUPLOADJOB_H #define KGAPI2_DRIVEFILEABSTRACTUPLOADJOB_H #include "file.h" #include "fileabstractdatajob.h" #include "kgapidrive_export.h" #include #include namespace KGAPI2 { namespace Drive { class KGAPIDRIVE_EXPORT FileAbstractUploadJob : public KGAPI2::Drive::FileAbstractDataJob { Q_OBJECT /** * Whether to use the content as indexable text. * * Default value is false. * * This property can be modified only when the job is not running. */ Q_PROPERTY(bool useContentAsIndexableText READ useContentAsIndexableText WRITE setUseContentAsIndexableText) public: explicit FileAbstractUploadJob(const FilePtr &metadata, const AccountPtr &account, QObject *parent = nullptr); explicit FileAbstractUploadJob(const FilesList &metadata, const AccountPtr &account, QObject *parent = nullptr); explicit FileAbstractUploadJob(const QString &filePath, const AccountPtr &account, QObject *parent = nullptr); explicit FileAbstractUploadJob(const QString &filePath, const FilePtr &metaData, const AccountPtr &account, QObject *parent = nullptr); explicit FileAbstractUploadJob(const QStringList &filePaths, const AccountPtr &account, QObject *parent = nullptr); explicit FileAbstractUploadJob(const QMap < QString /* file path */, FilePtr /* metadata */ > &files, const AccountPtr &account, QObject *parent = nullptr); ~FileAbstractUploadJob() override; bool useContentAsIndexableText() const; void setUseContentAsIndexableText(bool useContentAsIndexableText); + /** + * @brief Whether the request supports both My Drives and shared drives. + * + * Set to true by default as LibKGAPI supports Team Drives. + * + * @deprecated This parameter will only be effective until June 1, 2020. Afterwards all applications + * are assumed to support shared drives. + */ + KGAPIDRIVE_DEPRECATED bool supportsAllDrives() const; + + /** + * @brief Sets whether the request supports both My Drives and shared drives. + * + * Set to true by default as LibKGAPI supports Team Drives. + * + * @deprecated This parameter will only be effective until June 1, 2020. Afterwards all applications + * are assumed to support shared drives. + */ + KGAPIDRIVE_DEPRECATED void setSupportsAllDrives(bool supportsAllDrives); + QMap < QString /* file path */, FilePtr /* metadata */ > files() const; protected: void start() override; void dispatchRequest(QNetworkAccessManager *accessManager, const QNetworkRequest &request, const QByteArray &data, const QString &contentType) override; void handleReply(const QNetworkReply *reply, const QByteArray &rawData) override; virtual QUrl createUrl(const QString &filePath, const FilePtr &metaData) = 0; virtual QNetworkReply *dispatch(QNetworkAccessManager *accessManager, const QNetworkRequest &request, const QByteArray &data) = 0; void setSerializationOptions(File::SerializationOptions options); File::SerializationOptions serializationOptions() const; private: class Private; Private *const d; friend class Private; Q_PRIVATE_SLOT(d, void _k_uploadProgress(qint64 uploadedBytes, qint64 totalBytes)) }; } // namespace Drive } // namespace KGAPI2 #endif // KGAPI2_DRIVEFILEABSTRACTUPLOADJOB_H diff --git a/src/drive/filefetchjob.cpp b/src/drive/filefetchjob.cpp index 94cb4e2..3142f44 100644 --- a/src/drive/filefetchjob.cpp +++ b/src/drive/filefetchjob.cpp @@ -1,380 +1,394 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * 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 "filefetchjob.h" #include "filesearchquery.h" #include "account.h" #include "../debug.h" #include "driveservice.h" #include "file.h" #include "utils.h" #include #include #include using namespace KGAPI2; using namespace KGAPI2::Drive; class Q_DECL_HIDDEN FileFetchJob::Private { public: Private(FileFetchJob *parent); void processNext(); QNetworkRequest createRequest(const QUrl &url); QStringList fieldsToStrings(qulonglong fields); FileSearchQuery searchQuery; QStringList filesIDs; bool isFeed; - bool includeTeamDriveItems; + bool includeItemsFromAllDrives; + bool supportsAllDrives; bool updateViewedDate; qulonglong fields; private: FileFetchJob *const q; }; FileFetchJob::Private::Private(FileFetchJob *parent): isFeed(false), + includeItemsFromAllDrives(true), + supportsAllDrives(true), updateViewedDate(false), fields(FileFetchJob::AllFields), q(parent) { } QNetworkRequest FileFetchJob::Private::createRequest(const QUrl &url) { QNetworkRequest request; request.setUrl(url); request.setRawHeader("Authorization", "Bearer " + q->account()->accessToken().toLatin1()); return request; } QStringList FileFetchJob::Private::fieldsToStrings(qulonglong fields) { if (fields & AllFields) { return QStringList(); } QStringList fieldsStrings; // Always fetch kind fieldsStrings << QStringLiteral("kind"); // FIXME: Use QMetaEnum once it supports enums larger than int if (fields & Id) { fieldsStrings << QStringLiteral("id"); } if (fields & Title) { fieldsStrings << QStringLiteral("title"); } if (fields & MimeType) { fieldsStrings << QStringLiteral("mimeType"); } if (fields & Description) { fieldsStrings << QStringLiteral("description"); } if (fields & Labels) { fieldsStrings << QStringLiteral("labels"); } if (fields & CreatedDate) { fieldsStrings << QStringLiteral("createdDate"); } if (fields & ModifiedDate) { fieldsStrings << QStringLiteral("modifiedDate"); } if (fields & ModifiedByMeDate) { fieldsStrings << QStringLiteral("modifiedByMeDate"); } if (fields & DownloadUrl) { fieldsStrings << QStringLiteral("downloadUrl"); } if (fields & IndexableText) { fieldsStrings << QStringLiteral("indexableText"); } if (fields & UserPermission) { fieldsStrings << QStringLiteral("userPermission"); } if (fields & FileExtension) { fieldsStrings << QStringLiteral("fileExtension"); } if (fields & MD5Checksum) { fieldsStrings << QStringLiteral("md5Checksum"); } if (fields & FileSize) { fieldsStrings << QStringLiteral("fileSize"); } if (fields & AlternateLink) { fieldsStrings << QStringLiteral("alternateLink"); } if (fields & EmbedLink) { fieldsStrings << QStringLiteral("embedLink"); } if (fields & SharedWithMeDate) { fieldsStrings << QStringLiteral("sharedWithMeDate"); } if (fields & Parents) { fieldsStrings << QStringLiteral("parents"); } if (fields & ExportLinks) { fieldsStrings << QStringLiteral("exportLinks"); } if (fields & OriginalFilename) { fieldsStrings << QStringLiteral("originalFilename"); } if (fields & OwnerNames) { fieldsStrings << QStringLiteral("ownerNames"); } if (fields & LastModifiedByMeDate) { fieldsStrings << QStringLiteral("lastModifiedByMeDate"); } if (fields & Editable) { fieldsStrings << QStringLiteral("editable"); } if (fields & WritersCanShare) { fieldsStrings << QStringLiteral("writersCanShare"); } if (fields & ThumbnailLink) { fieldsStrings << QStringLiteral("thumbnailLink"); } if (fields & LastViewedByMeDate) { fieldsStrings << QStringLiteral("lastViewedByMeDate"); } if (fields & WebContentLink) { fieldsStrings << QStringLiteral("webContentLink"); } if (fields & ExplicitlyTrashed) { fieldsStrings << QStringLiteral("explicitlyTrashed"); } if (fields & ImageMediaMetadata) { fieldsStrings << QStringLiteral("imageMediaMetadata"); } if (fields & Thumbnail) { fieldsStrings << QStringLiteral("thumbnail"); } if (fields & WebViewLink) { fieldsStrings << QStringLiteral("webViewLink"); } if (fields & IconLink) { fieldsStrings << QStringLiteral("iconLink"); } if (fields & Shared) { fieldsStrings << QStringLiteral("shared"); } if (fields & Owners) { fieldsStrings << QStringLiteral("owners"); } if (fields & LastModifyingUser) { fieldsStrings << QStringLiteral("lastModifyingUser"); } if (fields & AppDataContents) { fieldsStrings << QStringLiteral("appDataContents"); } if (fields & OpenWithLinks) { fieldsStrings << QStringLiteral("openWithLinks"); } if (fields & DefaultOpenWithLink) { fieldsStrings << QStringLiteral("defaultOpenWithLink"); } if (fields & HeadRevisionId) { fieldsStrings << QStringLiteral("headRevisionId"); } if (fields & Copyable) { fieldsStrings << QStringLiteral("copyable"); } if (fields & Properties) { fieldsStrings << QStringLiteral("properties"); } if (fields & MarkedViewedByMeDate) { fieldsStrings << QStringLiteral("markedViewedByMeDate"); } if (fields & Version) { fieldsStrings << QStringLiteral("version"); } if (fields & SharingUser) { fieldsStrings << QStringLiteral("sharingUser"); } if (fields & Permissions) { fieldsStrings << QStringLiteral("permissions"); } return fieldsStrings; } void FileFetchJob::Private::processNext() { QUrl url; if (isFeed) { url = DriveService::fetchFilesUrl(); QUrlQuery query(url); if (!searchQuery.isEmpty()) { query.addQueryItem(QStringLiteral("q"), searchQuery.serialize()); } if (fields != FileFetchJob::AllFields) { const QStringList fieldsStrings = fieldsToStrings(fields); query.addQueryItem(QStringLiteral("fields"), QStringLiteral("etag,kind,nextLink,nextPageToken,selfLink,items(%1)").arg(fieldsStrings.join(QStringLiteral(",")))); } - if (includeTeamDriveItems) { - query.addQueryItem(QStringLiteral("includeTeamDriveItems"), QStringLiteral("true")); - query.addQueryItem(QStringLiteral("supportsTeamDrives"), QStringLiteral("true")); - } + query.addQueryItem(QStringLiteral("includeItemsFromAllDrives"), includeItemsFromAllDrives ? QStringLiteral("true") : QStringLiteral("false")); url.setQuery(query); } else { if (filesIDs.isEmpty()) { q->emitFinished(); return; } const QString fileId = filesIDs.takeFirst(); url = DriveService::fetchFileUrl(fileId); if (fields != FileFetchJob::AllFields) { const QStringList fieldsStrings = fieldsToStrings(fields); QUrlQuery query(url); query.addQueryItem(QStringLiteral("fields"), fieldsStrings.join(QStringLiteral(","))); url.setQuery(query); } } + QUrlQuery withDriveSupportQuery(url); + withDriveSupportQuery.addQueryItem(QStringLiteral("supportsAllDrives"), supportsAllDrives ? QStringLiteral("true") : QStringLiteral("false")); + url.setQuery(withDriveSupportQuery); + q->enqueueRequest(createRequest(url)); } FileFetchJob::FileFetchJob(const QString &fileId, const AccountPtr &account, QObject *parent): FetchJob(account, parent), d(new Private(this)) { d->filesIDs << fileId; } FileFetchJob::FileFetchJob(const QStringList &filesIds, const AccountPtr &account, QObject *parent): FetchJob(account, parent), d(new Private(this)) { d->filesIDs << filesIds; } FileFetchJob::FileFetchJob(const AccountPtr &account, QObject *parent): FetchJob(account, parent), d(new Private(this)) { d->isFeed = true; } FileFetchJob::FileFetchJob(const FileSearchQuery &query, const AccountPtr &account, QObject *parent): FetchJob(account, parent), d(new Private(this)) { d->isFeed = true; d->searchQuery = query; } FileFetchJob::~FileFetchJob() { delete d; } bool FileFetchJob::updateViewedDate() const { return d->updateViewedDate; } void FileFetchJob::setUpdateViewedDate(bool updateViewedDate) { if (isRunning()) { qCWarning(KGAPIDebug) << "Can't modify updateViewedDate property when job is running."; return; } d->updateViewedDate = updateViewedDate; } void FileFetchJob::start() { d->processNext(); } void FileFetchJob::setFields(qulonglong fields) { d->fields = fields; } qulonglong FileFetchJob::fields() const { return d->fields; } -bool FileFetchJob::includeTeamDriveItems() const +bool FileFetchJob::includeItemsFromAllDrives() const +{ + return d->includeItemsFromAllDrives; +} + +void FileFetchJob::setIncludeItemsFromAllDrives(bool includeItemsFromAllDrives) +{ + d->includeItemsFromAllDrives = includeItemsFromAllDrives; +} + +bool FileFetchJob::supportsAllDrives() const { - return d->includeTeamDriveItems; + return d->supportsAllDrives; } -void FileFetchJob::setIncludeTeamDriveItems(bool includeTeamDriveItems) +void FileFetchJob::setSupportsAllDrives(bool supportsAllDrives) { - d->includeTeamDriveItems = includeTeamDriveItems; + d->supportsAllDrives = supportsAllDrives; } ObjectsList FileFetchJob::handleReplyWithItems(const QNetworkReply *reply, const QByteArray &rawData) { ObjectsList items; const QString contentType = reply->header(QNetworkRequest::ContentTypeHeader).toString(); ContentType ct = Utils::stringToContentType(contentType); if (ct == KGAPI2::JSON) { if (d->isFeed) { FeedData feedData; items << File::fromJSONFeed(rawData, feedData); if (feedData.nextPageUrl.isValid()) { const QNetworkRequest request = d->createRequest(feedData.nextPageUrl); enqueueRequest(request); } } else { items << File::fromJSON(rawData); d->processNext(); } } else { setError(KGAPI2::InvalidResponse); setErrorString(tr("Invalid response content type")); emitFinished(); return items; } return items; } diff --git a/src/drive/filefetchjob.h b/src/drive/filefetchjob.h index 7900e20..dd950da 100644 --- a/src/drive/filefetchjob.h +++ b/src/drive/filefetchjob.h @@ -1,142 +1,175 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * 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 KGAPI2_DRIVEFILEFETCHJOB_H #define KGAPI2_DRIVEFILEFETCHJOB_H #include "fetchjob.h" #include "kgapidrive_export.h" #include namespace KGAPI2 { namespace Drive { class FileSearchQuery; class KGAPIDRIVE_EXPORT FileFetchJob : public KGAPI2::FetchJob { Q_OBJECT /** * Whether to update the view date after successfully retrieving files. * * Default value is false. * * This property can be modified only when the job is not running. */ Q_PROPERTY(bool updateViewedDate READ updateViewedDate WRITE setUpdateViewedDate) public: enum Fields { AllFields = 0ULL, Id = 1ULL << 0, Title = 1ULL << 1, MimeType = 1ULL << 2, Description = 1ULL << 3, Labels = 1ULL << 4, CreatedDate = 1ULL << 5, ModifiedDate = 1ULL << 6, ModifiedByMeDate = 1ULL << 7, DownloadUrl = 1ULL << 8, IndexableText = 1ULL << 9, UserPermission = 1ULL << 10, FileExtension = 1ULL << 11, MD5Checksum = 1ULL << 12, FileSize = 1ULL << 13, AlternateLink = 1ULL << 14, EmbedLink = 1ULL << 15, SharedWithMeDate = 1ULL << 16, Parents = 1ULL << 17, ExportLinks = 1ULL << 18, OriginalFilename = 1ULL << 19, OwnerNames = 1ULL << 20, LastModifiedByMeDate = 1ULL << 21, Editable = 1ULL << 22, WritersCanShare = 1ULL << 23, ThumbnailLink = 1ULL << 24, LastViewedByMeDate = 1ULL << 25, WebContentLink = 1ULL << 26, ExplicitlyTrashed = 1ULL << 27, ImageMediaMetadata = 1ULL << 28, Thumbnail = 1ULL << 29, WebViewLink = 1ULL << 30, IconLink = 1ULL << 31, Shared = 1ULL << 32, Owners = 1ULL << 33, LastModifyingUser = 1ULL << 34, AppDataContents = 1ULL << 35, OpenWithLinks = 1ULL << 36, DefaultOpenWithLink = 1ULL << 37, HeadRevisionId = 1ULL << 38, Copyable = 1ULL << 39, Properties = 1ULL << 40, MarkedViewedByMeDate = 1ULL << 41, Version = 1ULL << 42, SharingUser = 1ULL << 43, Permissions = 1ULL << 44, BasicFields = Id | Title | MimeType | CreatedDate | ModifiedDate | FileSize | DownloadUrl | Permissions, AccessFields = CreatedDate | ModifiedDate | ModifiedByMeDate | LastModifiedByMeDate | LastViewedByMeDate | MarkedViewedByMeDate, SharingFields = SharedWithMeDate | WritersCanShare | Shared | Owners | SharingUser | OwnerNames // TODO: More? }; explicit FileFetchJob(const QString &fileId, const AccountPtr &account, QObject *parent = nullptr); explicit FileFetchJob(const QStringList &filesIds, const AccountPtr &account, QObject *parent = nullptr); explicit FileFetchJob(const FileSearchQuery &query, const AccountPtr &account, QObject *parent = nullptr); explicit FileFetchJob(const AccountPtr &account, QObject *parent = nullptr); ~FileFetchJob() override; bool updateViewedDate() const; void setUpdateViewedDate(bool updateViewedDate); void setFields(qulonglong fields); qulonglong fields() const; - bool includeTeamDriveItems() const; - void setIncludeTeamDriveItems(bool includeTeamDriveItems); + /** + * @brief Whether both My Drive and shared drive items should be included in results. + * + * @deprecated This parameter will only be effective until June 1, 2020. Afterwards shared drive items will be included in the results. + */ + KGAPIDRIVE_DEPRECATED bool includeItemsFromAllDrives() const; + + /** + * @brief Sets whether both My Drive and shared drive items should be included in results. + * + * Set to true by default as LibKGAPI supports Team Drives. + * + * @deprecated This parameter will only be effective until June 1, 2020. Afterwards shared drive items will be included in the results. + */ + KGAPIDRIVE_DEPRECATED void setIncludeItemsFromAllDrives(bool includeItemsFromAllDrives); + + /** + * @brief Whether the request supports both My Drives and shared drives. + * + * Set to true by default as LibKGAPI supports Team Drives. + * + * @deprecated This parameter will only be effective until June 1, 2020. Afterwards all applications + * are assumed to support shared drives. + */ + KGAPIDRIVE_DEPRECATED bool supportsAllDrives() const; + + /** + * @brief Sets whether the request supports both My Drives and shared drives. + * + * Set to true by default as LibKGAPI supports Team Drives. + * + * @deprecated This parameter will only be effective until June 1, 2020. Afterwards all applications + * are assumed to support shared drives. + */ + KGAPIDRIVE_DEPRECATED void setSupportsAllDrives(bool supportsAllDrives); protected: void start() override; KGAPI2::ObjectsList handleReplyWithItems(const QNetworkReply *reply, const QByteArray &rawData) override; private: class Private; Private *const d; friend class Private; }; } // namespace Drive } // namespace KGAPI2 #endif // KGAPI2_DRIVEFILEFETCHJOB_H diff --git a/src/drive/parentreferencecreatejob.cpp b/src/drive/parentreferencecreatejob.cpp index f4f39ae..0341fe4 100644 --- a/src/drive/parentreferencecreatejob.cpp +++ b/src/drive/parentreferencecreatejob.cpp @@ -1,148 +1,165 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * 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 "parentreferencecreatejob.h" #include "account.h" #include "driveservice.h" #include "parentreference.h" #include "utils.h" #include #include +#include using namespace KGAPI2; using namespace KGAPI2::Drive; class Q_DECL_HIDDEN ParentReferenceCreateJob::Private { public: Private(ParentReferenceCreateJob *parent); void processNext(); + bool supportsAllDrives; QString fileId; ParentReferencesList references; private: ParentReferenceCreateJob *q; }; ParentReferenceCreateJob::Private::Private(ParentReferenceCreateJob *parent): + supportsAllDrives(true), q(parent) { } void ParentReferenceCreateJob::Private::processNext() { if (references.isEmpty()) { q->emitFinished(); return; } const ParentReferencePtr reference = references.takeFirst(); - const QUrl url = DriveService::createParentReferenceUrl(fileId); + QUrl url = DriveService::createParentReferenceUrl(fileId); + + QUrlQuery withDriveSupportQuery(url); + withDriveSupportQuery.addQueryItem(QStringLiteral("supportsAllDrives"), supportsAllDrives ? QStringLiteral("true") : QStringLiteral("false")); + url.setQuery(withDriveSupportQuery); QNetworkRequest request; request.setRawHeader("Authorization", "Bearer " + q->account()->accessToken().toLatin1()); request.setUrl(url); const QByteArray rawData = ParentReference::toJSON(reference); q->enqueueRequest(request, rawData, QStringLiteral("application/json")); } ParentReferenceCreateJob::ParentReferenceCreateJob(const QString &fileId, const QString &parentId, const AccountPtr &account, QObject *parent): CreateJob(account, parent), d(new Private(this)) { d->fileId = fileId; d->references << ParentReferencePtr(new ParentReference(parentId)); } ParentReferenceCreateJob::ParentReferenceCreateJob(const QString &fileId, const QStringList &parentsIds, const AccountPtr &account, QObject *parent): CreateJob(account, parent), d(new Private(this)) { d->fileId = fileId; for (const QString & parentId : qAsConst(parentsIds)) { d->references << ParentReferencePtr(new ParentReference(parentId)); } } ParentReferenceCreateJob::ParentReferenceCreateJob(const QString &fileId, const ParentReferencePtr &reference, const AccountPtr &account, QObject *parent): CreateJob(account, parent), d(new Private(this)) { d->fileId = fileId; d->references << reference; } ParentReferenceCreateJob::ParentReferenceCreateJob(const QString &fileId, const ParentReferencesList &references, const AccountPtr &account, QObject *parent): CreateJob(account, parent), d(new Private(this)) { d->fileId = fileId; d->references << references; } ParentReferenceCreateJob::~ParentReferenceCreateJob() { delete d; } +bool ParentReferenceCreateJob::supportsAllDrives() const +{ + return d->supportsAllDrives; +} + +void ParentReferenceCreateJob::setSupportsAllDrives(bool supportsAllDrives) +{ + d->supportsAllDrives = supportsAllDrives; +} + void ParentReferenceCreateJob::start() { d->processNext(); } ObjectsList ParentReferenceCreateJob::handleReplyWithItems(const QNetworkReply *reply, const QByteArray &rawData) { const QString contentType = reply->header(QNetworkRequest::ContentTypeHeader).toString(); ContentType ct = Utils::stringToContentType(contentType); ObjectsList items; if (ct == KGAPI2::JSON) { items << ParentReference::fromJSON(rawData); } else { setError(KGAPI2::InvalidResponse); setErrorString(tr("Invalid response content type")); emitFinished(); } // Enqueue next item or finish d->processNext(); return items; } diff --git a/src/drive/parentreferencecreatejob.h b/src/drive/parentreferencecreatejob.h index fa15c9c..3931d4c 100644 --- a/src/drive/parentreferencecreatejob.h +++ b/src/drive/parentreferencecreatejob.h @@ -1,76 +1,96 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * 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 KGAPI2_DRIVEPARENTREFERENCECREATEJOB_H #define KGAPI2_DRIVEPARENTREFERENCECREATEJOB_H #include "createjob.h" #include "kgapidrive_export.h" #include namespace KGAPI2 { namespace Drive { class KGAPIDRIVE_EXPORT ParentReferenceCreateJob : public KGAPI2::CreateJob { Q_OBJECT public: explicit ParentReferenceCreateJob(const QString &fileId, const QString &parentId, const AccountPtr &account, QObject *parent = nullptr); explicit ParentReferenceCreateJob(const QString &fileId, const QStringList &parentsIds, const AccountPtr &account, QObject *parent = nullptr); explicit ParentReferenceCreateJob(const QString &fileId, const ParentReferencePtr &reference, const AccountPtr &account, QObject *parent = nullptr); explicit ParentReferenceCreateJob(const QString &fileId, const ParentReferencesList &references, const AccountPtr &account, QObject *parent = nullptr); ~ParentReferenceCreateJob() override; + /** + * @brief Whether the request supports both My Drives and shared drives. + * + * Set to true by default as LibKGAPI supports Team Drives. + * + * @deprecated This parameter will only be effective until June 1, 2020. Afterwards all applications + * are assumed to support shared drives. + */ + KGAPIDRIVE_DEPRECATED bool supportsAllDrives() const; + + /** + * @brief Sets whether the request supports both My Drives and shared drives. + * + * Set to true by default as LibKGAPI supports Team Drives. + * + * @deprecated This parameter will only be effective until June 1, 2020. Afterwards all applications + * are assumed to support shared drives. + */ + KGAPIDRIVE_DEPRECATED void setSupportsAllDrives(bool supportsAllDrives); + protected: void start() override; KGAPI2::ObjectsList handleReplyWithItems(const QNetworkReply *reply, const QByteArray &rawData) override; private: class Private; Private *const d; friend class Private; }; } // namespace Drive } // namespace KGAPI2 #endif // KGAPI2_DRIVEPARENTREFERENCECREATEJOB_H diff --git a/src/drive/permissioncreatejob.cpp b/src/drive/permissioncreatejob.cpp index 68d86fb..ac29369 100644 --- a/src/drive/permissioncreatejob.cpp +++ b/src/drive/permissioncreatejob.cpp @@ -1,125 +1,142 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * 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 "permissioncreatejob.h" #include "account.h" #include "driveservice.h" #include "permission.h" #include "utils.h" #include #include +#include using namespace KGAPI2; using namespace KGAPI2::Drive; class Q_DECL_HIDDEN PermissionCreateJob::Private { public: Private(PermissionCreateJob *parent); void processNext(); PermissionsList permissions; QString fileId; + bool supportsAllDrives; private: PermissionCreateJob *const q; }; PermissionCreateJob::Private::Private(PermissionCreateJob *parent): + supportsAllDrives(true), q(parent) { } void PermissionCreateJob::Private::processNext() { if (permissions.isEmpty()) { q->emitFinished(); return; } const PermissionPtr permission = permissions.takeFirst(); - const QUrl url = DriveService::createPermissionUrl(fileId); + QUrl url = DriveService::createPermissionUrl(fileId); + + QUrlQuery withDriveSupportQuery(url); + withDriveSupportQuery.addQueryItem(QStringLiteral("supportsAllDrives"), supportsAllDrives ? QStringLiteral("true") : QStringLiteral("false")); + url.setQuery(withDriveSupportQuery); QNetworkRequest request; request.setRawHeader("Authorization", "Bearer " + q->account()->accessToken().toLatin1()); request.setUrl(url); const QByteArray rawData = Permission::toJSON(permission); q->enqueueRequest(request, rawData, QStringLiteral("application/json")); } PermissionCreateJob::PermissionCreateJob(const QString &fileId, const PermissionPtr &permission, const AccountPtr &account, QObject *parent): CreateJob(account, parent), d(new Private(this)) { d->fileId = fileId; d->permissions << permission; } PermissionCreateJob::PermissionCreateJob(const QString &fileId, const PermissionsList &permissions, const AccountPtr &account, QObject *parent): CreateJob(account, parent), d(new Private(this)) { d->fileId = fileId; d->permissions = permissions; } PermissionCreateJob::~PermissionCreateJob() { delete d; } +bool PermissionCreateJob::supportsAllDrives() const +{ + return d->supportsAllDrives; +} + +void PermissionCreateJob::setSupportsAllDrives(bool supportsAllDrives) +{ + d->supportsAllDrives = supportsAllDrives; +} + void PermissionCreateJob::start() { d->processNext(); } ObjectsList PermissionCreateJob::handleReplyWithItems(const QNetworkReply *reply, const QByteArray &rawData) { const QString contentType = reply->header(QNetworkRequest::ContentTypeHeader).toString(); ContentType ct = Utils::stringToContentType(contentType); ObjectsList items; if (ct == KGAPI2::JSON) { items << Permission::fromJSON(rawData); } else { setError(KGAPI2::InvalidResponse); setErrorString(tr("Invalid response content type")); emitFinished(); } // Enqueue next item or finish d->processNext(); return items; } diff --git a/src/drive/permissioncreatejob.h b/src/drive/permissioncreatejob.h index 72e1032..fd2990f 100644 --- a/src/drive/permissioncreatejob.h +++ b/src/drive/permissioncreatejob.h @@ -1,63 +1,83 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * 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 KGAPI2_DRIVEPERMISSIONCREATEJOB_H #define KGAPI2_DRIVEPERMISSIONCREATEJOB_H #include "createjob.h" #include "kgapidrive_export.h" namespace KGAPI2 { namespace Drive { class KGAPIDRIVE_EXPORT PermissionCreateJob : public KGAPI2::CreateJob { Q_OBJECT public: explicit PermissionCreateJob(const QString &fileId, const PermissionPtr &permission, const AccountPtr &account, QObject *parent = nullptr); explicit PermissionCreateJob(const QString &fileId, const PermissionsList &permissions, const AccountPtr &account, QObject *parent = nullptr); ~PermissionCreateJob() override; + /** + * @brief Whether the request supports both My Drives and shared drives. + * + * Set to true by default as LibKGAPI supports Team Drives. + * + * @deprecated This parameter will only be effective until June 1, 2020. Afterwards all applications + * are assumed to support shared drives. + */ + KGAPIDRIVE_DEPRECATED bool supportsAllDrives() const; + + /** + * @brief Sets whether the request supports both My Drives and shared drives. + * + * Set to true by default as LibKGAPI supports Team Drives. + * + * @deprecated This parameter will only be effective until June 1, 2020. Afterwards all applications + * are assumed to support shared drives. + */ + KGAPIDRIVE_DEPRECATED void setSupportsAllDrives(bool supportsAllDrives); + protected: void start() override; KGAPI2::ObjectsList handleReplyWithItems(const QNetworkReply *reply, const QByteArray &rawData) override; private: class Private; Private *const d; friend class Private; }; } // namespace Drive } // namespace KGAPI2 #endif // KGAPI2_DRIVEPERMISSIONCREATEJOB_H diff --git a/src/drive/permissiondeletejob.cpp b/src/drive/permissiondeletejob.cpp index e3d5fe8..c0e43aa 100644 --- a/src/drive/permissiondeletejob.cpp +++ b/src/drive/permissiondeletejob.cpp @@ -1,107 +1,126 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * 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 "permissiondeletejob.h" #include "permission.h" #include "account.h" #include "driveservice.h" #include +#include using namespace KGAPI2; using namespace KGAPI2::Drive; class Q_DECL_HIDDEN PermissionDeleteJob::Private { public: QString fileId; QStringList permissionsIds; + bool supportsAllDrives; }; PermissionDeleteJob::PermissionDeleteJob(const QString &fileId, const PermissionPtr &permission, const AccountPtr &account, QObject *parent): DeleteJob(account, parent), d(new Private) { + d->supportsAllDrives = true; d->fileId = fileId; d->permissionsIds << permission->id(); } PermissionDeleteJob::PermissionDeleteJob(const QString &fileId, const QString &permissionId, const AccountPtr &account, QObject *parent): DeleteJob(account, parent), d(new Private) { + d->supportsAllDrives = true; d->fileId = fileId; d->permissionsIds << permissionId; } PermissionDeleteJob::PermissionDeleteJob(const QString &fileId, const PermissionsList &permissions, const AccountPtr &account, QObject *parent): DeleteJob(account, parent), d(new Private) { + d->supportsAllDrives = true; d->fileId = fileId; for (const PermissionPtr & permission : qAsConst(permissions)) { d->permissionsIds << permission->id(); } } PermissionDeleteJob::PermissionDeleteJob(const QString &fileId, const QStringList &permissionsIds, const AccountPtr &account, QObject *parent): DeleteJob(account, parent), d(new Private) { + d->supportsAllDrives = true; d->fileId = fileId; d->permissionsIds << permissionsIds; } PermissionDeleteJob::~PermissionDeleteJob() { delete d; } +bool PermissionDeleteJob::supportsAllDrives() const +{ + return d->supportsAllDrives; +} + +void PermissionDeleteJob::setSupportsAllDrives(bool supportsAllDrives) +{ + d->supportsAllDrives = supportsAllDrives; +} + void PermissionDeleteJob::start() { if (d->permissionsIds.isEmpty()) { emitFinished(); return; } const QString permissionId = d->permissionsIds.takeFirst(); - const QUrl url = DriveService::deletePermissionUrl(d->fileId, permissionId); + QUrl url = DriveService::deletePermissionUrl(d->fileId, permissionId); + QUrlQuery withDriveSupportQuery(url); + withDriveSupportQuery.addQueryItem(QStringLiteral("supportsAllDrives"), d->supportsAllDrives ? QStringLiteral("true") : QStringLiteral("false")); + url.setQuery(withDriveSupportQuery); QNetworkRequest request(url); request.setRawHeader("Authorization", "Bearer " + account()->accessToken().toLatin1()); enqueueRequest(request); } diff --git a/src/drive/permissiondeletejob.h b/src/drive/permissiondeletejob.h index 7c2e238..6979180 100644 --- a/src/drive/permissiondeletejob.h +++ b/src/drive/permissiondeletejob.h @@ -1,70 +1,90 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * 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 KGAPI2_DRIVEPERMISSIONDELETEJOB_H #define KGAPI2_DRIVEPERMISSIONDELETEJOB_H #include "deletejob.h" #include "kgapidrive_export.h" #include namespace KGAPI2 { namespace Drive { class KGAPIDRIVE_EXPORT PermissionDeleteJob : KGAPI2::DeleteJob { Q_OBJECT public: explicit PermissionDeleteJob(const QString &fileId, const PermissionPtr &permission, const AccountPtr &account, QObject *parent = nullptr); explicit PermissionDeleteJob(const QString &fileId, const QString &permissionId, const AccountPtr &account, QObject *parent = nullptr); explicit PermissionDeleteJob(const QString &fileId, const PermissionsList &permissions, const AccountPtr &account, QObject *parent = nullptr); explicit PermissionDeleteJob(const QString &fileId, const QStringList &permissionsIds, const AccountPtr &account, QObject *parent = nullptr); ~PermissionDeleteJob() override; + /** + * @brief Whether the request supports both My Drives and shared drives. + * + * Set to true by default as LibKGAPI supports Team Drives. + * + * @deprecated This parameter will only be effective until June 1, 2020. Afterwards all applications + * are assumed to support shared drives. + */ + KGAPIDRIVE_DEPRECATED bool supportsAllDrives() const; + + /** + * @brief Sets whether the request supports both My Drives and shared drives. + * + * Set to true by default as LibKGAPI supports Team Drives. + * + * @deprecated This parameter will only be effective until June 1, 2020. Afterwards all applications + * are assumed to support shared drives. + */ + KGAPIDRIVE_DEPRECATED void setSupportsAllDrives(bool supportsAllDrives); + protected: void start() override; private: class Private; Private *const d; friend class Private; }; } // namespace Drive } // namespace KGAPI2 #endif // KGAPI2_DRIVEPERMISSIONDELETEJOB_H diff --git a/src/drive/permissionfetchjob.cpp b/src/drive/permissionfetchjob.cpp index a17e1d0..b45987b 100644 --- a/src/drive/permissionfetchjob.cpp +++ b/src/drive/permissionfetchjob.cpp @@ -1,125 +1,147 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * 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 "permissionfetchjob.h" #include "driveservice.h" #include "account.h" #include "file.h" #include "permission.h" #include "utils.h" - #include #include +#include using namespace KGAPI2; using namespace KGAPI2::Drive; class Q_DECL_HIDDEN PermissionFetchJob::Private { public: QString fileId; QString permissionId; + bool supportsAllDrives; }; PermissionFetchJob::PermissionFetchJob(const QString &fileId, const AccountPtr &account, QObject *parent): FetchJob(account, parent), d(new Private) { + d->supportsAllDrives = true; d->fileId = fileId; } PermissionFetchJob::PermissionFetchJob(const FilePtr &file, const AccountPtr &account, QObject *parent): FetchJob(account, parent), d(new Private) { + d->supportsAllDrives = true; d->fileId = file->id(); } PermissionFetchJob::PermissionFetchJob(const QString &fileId, const QString &permissionId, const AccountPtr &account, QObject *parent): FetchJob(account, parent), d(new Private) { + d->supportsAllDrives = true; d->fileId = fileId; d->permissionId = permissionId; } PermissionFetchJob::PermissionFetchJob(const FilePtr &file, const QString &permissionId, const AccountPtr &account, QObject *parent): FetchJob(account, parent), d(new Private) { + d->supportsAllDrives = true; d->fileId = file->id(); d->permissionId = permissionId; } PermissionFetchJob::~PermissionFetchJob() { delete d; } +bool PermissionFetchJob::supportsAllDrives() const +{ + return d->supportsAllDrives; +} + +void PermissionFetchJob::setSupportsAllDrives(bool supportsAllDrives) +{ + d->supportsAllDrives = supportsAllDrives; +} + void PermissionFetchJob::start() { - QNetworkRequest request; + QUrl url; if (d->permissionId.isEmpty()) { - request.setUrl(DriveService::fetchPermissionsUrl(d->fileId)); + url = DriveService::fetchPermissionsUrl(d->fileId); } else { - request.setUrl(DriveService::fetchPermissionUrl(d->fileId, d->permissionId)); + url = DriveService::fetchPermissionUrl(d->fileId, d->permissionId); } + + QUrlQuery withDriveSupportQuery(url); + withDriveSupportQuery.addQueryItem(QStringLiteral("supportsAllDrives"), d->supportsAllDrives ? QStringLiteral("true") : QStringLiteral("false")); + url.setQuery(withDriveSupportQuery); + + QNetworkRequest request; + request.setUrl(url); request.setRawHeader("Authorization", "Bearer " + account()->accessToken().toLatin1()); enqueueRequest(request); } ObjectsList PermissionFetchJob::handleReplyWithItems(const QNetworkReply *reply, const QByteArray &rawData) { ObjectsList items; const QString contentType = reply->header(QNetworkRequest::ContentTypeHeader).toString(); ContentType ct = Utils::stringToContentType(contentType); if (ct == KGAPI2::JSON) { if (d->permissionId.isEmpty()) { items << Permission::fromJSONFeed(rawData); } else { items << Permission::fromJSON(rawData); } } else { setError(KGAPI2::InvalidResponse); setErrorString(tr("Invalid response content type")); } emitFinished(); return items; } diff --git a/src/drive/permissionfetchjob.h b/src/drive/permissionfetchjob.h index b1b62ec..58d4b01 100644 --- a/src/drive/permissionfetchjob.h +++ b/src/drive/permissionfetchjob.h @@ -1,66 +1,86 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * 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 KGAPI2_DRIVEPERMISSIONFETCHJOB_H #define KGAPI2_DRIVEPERMISSIONFETCHJOB_H #include "fetchjob.h" #include "kgapidrive_export.h" namespace KGAPI2 { namespace Drive { class KGAPIDRIVE_EXPORT PermissionFetchJob : public KGAPI2::FetchJob { Q_OBJECT public: explicit PermissionFetchJob(const QString &fileId, const AccountPtr &account, QObject *parent = nullptr); explicit PermissionFetchJob(const FilePtr &file, const AccountPtr &account, QObject *parent = nullptr); explicit PermissionFetchJob(const QString &fileId, const QString &permissionId, const AccountPtr &account, QObject *parent = nullptr); explicit PermissionFetchJob(const FilePtr &file, const QString &permissionId, const AccountPtr &account, QObject *parent = nullptr); ~PermissionFetchJob() override; + /** + * @brief Whether the request supports both My Drives and shared drives. + * + * Set to true by default as LibKGAPI supports Team Drives. + * + * @deprecated This parameter will only be effective until June 1, 2020. Afterwards all applications + * are assumed to support shared drives. + */ + KGAPIDRIVE_DEPRECATED bool supportsAllDrives() const; + + /** + * @brief Sets whether the request supports both My Drives and shared drives. + * + * Set to true by default as LibKGAPI supports Team Drives. + * + * @deprecated This parameter will only be effective until June 1, 2020. Afterwards all applications + * are assumed to support shared drives. + */ + KGAPIDRIVE_DEPRECATED void setSupportsAllDrives(bool supportsAllDrives); + protected: void start() override; KGAPI2::ObjectsList handleReplyWithItems(const QNetworkReply *reply, const QByteArray &rawData) override; private: class Private; Private *const d; friend class Private; }; } // namespace Drive } // namespace KGAPI2 #endif // KGAPI2_DRIVEPERMISSIONFETCHJOB_H diff --git a/src/drive/permissionmodifyjob.cpp b/src/drive/permissionmodifyjob.cpp index d58324c..fbb74bd 100644 --- a/src/drive/permissionmodifyjob.cpp +++ b/src/drive/permissionmodifyjob.cpp @@ -1,124 +1,141 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * 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 "permissionmodifyjob.h" #include "account.h" #include "driveservice.h" #include "permission.h" #include "utils.h" #include #include +#include using namespace KGAPI2; using namespace KGAPI2::Drive; class Q_DECL_HIDDEN PermissionModifyJob::Private { public: Private(PermissionModifyJob *parent); void processNext(); QString fileId; PermissionsList permissions; + bool supportsAllDrives; private: PermissionModifyJob *q; }; PermissionModifyJob::Private::Private(PermissionModifyJob *parent): + supportsAllDrives(true), q(parent) { } void PermissionModifyJob::Private::processNext() { if (permissions.isEmpty()) { q->emitFinished(); return; } const PermissionPtr permission = permissions.takeFirst(); - const QUrl url = DriveService::modifyPermissionUrl(fileId, permission->id()); + QUrl url = DriveService::modifyPermissionUrl(fileId, permission->id()); + + QUrlQuery withDriveSupportQuery(url); + withDriveSupportQuery.addQueryItem(QStringLiteral("supportsAllDrives"), supportsAllDrives ? QStringLiteral("true") : QStringLiteral("false")); + url.setQuery(withDriveSupportQuery); QNetworkRequest request(url); request.setRawHeader("Authorization", "Bearer " + q->account()->accessToken().toLatin1()); const QByteArray rawData = Permission::toJSON(permission); q->enqueueRequest(request, rawData, QStringLiteral("application/json")); } PermissionModifyJob::PermissionModifyJob(const QString &fileId, const PermissionPtr &permission, const AccountPtr &account, QObject *parent): ModifyJob(account, parent), d(new Private(this)) { d->fileId = fileId; d->permissions << permission; } PermissionModifyJob::PermissionModifyJob(const QString &fileId, const PermissionsList &permissions, const AccountPtr &account, QObject *parent): ModifyJob(account, parent), d(new Private(this)) { d->fileId = fileId; d->permissions << permissions; } PermissionModifyJob::~PermissionModifyJob() { delete d; } +bool PermissionModifyJob::supportsAllDrives() const +{ + return d->supportsAllDrives; +} + +void PermissionModifyJob::setSupportsAllDrives(bool supportsAllDrives) +{ + d->supportsAllDrives = supportsAllDrives; +} + void PermissionModifyJob::start() { d->processNext(); } ObjectsList PermissionModifyJob::handleReplyWithItems(const QNetworkReply *reply, const QByteArray &rawData) { const QString contentType = reply->header(QNetworkRequest::ContentTypeHeader).toString(); ContentType ct = Utils::stringToContentType(contentType); ObjectsList items; if (ct == KGAPI2::JSON) { items << Permission::fromJSON(rawData); } else { setError(KGAPI2::InvalidResponse); setErrorString(tr("Invalid response content type")); emitFinished(); } // Enqueue next item or finish d->processNext(); return items; } diff --git a/src/drive/permissionmodifyjob.h b/src/drive/permissionmodifyjob.h index 0f1276b..0c2a78a 100644 --- a/src/drive/permissionmodifyjob.h +++ b/src/drive/permissionmodifyjob.h @@ -1,64 +1,84 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2013 Daniel Vrátil * * 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 KGAPI2_DRIVEPERMISSIONMODIFYJOB_H #define KGAPI2_DRIVEPERMISSIONMODIFYJOB_H #include "modifyjob.h" #include "kgapidrive_export.h" namespace KGAPI2 { namespace Drive { class KGAPIDRIVE_EXPORT PermissionModifyJob : public KGAPI2::ModifyJob { Q_OBJECT public: explicit PermissionModifyJob(const QString &fileId, const PermissionPtr &permission, const AccountPtr &account, QObject *parent = nullptr); explicit PermissionModifyJob(const QString &fileId, const PermissionsList &permissions, const AccountPtr &account, QObject *parent = nullptr); ~PermissionModifyJob() override; + /** + * @brief Whether the request supports both My Drives and shared drives. + * + * Set to true by default as LibKGAPI supports Team Drives. + * + * @deprecated This parameter will only be effective until June 1, 2020. Afterwards all applications + * are assumed to support shared drives. + */ + KGAPIDRIVE_DEPRECATED bool supportsAllDrives() const; + + /** + * @brief Sets whether the request supports both My Drives and shared drives. + * + * Set to true by default as LibKGAPI supports Team Drives. + * + * @deprecated This parameter will only be effective until June 1, 2020. Afterwards all applications + * are assumed to support shared drives. + */ + KGAPIDRIVE_DEPRECATED void setSupportsAllDrives(bool supportsAllDrives); + protected: void start() override; KGAPI2::ObjectsList handleReplyWithItems(const QNetworkReply *reply, const QByteArray &rawData) override; private: class Private; Private *const d; friend class Private; }; } // namespace Drive } // namespace KGAPI2 #endif // KGAPI2_DRIVEPERMISSIONMODIFYJOB_H