From 23132b14e9bf3e1ec1f7720bbe28a2051508bd0f Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Wed, 7 Jun 2017 22:17:12 +0200 Subject: Encapsulated parts --- .../src/domain/mime/mimetreeparser/messagepart.cpp | 15 +++++++++ .../src/domain/mime/mimetreeparser/messagepart.h | 2 ++ .../mime/mimetreeparser/objecttreeparser.cpp | 38 ++++++++++++++-------- .../domain/mime/mimetreeparser/objecttreeparser.h | 1 + .../mime/mimetreeparser/tests/interfacetest.cpp | 18 ++++++++++ .../src/domain/mime/mimetreeparser/textplain.cpp | 7 ++-- 6 files changed, 64 insertions(+), 17 deletions(-) (limited to 'framework/src/domain/mime/mimetreeparser') diff --git a/framework/src/domain/mime/mimetreeparser/messagepart.cpp b/framework/src/domain/mime/mimetreeparser/messagepart.cpp index 00abb003..df4dfeac 100644 --- a/framework/src/domain/mime/mimetreeparser/messagepart.cpp +++ b/framework/src/domain/mime/mimetreeparser/messagepart.cpp @@ -1292,3 +1292,18 @@ QString EncapsulatedRfc822MessagePart::text() const return renderInternalText(); } +QString EncapsulatedRfc822MessagePart::from() const +{ + if (auto from = mMessage->from(false)) { + return from->asUnicodeString(); + } + return {}; +} + +QDateTime EncapsulatedRfc822MessagePart::date() const +{ + if (auto date = mMessage->date(false)) { + return date->dateTime(); + } + return {}; +} diff --git a/framework/src/domain/mime/mimetreeparser/messagepart.h b/framework/src/domain/mime/mimetreeparser/messagepart.h index dd3a842f..7d266ac5 100644 --- a/framework/src/domain/mime/mimetreeparser/messagepart.h +++ b/framework/src/domain/mime/mimetreeparser/messagepart.h @@ -281,6 +281,8 @@ public: virtual ~EncapsulatedRfc822MessagePart(); QString text() const Q_DECL_OVERRIDE; + QString from() const; + QDateTime date() const; private: const KMime::Message::Ptr mMessage; diff --git a/framework/src/domain/mime/mimetreeparser/objecttreeparser.cpp b/framework/src/domain/mime/mimetreeparser/objecttreeparser.cpp index b137be87..8d8ddf12 100644 --- a/framework/src/domain/mime/mimetreeparser/objecttreeparser.cpp +++ b/framework/src/domain/mime/mimetreeparser/objecttreeparser.cpp @@ -190,20 +190,17 @@ KMime::Content *ObjectTreeParser::find(const std::function collect(MessagePart::Ptr start, const std::function &filter, const std::function &select) +static QVector collect(MessagePart::Ptr start, const std::function &evaluateSubtree, const std::function &select) { MessagePartPtr ptr = start.dynamicCast(); Q_ASSERT(ptr); - if (!filter(ptr)) { - return {}; - } - QVector list; - if (ptr) { + if (evaluateSubtree(ptr)) { for (const auto &p: ptr->subParts()) { - list << ::collect(p, filter, select); + list << ::collect(p, evaluateSubtree, select); } } + //Don't consider this part if we already selected a subpart if (list.isEmpty()) { if (select(ptr)) { @@ -213,14 +210,25 @@ static QVector collect(MessagePart::Ptr start, const std::func return list; } -QVector ObjectTreeParser::collectContentParts() +QVector ObjectTreeParser::collectContentParts() { - QVector contentParts = ::collect(mParsedPart, - [] (const MessagePartPtr &part) { - // return p->type() != "EncapsulatedPart"; + return collectContentParts(mParsedPart); +} + +QVector ObjectTreeParser::collectContentParts(MessagePart::Ptr start) +{ + return ::collect(start, + [start] (const MessagePartPtr &part) { + //Ignore the top-level + if (start.data() == part.data()) { + return true; + } + if (auto e = part.dynamicCast()) { + return false; + } return true; }, - [] (const MessagePartPtr &part) { + [start] (const MessagePartPtr &part) { if (dynamic_cast(part.data())) { return false; } else if (const auto text = dynamic_cast(part.data())) { @@ -233,6 +241,11 @@ QVector ObjectTreeParser::collectContentParts() return true; } else if (dynamic_cast(part.data())) { return true; + } else if (dynamic_cast(part.data())) { + if (start.data() == part.data()) { + return false; + } + return true; } else if (const auto enc = dynamic_cast(part.data())) { if (enc->error()) { return true; @@ -247,7 +260,6 @@ QVector ObjectTreeParser::collectContentParts() } return false; }); - return contentParts; } QVector ObjectTreeParser::collectAttachmentParts() diff --git a/framework/src/domain/mime/mimetreeparser/objecttreeparser.h b/framework/src/domain/mime/mimetreeparser/objecttreeparser.h index 398cbcd7..d219a52b 100644 --- a/framework/src/domain/mime/mimetreeparser/objecttreeparser.h +++ b/framework/src/domain/mime/mimetreeparser/objecttreeparser.h @@ -285,6 +285,7 @@ public: MessagePartPtr parsedPart() const; KMime::Content *find(const std::function &select); QVector collectContentParts(); + QVector collectContentParts(MessagePart::Ptr start); QVector collectAttachmentParts(); void decryptParts(); void importCertificates(); diff --git a/framework/src/domain/mime/mimetreeparser/tests/interfacetest.cpp b/framework/src/domain/mime/mimetreeparser/tests/interfacetest.cpp index f9b557c9..b9fdd356 100644 --- a/framework/src/domain/mime/mimetreeparser/tests/interfacetest.cpp +++ b/framework/src/domain/mime/mimetreeparser/tests/interfacetest.cpp @@ -319,6 +319,24 @@ private slots: QVERIFY(bool(part)); QVERIFY(part->error()); } + + void testEncapsulated() + { + MimeTreeParser::ObjectTreeParser otp; + otp.parseObjectTree(readMailFromFile("encapsulated-with-attachment.mbox")); + otp.decryptParts(); + auto partList = otp.collectContentParts(); + QCOMPARE(partList.size(), 2); + auto part = partList[1].dynamicCast(); + QVERIFY(bool(part)); + QCOMPARE(part->from(), QLatin1String("Thomas McGuire ")); + QCOMPARE(part->date().toString(), QLatin1String("Wed Aug 5 10:57:58 2009 GMT+0200")); + auto subPartList = otp.collectContentParts(part); + QCOMPARE(subPartList.size(), 1); + qWarning() << subPartList[0]->metaObject()->className(); + auto subPart = subPartList[0].dynamicCast(); + QVERIFY(bool(subPart)); + } }; QTEST_GUILESS_MAIN(InterfaceTest) diff --git a/framework/src/domain/mime/mimetreeparser/textplain.cpp b/framework/src/domain/mime/mimetreeparser/textplain.cpp index 32201a8a..d62cb2cf 100644 --- a/framework/src/domain/mime/mimetreeparser/textplain.cpp +++ b/framework/src/domain/mime/mimetreeparser/textplain.cpp @@ -41,13 +41,12 @@ const Interface::BodyPartFormatter *TextPlainBodyPartFormatter::create() MessagePart::Ptr TextPlainBodyPartFormatter::process(Interface::BodyPart &part) const { KMime::Content *node = part.content(); - const bool isFirstTextPart = (node->topLevel()->textContent() == node); TextMessagePart::Ptr mp; - if (isFirstTextPart) { - mp = TextMessagePart::Ptr(new TextMessagePart(part.objectTreeParser(), node)); + if (KMime::isAttachment(node)) { + mp = AttachmentMessagePart::Ptr(new AttachmentMessagePart(part.objectTreeParser(), node)); } else { - mp = TextMessagePart::Ptr(new AttachmentMessagePart(part.objectTreeParser(), node)); + mp = TextMessagePart::Ptr(new TextMessagePart(part.objectTreeParser(), node)); } return mp; -- cgit v1.2.3