From 1fe0ab05ae2bfe6505736f598bd535a71fb86a6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20Knau=C3=9F?= Date: Mon, 17 Oct 2016 15:35:49 +0200 Subject: replace cid links with actuall content of the images --- framework/domain/messageparser.h | 3 ++- framework/domain/messageparser_new.cpp | 33 +++++++++++++++++++++++---- framework/domain/messageparser_old.cpp | 23 ++++++++++++++----- framework/domain/mimetreeparser/interface.cpp | 11 ++++++++- framework/domain/mimetreeparser/interface.h | 2 ++ 5 files changed, 60 insertions(+), 12 deletions(-) (limited to 'framework/domain') diff --git a/framework/domain/messageparser.h b/framework/domain/messageparser.h index b3d7537d..5eb355e7 100644 --- a/framework/domain/messageparser.h +++ b/framework/domain/messageparser.h @@ -97,7 +97,7 @@ private: class NewContentModel : public QAbstractItemModel { Q_OBJECT public: - NewContentModel (const PartPtr &part); + NewContentModel (const PartPtr &part, const std::shared_ptr &parser); public: enum Roles { @@ -116,6 +116,7 @@ public: private: const PartPtr &mPart; + const std::shared_ptr &mParser; }; class NewModel : public QAbstractItemModel { diff --git a/framework/domain/messageparser_new.cpp b/framework/domain/messageparser_new.cpp index d1b956f5..4395f2e3 100644 --- a/framework/domain/messageparser_new.cpp +++ b/framework/domain/messageparser_new.cpp @@ -26,7 +26,7 @@ NewModel::NewModel(std::shared_ptr parser) { mParts = mParser->collectContentParts(); foreach(const auto &part, mParts) { - mContentMap.insert(part.get(), std::shared_ptr(new NewContentModel(part))); + mContentMap.insert(part.get(), std::shared_ptr(new NewContentModel(part, mParser))); } } @@ -87,8 +87,9 @@ int NewModel::columnCount(const QModelIndex &parent) const return 1; } -NewContentModel::NewContentModel(const Part::Ptr &part) +NewContentModel::NewContentModel(const Part::Ptr &part, const std::shared_ptr &parser) : mPart(part) + , mParser(parser) { } @@ -121,8 +122,32 @@ QVariant NewContentModel::data(const QModelIndex &index, int role) const return QString::fromLatin1(content->type()); case IsEmbededRole: return false; - case ContentRole: - return content->encodedContent(); + case ContentRole: { + auto text = content->encodedContent(); + if (data(index, TypeRole).toString() == "HtmlContent") { + const auto rx = QRegExp("(src)\\s*=\\s*(\"|')(cid:[^\"']+)\\2"); + int pos = 0; + while ((pos = rx.indexIn(text, pos)) != -1) { + const auto link = QUrl(rx.cap(3).toUtf8()); + pos += rx.matchedLength(); + const auto repl = mParser->getPart(link); + if (!repl) { + continue; + } + const auto content = repl->content(); + if(content.size() < 1) { + continue; + } + const auto mailMime = content.first()->mailMime(); + const auto mimetype = mailMime->mimetype().name(); + if (mimetype.startsWith("image/")) { + const auto data = content.first()->content(); + text.replace(rx.cap(0), QString("src=\"data:%1;base64,%2\"").arg(mimetype, QString::fromLatin1(data.toBase64()))); + } + } + } + return text; + } case SecurityLevelRole: return content->encryptions().size() > mPart->encryptions().size() ? "red": "black"; //test for gpg inline } diff --git a/framework/domain/messageparser_old.cpp b/framework/domain/messageparser_old.cpp index a364c8ab..a4247d8c 100644 --- a/framework/domain/messageparser_old.cpp +++ b/framework/domain/messageparser_old.cpp @@ -64,14 +64,25 @@ QVariant PartModel::data(const QModelIndex &index, int role) const // qDebug() << "Getting text: " << part->property("text").toString(); // FIXME: we should have a list per part, and not one for all parts. auto text = part->property("htmlContent").toString(); - auto rx = QRegExp("src=(\"|')cid:([^\1]*)\1"); - int pos = 0; + const auto rx = QRegExp("(src)\\s*=\\s*(\"|')(cid:[^\"']+)\\2"); + int pos = 0; while ((pos = rx.indexIn(text, pos)) != -1) { - auto repl = mParser->getPart(rx.cap(2).toUtf8()); - if (repl.isValid()) { - text.replace(rx.cap(0), QString("src=\"%1\"").arg(repl.toString())); - } + const auto link = QUrl(rx.cap(3).toUtf8()); pos += rx.matchedLength(); + const auto repl = mParser->getPart(link); + if (!repl) { + continue; + } + const auto content = repl->content(); + if(content.size() < 1) { + continue; + } + const auto mailMime = content.first()->mailMime(); + const auto mimetype = mailMime->mimetype().name(); + if (mimetype.startsWith("image/")) { + const auto data = content.first()->content(); + text.replace(rx.cap(0), QString("src=\"data:%1;base64,%2\"").arg(mimetype, QString::fromLatin1(data.toBase64()))); + } } return text; } diff --git a/framework/domain/mimetreeparser/interface.cpp b/framework/domain/mimetreeparser/interface.cpp index c2fd1e65..b5e29e6b 100644 --- a/framework/domain/mimetreeparser/interface.cpp +++ b/framework/domain/mimetreeparser/interface.cpp @@ -143,6 +143,15 @@ MailMime::Ptr MailMime::parent() const return d->parent; } +QByteArray MailMime::decodedContent() const +{ + if (!d->mNode) { + return QByteArray(); + } + return d->mNode->decodedContent(); +} + + class PartPrivate { public: @@ -581,7 +590,7 @@ void SinglePartPrivate::fillFrom(MimeTreeParser::AttachmentMessagePart::Ptr part q->reachParentD()->createMailMime(part.staticCast()); mType = q->mailMime()->mimetype().name().toUtf8(); mContent.clear(); - mContent.append(std::make_shared(part->text().toLocal8Bit(), q)); + mContent.append(std::make_shared(q->mailMime()->decodedContent(), q)); } SinglePart::SinglePart() diff --git a/framework/domain/mimetreeparser/interface.h b/framework/domain/mimetreeparser/interface.h index cc6c68d2..f88271af 100644 --- a/framework/domain/mimetreeparser/interface.h +++ b/framework/domain/mimetreeparser/interface.h @@ -100,6 +100,8 @@ public: // overwrite default charset with given charset QString encodedContent(QByteArray charset) const; + QByteArray decodedContent() const; + bool isFirstTextPart() const; bool isFirstPart() const; bool isTopLevelPart() const; -- cgit v1.2.3