From 5df2baeb48298d422000574f8755ea08b0c19a97 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Wed, 24 May 2017 08:01:12 +0200 Subject: Saving of attachments --- framework/qml/MailViewer.qml | 4 +++ framework/src/domain/mime/attachmentmodel.cpp | 38 +++++++++++++++++++++- framework/src/domain/mime/messageparser.h | 2 ++ .../src/domain/mime/mimetreeparser/interface.cpp | 16 +++++++++ .../src/domain/mime/mimetreeparser/interface.h | 1 + 5 files changed, 60 insertions(+), 1 deletion(-) (limited to 'framework') diff --git a/framework/qml/MailViewer.qml b/framework/qml/MailViewer.qml index 73dcc291..d2c0a3be 100644 --- a/framework/qml/MailViewer.qml +++ b/framework/qml/MailViewer.qml @@ -288,6 +288,10 @@ Rectangle { clip: true //TODO size encrypted signed type + MouseArea { + anchors.fill: parent + onClicked: messageParser.attachments.saveAttachmentToDisk(messageParser.attachments.index(index, 0)) + } } } } diff --git a/framework/src/domain/mime/attachmentmodel.cpp b/framework/src/domain/mime/attachmentmodel.cpp index 2871579c..714177e1 100644 --- a/framework/src/domain/mime/attachmentmodel.cpp +++ b/framework/src/domain/mime/attachmentmodel.cpp @@ -20,8 +20,11 @@ #include "messageparser.h" #include "mimetreeparser/interface.h" -#include #include +#include +#include +#include +#include QString sizeHuman(const Content::Ptr &content) { @@ -126,6 +129,39 @@ QVariant AttachmentModel::data(const QModelIndex &index, int role) const return QVariant(); } +bool AttachmentModel::saveAttachmentToDisk(const QModelIndex &index) +{ + if (index.internalPointer()) { + const auto entry = static_cast(index.internalPointer()); + const auto content = entry->content().at(0); + auto filename = entry->mailMime()->filename(); + auto data = content->mailMime()->decodedContent(); + + auto downloadDir = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation); + if (downloadDir.isEmpty()) { + downloadDir = "~"; + } + downloadDir += "/kube/"; + QDir{}.mkpath(downloadDir); + + auto fname = downloadDir + filename; + + if (content->mailMime()->isText() && !data.isEmpty()) { + // convert CRLF to LF before writing text attachments to disk + data = KMime::CRLFtoLF(data); + } + QFile f(fname); + if (!f.open(QIODevice::ReadWrite)) { + qWarning() << "Failed to write attachment to file:" << fname << " Error: " << f.errorString(); + return false; + } + f.write(data); + qInfo() << "Wrote attachment to file: " << fname; + return true; + } + return false; +} + QModelIndex AttachmentModel::parent(const QModelIndex &index) const { return QModelIndex(); diff --git a/framework/src/domain/mime/messageparser.h b/framework/src/domain/mime/messageparser.h index de4d8838..1f44b296 100644 --- a/framework/src/domain/mime/messageparser.h +++ b/framework/src/domain/mime/messageparser.h @@ -111,6 +111,8 @@ public: int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; + Q_INVOKABLE bool saveAttachmentToDisk(const QModelIndex &parent); + private: std::unique_ptr d; }; diff --git a/framework/src/domain/mime/mimetreeparser/interface.cpp b/framework/src/domain/mime/mimetreeparser/interface.cpp index b8556336..653789a5 100644 --- a/framework/src/domain/mime/mimetreeparser/interface.cpp +++ b/framework/src/domain/mime/mimetreeparser/interface.cpp @@ -150,6 +150,22 @@ QMimeType MailMime::mimetype() const return mimeDb.mimeTypeForName(ct->mimeType()); } +static KMime::Headers::ContentType *contentType(KMime::Content *node) +{ + if (node) { + return node->contentType(false); + } + return nullptr; +} + +bool MailMime::isText() const +{ + if (auto ct = contentType(d->mNode)) { + return ct->isText(); + } + return false; +} + MailMime::Ptr MailMime::parent() const { if (!d->parent) { diff --git a/framework/src/domain/mime/mimetreeparser/interface.h b/framework/src/domain/mime/mimetreeparser/interface.h index 7c3ea28b..05ad32b9 100644 --- a/framework/src/domain/mime/mimetreeparser/interface.h +++ b/framework/src/domain/mime/mimetreeparser/interface.h @@ -91,6 +91,7 @@ public: QByteArray cid() const; QByteArray charset() const; QString filename() const; + bool isText() const; // Unique identifier to ecactly this KMime::Content QByteArray link() const; -- cgit v1.2.3