File indexing completed on 2024-12-22 04:57:55
0001 /* 0002 SPDX-FileCopyrightText: 2016 Stefan Stäglich <sstaeglich@kdemail.net> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "tomboyitemuploadjob.h" 0008 #include "debug.h" 0009 #include <KLocalizedString> 0010 #include <QJsonArray> 0011 #include <QJsonDocument> 0012 #include <QJsonObject> 0013 #include <QUuid> 0014 0015 TomboyItemUploadJob::TomboyItemUploadJob(const Akonadi::Item &item, JobType jobType, QNetworkAccessManager *manager, QObject *parent) 0016 : TomboyJobBase(manager, parent) 0017 , mSourceItem(item) 0018 , mJobType(jobType) 0019 { 0020 mSourceItem = Akonadi::Item(item); 0021 if (item.hasPayload<KMime::Message::Ptr>()) { 0022 mNoteContent = item.payload<KMime::Message::Ptr>(); 0023 } 0024 0025 mRemoteRevision = item.parentCollection().remoteRevision().toInt(); 0026 0027 // Create random remote id if adding new item 0028 if (jobType == JobType::AddItem) { 0029 mSourceItem.setRemoteId(QUuid::createUuid().toString()); 0030 } 0031 } 0032 0033 Akonadi::Item TomboyItemUploadJob::item() const 0034 { 0035 return mSourceItem; 0036 } 0037 0038 JobType TomboyItemUploadJob::jobType() const 0039 { 0040 return mJobType; 0041 } 0042 0043 void TomboyItemUploadJob::start() 0044 { 0045 // Convert note to JSON 0046 QJsonObject jsonNote; 0047 jsonNote[QLatin1StringView("guid")] = mSourceItem.remoteId(); 0048 switch (mJobType) { 0049 case JobType::DeleteItem: 0050 jsonNote[QLatin1StringView("command")] = QStringLiteral("delete"); 0051 break; 0052 case JobType::AddItem: 0053 jsonNote[QLatin1StringView("create-date")] = getCurrentISOTime(); 0054 // Missing break is intended 0055 [[fallthrough]]; 0056 case JobType::ModifyItem: 0057 jsonNote[QLatin1StringView("title")] = mNoteContent->headerByType("subject")->asUnicodeString(); 0058 jsonNote[QLatin1StringView("note-content")] = mNoteContent->mainBodyPart()->decodedText(); 0059 jsonNote[QLatin1StringView("note-content-version")] = QStringLiteral("1"); 0060 jsonNote[QLatin1StringView("last-change-date")] = getCurrentISOTime(); 0061 } 0062 0063 // Create the full JSON object 0064 QJsonArray noteChanges; 0065 noteChanges.append(jsonNote); 0066 QJsonObject postJson; 0067 postJson[QLatin1StringView("note-changes")] = noteChanges; 0068 postJson[QLatin1StringView("latest-sync-revision")] = QString::number(++mRemoteRevision); 0069 QJsonDocument postData; 0070 postData.setObject(postJson); 0071 0072 // Network request 0073 QNetworkRequest request = QNetworkRequest(QUrl(mContentURL)); 0074 request.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/json; boundary=7d44e178b0439")); 0075 request.setHeader(QNetworkRequest::ContentLengthHeader, postData.toJson().length()); 0076 mReply = mRequestor->put(request, QList<O0RequestParameter>(), postData.toJson()); 0077 connect(mReply, &QNetworkReply::finished, this, &TomboyItemUploadJob::onRequestFinished); 0078 qCDebug(TOMBOYNOTESRESOURCE_LOG) << "TomboyItemUploadJob: Start network request"; 0079 } 0080 0081 void TomboyItemUploadJob::onRequestFinished() 0082 { 0083 checkReplyError(); 0084 if (error() != TomboyJobError::NoError) { 0085 setErrorText(mReply->errorString()); 0086 emitResult(); 0087 return; 0088 } 0089 qCDebug(TOMBOYNOTESRESOURCE_LOG) << "TomboyItemUploadJob: Network request finished. No error occurred"; 0090 0091 // Parse received data as JSON 0092 const QJsonDocument document = QJsonDocument::fromJson(mReply->readAll(), nullptr); 0093 0094 const QJsonObject jo = document.object(); 0095 const QJsonArray notes = jo[QLatin1StringView("notes")].toArray(); 0096 0097 // Check if server status is as expected 0098 bool found = false; 0099 for (const auto ¬e : notes) { 0100 found = (note.toObject()[QLatin1StringView("guid")].toString() == mSourceItem.remoteId()); 0101 if (found) { 0102 break; 0103 } 0104 } 0105 if (mJobType == JobType::DeleteItem && found) { 0106 setError(TomboyJobError::PermanentError); 0107 setErrorText(i18n("Sync error. Server status not as expected.")); 0108 emitResult(); 0109 return; 0110 } 0111 if (mJobType != JobType::DeleteItem && !found) { 0112 setError(TomboyJobError::PermanentError); 0113 setErrorText(i18n("Sync error. Server status not as expected.")); 0114 emitResult(); 0115 return; 0116 } 0117 0118 setError(TomboyJobError::NoError); 0119 emitResult(); 0120 } 0121 0122 QString TomboyItemUploadJob::getCurrentISOTime() const 0123 { 0124 QDateTime local = QDateTime::currentDateTime(); 0125 QDateTime utc = local.toUTC(); 0126 utc.setTimeSpec(Qt::LocalTime); 0127 int utcOffset = utc.secsTo(local); 0128 local.setOffsetFromUtc(utcOffset); 0129 0130 return local.toString(Qt::ISODate); 0131 } 0132 0133 #include "moc_tomboyitemuploadjob.cpp"