File indexing completed on 2024-05-12 05:22:20

0001 /*
0002  * This file is part of LibKGAPI library
0003  *
0004  * SPDX-FileCopyrightText: 2013 Daniel Vrátil <dvratil@redhat.com>
0005  *
0006  * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0007  */
0008 
0009 #include "filefetchjob.h"
0010 #include "debug.h"
0011 #include "driveservice.h"
0012 #include "file.h"
0013 #include "filesearchquery.h"
0014 #include "utils.h"
0015 
0016 #include <QNetworkReply>
0017 #include <QNetworkRequest>
0018 #include <QUrlQuery>
0019 
0020 using namespace KGAPI2;
0021 using namespace KGAPI2::Drive;
0022 
0023 class Q_DECL_HIDDEN FileFetchJob::Private
0024 {
0025 public:
0026     Private(FileFetchJob *parent);
0027     void processNext();
0028 
0029     FileSearchQuery searchQuery;
0030     QStringList filesIDs;
0031     bool isFeed = false;
0032     bool includeItemsFromAllDrives = true;
0033     bool supportsAllDrives = true;
0034 
0035     bool updateViewedDate = false;
0036 
0037     QStringList fields;
0038 
0039 private:
0040     FileFetchJob *const q;
0041 };
0042 
0043 FileFetchJob::Private::Private(FileFetchJob *parent)
0044     : q(parent)
0045 {
0046 }
0047 
0048 void FileFetchJob::Private::processNext()
0049 {
0050     QUrl url;
0051 
0052     if (isFeed) {
0053         url = DriveService::fetchFilesUrl();
0054 
0055         QUrlQuery query(url);
0056         if (!searchQuery.isEmpty()) {
0057             query.addQueryItem(QStringLiteral("q"), searchQuery.serialize());
0058         }
0059 
0060         query.addQueryItem(QStringLiteral("includeItemsFromAllDrives"), Utils::bool2Str(includeItemsFromAllDrives));
0061 
0062         url.setQuery(query);
0063 
0064         if (!fields.isEmpty()) {
0065             // Deserializing requires kind attribute, always force add it
0066             if (!fields.contains(File::Fields::Kind)) {
0067                 fields << File::Fields::Kind;
0068             }
0069             Job *baseJob = dynamic_cast<Job *>(q);
0070             baseJob->setFields({File::Fields::Etag,
0071                                 File::Fields::Kind,
0072                                 File::Fields::NextLink,
0073                                 File::Fields::NextPageToken,
0074                                 File::Fields::SelfLink,
0075                                 Job::buildSubfields(File::Fields::Items, fields)});
0076         }
0077     } else {
0078         if (filesIDs.isEmpty()) {
0079             q->emitFinished();
0080             return;
0081         }
0082 
0083         const QString fileId = filesIDs.takeFirst();
0084         url = DriveService::fetchFileUrl(fileId);
0085 
0086         if (!fields.isEmpty()) {
0087             // Deserializing requires kind attribute, always force add it
0088             if (!fields.contains(File::Fields::Kind)) {
0089                 fields << File::Fields::Kind;
0090             }
0091             Job *baseJob = dynamic_cast<Job *>(q);
0092             baseJob->setFields(fields);
0093         }
0094     }
0095 
0096     QUrlQuery withDriveSupportQuery(url);
0097     withDriveSupportQuery.addQueryItem(QStringLiteral("supportsAllDrives"), Utils::bool2Str(supportsAllDrives));
0098     url.setQuery(withDriveSupportQuery);
0099 
0100     QNetworkRequest request(url);
0101     q->enqueueRequest(request);
0102 }
0103 
0104 FileFetchJob::FileFetchJob(const QString &fileId, const AccountPtr &account, QObject *parent)
0105     : FetchJob(account, parent)
0106     , d(new Private(this))
0107 {
0108     d->filesIDs << fileId;
0109 }
0110 
0111 FileFetchJob::FileFetchJob(const QStringList &filesIds, const AccountPtr &account, QObject *parent)
0112     : FetchJob(account, parent)
0113     , d(new Private(this))
0114 {
0115     d->filesIDs << filesIds;
0116 }
0117 
0118 FileFetchJob::FileFetchJob(const AccountPtr &account, QObject *parent)
0119     : FetchJob(account, parent)
0120     , d(new Private(this))
0121 {
0122     d->isFeed = true;
0123 }
0124 
0125 FileFetchJob::FileFetchJob(const FileSearchQuery &query, const AccountPtr &account, QObject *parent)
0126     : FetchJob(account, parent)
0127     , d(new Private(this))
0128 {
0129     d->isFeed = true;
0130     d->searchQuery = query;
0131 }
0132 
0133 FileFetchJob::~FileFetchJob()
0134 {
0135     delete d;
0136 }
0137 
0138 bool FileFetchJob::updateViewedDate() const
0139 {
0140     return d->updateViewedDate;
0141 }
0142 
0143 void FileFetchJob::setUpdateViewedDate(bool updateViewedDate)
0144 {
0145     if (isRunning()) {
0146         qCWarning(KGAPIDebug) << "Can't modify updateViewedDate property when job is running.";
0147         return;
0148     }
0149 
0150     d->updateViewedDate = updateViewedDate;
0151 }
0152 
0153 void FileFetchJob::start()
0154 {
0155     d->processNext();
0156 }
0157 
0158 void FileFetchJob::setFields(const QStringList &fields)
0159 {
0160     if (isRunning()) {
0161         qCWarning(KGAPIDebug) << "Called setFields() on running job. Ignoring.";
0162         return;
0163     }
0164 
0165     d->fields = fields;
0166 }
0167 
0168 QStringList FileFetchJob::fields() const
0169 {
0170     return d->fields;
0171 }
0172 
0173 bool FileFetchJob::includeItemsFromAllDrives() const
0174 {
0175     return d->includeItemsFromAllDrives;
0176 }
0177 
0178 void FileFetchJob::setIncludeItemsFromAllDrives(bool includeItemsFromAllDrives)
0179 {
0180     d->includeItemsFromAllDrives = includeItemsFromAllDrives;
0181 }
0182 
0183 bool FileFetchJob::supportsAllDrives() const
0184 {
0185     return d->supportsAllDrives;
0186 }
0187 
0188 void FileFetchJob::setSupportsAllDrives(bool supportsAllDrives)
0189 {
0190     d->supportsAllDrives = supportsAllDrives;
0191 }
0192 
0193 const QStringList FileFetchJob::FieldShorthands::BasicFields = {File::Fields::Id,
0194                                                                 File::Fields::Title,
0195                                                                 File::Fields::MimeType,
0196                                                                 File::Fields::CreatedDate,
0197                                                                 File::Fields::ModifiedDate,
0198                                                                 File::Fields::FileSize,
0199                                                                 File::Fields::DownloadUrl,
0200                                                                 File::Fields::Permissions};
0201 
0202 const QStringList FileFetchJob::FieldShorthands::AccessFields = {File::Fields::CreatedDate,
0203                                                                  File::Fields::ModifiedDate,
0204                                                                  File::Fields::ModifiedByMeDate,
0205                                                                  File::Fields::LastModifiedByMeDate,
0206                                                                  File::Fields::LastViewedByMeDate,
0207                                                                  File::Fields::MarkedViewedByMeDate};
0208 
0209 const QStringList FileFetchJob::FieldShorthands::SharingFields = {File::Fields::SharedWithMeDate,
0210                                                                   File::Fields::WritersCanShare,
0211                                                                   File::Fields::Shared,
0212                                                                   File::Fields::Owners,
0213                                                                   File::Fields::SharingUser,
0214                                                                   File::Fields::OwnerNames};
0215 
0216 ObjectsList FileFetchJob::handleReplyWithItems(const QNetworkReply *reply, const QByteArray &rawData)
0217 {
0218     ObjectsList items;
0219 
0220     const QString contentType = reply->header(QNetworkRequest::ContentTypeHeader).toString();
0221     ContentType ct = Utils::stringToContentType(contentType);
0222     if (ct == KGAPI2::JSON) {
0223         if (d->isFeed) {
0224             FeedData feedData;
0225 
0226             items << File::fromJSONFeed(rawData, feedData);
0227 
0228             if (feedData.nextPageUrl.isValid()) {
0229                 QNetworkRequest request(feedData.nextPageUrl);
0230                 enqueueRequest(request);
0231             }
0232 
0233         } else {
0234             items << File::fromJSON(rawData);
0235 
0236             d->processNext();
0237         }
0238     } else {
0239         setError(KGAPI2::InvalidResponse);
0240         setErrorString(tr("Invalid response content type"));
0241         emitFinished();
0242         return items;
0243     }
0244 
0245     return items;
0246 }
0247 
0248 #include "moc_filefetchjob.cpp"