diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -10,6 +10,16 @@ fakenetworkaccessmanagerfactory.cpp testutils.cpp ) + +# Silence deprecation warnings for deprecated APIs tests. +set_source_files_properties( + drive/teamdrivecreatejobtest.cpp + drive/teamdrivedeletejobtest.cpp + drive/teamdrivefetchjobtest.cpp + drive/teamdrivemodifyjobtest.cpp + PROPERTIES COMPILE_FLAGS -Wno-deprecated-declarations +) + add_library(kgapitest STATIC ${kgapitest_SRCS}) target_link_libraries(kgapitest Qt5::Core Qt5::Network Qt5::Test KPimGAPICore) @@ -75,6 +85,12 @@ add_libkgapi2_test(drive filecopyjobtest) add_libkgapi2_test(drive filecreatejobtest) add_libkgapi2_test(drive filesearchquerytest) +add_libkgapi2_test(drive drivescreatejobtest) +add_libkgapi2_test(drive drivesdeletejobtest) +add_libkgapi2_test(drive drivesmodifyjobtest) +add_libkgapi2_test(drive driveshidejobtest) +add_libkgapi2_test(drive drivesfetchjobtest) +add_libkgapi2_test(drive drivessearchquerytest) add_libkgapi2_test(drive teamdrivecreatejobtest) add_libkgapi2_test(drive teamdrivedeletejobtest) add_libkgapi2_test(drive teamdrivemodifyjobtest) diff --git a/autotests/drive/data/drives.json b/autotests/drive/data/drives.json new file mode 100644 --- /dev/null +++ b/autotests/drive/data/drives.json @@ -0,0 +1,5 @@ +{ + "kind": "drive#drive", + "id": "somelongid", + "name": "A Drive" +} diff --git a/autotests/drive/data/drives_create_request.txt b/autotests/drive/data/drives_create_request.txt new file mode 100644 --- /dev/null +++ b/autotests/drive/data/drives_create_request.txt @@ -0,0 +1,8 @@ +POST https://www.googleapis.com/drive/v2/drives?requestId=MockRequestId&prettyPrint=false + +{ + "kind": "drive#drive", + "id": "somelongid", + "name": "A Drive", + "hidden": false +} diff --git a/autotests/drive/data/drives_create_response.txt b/autotests/drive/data/drives_create_response.txt new file mode 100644 --- /dev/null +++ b/autotests/drive/data/drives_create_response.txt @@ -0,0 +1,8 @@ +HTTP/1.1 200 OK +content-type: application/json; charset=UTF-8 + +{ + "kind": "drive#drive", + "id": "somelongid", + "name": "A Drive" +} diff --git a/autotests/drive/data/drives_delete_request.txt b/autotests/drive/data/drives_delete_request.txt new file mode 100644 --- /dev/null +++ b/autotests/drive/data/drives_delete_request.txt @@ -0,0 +1 @@ +DELETE https://www.googleapis.com/drive/v2/drives/somelongid diff --git a/autotests/drive/data/drives_fetch_request.txt b/autotests/drive/data/drives_fetch_request.txt new file mode 100644 --- /dev/null +++ b/autotests/drive/data/drives_fetch_request.txt @@ -0,0 +1 @@ +GET https://www.googleapis.com/drive/v2/drives?prettyPrint=false diff --git a/autotests/drive/data/drives_fetch_response.txt b/autotests/drive/data/drives_fetch_response.txt new file mode 100644 --- /dev/null +++ b/autotests/drive/data/drives_fetch_response.txt @@ -0,0 +1,18 @@ +HTTP/1.1 200 OK +content-type: application/json; charset=UTF-8 + +{ + "kind": "drive#driveList", + "items": [ + { + "kind": "drive#drive", + "id": "somelongid", + "name": "A Drive" + }, + { + "kind": "drive#drive", + "id": "anotherlongid", + "name": "Second Drive" + } + ] +} diff --git a/autotests/drive/data/drives_hide_request.txt b/autotests/drive/data/drives_hide_request.txt new file mode 100644 --- /dev/null +++ b/autotests/drive/data/drives_hide_request.txt @@ -0,0 +1 @@ +POST https://www.googleapis.com/drive/v2/drives/somelongid/hide?prettyPrint=false diff --git a/autotests/drive/data/drives_hide_response.txt b/autotests/drive/data/drives_hide_response.txt new file mode 100644 --- /dev/null +++ b/autotests/drive/data/drives_hide_response.txt @@ -0,0 +1,8 @@ +HTTP/1.1 200 OK +content-type: application/json; charset=UTF-8 + +{ + "kind": "drive#drive", + "id": "somelongid", + "name": "A Drive" +} diff --git a/autotests/drive/data/drives_modify_request.txt b/autotests/drive/data/drives_modify_request.txt new file mode 100644 --- /dev/null +++ b/autotests/drive/data/drives_modify_request.txt @@ -0,0 +1,8 @@ +POST https://www.googleapis.com/drive/v2/drives/somelongid?prettyPrint=false + +{ + "kind": "drive#drive", + "id": "somelongid", + "name": "Renamed Drive", + "hidden": false +} diff --git a/autotests/drive/data/drives_modify_response.txt b/autotests/drive/data/drives_modify_response.txt new file mode 100644 --- /dev/null +++ b/autotests/drive/data/drives_modify_response.txt @@ -0,0 +1,8 @@ +HTTP/1.1 200 OK +content-type: application/json; charset=UTF-8 + +{ + "kind": "drive#drive", + "id": "somelongid", + "name": "Renamed Drive" +} diff --git a/autotests/drive/drivescreatejobtest.cpp b/autotests/drive/drivescreatejobtest.cpp new file mode 100644 --- /dev/null +++ b/autotests/drive/drivescreatejobtest.cpp @@ -0,0 +1,92 @@ +/* + * 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 "drivescreatejob.h" +#include "drives.h" +#include "account.h" + +using namespace KGAPI2; + +Q_DECLARE_METATYPE(QList) +Q_DECLARE_METATYPE(KGAPI2::Drive::DrivesPtr) + +class DrivesCreateJobTest : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void initTestCase() + { + NetworkAccessManagerFactory::setFactory(new FakeNetworkAccessManagerFactory); + } + + void testCreate_data() + { + QTest::addColumn>("scenarios"); + QTest::addColumn("sourceDrives"); + QTest::addColumn("requestId"); + QTest::addColumn("expectedResult"); + + QTest::newRow("metadata only") + << QList{ + scenarioFromFile(QFINDTESTDATA("data/drives_create_request.txt"), + QFINDTESTDATA("data/drives_create_response.txt")) + } + << drivesFromFile(QFINDTESTDATA("data/drives.json")) + << QStringLiteral("MockRequestId") + << drivesFromFile(QFINDTESTDATA("data/drives.json")); + } + + void testCreate() + { + QFETCH(QList, scenarios); + QFETCH(Drive::DrivesPtr, sourceDrives); + QFETCH(QString, requestId); + QFETCH(Drive::DrivesPtr, expectedResult); + + FakeNetworkAccessManagerFactory::get()->setScenarios(scenarios); + + auto account = AccountPtr::create(QStringLiteral("MockAccount"), QStringLiteral("MockToken")); + Drive::DrivesCreateJob *job = new Drive::DrivesCreateJob(requestId, sourceDrives, account); + + QVERIFY(execJob(job)); + const auto items = job->items(); + QCOMPARE(items.count(), 1); + QVERIFY(*items.cbegin()); + QCOMPARE(**items.cbegin(), *expectedResult); + QCOMPARE(requestId, job->requestId()); + } +}; + +QTEST_GUILESS_MAIN(DrivesCreateJobTest) + +#include "drivescreatejobtest.moc" + + + + + diff --git a/autotests/drive/drivesdeletejobtest.cpp b/autotests/drive/drivesdeletejobtest.cpp new file mode 100644 --- /dev/null +++ b/autotests/drive/drivesdeletejobtest.cpp @@ -0,0 +1,80 @@ +/* + * 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 "types.h" +#include "drivesdeletejob.h" +#include "drives.h" +#include "account.h" + +using namespace KGAPI2; + +Q_DECLARE_METATYPE(QList) +Q_DECLARE_METATYPE(KGAPI2::Drive::DrivesPtr) + +class DrivesDeleteJobTest : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void initTestCase() + { + NetworkAccessManagerFactory::setFactory(new FakeNetworkAccessManagerFactory); + } + + void testDelete_data() + { + QTest::addColumn>("scenarios"); + QTest::addColumn("drivesId"); + + QTest::newRow("metadata only") + << QList{ + scenarioFromFile(QFINDTESTDATA("data/drives_delete_request.txt"), + QFINDTESTDATA("data/generic_no_content_response.txt")) + } + << QStringLiteral("somelongid"); + } + + void testDelete() + { + QFETCH(QList, scenarios); + QFETCH(QString, drivesId); + + FakeNetworkAccessManagerFactory::get()->setScenarios(scenarios); + + auto account = AccountPtr::create(QStringLiteral("MockAccount"), QStringLiteral("MockToken")); + Drive::DrivesDeleteJob *job = new Drive::DrivesDeleteJob(drivesId, account); + + QVERIFY(execJob(job)); + } +}; + +QTEST_GUILESS_MAIN(DrivesDeleteJobTest) + +#include "drivesdeletejobtest.moc" + + + + + diff --git a/autotests/drive/drivesfetchjobtest.cpp b/autotests/drive/drivesfetchjobtest.cpp new file mode 100644 --- /dev/null +++ b/autotests/drive/drivesfetchjobtest.cpp @@ -0,0 +1,72 @@ +/* + * 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 "drivesfetchjob.h" +#include "drives.h" +#include "account.h" + +namespace { + static const QString MockValue = QStringLiteral("MockValue"); +} + +using namespace KGAPI2; + +Q_DECLARE_METATYPE(QList) + +class DrivesFetchJobTest : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void initTestCase() + { + NetworkAccessManagerFactory::setFactory(new FakeNetworkAccessManagerFactory); + } + + void testFetch() + { + FakeNetworkAccessManagerFactory::get()->setScenarios({ + scenarioFromFile(QFINDTESTDATA("data/drives_fetch_request.txt"), + QFINDTESTDATA("data/drives_fetch_response.txt")) + + }); + const auto drive = drivesFromFile(QFINDTESTDATA("data/drives.json")); + + auto account = AccountPtr::create(MockValue, MockValue); + auto job = new Drive::DrivesFetchJob(account, nullptr); + QVERIFY(execJob(job)); + const auto items = job->items(); + QCOMPARE(items.count(), 2); + const auto returnedDrives = items.at(0).dynamicCast(); + QVERIFY(returnedDrives); + QCOMPARE(*returnedDrives, *drive); + } +}; + +QTEST_GUILESS_MAIN(DrivesFetchJobTest) + +#include "drivesfetchjobtest.moc" diff --git a/autotests/drive/driveshidejobtest.cpp b/autotests/drive/driveshidejobtest.cpp new file mode 100644 --- /dev/null +++ b/autotests/drive/driveshidejobtest.cpp @@ -0,0 +1,88 @@ +/* + * 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 "driveshidejob.h" +#include "drives.h" +#include "account.h" + +using namespace KGAPI2; + +Q_DECLARE_METATYPE(QList) +Q_DECLARE_METATYPE(KGAPI2::Drive::DrivesPtr) + +class DrivesHideJobTest : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void initTestCase() + { + NetworkAccessManagerFactory::setFactory(new FakeNetworkAccessManagerFactory); + } + + void testHide_data() + { + QTest::addColumn>("scenarios"); + QTest::addColumn("sourceDrive"); + QTest::addColumn("expectedResult"); + + QTest::newRow("metadata only") + << QList{ + scenarioFromFile(QFINDTESTDATA("data/drives_hide_request.txt"), + QFINDTESTDATA("data/drives_hide_response.txt")) + } + << drivesFromFile(QFINDTESTDATA("data/drives.json")) + << drivesFromFile(QFINDTESTDATA("data/drives.json")); + } + + void testHide() + { + QFETCH(QList, scenarios); + QFETCH(Drive::DrivesPtr, sourceDrive); + QFETCH(Drive::DrivesPtr, expectedResult); + + FakeNetworkAccessManagerFactory::get()->setScenarios(scenarios); + + auto account = AccountPtr::create(QStringLiteral("MockAccount"), QStringLiteral("MockToken")); + Drive::DrivesHideJob *job = new Drive::DrivesHideJob(sourceDrive, true, account); + + QVERIFY(execJob(job)); + const auto items = job->items(); + QCOMPARE(items.count(), 1); + QVERIFY(*items.cbegin()); + QCOMPARE(**items.cbegin(), *expectedResult); + } +}; + +QTEST_GUILESS_MAIN(DrivesHideJobTest) + +#include "driveshidejobtest.moc" + + + + + diff --git a/autotests/drive/drivesmodifyjobtest.cpp b/autotests/drive/drivesmodifyjobtest.cpp new file mode 100644 --- /dev/null +++ b/autotests/drive/drivesmodifyjobtest.cpp @@ -0,0 +1,93 @@ +/* + * 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 "drivesmodifyjob.h" +#include "drives.h" +#include "account.h" + +using namespace KGAPI2; + +Q_DECLARE_METATYPE(QList) +Q_DECLARE_METATYPE(KGAPI2::Drive::DrivesPtr) + +class DrivesModifyJobTest : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void initTestCase() + { + NetworkAccessManagerFactory::setFactory(new FakeNetworkAccessManagerFactory); + } + + void testModify_data() + { + QTest::addColumn>("scenarios"); + QTest::addColumn("sourceDrives"); + QTest::addColumn("requestId"); + + QTest::newRow("metadata only") + << QList{ + scenarioFromFile(QFINDTESTDATA("data/drives_modify_request.txt"), + QFINDTESTDATA("data/drives_modify_response.txt")) + } + << drivesFromFile(QFINDTESTDATA("data/drives.json")) + << QStringLiteral("MockRequestId"); + } + + void testModify() + { + QFETCH(QList, scenarios); + QFETCH(Drive::DrivesPtr, sourceDrives); + QFETCH(QString, requestId); + + FakeNetworkAccessManagerFactory::get()->setScenarios(scenarios); + + sourceDrives->setName(QStringLiteral("Renamed Drive")); + + auto account = AccountPtr::create(QStringLiteral("MockAccount"), QStringLiteral("MockToken")); + Drive::DrivesModifyJob *job = new Drive::DrivesModifyJob(sourceDrives, account); + + QVERIFY(execJob(job)); + + const auto items = job->items(); + QCOMPARE(items.count(), 1); + + Drive::DrivesPtr firstResult = (*items.cbegin()).dynamicCast(); + QVERIFY(firstResult); + QCOMPARE(*firstResult, *sourceDrives); + } +}; + +QTEST_GUILESS_MAIN(DrivesModifyJobTest) + +#include "drivesmodifyjobtest.moc" + + + + + diff --git a/autotests/drive/drivessearchquerytest.cpp b/autotests/drive/drivessearchquerytest.cpp new file mode 100644 --- /dev/null +++ b/autotests/drive/drivessearchquerytest.cpp @@ -0,0 +1,106 @@ +/* + * 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 "drivessearchquery.h" + +using namespace KGAPI2; +using namespace KGAPI2::Drive; + +Q_DECLARE_METATYPE(KGAPI2::Drive::DrivesSearchQuery) + +class DrivesSearchQueryTest: public QObject +{ + Q_OBJECT +public: + explicit DrivesSearchQueryTest() {} + + ~DrivesSearchQueryTest() {} + +private Q_SLOTS: + void testDrivesSearchQuery_data() + { + QTest::addColumn("query"); + QTest::addColumn("expected"); + + { + DrivesSearchQuery query; + query.addQuery(DrivesSearchQuery::CreatedDate, DrivesSearchQuery::Equals, QDateTime(QDate(2019, 6, 16), QTime(6, 36, 0), Qt::UTC)); + QTest::newRow("serialize time") << query + << "((createdDate = '2019-06-16T06:36:00'))"; + } + + { + DrivesSearchQuery query; + query.addQuery(DrivesSearchQuery::Name, DrivesSearchQuery::Contains, QLatin1String("Some String")); + QTest::newRow("contains") << query + << "((name contains 'Some String'))"; + } + + { + DrivesSearchQuery query; + query.addQuery(DrivesSearchQuery::Hidden, DrivesSearchQuery::Equals, true); + QTest::newRow("contains") << query + << "((hidden = true))"; + } + + { + DrivesSearchQuery query; + query.addQuery(DrivesSearchQuery::Name, DrivesSearchQuery::Contains, QLatin1String("Name")); + query.addQuery(DrivesSearchQuery::MemberCount, DrivesSearchQuery::Equals, 5); + QTest::newRow("A and B") << query + << "((name contains 'Name') and (memberCount = 5))"; + } + + { + DrivesSearchQuery query(DrivesSearchQuery::Or); + query.addQuery(DrivesSearchQuery::Name, DrivesSearchQuery::Contains, QLatin1String("Name")); + query.addQuery(DrivesSearchQuery::OrganizerCount, DrivesSearchQuery::Equals, 5); + QTest::newRow("A or B") << query + << "((name contains 'Name') or (organizerCount = 5))"; + } + + { + DrivesSearchQuery query(DrivesSearchQuery::Or); + query.addQuery(DrivesSearchQuery::CreatedDate, DrivesSearchQuery::Equals, QDateTime(QDate(2019, 3, 5), QTime(6, 36, 0), Qt::UTC)); + DrivesSearchQuery subquery; + subquery.addQuery(DrivesSearchQuery::Name, DrivesSearchQuery::Equals, QLatin1String("Test")); + subquery.addQuery(DrivesSearchQuery::MemberCount, DrivesSearchQuery::LessOrEqual, 10); + query.addQuery(subquery); + QTest::newRow("A or (B and C)") << query + << "((createdDate = '2019-03-05T06:36:00') or ((name = 'Test') and (memberCount <= 10)))"; + } + } + + void testDrivesSearchQuery() + { + QFETCH(DrivesSearchQuery, query); + QFETCH(QString, expected); + + const QString serialized = query.serialize(); + QCOMPARE(serialized, expected); + } +}; + +QTEST_GUILESS_MAIN(DrivesSearchQueryTest) + +#include "drivessearchquerytest.moc" 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::DrivesPtr drivesFromFile(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 @@ -23,6 +23,7 @@ #include "change.h" #include "file.h" #include "teamdrive.h" +#include "drives.h" #include "testutils.h" #include @@ -57,6 +58,16 @@ return file; } +KGAPI2::Drive::DrivesPtr drivesFromFile(const QString &path) +{ + QFile f(path); + VERIFY_RET(f.open(QIODevice::ReadOnly), {}); + + auto drives = KGAPI2::Drive::Drives::fromJSON(f.readAll()); + VERIFY_RET(drives, {}); + return drives; +} + KGAPI2::Drive::TeamdrivePtr teamdriveFromFile(const QString &path) { QFile f(path); diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,3 +1,4 @@ add_subdirectory(contacts) +add_subdirectory(drives) add_subdirectory(teamdrive) #add_subdirectory(staticmaps) diff --git a/examples/drives/CMakeLists.txt b/examples/drives/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/examples/drives/CMakeLists.txt @@ -0,0 +1,23 @@ +kde_enable_exceptions() + +include_directories( + ${CMAKE_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src + ${CMAKE_BINARY_DIR} +) + +set(drives_example_SRCS main.cpp mainwindow.cpp) +set(drives_example_HDRS mainwindow.h) +qt5_wrap_ui(drives_example_SRCS ui/main.ui) + +add_executable(drives-example + ${drives_example_SRCS} + ${drives_example_HDRS_MOC} +) + +target_link_libraries(drives-example + Qt5::Widgets + Qt5::Core + KF5::GAPICore + KF5::GAPIDrive +) diff --git a/examples/drives/main.cpp b/examples/drives/main.cpp new file mode 100644 --- /dev/null +++ b/examples/drives/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/drives/mainwindow.h b/examples/drives/mainwindow.h new file mode 100644 --- /dev/null +++ b/examples/drives/mainwindow.h @@ -0,0 +1,142 @@ +/* + 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 Drive with name in newDrivesEdit + */ + void createDrives(); + + /** + * Drive was created. + */ + void slotDrivesCreateJobFinished(KGAPI2::Job *job); + + /** + * Rename the selected Drive with name in renameDrivesEdit + */ + void renameSelectedDrives(); + + /** + * Drive was modified. + */ + void slotDrivesModifyJobFinished(KGAPI2::Job *job); + + /** + * Hide the selected Drive + */ + void hideSelectedDrives(); + + /** + * Unhide the selected Drive + */ + void unhideSelectedDrives(); + + /** + * Drive was modified. + */ + void slotDrivesHideJobFinished(KGAPI2::Job *job); + + /** + * All Drives were fetched. + */ + void slotFetchJobFinished(KGAPI2::Job *job); + + /** + * Drive listing was fetched. + */ + void slotDrivesFetchJobFinished(KGAPI2::Job *job); + + /** + * Retrieves list of all drives from user's Google drives + */ + void fetchDrivesList(); + + /** + * Deletes the selected Drive + */ + void deleteSelectedDrives(); + + /** + * Drive was deleted. + */ + void slotDrivesDeleteJobFinished(KGAPI2::Job *job); + + /** + * A specific team drive in drives list has been selected. Sends a request + * to Google to retrieve teh team drive file list. + */ + void drivesSelected(); + + /** + * A specific item in the drives list has been selected. Sends a request + * to Google to retrieve full details about the specific file + */ + void drivesItemSelected(); + + /** + * Drive item detail was fetched. + */ + void slotDrivesItemFetchJobFinished(KGAPI2::Job *job); + + private: + Ui::MainWindow *m_ui; + + KGAPI2::AccountPtr m_account; + +}; + +#endif // MAINWINDOW_H diff --git a/examples/drives/mainwindow.cpp b/examples/drives/mainwindow.cpp new file mode 100644 --- /dev/null +++ b/examples/drives/mainwindow.cpp @@ -0,0 +1,401 @@ +/* + 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 +#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->newDrivesButton, &QAbstractButton::clicked, + this, &MainWindow::createDrives); + connect(m_ui->drivesListButton, &QAbstractButton::clicked, + this, &MainWindow::fetchDrivesList); + connect(m_ui->drivesSelectedDeleteButton, &QAbstractButton::clicked, + this, &MainWindow::deleteSelectedDrives); + connect(m_ui->renameDrivesButton, &QAbstractButton::clicked, + this, &MainWindow::renameSelectedDrives); + connect(m_ui->hideDrivesButton, &QAbstractButton::clicked, + this, &MainWindow::hideSelectedDrives); + connect(m_ui->unhideDrivesButton, &QAbstractButton::clicked, + this, &MainWindow::unhideSelectedDrives); + connect(m_ui->drivesList, &QListWidget::itemSelectionChanged, + this, &MainWindow::drivesSelected); + connect(m_ui->drivesPreviewList, &QListWidget::itemSelectionChanged, + this, &MainWindow::drivesItemSelected); +} + +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->drivesListButton->setEnabled(true); + m_ui->newDrivesEdit->setEnabled(true); + m_ui->newDrivesButton->setEnabled(true); + m_ui->authButton->setEnabled(false); +} + +void MainWindow::createDrives() +{ + QString drivesName = m_ui->newDrivesEdit->text(); + if (drivesName.isEmpty()) { + return; + } + QString requestId = QUuid::createUuid().toString(); + + KGAPI2::Drive::DrivesPtr drives = KGAPI2::Drive::DrivesPtr::create(); + drives->setName(drivesName); + + KGAPI2::Drive::DrivesCreateJob *createJob = new KGAPI2::Drive::DrivesCreateJob(requestId, drives, m_account, this); + connect(createJob, &KGAPI2::Job::finished, + this, &MainWindow::slotDrivesCreateJobFinished); +} + +void MainWindow::slotDrivesCreateJobFinished(KGAPI2::Job *job) +{ + KGAPI2::Drive::DrivesCreateJob *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->drivesListButton->setEnabled(true); + return; + } + + m_ui->newDrivesEdit->clear(); + fetchDrivesList(); +} + +void MainWindow::renameSelectedDrives() +{ + QString drivesName = m_ui->renameDrivesEdit->text(); + if (drivesName.isEmpty()) { + return; + } + QString drivesId = m_ui->drivesList->selectedItems().at(0)->data(Qt::UserRole).toString(); + + KGAPI2::Drive::DrivesPtr drives = KGAPI2::Drive::DrivesPtr::create(); + drives->setId(drivesId); + drives->setName(drivesName); + + KGAPI2::Drive::DrivesModifyJob *modifyJob = new KGAPI2::Drive::DrivesModifyJob(drives, m_account, this); + connect(modifyJob, &KGAPI2::Job::finished, + this, &MainWindow::slotDrivesModifyJobFinished); +} + +void MainWindow::slotDrivesModifyJobFinished(KGAPI2::Job *job) +{ + KGAPI2::Drive::DrivesModifyJob *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->drivesListButton->setEnabled(true); + return; + } + + fetchDrivesList(); +} + +void MainWindow::hideSelectedDrives() +{ + QString drivesId = m_ui->drivesList->selectedItems().at(0)->data(Qt::UserRole).toString(); + + KGAPI2::Drive::DrivesPtr drive = KGAPI2::Drive::DrivesPtr::create(); + drive->setId(drivesId); + + KGAPI2::Drive::DrivesHideJob *hideJob = new KGAPI2::Drive::DrivesHideJob(drive, true, m_account, this); + connect(hideJob, &KGAPI2::Job::finished, + this, &MainWindow::slotDrivesHideJobFinished); +} + +void MainWindow::unhideSelectedDrives() +{ + QString drivesId = m_ui->drivesList->selectedItems().at(0)->data(Qt::UserRole).toString(); + + KGAPI2::Drive::DrivesPtr drive = KGAPI2::Drive::DrivesPtr::create(); + drive->setId(drivesId); + + KGAPI2::Drive::DrivesHideJob *hideJob = new KGAPI2::Drive::DrivesHideJob(drive, false, m_account, this); + connect(hideJob, &KGAPI2::Job::finished, + this, &MainWindow::slotDrivesHideJobFinished); +} + +void MainWindow::slotDrivesHideJobFinished(KGAPI2::Job *job) +{ + KGAPI2::Drive::DrivesHideJob *hideJob = qobject_cast(job); + Q_ASSERT(hideJob); + hideJob->deleteLater(); + + if (hideJob->error() != KGAPI2::NoError) { + m_ui->errorLabel->setText(QStringLiteral("Error: %1").arg(hideJob->errorString())); + m_ui->errorLabel->setVisible(true); + m_ui->drivesListButton->setEnabled(true); + return; + } + + fetchDrivesList(); +} + +void MainWindow::fetchDrivesList() +{ + if (m_account.isNull()) { + m_ui->errorLabel->setText(QStringLiteral("Error: Please authenticate first")); + m_ui->errorLabel->setVisible(true); + m_ui->authButton->setVisible(true); + return; + } + + bool showHidden = m_ui->showHiddenCheckBox->isChecked(); + + KGAPI2::Drive::DrivesSearchQuery query; + query.addQuery(KGAPI2::Drive::DrivesSearchQuery::Hidden, KGAPI2::Drive::DrivesSearchQuery::Equals, showHidden); + + KGAPI2::Drive::DrivesFetchJob *fetchJob = new KGAPI2::Drive::DrivesFetchJob(query, m_account, this); + fetchJob->setUseDomainAdminAccess(false); + fetchJob->setFields({ + KGAPI2::Drive::Drives::Fields::Id, + KGAPI2::Drive::Drives::Fields::Name, + KGAPI2::Drive::Drives::Fields::Hidden}); + connect(fetchJob, &KGAPI2::Job::finished, + this, &MainWindow::slotFetchJobFinished); + + m_ui->drivesListButton->setEnabled(false); +} + +void MainWindow::slotFetchJobFinished(KGAPI2::Job *job) +{ + KGAPI2::Drive::DrivesFetchJob *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->drivesListButton->setEnabled(true); + return; + } + + /* Get all items the job has retrieved */ + const KGAPI2::ObjectsList objects = fetchJob->items(); + m_ui->drivesList->clear(); + for (const KGAPI2::ObjectPtr &object : objects) { + const KGAPI2::Drive::DrivesPtr drives = object.dynamicCast(); + + /* Convert the drives to QListWidget item */ + QListWidgetItem *item = new QListWidgetItem(m_ui->drivesList); + item->setText(drives->name() + (drives->hidden() ? QStringLiteral(" (hidden)") : QStringLiteral(""))); + item->setData(Qt::UserRole, drives->id()); + + m_ui->drivesList->addItem(item); + } + + m_ui->drivesListButton->setEnabled(true); +} + +void MainWindow::deleteSelectedDrives() { + const QString drives_id = m_ui->drivesList->selectedItems().at(0)->data(Qt::UserRole).toString(); + + KGAPI2::Drive::DrivesDeleteJob *deleteJob = new KGAPI2::Drive::DrivesDeleteJob(drives_id, m_account, this); + connect(deleteJob, &KGAPI2::Job::finished, + this, &MainWindow::slotDrivesDeleteJobFinished); +} + +void MainWindow::slotDrivesDeleteJobFinished(KGAPI2::Job *job) +{ + KGAPI2::Drive::DrivesDeleteJob *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->drivesListButton->setEnabled(true); + return; + } + + fetchDrivesList(); +} + +void MainWindow::drivesSelected() +{ + bool hasSelection = (m_ui->drivesList->selectedItems().count() != 0); + + m_ui->drivesSelectedDeleteButton->setEnabled(hasSelection); + m_ui->renameDrivesButton->setEnabled(hasSelection); + m_ui->hideDrivesButton->setEnabled(hasSelection); + m_ui->unhideDrivesButton->setEnabled(hasSelection); + m_ui->renameDrivesEdit->setEnabled(hasSelection); + + m_ui->drivesPreviewList->clear(); + + if (!hasSelection) { + m_ui->renameDrivesEdit->clear(); + return; + } + + const QString id = m_ui->drivesList->selectedItems().at(0)->data(Qt::UserRole).toString(); + const QString name = m_ui->drivesList->selectedItems().at(0)->data(Qt::DisplayRole).toString(); + + m_ui->renameDrivesEdit->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->setFields({ + KGAPI2::Drive::File::Fields::Id, + KGAPI2::Drive::File::Fields::Title, + }); + connect(fileFetchJob, &KGAPI2::Job::finished, + this, &MainWindow::slotDrivesFetchJobFinished); +} + +void MainWindow::slotDrivesFetchJobFinished(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->drivesListButton->setEnabled(true); + return; + } + + /* Get all items we have received from Google */ + KGAPI2::ObjectsList objects = fetchJob->items(); + + Q_FOREACH (const KGAPI2::ObjectPtr &object, objects) { + const KGAPI2::Drive::FilePtr file = object.dynamicCast(); + + /* Convert the drives to QListWidget item */ + QListWidgetItem *item = new QListWidgetItem(m_ui->drivesPreviewList); + item->setText(file->title()); + item->setData(Qt::UserRole, file->id()); + + m_ui->drivesPreviewList->addItem(item); + } +} + +void MainWindow::drivesItemSelected() +{ + bool hasSelection = (m_ui->drivesPreviewList->selectedItems().count() != 0); + if (!hasSelection) { + return; + } + + const QString id = m_ui->drivesPreviewList->selectedItems().at(0)->data(Qt::UserRole).toString(); + + KGAPI2::Drive::FileFetchJob *fileFetchJob = new KGAPI2::Drive::FileFetchJob(id, m_account, nullptr); + fileFetchJob->setFields({ + KGAPI2::Drive::File::Fields::Title, + KGAPI2::Drive::File::Fields::FileSize, + }); + connect(fileFetchJob, &KGAPI2::Job::finished, + this, &MainWindow::slotDrivesItemFetchJobFinished); +} + +void MainWindow::slotDrivesItemFetchJobFinished(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; + } + + 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/drives/ui/main.ui b/examples/drives/ui/main.ui new file mode 100644 --- /dev/null +++ b/examples/drives/ui/main.ui @@ -0,0 +1,255 @@ + + + MainWindow + + + + 0 + 0 + 640 + 486 + + + + MainWindow + + + + + + + + + Authenticate + + + + + + + Not authenticated + + + + + + + + + Qt::Horizontal + + + + + + + + + false + + + Get Drive list + + + + + + + + 0 + 0 + + + + Show hidden + + + + + + + + + + + false + + + + + + + false + + + Create + + + + + + + + + + + false + + + + + + + false + + + Rename + + + + + + + false + + + Hide + + + + + + + false + + + Unhide + + + + + + + false + + + Delete + + + + + + + + + + + + + + 12 + 75 + true + + + + Qt::RightToLeft + + + Drive list + + + Qt::AlignCenter + + + + + + + + + + + + + + + 12 + 75 + true + + + + Qt::RightToLeft + + + Drive folder preview + + + Qt::AlignCenter + + + + + + + + + + + + + + + + + true + + + + + + + + + 0 + 0 + 640 + 30 + + + + + File + + + + + + + + + Quit + + + + + + + actionQuit + activated() + MainWindow + close() + + + -1 + -1 + + + 319 + 206 + + + + + diff --git a/examples/teamdrive/CMakeLists.txt b/examples/teamdrive/CMakeLists.txt --- a/examples/teamdrive/CMakeLists.txt +++ b/examples/teamdrive/CMakeLists.txt @@ -15,6 +15,9 @@ ${teamdrive_example_HDRS_MOC} ) +# The Team Drives example is, inevitably, dependant on deprecated APIs. +target_compile_options(teamdrive-example PRIVATE -Wno-deprecated-declarations) + target_link_libraries(teamdrive-example Qt5::Widgets Qt5::Core 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 Drives; +typedef QSharedPointer DrivesPtr; +typedef QList DrivesList; + class Teamdrive; typedef QSharedPointer TeamdrivePtr; typedef QList TeamdrivesList; 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,13 @@ revisiondeletejob.cpp revisionfetchjob.cpp revisionmodifyjob.cpp + drives.cpp + drivescreatejob.cpp + drivesdeletejob.cpp + drivesfetchjob.cpp + drivesmodifyjob.cpp + driveshidejob.cpp + drivessearchquery.cpp teamdrive.cpp teamdrivecreatejob.cpp teamdrivedeletejob.cpp @@ -89,6 +96,13 @@ RevisionDeleteJob RevisionFetchJob RevisionModifyJob + Drives + DrivesCreateJob + DrivesDeleteJob + DrivesFetchJob + DrivesModifyJob + DrivesHideJob + DrivesSearchQuery Teamdrive TeamdriveCreateJob TeamdriveDeleteJob diff --git a/src/drive/about.h b/src/drive/about.h --- a/src/drive/about.h +++ b/src/drive/about.h @@ -226,7 +226,7 @@ static const QString AdditionalRoles; static const QString BackgroundImageLink; static const QString BytesUsed; - static const QString CanCreateTeamDrives; + static const QString CanCreateDrives; static const QString ColorRgb; static const QString DisplayName; static const QString DomainSharingPolicy; @@ -380,6 +380,11 @@ */ UserPtr user() const; + /** + * @brief Returns whether the user can create shared drives. + */ + bool canCreateDrives() const; + /** * @brief Constructs a new DriveAbout object from given JSON data * diff --git a/src/drive/about.cpp b/src/drive/about.cpp --- a/src/drive/about.cpp +++ b/src/drive/about.cpp @@ -325,6 +325,7 @@ MaxUploadSizesList maxUploadSizes; QString permissionId; bool isCurrentAppInstalled; + bool canCreateDrives; UserPtr user; }; @@ -335,7 +336,8 @@ quotaBytesUsedAggregate(-1), largestChangeId(-1), remainingChangeIds(-1), - isCurrentAppInstalled(false) + isCurrentAppInstalled(false), + canCreateDrives(false) { } @@ -357,15 +359,16 @@ maxUploadSizes(other.maxUploadSizes), permissionId(other.permissionId), isCurrentAppInstalled(other.isCurrentAppInstalled), + canCreateDrives(other.canCreateDrives), user(other.user) { } const QString About::Fields::AdditionalRoleInfo = QStringLiteral("additionalRoleInfo"); const QString About::Fields::AdditionalRoles = QStringLiteral("additionalRoles"); const QString About::Fields::BackgroundImageLink = QStringLiteral("backgroundImageLink"); const QString About::Fields::BytesUsed = QStringLiteral("bytesUsed"); -const QString About::Fields::CanCreateTeamDrives = QStringLiteral("canCreateTeamDrives"); +const QString About::Fields::CanCreateDrives = QStringLiteral("canCreateDrives"); const QString About::Fields::ColorRgb = QStringLiteral("colorRgb"); const QString About::Fields::DisplayName = QStringLiteral("displayName"); const QString About::Fields::DomainSharingPolicy = QStringLiteral("domainSharingPolicy"); @@ -444,6 +447,7 @@ GAPI_COMPARE_CONTAINERS(maxUploadSizes) GAPI_COMPARE(permissionId) GAPI_COMPARE(isCurrentAppInstalled) + GAPI_COMPARE(canCreateDrives) GAPI_COMPARE_SHAREDPTRS(user) return true; } @@ -544,6 +548,11 @@ return d->user; } +bool About::canCreateDrives() const +{ + return d->canCreateDrives; +} + AboutPtr About::fromJSON(const QByteArray &jsonData) { QJsonDocument document = QJsonDocument::fromJson(jsonData); @@ -572,6 +581,7 @@ about->d->domainSharingPolicy = map.value(QStringLiteral("domainSharingPolicy")).toString(); about->d->permissionId = map.value(QStringLiteral("permissionId")).toString(); about->d->isCurrentAppInstalled = map.value(QStringLiteral("isCurrentAppInstalled")).toBool(); + about->d->canCreateDrives = map.value(QStringLiteral("canCreateDrives")).toBool(); const QVariantList importFormats = map.value(QStringLiteral("importFormats")).toList(); for (const QVariant &v : importFormats) { diff --git a/src/drive/drives.h b/src/drive/drives.h new file mode 100644 --- /dev/null +++ b/src/drive/drives.h @@ -0,0 +1,542 @@ +/* + 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_DRIVEDRIVES_H +#define LIBKGAPI2_DRIVEDRIVES_H + +#include "types.h" +#include "object.h" +#include "kgapidrive_export.h" + +#include + +#include + +namespace KGAPI2 +{ + +namespace Drive +{ + +/** + * @brief Drives contains a representation of a Drive. + * + * Getters and setters' documentation is based on Google Drive's API v2 reference + * @see Drives + * + * @since 5.11.41 + * @author David Barchiesi + */ +class KGAPIDRIVE_EXPORT Drives: public KGAPI2::Object +{ + + public: + + /** + * @brief Drives::Restrictions holds the structure used for + * a set of restrictions that apply to this shared drive + * or items inside this shared drive. + */ + class Restrictions + { + + public: + struct Fields { + static const QString AdminManagedRestrictions; + static const QString CopyRequiresWriterPermission; + static const QString DomainUsersOnly; + static const QString DriveMembersOnly; + }; + + 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 shared + * drive are required to modify restrictions. + */ + bool adminManagedRestrictions() const; + + /** + * @brief Sets whether administrative privileges on this shared drive + * are required to modify restrictions. + * + * @param adminManagedRestrictions + */ + void setAdminManagedRestrictions(bool adminManagedRestrictions) const; + + /** + * @brief Returns whether the options to copy, print, or download files + * inside this shared 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 shared drive. + */ + bool copyRequiresWriterPermission() const; + + /** + * @brief Sets whether the options to copy, print, or download files + * inside this shared 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 shared drive. + * + * @param copyRequiresWriterPermission + */ + void setCopyRequiresWriterPermission(bool copyRequiresWriterPermission) const; + + /** + * @brief Returns whether access to this shared drive and items inside + * this shared drive is restricted to users of the domain to which this + * shared drive belongs. This restriction may be overridden by other + * sharing policies controlled outside of this shared drive. + */ + bool domainUsersOnly() const; + + /** + * @brief Sets whether access to this shared drive and items inside this + * shared drive is restricted to users of the domain to which this + * shared drive belongs. This restriction may be overridden by other + * sharing policies controlled outside of this shared drive. + * + * @param domainUsersOnly + */ + void setDomainUsersOnly(bool domainUsersOnly) const; + + /** + * @brief Returns whether access to items inside this shared drive is + * restricted to its members. + */ + bool driveMembersOnly() const; + + /** + * @brief Sets whether access to items inside this shared drive is + * restricted to its members. + * + * @param driveMembersOnly + */ + void setDriveMembersOnly(bool driveMembersOnly) const; + + private: + class Private; + QScopedPointer const d; + friend class Private; + friend class Drives; + }; + + typedef QSharedPointer RestrictionsPtr; + + /** + * @brief Drives::Capabilities holds the structure used for + * capabilities the current user has on this shared drive. + */ + class Capabilities + { + + public: + struct Fields { + static const QString CanAddChildren; + static const QString CanChangeCopyRequiresWriterPermissionRestriction; + static const QString CanChangeDomainUsersOnlyRestriction; + static const QString CanChangeDriveBackground; + static const QString CanChangeDriveMembersOnlyRestriction; + static const QString CanComment; + static const QString CanCopy; + static const QString CanDeleteChildren; + static const QString CanDeleteDrive; + static const QString CanDownload; + static const QString CanEdit; + static const QString CanListChildren; + static const QString CanManageMembers; + static const QString CanReadRevisions; + static const QString CanRename; + static const QString CanRenameDrive; + static const QString CanShare; + static const QString CanTrashChildren; + }; + + 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 shared drive. + */ + bool canAddChildren() const; + + /** + * @brief Returns whether the current user can change the + * copyRequiresWriterPermission restriction of this shared drive. + */ + bool canChangeCopyRequiresWriterPermissionRestriction() const; + + /** + * @brief Returns whether the current user can change the domainUsersOnly + * restriction of this shared drive. + */ + bool canChangeDomainUsersOnlyRestriction() const; + + /** + * @brief Returns whether the current user can change the background of + * this shared drive. + */ + bool canChangeDriveBackground() const; + + /** + * @brief Returns whether the current user can change the driveMembersOnly + * restriction of this shared drive. + */ + bool canChangeDriveMembersOnlyRestriction() const; + + /** + * @brief Returns Whether the current user can comment on files in + * this shared drive. + */ + bool canComment() const; + + /** + * @brief Returns Whether the current user can copy files in this shared drive. + */ + bool canCopy() const; + + /** + * @brief Returns Whether the current user can delete children from + * folders in this shared drive. + */ + bool canDeleteChildren() const; + + /** + * @brief Returns Whether the current user can delete this shared drive. + * + * Attempting to delete the shared drive may still fail if there are + * untrashed items inside the shared drive. + */ + bool canDeleteDrive() const; + + /** + * @brief Returns Whether the current user can download files in this + * shared drive. + */ + bool canDownload() const; + + /** + * @brief Returns Whether the current user can edit files in this + * shared drive + */ + bool canEdit() const; + + /** + * @brief Returns Whether the current user can list the children of + * folders in this shared drive. + */ + bool canListChildren() const; + + /** + * @brief Returns Whether the current user can add members to this shared 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 shared drive. + */ + bool canReadRevisions() const; + + /** + * @brief Returns Whether the current user can rename files or folders + * in this shared drive. + */ + bool canRename() const; + + /** + * @brief Returns Whether the current user can rename this shared drive. + */ + bool canRenameDrive() const; + + /** + * @brief Returns Whether the current user can share files or folders + * in this shared drive. + */ + bool canShare() const; + + /** + * @brief Returns Whether the current user can trash children from + * folders in this shared drive. + */ + bool canTrashChildren() const; + + private: + class Private; + QScopedPointer const d; + friend class Private; + friend class Drives; + }; + + typedef QSharedPointer CapabilitiesPtr; + + /** + * @brief Drives::BackgroundImageFile holds the structure used + * for backgroundImageFile property. + */ + class BackgroundImageFile + { + + public: + struct Fields { + static const QString Id; + static const QString XCoordinate; + static const QString YCoordinate; + static const QString Width; + }; + + 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 an image file in Google Drive + * to use for the background image. + */ + QString id() const; + + /** + * @brief Sets the ID of an image file in Google Drive to + * use for the background image. + * + * @param id + */ + void setId(const QString &id) const; + + /** + * @brief Returns the X coordinate of the upper left corner of + * the cropping area in the background image. This is a value + * in the closed range of 0 to 1. This value represents the + * horizontal distance from the left side of the entire image + * to the left side of the cropping area divided by the width + * of the entire image. + */ + float xCoordinate() const; + + /** + * @brief Returns the X coordinate of the upper left corner of + * the cropping area in the background image. This is a value + * in the closed range of 0 to 1. This value represents the + * horizontal distance from the left side of the entire image + * to the left side of the cropping area divided by the width + * of the entire image. + * + * @param xCoordinate + */ + void setXCoordinate(float xCoordinate) const; + + /** + * @brief Returns the Y coordinate of the upper left corner of the + * cropping area in the background image. This is a value in the + * closed range of 0 to 1. This value represents the vertical + * distance from the top side of the entire image to the top side + * of the cropping area divided by the height of the entire image. + */ + float yCoordinate() const; + + /** + * @brief Sets the Y coordinate of the upper left corner of the + * cropping area in the background image. This is a value in the + * closed range of 0 to 1. This value represents the vertical + * distance from the top side of the entire image to the top side + * of the cropping area divided by the height of the entire image. + * + * @param yCoordinate + */ + void setYCoordinate(float yCoordinate) const; + + /** + * @brief Returns the width of the cropped image in the closed + * range of 0 to 1. This value represents the width of the cropped + * image divided by the width of the entire image. The height is + * computed by applying a width to height aspect ratio of 80 to 9. + * The resulting image must be at least 1280 pixels wide and + * 144 pixels high. + */ + float width() const; + + /** + * @brief Sets the width of the cropped image in the closed + * range of 0 to 1. This value represents the width of the cropped + * image divided by the width of the entire image. The height is + * computed by applying a width to height aspect ratio of 80 to 9. + * The resulting image must be at least 1280 pixels wide and + * 144 pixels high. + * + * @param width + */ + void setWidth(float width) const; + + private: + class Private; + QScopedPointer const d; + friend class Private; + friend class Drives; + }; + + typedef QSharedPointer BackgroundImageFilePtr; + + struct Fields { + static const QString Kind; + static const QString Items; + static const QString KindDrive; + static const QString PageToken; + static const QString NextPageToken; + static const QString Id; + static const QString Name; + static const QString ThemeId; + static const QString ColorRgb; + static const QString BackgroundImageFile; + static const QString BackgroundImageLink; + static const QString Capabilities; + static const QString CreatedDate; + static const QString Hidden; + static const QString Restrictions; + }; + + Drives(); + Drives(const Drives &other); + ~Drives() override; + bool operator==(const Drives &other) const; + bool operator!=(const Drives &other) const { return !operator==(other); } + + /** + * @brief Returns the ID of this shared drive which + * is also the ID of the top level folder of this + * shared drive. + */ + QString id() const; + + /** + * @brief Sets the ID of this shared drive which + * is also the ID of the top level folder of this + * shared drive. + * + * @param id + */ + void setId(const QString &id) const; + + /** + * @brief Returns the name of the drive. + */ + QString name() const; + + /** + * @brief Sets the name of the drive. + * + * @param name + */ + void setName(const QString &name) const; + + /** + * @brief Returns the themeId of the drive. + */ + QString themeId() const; + + /** + * @brief Sets the themeId of the shared drive. + * + * @param themeId + */ + void setThemeId(const QString &themeId) const; + + /** + * @brief Returns the colorRgb of the shared drive. + */ + QString colorRgb() const; + + /** + * @brief Sets the colorRgb of the shared drive. + * + * @param colorRgb + */ + void setColorRgb(const QString &colorRgb) const; + + /** + * @brief Returns the image file and cropping parameters from which a background image for this shared drive is set. + */ + BackgroundImageFilePtr backgroundImageFile() const; + + /** + * @brief Sets the backgroundImageFile of the shared drive. + * + * @param backgroundImageFile + */ + void setBackgroundImageFile(const BackgroundImageFilePtr &backgroundImageFile) const; + + /** + * @brief Returns the backgroundImageLink of the shared drive. + */ + QString backgroundImageLink() const; + + /** + * @brief Returns the capabilities the current user has on this shared drive. + */ + CapabilitiesPtr capabilities() const; + + /** + * @brief Returns the time at which the shared drive was created. + */ + QDateTime createdDate() const; + + /** + * @brief Returns whether the shared drive is hidden from default view. + */ + bool hidden() const; + + /** + * @brief Returns the set of restrictions that apply to this shared drive or + * items inside this shared drive. + */ + RestrictionsPtr restrictions() const; + + /** + * @brief Sets the restrictions of the shared drive. + * + * @param restrictions + */ + void setRestrictions(const RestrictionsPtr &restrictions) const; + + static DrivesPtr fromJSON(const QByteArray &jsonData); + static DrivesList fromJSONFeed(const QByteArray &jsonData, FeedData &feedData); + static QByteArray toJSON(const DrivesPtr &drives); + + private: + class Private; + QScopedPointer const d; + friend class Private; +}; + +} /* namespace Drive */ + +} /* namespace KGAPI2 */ + +#endif // LIBKGAPI2_DRIVEDRIVES_H diff --git a/src/drive/drives.cpp b/src/drive/drives.cpp new file mode 100644 --- /dev/null +++ b/src/drive/drives.cpp @@ -0,0 +1,709 @@ +/* + 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 "drives.h" +#include "utils_p.h" + +#include +#include +#include + +namespace { + static const QString ApiKind = QStringLiteral("drive#drive"); + static const QString ApiKindList = QStringLiteral("drive#driveList"); +} + +using namespace KGAPI2; +using namespace KGAPI2::Drive; + +///// Drives::Restrictions + +class Q_DECL_HIDDEN Drives::Restrictions::Private +{ + public: + Private() = default; + Private(const Private &other) = default; + + bool adminManagedRestrictions = false; + bool copyRequiresWriterPermission = false; + bool domainUsersOnly = false; + bool driveMembersOnly = false; +}; + +Drives::Restrictions::Restrictions(): + d(new Private) +{ +} + +Drives::Restrictions::Restrictions(const Drives::Restrictions &other): + d(new Private(*(other.d))) +{ +} + +Drives::Restrictions::~Restrictions() = default; + +bool Drives::Restrictions::operator==(const Drives::Restrictions &other) const +{ + GAPI_COMPARE(adminManagedRestrictions); + GAPI_COMPARE(copyRequiresWriterPermission); + GAPI_COMPARE(domainUsersOnly); + GAPI_COMPARE(driveMembersOnly); + return true; +} + +bool Drives::Restrictions::adminManagedRestrictions() const +{ + return d->adminManagedRestrictions; +} + +void Drives::Restrictions::setAdminManagedRestrictions(bool adminManagedRestrictions) const +{ + d->adminManagedRestrictions = adminManagedRestrictions; +} + +bool Drives::Restrictions::copyRequiresWriterPermission() const +{ + return d->copyRequiresWriterPermission; +} + +void Drives::Restrictions::setCopyRequiresWriterPermission(bool copyRequiresWriterPermission) const +{ + d->copyRequiresWriterPermission = copyRequiresWriterPermission; +} + +bool Drives::Restrictions::domainUsersOnly() const +{ + return d->domainUsersOnly; +} + +void Drives::Restrictions::setDomainUsersOnly(bool domainUsersOnly) const +{ + d->domainUsersOnly = domainUsersOnly; +} + +bool Drives::Restrictions::driveMembersOnly() const +{ + return d->driveMembersOnly; +} + +void Drives::Restrictions::setDriveMembersOnly(bool driveMembersOnly) const +{ + d->driveMembersOnly = driveMembersOnly; +} + +///// Drives::Capabilities + +class Q_DECL_HIDDEN Drives::Capabilities::Private +{ + public: + Private() = default; + Private(const Private &other) = default; + + bool canAddChildren = false; + bool canChangeCopyRequiresWriterPermissionRestriction = false; + bool canChangeDomainUsersOnlyRestriction = false; + bool canChangeDriveBackground = false; + bool canChangeDriveMembersOnlyRestriction = false; + bool canComment = false; + bool canCopy = false; + bool canDeleteChildren = false; + bool canDeleteDrive = false; + bool canDownload = false; + bool canEdit = false; + bool canListChildren = false; + bool canManageMembers = false; + bool canReadRevisions = false; + bool canRename = false; + bool canRenameDrive = false; + bool canShare = false; + bool canTrashChildren = false; +}; + +Drives::Capabilities::Capabilities(): + d(new Private) +{ +} + +Drives::Capabilities::Capabilities(const Drives::Capabilities &other): + d(new Private(*(other.d))) +{ +} + +Drives::Capabilities::~Capabilities() = default; + +bool Drives::Capabilities::operator==(const Drives::Capabilities &other) const +{ + GAPI_COMPARE(canAddChildren); + GAPI_COMPARE(canChangeCopyRequiresWriterPermissionRestriction); + GAPI_COMPARE(canChangeDomainUsersOnlyRestriction); + GAPI_COMPARE(canChangeDriveBackground); + GAPI_COMPARE(canChangeDriveMembersOnlyRestriction); + GAPI_COMPARE(canComment); + GAPI_COMPARE(canCopy); + GAPI_COMPARE(canDeleteChildren); + GAPI_COMPARE(canDeleteDrive); + GAPI_COMPARE(canDownload); + GAPI_COMPARE(canEdit); + GAPI_COMPARE(canListChildren); + GAPI_COMPARE(canManageMembers); + GAPI_COMPARE(canReadRevisions); + GAPI_COMPARE(canRename); + GAPI_COMPARE(canRenameDrive); + GAPI_COMPARE(canShare); + GAPI_COMPARE(canTrashChildren); + return true; +} + +bool Drives::Capabilities::canAddChildren() const +{ + return d->canAddChildren; +} + +bool Drives::Capabilities::canChangeCopyRequiresWriterPermissionRestriction() const +{ + return d->canChangeCopyRequiresWriterPermissionRestriction; +} + +bool Drives::Capabilities::canChangeDomainUsersOnlyRestriction() const +{ + return d->canChangeDomainUsersOnlyRestriction; +} + +bool Drives::Capabilities::canChangeDriveBackground() const +{ + return d->canChangeDriveBackground; +} + +bool Drives::Capabilities::canChangeDriveMembersOnlyRestriction() const +{ + return d->canChangeDriveMembersOnlyRestriction; +} + +bool Drives::Capabilities::canComment() const +{ + return d->canComment; +} + +bool Drives::Capabilities::canCopy() const +{ + return d->canCopy; +} + +bool Drives::Capabilities::canDeleteChildren() const +{ + return d->canDeleteChildren; +} + +bool Drives::Capabilities::canDeleteDrive() const +{ + return d->canDeleteDrive; +} + +bool Drives::Capabilities::canDownload() const +{ + return d->canDownload; +} + +bool Drives::Capabilities::canEdit() const +{ + return d->canEdit; +} + +bool Drives::Capabilities::canListChildren() const +{ + return d->canListChildren; +} + +bool Drives::Capabilities::canManageMembers() const +{ + return d->canManageMembers; +} + +bool Drives::Capabilities::canReadRevisions() const +{ + return d->canReadRevisions; +} + +bool Drives::Capabilities::canRename() const +{ + return d->canRename; +} + +bool Drives::Capabilities::canRenameDrive() const +{ + return d->canRenameDrive; +} + +bool Drives::Capabilities::canShare() const +{ + return d->canShare; +} + +bool Drives::Capabilities::canTrashChildren() const +{ + return d->canTrashChildren; +} + +///// Drives::BackgroundImageFile + +class Q_DECL_HIDDEN Drives::BackgroundImageFile::Private +{ + public: + Private() = default; + Private(const Private &other) = default; + + QString id; + float xCoordinate = 0.0f; + float yCoordinate = 0.0f; + float width = 0.0f; +}; + +Drives::BackgroundImageFile::BackgroundImageFile(): + d(new Private) +{ +} + +Drives::BackgroundImageFile::BackgroundImageFile(const Drives::BackgroundImageFile &other): + d(new Private(*(other.d))) +{ +} + +Drives::BackgroundImageFile::~BackgroundImageFile() = default; + +bool Drives::BackgroundImageFile::operator==(const Drives::BackgroundImageFile &other) const +{ + GAPI_COMPARE(id); + GAPI_COMPARE(xCoordinate); + GAPI_COMPARE(yCoordinate); + GAPI_COMPARE(width); + return true; +} + +QString Drives::BackgroundImageFile::id() const +{ + return d->id; +} + +void Drives::BackgroundImageFile::setId(const QString &id) const +{ + d->id = id; +} + +float Drives::BackgroundImageFile::xCoordinate() const +{ + return d->xCoordinate; +} + +void Drives::BackgroundImageFile::setXCoordinate(const float xCoordinate) const +{ + d->xCoordinate = xCoordinate; +} + +float Drives::BackgroundImageFile::yCoordinate() const +{ + return d->yCoordinate; +} + +void Drives::BackgroundImageFile::setYCoordinate(const float yCoordinate) const +{ + d->yCoordinate = yCoordinate; +} + +float Drives::BackgroundImageFile::width() const +{ + return d->width; +} + +void Drives::BackgroundImageFile::setWidth(const float width) const +{ + d->width = width; +} + +///// Drives + +class Q_DECL_HIDDEN Drives::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; + bool hidden = false; + RestrictionsPtr restrictions; + + static DrivesPtr fromJSON(const QVariantMap &map); +}; + +DrivesPtr Drives::Private::fromJSON(const QVariantMap &map) +{ + if (!map.contains(Drives::Fields::Kind) || + map[Drives::Fields::Kind].toString() != ApiKind) + { + return DrivesPtr(); + } + + auto drives = DrivesPtr::create(); + if (map.contains(Drives::Fields::Id)) { + drives->d->id = map[Drives::Fields::Id].toString(); + } + if (map.contains(Drives::Fields::Name)) { + drives->d->name = map[Drives::Fields::Name].toString(); + } + if (map.contains(Drives::Fields::ThemeId)) { + drives->d->themeId = map[Drives::Fields::ThemeId].toString(); + } + if (map.contains(Drives::Fields::ColorRgb)) { + drives->d->colorRgb = map[Drives::Fields::ColorRgb].toString(); + } + if (map.contains(Drives::Fields::BackgroundImageLink)) { + drives->d->backgroundImageLink = map[Drives::Fields::BackgroundImageLink].toString(); + } + if (map.contains(Drives::Fields::CreatedDate)) { + drives->d->createdDate = QDateTime::fromString(map[Drives::Fields::CreatedDate].toString(), Qt::ISODate); + } + if (map.contains(Drives::Fields::Hidden)) { + drives->d->hidden = map[Drives::Fields::Hidden].toBool(); + } + + if (map.contains(Drives::Fields::BackgroundImageFile)) { + const QVariantMap backgroundImageFileMap = map[Drives::Fields::BackgroundImageFile].toMap(); + auto backgroundImageFile = BackgroundImageFilePtr::create(); + backgroundImageFile->d->id = backgroundImageFileMap[Drives::BackgroundImageFile::Fields::Id].toString(); + backgroundImageFile->d->xCoordinate = backgroundImageFileMap[Drives::BackgroundImageFile::Fields::XCoordinate].toReal(); + backgroundImageFile->d->yCoordinate = backgroundImageFileMap[Drives::BackgroundImageFile::Fields::YCoordinate].toReal(); + backgroundImageFile->d->width = backgroundImageFileMap[Drives::BackgroundImageFile::Fields::Width].toReal(); + drives->d->backgroundImageFile = backgroundImageFile; + } + + if (map.contains(Drives::Fields::Capabilities)) { + const QVariantMap capabilitiesMap = map[Drives::Fields::Capabilities].toMap(); + auto capabilities = CapabilitiesPtr::create(); + capabilities->d->canAddChildren = capabilitiesMap[Drives::Capabilities::Fields::CanAddChildren].toBool(); + capabilities->d->canChangeCopyRequiresWriterPermissionRestriction = capabilitiesMap[Drives::Capabilities::Fields::CanChangeCopyRequiresWriterPermissionRestriction].toBool(); + capabilities->d->canChangeDomainUsersOnlyRestriction = capabilitiesMap[Drives::Capabilities::Fields::CanChangeDomainUsersOnlyRestriction].toBool(); + capabilities->d->canChangeDriveBackground = capabilitiesMap[Drives::Capabilities::Fields::CanChangeDriveBackground].toBool(); + capabilities->d->canChangeDriveMembersOnlyRestriction = capabilitiesMap[Drives::Capabilities::Fields::CanChangeDriveMembersOnlyRestriction].toBool(); + capabilities->d->canComment = capabilitiesMap[Drives::Capabilities::Fields::CanComment].toBool(); + capabilities->d->canCopy = capabilitiesMap[Drives::Capabilities::Fields::CanCopy].toBool(); + capabilities->d->canDeleteChildren = capabilitiesMap[Drives::Capabilities::Fields::CanDeleteChildren].toBool(); + capabilities->d->canDeleteDrive = capabilitiesMap[Drives::Capabilities::Fields::CanDeleteDrive].toBool(); + capabilities->d->canDownload = capabilitiesMap[Drives::Capabilities::Fields::CanDownload].toBool(); + capabilities->d->canEdit = capabilitiesMap[Drives::Capabilities::Fields::CanEdit].toBool(); + capabilities->d->canListChildren = capabilitiesMap[Drives::Capabilities::Fields::CanListChildren].toBool(); + capabilities->d->canManageMembers = capabilitiesMap[Drives::Capabilities::Fields::CanManageMembers].toBool(); + capabilities->d->canReadRevisions = capabilitiesMap[Drives::Capabilities::Fields::CanReadRevisions].toBool(); + capabilities->d->canRename = capabilitiesMap[Drives::Capabilities::Fields::CanRename].toBool(); + capabilities->d->canRenameDrive = capabilitiesMap[Drives::Capabilities::Fields::CanRenameDrive].toBool(); + capabilities->d->canShare = capabilitiesMap[Drives::Capabilities::Fields::CanShare].toBool(); + capabilities->d->canTrashChildren = capabilitiesMap[Drives::Capabilities::Fields::CanTrashChildren].toBool(); + drives->d->capabilities = capabilities; + } + + if (map.contains(Drives::Fields::Restrictions)) { + const QVariantMap restrictionsMap = map[Drives::Fields::Restrictions].toMap(); + auto restrictions = RestrictionsPtr::create(); + restrictions->d->adminManagedRestrictions = restrictionsMap[Drives::Restrictions::Fields::AdminManagedRestrictions].toBool(); + restrictions->d->copyRequiresWriterPermission = restrictionsMap[Drives::Restrictions::Fields::CopyRequiresWriterPermission].toBool(); + restrictions->d->domainUsersOnly = restrictionsMap[Drives::Restrictions::Fields::DomainUsersOnly].toBool(); + restrictions->d->driveMembersOnly = restrictionsMap[Drives::Restrictions::Fields::DriveMembersOnly].toBool(); + drives->d->restrictions = restrictions; + } + + return drives; +} + +const QString Drives::Restrictions::Fields::AdminManagedRestrictions = QStringLiteral("adminManagedRestrictions"); +const QString Drives::Restrictions::Fields::CopyRequiresWriterPermission = QStringLiteral("copyRequiresWriterPermission"); +const QString Drives::Restrictions::Fields::DomainUsersOnly = QStringLiteral("domainUsersOnly"); +const QString Drives::Restrictions::Fields::DriveMembersOnly = QStringLiteral("driveMembersOnly"); + +const QString Drives::Capabilities::Fields::CanAddChildren = QStringLiteral("canAddChildren"); +const QString Drives::Capabilities::Fields::CanChangeCopyRequiresWriterPermissionRestriction = QStringLiteral("canChangeCopyRequiresWriterPermissionRestriction"); +const QString Drives::Capabilities::Fields::CanChangeDomainUsersOnlyRestriction = QStringLiteral("canChangeDomainUsersOnlyRestriction"); +const QString Drives::Capabilities::Fields::CanChangeDriveBackground = QStringLiteral("canChangeDriveBackground"); +const QString Drives::Capabilities::Fields::CanChangeDriveMembersOnlyRestriction = QStringLiteral("canChangeDriveMembersOnlyRestriction"); +const QString Drives::Capabilities::Fields::CanComment = QStringLiteral("canComment"); +const QString Drives::Capabilities::Fields::CanCopy = QStringLiteral("canCopy"); +const QString Drives::Capabilities::Fields::CanDeleteChildren = QStringLiteral("canDeleteChildren"); +const QString Drives::Capabilities::Fields::CanDeleteDrive = QStringLiteral("canDeleteDrive"); +const QString Drives::Capabilities::Fields::CanDownload = QStringLiteral("canDownload"); +const QString Drives::Capabilities::Fields::CanEdit = QStringLiteral("canEdit"); +const QString Drives::Capabilities::Fields::CanListChildren = QStringLiteral("canListChildren"); +const QString Drives::Capabilities::Fields::CanManageMembers = QStringLiteral("canManageMembers"); +const QString Drives::Capabilities::Fields::CanReadRevisions = QStringLiteral("canReadRevisions"); +const QString Drives::Capabilities::Fields::CanRename = QStringLiteral("canRename"); +const QString Drives::Capabilities::Fields::CanRenameDrive = QStringLiteral("canRenameDrive"); +const QString Drives::Capabilities::Fields::CanShare = QStringLiteral("canShare"); +const QString Drives::Capabilities::Fields::CanTrashChildren = QStringLiteral("canTrashChildren"); + +const QString Drives::BackgroundImageFile::Fields::Id = QStringLiteral("id"); +const QString Drives::BackgroundImageFile::Fields::XCoordinate = QStringLiteral("xCoordinate"); +const QString Drives::BackgroundImageFile::Fields::YCoordinate = QStringLiteral("yCoordinate"); +const QString Drives::BackgroundImageFile::Fields::Width = QStringLiteral("width"); + +const QString Drives::Fields::Items = QStringLiteral("items"); +const QString Drives::Fields::KindDrive = QStringLiteral("kind"); +const QString Drives::Fields::PageToken = QStringLiteral("pageToken"); +const QString Drives::Fields::NextPageToken = QStringLiteral("nextPageToken"); +const QString Drives::Fields::Id = QStringLiteral("id"); +const QString Drives::Fields::Kind = QStringLiteral("kind"); +const QString Drives::Fields::Name = QStringLiteral("name"); +const QString Drives::Fields::ThemeId = QStringLiteral("themeId"); +const QString Drives::Fields::ColorRgb = QStringLiteral("colorRgb"); +const QString Drives::Fields::BackgroundImageFile = QStringLiteral("backgroundImageFile"); +const QString Drives::Fields::BackgroundImageLink = QStringLiteral("backgroundImageLink"); +const QString Drives::Fields::Capabilities = QStringLiteral("capabilities"); +const QString Drives::Fields::CreatedDate = QStringLiteral("createdDate"); +const QString Drives::Fields::Hidden = QStringLiteral("hidden"); +const QString Drives::Fields::Restrictions = QStringLiteral("restrictions"); + +Drives::Drives(): + KGAPI2::Object(), + d(new Private) +{ +} + +Drives::Drives(const Drives& other): + KGAPI2::Object(other), + d(new Private(*(other.d))) +{ +} + +Drives::~Drives() = default; + +bool Drives::operator==(const Drives &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(hidden); + GAPI_COMPARE_SHAREDPTRS(restrictions); + return true; +} + +QString Drives::id() const +{ + return d->id; +} + +void Drives::setId(const QString &id) const +{ + d->id = id; +} + +QString Drives::name() const +{ + return d->name; +} + +void Drives::setName(const QString &name) const +{ + d->name = name; +} + +QString Drives::themeId() const +{ + return d->themeId; +} + +void Drives::setThemeId(const QString &themeId) const +{ + d->themeId = themeId; +} + +QString Drives::colorRgb() const +{ + return d->colorRgb; +} + +void Drives::setColorRgb(const QString &colorRgb) const +{ + d->colorRgb = colorRgb; +} + +Drives::BackgroundImageFilePtr Drives::backgroundImageFile() const +{ + return d->backgroundImageFile; +} + +void Drives::setBackgroundImageFile(const Drives::BackgroundImageFilePtr &backgroundImageFile) const +{ + d->backgroundImageFile = backgroundImageFile; +} + +QString Drives::backgroundImageLink() const +{ + return d->backgroundImageLink; +} + +Drives::CapabilitiesPtr Drives::capabilities() const +{ + return d->capabilities; +} + +QDateTime Drives::createdDate() const +{ + return d->createdDate; +} + +bool Drives::hidden() const +{ + return d->hidden; +} + +void Drives::setRestrictions(const Drives::RestrictionsPtr &restrictions) const +{ + d->restrictions = restrictions; +} + +Drives::RestrictionsPtr Drives::restrictions() const +{ + return d->restrictions; +} + +DrivesPtr Drives::fromJSON(const QByteArray &jsonData) +{ + QJsonDocument document = QJsonDocument::fromJson(jsonData); + if (document.isNull()) { + return DrivesPtr(); + } + + const QVariant data = document.toVariant(); + return Private::fromJSON(data.toMap()); +} + +DrivesList Drives::fromJSONFeed(const QByteArray &jsonData, FeedData &feedData) +{ + QJsonDocument document = QJsonDocument::fromJson(jsonData); + if (document.isNull()) { + return DrivesList(); + } + + const QVariant data = document.toVariant(); + const QVariantMap map = data.toMap(); + if (!map.contains(Drives::Fields::Kind) || + map[Drives::Fields::Kind].toString() != ApiKindList) { + return DrivesList(); + } + + if (map.contains(Drives::Fields::NextPageToken)) { + feedData.nextPageUrl = DriveService::fetchDrivesUrl(); + QUrlQuery query(feedData.nextPageUrl); + query.addQueryItem(Drives::Fields::PageToken, map.value(Drives::Fields::NextPageToken).toString()); + feedData.nextPageUrl.setQuery(query); + } + + DrivesList list; + const QVariantList items = map[Drives::Fields::Items].toList(); + for (const QVariant & item : items) { + const DrivesPtr drives = Private::fromJSON(item.toMap()); + + if (!drives.isNull()) { + list << drives; + } + } + + return list; +} + +QByteArray Drives::toJSON(const DrivesPtr &drives) +{ + QVariantMap drivesMap; + drivesMap[Drives::Fields::Kind] = ApiKind; + if (!drives->id().isEmpty()) { + drivesMap[Drives::Fields::Id] = drives->id(); + } + if (!drives->name().isEmpty()) { + drivesMap[Drives::Fields::Name] = drives->name(); + } + if (!drives->themeId().isEmpty()) { + drivesMap[Drives::Fields::ThemeId] = drives->themeId(); + } + if (!drives->colorRgb().isEmpty()) { + drivesMap[Drives::Fields::ColorRgb] = drives->colorRgb(); + } + if (!drives->backgroundImageLink().isEmpty()) { + drivesMap[Drives::Fields::BackgroundImageLink] = drives->backgroundImageLink(); + } + if (drives->createdDate().isValid()) { + drivesMap[Drives::Fields::CreatedDate] = drives->createdDate(); + } + drivesMap[Drives::Fields::Hidden] = drives->hidden(); + + if (drives->restrictions()) { + QVariantMap restrictionsMap; + restrictionsMap[Drives::Restrictions::Fields::AdminManagedRestrictions] = drives->restrictions()->adminManagedRestrictions(); + restrictionsMap[Drives::Restrictions::Fields::CopyRequiresWriterPermission] = drives->restrictions()->copyRequiresWriterPermission(); + restrictionsMap[Drives::Restrictions::Fields::DomainUsersOnly] = drives->restrictions()->domainUsersOnly(); + restrictionsMap[Drives::Restrictions::Fields::DriveMembersOnly] = drives->restrictions()->driveMembersOnly(); + drivesMap[Drives::Fields::Restrictions] = restrictionsMap; + } + + if (drives->backgroundImageFile()) { + QVariantMap backgroundImageFileMap; + backgroundImageFileMap[Drives::BackgroundImageFile::Fields::Id] = drives->backgroundImageFile()->id(); + backgroundImageFileMap[Drives::BackgroundImageFile::Fields::XCoordinate] = drives->backgroundImageFile()->xCoordinate(); + backgroundImageFileMap[Drives::BackgroundImageFile::Fields::YCoordinate] = drives->backgroundImageFile()->yCoordinate(); + backgroundImageFileMap[Drives::BackgroundImageFile::Fields::Width] = drives->backgroundImageFile()->width(); + drivesMap[Drives::Fields::BackgroundImageFile] = backgroundImageFileMap; + } + + if (drives->capabilities()) { + QVariantMap capabilitiesMap; + capabilitiesMap[Drives::Capabilities::Fields::CanAddChildren] = drives->capabilities()->canAddChildren(); + capabilitiesMap[Drives::Capabilities::Fields::CanChangeCopyRequiresWriterPermissionRestriction] = drives->capabilities()->canChangeCopyRequiresWriterPermissionRestriction(); + capabilitiesMap[Drives::Capabilities::Fields::CanChangeDomainUsersOnlyRestriction] = drives->capabilities()->canChangeDomainUsersOnlyRestriction(); + capabilitiesMap[Drives::Capabilities::Fields::CanChangeDriveBackground] = drives->capabilities()->canChangeDriveBackground(); + capabilitiesMap[Drives::Capabilities::Fields::CanChangeDriveMembersOnlyRestriction] = drives->capabilities()->canChangeDriveMembersOnlyRestriction(); + capabilitiesMap[Drives::Capabilities::Fields::CanComment] = drives->capabilities()->canComment(); + capabilitiesMap[Drives::Capabilities::Fields::CanCopy] = drives->capabilities()->canCopy(); + capabilitiesMap[Drives::Capabilities::Fields::CanDeleteChildren] = drives->capabilities()->canDeleteChildren(); + capabilitiesMap[Drives::Capabilities::Fields::CanDeleteDrive] = drives->capabilities()->canDeleteDrive(); + capabilitiesMap[Drives::Capabilities::Fields::CanDownload] = drives->capabilities()->canDownload(); + capabilitiesMap[Drives::Capabilities::Fields::CanEdit] = drives->capabilities()->canEdit(); + capabilitiesMap[Drives::Capabilities::Fields::CanListChildren] = drives->capabilities()->canListChildren(); + capabilitiesMap[Drives::Capabilities::Fields::CanManageMembers] = drives->capabilities()->canManageMembers(); + capabilitiesMap[Drives::Capabilities::Fields::CanReadRevisions] = drives->capabilities()->canReadRevisions(); + capabilitiesMap[Drives::Capabilities::Fields::CanRename] = drives->capabilities()->canRename(); + capabilitiesMap[Drives::Capabilities::Fields::CanRenameDrive] = drives->capabilities()->canRenameDrive(); + capabilitiesMap[Drives::Capabilities::Fields::CanShare] = drives->capabilities()->canShare(); + capabilitiesMap[Drives::Capabilities::Fields::CanTrashChildren] = drives->capabilities()->canTrashChildren(); + drivesMap[Drives::Fields::Capabilities] = capabilitiesMap; + } + + QJsonDocument document = QJsonDocument::fromVariant(drivesMap); + return document.toJson(QJsonDocument::Compact); +} diff --git a/src/drive/teamdrivecreatejob.h b/src/drive/drivescreatejob.h copy from src/drive/teamdrivecreatejob.h copy to src/drive/drivescreatejob.h --- a/src/drive/teamdrivecreatejob.h +++ b/src/drive/drivescreatejob.h @@ -20,8 +20,8 @@ * License along with this library. If not, see . */ -#ifndef KGAPI2_DRIVETEAMDRIVECREATEJOB_H -#define KGAPI2_DRIVETEAMDRIVECREATEJOB_H +#ifndef KGAPI2_DRIVEDRIVESCREATEJOB_H +#define KGAPI2_DRIVEDRIVESCREATEJOB_H #include "createjob.h" #include "kgapidrive_export.h" @@ -32,18 +32,18 @@ namespace Drive { -class KGAPIDRIVE_EXPORT TeamdriveCreateJob : public KGAPI2::CreateJob +class KGAPIDRIVE_EXPORT DrivesCreateJob : public KGAPI2::CreateJob { Q_OBJECT public: - TeamdriveCreateJob(const QString &requestId, - const TeamdrivePtr &teamdrive, + DrivesCreateJob(const QString &requestId, + const DrivesPtr &drives, const AccountPtr &account, QObject *parent = nullptr); - TeamdriveCreateJob(const QString &requestId, - const TeamdrivesList &teamdrives, + DrivesCreateJob(const QString &requestId, + const DrivesList &drives, const AccountPtr &account, QObject *parent = nullptr); - ~TeamdriveCreateJob() override; + ~DrivesCreateJob() override; /** * @brief Returns the requestId used in this create request. @@ -65,4 +65,4 @@ } // namespace KGAPI2 -#endif // KGAPI2_DRIVETEAMDRIVECREATEJOB_H +#endif // KGAPI2_DRIVEDRIVESCREATEJOB_H diff --git a/src/drive/drivescreatejob.cpp b/src/drive/drivescreatejob.cpp new file mode 100644 --- /dev/null +++ b/src/drive/drivescreatejob.cpp @@ -0,0 +1,136 @@ +/* + * 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 "drivescreatejob.h" +#include "account.h" +#include "driveservice.h" +#include "drives.h" +#include "utils.h" + +#include +#include +#include + + +namespace { + static const QString RequestIdParam = QStringLiteral("requestId"); +} +using namespace KGAPI2; +using namespace KGAPI2::Drive; + +class Q_DECL_HIDDEN DrivesCreateJob::Private +{ + public: + Private(DrivesCreateJob *parent); + void processNext(); + + DrivesList drives; + QString requestId; + + private: + DrivesCreateJob *const q; +}; + +DrivesCreateJob::Private::Private(DrivesCreateJob *parent): + q(parent) +{ +} + +void DrivesCreateJob::Private::processNext() +{ + if (drives.isEmpty()) { + q->emitFinished(); + return; + } + + const DrivesPtr drive = drives.takeFirst(); + + QUrl url = DriveService::fetchDrivesUrl(); + + QUrlQuery query(url); + if (!requestId.isEmpty()) { + query.addQueryItem(RequestIdParam, requestId); + } + url.setQuery(query); + + QNetworkRequest request(url); + + const QByteArray rawData = Drives::toJSON(drive); + q->enqueueRequest(request, rawData, QStringLiteral("application/json")); +} + +DrivesCreateJob::DrivesCreateJob(const QString &requestId, + const DrivesPtr &drive, + const AccountPtr &account, + QObject *parent): + CreateJob(account, parent), + d(new Private(this)) +{ + d->requestId = requestId; + d->drives << drive; +} + +DrivesCreateJob::DrivesCreateJob(const QString &requestId, + const DrivesList &drives, + const AccountPtr &account, + QObject *parent): + CreateJob(account, parent), + d(new Private(this)) +{ + d->requestId = requestId; + d->drives = drives; +} + +DrivesCreateJob::~DrivesCreateJob() = default; + +QString DrivesCreateJob::requestId() const +{ + return d->requestId; +} + +void DrivesCreateJob::start() +{ + d->processNext(); +} + +ObjectsList DrivesCreateJob::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 << Drives::fromJSON(rawData); + } else { + setError(KGAPI2::InvalidResponse); + setErrorString(tr("Invalid response content type")); + emitFinished(); + return items; + } + + // Enqueue next item or finish + d->processNext(); + + return items; +} + + diff --git a/src/drive/teamdrivedeletejob.h b/src/drive/drivesdeletejob.h copy from src/drive/teamdrivedeletejob.h copy to src/drive/drivesdeletejob.h --- a/src/drive/teamdrivedeletejob.h +++ b/src/drive/drivesdeletejob.h @@ -21,8 +21,8 @@ */ -#ifndef KGAPI2_DRIVETEAMDRIVEDELETEJOB_H -#define KGAPI2_DRIVETEAMDRIVEDELETEJOB_H +#ifndef KGAPI2_DRIVEDRIVESDELETEJOB_H +#define KGAPI2_DRIVEDRIVESDELETEJOB_H #include "deletejob.h" #include "kgapidrive_export.h" @@ -33,20 +33,20 @@ namespace Drive { -class KGAPIDRIVE_EXPORT TeamdriveDeleteJob : public KGAPI2::DeleteJob +class KGAPIDRIVE_EXPORT DrivesDeleteJob : public KGAPI2::DeleteJob { Q_OBJECT public: - TeamdriveDeleteJob(const QString &teamdriveId, + DrivesDeleteJob(const QString &drivesId, const AccountPtr &account, QObject *parent = nullptr); - TeamdriveDeleteJob(const QStringList &teamdrivesIds, + DrivesDeleteJob(const QStringList &drivesIds, const AccountPtr &account, QObject *parent = nullptr); - TeamdriveDeleteJob(const TeamdrivePtr &teamdrive, + DrivesDeleteJob(const DrivesPtr &drives, const AccountPtr &account, QObject *parent = nullptr); - TeamdriveDeleteJob(const TeamdrivesList &teamdrives, + DrivesDeleteJob(const DrivesList &drives, const AccountPtr &account, QObject *parent = nullptr); - ~TeamdriveDeleteJob() override; + ~DrivesDeleteJob() override; protected: void start() override; @@ -61,4 +61,4 @@ } // namespace KGAPI2 -#endif // KGAPI2_DRIVETEAMDRIVEDELETEJOB_H +#endif // KGAPI2_DRIVEDRIVESDELETEJOB_H diff --git a/src/drive/drivesdeletejob.cpp b/src/drive/drivesdeletejob.cpp new file mode 100644 --- /dev/null +++ b/src/drive/drivesdeletejob.cpp @@ -0,0 +1,90 @@ +/* + * 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 "drivesdeletejob.h" +#include "drives.h" +#include "account.h" +#include "driveservice.h" + +#include + +using namespace KGAPI2; +using namespace KGAPI2::Drive; + +class Q_DECL_HIDDEN DrivesDeleteJob::Private +{ + public: + QStringList drivesIds; +}; + +DrivesDeleteJob::DrivesDeleteJob(const QString &drivesId, + const AccountPtr &account, QObject *parent): + DeleteJob(account, parent), + d(new Private) +{ + d->drivesIds << drivesId; +} + +DrivesDeleteJob::DrivesDeleteJob(const QStringList &drivesIds, + const AccountPtr &account, QObject *parent): + DeleteJob(account, parent), + d(new Private) +{ + d->drivesIds << drivesIds; +} + +DrivesDeleteJob::DrivesDeleteJob(const DrivesPtr &drives, + const AccountPtr &account, QObject *parent): + DeleteJob(account, parent), + d(new Private) +{ + d->drivesIds << drives->id(); +} + +DrivesDeleteJob::DrivesDeleteJob(const DrivesList &drives, + const AccountPtr &account, QObject *parent): + DeleteJob(account, parent), + d(new Private) +{ + for (const DrivesPtr & drives : qAsConst(drives)) { + d->drivesIds << drives->id(); + } +} + +DrivesDeleteJob::~DrivesDeleteJob() = default; + +void DrivesDeleteJob::start() +{ + if (d->drivesIds.isEmpty()) { + emitFinished(); + return; + } + + const QString drivesId = d->drivesIds.takeFirst(); + const QUrl url = DriveService::fetchDrivesUrl(drivesId); + + QNetworkRequest request(url); + enqueueRequest(request); +} + + 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,12 @@ KGAPIDRIVE_EXPORT QUrl modifyRevisionUrl(const QString &fileId, const QString &revisionId); + KGAPIDRIVE_EXPORT QUrl fetchDrivesUrl(const QString &drivesId); + + KGAPIDRIVE_EXPORT QUrl hideDrivesUrl(const QString &drivesId, bool hide); + + KGAPIDRIVE_EXPORT QUrl fetchDrivesUrl(); + KGAPIDRIVE_EXPORT QUrl fetchTeamdriveUrl(const QString &teamdriveId); KGAPIDRIVE_EXPORT QUrl fetchTeamdrivesUrl(); 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 DrivesBasePath(QStringLiteral("/drive/v2/drives")); static const QString TeamdriveBasePath(QStringLiteral("/drive/v2/teamdrives")); } @@ -287,6 +288,27 @@ return url; } +QUrl fetchDrivesUrl(const QString &drivesId) +{ + QUrl url(Private::GoogleApisUrl); + url.setPath(Private::DrivesBasePath % QLatin1Char('/') % drivesId); + return url; +} + +QUrl hideDrivesUrl(const QString &drivesId, bool hide) +{ + QUrl url(Private::GoogleApisUrl); + url.setPath(Private::DrivesBasePath % QLatin1Char('/') % drivesId % (hide ? QLatin1String("/hide") : QLatin1String("/unhide"))); + return url; +} + +QUrl fetchDrivesUrl() +{ + QUrl url(Private::GoogleApisUrl); + url.setPath(Private::DrivesBasePath); + return url; +} + QUrl fetchTeamdriveUrl(const QString &teamdriveId) { QUrl url(Private::GoogleApisUrl); diff --git a/src/drive/teamdrivefetchjob.h b/src/drive/drivesfetchjob.h copy from src/drive/teamdrivefetchjob.h copy to src/drive/drivesfetchjob.h --- a/src/drive/teamdrivefetchjob.h +++ b/src/drive/drivesfetchjob.h @@ -20,26 +20,27 @@ * License along with this library. If not, see . */ -#ifndef KGAPI2_DRIVETEAMDRIVEFETCHJOB_H -#define KGAPI2_DRIVETEAMDRIVEFETCHJOB_H +#ifndef KGAPI2_DRIVEDRIVESFETCHJOB_H +#define KGAPI2_DRIVEDRIVESFETCHJOB_H #include "fetchjob.h" #include "kgapidrive_export.h" -#include "teamdrivesearchquery.h" +#include "drivessearchquery.h" namespace KGAPI2 { namespace Drive { -class KGAPIDRIVE_EXPORT TeamdriveFetchJob : public KGAPI2::FetchJob +class KGAPIDRIVE_EXPORT DrivesFetchJob : public KGAPI2::FetchJob { Q_OBJECT /** - * Maximum number of teamdrives to return. + * Maximum number of shared drives to return. Acceptable + * values are 1 to 100, inclusive * * Default value if missing is 10. * @@ -52,7 +53,7 @@ /** * 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 + * shared Drives of the domain in which the requester is an administrator * are returned. * * Default value if missing is false. @@ -65,11 +66,11 @@ WRITE setUseDomainAdminAccess) public: - TeamdriveFetchJob(const TeamdriveSearchQuery &query, const AccountPtr &account, QObject *parent = nullptr); - TeamdriveFetchJob(const AccountPtr &account, QObject *parent = nullptr); - TeamdriveFetchJob(const QString &teamdriveId, const AccountPtr &account, + DrivesFetchJob(const DrivesSearchQuery &query, const AccountPtr &account, QObject *parent = nullptr); + DrivesFetchJob(const AccountPtr &account, QObject *parent = nullptr); + DrivesFetchJob(const QString &drivesId, const AccountPtr &account, QObject *parent = nullptr); - ~TeamdriveFetchJob() override; + ~DrivesFetchJob() override; int maxResults() const; void setMaxResults(int maxResults); @@ -97,4 +98,4 @@ } // namespace KGAPI2 -#endif // KGAPI2_DRIVETEAMDRIVEFETCHJOB_H +#endif // KGAPI2_DRIVEDRIVESFETCHJOB_H diff --git a/src/drive/drivesfetchjob.cpp b/src/drive/drivesfetchjob.cpp new file mode 100644 --- /dev/null +++ b/src/drive/drivesfetchjob.cpp @@ -0,0 +1,216 @@ +/* + * 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 "drivesfetchjob.h" +#include "account.h" +#include "drives.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 DrivesFetchJob::Private +{ + public: + Private(DrivesFetchJob *parent); + + DrivesSearchQuery searchQuery; + QString drivesId; + + int maxResults = 0; + QVariant useDomainAdminAccess; + + QStringList fields; + + private: + DrivesFetchJob *const q; +}; + +DrivesFetchJob::Private::Private(DrivesFetchJob *parent): + q(parent) +{ +} + +DrivesFetchJob::DrivesFetchJob(const QString &drivesId, + const AccountPtr &account, + QObject *parent): + FetchJob(account, parent), + d(new Private(this)) +{ + d->drivesId = drivesId; +} + +DrivesFetchJob::DrivesFetchJob(const DrivesSearchQuery &query, + const AccountPtr &account, QObject *parent): + FetchJob(account, parent), + d(new Private(this)) +{ + d->searchQuery = query; +} + +DrivesFetchJob::DrivesFetchJob(const AccountPtr &account, QObject *parent): + FetchJob(account, parent), + d(new Private(this)) +{ +} + +DrivesFetchJob::~DrivesFetchJob() = default; + +void DrivesFetchJob::setMaxResults(int maxResults) +{ + if (isRunning()) { + qCWarning(KGAPIDebug) << "Can't modify maxResults property when job is running"; + return; + } + + d->maxResults = maxResults; +} + +int DrivesFetchJob::maxResults() const +{ + return d->maxResults; +} + +void DrivesFetchJob::setUseDomainAdminAccess(bool useDomainAdminAccess) +{ + if (isRunning()) { + qCWarning(KGAPIDebug) << "Can't modify useDomainAdminAccess property when job is running"; + return; + } + + d->useDomainAdminAccess = useDomainAdminAccess; +} + +bool DrivesFetchJob::useDomainAdminAccess() const +{ + return d->useDomainAdminAccess.toBool(); +} + +void DrivesFetchJob::setFields(const QStringList &fields) +{ + if (isRunning()) { + qCWarning(KGAPIDebug) << "Called setFields() on running job. Ignoring."; + return; + } + + d->fields = fields; +} + +QStringList DrivesFetchJob::fields() const +{ + return d->fields; +} + +void DrivesFetchJob::start() +{ + QUrl url; + if (d->drivesId.isEmpty()) { + url = DriveService::fetchDrivesUrl(); + applyRequestParameters(url); + } else { + url = DriveService::fetchDrivesUrl(d->drivesId); + if (!d->fields.isEmpty()) { + // Deserializing requires kind attribute, always force add it + if (!d->fields.contains(Drives::Fields::Kind)) { + d->fields << Drives::Fields::Kind; + } + Job::setFields(d->fields); + } + } + + QNetworkRequest request(url); + enqueueRequest(request); +} + + +ObjectsList DrivesFetchJob::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->drivesId.isEmpty()) { + items << Drives::fromJSONFeed(rawData, feedData); + } else { + items << Drives::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); + QNetworkRequest request(feedData.nextPageUrl); + enqueueRequest(request); + } + + return items; +} + + +void DrivesFetchJob::applyRequestParameters(QUrl &url) { + QUrlQuery query(url); + if (d->maxResults != 0) { + query.addQueryItem(MaxResultsAttr, QString::number(d->maxResults)); + } + if (!d->useDomainAdminAccess.isNull()) { + query.addQueryItem(UseDomainAdminAccessAttr, d->useDomainAdminAccess.toBool() ? True : False); + } + if (!d->searchQuery.isEmpty()) { + query.addQueryItem(QStringLiteral("q"), d->searchQuery.serialize()); + } + if (!d->fields.isEmpty()) { + // Deserializing requires kind attribute, always force add it + if (!d->fields.contains(Drives::Fields::Kind)) { + d->fields << Drives::Fields::Kind; + } + QString itemFields = Job::buildSubfields(Drives::Fields::Items, d->fields); + Job::setFields({ + Drives::Fields::Kind, + Drives::Fields::NextPageToken, + itemFields + }); + } + url.setQuery(query); +} diff --git a/src/drive/teamdrivecreatejob.h b/src/drive/driveshidejob.h copy from src/drive/teamdrivecreatejob.h copy to src/drive/driveshidejob.h --- a/src/drive/teamdrivecreatejob.h +++ b/src/drive/driveshidejob.h @@ -20,8 +20,8 @@ * License along with this library. If not, see . */ -#ifndef KGAPI2_DRIVETEAMDRIVECREATEJOB_H -#define KGAPI2_DRIVETEAMDRIVECREATEJOB_H +#ifndef KGAPI2_DRIVEDRIVESHIDEJOB_H +#define KGAPI2_DRIVEDRIVESHIDEJOB_H #include "createjob.h" #include "kgapidrive_export.h" @@ -32,23 +32,18 @@ namespace Drive { -class KGAPIDRIVE_EXPORT TeamdriveCreateJob : public KGAPI2::CreateJob +class KGAPIDRIVE_EXPORT DrivesHideJob : public KGAPI2::CreateJob { Q_OBJECT public: - TeamdriveCreateJob(const QString &requestId, - const TeamdrivePtr &teamdrive, + DrivesHideJob(const DrivesPtr &drives, + bool hide, const AccountPtr &account, QObject *parent = nullptr); - TeamdriveCreateJob(const QString &requestId, - const TeamdrivesList &teamdrives, + DrivesHideJob(const DrivesList &drives, + bool hide, const AccountPtr &account, QObject *parent = nullptr); - ~TeamdriveCreateJob() override; - - /** - * @brief Returns the requestId used in this create request. - */ - QString requestId() const; + ~DrivesHideJob() override; protected: void start() override; @@ -65,4 +60,4 @@ } // namespace KGAPI2 -#endif // KGAPI2_DRIVETEAMDRIVECREATEJOB_H +#endif // KGAPI2_DRIVEDRIVESHIDEJOB_H diff --git a/src/drive/driveshidejob.cpp b/src/drive/driveshidejob.cpp new file mode 100644 --- /dev/null +++ b/src/drive/driveshidejob.cpp @@ -0,0 +1,123 @@ +/* + * 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 "driveshidejob.h" +#include "account.h" +#include "driveservice.h" +#include "drives.h" +#include "utils.h" + +#include +#include +#include + + +using namespace KGAPI2; +using namespace KGAPI2::Drive; + +class Q_DECL_HIDDEN DrivesHideJob::Private +{ + public: + Private(DrivesHideJob *parent); + void processNext(); + + bool hide = false; + + DrivesList drives; + + private: + DrivesHideJob *const q; +}; + +DrivesHideJob::Private::Private(DrivesHideJob *parent): + q(parent) +{ +} + +void DrivesHideJob::Private::processNext() +{ + if (drives.isEmpty()) { + q->emitFinished(); + return; + } + + const DrivesPtr drive = drives.takeFirst(); + + QUrl url = DriveService::hideDrivesUrl(drive->id(), hide); + + QNetworkRequest request(url); + + // A hide request doesn't have a body + q->enqueueRequest(request, nullptr, QStringLiteral("application/json")); +} + +DrivesHideJob::DrivesHideJob(const DrivesPtr &drive, + bool hide, + const AccountPtr &account, + QObject *parent): + CreateJob(account, parent), + d(new Private(this)) +{ + d->drives << drive; + d->hide = hide; +} + +DrivesHideJob::DrivesHideJob(const DrivesList &drives, + bool hide, + const AccountPtr &account, + QObject *parent): + CreateJob(account, parent), + d(new Private(this)) +{ + d->drives = drives; + d->hide = hide; +} + +DrivesHideJob::~DrivesHideJob() = default; + +void DrivesHideJob::start() +{ + d->processNext(); +} + +ObjectsList DrivesHideJob::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 << Drives::fromJSON(rawData); + } else { + setError(KGAPI2::InvalidResponse); + setErrorString(tr("Invalid response content type")); + emitFinished(); + return items; + } + + // Enqueue next item or finish + d->processNext(); + + return items; +} + + diff --git a/src/drive/teamdrivemodifyjob.h b/src/drive/drivesmodifyjob.h copy from src/drive/teamdrivemodifyjob.h copy to src/drive/drivesmodifyjob.h --- a/src/drive/teamdrivemodifyjob.h +++ b/src/drive/drivesmodifyjob.h @@ -21,8 +21,8 @@ */ -#ifndef KGAPI2_DRIVETEAMDRIVEMODIFYJOB_H -#define KGAPI2_DRIVETEAMDRIVEMODIFYJOB_H +#ifndef KGAPI2_DRIVEDRIVESMODIFYJOB_H +#define KGAPI2_DRIVEDRIVESMODIFYJOB_H #include "modifyjob.h" #include "kgapidrive_export.h" @@ -33,16 +33,33 @@ namespace Drive { -class KGAPIDRIVE_EXPORT TeamdriveModifyJob : public KGAPI2::ModifyJob +class KGAPIDRIVE_EXPORT DrivesModifyJob : public KGAPI2::ModifyJob { Q_OBJECT + /** + * Issue the request as a domain administrator; if set to true, then all + * shared 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: - explicit TeamdriveModifyJob(const TeamdrivePtr &teamdrive, + explicit DrivesModifyJob(const DrivesPtr &drives, const AccountPtr &account, QObject *parent = nullptr); - explicit TeamdriveModifyJob(const TeamdrivesList &teamdrives, + explicit DrivesModifyJob(const DrivesList &drives, const AccountPtr &account, QObject *parent = nullptr); - ~TeamdriveModifyJob() override; + ~DrivesModifyJob() override; + + void setUseDomainAdminAccess(bool useDomainAdminAccess); + bool useDomainAdminAccess() const; protected: void start() override; @@ -59,4 +76,4 @@ } // namespace KGAPI2 -#endif // KGAPI2_DRIVETEAMDRIVEMODIFYJOB_H +#endif // KGAPI2_DRIVEDRIVESMODIFYJOB_H diff --git a/src/drive/drivesmodifyjob.cpp b/src/drive/drivesmodifyjob.cpp new file mode 100644 --- /dev/null +++ b/src/drive/drivesmodifyjob.cpp @@ -0,0 +1,146 @@ +/* + * 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 "drivesmodifyjob.h" +#include "account.h" +#include "driveservice.h" +#include "drives.h" +#include "utils.h" +#include "../debug.h" + +#include +#include +#include + + +namespace { + 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 DrivesModifyJob::Private +{ + public: + Private(DrivesModifyJob *parent); + void processNext(); + + bool useDomainAdminAccess = false; + + DrivesList drives; + + private: + DrivesModifyJob *const q; +}; + +DrivesModifyJob::Private::Private(DrivesModifyJob *parent): + q(parent) +{ +} + +void DrivesModifyJob::setUseDomainAdminAccess(bool useDomainAdminAccess) +{ + if (isRunning()) { + qCWarning(KGAPIDebug) << "Can't modify useDomainAdminAccess property when job is running"; + return; + } + + d->useDomainAdminAccess = useDomainAdminAccess; +} + +bool DrivesModifyJob::useDomainAdminAccess() const +{ + return d->useDomainAdminAccess; +} + +void DrivesModifyJob::Private::processNext() +{ + if (drives.isEmpty()) { + q->emitFinished(); + return; + } + + const DrivesPtr drive = drives.takeFirst(); + QUrl url = DriveService::fetchDrivesUrl(drive->id()); + + QUrlQuery query(url); + if (useDomainAdminAccess != false) { + query.addQueryItem(UseDomainAdminAccessAttr, useDomainAdminAccess ? True : False); + } + url.setQuery(query); + + QNetworkRequest request(url); + + const QByteArray rawData = Drives::toJSON(drive); + q->enqueueRequest(request, rawData, QStringLiteral("application/json")); +} + +DrivesModifyJob::DrivesModifyJob(const DrivesPtr &drive, + const AccountPtr &account, + QObject *parent): + ModifyJob(account, parent), + d(new Private(this)) +{ + d->drives << drive; +} + +DrivesModifyJob::DrivesModifyJob(const DrivesList &drives, + const AccountPtr &account, + QObject *parent): + ModifyJob(account, parent), + d(new Private(this)) +{ + d->drives << drives; +} + +DrivesModifyJob::~DrivesModifyJob() = default; + +void DrivesModifyJob::start() +{ + d->processNext(); +} + +ObjectsList DrivesModifyJob::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 << Drives::fromJSON(rawData); + } else { + setError(KGAPI2::InvalidResponse); + setErrorString(tr("Invalid response content type")); + emitFinished(); + return items; + } + + // Enqueue next item or finish + d->processNext(); + + return items; +} + + diff --git a/src/drive/teamdrivemodifyjob.h b/src/drive/drivessearchquery.h copy from src/drive/teamdrivemodifyjob.h copy to src/drive/drivessearchquery.h --- a/src/drive/teamdrivemodifyjob.h +++ b/src/drive/drivessearchquery.h @@ -1,6 +1,4 @@ /* - * This file is part of LibKGAPI library - * * Copyright (C) 2019 David Barchiesi * * This library is free software; you can redistribute it and/or @@ -20,43 +18,49 @@ * License along with this library. If not, see . */ +#ifndef KGAPI2_DRIVE_DRIVESSEARCHQUERY_H +#define KGAPI2_DRIVE_DRIVESSEARCHQUERY_H -#ifndef KGAPI2_DRIVETEAMDRIVEMODIFYJOB_H -#define KGAPI2_DRIVETEAMDRIVEMODIFYJOB_H - -#include "modifyjob.h" #include "kgapidrive_export.h" +#include "searchquery.h" + +#include +#include + namespace KGAPI2 { - namespace Drive { -class KGAPIDRIVE_EXPORT TeamdriveModifyJob : public KGAPI2::ModifyJob +/** + * DrivesSearchQuery class allows simply building even complex shared drive search queries + * for DrivesFetchJob. + * + * See https://developers.google.com/drive/api/v2/search-shareddrives for allowed + * combinations of fields, compare operators, and value types. + */ +class KGAPIDRIVE_EXPORT DrivesSearchQuery : public SearchQuery { - Q_OBJECT - - public: - explicit TeamdriveModifyJob(const TeamdrivePtr &teamdrive, - const AccountPtr &account, QObject *parent = nullptr); - explicit TeamdriveModifyJob(const TeamdrivesList &teamdrives, - const AccountPtr &account, QObject *parent = nullptr); - ~TeamdriveModifyJob() override; - - protected: - void start() override; - KGAPI2::ObjectsList handleReplyWithItems(const QNetworkReply *reply, - const QByteArray &rawData) override; - - private: - class Private; - QScopedPointer d; - friend class Private; -}; +public: + enum Field { + Name, + Hidden, + CreatedDate, + MemberCount, + OrganizerCount + }; -} // namespace Drive + using SearchQuery::SearchQuery; -} // namespace KGAPI2 + using SearchQuery::addQuery; + void addQuery(Field field, CompareOperator op, const QVariant &value); + +private: + QString fieldToString(Field field); + QString valueToString(DrivesSearchQuery::Field field, const QVariant &var); +}; +} +} -#endif // KGAPI2_DRIVETEAMDRIVEMODIFYJOB_H +#endif // KGAPI2_DRIVE_DRIVESSEARCHQUERY_H diff --git a/src/drive/drivessearchquery.cpp b/src/drive/drivessearchquery.cpp new file mode 100644 --- /dev/null +++ b/src/drive/drivessearchquery.cpp @@ -0,0 +1,90 @@ +/* + * 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 "drivessearchquery.h" + +#include +#include + +using namespace KGAPI2; +using namespace KGAPI2::Drive; + + +QString DrivesSearchQuery::fieldToString(Field field) +{ + switch (field) { + case Name: + return QStringLiteral("name"); + case Hidden: + return QStringLiteral("hidden"); + case CreatedDate: + return QStringLiteral("createdDate"); + case MemberCount: + return QStringLiteral("memberCount"); + case OrganizerCount: + return QStringLiteral("organizerCount"); + } + + Q_ASSERT(false); + return QString(); +} + +QString DrivesSearchQuery::valueToString(DrivesSearchQuery::Field field, const QVariant &var) +{ + switch (field) { + case Name: + return QStringLiteral("'%1'").arg(var.toString().replace(QLatin1Char('\''), QLatin1String("\\\'"))); + case Hidden: + return (var.toBool() == true ? QStringLiteral("true") : QStringLiteral("false")); + case MemberCount: + case OrganizerCount: + return var.toString(); + case CreatedDate: + return QStringLiteral("'%1'").arg(var.toDateTime().toUTC().toString(QStringLiteral("yyyy-MM-ddThh:mm:ss"))); + } + + Q_ASSERT(false); + return QString(); +} + +void DrivesSearchQuery::addQuery(DrivesSearchQuery::Field field, DrivesSearchQuery::CompareOperator op, const QVariant &value) +{ + switch (field) { + case Name: + Q_ASSERT(op == Contains || op == Equals || op == NotEquals); + Q_ASSERT(value.canConvert()); + break; + case Hidden: + Q_ASSERT(op == Equals || op == NotEquals); + Q_ASSERT(value.canConvert()); + break; + case MemberCount: + case OrganizerCount: + Q_ASSERT(op == LessOrEqual || op == Less || op == Equals || op == NotEquals || op == Greater || op == GreaterOrEqual); + Q_ASSERT(value.canConvert()); + break; + case CreatedDate: + Q_ASSERT(op == LessOrEqual || op == Less || op == Equals || op == NotEquals || op == Greater || op == GreaterOrEqual); + Q_ASSERT(value.canConvert()); + break; + } + + SearchQuery::addQuery(fieldToString(field), op, valueToString(field, value)); +} diff --git a/src/drive/teamdrivecreatejob.h b/src/drive/teamdrivecreatejob.h --- a/src/drive/teamdrivecreatejob.h +++ b/src/drive/teamdrivecreatejob.h @@ -32,7 +32,7 @@ namespace Drive { -class KGAPIDRIVE_EXPORT TeamdriveCreateJob : public KGAPI2::CreateJob +class KGAPIDRIVE_DEPRECATED_EXPORT TeamdriveCreateJob : public KGAPI2::CreateJob { Q_OBJECT diff --git a/src/drive/teamdrivedeletejob.h b/src/drive/teamdrivedeletejob.h --- a/src/drive/teamdrivedeletejob.h +++ b/src/drive/teamdrivedeletejob.h @@ -33,7 +33,7 @@ namespace Drive { -class KGAPIDRIVE_EXPORT TeamdriveDeleteJob : public KGAPI2::DeleteJob +class KGAPIDRIVE_DEPRECATED_EXPORT TeamdriveDeleteJob : public KGAPI2::DeleteJob { Q_OBJECT diff --git a/src/drive/teamdrivefetchjob.h b/src/drive/teamdrivefetchjob.h --- a/src/drive/teamdrivefetchjob.h +++ b/src/drive/teamdrivefetchjob.h @@ -34,7 +34,7 @@ namespace Drive { -class KGAPIDRIVE_EXPORT TeamdriveFetchJob : public KGAPI2::FetchJob +class KGAPIDRIVE_DEPRECATED_EXPORT TeamdriveFetchJob : public KGAPI2::FetchJob { Q_OBJECT diff --git a/src/drive/teamdrivemodifyjob.h b/src/drive/teamdrivemodifyjob.h --- a/src/drive/teamdrivemodifyjob.h +++ b/src/drive/teamdrivemodifyjob.h @@ -33,7 +33,7 @@ namespace Drive { -class KGAPIDRIVE_EXPORT TeamdriveModifyJob : public KGAPI2::ModifyJob +class KGAPIDRIVE_DEPRECATED_EXPORT TeamdriveModifyJob : public KGAPI2::ModifyJob { Q_OBJECT