File indexing completed on 2024-05-12 05:22:13
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 "eventfetchjob.h" 0010 #include "account.h" 0011 #include "calendarservice.h" 0012 #include "debug.h" 0013 #include "event.h" 0014 #include "utils.h" 0015 0016 #include <QNetworkReply> 0017 #include <QNetworkRequest> 0018 #include <QUrlQuery> 0019 0020 using namespace KGAPI2; 0021 0022 class Q_DECL_HIDDEN EventFetchJob::Private 0023 { 0024 public: 0025 QString calendarId; 0026 QString eventId; 0027 QString filter; 0028 QString syncToken; 0029 bool fetchDeleted = true; 0030 quint64 updatedTimestamp = 0; 0031 quint64 timeMin = 0; 0032 quint64 timeMax = 0; 0033 }; 0034 0035 EventFetchJob::EventFetchJob(const QString &calendarId, const AccountPtr &account, QObject *parent) 0036 : FetchJob(account, parent) 0037 , d(new Private) 0038 { 0039 d->calendarId = calendarId; 0040 } 0041 0042 EventFetchJob::EventFetchJob(const QString &eventId, const QString &calendarId, const AccountPtr &account, QObject *parent) 0043 : FetchJob(account, parent) 0044 , d(new Private) 0045 { 0046 d->calendarId = calendarId; 0047 d->eventId = eventId; 0048 } 0049 0050 EventFetchJob::~EventFetchJob() = default; 0051 0052 void EventFetchJob::setFetchDeleted(bool fetchDeleted) 0053 { 0054 if (isRunning()) { 0055 qCWarning(KGAPIDebug) << "Can't modify fetchDeleted property when job is running"; 0056 return; 0057 } 0058 0059 d->fetchDeleted = fetchDeleted; 0060 } 0061 0062 bool EventFetchJob::fetchDeleted() 0063 { 0064 return d->fetchDeleted; 0065 } 0066 0067 void EventFetchJob::setFetchOnlyUpdated(quint64 timestamp) 0068 { 0069 if (isRunning()) { 0070 qCWarning(KGAPIDebug) << "Can't modify setFetchOnlyUpdated property when job is running"; 0071 return; 0072 } 0073 0074 d->updatedTimestamp = timestamp; 0075 } 0076 0077 quint64 EventFetchJob::fetchOnlyUpdated() const 0078 { 0079 return d->updatedTimestamp; 0080 } 0081 0082 void EventFetchJob::setTimeMax(quint64 timestamp) 0083 { 0084 if (isRunning()) { 0085 qCWarning(KGAPIDebug) << "Can't modify timeMax property when job is running"; 0086 return; 0087 } 0088 0089 d->timeMax = timestamp; 0090 } 0091 0092 quint64 EventFetchJob::timeMax() const 0093 { 0094 return d->timeMax; 0095 } 0096 0097 void EventFetchJob::setSyncToken(const QString &syncToken) 0098 { 0099 d->syncToken = syncToken; 0100 } 0101 0102 QString EventFetchJob::syncToken() const 0103 { 0104 return d->syncToken; 0105 } 0106 0107 void EventFetchJob::setTimeMin(quint64 timestamp) 0108 { 0109 if (isRunning()) { 0110 qCWarning(KGAPIDebug) << "Can't modify timeMin property when job is running"; 0111 return; 0112 } 0113 0114 d->timeMin = timestamp; 0115 } 0116 0117 quint64 EventFetchJob::timeMin() const 0118 { 0119 return d->timeMin; 0120 } 0121 0122 void EventFetchJob::setFilter(const QString &query) 0123 { 0124 if (isRunning()) { 0125 qCWarning(KGAPIDebug) << "Can't modify filter property when job is running"; 0126 return; 0127 } 0128 0129 d->filter = query; 0130 } 0131 0132 QString EventFetchJob::filter() const 0133 { 0134 return d->filter; 0135 } 0136 0137 void EventFetchJob::start() 0138 { 0139 QUrl url; 0140 if (d->eventId.isEmpty()) { 0141 url = CalendarService::fetchEventsUrl(d->calendarId); 0142 QUrlQuery query(url); 0143 query.addQueryItem(QStringLiteral("showDeleted"), Utils::bool2Str(d->fetchDeleted)); 0144 if (!d->filter.isEmpty()) { 0145 query.addQueryItem(QStringLiteral("q"), d->filter); 0146 } 0147 if (d->syncToken.isEmpty()) { 0148 if (d->updatedTimestamp > 0) { 0149 query.addQueryItem(QStringLiteral("updatedMin"), Utils::ts2Str(d->updatedTimestamp)); 0150 } 0151 if (d->timeMin > 0) { 0152 query.addQueryItem(QStringLiteral("timeMin"), Utils::ts2Str(d->timeMin)); 0153 } 0154 if (d->timeMax > 0) { 0155 query.addQueryItem(QStringLiteral("timeMax"), Utils::ts2Str(d->timeMax)); 0156 } 0157 } else { 0158 query.addQueryItem(QStringLiteral("syncToken"), d->syncToken); 0159 } 0160 url.setQuery(query); 0161 } else { 0162 url = CalendarService::fetchEventUrl(d->calendarId, d->eventId); 0163 } 0164 const QNetworkRequest request = CalendarService::prepareRequest(url); 0165 enqueueRequest(request); 0166 } 0167 0168 ObjectsList EventFetchJob::handleReplyWithItems(const QNetworkReply *reply, const QByteArray &rawData) 0169 { 0170 if (reply->error() == QNetworkReply::ContentGoneError || reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == Gone) { 0171 // Full sync required by server, redo request with no updatedMin and no syncToken 0172 d->updatedTimestamp = 0; 0173 d->syncToken.clear(); 0174 start(); 0175 // Errors are not cleared on success 0176 // Do it here or else the job will fail 0177 setError(KGAPI2::NoError); 0178 setErrorString(QString()); 0179 return ObjectsList(); 0180 } 0181 0182 FeedData feedData; 0183 feedData.requestUrl = reply->url(); 0184 ObjectsList items; 0185 const QString contentType = reply->header(QNetworkRequest::ContentTypeHeader).toString(); 0186 ContentType ct = Utils::stringToContentType(contentType); 0187 if (ct == KGAPI2::JSON) { 0188 if (d->eventId.isEmpty()) { 0189 items = CalendarService::parseEventJSONFeed(rawData, feedData); 0190 } else { 0191 items << CalendarService::JSONToEvent(rawData).dynamicCast<Object>(); 0192 } 0193 d->syncToken = feedData.syncToken; 0194 } else { 0195 setError(KGAPI2::InvalidResponse); 0196 setErrorString(tr("Invalid response content type")); 0197 emitFinished(); 0198 return items; 0199 } 0200 0201 if (feedData.nextPageUrl.isValid()) { 0202 const auto request = CalendarService::prepareRequest(feedData.nextPageUrl); 0203 enqueueRequest(request); 0204 } 0205 0206 return items; 0207 }