diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2017-05-29 16:17:04 +0200 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2017-06-04 12:57:04 +0200 |
commit | e452707fdfbd61be1e5633b516b653b7337e7865 (patch) | |
tree | 1e1d4b48ebf8d381f292436f2ba04b8763edc5de /framework/src/domain/mime/attachmentmodel.cpp | |
parent | 5a1033bdace740799a6e03389bee30e5a4de5d44 (diff) | |
download | kube-e452707fdfbd61be1e5633b516b653b7337e7865.tar.gz kube-e452707fdfbd61be1e5633b516b653b7337e7865.zip |
Reduced the messagetreeparser to aproximately what we actually require
While in a much more managable state it's still not pretty.
However, further refactoring can now gradually happen as we need to do
further work on it.
Things that should happen eventually:
* Simplify the logic that creates the messageparts (we don't need the whole formatter plugin complexity)
* Get rid of the nodehelper (let the parts hold the necessary data)
* Get rid of partmetadata (let the part handleit)
Diffstat (limited to 'framework/src/domain/mime/attachmentmodel.cpp')
-rw-r--r-- | framework/src/domain/mime/attachmentmodel.cpp | 76 |
1 files changed, 46 insertions, 30 deletions
diff --git a/framework/src/domain/mime/attachmentmodel.cpp b/framework/src/domain/mime/attachmentmodel.cpp index 99745796..68180afe 100644 --- a/framework/src/domain/mime/attachmentmodel.cpp +++ b/framework/src/domain/mime/attachmentmodel.cpp | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (c) 2016 Sandro Knauß <knauss@kolabsys.com> | 2 | Copyright (c) 2016 Sandro Knauß <knauss@kolabsys.com> |
3 | Copyright (c) 2017 Christian Mollekopf <mollekopf@kolabsys.com> | ||
3 | 4 | ||
4 | This library is free software; you can redistribute it and/or modify it | 5 | This library is free software; you can redistribute it and/or modify it |
5 | under the terms of the GNU Library General Public License as published by | 6 | under the terms of the GNU Library General Public License as published by |
@@ -17,8 +18,9 @@ | |||
17 | 02110-1301, USA. | 18 | 02110-1301, USA. |
18 | */ | 19 | */ |
19 | 20 | ||
20 | #include "messageparser.h" | 21 | #include "attachmentmodel.h" |
21 | #include "mimetreeparser/interface.h" | 22 | |
23 | #include <mimetreeparser/objecttreeparser.h> | ||
22 | 24 | ||
23 | #include <QDebug> | 25 | #include <QDebug> |
24 | #include <KMime/Content> | 26 | #include <KMime/Content> |
@@ -26,47 +28,48 @@ | |||
26 | #include <QStandardPaths> | 28 | #include <QStandardPaths> |
27 | #include <QDesktopServices> | 29 | #include <QDesktopServices> |
28 | #include <QDir> | 30 | #include <QDir> |
31 | #include <QUrl> | ||
32 | #include <QMimeDatabase> | ||
29 | 33 | ||
30 | QString sizeHuman(const Content::Ptr &content) | 34 | QString sizeHuman(float size) |
31 | { | 35 | { |
32 | float num = content->content().size(); | ||
33 | QStringList list; | 36 | QStringList list; |
34 | list << "KB" << "MB" << "GB" << "TB"; | 37 | list << "KB" << "MB" << "GB" << "TB"; |
35 | 38 | ||
36 | QStringListIterator i(list); | 39 | QStringListIterator i(list); |
37 | QString unit("Bytes"); | 40 | QString unit("Bytes"); |
38 | 41 | ||
39 | while(num >= 1024.0 && i.hasNext()) | 42 | while(size >= 1024.0 && i.hasNext()) |
40 | { | 43 | { |
41 | unit = i.next(); | 44 | unit = i.next(); |
42 | num /= 1024.0; | 45 | size /= 1024.0; |
43 | } | 46 | } |
44 | 47 | ||
45 | if (unit == "Bytes") { | 48 | if (unit == "Bytes") { |
46 | return QString().setNum(num) + " " + unit; | 49 | return QString().setNum(size) + " " + unit; |
47 | } else { | 50 | } else { |
48 | return QString().setNum(num,'f',2)+" "+unit; | 51 | return QString().setNum(size,'f',2)+" "+unit; |
49 | } | 52 | } |
50 | } | 53 | } |
51 | 54 | ||
52 | class AttachmentModelPrivate | 55 | class AttachmentModelPrivate |
53 | { | 56 | { |
54 | public: | 57 | public: |
55 | AttachmentModelPrivate(AttachmentModel *q_ptr, const std::shared_ptr<Parser> &parser); | 58 | AttachmentModelPrivate(AttachmentModel *q_ptr, const std::shared_ptr<MimeTreeParser::ObjectTreeParser> &parser); |
56 | 59 | ||
57 | AttachmentModel *q; | 60 | AttachmentModel *q; |
58 | std::shared_ptr<Parser> mParser; | 61 | std::shared_ptr<MimeTreeParser::ObjectTreeParser> mParser; |
59 | QVector<Part::Ptr> mAttachments; | 62 | QVector<MimeTreeParser::MessagePartPtr> mAttachments; |
60 | }; | 63 | }; |
61 | 64 | ||
62 | AttachmentModelPrivate::AttachmentModelPrivate(AttachmentModel* q_ptr, const std::shared_ptr<Parser>& parser) | 65 | AttachmentModelPrivate::AttachmentModelPrivate(AttachmentModel* q_ptr, const std::shared_ptr<MimeTreeParser::ObjectTreeParser>& parser) |
63 | : q(q_ptr) | 66 | : q(q_ptr) |
64 | , mParser(parser) | 67 | , mParser(parser) |
65 | { | 68 | { |
66 | mAttachments = mParser->collectAttachmentParts(); | 69 | mAttachments = mParser->collectAttachmentParts(); |
67 | } | 70 | } |
68 | 71 | ||
69 | AttachmentModel::AttachmentModel(std::shared_ptr<Parser> parser) | 72 | AttachmentModel::AttachmentModel(std::shared_ptr<MimeTreeParser::ObjectTreeParser> parser) |
70 | : d(std::unique_ptr<AttachmentModelPrivate>(new AttachmentModelPrivate(this, parser))) | 73 | : d(std::unique_ptr<AttachmentModelPrivate>(new AttachmentModelPrivate(this, parser))) |
71 | { | 74 | { |
72 | } | 75 | } |
@@ -94,7 +97,7 @@ QModelIndex AttachmentModel::index(int row, int column, const QModelIndex &paren | |||
94 | } | 97 | } |
95 | 98 | ||
96 | if (row < d->mAttachments.size()) { | 99 | if (row < d->mAttachments.size()) { |
97 | return createIndex(row, column, d->mAttachments.at(row).get()); | 100 | return createIndex(row, column, d->mAttachments.at(row).data()); |
98 | } | 101 | } |
99 | return QModelIndex(); | 102 | return QModelIndex(); |
100 | } | 103 | } |
@@ -110,44 +113,57 @@ QVariant AttachmentModel::data(const QModelIndex &index, int role) const | |||
110 | } | 113 | } |
111 | 114 | ||
112 | if (index.internalPointer()) { | 115 | if (index.internalPointer()) { |
113 | const auto entry = static_cast<Part *>(index.internalPointer()); | 116 | const auto part = static_cast<MimeTreeParser::MessagePart*>(index.internalPointer()); |
114 | const auto content = entry->content().at(0); | 117 | Q_ASSERT(part); |
118 | auto node = part->node(); | ||
119 | if (!node) { | ||
120 | qWarning() << "no content for attachment"; | ||
121 | return {}; | ||
122 | } | ||
123 | QMimeDatabase mimeDb; | ||
124 | const auto mimetype = mimeDb.mimeTypeForName(QString::fromLatin1(part->mimeType())); | ||
125 | const auto content = node->encodedContent(); | ||
115 | switch(role) { | 126 | switch(role) { |
116 | case TypeRole: | 127 | case TypeRole: |
117 | return content->mailMime()->mimetype().name(); | 128 | return mimetype.name(); |
118 | case NameRole: | 129 | case NameRole: |
119 | return entry->mailMime()->filename(); | 130 | return part->filename(); |
120 | case IconRole: | 131 | case IconRole: |
121 | return content->mailMime()->mimetype().iconName(); | 132 | return mimetype.iconName(); |
122 | case SizeRole: | 133 | case SizeRole: |
123 | return sizeHuman(content); | 134 | return sizeHuman(content.size()); |
124 | case IsEncryptedRole: | 135 | case IsEncryptedRole: |
125 | return content->encryptions().size() > 0; | 136 | return part->encryptions().size() > 0; |
126 | case IsSignedRole: | 137 | case IsSignedRole: |
127 | return content->signatures().size() > 0; | 138 | return part->signatures().size() > 0; |
128 | } | 139 | } |
129 | } | 140 | } |
130 | return QVariant(); | 141 | return QVariant(); |
131 | } | 142 | } |
132 | 143 | ||
133 | static QString saveAttachmentToDisk(const QModelIndex &index, const QString &path) | 144 | static QString saveAttachmentToDisk(const QModelIndex &index, const QString &path, bool readonly = false) |
134 | { | 145 | { |
135 | if (index.internalPointer()) { | 146 | if (index.internalPointer()) { |
136 | const auto entry = static_cast<Part *>(index.internalPointer()); | 147 | const auto part = static_cast<MimeTreeParser::MessagePart*>(index.internalPointer()); |
137 | const auto content = entry->content().at(0); | 148 | Q_ASSERT(part); |
138 | auto filename = entry->mailMime()->filename(); | 149 | auto node = part->node(); |
139 | auto data = content->mailMime()->decodedContent(); | 150 | auto data = node->decodedContent(); |
140 | if (content->mailMime()->isText() && !data.isEmpty()) { | 151 | if (part->isText()) { |
141 | // convert CRLF to LF before writing text attachments to disk | 152 | // convert CRLF to LF before writing text attachments to disk |
142 | data = KMime::CRLFtoLF(data); | 153 | data = KMime::CRLFtoLF(data); |
143 | } | 154 | } |
144 | auto fname = path + filename; | 155 | auto fname = path + part->filename(); |
145 | QFile f(fname); | 156 | QFile f(fname); |
146 | if (!f.open(QIODevice::ReadWrite)) { | 157 | if (!f.open(QIODevice::ReadWrite)) { |
147 | qWarning() << "Failed to write attachment to file:" << fname << " Error: " << f.errorString(); | 158 | qWarning() << "Failed to write attachment to file:" << fname << " Error: " << f.errorString(); |
148 | return {}; | 159 | return {}; |
149 | } | 160 | } |
150 | f.write(data); | 161 | f.write(data); |
162 | if (readonly) { | ||
163 | // make file read-only so that nobody gets the impression that he migh edit attached files | ||
164 | f.setPermissions(QFileDevice::ReadUser); | ||
165 | } | ||
166 | f.close(); | ||
151 | qInfo() << "Wrote attachment to file: " << fname; | 167 | qInfo() << "Wrote attachment to file: " << fname; |
152 | return fname; | 168 | return fname; |
153 | } | 169 | } |
@@ -170,7 +186,7 @@ bool AttachmentModel::openAttachment(const QModelIndex &index) | |||
170 | { | 186 | { |
171 | auto downloadDir = QStandardPaths::writableLocation(QStandardPaths::TempLocation)+ "/kube/"; | 187 | auto downloadDir = QStandardPaths::writableLocation(QStandardPaths::TempLocation)+ "/kube/"; |
172 | QDir{}.mkpath(downloadDir); | 188 | QDir{}.mkpath(downloadDir); |
173 | const auto filePath = ::saveAttachmentToDisk(index, downloadDir); | 189 | const auto filePath = ::saveAttachmentToDisk(index, downloadDir, true); |
174 | if (!filePath.isEmpty()) { | 190 | if (!filePath.isEmpty()) { |
175 | QDesktopServices::openUrl(QUrl("file://" + filePath)); | 191 | QDesktopServices::openUrl(QUrl("file://" + filePath)); |
176 | return true; | 192 | return true; |