From 4b1798f0cdf87361869e7cf2b341acacd056c410 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Wed, 5 Apr 2017 15:04:00 +0200 Subject: Moved cpp code into src directory --- framework/domain/mimetreeparser/interface.cpp | 1179 ------------------------- 1 file changed, 1179 deletions(-) delete mode 100644 framework/domain/mimetreeparser/interface.cpp (limited to 'framework/domain/mimetreeparser/interface.cpp') diff --git a/framework/domain/mimetreeparser/interface.cpp b/framework/domain/mimetreeparser/interface.cpp deleted file mode 100644 index 663a2013..00000000 --- a/framework/domain/mimetreeparser/interface.cpp +++ /dev/null @@ -1,1179 +0,0 @@ -/* - Copyright (c) 2016 Sandro Knauß - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#include "interface.h" -#include "interface_p.h" - -#include "stringhtmlwriter.h" -#include "objecttreesource.h" - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -class MailMimePrivate -{ -public: - MailMimePrivate(MailMime *p); - - MailMime *q; - KMime::Content *mNode; - std::shared_ptr parent; -}; - -MailMimePrivate::MailMimePrivate(MailMime* p) - : q(p) - , mNode(nullptr) - , parent(nullptr) -{ -} - - -MailMime::MailMime() - : d(std::unique_ptr(new MailMimePrivate(this))) -{ -} - -QByteArray MailMime::cid() const -{ - if (!d->mNode || !d->mNode->contentID()) { - return QByteArray(); - } - return d->mNode->contentID()->identifier(); -} - -QByteArray MailMime::charset() const -{ - if(!d->mNode || !d->mNode->contentType(false)) { - return QByteArray(); - } - if (d->mNode->contentType(false)) { - return d->mNode->contentType(false)->charset(); - } - return d->mNode->defaultCharset(); -} - -bool MailMime::isFirstTextPart() const -{ - if (!d->mNode || !d->mNode->topLevel()) { - return false; - } - return (d->mNode->topLevel()->textContent() == d->mNode); -} - -bool MailMime::isFirstPart() const -{ - if (!d->mNode || !d->mNode->parent()) { - return false; - } - return (d->mNode->parent()->contents().first() == d->mNode); -} - -bool MailMime::isTopLevelPart() const -{ - if (!d->mNode) { - return false; - } - return (d->mNode->topLevel() == d->mNode); -} - -MailMime::Disposition MailMime::disposition() const -{ - if (!d->mNode) { - return Invalid; - } - const auto cd = d->mNode->contentDisposition(false); - if (!cd) { - return Invalid; - } - switch (cd->disposition()){ - case KMime::Headers::CDinline: - return Inline; - case KMime::Headers::CDattachment: - return Attachment; - default: - return Invalid; - } -} - -QString MailMime::filename() const -{ - if (!d->mNode) { - return QString(); - } - const auto cd = d->mNode->contentDisposition(false); - if (!cd) { - return QString(); - } - return cd->filename(); -} - -QMimeType MailMime::mimetype() const -{ - if (!d->mNode) { - return QMimeType(); - } - - const auto ct = d->mNode->contentType(false); - if (!ct) { - return QMimeType(); - } - - QMimeDatabase mimeDb; - return mimeDb.mimeTypeForName(ct->mimeType()); -} - -MailMime::Ptr MailMime::parent() const -{ - if (!d->parent) { - d->parent = std::shared_ptr(new MailMime()); - d->parent->d->mNode = d->mNode->parent(); - } - return d->parent; -} - -QByteArray MailMime::decodedContent() const -{ - if (!d->mNode) { - return QByteArray(); - } - return d->mNode->decodedContent(); -} - -class KeyPrivate -{ -public: - Key *q; - GpgME::Key mKey; - QByteArray mKeyID; -}; - -Key::Key() - :d(std::unique_ptr(new KeyPrivate)) -{ - d->q = this; -} - - -Key::Key(KeyPrivate *d_ptr) - :d(std::unique_ptr(d_ptr)) -{ - d->q = this; -} - -Key::~Key() -{ - -} - -QString Key::keyid() const -{ - if (!d->mKey.isNull()) { - return d->mKey.keyID(); - } - - return d->mKeyID; -} - -QString Key::name() const -{ - //FIXME: is this the correct way to get the primary UID? - if (!d->mKey.isNull()) { - return d->mKey.userID(0).name(); - } - - return QString(); -} - -QString Key::email() const -{ - if (!d->mKey.isNull()) { - return d->mKey.userID(0).email(); - } - return QString(); -} - -QString Key::comment() const -{ - if (!d->mKey.isNull()) { - return d->mKey.userID(0).comment(); - } - return QString(); -} - -class SignaturePrivate -{ -public: - Signature *q; - GpgME::Signature mSignature; - Key::Ptr mKey; -}; - -Signature::Signature() - :d(std::unique_ptr(new SignaturePrivate)) -{ - d->q = this; -} - - -Signature::Signature(SignaturePrivate *d_ptr) - :d(std::unique_ptr(d_ptr)) -{ - d->q = this; -} - -Signature::~Signature() -{ - -} - -QDateTime Signature::creationDateTime() const -{ - QDateTime dt; - dt.setTime_t(d->mSignature.creationTime()); - return dt; -} - -QDateTime Signature::expirationDateTime() const -{ - QDateTime dt; - dt.setTime_t(d->mSignature.expirationTime()); - return dt; -} - -bool Signature::neverExpires() const -{ - return d->mSignature.neverExpires(); -} - -Key::Ptr Signature::key() const -{ - return d->mKey; -} - -class EncryptionPrivate -{ -public: - Encryption *q; - std::vector mRecipients; - Encryption::ErrorType mErrorType; - QString mErrorString; -}; - -Encryption::Encryption(EncryptionPrivate *d_ptr) - :d(std::unique_ptr(d_ptr)) -{ - d->q = this; -} - -Encryption::Encryption() - :d(std::unique_ptr(new EncryptionPrivate)) -{ - d->q = this; - d->mErrorType = Encryption::NoError; -} - -Encryption::~Encryption() -{ - -} - -std::vector Encryption::recipients() const -{ - return d->mRecipients; -} - -QString Encryption::errorString() -{ - return d->mErrorString; -} - -Encryption::ErrorType Encryption::errorType() -{ - return d->mErrorType; -} - - -class PartPrivate -{ -public: - PartPrivate(Part *part); - void appendSubPart(Part::Ptr subpart); - - QVector subParts(); - - Part *parent() const; - - const MailMime::Ptr &mailMime() const; - void createMailMime(const MimeTreeParser::MimeMessagePart::Ptr &part); - void createMailMime(const MimeTreeParser::TextMessagePart::Ptr &part); - void createMailMime(const MimeTreeParser::AlternativeMessagePart::Ptr &part); - void createMailMime(const MimeTreeParser::HtmlMessagePart::Ptr &part); - void createMailMime(const MimeTreeParser::EncryptedMessagePart::Ptr &part); - - static Encryption::Ptr createEncryption(const MimeTreeParser::EncryptedMessagePart::Ptr& part); - void appendEncryption(const MimeTreeParser::EncryptedMessagePart::Ptr &part); - static QVector createSignature(const MimeTreeParser::SignedMessagePart::Ptr& part); - void appendSignature(const MimeTreeParser::SignedMessagePart::Ptr &part); - - void setSignatures(const QVector &sigs); - void setEncryptions(const QVector &encs); - - const QVector &encryptions() const; - const QVector &signatures() const; -private: - Part *q; - Part *mParent; - QVector mSubParts; - QVector mEncryptions; - QVector mSignatures; - MailMime::Ptr mMailMime; -}; - -PartPrivate::PartPrivate(Part* part) - : q(part) - , mParent(Q_NULLPTR) -{ - -} - -void PartPrivate::createMailMime(const MimeTreeParser::HtmlMessagePart::Ptr& part) -{ - mMailMime = MailMime::Ptr(new MailMime); - mMailMime->d->mNode = part->mNode; -} - -void PartPrivate::createMailMime(const MimeTreeParser::AlternativeMessagePart::Ptr& part) -{ - mMailMime = MailMime::Ptr(new MailMime); - mMailMime->d->mNode = part->mNode; -} - -void PartPrivate::createMailMime(const MimeTreeParser::TextMessagePart::Ptr& part) -{ - mMailMime = MailMime::Ptr(new MailMime); - mMailMime->d->mNode = part->mNode; -} - -void PartPrivate::createMailMime(const MimeTreeParser::MimeMessagePart::Ptr& part) -{ - mMailMime = MailMime::Ptr(new MailMime); - mMailMime->d->mNode = part->mNode; -} - -void PartPrivate::createMailMime(const MimeTreeParser::EncryptedMessagePart::Ptr& part) -{ - mMailMime = MailMime::Ptr(new MailMime); - mMailMime->d->mNode = part->mNode; -} - -void PartPrivate::appendSubPart(Part::Ptr subpart) -{ - subpart->d->mParent = q; - mSubParts.append(subpart); -} - -Encryption::Ptr PartPrivate::createEncryption(const MimeTreeParser::EncryptedMessagePart::Ptr& part) -{ - QGpgME::KeyListJob *job = part->mCryptoProto->keyListJob(false); // local, no sigs - if (!job) { - qWarning() << "The Crypto backend does not support listing keys. "; - return Encryption::Ptr(); - } - - auto encpriv = new EncryptionPrivate(); - if (part->passphraseError()) { - encpriv->mErrorType = Encryption::PassphraseError; - encpriv->mErrorString = part->mMetaData.errorText; - } else if (part->isEncrypted() && !part->isDecryptable()) { - encpriv->mErrorType = Encryption::KeyMissing; - encpriv->mErrorString = part->mMetaData.errorText; - } else if (!part->isEncrypted() && !part->isDecryptable()) { - encpriv->mErrorType = Encryption::UnknownError; - encpriv->mErrorString = part->mMetaData.errorText; - } else { - encpriv->mErrorType = Encryption::NoError; - } - - foreach(const auto &recipient, part->mDecryptRecipients) { - std::vector found_keys; - const auto &keyid = recipient.keyID(); - GpgME::KeyListResult res = job->exec(QStringList(QLatin1String(keyid)), false, found_keys); - if (res.error()) { - qWarning() << "Error while searching key for Fingerprint: " << keyid; - continue; - } - if (found_keys.size() > 1) { - // Should not Happen - qWarning() << "Oops: Found more then one Key for Fingerprint: " << keyid; - } - if (found_keys.size() != 1) { - // Should not Happen at this point - qWarning() << "Oops: Found no Key for Fingerprint: " << keyid; - auto keypriv = new KeyPrivate; - keypriv->mKeyID = keyid; - encpriv->mRecipients.push_back(Key::Ptr(new Key(keypriv))); - } else { - auto key = found_keys[0]; - auto keypriv = new KeyPrivate; - keypriv->mKey = key; - encpriv->mRecipients.push_back(Key::Ptr(new Key(keypriv))); - } - } - return Encryption::Ptr(new Encryption(encpriv)); -} - -void PartPrivate::appendEncryption(const MimeTreeParser::EncryptedMessagePart::Ptr& part) -{ - mEncryptions.append(createEncryption(part)); -} - -void PartPrivate::setEncryptions(const QVector< Encryption::Ptr >& encs) -{ - mEncryptions = encs; -} - -QVector PartPrivate::createSignature(const MimeTreeParser::SignedMessagePart::Ptr& part) -{ - QVector sigs; - QGpgME::KeyListJob *job = part->mCryptoProto->keyListJob(false); // local, no sigs - if (!job) { - qWarning() << "The Crypto backend does not support listing keys. "; - return sigs; - } - - foreach(const auto &sig, part->mSignatures) { - auto sigpriv = new SignaturePrivate(); - sigpriv->mSignature = sig; - auto signature = std::make_shared(sigpriv); - sigs.append(signature); - - std::vector found_keys; - const auto &keyid = sig.fingerprint(); - GpgME::KeyListResult res = job->exec(QStringList(QLatin1String(keyid)), false, found_keys); - if (res.error()) { - qWarning() << "Error while searching key for Fingerprint: " << keyid; - continue; - } - if (found_keys.size() > 1) { - // Should not Happen - qWarning() << "Oops: Found more then one Key for Fingerprint: " << keyid; - continue; - } - if (found_keys.size() != 1) { - // Should not Happen at this point - qWarning() << "Oops: Found no Key for Fingerprint: " << keyid; - continue; - } else { - auto key = found_keys[0]; - auto keypriv = new KeyPrivate; - keypriv->mKey = key; - sigpriv->mKey = Key::Ptr(new Key(keypriv)); - } - } - return sigs; -} - -void PartPrivate::appendSignature(const MimeTreeParser::SignedMessagePart::Ptr& part) -{ - mSignatures.append(createSignature(part)); -} - - -void PartPrivate::setSignatures(const QVector< Signature::Ptr >& sigs) -{ - mSignatures = sigs; -} - -Part *PartPrivate::parent() const -{ - return mParent; -} - -QVector< Part::Ptr > PartPrivate::subParts() -{ - return mSubParts; -} - -const MailMime::Ptr& PartPrivate::mailMime() const -{ - return mMailMime; -} - -const QVector< Encryption::Ptr >& PartPrivate::encryptions() const -{ - return mEncryptions; -} - -const QVector< Signature::Ptr >& PartPrivate::signatures() const -{ - return mSignatures; -} - -Part::Part() - : d(std::unique_ptr(new PartPrivate(this))) -{ - -} - -bool Part::hasSubParts() const -{ - return !subParts().isEmpty(); -} - -QVector Part::subParts() const -{ - return d->subParts(); -} - -QByteArray Part::type() const -{ - return "Part"; -} - -QVector Part::availableContents() const -{ - return QVector(); -} - -QVector Part::content() const -{ - return content(availableContents().first()); -} - -QVector Part::content(const QByteArray& ct) const -{ - return QVector(); -} - -QVector Part::encryptions() const -{ - auto ret = d->encryptions(); - auto parent = d->parent(); - if (parent) { - ret.append(parent->encryptions()); - } - return ret; -} - -QVector Part::signatures() const -{ - auto ret = d->signatures(); - auto parent = d->parent(); - if (parent) { - ret.append(parent->signatures()); - } - return ret; -} - -MailMime::Ptr Part::mailMime() const -{ - return d->mailMime(); -} - -Part *Part::parent() const -{ - return d->parent(); -} - -class ContentPrivate -{ -public: - QByteArray mContent; - QByteArray mCodec; - Part *mParent; - Content *q; - MailMime::Ptr mMailMime; - QVector mEncryptions; - QVector mSignatures; - void appendSignature(const MimeTreeParser::SignedMessagePart::Ptr &sig); - void appendEncryption(const MimeTreeParser::EncryptedMessagePart::Ptr &enc); -}; - -void ContentPrivate::appendEncryption(const MimeTreeParser::EncryptedMessagePart::Ptr& enc) -{ - mEncryptions.append(PartPrivate::createEncryption(enc)); -} - -void ContentPrivate::appendSignature(const MimeTreeParser::SignedMessagePart::Ptr& sig) -{ - mSignatures.append(PartPrivate::createSignature(sig)); -} - - -Content::Content(const QByteArray& content, Part *parent) - : d(std::unique_ptr(new ContentPrivate)) -{ - d->q = this; - d->mContent = content; - d->mCodec = "utf-8"; - d->mParent = parent; -} - -Content::Content(ContentPrivate* d_ptr) - : d(std::unique_ptr(d_ptr)) -{ - d->q = this; -} - -Content::~Content() -{ -} - -QVector Content::encryptions() const -{ - auto ret = d->mEncryptions; - if (d->mParent) { - ret.append(d->mParent->encryptions()); - } - return ret; -} - -QVector Content::signatures() const -{ - auto ret = d->mSignatures; - if (d->mParent) { - ret.append(d->mParent->signatures()); - } - return ret; -} - -QByteArray Content::content() const -{ - return d->mContent; -} - -QByteArray Content::charset() const -{ - return d->mCodec; -} - -QString Content::encodedContent() const -{ - return QString::fromUtf8(content()); - // TODO: should set "raw" content not the already utf8 encoded content - // return encodedContent(charset()); -} - -QString Content::encodedContent(const QByteArray &charset) const -{ - QTextCodec *codec = QTextCodec::codecForName(charset); - return codec->toUnicode(content()); -} - -QByteArray Content::type() const -{ - return "Content"; -} - -MailMime::Ptr Content::mailMime() const -{ - if (d->mMailMime) { - return d->mMailMime; - } else { - return d->mParent->mailMime(); - } -} - -Part *Content::parent() const -{ - return d->mParent; -} - -HtmlContent::HtmlContent(const QByteArray& content, Part* parent) - : Content(content, parent) -{ - -} - -QByteArray HtmlContent::type() const -{ - return "HtmlContent"; -} - -PlainTextContent::PlainTextContent(const QByteArray& content, Part* parent) - : Content(content, parent) -{ - -} - -PlainTextContent::PlainTextContent(ContentPrivate* d_ptr) - : Content(d_ptr) -{ - -} - -HtmlContent::HtmlContent(ContentPrivate* d_ptr) - : Content(d_ptr) -{ - -} - - -QByteArray PlainTextContent::type() const -{ - return "PlainTextContent"; -} - -class AlternativePartPrivate -{ -public: - void fillFrom(MimeTreeParser::AlternativeMessagePart::Ptr part); - - QVector content(const QByteArray &ct) const; - - AlternativePart *q; - - QVector types() const; - -private: - QMap> mContent; - QVector mTypes; -}; - -void AlternativePartPrivate::fillFrom(MimeTreeParser::AlternativeMessagePart::Ptr part) -{ - mTypes = QVector() << "html" << "plaintext"; - - Content::Ptr content = std::make_shared(part->htmlContent().toLocal8Bit(), q); - mContent["html"].append(content); - content = std::make_shared(part->plaintextContent().toLocal8Bit(), q); - mContent["plaintext"].append(content); - q->reachParentD()->createMailMime(part); -} - -QVector AlternativePartPrivate::types() const -{ - return mTypes; -} - -QVector AlternativePartPrivate::content(const QByteArray& ct) const -{ - return mContent[ct]; -} - -AlternativePart::AlternativePart() - : d(std::unique_ptr(new AlternativePartPrivate)) -{ - d->q = this; -} - -AlternativePart::~AlternativePart() -{ - -} - -QByteArray AlternativePart::type() const -{ - return "AlternativePart"; -} - -QVector AlternativePart::availableContents() const -{ - return d->types(); -} - -QVector AlternativePart::content(const QByteArray& ct) const -{ - return d->content(ct); -} - -PartPrivate* AlternativePart::reachParentD() const -{ - return Part::d.get(); -} - -class SinglePartPrivate -{ -public: - void fillFrom(const MimeTreeParser::TextMessagePart::Ptr &part); - void fillFrom(const MimeTreeParser::HtmlMessagePart::Ptr &part); - void fillFrom(const MimeTreeParser::AttachmentMessagePart::Ptr &part); - void createEncryptionFailBlock(const MimeTreeParser::EncryptedMessagePart::Ptr &part); - SinglePart *q; - - QVector mContent; - QByteArray mType; -}; - -void SinglePartPrivate::fillFrom(const MimeTreeParser::TextMessagePart::Ptr &part) -{ - mType = "plaintext"; - mContent.clear(); - foreach (const auto &mp, part->subParts()) { - auto d_ptr = new ContentPrivate; - d_ptr->mContent = mp->text().toUtf8(); // TODO: should set "raw" content not the already utf8 encoded content - d_ptr->mParent = q; - const auto enc = mp.dynamicCast(); - auto sig = mp.dynamicCast(); - if (enc) { - d_ptr->appendEncryption(enc); - if (!enc->isDecryptable()) { - d_ptr->mContent = QByteArray(); - } - const auto s = enc->subParts(); - if (s.size() == 1) { - sig = s[0].dynamicCast(); - } - } - if (sig) { - d_ptr->appendSignature(sig); - } - mContent.append(std::make_shared(d_ptr)); - q->reachParentD()->createMailMime(part); - d_ptr->mCodec = q->mailMime()->charset(); - } -} - -void SinglePartPrivate::fillFrom(const MimeTreeParser::HtmlMessagePart::Ptr &part) -{ - mType = "html"; - mContent.clear(); - mContent.append(std::make_shared(part->text().toUtf8(), q)); - q->reachParentD()->createMailMime(part); -} - -void SinglePartPrivate::fillFrom(const MimeTreeParser::AttachmentMessagePart::Ptr &part) -{ - QMimeDatabase mimeDb; - q->reachParentD()->createMailMime(part.staticCast()); - const auto mimetype = q->mailMime()->mimetype(); - const auto content = q->mailMime()->decodedContent(); - mContent.clear(); - if (mimetype == mimeDb.mimeTypeForName("text/plain")) { - mType = "plaintext"; - mContent.append(std::make_shared(content, q)); - } else if (mimetype == mimeDb.mimeTypeForName("text/html")) { - mType = "html"; - mContent.append(std::make_shared(content, q)); - } else { - mType = mimetype.name().toUtf8(); - mContent.append(std::make_shared(content, q)); - } -} - -void SinglePartPrivate::createEncryptionFailBlock(const MimeTreeParser::EncryptedMessagePart::Ptr &part) -{ - mType = "plaintext"; - mContent.clear(); - mContent.append(std::make_shared(QByteArray(), q)); - q->reachParentD()->createMailMime(part); -} - -SinglePart::SinglePart() - : d(std::unique_ptr(new SinglePartPrivate)) -{ - d->q = this; -} - -SinglePart::~SinglePart() -{ - -} - -QVector SinglePart::availableContents() const -{ - return QVector() << d->mType; -} - -QVector< Content::Ptr > SinglePart::content(const QByteArray &ct) const -{ - if (ct == d->mType) { - return d->mContent; - } - return QVector(); -} - -QByteArray SinglePart::type() const -{ - return "SinglePart"; -} - -PartPrivate* SinglePart::reachParentD() const -{ - return Part::d.get(); -} - -ParserPrivate::ParserPrivate(Parser* parser) - : q(parser) - , mNodeHelper(std::make_shared()) -{ - -} - -void ParserPrivate::setMessage(const QByteArray& mimeMessage) -{ - const auto mailData = KMime::CRLFtoLF(mimeMessage); - mMsg = KMime::Message::Ptr(new KMime::Message); - mMsg->setContent(mailData); - mMsg->parse(); - - // render the mail - StringHtmlWriter htmlWriter; - ObjectTreeSource source(&htmlWriter); - MimeTreeParser::ObjectTreeParser otp(&source, mNodeHelper.get()); - - otp.parseObjectTree(mMsg.data()); - mPartTree = otp.parsedPart().dynamicCast(); - - mEmbeddedPartMap = htmlWriter.embeddedParts(); - mHtml = htmlWriter.html(); - - mTree = std::make_shared(); - createTree(mPartTree, mTree); -} - - -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(); - const auto alternative = mp.dynamicCast(); - const auto html = mp.dynamicCast(); - const auto attachment = mp.dynamicCast(); - if (attachment) { - auto part = std::make_shared(); - part->d->fillFrom(attachment); - tree->d->appendSubPart(part); - } else if (text) { - auto part = std::make_shared(); - part->d->fillFrom(text); - tree->d->appendSubPart(part); - } else if (alternative) { - auto part = std::make_shared(); - part->d->fillFrom(alternative); - tree->d->appendSubPart(part); - } else if (html) { - auto part = std::make_shared(); - part->d->fillFrom(html); - tree->d->appendSubPart(part); - } else { - const auto enc = mp.dynamicCast(); - const auto sig = mp.dynamicCast(); - if (enc || sig) { - auto subTree = std::make_shared(); - if (enc) { - subTree->d->appendEncryption(enc); - if (!enc->isDecryptable()) { - auto part = std::make_shared(); - part->d->createEncryptionFailBlock(enc); - part->reachParentD()->setEncryptions(subTree->d->encryptions()); - tree->d->appendSubPart(part); - return; - } - } - if (sig) { - subTree->d->appendSignature(sig); - } - createTree(m, subTree); - foreach(const auto &p, subTree->subParts()) { - tree->d->appendSubPart(p); - if (enc) { - p->d->setEncryptions(subTree->d->encryptions()); - } - if (sig) { - p->d->setSignatures(subTree->d->signatures()); - } - } - } else { - createTree(m, tree); - } - } - } -} - -Parser::Parser(const QByteArray& mimeMessage) - :d(std::unique_ptr(new ParserPrivate(this))) -{ - d->setMessage(mimeMessage); -} - -Parser::~Parser() -{ -} - -Part::Ptr Parser::getPart(const QUrl &url) -{ - if (url.scheme() == QStringLiteral("cid") && !url.path().isEmpty()) { - const auto cid = url.path(); - return find(d->mTree, [&cid](const Part::Ptr &p){ - const auto mime = p->mailMime(); - return mime->cid() == cid; - }); - } - return Part::Ptr(); -} - -QVector Parser::collectContentParts() const -{ - return collect(d->mTree, [](const Part::Ptr &p){return p->type() != "EncapsulatedPart";}, - [](const Content::Ptr &content){ - const auto mime = content->mailMime(); - - if (!mime) { - return true; - } - - if (mime->isFirstTextPart()) { - return true; - } - - { - auto _mime = content->parent()->mailMime(); - while (_mime) { - if (_mime && (_mime->isTopLevelPart() || _mime->isFirstTextPart())) { - return true; - } - if (_mime->isFirstPart()) { - _mime = _mime->parent(); - } else { - break; - } - } - } - - const auto ctname = mime->mimetype().name().trimmed().toLower(); - bool mightContent = (content->type() != "Content"); //Content we understand - - const auto cd = mime->disposition(); - if (cd && cd == MailMime::Inline) { - return mightContent; - } - - if (cd && cd == MailMime::Attachment) { - return false; - } - - if ((ctname.startsWith("text/") || ctname.isEmpty()) && - (!mime || mime->filename().trimmed().isEmpty())) { - // text/* w/o filename parameter: - return true; - } - return false; - }); -} - - -QVector Parser::collectAttachmentParts() const -{ - return collect(d->mTree, [](const Part::Ptr &p){return p->type() != "EncapsulatedPart";}, - [](const Content::Ptr &content){ - const auto mime = content->mailMime(); - - if (!mime) { - return false; - } - - if (mime->isFirstTextPart()) { - return false; - } - - { - QMimeDatabase mimeDb; - auto _mime = content->parent()->mailMime(); - const auto parent = _mime->parent(); - if (parent) { - const auto mimetype = parent->mimetype(); - if (mimetype == mimeDb.mimeTypeForName("multipart/related")) { - return false; - } - } - while (_mime) { - if (_mime && (_mime->isTopLevelPart() || _mime->isFirstTextPart())) { - return false; - } - if (_mime->isFirstPart()) { - _mime = _mime->parent(); - } else { - break; - } - } - } - - const auto ctname = mime->mimetype().name().trimmed().toLower(); - bool mightContent = (content->type() != "Content"); //Content we understand - - const auto cd = mime->disposition(); - if (cd && cd == MailMime::Inline) { - // explict "inline" disposition: - return !mightContent; - } - if (cd && cd == MailMime::Attachment) { - // explicit "attachment" disposition: - return true; - } - - const auto ct = mime->mimetype(); - if ((ctname.startsWith("text/") || ctname.isEmpty()) && - (!mime || mime->filename().trimmed().isEmpty())) { - // text/* w/o filename parameter: - return false; - } - return true; - }); -} - -QVector Parser::collect(const Part::Ptr &start, std::function select, std::function filter) const -{ - QVector ret; - foreach (const auto &part, start->subParts()) { - QVector contents; - foreach(const auto &ct, part->availableContents()) { - foreach(const auto &content, part->content(ct)) { - if (filter(content)) { - contents.append(ct); - break; - } - } - } - if (!contents.isEmpty()) { - ret.append(part); - } - if (select(part)){ - ret += collect(part, select, filter); - } - } - return ret; -} - -Part::Ptr Parser::find(const Part::Ptr &start, std::function select) const -{ - foreach (const auto &part, start->subParts()) { - if (select(part)) { - return part; - } - const auto ret = find(part, select); - if (ret) { - return ret; - } - } - return Part::Ptr(); -} -- cgit v1.2.3