File indexing completed on 2024-11-17 04:44:46
0001 /* 0002 SPDX-FileCopyrightText: 2015-2016 Krzysztof Nowicki <krissn@op.pl> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "ewsfetchcalendardetailjob.h" 0008 0009 #include <QTimeZone> 0010 0011 #include <KCalendarCore/Event> 0012 #include <KCalendarCore/ICalFormat> 0013 #include <KCalendarCore/MemoryCalendar> 0014 0015 #include "ewsgetitemrequest.h" 0016 #include "ewsitemshape.h" 0017 #include "ewsmailbox.h" 0018 #include "ewsoccurrence.h" 0019 #include "ewsresource_debug.h" 0020 0021 using namespace Akonadi; 0022 0023 EwsFetchCalendarDetailJob::EwsFetchCalendarDetailJob(EwsClient &client, QObject *parent, const Collection &collection) 0024 : EwsFetchItemDetailJob(client, parent, collection) 0025 { 0026 EwsItemShape shape(EwsShapeIdOnly); 0027 /* shape << EwsPropertyField(QStringLiteral("calendar:UID")); 0028 shape << EwsPropertyField(QStringLiteral("item:Subject")); 0029 shape << EwsPropertyField(QStringLiteral("item:Body")); 0030 shape << EwsPropertyField(QStringLiteral("calendar:Organizer")); 0031 shape << EwsPropertyField(QStringLiteral("calendar:RequiredAttendees")); 0032 shape << EwsPropertyField(QStringLiteral("calendar:OptionalAttendees")); 0033 shape << EwsPropertyField(QStringLiteral("calendar:Resources")); 0034 shape << EwsPropertyField(QStringLiteral("calendar:Start")); 0035 shape << EwsPropertyField(QStringLiteral("calendar:End")); 0036 shape << EwsPropertyField(QStringLiteral("calendar:IsAllDayEvent")); 0037 shape << EwsPropertyField(QStringLiteral("calendar:LegacyFreeBusyStatus")); 0038 shape << EwsPropertyField(QStringLiteral("calendar:AppointmentSequenceNumber")); 0039 shape << EwsPropertyField(QStringLiteral("calendar:IsRecurring")); 0040 shape << EwsPropertyField(QStringLiteral("calendar:Recurrence")); 0041 shape << EwsPropertyField(QStringLiteral("calendar:FirstOccurrence")); 0042 shape << EwsPropertyField(QStringLiteral("calendar:LastOccurrence")); 0043 shape << EwsPropertyField(QStringLiteral("calendar:ModifiedOccurrences")); 0044 shape << EwsPropertyField(QStringLiteral("calendar:DeletedOccurrences")); 0045 shape << EwsPropertyField(QStringLiteral("calendar:StartTimeZone")); 0046 shape << EwsPropertyField(QStringLiteral("calendar:EndTimeZone")); 0047 shape << EwsPropertyField(QStringLiteral("calendar:MyResponseType")); 0048 shape << EwsPropertyField(QStringLiteral("item:HasAttachments")); 0049 shape << EwsPropertyField(QStringLiteral("item:Attachments"));*/ 0050 0051 // shape << EwsPropertyField(QStringLiteral("item:Attachments")); 0052 shape << EwsPropertyField(QStringLiteral("calendar:ModifiedOccurrences")); 0053 shape << EwsPropertyField(QStringLiteral("calendar:DeletedOccurrences")); 0054 shape << EwsPropertyField(QStringLiteral("item:Body")); 0055 // shape << EwsPropertyField(QStringLiteral("item:Culture")); 0056 shape << EwsPropertyField(QStringLiteral("item:MimeContent")); 0057 shape << EwsPropertyField(QStringLiteral("item:Subject")); 0058 // shape << EwsPropertyField(QStringLiteral("calendar:TimeZone")); 0059 mRequest->setItemShape(shape); 0060 } 0061 0062 EwsFetchCalendarDetailJob::~EwsFetchCalendarDetailJob() = default; 0063 0064 void EwsFetchCalendarDetailJob::processItems(const EwsGetItemRequest::Response::List &responses) 0065 { 0066 Item::List::iterator it = mChangedItems.begin(); 0067 KCalendarCore::ICalFormat format; 0068 0069 EwsId::List addItems; 0070 0071 for (const EwsGetItemRequest::Response &resp : responses) { 0072 Item &item = *it; 0073 0074 if (!resp.isSuccess()) { 0075 qCWarningNC(EWSRES_LOG) << QStringLiteral("Failed to fetch item %1").arg(item.remoteId()); 0076 continue; 0077 } 0078 0079 const EwsItem &ewsItem = resp.item(); 0080 QString mimeContent = ewsItem[EwsItemFieldMimeContent].toString(); 0081 KCalendarCore::Calendar::Ptr memcal(new KCalendarCore::MemoryCalendar(QTimeZone::utc())); 0082 format.fromString(memcal, mimeContent); 0083 qCDebugNC(EWSRES_LOG) << QStringLiteral("Found %1 events").arg(memcal->events().count()); 0084 KCalendarCore::Incidence::Ptr incidence; 0085 if (memcal->events().count() > 1) { 0086 const auto memcalEvents{memcal->events()}; 0087 for (const KCalendarCore::Event::Ptr &event : memcalEvents) { 0088 qCDebugNC(EWSRES_LOG) << QString::number(event->recurrence()->recurrenceType(), 16) << event->recurrenceId() << event->recurrenceId().isValid(); 0089 if (!event->recurrenceId().isValid()) { 0090 incidence = event; 0091 } 0092 } 0093 const auto excList = ewsItem[EwsItemFieldModifiedOccurrences].value<EwsOccurrence::List>(); 0094 for (const EwsOccurrence &exc : excList) { 0095 addItems.append(exc.itemId()); 0096 } 0097 } else if (memcal->events().count() == 1) { 0098 incidence = memcal->events()[0]; 0099 } 0100 // KCalendarCore::Incidence::Ptr incidence(format.fromString(mimeContent)); 0101 0102 if (incidence) { 0103 QDateTime dt(incidence->dtStart()); 0104 if (dt.isValid()) { 0105 incidence->setDtStart(dt); 0106 } 0107 if (incidence->type() == KCalendarCore::Incidence::TypeEvent) { 0108 auto event = reinterpret_cast<KCalendarCore::Event *>(incidence.data()); 0109 dt = event->dtEnd(); 0110 if (dt.isValid()) { 0111 event->setDtEnd(dt); 0112 } 0113 } 0114 dt = incidence->recurrenceId(); 0115 if (dt.isValid()) { 0116 incidence->setRecurrenceId(dt); 0117 } 0118 0119 item.setPayload<KCalendarCore::Incidence::Ptr>(incidence); 0120 } 0121 0122 ++it; 0123 } 0124 0125 if (addItems.isEmpty()) { 0126 emitResult(); 0127 } else { 0128 auto req = new EwsGetItemRequest(mClient, this); 0129 EwsItemShape shape(EwsShapeIdOnly); 0130 // shape << EwsPropertyField(QStringLiteral("item:Attachments")); 0131 shape << EwsPropertyField(QStringLiteral("item:Body")); 0132 shape << EwsPropertyField(QStringLiteral("item:MimeContent")); 0133 // shape << EwsPropertyField(QStringLiteral("calendar:TimeZone")); 0134 // shape << EwsPropertyField(QStringLiteral("item:Culture")); 0135 req->setItemShape(shape); 0136 0137 req->setItemIds(addItems); 0138 connect(req, &KJob::result, this, &EwsFetchCalendarDetailJob::exceptionItemsFetched); 0139 req->start(); 0140 } 0141 } 0142 0143 void EwsFetchCalendarDetailJob::exceptionItemsFetched(KJob *job) 0144 { 0145 if (job->error()) { 0146 setError(job->error()); 0147 setErrorText(job->errorText()); 0148 emitResult(); 0149 return; 0150 } 0151 0152 auto req = qobject_cast<EwsGetItemRequest *>(job); 0153 0154 if (!req) { 0155 setError(1); 0156 setErrorText(QStringLiteral("Job is not an instance of EwsGetItemRequest")); 0157 emitResult(); 0158 return; 0159 } 0160 0161 KCalendarCore::ICalFormat format; 0162 const auto responses{req->responses()}; 0163 for (const EwsGetItemRequest::Response &resp : responses) { 0164 if (!resp.isSuccess()) { 0165 qCWarningNC(EWSRES_LOG) << QStringLiteral("Failed to fetch item."); 0166 continue; 0167 } 0168 const EwsItem &ewsItem = resp.item(); 0169 0170 Item item(KCalendarCore::Event::eventMimeType()); 0171 item.setParentCollection(mCollection); 0172 auto id = ewsItem[EwsItemFieldItemId].value<EwsId>(); 0173 item.setRemoteId(id.id()); 0174 item.setRemoteRevision(id.changeKey()); 0175 0176 QString mimeContent = ewsItem[EwsItemFieldMimeContent].toString(); 0177 KCalendarCore::Calendar::Ptr memcal(new KCalendarCore::MemoryCalendar(QTimeZone::utc())); 0178 format.fromString(memcal, mimeContent); 0179 KCalendarCore::Incidence::Ptr incidence(memcal->events().last()); 0180 incidence->clearRecurrence(); 0181 0182 QDateTime dt(incidence->dtStart()); 0183 if (dt.isValid()) { 0184 incidence->setDtStart(dt); 0185 } 0186 if (incidence->type() == KCalendarCore::Incidence::TypeEvent) { 0187 auto event = reinterpret_cast<KCalendarCore::Event *>(incidence.data()); 0188 dt = event->dtEnd(); 0189 if (dt.isValid()) { 0190 event->setDtEnd(dt); 0191 } 0192 } 0193 dt = incidence->recurrenceId(); 0194 if (dt.isValid()) { 0195 incidence->setRecurrenceId(dt); 0196 } 0197 0198 item.setPayload<KCalendarCore::Incidence::Ptr>(incidence); 0199 0200 mChangedItems.append(item); 0201 } 0202 0203 emitResult(); 0204 } 0205 0206 #include "moc_ewsfetchcalendardetailjob.cpp"