File indexing completed on 2024-11-24 04:44:14
0001 /* 0002 * SPDX-FileCopyrightText: 2012 Christian Mollekopf <mollekopf@kolabsys.com> 0003 * 0004 * SPDX-License-Identifier: AGPL-3.0-or-later 0005 */ 0006 0007 #include "xmlobject.h" 0008 #include "conversion/commonconversion.h" 0009 #include "conversion/kabcconversion.h" 0010 #include "conversion/kcalconversion.h" 0011 #include "conversion/kolabconversion.h" 0012 #include "kolabformatV2/event.h" 0013 #include "pimkolab_debug.h" 0014 #include "v2helpers.h" 0015 #include <QUuid> 0016 0017 namespace Kolab 0018 { 0019 static QString createUuid() 0020 { 0021 const QString uuid = QUuid::createUuid().toString(); 0022 return uuid.mid(1, uuid.size() - 2); 0023 } 0024 0025 XMLObject::XMLObject() = default; 0026 0027 std::string XMLObject::getSerializedUID() const 0028 { 0029 return mWrittenUID; 0030 } 0031 0032 std::vector<std::string> XMLObject::getAttachments() const 0033 { 0034 return mAttachments; 0035 } 0036 0037 std::string XMLObject::writeEvent(const Event &event, Version version, const std::string &productId) 0038 { 0039 mWrittenUID.clear(); 0040 if (version == KolabV2) { 0041 const KCalendarCore::Event::Ptr i = Conversion::toKCalendarCore(event); 0042 if (!i) { 0043 qCCritical(PIMKOLAB_LOG) << "invalid incidence"; 0044 return {}; 0045 } 0046 if (i->uid().isEmpty()) { 0047 i->setUid(createUuid()); 0048 } 0049 mWrittenUID = Conversion::toStdString(i->uid()); 0050 // The timezone is used for created and last modified dates 0051 const QString &xml = KolabV2::Event::eventToXML(i, QStringLiteral("UTC")); 0052 return Conversion::toStdString(xml); 0053 } 0054 const std::string result = Kolab::writeEvent(event, productId); 0055 mWrittenUID = Kolab::getSerializedUID(); 0056 ErrorHandler::handleLibkolabxmlErrors(); 0057 return result; 0058 } 0059 0060 Event XMLObject::readEvent(const std::string &s, Version version) 0061 { 0062 if (version == KolabV2) { 0063 QStringList attachments; 0064 const auto event = Kolab::fromXML<KCalendarCore::Event::Ptr, KolabV2::Event>(QString::fromUtf8(s.c_str()).toUtf8(), attachments); 0065 if (!event || Kolab::ErrorHandler::errorOccured()) { 0066 qCCritical(PIMKOLAB_LOG) << "failed to read xml"; 0067 return {}; 0068 } 0069 mAttachments.clear(); 0070 mAttachments.reserve(attachments.count()); 0071 for (const QString &attachment : std::as_const(attachments)) { 0072 mAttachments.push_back(Conversion::toStdString(attachment)); 0073 } 0074 return Conversion::fromKCalendarCore(*event); 0075 } 0076 const Kolab::Event event = Kolab::readEvent(s, false); 0077 ErrorHandler::handleLibkolabxmlErrors(); 0078 return event; 0079 } 0080 0081 std::string XMLObject::writeTodo(const Todo &event, Version version, const std::string &productId) 0082 { 0083 mWrittenUID.clear(); 0084 if (version == KolabV2) { 0085 const KCalendarCore::Todo::Ptr i = Conversion::toKCalendarCore(event); 0086 if (!i) { 0087 qCCritical(PIMKOLAB_LOG) << "invalid incidence"; 0088 return {}; 0089 } 0090 if (i->uid().isEmpty()) { 0091 i->setUid(createUuid()); 0092 } 0093 mWrittenUID = Conversion::toStdString(i->uid()); 0094 // The timezone is used for created and last modified dates 0095 const QString &xml = KolabV2::Task::taskToXML(i, QStringLiteral("UTC")); 0096 return Conversion::toStdString(xml); 0097 } 0098 const std::string result = Kolab::writeTodo(event, productId); 0099 mWrittenUID = Kolab::getSerializedUID(); 0100 ErrorHandler::handleLibkolabxmlErrors(); 0101 return result; 0102 } 0103 0104 Todo XMLObject::readTodo(const std::string &s, Version version) 0105 { 0106 if (version == KolabV2) { 0107 QStringList attachments; 0108 const auto event = Kolab::fromXML<KCalendarCore::Todo::Ptr, KolabV2::Task>(QString::fromUtf8(s.c_str()).toUtf8(), attachments); 0109 if (!event || Kolab::ErrorHandler::errorOccured()) { 0110 qCCritical(PIMKOLAB_LOG) << "failed to read xml"; 0111 return {}; 0112 } 0113 mAttachments.clear(); 0114 mAttachments.reserve(attachments.count()); 0115 for (const QString &attachment : std::as_const(attachments)) { 0116 mAttachments.push_back(Conversion::toStdString(attachment)); 0117 } 0118 return Conversion::fromKCalendarCore(*event); 0119 } 0120 const Kolab::Todo todo = Kolab::readTodo(s, false); 0121 ErrorHandler::handleLibkolabxmlErrors(); 0122 return todo; 0123 } 0124 0125 std::string XMLObject::writeJournal(const Journal &event, Version version, const std::string &productId) 0126 { 0127 mWrittenUID.clear(); 0128 if (version == KolabV2) { 0129 const KCalendarCore::Journal::Ptr i = Conversion::toKCalendarCore(event); 0130 if (!i) { 0131 qCCritical(PIMKOLAB_LOG) << "invalid journal"; 0132 return {}; 0133 } 0134 if (i->uid().isEmpty()) { 0135 i->setUid(createUuid()); 0136 } 0137 mWrittenUID = Conversion::toStdString(i->uid()); 0138 // The timezone is used for created and last modified dates 0139 const QString &xml = KolabV2::Journal::journalToXML(i, QStringLiteral("UTC")); 0140 return Conversion::toStdString(xml); 0141 } 0142 const std::string result = Kolab::writeJournal(event, productId); 0143 mWrittenUID = Kolab::getSerializedUID(); 0144 return result; 0145 } 0146 0147 Journal XMLObject::readJournal(const std::string &s, Version version) 0148 { 0149 if (version == KolabV2) { 0150 QStringList attachments; 0151 const auto event = Kolab::fromXML<KCalendarCore::Journal::Ptr, KolabV2::Journal>(QString::fromUtf8(s.c_str()).toUtf8(), attachments); 0152 if (!event || Kolab::ErrorHandler::errorOccured()) { 0153 qCCritical(PIMKOLAB_LOG) << "failed to read xml"; 0154 return {}; 0155 } 0156 mAttachments.clear(); 0157 mAttachments.reserve(attachments.count()); 0158 for (const QString &attachment : std::as_const(attachments)) { 0159 mAttachments.push_back(Conversion::toStdString(attachment)); 0160 } 0161 return Conversion::fromKCalendarCore(*event); 0162 } 0163 const Kolab::Journal journal = Kolab::readJournal(s, false); 0164 ErrorHandler::handleLibkolabxmlErrors(); 0165 return journal; 0166 } 0167 0168 std::string XMLObject::writeFreebusy(const Freebusy &event, Version version, const std::string &productId) 0169 { 0170 mWrittenUID.clear(); 0171 if (version != KolabV3) { 0172 qCCritical(PIMKOLAB_LOG) << "only v3 implementation available"; 0173 return {}; 0174 } 0175 const std::string result = Kolab::writeFreebusy(event, productId); 0176 mWrittenUID = Kolab::getSerializedUID(); 0177 return result; 0178 } 0179 0180 Freebusy XMLObject::readFreebusy(const std::string &s, Version version) 0181 { 0182 if (version != KolabV3) { 0183 qCCritical(PIMKOLAB_LOG) << "only v3 implementation available"; 0184 return {}; 0185 } 0186 return Kolab::readFreebusy(s, false); 0187 } 0188 0189 std::string XMLObject::logoAttachmentName() const 0190 { 0191 return mLogoAttachmentName; 0192 } 0193 0194 std::string XMLObject::pictureAttachmentName() const 0195 { 0196 return mPictureAttachmentName; 0197 } 0198 0199 std::string XMLObject::soundAttachmentName() const 0200 { 0201 return mSoundAttachmentName; 0202 } 0203 0204 Contact XMLObject::readContact(const std::string &s, Version version) 0205 { 0206 if (version == KolabV2) { 0207 const QByteArray xmlData(s.c_str(), s.size()); 0208 QString pictureAttachmentName; 0209 QString logoAttachmentName; 0210 QString soundAttachmentName; 0211 const KContacts::Addressee addressee = addresseeFromKolab(xmlData, pictureAttachmentName, logoAttachmentName, soundAttachmentName); 0212 mPictureAttachmentName = Conversion::toStdString(pictureAttachmentName); 0213 mLogoAttachmentName = Conversion::toStdString(logoAttachmentName); 0214 mSoundAttachmentName = Conversion::toStdString(soundAttachmentName); 0215 return Conversion::fromKABC(addressee); 0216 } 0217 const Kolab::Contact contact = Kolab::readContact(s, false); 0218 ErrorHandler::handleLibkolabxmlErrors(); 0219 return contact; 0220 } 0221 0222 std::string XMLObject::writeContact(const Contact &contact, Version version, const std::string &productId) 0223 { 0224 mWrittenUID.clear(); 0225 if (version == KolabV2) { 0226 // FIXME attachment names are hardcoded for now 0227 KContacts::Addressee addressee = Conversion::toKABC(contact); 0228 if (addressee.uid().isEmpty()) { 0229 addressee.setUid(createUuid()); 0230 } 0231 mWrittenUID = Conversion::toStdString(addressee.uid()); 0232 const KolabV2::Contact contact(&addressee); 0233 return Conversion::toStdString(contact.saveXML()); 0234 } 0235 const std::string result = Kolab::writeContact(contact, productId); 0236 mWrittenUID = Kolab::getSerializedUID(); 0237 ErrorHandler::handleLibkolabxmlErrors(); 0238 return result; 0239 } 0240 0241 DistList XMLObject::readDistlist(const std::string &s, Version version) 0242 { 0243 if (version == KolabV2) { 0244 const QByteArray xmlData(s.c_str(), s.size()); 0245 const KContacts::ContactGroup contactGroup = contactGroupFromKolab(xmlData); 0246 return Conversion::fromKABC(contactGroup); 0247 } 0248 const Kolab::DistList distlist = Kolab::readDistlist(s, false); 0249 ErrorHandler::handleLibkolabxmlErrors(); 0250 return distlist; 0251 } 0252 0253 std::string XMLObject::writeDistlist(const DistList &distlist, Version version, const std::string &productId) 0254 { 0255 mWrittenUID.clear(); 0256 if (version == KolabV2) { 0257 KContacts::ContactGroup contactGroup = Conversion::toKABC(distlist); 0258 if (contactGroup.id().isEmpty()) { 0259 contactGroup.setId(createUuid()); 0260 } 0261 mWrittenUID = Conversion::toStdString(contactGroup.id()); 0262 const KolabV2::DistributionList d(&contactGroup); 0263 return Conversion::toStdString(d.saveXML()); 0264 } 0265 const std::string result = Kolab::writeDistlist(distlist, productId); 0266 mWrittenUID = Kolab::getSerializedUID(); 0267 ErrorHandler::handleLibkolabxmlErrors(); 0268 return result; 0269 } 0270 0271 Note XMLObject::readNote(const std::string &s, Version version) 0272 { 0273 if (version == KolabV2) { 0274 const KMime::Message::Ptr msg = noteFromKolab(QByteArray(s.c_str(), s.length()), QDateTime()); 0275 if (!msg || Kolab::ErrorHandler::errorOccured()) { 0276 qCCritical(PIMKOLAB_LOG) << "failed to read xml"; 0277 return {}; 0278 } 0279 return Conversion::fromNote(msg); 0280 } 0281 const Kolab::Note note = Kolab::readNote(s, false); 0282 ErrorHandler::handleLibkolabxmlErrors(); 0283 return note; 0284 } 0285 0286 std::string XMLObject::writeNote(const Note ¬e, Version version, const std::string &productId) 0287 { 0288 mWrittenUID.clear(); 0289 if (version == KolabV2) { 0290 Note noteWithUID = note; 0291 if (noteWithUID.uid().empty()) { 0292 noteWithUID.setUid(Conversion::toStdString(createUuid())); 0293 } 0294 mWrittenUID = noteWithUID.uid(); 0295 const KMime::Message::Ptr n = Conversion::toNote(noteWithUID); 0296 const QByteArray &xml = noteToKolabXML(n); 0297 return std::string(xml.constData()); 0298 } 0299 const std::string result = Kolab::writeNote(note, productId); 0300 mWrittenUID = Kolab::getSerializedUID(); 0301 ErrorHandler::handleLibkolabxmlErrors(); 0302 return result; 0303 } 0304 0305 Configuration XMLObject::readConfiguration(const std::string &s, Version version) 0306 { 0307 if (version == KolabV2) { 0308 QString lang; 0309 const QStringList dict = readLegacyDictionaryConfiguration(QByteArray(s.c_str(), s.length()), lang); 0310 if (lang.isEmpty()) { 0311 qCCritical(PIMKOLAB_LOG) << "not a dictionary or not a v2 configuration object"; 0312 return {}; 0313 } 0314 std::vector<std::string> entries; 0315 entries.reserve(dict.size()); 0316 for (const QString &e : std::as_const(dict)) { 0317 entries.push_back(Conversion::toStdString(e)); 0318 } 0319 Kolab::Dictionary dictionary(Conversion::toStdString(lang)); 0320 dictionary.setEntries(entries); 0321 return Configuration(dictionary); 0322 } 0323 const Kolab::Configuration configuration = Kolab::readConfiguration(s, false); 0324 ErrorHandler::handleLibkolabxmlErrors(); 0325 return configuration; 0326 } 0327 0328 std::string XMLObject::writeConfiguration(const Configuration &configuration, Version version, const std::string &productId) 0329 { 0330 mWrittenUID.clear(); 0331 if (version != KolabV3) { 0332 qCCritical(PIMKOLAB_LOG) << "only v3 implementation available"; 0333 return {}; 0334 } 0335 const std::string result = Kolab::writeConfiguration(configuration, productId); 0336 mWrittenUID = Kolab::getSerializedUID(); 0337 ErrorHandler::handleLibkolabxmlErrors(); 0338 return result; 0339 } 0340 0341 File XMLObject::readFile(const std::string &s, Version version) 0342 { 0343 if (version == KolabV2) { 0344 qCCritical(PIMKOLAB_LOG) << "only v3 implementation available"; 0345 return {}; 0346 } 0347 const Kolab::File file = Kolab::readFile(s, false); 0348 ErrorHandler::handleLibkolabxmlErrors(); 0349 return file; 0350 } 0351 0352 std::string XMLObject::writeFile(const File &file, Version version, const std::string &productId) 0353 { 0354 mWrittenUID.clear(); 0355 if (version != KolabV3) { 0356 qCCritical(PIMKOLAB_LOG) << "only v3 implementation available"; 0357 return {}; 0358 } 0359 const std::string result = Kolab::writeFile(file, productId); 0360 mWrittenUID = Kolab::getSerializedUID(); 0361 ErrorHandler::handleLibkolabxmlErrors(); 0362 return result; 0363 } 0364 }