File indexing completed on 2024-11-24 04:44:12
0001 /* 0002 0003 SPDX-FileCopyrightText: 2012 Christian Mollekopf <chrigi_1@fastmail.fm> 0004 0005 SPDX-License-Identifier: LGPL-2.1-or-later 0006 */ 0007 0008 #include "icalendar.h" 0009 #include "imip.h" 0010 #include "libkolab-version.h" 0011 #include "pimkolab_debug.h" 0012 0013 #include <KMime/Message> 0014 0015 #include "conversion/commonconversion.h" 0016 #include "conversion/kcalconversion.h" 0017 #include "mime/mimeutils.h" 0018 #include <KCalendarCore/Event> 0019 #include <KCalendarCore/ICalFormat> 0020 #include <KCalendarCore/MemoryCalendar> 0021 0022 #include <KLocalizedString> 0023 0024 #include <QTimeZone> 0025 0026 #include <iostream> 0027 0028 namespace Kolab 0029 { 0030 std::string toICal(const std::vector<Event> &events) 0031 { 0032 KCalendarCore::Calendar::Ptr calendar(new KCalendarCore::MemoryCalendar(Kolab::Conversion::getTimeSpec(true, std::string()))); 0033 for (const Event &event : events) { 0034 KCalendarCore::Event::Ptr kcalEvent = Conversion::toKCalendarCore(event); 0035 kcalEvent->setCreated(QDateTime::currentDateTimeUtc()); // sets dtstamp 0036 calendar->addEvent(kcalEvent); 0037 } 0038 KCalendarCore::ICalFormat format; 0039 format.setApplication(QStringLiteral("libkolab"), QStringLiteral(LIBKOLAB_LIB_VERSION_STRING)); 0040 // qCDebug(PIMKOLAB_LOG) << format.createScheduleMessage(calendar->events().first(), KCalendarCore::iTIPRequest); 0041 0042 return Conversion::toStdString(format.toString(calendar)); 0043 } 0044 0045 std::vector<Event> fromICalEvents(const std::string &input) 0046 { 0047 KCalendarCore::Calendar::Ptr calendar(new KCalendarCore::MemoryCalendar(Kolab::Conversion::getTimeSpec(true, std::string()))); 0048 KCalendarCore::ICalFormat format; 0049 format.setApplication(QStringLiteral("libkolab"), QStringLiteral(LIBKOLAB_LIB_VERSION_STRING)); 0050 format.fromString(calendar, Conversion::fromStdString(input)); 0051 std::vector<Event> events; 0052 const auto eventsList = calendar->events(); 0053 for (const KCalendarCore::Event::Ptr &event : eventsList) { 0054 events.push_back(Conversion::fromKCalendarCore(*event)); 0055 } 0056 return events; 0057 } 0058 0059 ITipHandler::ITipHandler() 0060 : mMethod(iTIPNoMethod) 0061 { 0062 } 0063 0064 ITipHandler::ITipMethod mapFromKCalendarCore(KCalendarCore::iTIPMethod method) 0065 { 0066 Q_ASSERT((int)KCalendarCore::iTIPPublish == (int)ITipHandler::iTIPPublish); 0067 Q_ASSERT((int)KCalendarCore::iTIPNoMethod == (int)ITipHandler::iTIPNoMethod); 0068 return static_cast<ITipHandler::ITipMethod>(method); 0069 } 0070 0071 KCalendarCore::iTIPMethod mapToKCalendarCore(ITipHandler::ITipMethod method) 0072 { 0073 Q_ASSERT((int)KCalendarCore::iTIPPublish == (int)ITipHandler::iTIPPublish); 0074 Q_ASSERT((int)KCalendarCore::iTIPNoMethod == (int)ITipHandler::iTIPNoMethod); 0075 return static_cast<KCalendarCore::iTIPMethod>(method); 0076 } 0077 0078 std::string ITipHandler::toITip(const Event &event, ITipHandler::ITipMethod method) const 0079 { 0080 KCalendarCore::ICalFormat format; 0081 format.setApplication(QStringLiteral("libkolab"), QStringLiteral(LIBKOLAB_LIB_VERSION_STRING)); 0082 KCalendarCore::iTIPMethod m = mapToKCalendarCore(method); 0083 if (m == KCalendarCore::iTIPNoMethod) { 0084 return {}; 0085 } 0086 // qCDebug(PIMKOLAB_LOG) << event.start(). 0087 /* TODO 0088 * DTSTAMP is created 0089 * CREATED is current timestamp 0090 * LASTMODIFIED is lastModified 0091 * 0092 * Double check if that is correct. 0093 * 0094 * I think DTSTAMP should be the current timestamp, and CREATED should be the creation date. 0095 */ 0096 KCalendarCore::Event::Ptr e = Conversion::toKCalendarCore(event); 0097 return Conversion::toStdString(format.createScheduleMessage(e, m)); 0098 } 0099 0100 std::vector<Event> ITipHandler::fromITip(const std::string &string) 0101 { 0102 KCalendarCore::Calendar::Ptr calendar(new KCalendarCore::MemoryCalendar(QTimeZone::utc())); 0103 KCalendarCore::ICalFormat format; 0104 KCalendarCore::ScheduleMessage::Ptr msg = format.parseScheduleMessage(calendar, Conversion::fromStdString(string)); 0105 KCalendarCore::Event::Ptr event = msg->event().dynamicCast<KCalendarCore::Event>(); 0106 std::vector<Event> events; 0107 events.push_back(Conversion::fromKCalendarCore(*event)); 0108 mMethod = mapFromKCalendarCore(msg->method()); 0109 return events; 0110 } 0111 0112 ITipHandler::ITipMethod ITipHandler::method() const 0113 { 0114 return mMethod; 0115 } 0116 0117 std::string ITipHandler::toIMip(const Event &event, ITipHandler::ITipMethod m, const std::string &from, bool bccMe) const 0118 { 0119 KCalendarCore::Event::Ptr e = Conversion::toKCalendarCore(event); 0120 // e->recurrence()->addRDateTime(e->dtStart()); //FIXME The createScheduleMessage converts everything to utc without a recurrence. 0121 KCalendarCore::ICalFormat format; 0122 format.setApplication(QStringLiteral("libkolab"), QStringLiteral(LIBKOLAB_LIB_VERSION_STRING)); 0123 KCalendarCore::iTIPMethod method = mapToKCalendarCore(m); 0124 const QString &messageText = format.createScheduleMessage(e, method); 0125 // This code is mostly from MailScheduler::performTransaction 0126 if (method == KCalendarCore::iTIPRequest || method == KCalendarCore::iTIPCancel || method == KCalendarCore::iTIPAdd 0127 || method == KCalendarCore::iTIPDeclineCounter) { 0128 return Conversion::toStdString(QString::fromUtf8(mailAttendees(e, bccMe, messageText))); 0129 } else { 0130 QString subject; 0131 if (e && method == KCalendarCore::iTIPCounter) { 0132 subject = i18n("Counter proposal: %1", e->summary()); 0133 } 0134 return Conversion::toStdString(QString::fromUtf8(mailOrganizer(e, Conversion::fromStdString(from), bccMe, messageText, subject))); 0135 } 0136 } 0137 0138 std::vector<Event> ITipHandler::fromIMip(const std::string &input) 0139 { 0140 KMime::Message::Ptr msg = KMime::Message::Ptr(new KMime::Message); 0141 msg->setContent(Conversion::fromStdString(input).toUtf8()); 0142 msg->parse(); 0143 msg->content(KMime::ContentIndex()); 0144 0145 KMime::Content *c = Kolab::Mime::findContentByType(msg, "text/calendar"); 0146 if (!c) { 0147 qCWarning(PIMKOLAB_LOG) << "could not find text/calendar part"; 0148 return {}; 0149 } 0150 return fromITip(Conversion::toStdString(QString::fromUtf8(c->decodedContent()))); 0151 } 0152 }