diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -75,3 +75,4 @@ add_libkgapi2_test(drive filecopyjobtest) add_libkgapi2_test(drive filecreatejobtest) add_libkgapi2_test(drive filesearchquerytest) +add_libkgapi2_test(drive teamdrivefetchjobtest) diff --git a/autotests/drive/data/teamdrive.json b/autotests/drive/data/teamdrive.json new file mode 100644 --- /dev/null +++ b/autotests/drive/data/teamdrive.json @@ -0,0 +1,5 @@ +{ + "kind": "drive#teamDrive", + "id": "0APqEW6eViiMXUk9PVA", + "name": "First Team Drive" +} diff --git a/autotests/drive/data/teamdrive_fetch_request.txt b/autotests/drive/data/teamdrive_fetch_request.txt new file mode 100644 --- /dev/null +++ b/autotests/drive/data/teamdrive_fetch_request.txt @@ -0,0 +1 @@ +GET https://www.googleapis.com/drive/v2/teamdrives diff --git a/autotests/drive/data/teamdrive_fetch_response.txt b/autotests/drive/data/teamdrive_fetch_response.txt new file mode 100644 --- /dev/null +++ b/autotests/drive/data/teamdrive_fetch_response.txt @@ -0,0 +1,18 @@ +HTTP/1.1 200 OK +content-type: application/json; charset=UTF-8 + +{ + "kind": "drive#teamDriveList", + "items": [ + { + "kind": "drive#teamDrive", + "id": "0APqEW6eViiMXUk9PVA", + "name": "First Team Drive" + }, + { + "kind": "drive#teamDrive", + "id": "0ABDsFtYHWBtYUk9PVA", + "name": "Second Team Drive" + } + ] +} diff --git a/autotests/drive/drivetestutils.h b/autotests/drive/drivetestutils.h --- a/autotests/drive/drivetestutils.h +++ b/autotests/drive/drivetestutils.h @@ -26,6 +26,7 @@ KGAPI2::Drive::AboutPtr aboutFromFile(const QString &path); KGAPI2::Drive::ChangePtr changeFromFile(const QString &path); KGAPI2::Drive::FilePtr fileFromFile(const QString &path); +KGAPI2::Drive::TeamdrivePtr teamdriveFromFile(const QString &path); #endif diff --git a/autotests/drive/drivetestutils.cpp b/autotests/drive/drivetestutils.cpp --- a/autotests/drive/drivetestutils.cpp +++ b/autotests/drive/drivetestutils.cpp @@ -22,6 +22,7 @@ #include "about.h" #include "change.h" #include "file.h" +#include "teamdrive.h" #include "testutils.h" #include @@ -55,3 +56,13 @@ VERIFY_RET(file, {}); return file; } + +KGAPI2::Drive::TeamdrivePtr teamdriveFromFile(const QString &path) +{ + QFile f(path); + VERIFY_RET(f.open(QIODevice::ReadOnly), {}); + + auto teamdrive = KGAPI2::Drive::Teamdrive::fromJSON(f.readAll()); + VERIFY_RET(teamdrive, {}); + return teamdrive; +} diff --git a/autotests/drive/teamdrivefetchjobtest.cpp b/autotests/drive/teamdrivefetchjobtest.cpp new file mode 100644 --- /dev/null +++ b/autotests/drive/teamdrivefetchjobtest.cpp @@ -0,0 +1,75 @@ +/* + * 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 +#include + +#include "fakenetworkaccessmanagerfactory.h" +#include "testutils.h" +#include "drivetestutils.h" + +#include "types.h" +#include "teamdrivefetchjob.h" +#include "teamdrive.h" +#include "account.h" + +namespace { + static const QString MockValue = QStringLiteral("MockValue"); +} + +using namespace KGAPI2; + +Q_DECLARE_METATYPE(QList) + +class TeamdriveFetchJobTest : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void initTestCase() + { + NetworkAccessManagerFactory::setFactory(new FakeNetworkAccessManagerFactory); + } + + void testFetch() + { + FakeNetworkAccessManagerFactory::get()->setScenarios({ + scenarioFromFile(QFINDTESTDATA("data/teamdrive_fetch_request.txt"), + QFINDTESTDATA("data/teamdrive_fetch_response.txt")) + + }); + const auto teamdrive = teamdriveFromFile(QFINDTESTDATA("data/teamdrive.json")); + + auto account = AccountPtr::create(MockValue, MockValue); + auto job = new Drive::TeamdriveFetchJob(account, nullptr); + QVERIFY(execJob(job)); + const auto items = job->items(); + QCOMPARE(items.count(), 2); + const auto returnedTeamdrive = items.at(0).dynamicCast(); + QVERIFY(returnedTeamdrive); + QCOMPARE(*returnedTeamdrive, *teamdrive); + } +}; + +QTEST_GUILESS_MAIN(TeamdriveFetchJobTest) + +#include "teamdrivefetchjobtest.moc" + + + diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,2 +1,3 @@ add_subdirectory(contacts) +add_subdirectory(teamdrive) #add_subdirectory(staticmaps) diff --git a/examples/teamdrive/CMakeLists.txt b/examples/teamdrive/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/examples/teamdrive/CMakeLists.txt @@ -0,0 +1,23 @@ +kde_enable_exceptions() + +include_directories( + ${CMAKE_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src + ${CMAKE_BINARY_DIR} +) + +set(teamdrive_example_SRCS main.cpp mainwindow.cpp) +set(teamdrive_example_HDRS mainwindow.h) +qt5_wrap_ui(teamdrive_example_SRCS ui/main.ui) + +add_executable(teamdrive-example + ${teamdrive_example_SRCS} + ${teamdrive_example_HDRS_MOC} +) + +target_link_libraries(teamdrive-example + Qt5::Widgets + Qt5::Core + KF5::GAPICore + KF5::GAPIDrive +) diff --git a/examples/teamdrive/main.cpp b/examples/teamdrive/main.cpp new file mode 100644 --- /dev/null +++ b/examples/teamdrive/main.cpp @@ -0,0 +1,34 @@ +/* + 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 + +#include "mainwindow.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + MainWindow ex; + ex.show(); + + return app.exec(); +} diff --git a/examples/teamdrive/mainwindow.h b/examples/teamdrive/mainwindow.h new file mode 100644 --- /dev/null +++ b/examples/teamdrive/mainwindow.h @@ -0,0 +1,87 @@ +/* + 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); + + /** + * 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(); + + /** + * A specific contact in contact list has been selected. Sends a request + * to Google to retrieve full details about the specific contact + */ + void teamdriveSelected(); + + private: + Ui::MainWindow *m_ui; + + KGAPI2::AccountPtr m_account; + +}; + +#endif // MAINWINDOW_H diff --git a/examples/teamdrive/mainwindow.cpp b/examples/teamdrive/mainwindow.cpp new file mode 100644 --- /dev/null +++ b/examples/teamdrive/mainwindow.cpp @@ -0,0 +1,183 @@ +/* + 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 + +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->teamdriveListButton, &QAbstractButton::clicked, + this, &MainWindow::fetchTeamdriveList); + connect(m_ui->teamdriveList, &QListWidget::itemSelectionChanged, + this, &MainWindow::teamdriveSelected); +} + +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->authButton->setEnabled(false); +} + +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(); + + 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::teamdriveSelected() +{ + if (m_ui->teamdriveList->selectedItems().count() == 0) { + m_ui->teamdrivePreview->clear(); + return; + } + + const QString id = m_ui->teamdriveList->selectedItems().at(0)->data(Qt::UserRole).toString(); + + 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) */ + 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'); + } + + m_ui->teamdrivePreview->setText(text); +} diff --git a/examples/teamdrive/ui/main.ui b/examples/teamdrive/ui/main.ui new file mode 100644 --- /dev/null +++ b/examples/teamdrive/ui/main.ui @@ -0,0 +1,168 @@ + + + MainWindow + + + + 0 + 0 + 640 + 413 + + + + MainWindow + + + + + + + + + Authenticate + + + + + + + Not authenticated + + + + + + + + + Qt::Horizontal + + + + + + + false + + + Get Team Drive list + + + + + + + + + + + + 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 + 25 + + + + + File + + + + + + + + + Quit + + + + + + + + + actionQuit + activated() + MainWindow + close() + + + -1 + -1 + + + 319 + 206 + + + + + diff --git a/src/core/types.h b/src/core/types.h --- a/src/core/types.h +++ b/src/core/types.h @@ -115,6 +115,10 @@ typedef QSharedPointer RevisionPtr; typedef QList RevisionsList; +class Teamdrive; +typedef QSharedPointer TeamdrivePtr; +typedef QList TeamdrivesList; + class User; typedef QSharedPointer UserPtr; typedef QList UsersList; diff --git a/src/drive/CMakeLists.txt b/src/drive/CMakeLists.txt --- a/src/drive/CMakeLists.txt +++ b/src/drive/CMakeLists.txt @@ -38,6 +38,8 @@ revisiondeletejob.cpp revisionfetchjob.cpp revisionmodifyjob.cpp + teamdrive.cpp + teamdrivefetchjob.cpp user.cpp ../debug.cpp @@ -83,6 +85,8 @@ RevisionDeleteJob RevisionFetchJob RevisionModifyJob + Teamdrive + TeamdriveFetchJob User PREFIX KGAPI/Drive REQUIRED_HEADERS kgapidrive_HEADERS diff --git a/src/drive/driveservice.h b/src/drive/driveservice.h --- a/src/drive/driveservice.h +++ b/src/drive/driveservice.h @@ -116,6 +116,11 @@ KGAPIDRIVE_EXPORT QUrl modifyRevisionUrl(const QString &fileId, const QString &revisionId); + KGAPIDRIVE_EXPORT QUrl fetchTeamdriveUrl(const QString &teamdriveId); + + KGAPIDRIVE_EXPORT QUrl fetchTeamdrivesUrl(); + + } // namespace DriveService } // namespace KGAPI2 diff --git a/src/drive/driveservice.cpp b/src/drive/driveservice.cpp --- a/src/drive/driveservice.cpp +++ b/src/drive/driveservice.cpp @@ -34,6 +34,7 @@ static const QString AppsBasePath(QStringLiteral("/drive/v2/about")); static const QString FilesBasePath(QStringLiteral("/drive/v2/files")); static const QString ChangeBasePath(QStringLiteral("/drive/v2/changes")); + static const QString TeamdriveBasePath(QStringLiteral("/drive/v2/teamdrives")); } namespace DriveService @@ -286,6 +287,20 @@ return url; } +QUrl fetchTeamdriveUrl(const QString &teamdriveId) +{ + QUrl url(Private::GoogleApisUrl); + url.setPath(Private::TeamdriveBasePath % QLatin1Char('/') % teamdriveId); + return url; +} + +QUrl fetchTeamdrivesUrl() +{ + QUrl url(Private::GoogleApisUrl); + url.setPath(Private::TeamdriveBasePath); + return url; +} + } // namespace DriveService } // namespace KGAPI2 diff --git a/src/drive/teamdrive.h b/src/drive/teamdrive.h new file mode 100644 --- /dev/null +++ b/src/drive/teamdrive.h @@ -0,0 +1,342 @@ +/* + 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 LIBKGAPI2_DRIVETEAMDRIVE_H +#define LIBKGAPI2_DRIVETEAMDRIVE_H + +#include "types.h" +#include "object.h" +#include "kgapidrive_export.h" + +#include + +#include + +namespace KGAPI2 +{ + +namespace Drive +{ + +/** + * @brief Teamdrive contains a representation of a Team Drive. + * + * Getters and setters' documentation is based on Google Drive's API v2 reference + * @see Teamdrives + * + * @since x.0 + * @author David Barchiesi + */ +class KGAPIDRIVE_EXPORT Teamdrive: public KGAPI2::Object +{ + + public: + + /** + * @brief DriveTeamdrive::Restrictions holds the structure used for + * restrictions property. + */ + class Restrictions + { + + public: + Restrictions(); + Restrictions(const Restrictions &other); + ~Restrictions(); + bool operator==(const Restrictions &other) const; + bool operator!=(const Restrictions &other) const { return !operator==(other); } + + /** + * @brief Returns whether administrative privileges on this Team Drive + * are required to modify restrictions. + */ + bool adminManagedRestrictions() const; + + /** + * @brief Returns whether the options to copy, print, or download files + * inside this Team Drive, should be disabled for readers and commenters. + * When this restriction is set to true, it will override the similarly + * named field to true for any file inside this Team Drive. + */ + bool copyRequiresWriterPermission() const; + + /** + * @brief Returns whether access to this Team Drive and items inside this + * Team Drive is restricted to users of the domain to which this Team + * Drive belongs. This restriction may be overridden by other sharing + * policies controlled outside of this Team Drive. + */ + bool domainUsersOnly() const; + + /** + * @brief Returns whether access to items inside this Team Drive is + * restricted to members of this Team Drive. + */ + bool teamMembersOnly() const; + + private: + class Private; + QScopedPointer const d; + friend class Private; + friend class Teamdrive; + }; + + typedef QSharedPointer RestrictionsPtr; + + /** + * @brief DriveTeamdrive::Capabilities holds the structure used for capabilities property. + */ + class Capabilities + { + + public: + Capabilities(); + Capabilities(const Capabilities &other); + ~Capabilities(); + bool operator==(const Capabilities &other) const; + bool operator!=(const Capabilities &other) const { return !operator==(other); } + + /** + * @brief Returns whether the current user can add children to folders + * in this Team Drive. + */ + bool canAddChildren() const; + + /** + * @brief Returns whether the current user can change the + * copyRequiresWriterPermission restriction of this Team Drive. + */ + bool canChangeCopyRequiresWriterPermissionRestriction() const; + + /** + * @brief Returns whether the current user can change the domainUsersOnly + * restriction of this Team Drive. + */ + bool canChangeDomainUsersOnlyRestriction() const; + + /** + * @brief Returns whether the current user can change the background of + * this Team Drive. + */ + bool canChangeTeamDriveBackground() const; + + /** + * @brief Returns whether the current user can change the teamMembersOnly + * restriction of this Team Drive. + */ + bool canChangeTeamMembersOnlyRestriction() const; + + /** + * @brief Returns Whether the current user can comment on files in + * this Team Drive. + */ + bool canComment() const; + + /** + * @brief Returns Whether the current user can copy files in this Team Drive. + */ + bool canCopy() const; + + /** + * @brief Returns Whether the current user can delete children from + * folders in this Team Drive. + */ + bool canDeleteChildren() const; + + /** + * @brief Returns Whether the current user can delete this Team Drive. + * + * Attempting to delete the Team Drive may still fail if there are + * untrashed items inside the Team Drive. + */ + bool canDeleteTeamDrive() const; + + /** + * @brief Returns Whether the current user can download files in this + * Team Drive. + */ + bool canDownload() const; + + /** + * @brief Returns Whether the current user can edit files in this + * Team Drive + */ + bool canEdit() const; + + /** + * @brief Returns Whether the current user can list the children of + * folders in this Team Drive. + */ + bool canListChildren() const; + + /** + * @brief Returns Whether the current user can add members to this Team Drive + * or remove them or change their role. + */ + bool canManageMembers() const; + + /** + * @brief Returns Whether the current user can read the revisions + * resource of files in this Team Drive. + */ + bool canReadRevisions() const; + + /** + * @brief Returns Whether the current user can rename files or folders + * in this Team Drive. + */ + bool canRename() const; + + /** + * @brief Returns Whether the current user can rename this Team Drive. + */ + bool canRenameTeamDrive() const; + + /** + * @brief Returns Whether the current user can share files or folders + * in this Team Drive. + */ + bool canShare() const; + + /** + * @brief Returns Whether the current user can trash children from + * folders in this Team Drive. + */ + bool canTrashChildren() const; + + private: + class Private; + QScopedPointer const d; + friend class Private; + friend class Teamdrive; + }; + + typedef QSharedPointer CapabilitiesPtr; + + /** + * @brief DriveTeamdrive::BackgroundImageFile holds the structure used + * for backgroundImageFile property. + */ + class BackgroundImageFile + { + + public: + BackgroundImageFile(); + BackgroundImageFile(const BackgroundImageFile &other); + ~BackgroundImageFile(); + bool operator==(const BackgroundImageFile &other) const; + bool operator!=(const BackgroundImageFile &other) const { return !operator==(other); } + + /** + * @brief Returns the id of the background image file. + */ + QString id() const; + + /** + * @brief Returns the x coordinate for this background image file. + */ + float xCoordinate() const; + + /** + * @brief Returns the y coordinate for this background image file. + */ + float yCoordinate() const; + + /** + * @brief Returns the width for this background image file. + */ + float width() const; + + private: + class Private; + QScopedPointer const d; + friend class Private; + friend class Teamdrive; + }; + + typedef QSharedPointer BackgroundImageFilePtr; + + Teamdrive(); + Teamdrive(const Teamdrive &other); + ~Teamdrive() override; + bool operator==(const Teamdrive &other) const; + bool operator!=(const Teamdrive &other) const { return !operator==(other); } + + /** + * @brief Returns the id of the teamdrive. + */ + QString id() const; + + /** + * @brief Returns the name of the teamdrive. + */ + QString name() const; + + /** + * @brief Returns the themeId of the teamdrive. + */ + QString themeId() const; + + /** + * @brief Returns the colorRgb of the teamdrive. + */ + QString colorRgb() const; + + /** + * @brief Returns the image file and cropping parameters from which a background image for this Team Drive is set. + */ + BackgroundImageFilePtr backgroundImageFile() const; + + /** + * @brief Returns the backgroundImageLink of the teamdrive. + */ + QString backgroundImageLink() const; + + /** + * @brief Returns the capabilities the current user has on this Team Drive. + */ + CapabilitiesPtr capabilities() const; + + /** + * @brief Returns the time at which the Team Drive was created. + */ + QDateTime createdDate() const; + + /** + * @brief Returns the set of restrictions that apply to this Team Drive or + * items inside this Team Drive. + */ + RestrictionsPtr restrictions() const; + + static TeamdrivePtr fromJSON(const QByteArray &jsonData); + static TeamdrivesList fromJSONFeed(const QByteArray &jsonData, FeedData &feedData); + static QByteArray toJSON(const TeamdrivePtr &teamdrive); + + private: + class Private; + QScopedPointer const d; + friend class Private; +}; + +} /* namespace Drive */ + +} /* namespace KGAPI2 */ + +#endif // LIBKGAPI2_DRIVETEAMDRIVE_H diff --git a/src/drive/teamdrive.cpp b/src/drive/teamdrive.cpp new file mode 100644 --- /dev/null +++ b/src/drive/teamdrive.cpp @@ -0,0 +1,583 @@ +/* + 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 "driveservice.h" +#include "teamdrive.h" +#include "utils_p.h" + +#include +#include +#include + +namespace { + static const QString AdminManagedRestrictionsAttr = QStringLiteral("adminManagedRestrictions"); + static const QString BackgroundImageFileAttr = QStringLiteral("backgroundImageFile"); + static const QString BackgroundImageLinkAttr = QStringLiteral("backgroundImageLink"); + static const QString CanAddChildrenAttr = QStringLiteral("canAddChildren"); + static const QString CanChangeCopyRequiresWriterPermissionRestrictionAttr = QStringLiteral("canChangeCopyRequiresWriterPermissionRestriction"); + static const QString CanChangeDomainUsersOnlyRestrictionAttr = QStringLiteral("canChangeDomainUsersOnlyRestriction"); + static const QString CanChangeTeamDriveBackgroundAttr = QStringLiteral("canChangeTeamDriveBackground"); + static const QString CanChangeTeamMembersOnlyRestrictionAttr = QStringLiteral("canChangeTeamMembersOnlyRestriction"); + static const QString CanCommentAttr = QStringLiteral("canComment"); + static const QString CanCopyAttr = QStringLiteral("canCopy"); + static const QString CanDeleteChildrenAttr = QStringLiteral("canDeleteChildren"); + static const QString CanDeleteTeamDriveAttr = QStringLiteral("canDeleteTeamDrive"); + static const QString CanDownloadAttr = QStringLiteral("canDownload"); + static const QString CanEditAttr = QStringLiteral("canEdit"); + static const QString CanListChildrenAttr = QStringLiteral("canListChildren"); + static const QString CanManageMembersAttr = QStringLiteral("canManageMembers"); + static const QString CanReadRevisionsAttr = QStringLiteral("canReadRevisions"); + static const QString CanRenameAttr = QStringLiteral("canRename"); + static const QString CanRenameTeamDriveAttr = QStringLiteral("canRenameTeamDrive"); + static const QString CanShareAttr = QStringLiteral("canShare"); + static const QString CanTrashChildrenAttr = QStringLiteral("canTrashChildren"); + static const QString CapabilitiesAttr = QStringLiteral("capabilities"); + static const QString ColorRgbAttr = QStringLiteral("colorRgb"); + static const QString CopyRequiresWriterPermissionAttr = QStringLiteral("copyRequiresWriterPermission"); + static const QString CreatedDateAttr = QStringLiteral("createdDate"); + static const QString DomainUsersOnlyAttr = QStringLiteral("domainUsersOnly"); + static const QString IdAttr = QStringLiteral("id"); + static const QString ItemsAttr = QStringLiteral("items"); + static const QString KindAttr = QStringLiteral("kind"); + static const QString KindDriveAttr = QStringLiteral("kind"); + static const QString NameAttr = QStringLiteral("name"); + static const QString PageTokenAttr = QStringLiteral("pageToken"); + static const QString NextPageTokenAttr = QStringLiteral("nextPageToken"); + static const QString RestrictionsAttr = QStringLiteral("restrictions"); + static const QString TeamMembersOnlyAttr = QStringLiteral("teamMembersOnly"); + static const QString ThemeIdAttr = QStringLiteral("themeId"); + static const QString WidthAttr = QStringLiteral("width"); + static const QString XCoordinateAttr = QStringLiteral("xCoordinate"); + static const QString YCoordinateAttr = QStringLiteral("yCoordinate"); +} + +using namespace KGAPI2; +using namespace KGAPI2::Drive; + +///// DriveTeamdrive::Restrictions + +class Q_DECL_HIDDEN Teamdrive::Restrictions::Private +{ + public: + Private() = default; + Private(const Private &other) = default; + + bool adminManagedRestrictions = false; + bool copyRequiresWriterPermission = false; + bool domainUsersOnly = false; + bool teamMembersOnly = false; +}; + +Teamdrive::Restrictions::Restrictions(): + d(new Private) +{ +} + +Teamdrive::Restrictions::Restrictions(const Teamdrive::Restrictions &other): + d(new Private(*(other.d))) +{ +} + +Teamdrive::Restrictions::~Restrictions() = default; + +bool Teamdrive::Restrictions::operator==(const Teamdrive::Restrictions &other) const +{ + GAPI_COMPARE(adminManagedRestrictions); + GAPI_COMPARE(copyRequiresWriterPermission); + GAPI_COMPARE(domainUsersOnly); + GAPI_COMPARE(teamMembersOnly); + return true; +} + +bool Teamdrive::Restrictions::adminManagedRestrictions() const +{ + return d->adminManagedRestrictions; +} + +bool Teamdrive::Restrictions::copyRequiresWriterPermission() const +{ + return d->copyRequiresWriterPermission; +} + +bool Teamdrive::Restrictions::domainUsersOnly() const +{ + return d->domainUsersOnly; +} + +bool Teamdrive::Restrictions::teamMembersOnly() const +{ + return d->teamMembersOnly; +} + +///// DriveTeamdrive::Capabilities + +class Q_DECL_HIDDEN Teamdrive::Capabilities::Private +{ + public: + Private() = default; + Private(const Private &other) = default; + + bool canAddChildren = false; + bool canChangeCopyRequiresWriterPermissionRestriction = false; + bool canChangeDomainUsersOnlyRestriction = false; + bool canChangeTeamDriveBackground = false; + bool canChangeTeamMembersOnlyRestriction = false; + bool canComment = false; + bool canCopy = false; + bool canDeleteChildren = false; + bool canDeleteTeamDrive = false; + bool canDownload = false; + bool canEdit = false; + bool canListChildren = false; + bool canManageMembers = false; + bool canReadRevisions = false; + bool canRename = false; + bool canRenameTeamDrive = false; + bool canShare = false; + bool canTrashChildren = false; +}; + +Teamdrive::Capabilities::Capabilities(): + d(new Private) +{ +} + +Teamdrive::Capabilities::Capabilities(const Teamdrive::Capabilities &other): + d(new Private(*(other.d))) +{ +} + +Teamdrive::Capabilities::~Capabilities() = default; + +bool Teamdrive::Capabilities::operator==(const Teamdrive::Capabilities &other) const +{ + GAPI_COMPARE(canAddChildren); + GAPI_COMPARE(canChangeCopyRequiresWriterPermissionRestriction); + GAPI_COMPARE(canChangeDomainUsersOnlyRestriction); + GAPI_COMPARE(canChangeTeamDriveBackground); + GAPI_COMPARE(canChangeTeamMembersOnlyRestriction); + GAPI_COMPARE(canComment); + GAPI_COMPARE(canCopy); + GAPI_COMPARE(canDeleteChildren); + GAPI_COMPARE(canDeleteTeamDrive); + GAPI_COMPARE(canDownload); + GAPI_COMPARE(canEdit); + GAPI_COMPARE(canListChildren); + GAPI_COMPARE(canManageMembers); + GAPI_COMPARE(canReadRevisions); + GAPI_COMPARE(canRename); + GAPI_COMPARE(canRenameTeamDrive); + GAPI_COMPARE(canShare); + GAPI_COMPARE(canTrashChildren); + return true; +} + +bool Teamdrive::Capabilities::canAddChildren() const +{ + return d->canAddChildren; +} + +bool Teamdrive::Capabilities::canChangeCopyRequiresWriterPermissionRestriction() const +{ + return d->canChangeCopyRequiresWriterPermissionRestriction; +} + +bool Teamdrive::Capabilities::canChangeDomainUsersOnlyRestriction() const +{ + return d->canChangeDomainUsersOnlyRestriction; +} + +bool Teamdrive::Capabilities::canChangeTeamDriveBackground() const +{ + return d->canChangeTeamDriveBackground; +} + +bool Teamdrive::Capabilities::canChangeTeamMembersOnlyRestriction() const +{ + return d->canChangeTeamMembersOnlyRestriction; +} + +bool Teamdrive::Capabilities::canComment() const +{ + return d->canComment; +} + +bool Teamdrive::Capabilities::canCopy() const +{ + return d->canCopy; +} + +bool Teamdrive::Capabilities::canDeleteChildren() const +{ + return d->canDeleteChildren; +} + +bool Teamdrive::Capabilities::canDeleteTeamDrive() const +{ + return d->canDeleteTeamDrive; +} + +bool Teamdrive::Capabilities::canDownload() const +{ + return d->canDownload; +} + +bool Teamdrive::Capabilities::canEdit() const +{ + return d->canEdit; +} + +bool Teamdrive::Capabilities::canListChildren() const +{ + return d->canListChildren; +} + +bool Teamdrive::Capabilities::canManageMembers() const +{ + return d->canManageMembers; +} + +bool Teamdrive::Capabilities::canReadRevisions() const +{ + return d->canReadRevisions; +} + +bool Teamdrive::Capabilities::canRename() const +{ + return d->canRename; +} + +bool Teamdrive::Capabilities::canRenameTeamDrive() const +{ + return d->canRenameTeamDrive; +} + +bool Teamdrive::Capabilities::canShare() const +{ + return d->canShare; +} + +bool Teamdrive::Capabilities::canTrashChildren() const +{ + return d->canTrashChildren; +} + +///// DriveTeamdrive::BackgroundImageFile + +class Q_DECL_HIDDEN Teamdrive::BackgroundImageFile::Private +{ + public: + Private() = default; + Private(const Private &other) = default; + + QString id; + float xCoordinate = 0.0f; + float yCoordinate = 0.0f; + float width = 0.0f; +}; + +Teamdrive::BackgroundImageFile::BackgroundImageFile(): + d(new Private) +{ +} + +Teamdrive::BackgroundImageFile::BackgroundImageFile(const Teamdrive::BackgroundImageFile &other): + d(new Private(*(other.d))) +{ +} + +Teamdrive::BackgroundImageFile::~BackgroundImageFile() = default; + +bool Teamdrive::BackgroundImageFile::operator==(const Teamdrive::BackgroundImageFile &other) const +{ + GAPI_COMPARE(id); + GAPI_COMPARE(xCoordinate); + GAPI_COMPARE(yCoordinate); + GAPI_COMPARE(width); + return true; +} + +QString Teamdrive::BackgroundImageFile::id() const +{ + return d->id; +} + +float Teamdrive::BackgroundImageFile::xCoordinate() const +{ + return d->xCoordinate; +} + +float Teamdrive::BackgroundImageFile::yCoordinate() const +{ + return d->yCoordinate; +} + +float Teamdrive::BackgroundImageFile::width() const +{ + return d->width; +} + +///// DriveTeamdrive + +class Q_DECL_HIDDEN Teamdrive::Private +{ + public: + Private() = default; + Private(const Private& other) = default; + + QString id; + QString name; + QString themeId; + QString colorRgb; + BackgroundImageFilePtr backgroundImageFile; + QString backgroundImageLink; + CapabilitiesPtr capabilities; + QDateTime createdDate; + RestrictionsPtr restrictions; + + static TeamdrivePtr fromJSON(const QVariantMap &map); +}; + +TeamdrivePtr Teamdrive::Private::fromJSON(const QVariantMap &map) +{ + if (!map.contains(KindAttr) || + map[KindAttr].toString() != QLatin1String("drive#teamDrive")) + { + return TeamdrivePtr(); + } + + auto teamdrive = TeamdrivePtr::create(); + teamdrive->d->id = map[IdAttr].toString(); + teamdrive->d->name = map[NameAttr].toString(); + teamdrive->d->themeId = map[ThemeIdAttr].toString(); + teamdrive->d->colorRgb = map[ColorRgbAttr].toString(); + teamdrive->d->backgroundImageLink = map[BackgroundImageLinkAttr].toString(); + teamdrive->d->createdDate = QDateTime::fromString(map[CreatedDateAttr].toString(), Qt::ISODate); + + const QVariantMap backgroundImageFileMap = map[BackgroundImageFileAttr].toMap(); + auto backgroundImageFile = BackgroundImageFilePtr::create(); + backgroundImageFile->d->id = backgroundImageFileMap[IdAttr].toString(); + backgroundImageFile->d->xCoordinate = backgroundImageFileMap[XCoordinateAttr].toReal(); + backgroundImageFile->d->yCoordinate = backgroundImageFileMap[YCoordinateAttr].toReal(); + backgroundImageFile->d->width = backgroundImageFileMap[WidthAttr].toReal(); + teamdrive->d->backgroundImageFile = backgroundImageFile; + + const QVariantMap capabilitiesMap = map[CapabilitiesAttr].toMap(); + auto capabilities = CapabilitiesPtr::create(); + capabilities->d->canAddChildren = capabilitiesMap[CanAddChildrenAttr].toBool(); + capabilities->d->canChangeCopyRequiresWriterPermissionRestriction = capabilitiesMap[CanChangeCopyRequiresWriterPermissionRestrictionAttr].toBool(); + capabilities->d->canChangeDomainUsersOnlyRestriction = capabilitiesMap[CanChangeDomainUsersOnlyRestrictionAttr].toBool(); + capabilities->d->canChangeTeamDriveBackground = capabilitiesMap[CanChangeTeamDriveBackgroundAttr].toBool(); + capabilities->d->canChangeTeamMembersOnlyRestriction = capabilitiesMap[CanChangeTeamMembersOnlyRestrictionAttr].toBool(); + capabilities->d->canComment = capabilitiesMap[CanCommentAttr].toBool(); + capabilities->d->canCopy = capabilitiesMap[CanCopyAttr].toBool(); + capabilities->d->canDeleteChildren = capabilitiesMap[CanDeleteChildrenAttr].toBool(); + capabilities->d->canDeleteTeamDrive = capabilitiesMap[CanDeleteTeamDriveAttr].toBool(); + capabilities->d->canDownload = capabilitiesMap[CanDownloadAttr].toBool(); + capabilities->d->canEdit = capabilitiesMap[CanEditAttr].toBool(); + capabilities->d->canListChildren = capabilitiesMap[CanListChildrenAttr].toBool(); + capabilities->d->canManageMembers = capabilitiesMap[CanManageMembersAttr].toBool(); + capabilities->d->canReadRevisions = capabilitiesMap[CanReadRevisionsAttr].toBool(); + capabilities->d->canRename = capabilitiesMap[CanRenameAttr].toBool(); + capabilities->d->canRenameTeamDrive = capabilitiesMap[CanRenameTeamDriveAttr].toBool(); + capabilities->d->canShare = capabilitiesMap[CanShareAttr].toBool(); + capabilities->d->canTrashChildren = capabilitiesMap[CanTrashChildrenAttr].toBool(); + teamdrive->d->capabilities = capabilities; + + const QVariantMap restrictionsMap = map[RestrictionsAttr].toMap(); + auto restrictions = RestrictionsPtr::create(); + restrictions->d->adminManagedRestrictions = restrictionsMap[AdminManagedRestrictionsAttr].toBool(); + restrictions->d->copyRequiresWriterPermission = restrictionsMap[CopyRequiresWriterPermissionAttr].toBool(); + restrictions->d->domainUsersOnly = restrictionsMap[DomainUsersOnlyAttr].toBool(); + restrictions->d->teamMembersOnly = restrictionsMap[TeamMembersOnlyAttr].toBool(); + teamdrive->d->restrictions = restrictions; + + return teamdrive; +} + +Teamdrive::Teamdrive(): + KGAPI2::Object(), + d(new Private) +{ +} + +Teamdrive::Teamdrive(const Teamdrive& other): + KGAPI2::Object(other), + d(new Private(*(other.d))) +{ +} + +Teamdrive::~Teamdrive() = default; + +bool Teamdrive::operator==(const Teamdrive &other) const +{ + if (!Object::operator==(other)) { + return false; + } + GAPI_COMPARE(id); + GAPI_COMPARE(name); + GAPI_COMPARE(themeId); + GAPI_COMPARE(colorRgb); + GAPI_COMPARE_SHAREDPTRS(backgroundImageFile); + GAPI_COMPARE(backgroundImageLink); + GAPI_COMPARE_SHAREDPTRS(capabilities); + GAPI_COMPARE(createdDate); + GAPI_COMPARE_SHAREDPTRS(restrictions); + return true; +} + +QString Teamdrive::id() const +{ + return d->id; +} + +QString Teamdrive::name() const +{ + return d->name; +} + +QString Teamdrive::themeId() const +{ + return d->themeId; +} + +QString Teamdrive::colorRgb() const +{ + return d->colorRgb; +} + +Teamdrive::BackgroundImageFilePtr Teamdrive::backgroundImageFile() const +{ + return d->backgroundImageFile; +} + +QString Teamdrive::backgroundImageLink() const +{ + return d->backgroundImageLink; +} + +Teamdrive::CapabilitiesPtr Teamdrive::capabilities() const +{ + return d->capabilities; +} + +QDateTime Teamdrive::createdDate() const +{ + return d->createdDate; +} + +Teamdrive::RestrictionsPtr Teamdrive::restrictions() const +{ + return d->restrictions; +} + +TeamdrivePtr Teamdrive::fromJSON(const QByteArray &jsonData) +{ + QJsonDocument document = QJsonDocument::fromJson(jsonData); + if (document.isNull()) { + return TeamdrivePtr(); + } + + const QVariant data = document.toVariant(); + return Private::fromJSON(data.toMap()); +} + +TeamdrivesList Teamdrive::fromJSONFeed(const QByteArray &jsonData, FeedData &feedData) +{ + QJsonDocument document = QJsonDocument::fromJson(jsonData); + if (document.isNull()) { + return TeamdrivesList(); + } + + const QVariant data = document.toVariant(); + const QVariantMap map = data.toMap(); + if (!map.contains(KindAttr) || + map[KindAttr].toString() != QLatin1String("drive#teamDriveList")) { + return TeamdrivesList(); + } + + if (map.contains(NextPageTokenAttr)) { + feedData.nextPageUrl = DriveService::fetchTeamdrivesUrl(); + QUrlQuery query(feedData.nextPageUrl); + query.addQueryItem(PageTokenAttr, map.value(NextPageTokenAttr).toString()); + feedData.nextPageUrl.setQuery(query); + } + + TeamdrivesList list; + const QVariantList items = map[ItemsAttr].toList(); + for (const QVariant & item : items) { + const TeamdrivePtr teamdrive = Private::fromJSON(item.toMap()); + + if (!teamdrive.isNull()) { + list << teamdrive; + } + } + + return list; +} + +QByteArray Teamdrive::toJSON(const TeamdrivePtr &teamdrive) +{ + QVariantMap teamDriveMap; + teamDriveMap[IdAttr] = teamdrive->id(); + teamDriveMap[NameAttr] = teamdrive->name(); + teamDriveMap[ThemeIdAttr] = teamdrive->themeId(); + teamDriveMap[ColorRgbAttr] = teamdrive->colorRgb(); + teamDriveMap[BackgroundImageLinkAttr] = teamdrive->backgroundImageLink(); + teamDriveMap[CreatedDateAttr] = teamdrive->createdDate(); + + QVariantMap restrictionsMap; + restrictionsMap[AdminManagedRestrictionsAttr] = teamdrive->restrictions()->adminManagedRestrictions(); + restrictionsMap[CopyRequiresWriterPermissionAttr] = teamdrive->restrictions()->copyRequiresWriterPermission(); + restrictionsMap[DomainUsersOnlyAttr] = teamdrive->restrictions()->domainUsersOnly(); + restrictionsMap[TeamMembersOnlyAttr] = teamdrive->restrictions()->teamMembersOnly(); + teamDriveMap[RestrictionsAttr] = restrictionsMap; + + QVariantMap backgroundImageFileMap; + backgroundImageFileMap[IdAttr] = teamdrive->backgroundImageFile()->id(); + backgroundImageFileMap[XCoordinateAttr] = teamdrive->backgroundImageFile()->xCoordinate(); + backgroundImageFileMap[YCoordinateAttr] = teamdrive->backgroundImageFile()->yCoordinate(); + backgroundImageFileMap[WidthAttr] = teamdrive->backgroundImageFile()->width(); + teamDriveMap[BackgroundImageFileAttr] = backgroundImageFileMap; + + QVariantMap capabilitiesMap; + capabilitiesMap[CanAddChildrenAttr] = teamdrive->capabilities()->canAddChildren(); + capabilitiesMap[CanChangeCopyRequiresWriterPermissionRestrictionAttr] = teamdrive->capabilities()->canChangeCopyRequiresWriterPermissionRestriction(); + capabilitiesMap[CanChangeDomainUsersOnlyRestrictionAttr] = teamdrive->capabilities()->canChangeDomainUsersOnlyRestriction(); + capabilitiesMap[CanChangeTeamDriveBackgroundAttr] = teamdrive->capabilities()->canChangeTeamDriveBackground(); + capabilitiesMap[CanChangeTeamMembersOnlyRestrictionAttr] = teamdrive->capabilities()->canChangeTeamMembersOnlyRestriction(); + capabilitiesMap[CanCommentAttr] = teamdrive->capabilities()->canComment(); + capabilitiesMap[CanCopyAttr] = teamdrive->capabilities()->canCopy(); + capabilitiesMap[CanDeleteChildrenAttr] = teamdrive->capabilities()->canDeleteChildren(); + capabilitiesMap[CanDeleteTeamDriveAttr] = teamdrive->capabilities()->canDeleteTeamDrive(); + capabilitiesMap[CanDownloadAttr] = teamdrive->capabilities()->canDownload(); + capabilitiesMap[CanEditAttr] = teamdrive->capabilities()->canEdit(); + capabilitiesMap[CanListChildrenAttr] = teamdrive->capabilities()->canListChildren(); + capabilitiesMap[CanManageMembersAttr] = teamdrive->capabilities()->canManageMembers(); + capabilitiesMap[CanReadRevisionsAttr] = teamdrive->capabilities()->canReadRevisions(); + capabilitiesMap[CanRenameAttr] = teamdrive->capabilities()->canRename(); + capabilitiesMap[CanRenameTeamDriveAttr] = teamdrive->capabilities()->canRenameTeamDrive(); + capabilitiesMap[CanShareAttr] = teamdrive->capabilities()->canShare(); + capabilitiesMap[CanTrashChildrenAttr] = teamdrive->capabilities()->canTrashChildren(); + teamDriveMap[CapabilitiesAttr] = capabilitiesMap; + + QJsonDocument document = QJsonDocument::fromVariant(teamDriveMap); + return document.toJson(QJsonDocument::Compact); +} diff --git a/src/drive/teamdrivefetchjob.h b/src/drive/teamdrivefetchjob.h new file mode 100644 --- /dev/null +++ b/src/drive/teamdrivefetchjob.h @@ -0,0 +1,94 @@ +/* + * This file is part of LibKGAPI library + * + * 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 KGAPI2_DRIVETEAMDRIVEFETCHJOB_H +#define KGAPI2_DRIVETEAMDRIVEFETCHJOB_H + +#include "fetchjob.h" +#include "kgapidrive_export.h" + +namespace KGAPI2 +{ + +namespace Drive +{ + +class KGAPIDRIVE_EXPORT TeamdriveFetchJob : public KGAPI2::FetchJob +{ + Q_OBJECT + + /** + * Maximum number of teamdrives to return. + * + * Default value if missing is 10. + * + * 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) + + /** + * Issue the request as a domain administrator; if set to true, then all + * Team Drives of the domain in which the requester is an administrator + * are returned. + * + * Default value if missing is false. + * + * 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 useDomainAdminAccess + READ useDomainAdminAccess + WRITE setUseDomainAdminAccess) + + public: + TeamdriveFetchJob(const AccountPtr &account, QObject *parent = nullptr); + TeamdriveFetchJob(const QString &teamdriveId, const AccountPtr &account, + QObject *parent = nullptr); + ~TeamdriveFetchJob() override; + + int maxResults() const; + void setMaxResults(int maxResults); + + void setUseDomainAdminAccess(bool useDomainAdminAccess); + bool useDomainAdminAccess() const; + + protected: + void start() override; + KGAPI2::ObjectsList handleReplyWithItems(const QNetworkReply *reply, + const QByteArray &rawData) override; + + private: + class Private; + QScopedPointer d; + friend class Private; + + void applyRequestParameters(QUrl &url); +}; + +} // namespace Drive + +} // namespace KGAPI2 + +#endif // KGAPI2_DRIVETEAMDRIVEFETCHJOB_H diff --git a/src/drive/teamdrivefetchjob.cpp b/src/drive/teamdrivefetchjob.cpp new file mode 100644 --- /dev/null +++ b/src/drive/teamdrivefetchjob.cpp @@ -0,0 +1,179 @@ +/* + * This file is part of LibKGAPI library + * + * 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 "teamdrivefetchjob.h" +#include "account.h" +#include "teamdrive.h" +#include "../debug.h" +#include "driveservice.h" +#include "utils.h" + +#include +#include +#include + +namespace { + static const QString MaxResultsAttr = QStringLiteral("maxResults"); + static const QString UseDomainAdminAccessAttr = QStringLiteral("useDomainAdminAccess"); + static const QString True = QStringLiteral("true"); + static const QString False = QStringLiteral("false"); +} +using namespace KGAPI2; +using namespace KGAPI2::Drive; + +class Q_DECL_HIDDEN TeamdriveFetchJob::Private +{ + public: + Private(TeamdriveFetchJob *parent); + QNetworkRequest createRequest(const QUrl &url); + + QString teamdriveId; + + int maxResults = 0; + bool useDomainAdminAccess = false; + + private: + TeamdriveFetchJob *const q; +}; + +TeamdriveFetchJob::Private::Private(TeamdriveFetchJob *parent): + q(parent) +{ +} + +QNetworkRequest TeamdriveFetchJob::Private::createRequest(const QUrl &url) +{ + QNetworkRequest request; + request.setRawHeader("Authorization", "Bearer " + q->account()->accessToken().toLatin1()); + request.setUrl(url); + + return request; +} + + +TeamdriveFetchJob::TeamdriveFetchJob(const QString &teamdriveId, + const AccountPtr &account, + QObject *parent): + FetchJob(account, parent), + d(new Private(this)) +{ + d->teamdriveId = teamdriveId; +} + +TeamdriveFetchJob::TeamdriveFetchJob(const AccountPtr &account, QObject *parent): + FetchJob(account, parent), + d(new Private(this)) +{ +} + +TeamdriveFetchJob::~TeamdriveFetchJob() = default; + +void TeamdriveFetchJob::setMaxResults(int maxResults) +{ + if (isRunning()) { + qCWarning(KGAPIDebug) << "Can't modify maxResults property when job is running"; + return; + } + + d->maxResults = maxResults; +} + +int TeamdriveFetchJob::maxResults() const +{ + return d->maxResults; +} + +void TeamdriveFetchJob::setUseDomainAdminAccess(bool useDomainAdminAccess) +{ + if (isRunning()) { + qCWarning(KGAPIDebug) << "Can't modify useDomainAdminAccess property when job is running"; + return; + } + + d->useDomainAdminAccess = useDomainAdminAccess; +} + +bool TeamdriveFetchJob::useDomainAdminAccess() const +{ + return d->useDomainAdminAccess; +} + +void TeamdriveFetchJob::start() +{ + QUrl url; + if (d->teamdriveId.isEmpty()) { + url = DriveService::fetchTeamdrivesUrl(); + applyRequestParameters(url); + } else { + url = DriveService::fetchTeamdriveUrl(d->teamdriveId); + } + + const QNetworkRequest request = d->createRequest(url); + enqueueRequest(request); +} + + +ObjectsList TeamdriveFetchJob::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->teamdriveId.isEmpty()) { + items << Teamdrive::fromJSONFeed(rawData, feedData); + } else { + items << Teamdrive::fromJSON(rawData); + } + } else { + setError(KGAPI2::InvalidResponse); + setErrorString(tr("Invalid response content type")); + emitFinished(); + return items; + } + + if (feedData.nextPageUrl.isValid()) { + // Reapply query options + applyRequestParameters(feedData.nextPageUrl); + const QNetworkRequest request = d->createRequest(feedData.nextPageUrl); + enqueueRequest(request); + } + + return items; +} + + +void TeamdriveFetchJob::applyRequestParameters(QUrl &url) { + QUrlQuery query(url); + if (d->maxResults != 0) { + query.addQueryItem(MaxResultsAttr, QString::number(d->maxResults)); + } + if (d->useDomainAdminAccess != false) { + query.addQueryItem(UseDomainAdminAccessAttr, d->useDomainAdminAccess ? True : False); + } + url.setQuery(query); +}