diff --git a/framework/domain/mimetreeparser/interface.h b/framework/domain/mimetreeparser/interface.h --- a/framework/domain/mimetreeparser/interface.h +++ b/framework/domain/mimetreeparser/interface.h @@ -66,7 +66,7 @@ bool hasSubParts() const; QVector subParts() const; - Part::Ptr parent() const; + Part *parent() const; virtual QVector signatures() const; virtual QVector encryptions() const; @@ -85,6 +85,8 @@ QByteArray content() const; + QByteArray charset() const; + //Use default charset QString encodedContent() const; @@ -162,8 +164,8 @@ ContentPart(); virtual ~ContentPart(); - - QVector content(Type ct) const; + + QVector content(Type ct) const; Types availableContents() const; @@ -259,7 +261,6 @@ std::unique_ptr d; }; - class Key { QString keyid() const; @@ -309,7 +310,7 @@ Part::Ptr getPart(QUrl url); - //template QVector collect(Part start, std::function select, std::function filter) const; + template QVector collect(const Part::Ptr &start, std::function select, std::function filter) const; QVector collectAttachments(Part::Ptr start, std::function select, std::function filter) const; ContentPart::Ptr collectContentPart(Part::Ptr start, std::function select, std::function filter) const; ContentPart::Ptr collectContentPart(const Part::Ptr& start) const; @@ -324,4 +325,5 @@ private: std::unique_ptr d; -}; \ No newline at end of file +}; + diff --git a/framework/domain/mimetreeparser/interface.cpp b/framework/domain/mimetreeparser/interface.cpp --- a/framework/domain/mimetreeparser/interface.cpp +++ b/framework/domain/mimetreeparser/interface.cpp @@ -38,26 +38,27 @@ QVector subParts(); - const std::weak_ptr &parent() const; + Part *parent() const; private: Part *q; - std::weak_ptr mParent; + Part *mParent; QVector mSubParts; }; PartPrivate::PartPrivate(Part* part) - :q(part) + : q(part) + , mParent(Q_NULLPTR) { } void PartPrivate::appendSubPart(Part::Ptr subpart) { - subpart->d->mParent = Part::Ptr(q); + subpart->d->mParent = q; mSubParts.append(subpart); } -const std::weak_ptr &PartPrivate::parent() const +Part *PartPrivate::parent() const { return mParent; } @@ -90,7 +91,7 @@ QVector Part::encryptions() const { - auto parent = d->parent().lock(); + auto parent = d->parent(); if (parent) { return parent->encryptions(); } else { @@ -100,7 +101,7 @@ QVector Part::signatures() const { - auto parent = d->parent().lock(); + auto parent = d->parent(); if (parent) { return parent->signatures(); } else { @@ -146,28 +147,40 @@ return QVector(); } +QByteArray Content::content() const +{ + return d->mContent; +} + +QByteArray Content::charset() const +{ + return d->mCodec; +} + class ContentPartPrivate { public: void fillFrom(MimeTreeParser::TextMessagePart::Ptr part); void fillFrom(MimeTreeParser::HtmlMessagePart::Ptr part); void fillFrom(MimeTreeParser::AlternativeMessagePart::Ptr part); - QVector contents() const; + QVector content() const; ContentPart *q; + + ContentPart::Types types() const; private: - QVector mContents; + QVector mContent; ContentPart::Types mTypes; }; void ContentPartPrivate::fillFrom(MimeTreeParser::TextMessagePart::Ptr part) { mTypes = ContentPart::PlainText; foreach (const auto &mp, part->subParts()) { auto content = std::make_shared(mp->text().toLocal8Bit(), q); - mContents.append(content); + mContent.append(content); } } @@ -181,6 +194,22 @@ mTypes = ContentPart::Html | ContentPart::PlainText; } +ContentPart::Types ContentPartPrivate::types() const +{ + return mTypes; +} + +QVector ContentPartPrivate::content() const +{ + return mContent; +} + +QVector ContentPart::content(ContentPart::Type ct) const +{ + return d->content(); +} + + ContentPart::ContentPart() : d(std::unique_ptr(new ContentPartPrivate)) { @@ -197,6 +226,11 @@ return "ContentPart"; } +ContentPart::Types ContentPart::availableContents() const +{ + return d->types(); +} + class MimePartPrivate { public: @@ -230,7 +264,7 @@ ParserPrivate(Parser *parser); void setMessage(const QByteArray &mimeMessage); - void createTree(MimeTreeParser::MessagePart::Ptr start, Part::Ptr tree); + void createTree(const MimeTreeParser::MessagePart::Ptr& start, const Part::Ptr& tree); Part::Ptr mTree; private: @@ -273,9 +307,8 @@ } -void ParserPrivate::createTree(MimeTreeParser::MessagePart::Ptr start, Part::Ptr tree) +void ParserPrivate::createTree(const MimeTreeParser::MessagePart::Ptr &start, const Part::Ptr &tree) { - foreach (const auto &mp, start->subParts()) { const auto m = mp.dynamicCast(); const auto text = mp.dynamicCast(); @@ -316,20 +349,30 @@ ContentPart::Ptr Parser::collectContentPart(const Part::Ptr &start) const { - foreach (const auto &part, start->subParts()) { - if (part->type() == "ContentPart") { - return std::dynamic_pointer_cast(part); - } else { - auto ret = collectContentPart(part); - if (ret) { - return ret; - } - } - } + const auto ret = collect(start, [](const Part::Ptr &p){return p->type() == "ContentPart";}, [](const ContentPart::Ptr &p){return true;}); + if (ret.size() > 0) { + return ret[0]; + }; return ContentPart::Ptr(); } ContentPart::Ptr Parser::collectContentPart() const { return collectContentPart(d->mTree); } + +template +QVector Parser::collect(const Part::Ptr &start, std::function select, std::function filter) const +{ + QVector ret; + foreach (const auto &part, start->subParts()) { + if (select(part)){ + const auto p = std::dynamic_pointer_cast(part); + if (p && filter(p)) { + ret.append(p); + } + ret += collect(part, select, filter); + } + } + return ret; +} diff --git a/framework/domain/mimetreeparser/tests/data/html.mbox b/framework/domain/mimetreeparser/tests/data/html.mbox --- a/framework/domain/mimetreeparser/tests/data/html.mbox +++ b/framework/domain/mimetreeparser/tests/data/html.mbox @@ -9,23 +9,11 @@ X-KMail-Templates: 9 User-Agent: KMail/4.6 beta5 (Linux/2.6.34.7-0.7-desktop; KDE/4.6.41; x86_64; git-0269848; 2011-04-19) MIME-Version: 1.0 -Content-Type: multipart/alternative; boundary="nextPart8606278.tpV19BTJKu" -Content-Transfer-Encoding: 7Bit - - ---nextPart8606278.tpV19BTJKu -Content-Transfer-Encoding: 7Bit -Content-Type: text/plain; charset="windows-1252" - -Some HTML text ---nextPart8606278.tpV19BTJKu Content-Transfer-Encoding: 7Bit Content-Type: text/html; charset="windows-1252"

