diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt index 2fe2c90..9502dae 100644 --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -1,78 +1,79 @@ include(ECMAddTests) find_package(Qt5Test CONFIG REQUIRED) set(kgapitest_SRCS fakeaccountstorage.cpp fakeauthwidget.cpp fakenetworkreply.cpp fakenetworkaccessmanager.cpp fakenetworkaccessmanagerfactory.cpp testutils.cpp ) add_library(kgapitest STATIC ${kgapitest_SRCS}) target_link_libraries(kgapitest Qt5::Core Qt5::Network Qt5::Test KPimGAPICore) macro(add_libkgapi2_test _module _testname) set(testSources ${_module}/${_testname}.cpp) string(SUBSTRING ${_module} 0 1 moduleFirst) string(SUBSTRING ${_module} 1 -1 moduleLast) string(TOUPPER ${moduleFirst} moduleFirst) string(CONCAT moduleName ${moduleFirst} ${moduleLast}) set(extraLibs "KPimGAPI${moduleName}") set(utilsFile ${CMAKE_CURRENT_SOURCE_DIR}/${_module}/${_module}testutils.cpp) if (EXISTS ${utilsFile}) list(APPEND testSources ${utilsFile}) endif() ecm_add_test(${testSources} LINK_LIBRARIES kgapitest KPimGAPICore ${extraLibs} TEST_NAME ${_testname} NAME_PREFIX ${_module}- ) endmacro(add_libkgapi2_test) ecm_add_test(fakenamtest.cpp LINK_LIBRARIES kgapitest KPimGAPICore TEST_NAME fakenamtest NAME_PREFIX fake-) add_libkgapi2_test(core accountinfofetchjobtest) add_libkgapi2_test(core accountmanagertest) add_libkgapi2_test(core createjobtest) add_libkgapi2_test(core fetchjobtest) add_libkgapi2_test(contacts contactcreatejobtest) add_libkgapi2_test(contacts contactdeletejobtest) add_libkgapi2_test(contacts contactfetchjobtest) add_libkgapi2_test(contacts contactfetchphotojobtest) add_libkgapi2_test(contacts contactmodifyjobtest) add_libkgapi2_test(contacts contactsgroupcreatejobtest) add_libkgapi2_test(contacts contactsgroupdeletejobtest) add_libkgapi2_test(contacts contactsgroupfetchjobtest) add_libkgapi2_test(contacts contactsgroupmodifyjobtest) add_libkgapi2_test(calendar calendarcreatejobtest) add_libkgapi2_test(calendar calendardeletejobtest) add_libkgapi2_test(calendar calendarfetchjobtest) add_libkgapi2_test(calendar calendarmodifyjobtest) add_libkgapi2_test(calendar eventcreatejobtest) add_libkgapi2_test(calendar eventdeletejobtest) add_libkgapi2_test(calendar eventfetchjobtest) add_libkgapi2_test(calendar eventmodifyjobtest) add_libkgapi2_test(calendar freebusyqueryjobtest) add_libkgapi2_test(tasks taskcreatejobtest) add_libkgapi2_test(tasks taskdeletejobtest) add_libkgapi2_test(tasks taskfetchjobtest) add_libkgapi2_test(tasks taskmodifyjobtest) add_libkgapi2_test(tasks taskmovejobtest) add_libkgapi2_test(tasks tasklistcreatejobtest) add_libkgapi2_test(tasks tasklistdeletejobtest) add_libkgapi2_test(tasks tasklistfetchjobtest) add_libkgapi2_test(tasks tasklistmodifyjobtest) add_libkgapi2_test(drive aboutfetchjobtest) add_libkgapi2_test(drive changefetchjobtest) add_libkgapi2_test(drive filecopyjobtest) add_libkgapi2_test(drive filecreatejobtest) add_libkgapi2_test(drive filesearchquerytest) add_libkgapi2_test(drive teamdrivefetchjobtest) +add_libkgapi2_test(drive teamdrivesearchquerytest) diff --git a/autotests/drive/teamdrivesearchquerytest.cpp b/autotests/drive/teamdrivesearchquerytest.cpp new file mode 100644 index 0000000..13cc0d6 --- /dev/null +++ b/autotests/drive/teamdrivesearchquerytest.cpp @@ -0,0 +1,99 @@ +/* + * 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 "teamdrivesearchquery.h" + +using namespace KGAPI2; +using namespace KGAPI2::Drive; + +Q_DECLARE_METATYPE(KGAPI2::Drive::TeamdriveSearchQuery) + +class TeamdriveSearchQueryTest: public QObject +{ + Q_OBJECT +public: + explicit TeamdriveSearchQueryTest() {} + + ~TeamdriveSearchQueryTest() {} + +private Q_SLOTS: + void testTeamdriveSearchQuery_data() + { + QTest::addColumn("query"); + QTest::addColumn("expected"); + + { + TeamdriveSearchQuery query; + query.addQuery(TeamdriveSearchQuery::CreatedTime, TeamdriveSearchQuery::Equals, QDateTime(QDate(2019, 3, 5), QTime(6, 36, 0), Qt::UTC)); + QTest::newRow("serialize time") << query + << "((createdTime = '2019-03-05T06:36:00'))"; + } + + { + TeamdriveSearchQuery query; + query.addQuery(TeamdriveSearchQuery::Name, TeamdriveSearchQuery::Contains, QLatin1String("Some String")); + QTest::newRow("contains") << query + << "((name contains 'Some String'))"; + } + + { + TeamdriveSearchQuery query; + query.addQuery(TeamdriveSearchQuery::Name, TeamdriveSearchQuery::Contains, QLatin1String("Name")); + query.addQuery(TeamdriveSearchQuery::MemberCount, TeamdriveSearchQuery::Equals, 5); + QTest::newRow("A and B") << query + << "((name contains 'Name') and (memberCount = 5))"; + } + + { + TeamdriveSearchQuery query(TeamdriveSearchQuery::Or); + query.addQuery(TeamdriveSearchQuery::Name, TeamdriveSearchQuery::Contains, QLatin1String("Name")); + query.addQuery(TeamdriveSearchQuery::OrganizerCount, TeamdriveSearchQuery::Equals, 5); + QTest::newRow("A or B") << query + << "((name contains 'Name') or (organizerCount = 5))"; + } + + { + TeamdriveSearchQuery query(TeamdriveSearchQuery::Or); + query.addQuery(TeamdriveSearchQuery::CreatedTime, TeamdriveSearchQuery::Equals, QDateTime(QDate(2019, 3, 5), QTime(6, 36, 0), Qt::UTC)); + TeamdriveSearchQuery subquery; + subquery.addQuery(TeamdriveSearchQuery::Name, TeamdriveSearchQuery::Equals, QLatin1String("Test")); + subquery.addQuery(TeamdriveSearchQuery::MemberCount, TeamdriveSearchQuery::LessOrEqual, 10); + query.addQuery(subquery); + QTest::newRow("A or (B and C)") << query + << "((createdTime = '2019-03-05T06:36:00') or ((name = 'Test') and (memberCount <= 10)))"; + } + } + + void testTeamdriveSearchQuery() + { + QFETCH(TeamdriveSearchQuery, query); + QFETCH(QString, expected); + + const QString serialized = query.serialize(); + QCOMPARE(serialized, expected); + } +}; + +QTEST_GUILESS_MAIN(TeamdriveSearchQueryTest) + +#include "teamdrivesearchquerytest.moc" diff --git a/examples/teamdrive/mainwindow.cpp b/examples/teamdrive/mainwindow.cpp index 32c2362..3d9a04a 100644 --- a/examples/teamdrive/mainwindow.cpp +++ b/examples/teamdrive/mainwindow.cpp @@ -1,183 +1,187 @@ /* 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 MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), m_ui(new Ui::MainWindow) { /* Initialize GUI */ m_ui->setupUi(this); m_ui->errorLabel->setVisible(false); connect(m_ui->authButton, &QAbstractButton::clicked, this, &MainWindow::authenticate); connect(m_ui->teamdriveListButton, &QAbstractButton::clicked, this, &MainWindow::fetchTeamdriveList); connect(m_ui->teamdriveList, &QListWidget::itemSelectionChanged, this, &MainWindow::teamdriveSelected); } MainWindow::~MainWindow() { delete m_ui; } void MainWindow::authenticate() { KGAPI2::AccountPtr account(new KGAPI2::Account); account->setScopes( QList() << KGAPI2::Account::driveScopeUrl() ); /* Create AuthJob to retrieve OAuth tokens for the account */ KGAPI2::AuthJob *authJob = new KGAPI2::AuthJob( account, QStringLiteral("554041944266.apps.googleusercontent.com"), QStringLiteral("mdT1DjzohxN3npUUzkENT0gO")); connect(authJob, &KGAPI2::Job::finished, this, &MainWindow::slotAuthJobFinished); } void MainWindow::slotAuthJobFinished(KGAPI2::Job *job) { KGAPI2::AuthJob *authJob = qobject_cast(job); Q_ASSERT(authJob); /* Always remember to delete the jobs, otherwise your application will * leak memory. */ authJob->deleteLater(); if (authJob->error() != KGAPI2::NoError) { m_ui->errorLabel->setText(QStringLiteral("Error: %1").arg(authJob->errorString())); m_ui->errorLabel->setVisible(true); return; } m_account = authJob->account(); m_ui->authStatusLabel->setText(QStringLiteral("Authenticated")); m_ui->teamdriveListButton->setEnabled(true); m_ui->authButton->setEnabled(false); } void MainWindow::fetchTeamdriveList() { if (m_account.isNull()) { m_ui->errorLabel->setText(QStringLiteral("Error: Please authenticate first")); m_ui->errorLabel->setVisible(true); m_ui->authButton->setVisible(true); return; } - KGAPI2::Drive::TeamdriveFetchJob *fetchJob = new KGAPI2::Drive::TeamdriveFetchJob(m_account, this); + KGAPI2::Drive::TeamdriveSearchQuery query; + query.addQuery(KGAPI2::Drive::TeamdriveSearchQuery::MemberCount, KGAPI2::Drive::TeamdriveSearchQuery::Less, 10); + + KGAPI2::Drive::TeamdriveFetchJob *fetchJob = new KGAPI2::Drive::TeamdriveFetchJob(query, m_account, this); connect(fetchJob, &KGAPI2::Job::finished, this, &MainWindow::slotFetchJobFinished); m_ui->teamdriveListButton->setEnabled(false); } void MainWindow::slotFetchJobFinished(KGAPI2::Job *job) { KGAPI2::Drive::TeamdriveFetchJob *fetchJob = qobject_cast(job); Q_ASSERT(fetchJob); fetchJob->deleteLater(); if (fetchJob->error() != KGAPI2::NoError) { m_ui->errorLabel->setText(QStringLiteral("Error: %1").arg(fetchJob->errorString())); m_ui->errorLabel->setVisible(true); m_ui->teamdriveListButton->setEnabled(true); return; } /* Get all items the job has retrieved */ const KGAPI2::ObjectsList objects = fetchJob->items(); for (const KGAPI2::ObjectPtr &object : objects) { const KGAPI2::Drive::TeamdrivePtr teamdrive = object.dynamicCast(); /* Convert the teamdrive to QListWidget item */ QListWidgetItem *item = new QListWidgetItem(m_ui->teamdriveList); item->setText(teamdrive->name()); item->setData(Qt::UserRole, teamdrive->id()); m_ui->teamdriveList->addItem(item); } m_ui->teamdriveListButton->setEnabled(true); } void MainWindow::teamdriveSelected() { if (m_ui->teamdriveList->selectedItems().count() == 0) { m_ui->teamdrivePreview->clear(); return; } const QString id = m_ui->teamdriveList->selectedItems().at(0)->data(Qt::UserRole).toString(); KGAPI2::Drive::FileSearchQuery query; query.addQuery(KGAPI2::Drive::FileSearchQuery::Trashed, KGAPI2::Drive::FileSearchQuery::Equals, false); query.addQuery(KGAPI2::Drive::FileSearchQuery::Parents, KGAPI2::Drive::FileSearchQuery::In, id); KGAPI2::Drive::FileFetchJob *fileFetchJob = new KGAPI2::Drive::FileFetchJob(query, m_account, nullptr); fileFetchJob->setIncludeTeamDriveItems(true); fileFetchJob->setFields((KGAPI2::Drive::FileFetchJob::BasicFields & ~KGAPI2::Drive::FileFetchJob::Permissions) | KGAPI2::Drive::FileFetchJob::Labels | KGAPI2::Drive::FileFetchJob::ExportLinks | KGAPI2::Drive::FileFetchJob::LastViewedByMeDate); connect(fileFetchJob, &KGAPI2::Job::finished, this, &MainWindow::slotTeamdriveFetchJobFinished); } void MainWindow::slotTeamdriveFetchJobFinished(KGAPI2::Job *job) { KGAPI2::Drive::FileFetchJob *fetchJob = qobject_cast(job); Q_ASSERT(fetchJob); fetchJob->deleteLater(); if (fetchJob->error() != KGAPI2::NoError) { m_ui->errorLabel->setText(QStringLiteral("Error: %1").arg(fetchJob->errorString())); m_ui->errorLabel->setVisible(true); m_ui->teamdriveListButton->setEnabled(true); return; } /* Get all items we have received from Google (should be just one) */ KGAPI2::ObjectsList objects = fetchJob->items(); QString text; Q_FOREACH (const KGAPI2::ObjectPtr &object, objects) { const KGAPI2::Drive::FilePtr file = object.dynamicCast(); text += QStringLiteral("%1").arg(file->title()); text += QLatin1Char('\n'); } m_ui->teamdrivePreview->setText(text); } diff --git a/src/drive/CMakeLists.txt b/src/drive/CMakeLists.txt index aca159b..64d46a8 100644 --- a/src/drive/CMakeLists.txt +++ b/src/drive/CMakeLists.txt @@ -1,146 +1,148 @@ set(kgapidrive_SRCS about.cpp aboutfetchjob.cpp app.cpp appfetchjob.cpp change.cpp changefetchjob.cpp childreference.cpp childreferencecreatejob.cpp childreferencedeletejob.cpp childreferencefetchjob.cpp driveservice.cpp searchquery.cpp file.cpp fileabstractdatajob.cpp fileabstractmodifyjob.cpp fileabstractuploadjob.cpp filecopyjob.cpp filecreatejob.cpp filedeletejob.cpp filefetchcontentjob.cpp filefetchjob.cpp filemodifyjob.cpp filesearchquery.cpp filetouchjob.cpp filetrashjob.cpp fileuntrashjob.cpp parentreference.cpp parentreferencecreatejob.cpp parentreferencedeletejob.cpp parentreferencefetchjob.cpp permission.cpp permissioncreatejob.cpp permissiondeletejob.cpp permissionfetchjob.cpp permissionmodifyjob.cpp revision.cpp revisiondeletejob.cpp revisionfetchjob.cpp revisionmodifyjob.cpp teamdrive.cpp teamdrivefetchjob.cpp + teamdrivesearchquery.cpp user.cpp ../debug.cpp ) ecm_generate_headers(kgapidrive_CamelCase_HEADERS HEADER_NAMES About AboutFetchJob App AppFetchJob Change ChangeFetchJob ChildReference ChildReferenceCreateJob ChildReferenceDeleteJob ChildReferenceFetchJob SearchQuery File FileAbstractDataJob FileAbstractModifyJob FileAbstractUploadJob FileCopyJob FileCreateJob FileDeleteJob FileFetchContentJob FileFetchJob FileModifyJob FileSearchQuery FileTouchJob FileTrashJob FileUntrashJob ParentReference ParentReferenceCreateJob ParentReferenceDeleteJob ParentReferenceFetchJob Permission PermissionCreateJob PermissionDeleteJob PermissionFetchJob PermissionModifyJob Revision RevisionDeleteJob RevisionFetchJob RevisionModifyJob Teamdrive TeamdriveFetchJob + TeamdriveSearchQuery User PREFIX KGAPI/Drive REQUIRED_HEADERS kgapidrive_HEADERS ) add_library(KPimGAPIDrive ${kgapidrive_SRCS} ) generate_export_header(KPimGAPIDrive BASE_NAME kgapidrive) add_library(KPim::GAPIDrive ALIAS KPimGAPIDrive) # TODO: Backwards compatibility, remove in next major release add_library(KF5::GAPIDrive ALIAS KPimGAPIDrive) target_include_directories(KPimGAPIDrive INTERFACE "$") target_link_libraries(KPimGAPIDrive PUBLIC KPim::GAPICore PRIVATE Qt5::Network ) set_target_properties(KPimGAPIDrive PROPERTIES VERSION ${KGAPI_VERSION_STRING} SOVERSION ${KGAPI_SOVERSION} EXPORT_NAME GAPIDrive ) install(TARGETS KPimGAPIDrive EXPORT KPimGAPITargets ${KDE_INSTALL_TARGETS_DEFAULT_ARGS} ) install(FILES ${kgapidrive_CamelCase_HEADERS} DESTINATION "${KDE_INSTALL_INCLUDEDIR}/KPim/KGAPI/KGAPI/Drive" COMPONENT Devel ) install(FILES ${kgapidrive_HEADERS} "${CMAKE_CURRENT_BINARY_DIR}/kgapidrive_export.h" DESTINATION "${KDE_INSTALL_INCLUDEDIR}/KPim/KGAPI/kgapi/drive" COMPONENT Devel ) ecm_generate_pri_file(BASE_NAME KGAPIDrive LIB_NAME KPimGAPIDrive DEPS "GAPICore" FILENAME_VAR PRI_FILENAME INCLUDE_INSTALL_DIR "${KDE_INSTALL_INCLUDEDIR}/KPim/KGAPI" ) install(FILES "${PRI_FILENAME}" DESTINATION "${ECM_MKSPECS_INSTALL_DIR}" ) diff --git a/src/drive/teamdrivefetchjob.cpp b/src/drive/teamdrivefetchjob.cpp index db6d70b..ea59b67 100644 --- a/src/drive/teamdrivefetchjob.cpp +++ b/src/drive/teamdrivefetchjob.cpp @@ -1,179 +1,192 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2019 David Barchiesi * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "teamdrivefetchjob.h" #include "account.h" #include "teamdrive.h" #include "../debug.h" #include "driveservice.h" #include "utils.h" #include #include #include namespace { static const QString MaxResultsAttr = QStringLiteral("maxResults"); static const QString UseDomainAdminAccessAttr = QStringLiteral("useDomainAdminAccess"); static const QString True = QStringLiteral("true"); static const QString False = QStringLiteral("false"); } using namespace KGAPI2; using namespace KGAPI2::Drive; class Q_DECL_HIDDEN TeamdriveFetchJob::Private { public: Private(TeamdriveFetchJob *parent); QNetworkRequest createRequest(const QUrl &url); + TeamdriveSearchQuery searchQuery; QString teamdriveId; int maxResults = 0; bool useDomainAdminAccess = false; private: TeamdriveFetchJob *const q; }; TeamdriveFetchJob::Private::Private(TeamdriveFetchJob *parent): q(parent) { } QNetworkRequest TeamdriveFetchJob::Private::createRequest(const QUrl &url) { QNetworkRequest request; request.setRawHeader("Authorization", "Bearer " + q->account()->accessToken().toLatin1()); request.setUrl(url); return request; } TeamdriveFetchJob::TeamdriveFetchJob(const QString &teamdriveId, const AccountPtr &account, QObject *parent): FetchJob(account, parent), d(new Private(this)) { d->teamdriveId = teamdriveId; } +TeamdriveFetchJob::TeamdriveFetchJob(const TeamdriveSearchQuery &query, + const AccountPtr &account, QObject *parent): + FetchJob(account, parent), + d(new Private(this)) +{ + d->useDomainAdminAccess = true; + d->searchQuery = query; +} + TeamdriveFetchJob::TeamdriveFetchJob(const AccountPtr &account, QObject *parent): FetchJob(account, parent), d(new Private(this)) { } TeamdriveFetchJob::~TeamdriveFetchJob() = default; void TeamdriveFetchJob::setMaxResults(int maxResults) { if (isRunning()) { qCWarning(KGAPIDebug) << "Can't modify maxResults property when job is running"; return; } d->maxResults = maxResults; } int TeamdriveFetchJob::maxResults() const { return d->maxResults; } void TeamdriveFetchJob::setUseDomainAdminAccess(bool useDomainAdminAccess) { if (isRunning()) { qCWarning(KGAPIDebug) << "Can't modify useDomainAdminAccess property when job is running"; return; } d->useDomainAdminAccess = useDomainAdminAccess; } bool TeamdriveFetchJob::useDomainAdminAccess() const { return d->useDomainAdminAccess; } void TeamdriveFetchJob::start() { QUrl url; if (d->teamdriveId.isEmpty()) { url = DriveService::fetchTeamdrivesUrl(); applyRequestParameters(url); } else { url = DriveService::fetchTeamdriveUrl(d->teamdriveId); } const QNetworkRequest request = d->createRequest(url); enqueueRequest(request); } ObjectsList TeamdriveFetchJob::handleReplyWithItems(const QNetworkReply *reply, const QByteArray &rawData) { FeedData feedData; feedData.requestUrl = reply->url(); ObjectsList items; QString itemId; const QString contentType = reply->header(QNetworkRequest::ContentTypeHeader).toString(); ContentType ct = Utils::stringToContentType(contentType); if (ct == KGAPI2::JSON) { if (d->teamdriveId.isEmpty()) { items << Teamdrive::fromJSONFeed(rawData, feedData); } else { items << Teamdrive::fromJSON(rawData); } } else { setError(KGAPI2::InvalidResponse); setErrorString(tr("Invalid response content type")); emitFinished(); return items; } if (feedData.nextPageUrl.isValid()) { // Reapply query options applyRequestParameters(feedData.nextPageUrl); const QNetworkRequest request = d->createRequest(feedData.nextPageUrl); enqueueRequest(request); } return items; } void TeamdriveFetchJob::applyRequestParameters(QUrl &url) { QUrlQuery query(url); if (d->maxResults != 0) { query.addQueryItem(MaxResultsAttr, QString::number(d->maxResults)); } if (d->useDomainAdminAccess != false) { query.addQueryItem(UseDomainAdminAccessAttr, d->useDomainAdminAccess ? True : False); } + if (!d->searchQuery.isEmpty()) { + query.addQueryItem(QStringLiteral("q"), d->searchQuery.serialize()); + } url.setQuery(query); } diff --git a/src/drive/teamdrivefetchjob.h b/src/drive/teamdrivefetchjob.h index d7bad98..48b9e30 100644 --- a/src/drive/teamdrivefetchjob.h +++ b/src/drive/teamdrivefetchjob.h @@ -1,94 +1,97 @@ /* * This file is part of LibKGAPI library * * Copyright (C) 2019 David Barchiesi * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #ifndef KGAPI2_DRIVETEAMDRIVEFETCHJOB_H #define KGAPI2_DRIVETEAMDRIVEFETCHJOB_H #include "fetchjob.h" #include "kgapidrive_export.h" +#include "teamdrivesearchquery.h" + namespace KGAPI2 { namespace Drive { class KGAPIDRIVE_EXPORT TeamdriveFetchJob : public KGAPI2::FetchJob { Q_OBJECT /** * Maximum number of teamdrives to return. * * Default value if missing is 10. * * This property does not have any effect when fetching a specific event and * can be modified only when the job is not running. */ Q_PROPERTY(int maxResults READ maxResults WRITE setMaxResults) /** * Issue the request as a domain administrator; if set to true, then all * Team Drives of the domain in which the requester is an administrator * are returned. * * Default value if missing is false. * * This property does not have any effect when fetching a specific event and * can be modified only when the job is not running. */ Q_PROPERTY(bool useDomainAdminAccess READ useDomainAdminAccess WRITE setUseDomainAdminAccess) public: + TeamdriveFetchJob(const TeamdriveSearchQuery &query, const AccountPtr &account, QObject *parent = nullptr); TeamdriveFetchJob(const AccountPtr &account, QObject *parent = nullptr); TeamdriveFetchJob(const QString &teamdriveId, const AccountPtr &account, QObject *parent = nullptr); ~TeamdriveFetchJob() override; int maxResults() const; void setMaxResults(int maxResults); void setUseDomainAdminAccess(bool useDomainAdminAccess); bool useDomainAdminAccess() const; protected: void start() override; KGAPI2::ObjectsList handleReplyWithItems(const QNetworkReply *reply, const QByteArray &rawData) override; private: class Private; QScopedPointer d; friend class Private; void applyRequestParameters(QUrl &url); }; } // namespace Drive } // namespace KGAPI2 #endif // KGAPI2_DRIVETEAMDRIVEFETCHJOB_H diff --git a/src/drive/teamdrivesearchquery.cpp b/src/drive/teamdrivesearchquery.cpp new file mode 100644 index 0000000..f2189a4 --- /dev/null +++ b/src/drive/teamdrivesearchquery.cpp @@ -0,0 +1,82 @@ +/* + * 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 "teamdrivesearchquery.h" + +#include +#include + +using namespace KGAPI2; +using namespace KGAPI2::Drive; + + +QString TeamdriveSearchQuery::fieldToString(Field field) +{ + switch (field) { + case Name: + return QStringLiteral("name"); + case CreatedTime: + return QStringLiteral("createdTime"); + case MemberCount: + return QStringLiteral("memberCount"); + case OrganizerCount: + return QStringLiteral("organizerCount"); + } + + Q_ASSERT(false); + return QString(); +} + +QString TeamdriveSearchQuery::valueToString(TeamdriveSearchQuery::Field field, const QVariant &var) +{ + switch (field) { + case Name: + return QStringLiteral("'%1'").arg(var.toString().replace(QLatin1Char('\''), QLatin1String("\\\'"))); + case MemberCount: + case OrganizerCount: + return var.toString(); + case CreatedTime: + return QStringLiteral("'%1'").arg(var.toDateTime().toUTC().toString(QStringLiteral("yyyy-MM-ddThh:mm:ss"))); + } + + Q_ASSERT(false); + return QString(); +} + +void TeamdriveSearchQuery::addQuery(TeamdriveSearchQuery::Field field, TeamdriveSearchQuery::CompareOperator op, const QVariant &value) +{ + switch (field) { + case Name: + Q_ASSERT(op == Contains || 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 CreatedTime: + 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/teamdrivesearchquery.h b/src/drive/teamdrivesearchquery.h new file mode 100644 index 0000000..3a4dfdf --- /dev/null +++ b/src/drive/teamdrivesearchquery.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2019 David Barchiesi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) version 3, or any + * later version accepted by the membership of KDE e.V. (or its + * successor approved by the membership of KDE e.V.), which shall + * act as a proxy defined in Section 6 of version 3 of the license. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#ifndef KGAPI2_DRIVE_TEAMDRIVESEARCHQUERY_H +#define KGAPI2_DRIVE_TEAMDRIVESEARCHQUERY_H + +#include "kgapidrive_export.h" + +#include "searchquery.h" + +#include +#include + +namespace KGAPI2 +{ +namespace Drive +{ + +/** + * TeamdriveSearchQuery class allows simply building even complex team drive search queries + * for TeamdriveFetchJob. + * + * See https://developers.google.com/drive/web/search-parameters for allowed + * combinations of fields, compare operators, and value types. + * + * @since 2.3 + */ +class KGAPIDRIVE_EXPORT TeamdriveSearchQuery : public SearchQuery +{ +public: + enum Field { + Name, + CreatedTime, + MemberCount, + OrganizerCount + }; + + using SearchQuery::SearchQuery; + + using SearchQuery::addQuery; + void addQuery(Field field, CompareOperator op, const QVariant &value); + +private: + QString fieldToString(Field field); + QString valueToString(TeamdriveSearchQuery::Field field, const QVariant &var); +}; +} +} + +#endif // KGAPI2_DRIVE_TEAMDRIVESEARCHQUERY_H