diff --git a/autotests/drive/aboutfetchjobtest.cpp b/autotests/drive/aboutfetchjobtest.cpp
--- a/autotests/drive/aboutfetchjobtest.cpp
+++ b/autotests/drive/aboutfetchjobtest.cpp
@@ -17,7 +17,7 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
*/
-
+#include
#include
#include
@@ -32,7 +32,12 @@
using namespace KGAPI2;
+namespace {
+ static const char *LimitedFieldTag = "limited fields";
+}
+
Q_DECLARE_METATYPE(QList)
+Q_DECLARE_METATYPE(KGAPI2::Drive::AboutPtr)
class AboutFetchJobTest : public QObject
{
@@ -43,17 +48,40 @@
NetworkAccessManagerFactory::setFactory(new FakeNetworkAccessManagerFactory);
}
+ void testFetch_data()
+ {
+ QTest::addColumn>("scenarios");
+ QTest::addColumn("about");
+
+ QTest::newRow("")
+ << QList{
+ scenarioFromFile(QFINDTESTDATA("data/about_fetch_request.txt"),
+ QFINDTESTDATA("data/about_fetch_response.txt"))
+ }
+ << aboutFromFile(QFINDTESTDATA("data/about.json"));
+
+ QTest::newRow(LimitedFieldTag)
+ << QList{
+ scenarioFromFile(QFINDTESTDATA("data/about_fetch_limited_fields_request.txt"),
+ QFINDTESTDATA("data/about_fetch_limited_fields_response.txt"))
+ }
+ << aboutFromFile(QFINDTESTDATA("data/about_limited_fields.json"));
+ }
+
void testFetch()
{
- FakeNetworkAccessManagerFactory::get()->setScenarios({
- scenarioFromFile(QFINDTESTDATA("data/about_fetch_request.txt"),
- QFINDTESTDATA("data/about_fetch_response.txt"))
+ QFETCH(QList, scenarios);
+ QFETCH(KGAPI2::Drive::AboutPtr, about);
- });
- const auto about = aboutFromFile(QFINDTESTDATA("data/about.json"));
+ FakeNetworkAccessManagerFactory::get()->setScenarios(scenarios);
auto account = AccountPtr::create(QStringLiteral("MockAccount"), QStringLiteral("MockToken"));
auto job = new Drive::AboutFetchJob(account, nullptr);
+
+ if (strcmp(LimitedFieldTag, QTest::currentDataTag()) == 0) {
+ job->setFields({ Drive::About::KindField, Drive::About::PermissionIdField });
+ }
+
QVERIFY(execJob(job));
const auto items = job->items();
QCOMPARE(items.count(), 1);
diff --git a/autotests/drive/data/about_fetch_limited_fields_request.txt b/autotests/drive/data/about_fetch_limited_fields_request.txt
new file mode 100644
--- /dev/null
+++ b/autotests/drive/data/about_fetch_limited_fields_request.txt
@@ -0,0 +1 @@
+GET https://www.googleapis.com/drive/v2/about?includeSubscribed=true&fields=kind,permissionId&prettyPrint=false
diff --git a/autotests/drive/data/about_fetch_limited_fields_response.txt b/autotests/drive/data/about_fetch_limited_fields_response.txt
new file mode 100644
--- /dev/null
+++ b/autotests/drive/data/about_fetch_limited_fields_response.txt
@@ -0,0 +1,7 @@
+HTTP/1.1 200 OK
+content-type: application/json; charset=UTF-8
+
+{
+ "kind": "drive#about",
+ "permissionId": "07857126568572968161"
+}
diff --git a/autotests/drive/data/about_fetch_request.txt b/autotests/drive/data/about_fetch_request.txt
--- a/autotests/drive/data/about_fetch_request.txt
+++ b/autotests/drive/data/about_fetch_request.txt
@@ -1 +1 @@
-GET https://www.googleapis.com/drive/v2/about?includeSubscribed=true
+GET https://www.googleapis.com/drive/v2/about?includeSubscribed=true&prettyPrint=false
diff --git a/autotests/drive/data/about_limited_fields.json b/autotests/drive/data/about_limited_fields.json
new file mode 100644
--- /dev/null
+++ b/autotests/drive/data/about_limited_fields.json
@@ -0,0 +1,4 @@
+{
+ "kind": "drive#about",
+ "permissionId": "07857126568572968161"
+}
diff --git a/src/core/job.h b/src/core/job.h
--- a/src/core/job.h
+++ b/src/core/job.h
@@ -27,6 +27,7 @@
#include "kgapicore_export.h"
#include
+#include
class QNetworkAccessManager;
class QNetworkReply;
@@ -40,12 +41,13 @@
*
* Usual workflow of Job subclasses is to reimplement Job::start,
* Job::dispatchRequest and Job::handleReply, then enqueue a QNetworkRequest using
- * Job::enqueueRequest. The request will automatically be scheduled in a queue
- * and dispatched by calling Job::dispatchRequest implementation. When a reply
- * is received, the Job will automatically perform error handling and if there
- * is no error, the reply is passed to implementation of Job::handleReply.
+ * Job::enqueueRequest. An authorized request is buildable with Job::authorizedRequest.
+ * The request will automatically be scheduled in a queue and dispatched by calling
+ * Job::dispatchRequest implementation. When a reply is received, the Job will
+ * automatically perform error handling and if there is no error, the reply is passed
+ * to implementation of Job::handleReply.
*
- * Job is automatically when program enters an event loop.
+ * Job is automatically started when program enters an event loop.
*
* @author Daniel Vrátil
* @since 2.0
@@ -72,7 +74,7 @@
* @brief Whether the job is running
*
* This property indicates whether the job is running or not. The value is
- * set to @p true when the job is started (see Job::start) and back to
+ * set to @p true when the job is started (see Job::start) and back to
* @p false right before Job::finished is emitted.
*
* @see Job::isRunning, Job::finished
@@ -178,6 +180,40 @@
*/
AccountPtr account() const;
+ /**
+ * @brief Sets whether response will have indentations and line breaks.
+ *
+ * When this is false, it can reduce the response payload size,
+ * which might lead to better performance in some environments.
+ * Default is false.
+ *
+ * @param prettyPrint
+ */
+ void setPrettyPrint(bool &prettyPrint);
+
+ /**
+ * @brief Returns prettyPrint query parameter.
+ *
+ * @return prettyPrint query parameter
+ */
+ bool prettyPrint() const;
+
+ /**
+ * @brief Set subset of fields to include in the response.
+ *
+ * Use for better performance.
+ *
+ * @param fields List of fields
+ */
+ void setFields(const QStringList &fields);
+
+ /**
+ * @brief Returns fields selector.
+ *
+ * @return List of fields
+ */
+ QStringList fields() const;
+
/**
* @brief Restarts this job
*
@@ -186,7 +222,7 @@
*
* The job will throw away all results retrieved in previous run and retrieve
* everything again.
- *
+ *
* @see Job::aboutToStart
*/
void restart();
@@ -308,6 +344,17 @@
*/
virtual void handleReply(const QNetworkReply *reply, const QByteArray &rawData) = 0;
+ /**
+ * @brief Builds a request with headers and standard query parameters.
+ *
+ * Subclasses should use this method to get an authorized request with
+ * standard query parameters.
+ *
+ * @param url Api url
+ * @return Enqueuable request
+ */
+ QNetworkRequest authorizedRequest(QUrl &url) const;
+
/**
* @brief Enqueues @p request in dispatcher queue
*
diff --git a/src/core/job.cpp b/src/core/job.cpp
--- a/src/core/job.cpp
+++ b/src/core/job.cpp
@@ -31,9 +31,15 @@
#include
#include
#include
+#include
using namespace KGAPI2;
+namespace {
+ static const QString FieldsParam = QStringLiteral("fields");
+ static const QString PrettyPrintParam = QStringLiteral("prettyPrint");
+}
+
FileLogger *FileLogger::sInstance = nullptr;
FileLogger::FileLogger()
@@ -102,6 +108,7 @@
error(KGAPI2::NoError),
accessManager(nullptr),
maxTimeout(0),
+ prettyPrint(false),
q(parent)
{
}
@@ -421,6 +428,56 @@
d->account = account;
}
+bool Job::prettyPrint() const
+{
+ return d->prettyPrint;
+}
+
+void Job::setPrettyPrint(bool &prettyPrint)
+{
+ if (d->isRunning) {
+ qCWarning(KGAPIDebug) << "Called setPrettyPrint() on running job. Ignoring.";
+ return;
+ }
+
+ d->prettyPrint = prettyPrint;
+}
+
+QStringList Job::fields() const
+{
+ return d->fields;
+}
+
+void Job::setFields(const QStringList &fields)
+{
+ if (d->isRunning) {
+ qCWarning(KGAPIDebug) << "Called setFields() on running job. Ignoring.";
+ return;
+ }
+
+ d->fields = fields;
+}
+
+QNetworkRequest Job::authorizedRequest(QUrl &url) const
+{
+ QNetworkRequest request;
+ if (d->account) {
+ request.setRawHeader("Authorization", "Bearer " + d->account->accessToken().toLatin1());
+ }
+
+ QUrlQuery query(url);
+ if (!d->fields.isEmpty()) {
+ query.addQueryItem(FieldsParam, d->fields.join(QStringLiteral(",")));
+ }
+ query.addQueryItem(PrettyPrintParam, d->prettyPrint ? QStringLiteral("true") : QStringLiteral("false"));
+
+
+ url.setQuery(query);
+ request.setUrl(url);
+
+ return request;
+}
+
void Job::restart()
{
if (d->isRunning) {
diff --git a/src/core/job_p.h b/src/core/job_p.h
--- a/src/core/job_p.h
+++ b/src/core/job_p.h
@@ -81,6 +81,8 @@
QQueue requestQueue;
QTimer *dispatchTimer;
int maxTimeout;
+ bool prettyPrint;
+ QStringList fields;
Request currentRequest;
diff --git a/src/drive/about.h b/src/drive/about.h
--- a/src/drive/about.h
+++ b/src/drive/about.h
@@ -221,8 +221,54 @@
typedef QSharedPointer MaxUploadSizePtr;
typedef QList MaxUploadSizesList;
- explicit About(const About &other);
- virtual ~About();
+ static const QString AdditionalRoleInfoField;
+ static const QString AdditionalRolesField;
+ static const QString BackgroundImageLinkField;
+ static const QString BytesUsedField;
+ static const QString CanCreateTeamDrivesField;
+ static const QString ColorRgbField;
+ static const QString DisplayNameField;
+ static const QString DomainSharingPolicyField;
+ static const QString EmailAddressField;
+ static const QString EtagField;
+ static const QString ExportFormatsField;
+ static const QString FeatureNameField;
+ static const QString FeatureRateField;
+ static const QString FeaturesField;
+ static const QString FolderColorPaletteField;
+ static const QString IdField;
+ static const QString ImportFormatsField;
+ static const QString IsAuthenticatedUserField;
+ static const QString IsCurrentAppInstalledField;
+ static const QString KindField;
+ static const QString LanguageCodeField;
+ static const QString LargestChangeIdField;
+ static const QString MaxUploadSizesField;
+ static const QString NameField;
+ static const QString PermissionIdField;
+ static const QString PictureField;
+ static const QString PrimaryRoleField;
+ static const QString QuotaBytesByServiceField;
+ static const QString QuotaBytesTotalField;
+ static const QString QuotaBytesUsedField;
+ static const QString QuotaBytesUsedAggregateField;
+ static const QString QuotaBytesUsedInTrashField;
+ static const QString QuotaTypeField;
+ static const QString RemainingChangeIdsField;
+ static const QString RoleSetsField;
+ static const QString RootFolderIdField;
+ static const QString SelfLinkField;
+ static const QString ServiceNameField;
+ static const QString SizeField;
+ static const QString SourceField;
+ static const QString TargetsField;
+ static const QString TeamDriveThemesField;
+ static const QString TypeField;
+ static const QString UrlField;
+ static const QString UserField;
+
+ About(const About &other);
+ ~About() override;
bool operator==(const About &other) const;
bool operator!=(const About &other) const { return !operator==(other); }
@@ -340,10 +386,10 @@
static AboutPtr fromJSON(const QByteArray &jsonData);
private:
- explicit About();
+ About();
class Private;
- Private *const d;
+ QScopedPointer const d;
friend class Private;
};
diff --git a/src/drive/about.cpp b/src/drive/about.cpp
--- a/src/drive/about.cpp
+++ b/src/drive/about.cpp
@@ -361,6 +361,52 @@
{
}
+const QString About::AdditionalRoleInfoField = QStringLiteral("additionalRoleInfo");
+const QString About::AdditionalRolesField = QStringLiteral("additionalRoles");
+const QString About::BackgroundImageLinkField = QStringLiteral("backgroundImageLink");
+const QString About::BytesUsedField = QStringLiteral("bytesUsed");
+const QString About::CanCreateTeamDrivesField = QStringLiteral("canCreateTeamDrives");
+const QString About::ColorRgbField = QStringLiteral("colorRgb");
+const QString About::DisplayNameField = QStringLiteral("displayName");
+const QString About::DomainSharingPolicyField = QStringLiteral("domainSharingPolicy");
+const QString About::EmailAddressField = QStringLiteral("emailAddress");
+const QString About::EtagField = QStringLiteral("etag");
+const QString About::ExportFormatsField = QStringLiteral("exportFormats");
+const QString About::FeatureNameField = QStringLiteral("featureName");
+const QString About::FeatureRateField = QStringLiteral("featureRate");
+const QString About::FeaturesField = QStringLiteral("features");
+const QString About::FolderColorPaletteField = QStringLiteral("folderColorPalette");
+const QString About::IdField = QStringLiteral("id");
+const QString About::ImportFormatsField = QStringLiteral("importFormats");
+const QString About::IsAuthenticatedUserField = QStringLiteral("isAuthenticatedUser");
+const QString About::IsCurrentAppInstalledField = QStringLiteral("isCurrentAppInstalled");
+const QString About::KindField = QStringLiteral("kind");
+const QString About::LanguageCodeField = QStringLiteral("languageCode");
+const QString About::LargestChangeIdField = QStringLiteral("largestChangeId");
+const QString About::MaxUploadSizesField = QStringLiteral("maxUploadSizes");
+const QString About::NameField = QStringLiteral("name");
+const QString About::PermissionIdField = QStringLiteral("permissionId");
+const QString About::PictureField = QStringLiteral("picture");
+const QString About::PrimaryRoleField = QStringLiteral("primaryRole");
+const QString About::QuotaBytesByServiceField = QStringLiteral("quotaBytesByService");
+const QString About::QuotaBytesTotalField = QStringLiteral("quotaBytesTotal");
+const QString About::QuotaBytesUsedAggregateField = QStringLiteral("quotaBytesUsedAggregate");
+const QString About::QuotaBytesUsedInTrashField = QStringLiteral("quotaBytesUsedInTrash");
+const QString About::QuotaBytesUsedField = QStringLiteral("quotaBytesUsed");
+const QString About::QuotaTypeField = QStringLiteral("quotaType");
+const QString About::RemainingChangeIdsField = QStringLiteral("remainingChangeIds");
+const QString About::RoleSetsField = QStringLiteral("roleSets");
+const QString About::RootFolderIdField = QStringLiteral("rootFolderId");
+const QString About::SelfLinkField = QStringLiteral("selfLink");
+const QString About::ServiceNameField = QStringLiteral("serviceName");
+const QString About::SizeField = QStringLiteral("size");
+const QString About::SourceField = QStringLiteral("source");
+const QString About::TargetsField = QStringLiteral("targets");
+const QString About::TeamDriveThemesField = QStringLiteral("teamDriveThemes");
+const QString About::TypeField = QStringLiteral("type");
+const QString About::UrlField = QStringLiteral("url");
+const QString About::UserField = QStringLiteral("user");
+
About::About():
KGAPI2::Object(),
d(new Private)
@@ -373,10 +419,7 @@
{
}
-About::~About()
-{
- delete d;
-}
+About::~About() = default;
bool About::operator==(const About &other) const
{
diff --git a/src/drive/aboutfetchjob.cpp b/src/drive/aboutfetchjob.cpp
--- a/src/drive/aboutfetchjob.cpp
+++ b/src/drive/aboutfetchjob.cpp
@@ -30,6 +30,7 @@
#include
#include
+#include
using namespace KGAPI2;
using namespace KGAPI2::Drive;
@@ -118,9 +119,8 @@
void AboutFetchJob::start()
{
- QNetworkRequest request;
- request.setRawHeader("Authorization", "Bearer " + account()->accessToken().toLatin1());
- request.setUrl(DriveService::fetchAboutUrl(d->includeSubscribed, d->maxChangeIdCount, d->startChangeId));
+ QUrl url = DriveService::fetchAboutUrl(d->includeSubscribed, d->maxChangeIdCount, d->startChangeId);
+ QNetworkRequest request = authorizedRequest(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
@@ -43,7 +43,8 @@
*/
KGAPIDRIVE_EXPORT QUrl fetchAboutUrl(bool includeSubscribed,
qlonglong maxChangeIdCount,
- qlonglong startChangeId);
+ qlonglong startChangeId,
+ QList > standardQueryParams);
KGAPIDRIVE_EXPORT QUrl fetchAppUrl(const QString &appId);
diff --git a/src/drive/driveservice.cpp b/src/drive/driveservice.cpp
--- a/src/drive/driveservice.cpp
+++ b/src/drive/driveservice.cpp
@@ -40,11 +40,12 @@
namespace DriveService
{
-QUrl fetchAboutUrl(bool includeSubscribed, qlonglong maxChangeIdCount, qlonglong startChangeId)
+QUrl fetchAboutUrl(bool includeSubscribed, qlonglong maxChangeIdCount, qlonglong startChangeId, QList > standardQueryParams)
{
QUrl url(Private::GoogleApisUrl);
url.setPath(Private::AppsBasePath);
QUrlQuery query(url);
+ query.setQueryItems(standardQueryParams);
query.addQueryItem(QStringLiteral("includeSubscribed"), Utils::bool2Str(includeSubscribed));
if (maxChangeIdCount > 0) {
query.addQueryItem(QStringLiteral("maxChangeIdCount"), QString::number(maxChangeIdCount));