Some HTML text

---nextPart8606278.tpV19BTJKu-- - diff --git a/framework/domain/mimetreeparser/tests/interfacetest.cpp b/framework/domain/mimetreeparser/tests/interfacetest.cpp --- a/framework/domain/mimetreeparser/tests/interfacetest.cpp +++ b/framework/domain/mimetreeparser/tests/interfacetest.cpp @@ -39,9 +39,32 @@ { Parser parser(readMailFromFile("plaintext.mbox")); auto contentPart = parser.collectContentPart(); - //QVERIFY((bool)contentPart); + QVERIFY((bool)contentPart); + QCOMPARE(contentPart->availableContents(), ContentPart::PlainText); + auto contentList = contentPart->content(ContentPart::PlainText); + QCOMPARE(contentList.size(), 1); + QCOMPARE(contentList[0]->content(), QStringLiteral("If you can see this text it means that your email client couldn't display our newsletter properly.\nPlease visit this link to view the newsletter on our website: http://www.gog.com/newsletter/\n\n- GOG.com Team\n\n").toLocal8Bit()); + QCOMPARE(contentList[0]->charset(), QStringLiteral("utf-8").toLocal8Bit()); + QCOMPARE(contentList[0]->encryptions().size(), 0); + QCOMPARE(contentList[0]->signatures().size(), 0); + } + + void testTextAlternative() + { + Parser parser(readMailFromFile("alternative.mbox")); + auto contentPart = parser.collectContentPart(); + QVERIFY((bool)contentPart); + QCOMPARE(contentPart->availableContents(), ContentPart::PlainText | ContentPart::Html); + } + + void testTextHtml() + { + Parser parser(readMailFromFile("html.mbox")); + auto contentPart = parser.collectContentPart(); + QVERIFY((bool)contentPart); + QCOMPARE(contentPart->availableContents(), ContentPart::Html); } }; QTEST_GUILESS_MAIN(InterfaceTest) #include "interfacetest.moc" \ No newline at end of file