summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Mollekopf <mollekopf@kolabsys.com>2015-05-07 15:20:49 +0200
committerChristian Mollekopf <mollekopf@kolabsys.com>2015-05-07 16:42:32 +0200
commit572dd4e413f3b98196a2e9e0b1ad090e6f1daa01 (patch)
treec9a4080777ec91c219d59c2ef0df8ca11e6d68ff
parenta7549c655636418015af59ddad002ca1001460e1 (diff)
downloadlibkolab-572dd4e413f3b98196a2e9e0b1ad090e6f1daa01.tar.gz
Moved MIME message handling from KolabObject to MIMEObject
-rw-r--r--conversion/commonconversion.cpp25
-rw-r--r--conversion/commonconversion.h3
-rw-r--r--conversion/kcalconversion.cpp4
-rw-r--r--kolabformat/kolabobject.cpp442
-rw-r--r--kolabformat/mimeobject.cpp717
-rw-r--r--kolabformat/mimeobject.h45
-rw-r--r--kolabformat/v2helpers.cpp8
-rw-r--r--mime/mimeutils.cpp105
-rw-r--r--mime/mimeutils.h15
9 files changed, 899 insertions, 465 deletions
diff --git a/conversion/commonconversion.cpp b/conversion/commonconversion.cpp
index 177b796..c30f6cf 100644
--- a/conversion/commonconversion.cpp
+++ b/conversion/commonconversion.cpp
@@ -144,27 +144,34 @@ QUrl toMailto(const std::string &email, const std::string &name)
std::string fromMailto(const QUrl &mailtoUri, std::string &name)
{
- const std::string &decoded = toStdString(mailtoUri.toString());
+ const QPair<std::string, std::string> pair = fromMailto(toStdString(mailtoUri.toString()));
+ name = pair.second;
+ return pair.first;
+}
+
+QPair<std::string, std::string> fromMailto(const std::string &mailto)
+{
+ const std::string &decoded = toStdString(QUrl::fromPercentEncoding(QByteArray(mailto.c_str())));
if (decoded.substr(0, 7).compare("mailto:")) {
- WARNING("no mailto address");
- std::cout << decoded << std::endl;
- return decoded;
+ // WARNING("no mailto address");
+ // std::cout << decoded << std::endl;
+ return qMakePair(decoded, std::string());
}
std::size_t begin = decoded.find('<',7);
if (begin == std::string::npos) {
WARNING("no mailto address");
std::cout << decoded << std::endl;
- return decoded;
+ return qMakePair(decoded, std::string());
}
std::size_t end = decoded.find('>', begin);
if (end == std::string::npos) {
WARNING("no mailto address");
std::cout << decoded << std::endl;
- return decoded;
+ return qMakePair(decoded, std::string());
}
- name = decoded.substr(7, begin-7);
- const std::string &email = decoded.substr(begin+1, end-begin-1);
- return email;
+ const std::string name = decoded.substr(7, begin-7);
+ const std::string email = decoded.substr(begin+1, end-begin-1);
+ return qMakePair(email, name);
}
}
diff --git a/conversion/commonconversion.h b/conversion/commonconversion.h
index fd4c191..6bed36c 100644
--- a/conversion/commonconversion.h
+++ b/conversion/commonconversion.h
@@ -38,6 +38,7 @@ namespace Kolab {
QUrl toMailto(const std::string &email, const std::string &name = std::string());
std::string fromMailto(const QUrl &mailtoUri, std::string &name);
+ QPair<std::string, std::string> fromMailto(const std::string &mailto);
inline std::string toStdString(const QString &s)
{
@@ -52,4 +53,4 @@ namespace Kolab {
};
};
-#endif \ No newline at end of file
+#endif
diff --git a/conversion/kcalconversion.cpp b/conversion/kcalconversion.cpp
index bec4478..4cf588e 100644
--- a/conversion/kcalconversion.cpp
+++ b/conversion/kcalconversion.cpp
@@ -315,9 +315,11 @@ void setIncidence(KCalCore::Incidence &i, const T &e)
foreach (const Kolab::Attachment a, e.attachments()) {
KCalCore::Attachment::Ptr ptr;
if (!a.uri().empty()) {
+ qDebug() << "with uri";
ptr = KCalCore::Attachment::Ptr(new KCalCore::Attachment(fromStdString(a.uri()), fromStdString(a.mimetype())));
} else {
- ptr = KCalCore::Attachment::Ptr(new KCalCore::Attachment(QByteArray::fromRawData(a.data().c_str(), a.data().size()), fromStdString(a.mimetype())));
+ qDebug() << "with data " << a.data();
+ ptr = KCalCore::Attachment::Ptr(new KCalCore::Attachment(QByteArray::fromRawData(a.data().c_str(), a.data().size()).toBase64(), fromStdString(a.mimetype())));
}
if (!a.label().empty()) {
ptr->setLabel(fromStdString(a.label()));
diff --git a/kolabformat/kolabobject.cpp b/kolabformat/kolabobject.cpp
index 60ab81c..fc368c9 100644
--- a/kolabformat/kolabobject.cpp
+++ b/kolabformat/kolabobject.cpp
@@ -35,6 +35,7 @@
#include <conversion/kolabconversion.h>
#include <conversion/commonconversion.h>
#include <akonadi/notes/noteutils.h>
+#include <kolabformat/mimeobject.h>
#include <kolabformat.h>
@@ -162,9 +163,6 @@ public:
mAddressee = KContacts::Addressee();
}
- ObjectType readKolabV2(const KMime::Message::Ptr &msg, Kolab::ObjectType objectType);
- ObjectType readKolabV3(const KMime::Message::Ptr &msg, Kolab::ObjectType objectType);
-
KCalCore::Incidence::Ptr mIncidence;
KContacts::Addressee mAddressee;
KContacts::ContactGroup mContactGroup;
@@ -210,90 +208,6 @@ void KolabObjectReader::setVersion(Version version)
d->mDoOverrideVersion = true;
}
-Kolab::ObjectType getObjectType(const QString &type)
-{
- if (type == eventKolabType()) {
- return EventObject;
- } else if (type == todoKolabType()) {
- return TodoObject;
- } else if (type == journalKolabType()) {
- return JournalObject;
- } else if (type == contactKolabType()) {
- return ContactObject;
- } else if (type == distlistKolabType() || type == distlistKolabTypeCompat()) {
- return DistlistObject;
- } else if (type == noteKolabType()) {
- return NoteObject;
- } else if (type == freebusyKolabType()) {
- return FreebusyObject;
- } else if (type.contains(dictKolabType())) { //Previous versions appended the language to the type
- return DictionaryConfigurationObject;
- } else if (type == relationKolabType()) {
- return RelationConfigurationObject;
- }
- Warning() << "Unknown object type: " << type;
- return Kolab::InvalidObject;
-}
-
-QByteArray getTypeString(Kolab::ObjectType type)
-{
- switch (type) {
- case EventObject:
- return KOLAB_TYPE_EVENT;
- case TodoObject:
- return KOLAB_TYPE_TASK;
- case JournalObject:
- return KOLAB_TYPE_JOURNAL;
- case FreebusyObject:
- return KOLAB_TYPE_FREEBUSY;
- case ContactObject:
- return KOLAB_TYPE_CONTACT;
- case DistlistObject:
- return KOLAB_TYPE_DISTLIST;
- case NoteObject:
- return KOLAB_TYPE_NOTE;
- case DictionaryConfigurationObject:
- return KOLAB_TYPE_CONFIGURATION;
- case RelationConfigurationObject:
- return KOLAB_TYPE_RELATION;
- default:
- Critical() << "unknown type "<< type;
- }
- return QByteArray();
-}
-
-QByteArray getMimeType(Kolab::ObjectType type)
-{
- switch (type) {
- case EventObject:
- case TodoObject:
- case JournalObject:
- case FreebusyObject:
- return MIME_TYPE_XCAL;
- case ContactObject:
- case DistlistObject:
- return MIME_TYPE_XCARD;
- case NoteObject:
- case DictionaryConfigurationObject:
- case RelationConfigurationObject:
- return MIME_TYPE_KOLAB;
- default:
- Critical() << "unknown type "<< type;
- }
- return QByteArray();
-}
-
-Kolab::ObjectType detectType(const KMime::Message::Ptr &msg)
-{
- Q_FOREACH(const QByteArray &type, Mime::getContentMimeTypeList(msg)) {
- Kolab::ObjectType t = getObjectType(type); //works for v2 types
- if (t != InvalidObject) {
- return t;
- }
- }
- return InvalidObject;
-}
-
void printMessageDebugInfo(const KMime::Message::Ptr &msg)
{
//TODO replace by Debug stream for Mimemessage
@@ -302,148 +216,92 @@ void printMessageDebugInfo(const KMime::Message::Ptr &msg)
// Debug() << msg->encodedContent();
}
-ObjectType KolabObjectReader::Private::readKolabV2(const KMime::Message::Ptr &msg, Kolab::ObjectType objectType)
+ObjectType KolabObjectReader::parseMimeMessage(const KMime::Message::Ptr &msg)
{
- if (objectType == DictionaryConfigurationObject) {
- KMime::Content *xmlContent = Mime::findContentByType( msg, "application/xml" );
- if ( !xmlContent ) {
- Critical() << "no application/xml part found";
- printMessageDebugInfo(msg);
- return InvalidObject;
- }
- const QByteArray &xmlData = xmlContent->decodedContent();
- mDictionary = readLegacyDictionaryConfiguration(xmlData, mDictionaryLanguage);
- mObjectType = objectType;
- return mObjectType;
- }
- KMime::Content *xmlContent = Mime::findContentByType( msg, getTypeString(objectType) );
- if ( !xmlContent ) {
- Critical() << "no part with type" << getTypeString(objectType) << " found";
- printMessageDebugInfo(msg);
- return InvalidObject;
- }
- const QByteArray &xmlData = xmlContent->decodedContent();
- Q_ASSERT(!xmlData.isEmpty());
- QStringList attachments;
-
- switch (objectType) {
- case EventObject:
- mIncidence = fromXML<KCalCore::Event::Ptr, KolabV2::Event>(xmlData, attachments);
- break;
- case TodoObject:
- mIncidence = fromXML<KCalCore::Todo::Ptr, KolabV2::Task>(xmlData, attachments);
- break;
- case JournalObject:
- mIncidence = fromXML<KCalCore::Journal::Ptr, KolabV2::Journal>(xmlData, attachments);
- break;
- case ContactObject:
- mAddressee = addresseeFromKolab(xmlData, msg);
- break;
- case DistlistObject:
- mContactGroup = contactGroupFromKolab(xmlData);
- break;
- case NoteObject:
- mNote = noteFromKolab(xmlData, KDateTime(msg->date()->dateTime()));
- break;
- default:
- CRITICAL("no kolab object found ");
- break;
- }
- if (!mIncidence.isNull()) {
-// qDebug() << "v2 attachments " << attachments.size() << d->mIncidence->attachments().size();
- mIncidence->clearAttachments();
- Mime::getAttachments(mIncidence, attachments, msg);
- if (mIncidence->attachments().size() != attachments.size()) {
- Error() << "Could not extract all attachments. " << mIncidence->attachments().size() << " out of " << attachments.size();
- }
- }
- if (ErrorHandler::errorOccured()) {
+ ErrorHandler::clearErrors();
+ d->mObjectType = InvalidObject;
+ if (msg->contents().isEmpty()) {
+ Critical() << "message has no contents (we likely failed to parse it correctly)";
printMessageDebugInfo(msg);
return InvalidObject;
}
- mObjectType = objectType;
- return mObjectType;
-}
-
-ObjectType KolabObjectReader::Private::readKolabV3(const KMime::Message::Ptr &msg, Kolab::ObjectType objectType)
-{
- KMime::Content * const xmlContent = Mime::findContentByType( msg, getMimeType(objectType) );
- if ( !xmlContent ) {
- Critical() << "no " << getMimeType(objectType) << " part found";
- printMessageDebugInfo(msg);
- return InvalidObject;
+ const std::string message = msg->encodedContent().toStdString();
+ Kolab::MIMEObject mimeObject;
+ mimeObject.setObjectType(d->mOverrideObjectType);
+ if (d->mDoOverrideVersion) {
+ mimeObject.setVersion(d->mOverrideVersion);
}
- const QByteArray &content = xmlContent->decodedContent();
- const std::string xml = std::string(content.data(), content.size());
- switch (objectType) {
+ d->mObjectType = mimeObject.parseMessage(message);
+ d->mVersion = mimeObject.getVersion();
+ switch (mimeObject.getType()) {
case EventObject: {
- const Kolab::Event & event = Kolab::readEvent(xml, false);
- mIncidence = Kolab::Conversion::toKCalCore(event);
+ const Kolab::Event & event = mimeObject.getEvent();
+ d->mIncidence = Kolab::Conversion::toKCalCore(event);
}
break;
case TodoObject: {
- const Kolab::Todo & event = Kolab::readTodo(xml, false);
- mIncidence = Kolab::Conversion::toKCalCore(event);
+ const Kolab::Todo & event = mimeObject.getTodo();
+ d->mIncidence = Kolab::Conversion::toKCalCore(event);
}
break;
case JournalObject: {
- const Kolab::Journal & event = Kolab::readJournal(xml, false);
- mIncidence = Kolab::Conversion::toKCalCore(event);
+ const Kolab::Journal & event = mimeObject.getJournal();
+ d->mIncidence = Kolab::Conversion::toKCalCore(event);
}
break;
case ContactObject: {
- const Kolab::Contact &contact = Kolab::readContact(xml, false);
- mAddressee = Kolab::Conversion::toKABC(contact); //TODO extract attachments
+ const Kolab::Contact &contact = mimeObject.getContact();
+ d->mAddressee = Kolab::Conversion::toKABC(contact); //TODO extract attachments
}
break;
case DistlistObject: {
- const Kolab::DistList &distlist = Kolab::readDistlist(xml, false);
- mContactGroup = Kolab::Conversion::toKABC(distlist);
+ const Kolab::DistList &distlist = mimeObject.getDistlist();
+ d->mContactGroup = Kolab::Conversion::toKABC(distlist);
}
break;
case NoteObject: {
- const Kolab::Note &note = Kolab::readNote(xml, false);
- mNote = Kolab::Conversion::toNote(note);
+ const Kolab::Note &note = mimeObject.getNote();
+ d->mNote = Kolab::Conversion::toNote(note);
}
break;
case DictionaryConfigurationObject: {
- const Kolab::Configuration &configuration = Kolab::readConfiguration(xml, false);
+ const Kolab::Configuration &configuration = mimeObject.getConfiguration();
const Kolab::Dictionary &dictionary = configuration.dictionary();
- mDictionary.clear();
+ d->mDictionary.clear();
foreach (const std::string &entry, dictionary.entries()) {
- mDictionary.append(Conversion::fromStdString(entry));
+ d->mDictionary.append(Conversion::fromStdString(entry));
}
- mDictionaryLanguage = Conversion::fromStdString(dictionary.language());
+ d->mDictionaryLanguage = Conversion::fromStdString(dictionary.language());
}
break;
case FreebusyObject: {
- const Kolab::Freebusy &fb = Kolab::readFreebusy(xml, false);
- mFreebusy = fb;
- }
+ const Kolab::Freebusy &fb = mimeObject.getFreebusy();
+ d->mFreebusy = fb;
break;
+ }
case RelationConfigurationObject: {
- const Kolab::Configuration &configuration = Kolab::readConfiguration(xml, false);
+ const Kolab::Configuration &configuration = mimeObject.getConfiguration();
const Kolab::Relation &relation = configuration.relation();
if (relation.type() == "tag") {
- mTag = Akonadi::Tag();
- mTag.setName(Conversion::fromStdString(relation.name()));
- mTag.setGid(Conversion::fromStdString(configuration.uid()).toLatin1());
- mTag.setType(Akonadi::Tag::GENERIC);
+ d->mTag = Akonadi::Tag();
+ d->mTag.setName(Conversion::fromStdString(relation.name()));
+ d->mTag.setGid(Conversion::fromStdString(configuration.uid()).toLatin1());
+ d->mTag.setType(Akonadi::Tag::GENERIC);
- mTagMembers.reserve(relation.members().size());
+ d->mTagMembers.reserve(relation.members().size());
foreach (const std::string &member, relation.members()) {
- mTagMembers << Conversion::fromStdString(member);
+ d->mTagMembers << Conversion::fromStdString(member);
}
} else if (relation.type() == "generic") {
if (relation.members().size() == 2) {
- mRelation = Akonadi::Relation();
- mRelation.setRemoteId(Conversion::fromStdString(configuration.uid()).toLatin1());
- mRelation.setType(Akonadi::Relation::GENERIC);
+ d->mRelation = Akonadi::Relation();
+ d->mRelation.setRemoteId(Conversion::fromStdString(configuration.uid()).toLatin1());
+ d->mRelation.setType(Akonadi::Relation::GENERIC);
- mTagMembers.reserve(relation.members().size());
+ d->mTagMembers.reserve(relation.members().size());
foreach (const std::string &member, relation.members()) {
- mTagMembers << Conversion::fromStdString(member);
+ d->mTagMembers << Conversion::fromStdString(member);
}
} else {
Critical() << "generic relation had wrong number of members:" << relation.members().size();
@@ -460,69 +318,7 @@ ObjectType KolabObjectReader::Private::readKolabV3(const KMime::Message::Ptr &ms
printMessageDebugInfo(msg);
break;
}
-
- if (!mIncidence.isNull()) {
-// qDebug() << "getting attachments";
- Mime::getAttachmentsById(mIncidence, msg);
- }
- ErrorHandler::handleLibkolabxmlErrors();
- if (ErrorHandler::errorOccured()) {
- printMessageDebugInfo(msg);
- return InvalidObject;
- }
- mObjectType = objectType;
- return mObjectType;
-}
-
-ObjectType KolabObjectReader::parseMimeMessage(const KMime::Message::Ptr &msg)
-{
- ErrorHandler::clearErrors();
- d->mObjectType = InvalidObject;
- if (msg->contents().isEmpty()) {
- Critical() << "message has no contents (we likely failed to parse it correctly)";
- printMessageDebugInfo(msg);
- return InvalidObject;
- }
- Kolab::ObjectType objectType = InvalidObject;
- if (d->mOverrideObjectType == InvalidObject) {
- if (KMime::Headers::Base *xKolabHeader = msg->getHeaderByType(X_KOLAB_TYPE_HEADER)) {
- objectType = getObjectType(xKolabHeader->asUnicodeString().trimmed());
- } else {
- Warning() << "could not find the X-Kolab-Type Header, trying autodetection" ;
- //This works only for v2 messages atm.
- objectType = detectType(msg);
- }
- } else {
- objectType = d->mOverrideObjectType;
- }
- if (objectType == InvalidObject) {
- Critical() << "unable to detect object type";
- printMessageDebugInfo(msg);
- return InvalidObject;
- }
-
- if (!d->mDoOverrideVersion) {
- KMime::Headers::Base *xKolabVersion = msg->getHeaderByType(X_KOLAB_MIME_VERSION_HEADER);
- if (!xKolabVersion) {
- //For backwards compatibility to development versions, can be removed in future versions
- xKolabVersion = msg->getHeaderByType(X_KOLAB_MIME_VERSION_HEADER_COMPAT);
- }
- if (!xKolabVersion || xKolabVersion->asUnicodeString() == KOLAB_VERSION_V2) {
- d->mVersion = KolabV2;
- } else {
- if (xKolabVersion->asUnicodeString() != KOLAB_VERSION_V3) { //TODO version compatibility check?
- Warning() << "Kolab Version Header available but not on the same version as the implementation: " << xKolabVersion->asUnicodeString();
- }
- d->mVersion = KolabV3;
- }
- } else {
- d->mVersion = d->mOverrideVersion;
- }
-
- if (d->mVersion == KolabV2) {
- return d->readKolabV2(msg, objectType);
- }
- return d->readKolabV3(msg, objectType);
+ return d->mObjectType;
}
Version KolabObjectReader::getVersion() const
@@ -606,89 +402,51 @@ Akonadi::Relation KolabObjectReader::getRelation() const
return d->mRelation;
}
-
-//Normalize incidences before serializing them
-KCalCore::Incidence::Ptr normalizeIncidence(KCalCore::Incidence::Ptr original)
-{
- KCalCore::Incidence::Ptr i = KCalCore::Incidence::Ptr(original->clone()); //We copy to avoid destructive writing
- Q_FOREACH (KCalCore::Attachment::Ptr attachment, i->attachments()) {
- attachment->setUri(QString::fromLatin1("cid:")+QString::fromLatin1(KMime::uniqueString() + '@' + "kolab.resource.akonadi")); //Serialize the attachment as attachment with uri, referencing the created mime-part
- }
- return i;
-}
-/*
-KContacts::Addressee normalizeContact(const KContacts::Addressee &a)
-{
- KContacts::Addressee addresee = a;
- Q_FOREACH (KCalCore::Attachment::Ptr attachment, addresee.photo()) {
- attachment->setUri(QString::fromLatin1("cid:")+QString::fromLatin1(KMime::uniqueString() + '@' + "kolab.resource.akonadi")); //Serialize the attachment as attachment with uri, referencing the created mime-part
- }
- return i;
-}*/
-
-QString getProductId(const QString &pId)
+static KMime::Message::Ptr createMimeMessage(const std::string &mimeMessage)
{
- if (pId.isEmpty()) {
- return LIBKOLAB_LIB_VERSION_STRING;
- }
- return pId+" "+LIBKOLAB_LIB_VERSION_STRING;
+ KMime::Message::Ptr msg(new KMime::Message);
+ msg->setContent(QByteArray(mimeMessage.c_str()));
+ msg->parse();
+ return msg;
}
-KMime::Message::Ptr KolabObjectWriter::writeEvent(const KCalCore::Event::Ptr &i, Version v, const QString &productId, const QString &tz)
+KMime::Message::Ptr KolabObjectWriter::writeEvent(const KCalCore::Event::Ptr &i, Version v, const QString &productId, const QString &)
{
ErrorHandler::clearErrors();
if (!i) {
Critical() << "passed a null pointer";
return KMime::Message::Ptr();
}
- Q_ASSERT(!i.isNull());
- if (v == KolabV3) {
- KCalCore::Event::Ptr ic = normalizeIncidence(i).dynamicCast<KCalCore::Event>();
- const Kolab::Event &incidence = Kolab::Conversion::fromKCalCore(*ic);
- const std::string &v3String = Kolab::writeEvent(incidence, std::string(getProductId(productId).toUtf8().constData()));
- ErrorHandler::handleLibkolabxmlErrors();
- return Mime::createMessage(ic, xCalMimeType(), eventKolabType(), QString::fromUtf8(v3String.c_str()).toUtf8(), true, getProductId(productId));
- }
- const QString &xml = KolabV2::Event::eventToXML(i, tz);
- return Mime::createMessage(i, eventKolabType(), eventKolabType(), xml.toUtf8(), false, getProductId(productId));
+ const Kolab::Event &event = Kolab::Conversion::fromKCalCore(*i);
+ Kolab::MIMEObject mimeObject;
+ const std::string mimeMessage = mimeObject.writeEvent(event, v, productId.toStdString());
+ return createMimeMessage(mimeMessage);
}
-KMime::Message::Ptr KolabObjectWriter::writeTodo(const KCalCore::Todo::Ptr &i, Version v, const QString &productId, const QString &tz)
+KMime::Message::Ptr KolabObjectWriter::writeTodo(const KCalCore::Todo::Ptr &i, Version v, const QString &productId, const QString &)
{
ErrorHandler::clearErrors();
if (!i) {
Critical() << "passed a null pointer";
return KMime::Message::Ptr();
}
- Q_ASSERT(!i.isNull());
- if (v == KolabV3) {
- KCalCore::Todo::Ptr ic = normalizeIncidence(i).dynamicCast<KCalCore::Todo>();
- const Kolab::Todo &incidence = Kolab::Conversion::fromKCalCore(*ic);
- const std::string &v3String = Kolab::writeTodo(incidence, Conversion::toStdString(getProductId(productId)));
- ErrorHandler::handleLibkolabxmlErrors();
- return Mime::createMessage(ic, xCalMimeType(), todoKolabType(), Conversion::fromStdString(v3String).toUtf8(), true, getProductId(productId));
- }
- const QString &xml = KolabV2::Task::taskToXML(i, tz);
- return Mime::createMessage(i, todoKolabType(), todoKolabType(), xml.toUtf8(), false, getProductId(productId));
+ const Kolab::Todo &todo = Kolab::Conversion::fromKCalCore(*i);
+ Kolab::MIMEObject mimeObject;
+ const std::string mimeMessage = mimeObject.writeTodo(todo, v, productId.toStdString());
+ return createMimeMessage(mimeMessage);
}
-KMime::Message::Ptr KolabObjectWriter::writeJournal(const KCalCore::Journal::Ptr &i, Version v, const QString &productId, const QString &tz)
+KMime::Message::Ptr KolabObjectWriter::writeJournal(const KCalCore::Journal::Ptr &i, Version v, const QString &productId, const QString &)
{
ErrorHandler::clearErrors();
if (!i) {
Critical() << "passed a null pointer";
return KMime::Message::Ptr();
}
- Q_ASSERT(!i.isNull());
- if (v == KolabV3) {
- KCalCore::Journal::Ptr ic = normalizeIncidence(i).dynamicCast<KCalCore::Journal>();
- const Kolab::Journal &incidence = Kolab::Conversion::fromKCalCore(*ic);
- const std::string &v3String = Kolab::writeJournal(incidence, Conversion::toStdString(getProductId(productId)));
- ErrorHandler::handleLibkolabxmlErrors();
- return Mime::createMessage(ic, xCalMimeType(), journalKolabType(), Conversion::fromStdString(v3String).toUtf8(), true, getProductId(productId));
- }
- const QString &xml = KolabV2::Journal::journalToXML(i, tz);
- return Mime::createMessage(i, journalKolabType(), journalKolabType(), xml.toUtf8(), false, getProductId(productId));
+ const Kolab::Journal &journal = Kolab::Conversion::fromKCalCore(*i);
+ Kolab::MIMEObject mimeObject;
+ const std::string mimeMessage = mimeObject.writeJournal(journal, v, productId.toStdString());
+ return createMimeMessage(mimeMessage);
}
KMime::Message::Ptr KolabObjectWriter::writeIncidence(const KCalCore::Incidence::Ptr &i, Version v, const QString& productId, const QString& tz)
@@ -714,52 +472,37 @@ KMime::Message::Ptr KolabObjectWriter::writeIncidence(const KCalCore::Incidence:
KMime::Message::Ptr KolabObjectWriter::writeContact(const KContacts::Addressee &addressee, Version v, const QString &productId)
{
ErrorHandler::clearErrors();
- if (v == KolabV3) {
- const Kolab::Contact &contact = Kolab::Conversion::fromKABC(addressee);
- const std::string &v3String = Kolab::writeContact(contact, Conversion::toStdString(getProductId(productId)));
- ErrorHandler::handleLibkolabxmlErrors();
- return Mime::createMessage(addressee, xCardMimeType(), contactKolabType(), Conversion::fromStdString(v3String).toUtf8(), true, getProductId(productId));
- }
- KolabV2::Contact contact(&addressee);
- return contactToKolabFormat(contact, getProductId(productId));
+ const Kolab::Contact &contact = Kolab::Conversion::fromKABC(addressee);
+ Kolab::MIMEObject mimeObject;
+ const std::string mimeMessage = mimeObject.writeContact(contact, v, productId.toStdString());
+ return createMimeMessage(mimeMessage);
}
-KMime::Message::Ptr KolabObjectWriter::writeDistlist(const KContacts::ContactGroup &distlist, Version v, const QString &productId)
+KMime::Message::Ptr KolabObjectWriter::writeDistlist(const KContacts::ContactGroup &kDistList, Version v, const QString &productId)
{
ErrorHandler::clearErrors();
- if (v == KolabV3) {
- const Kolab::DistList &dist = Kolab::Conversion::fromKABC(distlist);
- const std::string &v3String = Kolab::writeDistlist(dist, Conversion::toStdString(getProductId(productId)));
- ErrorHandler::handleLibkolabxmlErrors();
- return Mime::createMessage(Conversion::fromStdString(dist.uid()), xCardMimeType(), distlistKolabType(), Conversion::fromStdString(v3String).toUtf8(), true, getProductId(productId));
- }
- KolabV2::DistributionList d(&distlist);
- return distListToKolabFormat(d, getProductId(productId));
+ const Kolab::DistList &distlist = Kolab::Conversion::fromKABC(kDistList);
+ Kolab::MIMEObject mimeObject;
+ const std::string mimeMessage = mimeObject.writeDistlist(distlist, v, productId.toStdString());
+ return createMimeMessage(mimeMessage);
}
-KMime::Message::Ptr KolabObjectWriter::writeNote(const KMime::Message::Ptr &note, Version v, const QString &productId)
+KMime::Message::Ptr KolabObjectWriter::writeNote(const KMime::Message::Ptr &n, Version v, const QString &productId)
{
ErrorHandler::clearErrors();
- if (!note) {
+ if (!n) {
Critical() << "passed a null pointer";
return KMime::Message::Ptr();
}
- Q_ASSERT(note.get());
- if (v == KolabV3) {
- const Kolab::Note &n = Kolab::Conversion::fromNote(note);
- const std::string &v3String = Kolab::writeNote(n, Conversion::toStdString(getProductId(productId)));
- ErrorHandler::handleLibkolabxmlErrors();
- return Mime::createMessage(Conversion::fromStdString(n.uid()), kolabMimeType(), noteKolabType(), Conversion::fromStdString(v3String).toUtf8(), true, getProductId(productId));
- }
- return noteToKolab(note, getProductId(productId));
+ const Kolab::Note &note = Kolab::Conversion::fromNote(n);
+ Kolab::MIMEObject mimeObject;
+ const std::string mimeMessage = mimeObject.writeNote(note, v, productId.toStdString());
+ return createMimeMessage(mimeMessage);
}
KMime::Message::Ptr KolabObjectWriter::writeDictionary(const QStringList &entries, const QString& lang, Version v, const QString& productId)
{
ErrorHandler::clearErrors();
- if (v != KolabV3) {
- Critical() << "only v3 implementation available";
- }
Kolab::Dictionary dictionary(Conversion::toStdString(lang));
std::vector <std::string> ent;
@@ -768,29 +511,28 @@ KMime::Message::Ptr KolabObjectWriter::writeDictionary(const QStringList &entrie
}
dictionary.setEntries(ent);
Kolab::Configuration configuration(dictionary); //TODO preserve creation/lastModified date
- const std::string &v3String = Kolab::writeConfiguration(configuration, Conversion::toStdString(getProductId(productId)));
- ErrorHandler::handleLibkolabxmlErrors();
- return Mime::createMessage(Conversion::fromStdString(configuration.uid()), kolabMimeType(), dictKolabType(), Conversion::fromStdString(v3String).toUtf8(), true, getProductId(productId));
+ Kolab::MIMEObject mimeObject;
+ const std::string mimeMessage = mimeObject.writeConfiguration(configuration, v, productId.toStdString());
+ return createMimeMessage(mimeMessage);
}
KMime::Message::Ptr KolabObjectWriter::writeFreebusy(const Freebusy &freebusy, Version v, const QString& productId)
{
ErrorHandler::clearErrors();
- if (v != KolabV3) {
- Critical() << "only v3 implementation available";
- }
- const std::string &v3String = Kolab::writeFreebusy(freebusy, Conversion::toStdString(getProductId(productId)));
- ErrorHandler::handleLibkolabxmlErrors();
- return Mime::createMessage(Conversion::fromStdString(freebusy.uid()), xCalMimeType(), freebusyKolabType(), Conversion::fromStdString(v3String).toUtf8(), true, getProductId(productId));
+ Kolab::MIMEObject mimeObject;
+ const std::string mimeMessage = mimeObject.writeFreebusy(freebusy, v, productId.toStdString());
+ return createMimeMessage(mimeMessage);
}
KMime::Message::Ptr writeRelationHelper(const Kolab::Relation &relation, const QByteArray &uid, const QString &productId)
{
+ ErrorHandler::clearErrors();
+ Kolab::MIMEObject mimeObject;
+
Kolab::Configuration configuration(relation); //TODO preserve creation/lastModified date
configuration.setUid(uid.constData());
- const std::string &v3String = Kolab::writeConfiguration(configuration, Conversion::toStdString(getProductId(productId)));
- ErrorHandler::handleLibkolabxmlErrors();
- return Mime::createMessage(Conversion::fromStdString(configuration.uid()), kolabMimeType(), relationKolabType(), Conversion::fromStdString(v3String).toUtf8(), true, getProductId(productId));
+ const std::string mimeMessage = mimeObject.writeConfiguration(configuration, Kolab::KolabV3, Conversion::toStdString(productId));
+ return createMimeMessage(mimeMessage);
}
KMime::Message::Ptr KolabObjectWriter::writeTag(const Akonadi::Tag &tag, const QStringList &members, Version v, const QString &productId)
diff --git a/kolabformat/mimeobject.cpp b/kolabformat/mimeobject.cpp
index 336104b..98386cf 100644
--- a/kolabformat/mimeobject.cpp
+++ b/kolabformat/mimeobject.cpp
@@ -19,144 +19,717 @@
#include "conversion/kcalconversion.h"
#include "conversion/kolabconversion.h"
#include "conversion/kabcconversion.h"
+#include "conversion/commonconversion.h"
#include "kolabformat/kolabobject.h"
+#include "kolabformat/xmlobject.h"
+#include "kolabformat/errorhandler.h"
+#include "kolabformat/v2helpers.h"
+#include "mime/mimeutils.h"
+#include "libkolab-version.h"
#include <QString>
+#include <QtGlobal>
+#include <boost/algorithm/string/predicate.hpp>
+
+
+Q_DECLARE_METATYPE(Kolab::Event);
+Q_DECLARE_METATYPE(Kolab::Todo);
+Q_DECLARE_METATYPE(Kolab::Journal);
+Q_DECLARE_METATYPE(Kolab::Contact);
+Q_DECLARE_METATYPE(Kolab::DistList);
+Q_DECLARE_METATYPE(Kolab::Note);
+Q_DECLARE_METATYPE(Kolab::Freebusy);
+Q_DECLARE_METATYPE(Kolab::Configuration);
+
+static inline std::string eventKolabType() { return std::string(KOLAB_TYPE_EVENT); };
+static inline std::string todoKolabType() { return std::string(KOLAB_TYPE_TASK); };
+static inline std::string journalKolabType() { return std::string(KOLAB_TYPE_JOURNAL); };
+static inline std::string contactKolabType() { return std::string(KOLAB_TYPE_CONTACT); };
+static inline std::string distlistKolabType() { return std::string(KOLAB_TYPE_DISTLIST); }
+static inline std::string distlistKolabTypeCompat() { return std::string(KOLAB_TYPE_DISTLIST_V2); }
+static inline std::string noteKolabType() { return std::string(KOLAB_TYPE_NOTE); }
+static inline std::string configurationKolabType() { return std::string(KOLAB_TYPE_CONFIGURATION); }
+static inline std::string dictKolabType() { return std::string(KOLAB_TYPE_DICT); }
+static inline std::string freebusyKolabType() { return std::string(KOLAB_TYPE_FREEBUSY); }
+static inline std::string relationKolabType() { return std::string(KOLAB_TYPE_RELATION); }
+
+static inline std::string xCalMimeType() { return std::string(MIME_TYPE_XCAL); };
+static inline std::string xCardMimeType() { return std::string(MIME_TYPE_XCARD); };
+static inline std::string kolabMimeType() { return std::string(MIME_TYPE_KOLAB); };
+
+static std::string getProductId(const std::string &pId)
+{
+ if (pId.empty()) {
+ return LIBKOLAB_LIB_VERSION_STRING;
+ }
+ return pId + " " + LIBKOLAB_LIB_VERSION_STRING;
+}
namespace Kolab
{
-MIMEObject::MIMEObject()
+static Kolab::ObjectType getObjectType(const std::string &type)
{
+ if (type == eventKolabType()) {
+ return EventObject;
+ } else if (type == todoKolabType()) {
+ return TodoObject;
+ } else if (type == journalKolabType()) {
+ return JournalObject;
+ } else if (type == contactKolabType()) {
+ return ContactObject;
+ } else if (type == distlistKolabType() || type == distlistKolabTypeCompat()) {
+ return DistlistObject;
+ } else if (type == noteKolabType()) {
+ return NoteObject;
+ } else if (type == freebusyKolabType()) {
+ return FreebusyObject;
+ } else if (boost::contains(type, dictKolabType())) { //Previous versions appended the language to the type
+ return DictionaryConfigurationObject;
+ } else if (type == relationKolabType()) {
+ return RelationConfigurationObject;
+ }
+ Warning() << "Unknown object type: " << type;
+ return Kolab::InvalidObject;
+}
+static QByteArray getTypeString(Kolab::ObjectType type)
+{
+ switch (type) {
+ case EventObject:
+ return KOLAB_TYPE_EVENT;
+ case TodoObject:
+ return KOLAB_TYPE_TASK;
+ case JournalObject:
+ return KOLAB_TYPE_JOURNAL;
+ case FreebusyObject:
+ return KOLAB_TYPE_FREEBUSY;
+ case ContactObject:
+ return KOLAB_TYPE_CONTACT;
+ case DistlistObject:
+ return KOLAB_TYPE_DISTLIST;
+ case NoteObject:
+ return KOLAB_TYPE_NOTE;
+ case DictionaryConfigurationObject:
+ return KOLAB_TYPE_CONFIGURATION;
+ case RelationConfigurationObject:
+ return KOLAB_TYPE_RELATION;
+ default:
+ Critical() << "unknown type "<< type;
+ }
+ return QByteArray();
}
-std::string MIMEObject::writeEvent(const Event &event, Version version, const std::string &productId)
+static QByteArray getMimeType(Kolab::ObjectType type)
{
+ switch (type) {
+ case EventObject:
+ case TodoObject:
+ case JournalObject:
+ case FreebusyObject:
+ return MIME_TYPE_XCAL;
+ case ContactObject:
+ case DistlistObject:
+ return MIME_TYPE_XCARD;
+ case NoteObject:
+ case DictionaryConfigurationObject:
+ case RelationConfigurationObject:
+ return MIME_TYPE_KOLAB;
+ default:
+ Critical() << "unknown type "<< type;
+ }
+ return QByteArray();
+}
- KCalCore::Event::Ptr KEvent = Conversion::toKCalCore(event);
+static Kolab::ObjectType detectType(const KMime::Message::Ptr &msg)
+{
+ Q_FOREACH(const QByteArray &type, Mime::getContentMimeTypeList(msg)) {
+ Kolab::ObjectType t = getObjectType(type.toStdString()); //works for v2 types
+ if (t != InvalidObject) {
+ return t;
+ }
+ }
+ return InvalidObject;
+}
- KMime::Message::Ptr msg = KolabObjectWriter().writeEvent(KEvent, version, QString::fromStdString(productId));
- msg->assemble();
+static void printMessageDebugInfo(const KMime::Message::Ptr &msg)
+{
+ //TODO replace by Debug stream for Mimemessage
+ Debug() << "MessageId: " << msg->messageID()->asUnicodeString();
+ Debug() << "Subject: " << msg->subject()->asUnicodeString();
+// Debug() << msg->encodedContent();
+}
- return msg->encodedContent().data();
+//@cond PRIVATE
+class MIMEObject::Private
+{
+public:
+ Private()
+ : mObjectType(InvalidObject),
+ mVersion(KolabV3),
+ mOverrideObjectType(InvalidObject),
+ mDoOverrideVersion(false)
+ {
+ }
+
+ QVariant readKolabV2(const KMime::Message::Ptr &msg, Kolab::ObjectType objectType);
+ QVariant readKolabV3(const KMime::Message::Ptr &msg, Kolab::ObjectType objectType);
+ QVariant parseMimeMessage(const KMime::Message::Ptr &msg);
+ QVariant parseMimeMessage(const std::string &s);
+
+ ObjectType mObjectType;
+ Version mVersion;
+ ObjectType mOverrideObjectType;
+ Version mOverrideVersion;
+ bool mDoOverrideVersion;
+ QVariant mObject;
+};
+//@endcond
+
+static std::vector<Kolab::Attachment> getAttachments(const std::vector<Kolab::Attachment> &attachments, const KMime::Message::Ptr &msg)
+{
+ std::vector<Kolab::Attachment> allAttachments;
+ foreach (const Kolab::Attachment &attachment, attachments) {
+ if (!attachment.uri().empty()) {
+ const Kolab::Attachment extracted = Mime::getAttachment(attachment.uri(), msg);
+ if (extracted.isValid()) {
+ allAttachments.push_back(extracted);
+ }
+ } else {
+ allAttachments.push_back(attachment);
+ }
+ }
+ return allAttachments;
}
-Event MIMEObject::readEvent(const std::string &s)
+static std::vector<Kolab::Attachment> getAttachments(const QStringList &attachmentNames, const KMime::Message::Ptr &msg)
{
+ std::vector<Kolab::Attachment> allAttachments;
+ foreach (const QString &name, attachmentNames) {
+ const Kolab::Attachment extracted = Mime::getAttachmentByName(name, msg);
+ if (extracted.isValid()) {
+ allAttachments.push_back(extracted);
+ }
+ }
+ return allAttachments;
+}
+QVariant MIMEObject::Private::readKolabV2(const KMime::Message::Ptr &msg, Kolab::ObjectType objectType)
+{
+ if (objectType == DictionaryConfigurationObject) {
+ KMime::Content *xmlContent = Mime::findContentByType(msg, "application/xml");
+ if (!xmlContent) {
+ Critical() << "no application/xml part found";
+ printMessageDebugInfo(msg);
+ return InvalidObject;
+ }
+ const QByteArray &xmlData = xmlContent->decodedContent();
+ QString dictionaryLanguage;
+ const QStringList entries = Kolab::readLegacyDictionaryConfiguration(xmlData, dictionaryLanguage);
+ mObjectType = objectType;
+ Kolab::Dictionary dictionary(Conversion::toStdString(dictionaryLanguage));
+ std::vector<std::string> convertedEntries;
+ foreach (const QString &value, entries) {
+ convertedEntries.push_back(Conversion::toStdString(value));
+ }
+ dictionary.setEntries(convertedEntries);
+ return QVariant::fromValue(Kolab::Configuration(dictionary));
+ }
+ KMime::Content *xmlContent = Mime::findContentByType(msg, getTypeString(objectType));
+ if (!xmlContent) {
+ Critical() << "no part with type" << getTypeString(objectType) << " found";
+ printMessageDebugInfo(msg);
+ return QVariant();
+ }
+ const QByteArray &xmlData = xmlContent->decodedContent();
+ Q_ASSERT(!xmlData.isEmpty());
+
+ QVariant variant;
+ switch (objectType) {
+ case EventObject: {
+ QStringList attachments;
+ KCalCore::Event::Ptr kEvent = fromXML<KCalCore::Event::Ptr, KolabV2::Event>(xmlData, attachments);
+ Kolab::Event event = Kolab::Conversion::fromKCalCore(*kEvent);
+ event.setAttachments(getAttachments(attachments, msg));
+ variant = QVariant::fromValue(event);
+ break;
+ }
+ case TodoObject: {
+ QStringList attachments;
+ KCalCore::Todo::Ptr kTodo = fromXML<KCalCore::Todo::Ptr, KolabV2::Task>(xmlData, attachments);
+ Kolab::Todo todo = Kolab::Conversion::fromKCalCore(*kTodo);
+ todo.setAttachments(getAttachments(attachments, msg));
+ variant = QVariant::fromValue(todo);
+ break;
+ }
+ case JournalObject: {
+ QStringList attachments;
+ KCalCore::Journal::Ptr kJournal = fromXML<KCalCore::Journal::Ptr, KolabV2::Journal>(xmlData, attachments);
+ Kolab::Journal journal = Kolab::Conversion::fromKCalCore(*kJournal);
+ journal.setAttachments(getAttachments(attachments, msg));
+ variant = QVariant::fromValue(journal);
+ break;
+ }
+ case ContactObject: {
+ KContacts::Addressee kContact= addresseeFromKolab(xmlData, msg);
+ Kolab::Contact contact = Kolab::Conversion::fromKABC(kContact);
+ variant = QVariant::fromValue(contact);
+ break;
+ }
+ case DistlistObject: {
+ KContacts::ContactGroup kContactGroup= contactGroupFromKolab(xmlData);
+ Kolab::DistList distlist = Kolab::Conversion::fromKABC(kContactGroup);
+ variant = QVariant::fromValue(distlist);
+ break;
+ }
+ case NoteObject: {
+ KMime::Message::Ptr kNote = noteFromKolab(xmlData, KDateTime(msg->date()->dateTime()));
+ Kolab::Note note = Kolab::Conversion::fromNote(kNote);
+ variant = QVariant::fromValue(note);
+ break;
+ }
+ default:
+ CRITICAL("no kolab object found ");
+ break;
+ }
+ if (ErrorHandler::errorOccured()) {
+ printMessageDebugInfo(msg);
+ return QVariant();
+ }
+ mObjectType = objectType;
+ return variant;
+}
+
+QVariant MIMEObject::Private::readKolabV3(const KMime::Message::Ptr &msg, Kolab::ObjectType objectType)
+{
+ KMime::Content * const xmlContent = Mime::findContentByType(msg, getMimeType(objectType));
+ if (!xmlContent) {
+ Critical() << "no " << getMimeType(objectType) << " part found";
+ printMessageDebugInfo(msg);
+ return InvalidObject;
+ }
+ const QByteArray &content = xmlContent->decodedContent();
+ const std::string xml = std::string(content.data(), content.size());
+ QVariant variant;
+ switch (objectType) {
+ case EventObject: {
+ Kolab::Event event = Kolab::readEvent(xml, false);
+ event.setAttachments(getAttachments(event.attachments(), msg));
+ variant = QVariant::fromValue<Kolab::Event>(event);
+ break;
+ }
+ case TodoObject: {
+ Kolab::Todo todo = Kolab::readTodo(xml, false);
+ todo.setAttachments(getAttachments(todo.attachments(), msg));
+ variant = QVariant::fromValue<Kolab::Todo>(todo);
+ break;
+ }
+ case JournalObject: {
+ Kolab::Journal journal = Kolab::readJournal(xml, false);
+ journal.setAttachments(getAttachments(journal.attachments(), msg));
+ variant = QVariant::fromValue<Kolab::Journal>(journal);
+ break;
+ }
+ case ContactObject:
+ variant = QVariant::fromValue<Kolab::Contact>(Kolab::readContact(xml, false));
+ break;
+ case DistlistObject:
+ variant = QVariant::fromValue<Kolab::DistList>(Kolab::readDistlist(xml, false));
+ break;
+ case NoteObject:
+ variant = QVariant::fromValue<Kolab::Note>(Kolab::readNote(xml, false));
+ break;
+ case FreebusyObject:
+ variant = QVariant::fromValue<Kolab::Freebusy>(Kolab::readFreebusy(xml, false));
+ break;
+ case DictionaryConfigurationObject:
+ case RelationConfigurationObject:
+ variant = QVariant::fromValue<Kolab::Configuration>(Kolab::readConfiguration(xml, false));
+ break;
+ default:
+ Critical() << "no kolab object found ";
+ printMessageDebugInfo(msg);
+ break;
+ }
+
+ ErrorHandler::handleLibkolabxmlErrors();
+ if (ErrorHandler::errorOccured()) {
+ printMessageDebugInfo(msg);
+ return QVariant();
+ }
+ mObjectType = objectType;
+ return variant;
+}
+
+
+
+QVariant MIMEObject::Private::parseMimeMessage(const KMime::Message::Ptr &msg)
+{
+ ErrorHandler::clearErrors();
+ mObjectType = InvalidObject;
+ if (msg->contents().isEmpty()) {
+ Critical() << "message has no contents (we likely failed to parse it correctly)";
+ printMessageDebugInfo(msg);
+ return QVariant();
+ }
+ Kolab::ObjectType objectType = InvalidObject;
+ if (mOverrideObjectType == InvalidObject) {
+ if (KMime::Headers::Base *xKolabHeader = msg->getHeaderByType(X_KOLAB_TYPE_HEADER)) {
+ objectType = getObjectType(xKolabHeader->asUnicodeString().trimmed().toStdString());
+ } else {
+ Warning() << "could not find the X-Kolab-Type Header, trying autodetection" ;
+ //This works only for v2 messages atm.
+ objectType = detectType(msg);
+ }
+ } else {
+ objectType = mOverrideObjectType;
+ }
+ if (objectType == InvalidObject) {
+ Critical() << "unable to detect object type";
+ printMessageDebugInfo(msg);
+ return QVariant();
+ }
+
+ if (!mDoOverrideVersion) {
+ KMime::Headers::Base *xKolabVersion = msg->getHeaderByType(X_KOLAB_MIME_VERSION_HEADER);
+ if (!xKolabVersion) {
+ //For backwards compatibility to development versions, can be removed in future versions
+ xKolabVersion = msg->getHeaderByType(X_KOLAB_MIME_VERSION_HEADER_COMPAT);
+ }
+ if (!xKolabVersion || xKolabVersion->asUnicodeString() == KOLAB_VERSION_V2) {
+ mVersion = KolabV2;
+ } else {
+ if (xKolabVersion->asUnicodeString() != KOLAB_VERSION_V3) { //TODO version compatibility check?
+ Warning() << "Kolab Version Header available but not on the same version as the implementation: " << xKolabVersion->asUnicodeString();
+ }
+ mVersion = KolabV3;
+ }
+ } else {
+ mVersion = mOverrideVersion;
+ }
+
+ if (mVersion == KolabV2) {
+ return readKolabV2(msg, objectType);
+ }
+ return readKolabV3(msg, objectType);
+}
+
+QVariant MIMEObject::Private::parseMimeMessage(const std::string &s)
+{
KMime::Message::Ptr msg(new KMime::Message);
msg->setContent(QByteArray(s.c_str()));
msg->parse();
-
- KCalCore::Event::Ptr event = KolabObjectReader(msg).getEvent();
-
- return Conversion::fromKCalCore(*event);
+ return parseMimeMessage(msg);
}
-std::string MIMEObject::writeTodo(const Todo &todo, Version version, const std::string &productId){
- KCalCore::Todo::Ptr kTodo = Conversion::toKCalCore(todo);
+MIMEObject::MIMEObject()
+ : d(new MIMEObject::Private)
+{
- KMime::Message::Ptr msg = KolabObjectWriter().writeTodo(kTodo, version, QString::fromStdString(productId));
- msg->assemble();
+}
- return msg->encodedContent().data();
+void MIMEObject::setObjectType(ObjectType type)
+{
+ d->mOverrideObjectType = type;
}
+void MIMEObject::setVersion(Version version)
+{
+ d->mOverrideVersion = version;
+ d->mDoOverrideVersion = true;
+}
-Todo MIMEObject::readTodo(const std::string &s){
+std::vector<Kolab::Attachment> convertToReferences(const std::vector<Kolab::Attachment> &attachments)
+{
+ std::vector<Kolab::Attachment> attachmentsWithReferences;
+ Q_FOREACH (const Kolab::Attachment &a, attachments) {
+ Kolab::Attachment attachment;
+ attachment.setLabel(a.label());
+ attachment.setUri((QString::fromLatin1("cid:")+QString::fromLatin1(KMime::uniqueString() + '@' + "kolab.resource.akonadi")).toStdString(), a.mimetype()); //Serialize the attachment as attachment with uri, referencing the created mime-part
+ attachmentsWithReferences.push_back(attachment);
+ }
+ return attachmentsWithReferences;
+}
- KMime::Message::Ptr msg(new KMime::Message);
- msg->setContent(QByteArray(s.c_str()));
- msg->parse();
-
- KCalCore::Todo::Ptr todo = KolabObjectReader(msg).getTodo();
-
- return Conversion::fromKCalCore(*todo);
+template <class T>
+static T convertAttachmentsToReferences(const T &incidence)
+{
+ T removedAttachments = incidence;
+ removedAttachments.setAttachments(convertToReferences(incidence.attachments()));
+ return removedAttachments;
}
+static void addAttachments(KMime::Message::Ptr msg, const std::vector<Attachment> &attachments)
+{
+ foreach (const Attachment &attachment, attachments) {
+ msg->addContent(Mime::createAttachmentPart(Mime::fromCid(QByteArray(attachment.uri().c_str())).toLatin1(), QByteArray(attachment.mimetype().c_str()), QString::fromStdString(attachment.label()), QByteArray(attachment.data().c_str())));
+ }
+}
-std::string MIMEObject::writeJournal(const Journal &journal, Version version, const std::string &productId){
- KCalCore::Journal::Ptr kJournal = Conversion::toKCalCore(journal);
+ObjectType MIMEObject::parseMessage(const std::string &msg)
+{
+ d->mObject = d->parseMimeMessage(msg);
+ return d->mObjectType;
+}
- KMime::Message::Ptr msg = KolabObjectWriter().writeJournal(kJournal, version, QString::fromStdString(productId));
- msg->assemble();
+ObjectType MIMEObject::getType() const
+{
+ return d->mObjectType;
+}
- return msg->encodedContent().data();
+Version MIMEObject::getVersion() const
+{
+ return d->mVersion;
}
+Kolab::Event MIMEObject::getEvent() const
+{
+ return d->mObject.value<Kolab::Event>();
+}
-Journal MIMEObject::readJournal(const std::string &s){
+Kolab::Todo MIMEObject::getTodo() const
+{
+ return d->mObject.value<Kolab::Todo>();
+}
- KMime::Message::Ptr msg(new KMime::Message);
- msg->setContent(QByteArray(s.c_str()));
- msg->parse();
-
- KCalCore::Journal::Ptr journal = KolabObjectReader(msg).getJournal();
-
- return Conversion::fromKCalCore(*journal);
+Kolab::Journal MIMEObject::getJournal() const
+{
+ return d->mObject.value<Kolab::Journal>();
}
-std::string MIMEObject::writeNote(const Note &note, Version version, const std::string &productId){
- KMime::Message::Ptr kNote = Conversion::toNote(note);
+Kolab::Note MIMEObject::getNote() const
+{
+ return d->mObject.value<Kolab::Note>();
+}
- KMime::Message::Ptr msg = KolabObjectWriter().writeNote(kNote, version, QString::fromStdString(productId));
- msg->assemble();
+Kolab::Contact MIMEObject::getContact() const
+{
+ return d->mObject.value<Kolab::Contact>();
+}
- return msg->encodedContent().data();
+Kolab::DistList MIMEObject::getDistlist() const
+{
+ return d->mObject.value<Kolab::DistList>();
}
+Kolab::Freebusy MIMEObject::getFreebusy() const
+{
+ return d->mObject.value<Kolab::Freebusy>();
+}
-Note MIMEObject::readNote(const std::string &s){
+Kolab::Configuration MIMEObject::getConfiguration() const
+{
+ return d->mObject.value<Kolab::Configuration>();
+}
- KMime::Message::Ptr msg(new KMime::Message);
- msg->setContent(QByteArray(s.c_str()));
- msg->parse();
-
- KMime::Message::Ptr note = KolabObjectReader(msg).getNote();
-
- return Conversion::fromNote(note);
+std::string MIMEObject::writeEvent(const Event &event, Version version, const std::string &pId)
+{
+ ErrorHandler::clearErrors();
+ const std::string productId = getProductId(pId);
+
+ KMime::Message::Ptr msg;
+ Kolab::XMLObject xmlObject;
+ if (version == KolabV3) {
+ const std::string xml = xmlObject.writeEvent(convertAttachmentsToReferences(event), version, productId);
+ msg = Mime::createMessage(xCalMimeType(), eventKolabType(), xml, true, productId, event.organizer().email(), event.organizer().name(), event.uid());
+ } else if (version == KolabV2) {
+ const std::string xml = xmlObject.writeEvent(event, version, productId);
+ msg = Mime::createMessage(eventKolabType(), eventKolabType(), xml, false, productId, event.organizer().email(), event.organizer().name(), event.uid());
+ }
+ addAttachments(msg, event.attachments());
+ msg->assemble();
+ return msg->encodedContent().data();
}
-std::string MIMEObject::writeContact(const Contact &contact, Version version, const std::string &productId){
- KContacts::Addressee kContact = Conversion::toKABC(contact);
+Event MIMEObject::readEvent(const std::string &s)
+{
+ return d->parseMimeMessage(s).value<Kolab::Event>();
+}
- KMime::Message::Ptr msg = KolabObjectWriter().writeContact(kContact, version, QString::fromStdString(productId));
+std::string MIMEObject::writeTodo(const Todo &todo, Version version, const std::string &pId)
+{
+ ErrorHandler::clearErrors();
+ const std::string productId = getProductId(pId);
+
+ KMime::Message::Ptr msg;
+ Kolab::XMLObject xmlObject;
+ if (version == KolabV3) {
+ const std::string xml = xmlObject.writeTodo(convertAttachmentsToReferences(todo), version, productId);
+ msg = Mime::createMessage(xCalMimeType(), todoKolabType(), xml, true, productId, todo.organizer().email(), todo.organizer().name(), todo.uid());
+ } else if (version == KolabV2) {
+ const std::string xml = xmlObject.writeTodo(todo, version, productId);
+ msg = Mime::createMessage(todoKolabType(), todoKolabType(), xml, false, productId, todo.organizer().email(), todo.organizer().name(), todo.uid());
+ }
+ addAttachments(msg, todo.attachments());
msg->assemble();
+ return msg->encodedContent().data();
+}
+
+Todo MIMEObject::readTodo(const std::string &s)
+{
+ return d->parseMimeMessage(s).value<Kolab::Todo>();
+}
+std::string MIMEObject::writeJournal(const Journal &journal, Version version, const std::string &pId)
+{
+ ErrorHandler::clearErrors();
+ const std::string productId = getProductId(pId);
+
+ KMime::Message::Ptr msg;
+ Kolab::XMLObject xmlObject;
+ if (version == KolabV3) {
+ const std::string xml = xmlObject.writeJournal(convertAttachmentsToReferences(journal), version, productId);
+ msg = Mime::createMessage(xCalMimeType(), journalKolabType(), xml, true, productId, std::string(), std::string(), journal.uid());
+ } else if (version == KolabV2) {
+ const std::string xml = xmlObject.writeJournal(journal, version, productId);
+ msg = Mime::createMessage(journalKolabType(), journalKolabType(), xml, false, productId, std::string(), std::string(), journal.uid());
+ }
+ addAttachments(msg, journal.attachments());
+ msg->assemble();
return msg->encodedContent().data();
}
+Journal MIMEObject::readJournal(const std::string &s){
-Contact MIMEObject::readContact(const std::string &s){
+ return d->parseMimeMessage(s).value<Kolab::Journal>();
+}
- KMime::Message::Ptr msg(new KMime::Message);
- msg->setContent(QByteArray(s.c_str()));
- msg->parse();
-
- KContacts::Addressee contact = KolabObjectReader(msg).getContact();
-
- return Conversion::fromKABC(contact);
+std::string MIMEObject::writeNote(const Note &note, Version version, const std::string &pId)
+{
+ ErrorHandler::clearErrors();
+ const std::string productId = getProductId(pId);
+
+ KMime::Message::Ptr msg;
+ Kolab::XMLObject xmlObject;
+ if (version == KolabV3) {
+ const std::string xml = xmlObject.writeNote(convertAttachmentsToReferences(note), version, productId);
+ msg = Mime::createMessage(xCalMimeType(), noteKolabType(), xml, true, productId, std::string(), std::string(), note.uid());
+ } else if (version == KolabV2) {
+ const std::string xml = xmlObject.writeNote(note, version, productId);
+ msg = Mime::createMessage(noteKolabType(), noteKolabType(), xml, false, productId, std::string(), std::string(), note.uid());
+ }
+ addAttachments(msg, note.attachments());
+ msg->assemble();
+ return msg->encodedContent().data();
+}
+
+Note MIMEObject::readNote(const std::string &s){
+
+ return d->parseMimeMessage(s).value<Kolab::Note>();
+}
+
+std::string MIMEObject::writeContact(const Contact &contact, Version version, const std::string &pId)
+{
+ ErrorHandler::clearErrors();
+ const std::string productId = getProductId(pId);
+
+ KMime::Message::Ptr msg;
+ Kolab::XMLObject xmlObject;
+ const std::string xml = xmlObject.writeContact(contact, version, productId);
+
+ Email preferredEmail = !contact.emailAddresses().empty() ? contact.emailAddresses().at(contact.emailAddressPreferredIndex()) : Email();
+ QPair<std::string, std::string> pair = Conversion::fromMailto(preferredEmail.address());
+ std::string name = pair.second;
+ std::string email = pair.first;
+
+ if (version == KolabV3) {
+ msg = Mime::createMessage(xCardMimeType(), contactKolabType(), xml, true, productId, email, name, contact.uid());
+ } else if (version == KolabV2) {
+ msg = Mime::createMessage(contactKolabType(), contactKolabType(), xml, false, productId, email, name, contact.uid());
+ }
+ msg->assemble();
+ return msg->encodedContent().data();
}
-std::string MIMEObject::writeDistlist(const DistList &distlist, Version version, const std::string &productId){
- KContacts::ContactGroup kDistlist = Conversion::toKABC(distlist);
+Contact MIMEObject::readContact(const std::string &s){
+
+ return d->parseMimeMessage(s).value<Kolab::Contact>();
+}
- KMime::Message::Ptr msg = KolabObjectWriter().writeDistlist(kDistlist, version, QString::fromStdString(productId));
+std::string MIMEObject::writeDistlist(const DistList &distlist, Version version, const std::string &pId)
+{
+ ErrorHandler::clearErrors();
+ const std::string productId = getProductId(pId);
+
+ KMime::Message::Ptr msg;
+ Kolab::XMLObject xmlObject;
+ const std::string xml = xmlObject.writeDistlist(distlist, version, productId);
+ if (version == KolabV3) {
+ msg = Mime::createMessage(xCardMimeType(), distlistKolabType(), xml, true, productId, std::string(), std::string(), distlist.uid());
+ } else if (version == KolabV2) {
+ msg = Mime::createMessage(distlistKolabType(), distlistKolabType(), xml, false, productId, std::string(), std::string(), distlist.uid());
+ }
msg->assemble();
+ return msg->encodedContent().data();
+}
+DistList MIMEObject::readDistlist(const std::string &s)
+{
+ return d->parseMimeMessage(s).value<Kolab::DistList>();
+}
+
+std::string MIMEObject::writeConfiguration(const Configuration &configuration, Version version, const std::string& pId)
+{
+ ErrorHandler::clearErrors();
+ const std::string productId = getProductId(pId);
+
+ KMime::Message::Ptr msg;
+ Kolab::XMLObject xmlObject;
+ const std::string xml = xmlObject.writeConfiguration(configuration, version, productId);
+ std::string kolabType;
+ switch (configuration.type()) {
+ case Kolab::Configuration::TypeDictionary:
+ kolabType = dictKolabType();
+ break;
+ case Kolab::Configuration::TypeRelation:
+ kolabType = relationKolabType();
+ break;
+ case Kolab::Configuration::TypeSnippet:
+ kolabType = configurationKolabType();
+ break;
+ case Kolab::Configuration::TypeFileDriver:
+ kolabType = configurationKolabType();
+ break;
+ case Kolab::Configuration::TypeCategoryColor:
+ kolabType = configurationKolabType();
+ break;
+ default:
+ break;
+ }
+ if (version == KolabV3) {
+ msg = Mime::createMessage(kolabMimeType(), kolabType, xml, true, productId, std::string(), std::string(), configuration.uid());
+ } else if (version == KolabV2) {
+ Critical() << "Not available in KolabV2";
+ }
+ msg->assemble();
return msg->encodedContent().data();
}
+Configuration MIMEObject::readConfiguration(const std::string &s)
+{
+ return d->parseMimeMessage(s).value<Kolab::Configuration>();
+}
-DistList MIMEObject::readDistlist(const std::string &s){
+std::string MIMEObject::writeFreebusy(const Freebusy &freebusy, Version version, const std::string& pId)
+{
+ ErrorHandler::clearErrors();
+ const std::string productId = getProductId(pId);
+
+ KMime::Message::Ptr msg;
+ Kolab::XMLObject xmlObject;
+ const std::string xml = xmlObject.writeFreebusy(freebusy, version, productId);
+ if (version == KolabV3) {
+ msg = Mime::createMessage(xCalMimeType(), freebusyKolabType(), xml, true, productId, std::string(), std::string(), freebusy.uid());
+ } else if (version == KolabV2) {
+ Critical() << "Not available in KolabV2";
+ }
+ msg->assemble();
+ return msg->encodedContent().data();
+}
- KMime::Message::Ptr msg(new KMime::Message);
- msg->setContent(QByteArray(s.c_str()));
- msg->parse();
-
- KContacts::ContactGroup distlist = KolabObjectReader(msg).getDistlist();
-
- return Conversion::fromKABC(distlist);
+Freebusy MIMEObject::readFreebusy(const std::string &s)
+{
+ return d->parseMimeMessage(s).value<Kolab::Freebusy>();
}
+
}
diff --git a/kolabformat/mimeobject.h b/kolabformat/mimeobject.h
index 89ff788..b6c6eb0 100644
--- a/kolabformat/mimeobject.h
+++ b/kolabformat/mimeobject.h
@@ -37,6 +37,37 @@ class KOLAB_EXPORT MIMEObject
public:
MIMEObject();
+ ObjectType parseMessage(const std::string &msg);
+
+ /**
+ * Set to override the autodetected object type, before parsing the message.
+ */
+ void setObjectType(ObjectType);
+
+ /**
+ * Set to override the autodetected version, before parsing the message.
+ */
+ void setVersion(Version);
+
+ /**
+ * Returns the Object type of the parsed kolab object.
+ */
+ ObjectType getType() const;
+
+ /**
+ * Returns the kolab-format version of the parsed kolab object.
+ */
+ Version getVersion() const;
+
+ Kolab::Event getEvent() const;
+ Kolab::Todo getTodo() const;
+ Kolab::Journal getJournal() const;
+ Kolab::Note getNote() const;
+ Kolab::Contact getContact() const;
+ Kolab::DistList getDistlist() const;
+ Kolab::Freebusy getFreebusy() const;
+ Kolab::Configuration getConfiguration() const;
+
std::string writeEvent(const Kolab::Event &event, Version version, const std::string &productId = std::string());
Kolab::Event readEvent(const std::string &s);
@@ -55,6 +86,20 @@ public:
std::string writeDistlist(const Kolab::DistList &distlist, Version version, const std::string &productId = std::string());
Kolab::DistList readDistlist(const std::string &s);
+ std::string writeFreebusy(const Kolab::Freebusy &freebusy, Version version, const std::string &productId = std::string());
+ Kolab::Freebusy readFreebusy(const std::string &s);
+
+ std::string writeConfiguration(const Kolab::Configuration &freebusy, Version version, const std::string &productId = std::string());
+ Kolab::Configuration readConfiguration(const std::string &s);
+
+private:
+ //@cond PRIVATE
+ MIMEObject(const MIMEObject &other);
+ MIMEObject &operator=(const MIMEObject &rhs);
+ class Private;
+ Private *const d;
+ //@endcond
};
+
}
#endif
diff --git a/kolabformat/v2helpers.cpp b/kolabformat/v2helpers.cpp
index 1813ba2..f7e7d0c 100644
--- a/kolabformat/v2helpers.cpp
+++ b/kolabformat/v2helpers.cpp
@@ -147,7 +147,7 @@ static QByteArray createPicture(const QImage &img, const QString &/*format*/, QS
KMime::Message::Ptr contactToKolabFormat(const KolabV2::Contact& contact, const QString &productId)
{
- KMime::Message::Ptr message = Mime::createMessage( KOLAB_TYPE_CONTACT, false, productId );
+ KMime::Message::Ptr message = Mime::createMessage( QByteArray(KOLAB_TYPE_CONTACT), false, productId.toLatin1() );
if (!message) {
Critical() << "empty message";
return KMime::Message::Ptr();
@@ -161,14 +161,14 @@ KMime::Message::Ptr contactToKolabFormat(const KolabV2::Contact& contact, const
if ( !contact.picture().isNull() ) {
QString type;
const QByteArray &pic = createPicture(contact.picture(), contact.pictureFormat(), type);
- content = Mime::createAttachmentPart(QByteArray(), type, /*"kolab-picture.png"*/contact.pictureAttachmentName(), pic );
+ content = Mime::createAttachmentPart(QByteArray(), type.toLatin1(), /*"kolab-picture.png"*/contact.pictureAttachmentName(), pic );
message->addContent(content);
}
if ( !contact.logo().isNull() ) {
QString type;
const QByteArray &pic = createPicture(contact.logo(), contact.logoFormat(), type);
- content = Mime::createAttachmentPart(QByteArray(), type, /*"kolab-logo.png"*/contact.logoAttachmentName(), pic );
+ content = Mime::createAttachmentPart(QByteArray(), type.toLatin1(), /*"kolab-logo.png"*/contact.logoAttachmentName(), pic );
message->addContent(content);
}
@@ -192,7 +192,7 @@ KContacts::ContactGroup contactGroupFromKolab(const QByteArray &xmlData)
KMime::Message::Ptr distListToKolabFormat(const KolabV2::DistributionList& distList, const QString &productId)
{
- KMime::Message::Ptr message = Mime::createMessage( KOLAB_TYPE_DISTLIST_V2, false, productId );
+ KMime::Message::Ptr message = Mime::createMessage( KOLAB_TYPE_DISTLIST_V2, false, productId.toLatin1() );
if (!message) {
Critical() << "empty message";
return KMime::Message::Ptr();
diff --git a/mime/mimeutils.cpp b/mime/mimeutils.cpp
index 27e0e9c..7b22c29 100644
--- a/mime/mimeutils.cpp
+++ b/mime/mimeutils.cpp
@@ -22,6 +22,7 @@
#include <kcontacts/addressee.h>
#include "kolabformat/kolabdefinitions.h"
#include "kolabformat/errorhandler.h"
+#include <kolabformat.h>
#include "libkolab-version.h"
namespace Kolab {
@@ -92,9 +93,32 @@ QString fromCid(const QString &cid)
return cid.right(cid.size()-4);
}
+KMime::Message::Ptr createMessage(const QByteArray &mimetype, const QByteArray &xKolabType, const QByteArray &xml, bool v3, const QByteArray &productId,
+ const QByteArray &fromEmail, const QString &fromName, const QString &subject)
+{
+ KMime::Message::Ptr message = createMessage(xKolabType, v3, productId);
+ if (!fromEmail.isEmpty()) {
+ KMime::Types::Mailbox mb;
+ mb.setName(fromName);
+ mb.setAddress(fromEmail);
+ message->from()->addAddress(mb);
+ }
+ qWarning() << "Create message subject: " << subject;
+ message->subject()->fromUnicodeString(subject, "utf-8");
+ message->addContent(createMainPart(mimetype, xml));
+ return message;
+}
+
+KMime::Message::Ptr createMessage(const std::string &mimetype, const std::string &xKolabType, const std::string &xml, bool v3, const std::string &productId,
+ const std::string &fromEmail, const std::string &fromName, const std::string &subject)
+{
+ return createMessage(QByteArray(mimetype.c_str()), QByteArray(xKolabType.c_str()), QByteArray(xml.c_str()), v3, QByteArray(productId.data()), QByteArray(fromEmail.c_str()), QString::fromStdString(fromName), QString::fromStdString(subject));
+}
+
+//TODO remove
KMime::Message::Ptr createMessage(const KCalCore::Incidence::Ptr &incidencePtr, const QString &mimetype, const QString &xKolabType, const QByteArray &xml, bool v3, const QString &productId)
{
- KMime::Message::Ptr message = createMessage( xKolabType, v3, productId );
+ KMime::Message::Ptr message = createMessage( xKolabType.toLatin1(), v3, productId.toLatin1() );
if (!incidencePtr) {
Error() << "invalid incidence passed in";
message->assemble();
@@ -105,7 +129,7 @@ KMime::Message::Ptr createMessage(const KCalCore::Incidence::Ptr &incidencePtr,
}
message->subject()->fromUnicodeString( incidencePtr->uid(), "utf-8" );
- KMime::Content *content = createMainPart( mimetype, xml );
+ KMime::Content *content = createMainPart( mimetype.toLatin1(), xml );
message->addContent( content );
Q_FOREACH (KCalCore::Attachment::Ptr attachment, incidencePtr->attachments()) {
@@ -114,7 +138,7 @@ KMime::Message::Ptr createMessage(const KCalCore::Incidence::Ptr &incidencePtr,
//onyl by url, skip
continue;
}
- message->addContent( createAttachmentPart(fromCid(attachment->uri()).toLatin1(), attachment->mimeType(), attachment->label(), attachment->decodedData() ) );
+ message->addContent( createAttachmentPart(fromCid(attachment->uri()).toLatin1(), attachment->mimeType().toLatin1(), attachment->label(), attachment->decodedData() ) );
}
message->assemble();
@@ -123,11 +147,11 @@ KMime::Message::Ptr createMessage(const KCalCore::Incidence::Ptr &incidencePtr,
KMime::Message::Ptr createMessage(const KContacts::Addressee &contact, const QString &mimetype, const QString &xKolabType, const QByteArray &xml, bool v3, const QString &prodid)
{
- KMime::Message::Ptr message = Mime::createMessage( xKolabType, v3, prodid );
+ KMime::Message::Ptr message = Mime::createMessage( xKolabType.toLatin1(), v3, prodid.toLatin1() );
message->subject()->fromUnicodeString( contact.uid(), "utf-8" );
message->from()->fromUnicodeString( contact.fullEmail(), "utf-8" );
- KMime::Content* content = Mime::createMainPart( mimetype, xml );
+ KMime::Content* content = Mime::createMainPart( mimetype.toLatin1(), xml );
message->addContent( content );
// TODO add pictures as separate mimeparts
@@ -164,12 +188,12 @@ KMime::Message::Ptr createMessage(const KContacts::Addressee &contact, const QSt
KMime::Message::Ptr createMessage(const QString &subject, const QString &mimetype, const QString &xKolabType, const QByteArray &xml, bool v3, const QString &prodid)
{
- KMime::Message::Ptr message = createMessage( xKolabType, v3, prodid );
+ KMime::Message::Ptr message = createMessage( xKolabType.toLatin1(), v3, prodid.toLatin1() );
if (!subject.isEmpty()) {
message->subject()->fromUnicodeString( subject, "utf-8" );
}
- KMime::Content *content = createMainPart( mimetype, xml );
+ KMime::Content *content = createMainPart( mimetype.toLatin1(), xml );
message->addContent( content );
message->assemble();
@@ -197,44 +221,42 @@ KMime::Content* createExplanationPart(bool v3)
}
-KMime::Message::Ptr createMessage(const QString& xKolabType, bool v3, const QString &prodid)
+KMime::Message::Ptr createMessage(const QByteArray& xKolabType, bool v3, const QByteArray &prodid)
{
- KMime::Message::Ptr message( new KMime::Message );
- message->date()->setDateTime( KDateTime::currentUtcDateTime().dateTime() );
- KMime::Headers::Generic *h = new KMime::Headers::Generic( X_KOLAB_TYPE_HEADER, message.get(), xKolabType, "utf-8" );
- message->appendHeader( h );
+ KMime::Message::Ptr message(new KMime::Message);
+ message->date()->setDateTime(KDateTime::currentUtcDateTime().dateTime());
+ message->appendHeader(new KMime::Headers::Generic(X_KOLAB_TYPE_HEADER, message.get(), xKolabType, "utf-8"));
if (v3) {
- KMime::Headers::Generic *vh = new KMime::Headers::Generic( X_KOLAB_MIME_VERSION_HEADER, message.get(), KOLAB_VERSION_V3, "utf-8" );
- message->appendHeader( vh );
+ message->appendHeader(new KMime::Headers::Generic(X_KOLAB_MIME_VERSION_HEADER, message.get(), KOLAB_VERSION_V3, "utf-8"));
}
- message->userAgent()->from7BitString( prodid.toLatin1() );
- message->contentType()->setMimeType( "multipart/mixed" );
- message->contentType()->setBoundary( KMime::multiPartBoundary() );
-
- message->addContent( createExplanationPart(v3) );
+ message->userAgent()->from7BitString(prodid);
+ message->contentType()->setMimeType("multipart/mixed");
+ message->contentType()->setBoundary(KMime::multiPartBoundary());
+ message->addContent(createExplanationPart(v3));
return message;
}
-KMime::Content* createMainPart(const QString& mimeType, const QByteArray& decodedContent)
+KMime::Content* createMainPart(const QByteArray& mimeType, const QByteArray& decodedContent)
{
KMime::Content* content = new KMime::Content();
- content->contentType()->setMimeType( mimeType.toLatin1() );
- content->contentType()->setName( KOLAB_OBJECT_FILENAME, "us-ascii" );
+ content->contentType()->setMimeType(mimeType);
+ content->contentType()->setName(KOLAB_OBJECT_FILENAME, "us-ascii");
content->contentTransferEncoding()->setEncoding( KMime::Headers::CEquPr );
content->contentDisposition()->setDisposition( KMime::Headers::CDattachment );
content->contentDisposition()->setFilename( KOLAB_OBJECT_FILENAME );
- content->setBody( decodedContent );
+ content->setBody(decodedContent);
return content;
}
-KMime::Content* createAttachmentPart(const QByteArray& cid, const QString& mimeType, const QString& fileName, const QByteArray& decodedContent)
+KMime::Content* createAttachmentPart(const QByteArray& cid, const QByteArray& mimeType, const QString& fileName, const QByteArray& decodedContent)
{
+ qDebug() << "content: " << decodedContent;
KMime::Content* content = new KMime::Content();
if (!cid.isEmpty()) {
content->contentID()->setIdentifier( cid );
}
- content->contentType()->setMimeType( mimeType.toLatin1() );
+ content->contentType()->setMimeType( mimeType );
content->contentType()->setName( fileName, "utf-8" );
content->contentTransferEncoding()->setEncoding( KMime::Headers::CEbase64 );
content->contentDisposition()->setDisposition( KMime::Headers::CDattachment );
@@ -296,6 +318,39 @@ void getAttachmentsById(KCalCore::Incidence::Ptr incidence, const KMime::Message
}
}
+Kolab::Attachment getAttachment(const std::string &id, const KMime::Message::Ptr &mimeData)
+{
+ if (!QString::fromStdString(id).contains("cid:")) {
+ Error() << "not a cid reference";
+ return Kolab::Attachment();
+ }
+ QByteArray type;
+ QString name;
+ KMime::Content *content = findContentById(mimeData, fromCid(QString::fromStdString(id)).toLatin1(), type, name);
+ if (!content) { // guard against malformed events with non-existent attachments
+ Error() << "could not find attachment: "<< name << type;
+ return Kolab::Attachment();
+ }
+ // Debug() << id << content->decodedContent().toBase64().toStdString();
+ Kolab::Attachment attachment;
+ attachment.setData(content->decodedContent().toStdString(), type.toStdString());
+ attachment.setLabel(name.toStdString());
+ return attachment;
+}
+
+Kolab::Attachment getAttachmentByName(const QString &name, const KMime::Message::Ptr &mimeData)
+{
+ QByteArray type;
+ KMime::Content *content = findContentByName(mimeData, name, type);
+ if (!content) { // guard against malformed events with non-existent attachments
+ Warning() << "could not find attachment: "<< name.toUtf8() << type;
+ return Kolab::Attachment();
+ }
+ Kolab::Attachment attachment;
+ attachment.setData(content->decodedContent().toStdString(), type.toStdString());
+ attachment.setLabel(name.toStdString());
+ return attachment;
+}
}; //Namespace
diff --git a/mime/mimeutils.h b/mime/mimeutils.h
index 85436ec..b4916df 100644
--- a/mime/mimeutils.h
+++ b/mime/mimeutils.h
@@ -27,6 +27,7 @@
class QDomDocument;
namespace Kolab {
+ class Attachment;
namespace Mime {
KMime::Content* findContentByName(const KMime::Message::Ptr &data, const QString &name, QByteArray &type);
@@ -42,6 +43,13 @@ QList<QByteArray> getContentMimeTypeList(const KMime::Message::Ptr &data);
void getAttachments(KCalCore::Incidence::Ptr incidence, const QStringList &attachments, const KMime::Message::Ptr &mimeData);
//v3
void getAttachmentsById(KCalCore::Incidence::Ptr incidence, const KMime::Message::Ptr &mimeData);
+Kolab::Attachment getAttachment(const std::string &id, const KMime::Message::Ptr &mimeData);
+Kolab::Attachment getAttachmentByName(const QString &name, const KMime::Message::Ptr &mimeData);
+
+KMime::Message::Ptr createMessage(const QByteArray &mimetype, const QByteArray &xKolabType, const QByteArray &xml, bool v3, const QByteArray &productId,
+ const QByteArray &fromEmail, const QString &fromName, const QString &subject);
+KMime::Message::Ptr createMessage(const std::string &mimetype, const std::string &xKolabType, const std::string &xml, bool v3, const std::string &productId,
+ const std::string &fromEmail, const std::string &fromName, const std::string &subject);
///Generic serializing functions
KMime::Message::Ptr createMessage(const KCalCore::Incidence::Ptr &incidencePtr, const QString &mimetype, const QString &xKolabType, const QByteArray &xml, bool v3, const QString &prodid);
@@ -49,9 +57,10 @@ KMime::Message::Ptr createMessage(const KContacts::Addressee &contact, const QSt
KMime::Message::Ptr createMessage(const QString &subject, const QString &mimetype, const QString &xKolabType, const QByteArray &xml, bool v3, const QString &prodid);
KMime::Content* createExplanationPart();
-KMime::Message::Ptr createMessage(const QString& mimeType, bool v3, const QString &prodid);
-KMime::Content* createMainPart(const QString& mimeType, const QByteArray& decodedContent);
-KMime::Content* createAttachmentPart(const QByteArray &cid, const QString& mimeType, const QString& fileName, const QByteArray& decodedContent);
+KMime::Message::Ptr createMessage(const QByteArray& mimeType, bool v3, const QByteArray &prodid);
+KMime::Content* createMainPart(const QByteArray& mimeType, const QByteArray& decodedContent);
+KMime::Content* createAttachmentPart(const QByteArray& cid, const QByteArray& mimeType, const QString& fileName, const QByteArray& decodedContent);
+QString fromCid(const QString &cid);
};
}; //Namespace