kolabformat/kolabdefinitions.h kolabformat/kolabobject.cpp kolabformat/kolabobject.h tests/kolabobjecttest.cpp tests/kolabobjecttest.h
Christian Mollekopf
mollekopf at kolabsys.com
Fri Aug 29 11:00:16 CEST 2014
kolabformat/kolabdefinitions.h | 4 +
kolabformat/kolabobject.cpp | 112 +++++++++++++++++++++++++++++++++++++++++
kolabformat/kolabobject.h | 15 +++++
tests/kolabobjecttest.cpp | 28 ++++++++++
tests/kolabobjecttest.h | 1
5 files changed, 159 insertions(+), 1 deletion(-)
New commits:
commit 1173670e0716cdcb2d4fde6f80fc00f1a5d4ed38
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Wed Aug 27 10:26:26 2014 +0200
Added tag support.
Thanks to Kevin Krammer for the initial version of the patch.
diff --git a/kolabformat/kolabdefinitions.h b/kolabformat/kolabdefinitions.h
index 379648c..e1d8e93 100644
--- a/kolabformat/kolabdefinitions.h
+++ b/kolabformat/kolabdefinitions.h
@@ -63,6 +63,7 @@ namespace Kolab {
#define KOLAB_TYPE_DICT "application/x-vnd.kolab.configuration.dictionary"
#define KOLAB_TYPE_FREEBUSY "application/x-vnd.kolab.freebusy"
#define KOLAB_TYPE_FILE "application/x-vnd.kolab.file"
+#define KOLAB_TYPE_RELATION "application/x-vnd.kolab.configuration.relation"
enum Version {
KolabV2,
@@ -78,7 +79,8 @@ enum ObjectType {
DistlistObject,
NoteObject,
DictionaryConfigurationObject,
- FreebusyObject
+ FreebusyObject,
+ RelationConfigurationObject
};
}
diff --git a/kolabformat/kolabobject.cpp b/kolabformat/kolabobject.cpp
index b894818..90b4e78 100644
--- a/kolabformat/kolabobject.cpp
+++ b/kolabformat/kolabobject.cpp
@@ -51,6 +51,7 @@ static inline QString noteKolabType() { return QString::fromLatin1(KOLAB_TYPE_NO
static inline QString configurationKolabType() { return QString::fromLatin1(KOLAB_TYPE_CONFIGURATION); }
static inline QString dictKolabType() { return QString::fromLatin1(KOLAB_TYPE_DICT); }
static inline QString freebusyKolabType() { return QString::fromLatin1(KOLAB_TYPE_FREEBUSY); }
+static inline QString relationKolabType() { return QString::fromLatin1(KOLAB_TYPE_RELATION); }
static inline QString xCalMimeType() { return QString::fromLatin1(MIME_TYPE_XCAL); };
static inline QString xCardMimeType() { return QString::fromLatin1(MIME_TYPE_XCARD); };
@@ -61,6 +62,62 @@ KCalCore::Event::Ptr readV2EventXML(const QByteArray& xmlData, QStringList& atta
return fromXML<KCalCore::Event::Ptr, KolabV2::Event>(xmlData, attachments);
}
+RelationMember parseMemberUrl(const QString &string)
+{
+ RelationMember member;
+ QUrl url(QUrl::fromPercentEncoding(string.toLatin1()));
+ QList<QByteArray> path = url.encodedPath().split('/');
+ // qDebug() << path;
+ int start = path.indexOf("user");
+ if (start < 0) {
+ kWarning() << "Couldn't find \"user\" in path: " << path;
+ return RelationMember();
+ }
+ path = path.mid(start + 1);
+ if (path.size() < 2) {
+ kWarning() << "Incomplete path: " << path;
+ return RelationMember();
+ }
+ // user-name
+ path.removeFirst();
+ member.uid = path.takeLast().toLong();
+ member.mailbox = path;
+ member.messageId = url.queryItemValue("message-id");
+ member.subject = url.queryItemValue("subject");
+ member.date = url.queryItemValue("date");
+ // qDebug() << member.uid << member.mailbox;
+ return member;
+}
+
+static QByteArray join(const QList<QByteArray> &list, const QByteArray &c)
+{
+ QByteArray result;
+ Q_FOREACH (const QByteArray &a, list) {
+ result += a + c;
+ }
+ result.chop(c.size());
+ return result;
+}
+
+KOLAB_EXPORT QString generateMemberUrl(const RelationMember &member)
+{
+ QUrl url;
+ url.setScheme("imap");
+ QList<QByteArray> path;
+ path << "user";
+ path << "localuser at localhost";
+ path << member.mailbox;
+ path << QByteArray::number(member.uid);
+ url.setPath("/" + join(path, "/"));
+
+ QList<QPair<QString, QString> > queryItems;
+ queryItems.append(qMakePair(QString::fromLatin1("message-id"), member.messageId));
+ queryItems.append(qMakePair(QString::fromLatin1("subject"), member.subject));
+ queryItems.append(qMakePair(QString::fromLatin1("date"), member.date));
+ url.setQueryItems(queryItems);
+
+ return QString::fromLatin1(url.toEncoded());
+}
//@cond PRIVATE
class KolabObjectReader::Private
@@ -87,6 +144,8 @@ public:
ObjectType mObjectType;
Version mVersion;
Kolab::Freebusy mFreebusy;
+ Akonadi::Tag mTag;
+ QStringList mTagMembers;
ObjectType mOverrideObjectType;
Version mOverrideVersion;
bool mDoOverrideVersion;
@@ -138,6 +197,8 @@ Kolab::ObjectType getObjectType(const QString &type)
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;
@@ -162,6 +223,8 @@ QByteArray getTypeString(Kolab::ObjectType type)
return KOLAB_TYPE_NOTE;
case DictionaryConfigurationObject:
return KOLAB_TYPE_CONFIGURATION;
+ case RelationConfigurationObject:
+ return KOLAB_TYPE_RELATION;
default:
Critical() << "unknown type "<< type;
}
@@ -181,6 +244,7 @@ QByteArray getMimeType(Kolab::ObjectType type)
return MIME_TYPE_XCARD;
case NoteObject:
case DictionaryConfigurationObject:
+ case RelationConfigurationObject:
return MIME_TYPE_KOLAB;
default:
Critical() << "unknown type "<< type;
@@ -326,6 +390,22 @@ ObjectType KolabObjectReader::Private::readKolabV3(const KMime::Message::Ptr &ms
mFreebusy = fb;
}
break;
+ case RelationConfigurationObject: {
+ const Kolab::Configuration &configuration = Kolab::readConfiguration(xml, false);
+ const Kolab::Relation &relation = configuration.relation();
+
+ mTag = Akonadi::Tag();
+ mTag.setName(Conversion::fromStdString(relation.name()));
+ mTag.setGid(Conversion::fromStdString(configuration.uid()).toLatin1());
+ mTag.setType(Akonadi::Tag::PLAIN);
+
+ mTagMembers.reserve(relation.members().size());
+ foreach (const std::string &member, relation.members()) {
+ mTagMembers << Conversion::fromStdString(member);
+ }
+
+ }
+ break;
default:
Critical() << "no kolab object found ";
printMessageDebugInfo(msg);
@@ -452,6 +532,16 @@ Freebusy KolabObjectReader::getFreebusy() const
return d->mFreebusy;
}
+Akonadi::Tag KolabObjectReader::getTag() const
+{
+ return d->mTag;
+}
+
+QStringList KolabObjectReader::getTagMembers() const
+{
+ return d->mTagMembers;
+}
+
//Normalize incidences before serializing them
KCalCore::Incidence::Ptr normalizeIncidence(KCalCore::Incidence::Ptr original)
@@ -630,6 +720,28 @@ KMime::Message::Ptr KolabObjectWriter::writeFreebusy(const Freebusy &freebusy, V
return Mime::createMessage(Conversion::fromStdString(freebusy.uid()), xCalMimeType(), freebusyKolabType(), Conversion::fromStdString(v3String).toUtf8(), true, getProductId(productId));
}
+KMime::Message::Ptr KolabObjectWriter::writeTag(const Akonadi::Tag &tag, const QStringList &members, Version v, const QString &productId)
+{
+ ErrorHandler::clearErrors();
+ if (v != KolabV3) {
+ Critical() << "only v3 implementation available";
+ }
+
+ Kolab::Relation relation(Conversion::toStdString(tag.name()), "tag");
+ std::vector<std::string> m;
+ m.reserve(members.count());
+ foreach (const QString &member, members) {
+ m.push_back(Conversion::toStdString(member));
+ }
+ relation.setMembers(m);
+
+ Kolab::Configuration configuration(relation); //TODO preserve creation/lastModified date
+ configuration.setUid(tag.gid().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));
+}
+
diff --git a/kolabformat/kolabobject.h b/kolabformat/kolabobject.h
index 1b39ad6..71a0e4b 100644
--- a/kolabformat/kolabobject.h
+++ b/kolabformat/kolabobject.h
@@ -20,6 +20,7 @@
#include <kolab_export.h>
+#include <akonadi/tag.h>
#include <kabc/addressee.h>
#include <kabc/contactgroup.h>
#include <kcalcore/incidence.h>
@@ -37,6 +38,17 @@ class Freebusy;
KOLAB_EXPORT KCalCore::Event::Ptr readV2EventXML(const QByteArray &xmlData, QStringList &attachments);
+struct KOLAB_EXPORT RelationMember {
+ QString messageId;
+ QString subject;
+ QString date;
+ QList<QByteArray> mailbox;
+ QString user;
+ qint64 uid;
+};
+KOLAB_EXPORT RelationMember parseMemberUrl(const QString &url);
+KOLAB_EXPORT QString generateMemberUrl(const RelationMember &url);
+
/**
* Class to read Kolab Mime files
*
@@ -87,6 +99,8 @@ public:
KMime::Message::Ptr getNote() const;
QStringList getDictionary(QString &lang) const;
Freebusy getFreebusy() const;
+ Akonadi::Tag getTag() const;
+ QStringList getTagMembers() const;
private:
//@cond PRIVATE
@@ -111,6 +125,7 @@ public:
static KMime::Message::Ptr writeNote(const KMime::Message::Ptr &, Version v = KolabV3, const QString &productId = QString());
static KMime::Message::Ptr writeDictionary(const QStringList &, const QString &lang, Version v = KolabV3, const QString &productId = QString());
static KMime::Message::Ptr writeFreebusy(const Kolab::Freebusy &, Version v = KolabV3, const QString &productId = QString());
+ static KMime::Message::Ptr writeTag(const Akonadi::Tag &, const QStringList &items, Version v = KolabV3, const QString &productId = QString());
};
diff --git a/tests/kolabobjecttest.cpp b/tests/kolabobjecttest.cpp
index a90b39d..f57ce1d 100644
--- a/tests/kolabobjecttest.cpp
+++ b/tests/kolabobjecttest.cpp
@@ -80,6 +80,34 @@ void KolabObjectTest::dontCrashWithEmptyIncidence()
QCOMPARE(Kolab::ErrorHandler::instance().error(), Kolab::ErrorHandler::Critical);
}
+void KolabObjectTest::parseRelationMembers()
+{
+ {
+ // QString memberString("imap:///user/jan.aachen%40lhm.klab.cc/INBOX/20?message-id=%3Cf06aa3345a25005380b47547ad161d36%40lhm.klab.cc%3E&date=Tue%2C+12+Aug+2014+20%3A42%3A59+%2B0200&subject=Re%3A+test");
+ QString memberString("imap:///user/jan.aachen%40lhm.klab.cc/INBOX/20?message-id=%3Cf06aa3345a25005380b47547ad161d36%40lhm.klab.cc%3E&date=Tue%2C+12+Aug+2014+20%3A42%3A59+%2B0200&subject=Re%3A+test");
+ Kolab::RelationMember member = Kolab::parseMemberUrl(memberString);
+
+
+ const QString result = Kolab::generateMemberUrl(member);
+ qDebug() << result;
+ }
+
+ {
+
+ Kolab::RelationMember member;
+ member.uid = 20;
+ member.mailbox = QList<QByteArray>() << "INBOX";
+ member.user = "john.doe at example.org";
+ member.messageId = "messageid";
+ member.date = "date";
+ member.subject = "subject";
+ QString url = Kolab::generateMemberUrl(member);
+ qDebug() << url;
+ Kolab::RelationMember result = Kolab::parseMemberUrl(url);
+ QCOMPARE(result.uid, member.uid);
+ QCOMPARE(result.mailbox, member.mailbox);
+ }
+}
diff --git a/tests/kolabobjecttest.h b/tests/kolabobjecttest.h
index 9e0b760..7cf3298 100644
--- a/tests/kolabobjecttest.h
+++ b/tests/kolabobjecttest.h
@@ -27,6 +27,7 @@ private slots:
void preserveUnicode();
void dontCrashWithEmptyOrganizer();
void dontCrashWithEmptyIncidence();
+ void parseRelationMembers();
};
#endif // KOLABOBJECTTEST_H
More information about the commits
mailing list