summaryrefslogtreecommitdiffstats
path: root/framework/domain
diff options
context:
space:
mode:
Diffstat (limited to 'framework/domain')
-rw-r--r--framework/domain/CMakeLists.txt2
-rw-r--r--framework/domain/mimetreeparser/CMakeLists.txt12
-rw-r--r--framework/domain/mimetreeparser/interface.cpp335
-rw-r--r--framework/domain/mimetreeparser/interface.h281
-rw-r--r--framework/domain/mimetreeparser/objecttreesource.cpp151
-rw-r--r--framework/domain/mimetreeparser/objecttreesource.h57
-rw-r--r--framework/domain/mimetreeparser/stringhtmlwriter.cpp150
-rw-r--r--framework/domain/mimetreeparser/stringhtmlwriter.h71
-rw-r--r--framework/domain/mimetreeparser/tests/CMakeLists.txt10
-rw-r--r--framework/domain/mimetreeparser/tests/data/alternative.mbox34
-rw-r--r--framework/domain/mimetreeparser/tests/data/html.mbox31
-rw-r--r--framework/domain/mimetreeparser/tests/data/htmlonly.mbox21
-rw-r--r--framework/domain/mimetreeparser/tests/data/htmlonlyexternal.mbox21
-rw-r--r--framework/domain/mimetreeparser/tests/data/plaintext.mbox17
-rw-r--r--framework/domain/mimetreeparser/tests/interfacetest.cpp47
-rw-r--r--framework/domain/mimetreeparser/thoughts.txt (renamed from framework/domain/mimetreeparser/test.cpp)24
16 files changed, 1090 insertions, 174 deletions
diff --git a/framework/domain/CMakeLists.txt b/framework/domain/CMakeLists.txt
index ea293655..92a81352 100644
--- a/framework/domain/CMakeLists.txt
+++ b/framework/domain/CMakeLists.txt
@@ -26,3 +26,5 @@ add_subdirectory(actions/tests)
26 26
27install(TARGETS mailplugin DESTINATION ${QML_INSTALL_DIR}/org/kube/framework/domain) 27install(TARGETS mailplugin DESTINATION ${QML_INSTALL_DIR}/org/kube/framework/domain)
28install(FILES qmldir DESTINATION ${QML_INSTALL_DIR}/org/kube/framework/domain) 28install(FILES qmldir DESTINATION ${QML_INSTALL_DIR}/org/kube/framework/domain)
29
30add_subdirectory(mimetreeparser) \ No newline at end of file
diff --git a/framework/domain/mimetreeparser/CMakeLists.txt b/framework/domain/mimetreeparser/CMakeLists.txt
new file mode 100644
index 00000000..e1c04893
--- /dev/null
+++ b/framework/domain/mimetreeparser/CMakeLists.txt
@@ -0,0 +1,12 @@
1set(mimetreeparser_SRCS
2 interface.cpp
3 objecttreesource.cpp
4 stringhtmlwriter.cpp
5)
6
7add_library(mimetreeparser SHARED ${mimetreeparser_SRCS})
8
9qt5_use_modules(mimetreeparser Core Gui)
10target_link_libraries(mimetreeparser KF5::Mime KF5::MimeTreeParser)
11
12add_subdirectory(tests) \ No newline at end of file
diff --git a/framework/domain/mimetreeparser/interface.cpp b/framework/domain/mimetreeparser/interface.cpp
new file mode 100644
index 00000000..6a399015
--- /dev/null
+++ b/framework/domain/mimetreeparser/interface.cpp
@@ -0,0 +1,335 @@
1/*
2 Copyright (c) 2016 Sandro Knauß <knauss@kolabsystems.com>
3
4 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 the Free Software Foundation; either version 2 of the License, or (at your
7 option) any later version.
8
9 This library is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12 License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to the
16 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 02110-1301, USA.
18*/
19
20#include "interface.h"
21
22#include "stringhtmlwriter.h"
23#include "objecttreesource.h"
24
25#include <KMime/Content>
26#include <MimeTreeParser/ObjectTreeParser>
27#include <MimeTreeParser/MessagePart>
28#include <MimeTreeParser/NodeHelper>
29
30#include <QDebug>
31#include <QImage>
32
33class PartPrivate
34{
35public:
36 PartPrivate(Part *part);
37 void appendSubPart(Part::Ptr subpart);
38
39 QVector<Part::Ptr> subParts();
40
41 const std::weak_ptr<Part> &parent() const;
42private:
43 Part *q;
44 std::weak_ptr<Part> mParent;
45 QVector<Part::Ptr> mSubParts;
46};
47
48PartPrivate::PartPrivate(Part* part)
49 :q(part)
50{
51
52}
53
54void PartPrivate::appendSubPart(Part::Ptr subpart)
55{
56 subpart->d->mParent = Part::Ptr(q);
57 mSubParts.append(subpart);
58}
59
60const std::weak_ptr<Part> &PartPrivate::parent() const
61{
62 return mParent;
63}
64
65QVector< Part::Ptr > PartPrivate::subParts()
66{
67 return mSubParts;
68}
69
70Part::Part()
71 : d(std::unique_ptr<PartPrivate>(new PartPrivate(this)))
72{
73
74}
75
76bool Part::hasSubParts() const
77{
78 return !subParts().isEmpty();
79}
80
81QVector<Part::Ptr> Part::subParts() const
82{
83 return d->subParts();
84}
85
86QByteArray Part::type() const
87{
88 return "Part";
89}
90
91QVector<Encryption> Part::encryptions() const
92{
93 auto parent = d->parent().lock();
94 if (parent) {
95 return parent->encryptions();
96 } else {
97 return QVector<Encryption>();
98 }
99}
100
101QVector<Signature> Part::signatures() const
102{
103 auto parent = d->parent().lock();
104 if (parent) {
105 return parent->signatures();
106 } else {
107 return QVector<Signature>();
108 }
109}
110
111class ContentPrivate
112{
113public:
114 QByteArray mContent;
115 QByteArray mCodec;
116 Part *mParent;
117 Content *q;
118};
119
120Content::Content(const QByteArray& content, ContentPart *parent)
121 : d(std::unique_ptr<ContentPrivate>(new ContentPrivate))
122{
123 d->q = this;
124 d->mContent = content;
125 d->mCodec = "utf-8";
126 d->mParent = parent;
127}
128
129Content::~Content()
130{
131}
132
133QVector< Encryption > Content::encryptions() const
134{
135 if (d->mParent) {
136 return d->mParent->encryptions();
137 }
138 return QVector<Encryption>();
139}
140
141QVector< Signature > Content::signatures() const
142{
143 if (d->mParent) {
144 return d->mParent->signatures();
145 }
146 return QVector<Signature>();
147}
148
149class ContentPartPrivate
150{
151public:
152 void fillFrom(MimeTreeParser::TextMessagePart::Ptr part);
153 void fillFrom(MimeTreeParser::HtmlMessagePart::Ptr part);
154 void fillFrom(MimeTreeParser::AlternativeMessagePart::Ptr part);
155
156 QVector<Content::Ptr> contents() const;
157
158 ContentPart *q;
159
160private:
161 QVector<Content::Ptr> mContents;
162 ContentPart::Types mTypes;
163};
164
165void ContentPartPrivate::fillFrom(MimeTreeParser::TextMessagePart::Ptr part)
166{
167 mTypes = ContentPart::PlainText;
168 foreach (const auto &mp, part->subParts()) {
169 auto content = std::make_shared<Content>(mp->text().toLocal8Bit(), q);
170 mContents.append(content);
171 }
172}
173
174void ContentPartPrivate::fillFrom(MimeTreeParser::HtmlMessagePart::Ptr part)
175{
176 mTypes = ContentPart::Html;
177}
178
179void ContentPartPrivate::fillFrom(MimeTreeParser::AlternativeMessagePart::Ptr part)
180{
181 mTypes = ContentPart::Html | ContentPart::PlainText;
182}
183
184ContentPart::ContentPart()
185 : d(std::unique_ptr<ContentPartPrivate>(new ContentPartPrivate))
186{
187 d->q = this;
188}
189
190ContentPart::~ContentPart()
191{
192
193}
194
195QByteArray ContentPart::type() const
196{
197 return "ContentPart";
198}
199
200class MimePartPrivate
201{
202public:
203 void fillFrom(MimeTreeParser::MessagePart::Ptr part);
204};
205
206QByteArray MimePart::type() const
207{
208 return "MimePart";
209}
210
211class AttachmentPartPrivate
212{
213public:
214 void fillFrom(MimeTreeParser::AttachmentMessagePart::Ptr part);
215};
216
217void AttachmentPartPrivate::fillFrom(MimeTreeParser::AttachmentMessagePart::Ptr part)
218{
219
220}
221
222QByteArray AttachmentPart::type() const
223{
224 return "AttachmentPart";
225}
226
227class ParserPrivate
228{
229public:
230 ParserPrivate(Parser *parser);
231
232 void setMessage(const QByteArray &mimeMessage);
233 void createTree(MimeTreeParser::MessagePart::Ptr start, Part::Ptr tree);
234
235 Part::Ptr mTree;
236private:
237 Parser *q;
238
239 MimeTreeParser::MessagePart::Ptr mPartTree;
240 std::shared_ptr<MimeTreeParser::NodeHelper> mNodeHelper;
241 QString mHtml;
242 QMap<QByteArray, QUrl> mEmbeddedPartMap;
243};
244
245ParserPrivate::ParserPrivate(Parser* parser)
246 : q(parser)
247 , mNodeHelper(std::make_shared<MimeTreeParser::NodeHelper>())
248{
249
250}
251
252void ParserPrivate::setMessage(const QByteArray& mimeMessage)
253{
254 const auto mailData = KMime::CRLFtoLF(mimeMessage);
255 KMime::Message::Ptr msg(new KMime::Message);
256 msg->setContent(mailData);
257 msg->parse();
258
259 // render the mail
260 StringHtmlWriter htmlWriter;
261 QImage paintDevice;
262 ObjectTreeSource source(&htmlWriter);
263 MimeTreeParser::ObjectTreeParser otp(&source, mNodeHelper.get());
264
265 otp.parseObjectTree(msg.data());
266 mPartTree = otp.parsedPart().dynamicCast<MimeTreeParser::MessagePart>();
267
268 mEmbeddedPartMap = htmlWriter.embeddedParts();
269 mHtml = htmlWriter.html();
270
271 mTree = std::make_shared<Part>();
272 createTree(mPartTree, mTree);
273}
274
275
276void ParserPrivate::createTree(MimeTreeParser::MessagePart::Ptr start, Part::Ptr tree)
277{
278
279 foreach (const auto &mp, start->subParts()) {
280 const auto m = mp.dynamicCast<MimeTreeParser::MessagePart>();
281 const auto text = mp.dynamicCast<MimeTreeParser::TextMessagePart>();
282 const auto alternative = mp.dynamicCast<MimeTreeParser::AlternativeMessagePart>();
283 const auto html = mp.dynamicCast<MimeTreeParser::HtmlMessagePart>();
284 const auto attachment = mp.dynamicCast<MimeTreeParser::AttachmentMessagePart>();
285 if (text) {
286 auto part = std::make_shared<ContentPart>();
287 part->d->fillFrom(text);
288 mTree->d->appendSubPart(part);
289 } else if (alternative) {
290 auto part = std::make_shared<ContentPart>();
291 part->d->fillFrom(alternative);
292 mTree->d->appendSubPart(part);
293 } else if (html) {
294 auto part = std::make_shared<ContentPart>();
295 part->d->fillFrom(html);
296 mTree->d->appendSubPart(part);
297 } else if (attachment) {
298 auto part = std::make_shared<AttachmentPart>();
299 part->d->fillFrom(attachment);
300 mTree->d->appendSubPart(part);
301 } else {
302 createTree(m, tree);
303 }
304 }
305}
306
307Parser::Parser(const QByteArray& mimeMessage)
308 :d(std::unique_ptr<ParserPrivate>(new ParserPrivate(this)))
309{
310 d->setMessage(mimeMessage);
311}
312
313Parser::~Parser()
314{
315}
316
317ContentPart::Ptr Parser::collectContentPart(const Part::Ptr &start) const
318{
319 foreach (const auto &part, start->subParts()) {
320 if (part->type() == "ContentPart") {
321 return std::dynamic_pointer_cast<ContentPart>(part);
322 } else {
323 auto ret = collectContentPart(part);
324 if (ret) {
325 return ret;
326 }
327 }
328 }
329 return ContentPart::Ptr();
330}
331
332ContentPart::Ptr Parser::collectContentPart() const
333{
334 return collectContentPart(d->mTree);
335}
diff --git a/framework/domain/mimetreeparser/interface.h b/framework/domain/mimetreeparser/interface.h
index 320030b7..82f88e73 100644
--- a/framework/domain/mimetreeparser/interface.h
+++ b/framework/domain/mimetreeparser/interface.h
@@ -19,104 +19,70 @@
19 19
20#pragma once 20#pragma once
21 21
22#include <functional>
23#include <memory>
24
25#include <QDateTime>
22#include <QUrl> 26#include <QUrl>
23#include <QMimeType> 27#include <QMimeType>
24 28
25class Part; 29class Part;
26typedef std::shared_ptr<Part> Part::Ptr; 30class PartPrivate;
27class EncryptionPart;
28typedef std::shared_ptr<Part> EncryptionPart::Ptr;
29class SignaturePart;
30typedef std::shared_ptr<Part> SignaturePart::Ptr;
31 31
32class MimePart; 32class MimePart;
33typedef std::shared_ptr<Part> MimePart::Ptr;
34class MimePartPrivate; 33class MimePartPrivate;
35 34
36class ContentPart; 35class ContentPart;
37typedef std::shared_ptr<Part> ContentPart::Ptr;
38class ContentPartPrivate; 36class ContentPartPrivate;
39 37
40class EncryptionErrorPart; 38class EncryptionPart;
41typedef std::shared_ptr<Part> EncryptionErrorPart::Ptr; 39class EncryptionPartPrivate;
42class EncryptionErrorPartPrivate;
43 40
44class AttachmentPart; 41class AttachmentPart;
45typedef std::shared_ptr<Part> AttachmentPart::Ptr;
46class AttachmentPartPrivate; 42class AttachmentPartPrivate;
47 43
48class EncapsulatedPart; 44class EncapsulatedPart;
49typedef std::shared_ptr<Part> EncapsulatedPart::Ptr; 45class EncapsulatedPartPrivate;
50class EncapsulatedPart;
51 46
52class CertPart; 47class CertPart;
53typedef std::shared_ptr<Part> CertPart::Ptr; 48class CertPartPrivate;
49
50class Content;
51class ContentPrivate;
54 52
55class Key; 53class Key;
56class Signature; 54class Signature;
57class Encryption; 55class Encryption;
58 56
59class Parser; 57class Parser;
60typedef std::shared_ptr<Parser> Parser::Ptr;
61class ParserPrivate; 58class ParserPrivate;
62 59
63class Parser
64{
65public:
66 Parser(const QByteArray &mimeMessage);
67
68 Part::Ptr getPart(QUrl url);
69
70 QVector<AttachmentPart::Ptr> collect<AttachmentPart>() const;
71 QVector<ContentPart:Ptr> collect<ContentPart>() const;
72 QVector<T::Ptr> collect<T>(Part start, std::function<bool(const Part &)> select, std::function<bool(const T::Ptr &)> filter) const;
73
74private:
75 std::unique_ptr<ParserPrivate> d;
76};
77
78
79class Part 60class Part
80{ 61{
81public: 62public:
82 virtual QByteArray type() const = 0; 63 typedef std::shared_ptr<Part> Ptr;
64 Part();
65 virtual QByteArray type() const;
83 66
84 bool hasSubParts() const; 67 bool hasSubParts() const;
85 QList<Part::Ptr> subParts() const; 68 QVector<Part::Ptr> subParts() const;
86 Part parent() const; 69 Part::Ptr parent() const;
87 70
88 virtual QVector<Signature> signatures() const; 71 virtual QVector<Signature> signatures() const;
89 virtual QVector<Encryption> encryptions() const; 72 virtual QVector<Encryption> encryptions() const;
73private:
74 std::unique_ptr<PartPrivate> d;
75 friend class ParserPrivate;
76 friend class PartPrivate;
90}; 77};
91 78
92//A structure element, that we need to reflect, that there is a Encryption starts 79class Content
93// only add a new Encrption block to encryptions block
94class EncryptionPart : public Part
95{
96public:
97 QVector<Encryption> encryptions() const Q_DECL_OVERRIDE;
98 QByteArray type() const Q_DECL_OVERRIDE;
99};
100
101// A structure element, that we need to reflect, that there is a Signature starts
102// only add a new Signature block to signature block
103// With this we can a new Singature type like pep aka
104/*
105 * add a bodypartformatter, that returns a PEPSignaturePart with all signed subparts that are signed with pep.
106 * subclass Signature aka PEPSignature to reflect different way of properties of PEPSignatures.
107 */
108class SignaturePart : public Part
109{ 80{
110public: 81public:
111 QVector<Signature> signatures() const Q_DECL_OVERRIDE; 82 typedef std::shared_ptr<Content> Ptr;
112 QByteArray type() const Q_DECL_OVERRIDE; 83 Content(const QByteArray &content, ContentPart *parent);
113}; 84 virtual ~Content();
114
115 85
116
117class TextPart : public Part
118{
119public:
120 QByteArray content() const; 86 QByteArray content() const;
121 87
122 //Use default charset 88 //Use default charset
@@ -124,14 +90,20 @@ public:
124 90
125 // overwrite default charset with given charset 91 // overwrite default charset with given charset
126 QString encodedContent(QByteArray charset) const; 92 QString encodedContent(QByteArray charset) const;
127} 93
94 virtual QVector<Signature> signatures() const;
95 virtual QVector<Encryption> encryptions() const;
96private:
97 std::unique_ptr<ContentPrivate> d;
98};
128 99
129/* 100/*
130 * A MessagePart that is based on a KMime::Content 101 * A MessagePart that is based on a KMime::Content
131 */ 102 */
132class MimePart : public TextPart 103class MimePart : public Part
133{ 104{
134public: 105public:
106 typedef std::shared_ptr<MimePart> Ptr;
135 /** 107 /**
136 * Various possible values for the "Content-Disposition" header. 108 * Various possible values for the "Content-Disposition" header.
137 */ 109 */
@@ -154,6 +126,13 @@ public:
154 // Unique identifier to ecactly this KMime::Content 126 // Unique identifier to ecactly this KMime::Content
155 QByteArray link() const; 127 QByteArray link() const;
156 128
129 QByteArray content() const;
130
131 //Use default charset
132 QString encodedContent() const;
133
134 // overwrite default charset with given charset
135 QString encodedContent(QByteArray charset) const;
157 136
158 QByteArray type() const Q_DECL_OVERRIDE; 137 QByteArray type() const Q_DECL_OVERRIDE;
159private: 138private:
@@ -171,77 +150,84 @@ private:
171 * for alternative, we are represating three messageparts 150 * for alternative, we are represating three messageparts
172 * - "headers" do we return?, we can use setType to make it possible to select and than return these headers 151 * - "headers" do we return?, we can use setType to make it possible to select and than return these headers
173 */ 152 */
174class MainContentPart : public MimePart 153class ContentPart : public Part
175{ 154{
176public: 155public:
177 enum Types { 156 typedef std::shared_ptr<ContentPart> Ptr;
178 PlainText, 157 enum Type {
179 Html 158 PlainText = 0x0001,
159 Html = 0x0002
180 }; 160 };
181 Q_DECLARE_FLAGS(Types, Type) 161 Q_DECLARE_FLAGS(Types, Type)
182 162
183 QVector<TextPart> content(Content::Type ct) const; 163 ContentPart();
164 virtual ~ContentPart();
165
166 QVector<Content> content(Type ct) const;
184 167
185 Content::Types availableContent() const; 168 Types availableContents() const;
186 169
187 QByteArray type() const Q_DECL_OVERRIDE; 170 QByteArray type() const Q_DECL_OVERRIDE;
188 171
189private: 172private:
190 std::unique_ptr<ContentPartPrivate> d; 173 std::unique_ptr<ContentPartPrivate> d;
174
175 friend class ParserPrivate;
191}; 176};
192 177
193Q_DECLARE_OPERATORS_FOR_FLAGS(ContentPart::Type) 178Q_DECLARE_OPERATORS_FOR_FLAGS(ContentPart::Types);
194 179
195class AttachmentPart : public MimePart 180class AttachmentPart : public MimePart
196{ 181{
197public: 182public:
183 typedef std::shared_ptr<AttachmentPart> Ptr;
198 QByteArray type() const Q_DECL_OVERRIDE; 184 QByteArray type() const Q_DECL_OVERRIDE;
199 185
200private: 186private:
201 std::unique_ptr<AttachmentPartPrivate> d; 187 std::unique_ptr<AttachmentPartPrivate> d;
188 friend class ParserPrivate;
202}; 189};
203 190
204/* 191/*
205 * Faild to decrypt part
206 * thigs liks this can happen:
207 * decryption in progress
208 * have not tried at all to decrypt
209 * wrong passphrase
210 * no private key
211 * cryptobackend is not configured correctly (no gpg available)
212 * -> S/Mime and PGP have different meaning in their errors
213 *
214 * Open Questions: 192 * Open Questions:
215 * - How to make the string translateable for multiple clients, so that multiple clients can show same error messages, 193 * - How to make the string translateable for multiple clients, so that multiple clients can show same error messages,
216 * that helps users to understand what is going on ? 194 * that helps users to understand what is going on ?
217 * - Does openpgp have translations already? 195 * - Does openpgp have translations already?
218 */ 196 */
219class EncryptionErrorPart : public Part 197class EncryptionError
220{ 198{
221public: 199public:
222 Error errorId() const; 200 int errorId() const;
223 201 QString errorString() const;
224 CryptoBackend cryptoBackend(); 202};
225 203
204class EncryptionPart : public MimePart
205{
206public:
207 typedef std::shared_ptr<EncryptionPart> Ptr;
226 QByteArray type() const Q_DECL_OVERRIDE; 208 QByteArray type() const Q_DECL_OVERRIDE;
227 209
210 EncryptionError error() const;
211
228private: 212private:
229 std::unique_ptr<EncryptionErrorPartPrivate> d; 213 std::unique_ptr<EncryptionPartPrivate> d;
230}; 214};
231 215
216
232/* 217/*
233 * we want to request complete headers like: 218 * we want to request complete headers like:
234 * from/to... 219 * from/to...
235 */ 220 */
236 221
237class EncapsulatedPart :: public AttachmentPart 222class EncapsulatedPart : public AttachmentPart
238{ 223{
239public: 224public:
225 typedef std::shared_ptr<EncapsulatedPart> Ptr;
240 QByteArray type() const Q_DECL_OVERRIDE; 226 QByteArray type() const Q_DECL_OVERRIDE;
241 227
242 QByteArray header<Type>(); 228 //template <class T> QByteArray header<T>();
243private: 229private:
244 std::unique_ptr<EncryptionErrorPartPrivate> d; 230 std::unique_ptr<EncapsulatedPartPrivate> d;
245}; 231};
246 232
247/* 233/*
@@ -249,64 +235,31 @@ private:
249 * checking a cert (if it is a valid cert) 235 * checking a cert (if it is a valid cert)
250 */ 236 */
251 237
252class CertPart :: public AttachmentPart 238class CertPart : public AttachmentPart
253{ 239{
254public: 240public:
241 typedef std::shared_ptr<CertPart> Ptr;
255 QByteArray type() const Q_DECL_OVERRIDE; 242 QByteArray type() const Q_DECL_OVERRIDE;
256 243
257 bool checkCert() const; 244 enum CertType {
258 Status importCert() const; 245 Pgp,
259 246 SMime
260private: 247 };
261 std::unique_ptr<CertPartPrivate> d;
262};
263
264/*
265the ggme error class
266
267// class GPGMEPP_EXPORT ErrorImportResult
268{
269public:
270 Error() : mErr(0), mMessage() {}
271 explicit Error(unsigned int e) : mErr(e), mMessage() {}
272
273 const char *source() const;
274 const char *asString() const;
275
276 int code() const;
277 int sourceID() const;
278
279 bool isCanceled() const;
280 248
281 unsigned int encodedError() const 249 enum CertSubType {
282 { 250 Public,
283 return mErr; 251 Private
284 } 252 };
285 int toErrno() const;
286 253
287 static bool hasSystemError(); 254 CertType certType() const;
288 static Error fromSystemError(unsigned int src = GPGMEPP_ERR_SOURCE_DEFAULT); 255 CertSubType certSubType() const;
289 static void setSystemError(gpg_err_code_t err); 256 int keyLength() const;
290 static void setErrno(int err);
291 static Error fromErrno(int err, unsigned int src = GPGMEPP_ERR_SOURCE_DEFAULT);
292 static Error fromCode(unsigned int err, unsigned int src = GPGMEPP_ERR_SOURCE_DEFAULT);
293 257
294 GPGMEPP_MAKE_SAFE_BOOL_OPERATOR(mErr &&!isCanceled())
295private: 258private:
296 unsigned int mErr; 259 std::unique_ptr<CertPartPrivate> d;
297 mutable std::string mMessage;
298}; 260};
299*/
300 261
301/*
302 * a used smime/PGP key
303 * in the end we also need things like:
304 bool isRevokation() const;
305 bool isInvalid() const;
306 bool isExpired() const;
307 262
308 -> so we end up wrapping GpgME::Key
309 */
310class Key 263class Key
311{ 264{
312 QString keyid() const; 265 QString keyid() const;
@@ -314,8 +267,14 @@ class Key
314 QString email() const; 267 QString email() const;
315 QString comment() const; 268 QString comment() const;
316 QVector<QString> emails() const; 269 QVector<QString> emails() const;
270 enum KeyTrust {
271 Unknown, Undefined, Never, Marginal, Full, Ultimate
272 };
317 KeyTrust keyTrust() const; 273 KeyTrust keyTrust() const;
318 CryptoBackend cryptoBackend() const; 274
275 bool isRevokation() const;
276 bool isInvalid() const;
277 bool isExpired() const;
319 278
320 std::vector<Key> subkeys(); 279 std::vector<Key> subkeys();
321 Key parentkey() const; 280 Key parentkey() const;
@@ -328,35 +287,7 @@ class Signature
328 QDateTime expirationTime() const; 287 QDateTime expirationTime() const;
329 bool neverExpires() const; 288 bool neverExpires() const;
330 289
331 bool inProgress(); //if the verfication is inProgress 290 //template <> StatusObject<SignatureVerificationResult> verify() const;
332
333 enum Validity {
334 Unknown, Undefined, Never, Marginal, Full, Ultimate
335 };
336 Validity validity() const;
337
338 // to determine if we need this in our usecase (email)
339 // GpgME::VerificationResult
340 enum Summary {
341 None = 0x000,
342 Valid = 0x001,
343 Green = 0x002,
344 Red = 0x004,
345 KeyRevoked = 0x008,
346 KeyExpired = 0x010,
347 SigExpired = 0x020,
348 KeyMissing = 0x040,
349 CrlMissing = 0x080,
350 CrlTooOld = 0x100,
351 BadPolicy = 0x200,
352 SysError = 0x400
353 };
354 Summary summary() const;
355
356 const char *policyURL() const;
357 GpgME::Notation notation(unsigned int index) const;
358 std::vector<GpgME::Notation> notations() const;
359
360}; 291};
361 292
362/* 293/*
@@ -367,4 +298,30 @@ class Signature
367class Encryption 298class Encryption
368{ 299{
369 std::vector<Key> recipients() const; 300 std::vector<Key> recipients() const;
301};
302
303class Parser
304{
305public:
306 typedef std::shared_ptr<Parser> Ptr;
307 Parser(const QByteArray &mimeMessage);
308 ~Parser();
309
310 Part::Ptr getPart(QUrl url);
311
312 //template <typename T> QVector<T::Ptr> collect<T>(Part start, std::function<bool(const Part &)> select, std::function<bool(const T::Ptr &)> filter) const;
313 QVector<AttachmentPart::Ptr> collectAttachments(Part::Ptr start, std::function<bool(const Part::Ptr &)> select, std::function<bool(const AttachmentPart::Ptr &)> filter) const;
314 ContentPart::Ptr collectContentPart(Part::Ptr start, std::function<bool(const Part::Ptr &)> select, std::function<bool(const ContentPart::Ptr &)> filter) const;
315 ContentPart::Ptr collectContentPart(const Part::Ptr& start) const;
316 ContentPart::Ptr collectContentPart() const;
317 //template <> QVector<ContentPart::Ptr> collect<ContentPart>() const;
318
319 //template <> static StatusObject<SignatureVerificationResult> verifySignature(const Signature signature) const;
320 //template <> static StatusObject<Part> decrypt(const EncryptedPart part) const;
321
322signals:
323 void partsChanged();
324
325private:
326 std::unique_ptr<ParserPrivate> d;
370}; \ No newline at end of file 327}; \ No newline at end of file
diff --git a/framework/domain/mimetreeparser/objecttreesource.cpp b/framework/domain/mimetreeparser/objecttreesource.cpp
new file mode 100644
index 00000000..12cf88ab
--- /dev/null
+++ b/framework/domain/mimetreeparser/objecttreesource.cpp
@@ -0,0 +1,151 @@
1/*
2 Copyright (C) 2009 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net
3 Copyright (c) 2009 Andras Mantia <andras@kdab.net>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18*/
19
20#include "objecttreesource.h"
21
22#include <MimeTreeParser/AttachmentStrategy>
23#include <MimeTreeParser/BodyPartFormatterBaseFactory>
24#include <MimeTreeParser/MessagePart>
25#include <MimeTreeParser/MessagePartRenderer>
26
27class ObjectSourcePrivate
28{
29public:
30 ObjectSourcePrivate()
31 : mWriter(0)
32 , mAllowDecryption(true)
33 , mHtmlLoadExternal(true)
34 , mHtmlMail(true)
35 {
36
37 }
38 MimeTreeParser::HtmlWriter *mWriter;
39 MimeTreeParser::BodyPartFormatterBaseFactory mBodyPartFormatterBaseFactory;
40 bool mAllowDecryption;
41 bool mHtmlLoadExternal;
42 bool mHtmlMail;
43};
44
45ObjectTreeSource::ObjectTreeSource(MimeTreeParser::HtmlWriter *writer)
46 : MimeTreeParser::Interface::ObjectTreeSource()
47 , d(new ObjectSourcePrivate)
48 {
49 d->mWriter = writer;
50 }
51
52ObjectTreeSource::~ObjectTreeSource()
53{
54 delete d;
55}
56
57void ObjectTreeSource::setAllowDecryption(bool allowDecryption)
58{
59 d->mAllowDecryption = allowDecryption;
60}
61
62MimeTreeParser::HtmlWriter *ObjectTreeSource::htmlWriter()
63{
64 return d->mWriter;
65}
66
67bool ObjectTreeSource::htmlLoadExternal() const
68{
69 return d->mHtmlLoadExternal;
70}
71
72void ObjectTreeSource::setHtmlLoadExternal(bool loadExternal)
73{
74 d->mHtmlLoadExternal = loadExternal;
75}
76
77bool ObjectTreeSource::htmlMail() const
78{
79 return d->mHtmlMail;
80}
81
82void ObjectTreeSource::setHtmlMail(bool htmlMail)
83{
84 d->mHtmlMail = htmlMail;
85}
86
87bool ObjectTreeSource::decryptMessage() const
88{
89 return d->mAllowDecryption;
90}
91
92bool ObjectTreeSource::showSignatureDetails() const
93{
94 return true;
95}
96
97int ObjectTreeSource::levelQuote() const
98{
99 return 1;
100}
101
102const QTextCodec *ObjectTreeSource::overrideCodec()
103{
104 return Q_NULLPTR;
105}
106
107QString ObjectTreeSource::createMessageHeader(KMime::Message *message)
108{
109 return QString();
110}
111
112const MimeTreeParser::AttachmentStrategy *ObjectTreeSource::attachmentStrategy()
113{
114 return MimeTreeParser::AttachmentStrategy::smart();
115}
116
117QObject *ObjectTreeSource::sourceObject()
118{
119 return Q_NULLPTR;
120}
121
122void ObjectTreeSource::setHtmlMode(MimeTreeParser::Util::HtmlMode mode)
123{
124 Q_UNUSED(mode);
125}
126
127bool ObjectTreeSource::autoImportKeys() const
128{
129 return false;
130}
131
132bool ObjectTreeSource::showEmoticons() const
133{
134 return false;
135}
136
137bool ObjectTreeSource::showExpandQuotesMark() const
138{
139 return false;
140}
141
142const MimeTreeParser::BodyPartFormatterBaseFactory *ObjectTreeSource::bodyPartFormatterFactory()
143{
144 return &(d->mBodyPartFormatterBaseFactory);
145}
146
147MimeTreeParser::Interface::MessagePartRenderer::Ptr ObjectTreeSource::messagePartTheme(MimeTreeParser::Interface::MessagePart::Ptr msgPart)
148{
149 Q_UNUSED(msgPart);
150 return MimeTreeParser::Interface::MessagePartRenderer::Ptr();
151}
diff --git a/framework/domain/mimetreeparser/objecttreesource.h b/framework/domain/mimetreeparser/objecttreesource.h
new file mode 100644
index 00000000..bb0cd679
--- /dev/null
+++ b/framework/domain/mimetreeparser/objecttreesource.h
@@ -0,0 +1,57 @@
1/*
2 Copyright (C) 2009 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net
3 Copyright (c) 2009 Andras Mantia <andras@kdab.net>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18*/
19
20#ifndef MAILVIEWER_OBJECTTREEEMPTYSOURCE_H
21#define MAILVIEWER_OBJECTTREEEMPTYSOURCE_H
22
23#include <MimeTreeParser/ObjectTreeSource>
24
25class QString;
26
27class ObjectSourcePrivate;
28class ObjectTreeSource : public MimeTreeParser::Interface::ObjectTreeSource
29{
30public:
31 ObjectTreeSource(MimeTreeParser::HtmlWriter *writer);
32 virtual ~ObjectTreeSource();
33 void setHtmlLoadExternal(bool loadExternal);
34 void setHtmlMail(bool htmlMail);
35 bool htmlMail() const Q_DECL_OVERRIDE;
36 bool decryptMessage() const Q_DECL_OVERRIDE;
37 bool htmlLoadExternal() const Q_DECL_OVERRIDE;
38 bool showSignatureDetails() const Q_DECL_OVERRIDE;
39 void setHtmlMode(MimeTreeParser::Util::HtmlMode mode) Q_DECL_OVERRIDE;
40 void setAllowDecryption(bool allowDecryption);
41 int levelQuote() const Q_DECL_OVERRIDE;
42 const QTextCodec *overrideCodec() Q_DECL_OVERRIDE;
43 QString createMessageHeader(KMime::Message *message) Q_DECL_OVERRIDE;
44 const MimeTreeParser::AttachmentStrategy *attachmentStrategy() Q_DECL_OVERRIDE;
45 MimeTreeParser::HtmlWriter *htmlWriter() Q_DECL_OVERRIDE;
46 QObject *sourceObject() Q_DECL_OVERRIDE;
47 bool autoImportKeys() const Q_DECL_OVERRIDE;
48 bool showEmoticons() const Q_DECL_OVERRIDE;
49 bool showExpandQuotesMark() const Q_DECL_OVERRIDE;
50 const MimeTreeParser::BodyPartFormatterBaseFactory *bodyPartFormatterFactory() Q_DECL_OVERRIDE;
51 MimeTreeParser::Interface::MessagePartRendererPtr messagePartTheme(MimeTreeParser::Interface::MessagePartPtr msgPart) Q_DECL_OVERRIDE;
52private:
53 ObjectSourcePrivate *const d;
54};
55
56#endif
57
diff --git a/framework/domain/mimetreeparser/stringhtmlwriter.cpp b/framework/domain/mimetreeparser/stringhtmlwriter.cpp
new file mode 100644
index 00000000..88034492
--- /dev/null
+++ b/framework/domain/mimetreeparser/stringhtmlwriter.cpp
@@ -0,0 +1,150 @@
1/* -*- c++ -*-
2 filehtmlwriter.cpp
3
4 This file is part of KMail, the KDE mail client.
5 Copyright (c) 2003 Marc Mutz <mutz@kde.org>
6
7 KMail is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License, version 2, as
9 published by the Free Software Foundation.
10
11 KMail is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
20 In addition, as a special exception, the copyright holders give
21 permission to link the code of this program with any edition of
22 the Qt library by Trolltech AS, Norway (or with modified versions
23 of Qt that use the same license as Qt), and distribute linked
24 combinations including the two. You must obey the GNU General
25 Public License in all respects for all of the code used other than
26 Qt. If you modify this file, you may extend this exception to
27 your version of the file, but you are not obligated to do so. If
28 you do not wish to do so, delete this exception statement from
29 your version.
30*/
31
32#include "stringhtmlwriter.h"
33
34#include <QDebug>
35#include <QTextStream>
36#include <QUrl>
37
38StringHtmlWriter::StringHtmlWriter()
39 : MimeTreeParser::HtmlWriter()
40 , mState(Ended)
41{
42}
43
44StringHtmlWriter::~StringHtmlWriter()
45{
46}
47
48void StringHtmlWriter::begin(const QString &css)
49{
50 if (mState != Ended) {
51 qWarning() << "begin() called on non-ended session!";
52 reset();
53 }
54
55 mState = Begun;
56 mExtraHead.clear();
57 mHtml.clear();
58
59 if (!css.isEmpty()) {
60 write(QLatin1String("<!-- CSS Definitions \n") + css + QLatin1String("-->\n"));
61 }
62}
63
64void StringHtmlWriter::end()
65{
66 if (mState != Begun) {
67 qWarning() << "Called on non-begun or queued session!";
68 }
69
70 if (!mExtraHead.isEmpty()) {
71 insertExtraHead();
72 mExtraHead.clear();
73 }
74 resolveCidUrls();
75 mState = Ended;
76}
77
78void StringHtmlWriter::reset()
79{
80 if (mState != Ended) {
81 mHtml.clear();
82 mExtraHead.clear();
83 mState = Begun; // don't run into end()'s warning
84 end();
85 mState = Ended;
86 }
87}
88
89void StringHtmlWriter::write(const QString &str)
90{
91 if (mState != Begun) {
92 qWarning() << "Called in Ended or Queued state!";
93 }
94 mHtml.append(str);
95}
96
97void StringHtmlWriter::queue(const QString &str)
98{
99 write(str);
100}
101
102void StringHtmlWriter::flush()
103{
104 mState = Begun; // don't run into end()'s warning
105 end();
106}
107
108void StringHtmlWriter::embedPart(const QByteArray &contentId, const QString &url)
109{
110 write("<!-- embedPart(contentID=" + contentId + ", url=" + url + ") -->\n");
111 mEmbeddedPartMap.insert(contentId, url);
112}
113
114void StringHtmlWriter::resolveCidUrls()
115{
116 for (const auto &cid : mEmbeddedPartMap.keys()) {
117 mHtml.replace(QString("src=\"cid:%1\"").arg(QString(cid)), QString("src=\"%1\"").arg(mEmbeddedPartMap.value(cid).toString()));
118 }
119}
120
121void StringHtmlWriter::extraHead(const QString &extraHead)
122{
123 if (mState != Ended) {
124 qWarning() << "Called on non-started session!";
125 }
126 mExtraHead.append(extraHead);
127}
128
129
130void StringHtmlWriter::insertExtraHead()
131{
132 const QString headTag(QStringLiteral("<head>"));
133 const int index = mHtml.indexOf(headTag);
134 if (index != -1) {
135 mHtml.insert(index + headTag.length(), mExtraHead);
136 }
137}
138
139QMap<QByteArray, QUrl> StringHtmlWriter::embeddedParts() const
140{
141 return mEmbeddedPartMap;
142}
143
144QString StringHtmlWriter::html() const
145{
146 if (mState != Ended) {
147 qWarning() << "Called on non-ended session!";
148 }
149 return mHtml;
150}
diff --git a/framework/domain/mimetreeparser/stringhtmlwriter.h b/framework/domain/mimetreeparser/stringhtmlwriter.h
new file mode 100644
index 00000000..fa5b760e
--- /dev/null
+++ b/framework/domain/mimetreeparser/stringhtmlwriter.h
@@ -0,0 +1,71 @@
1/* -*- c++ -*-
2
3 Copyright (c) 2016 Sandro Knauß <sknauss@kde.org>
4
5 Kube is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License, version 2, as
7 published by the Free Software Foundation.
8
9 Kube is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
18 In addition, as a special exception, the copyright holders give
19 permission to link the code of this program with any edition of
20 the Qt library by Trolltech AS, Norway (or with modified versions
21 of Qt that use the same license as Qt), and distribute linked
22 combinations including the two. You must obey the GNU General
23 Public License in all respects for all of the code used other than
24 Qt. If you modify this file, you may extend this exception to
25 your version of the file, but you are not obligated to do so. If
26 you do not wish to do so, delete this exception statement from
27 your version.
28*/
29
30#ifndef __KUBE_FRAMEWORK_MAIL_STRINGHTMLWRITER_H__
31#define __KUBE_FRAMEWORK_MAIL_STRINGHTMLWRITER_H__
32
33#include <MimeTreeParser/HtmlWriter>
34
35#include <QFile>
36#include <QTextStream>
37
38class QString;
39
40class StringHtmlWriter : public MimeTreeParser::HtmlWriter
41{
42public:
43 explicit StringHtmlWriter();
44 virtual ~StringHtmlWriter();
45
46 void begin(const QString &cssDefs) Q_DECL_OVERRIDE;
47 void end() Q_DECL_OVERRIDE;
48 void reset() Q_DECL_OVERRIDE;
49 void write(const QString &str) Q_DECL_OVERRIDE;
50 void queue(const QString &str) Q_DECL_OVERRIDE;
51 void flush() Q_DECL_OVERRIDE;
52 void embedPart(const QByteArray &contentId, const QString &url) Q_DECL_OVERRIDE;
53 void extraHead(const QString &str) Q_DECL_OVERRIDE;
54
55 QString html() const;
56 QMap<QByteArray, QUrl> embeddedParts() const;
57private:
58 void insertExtraHead();
59 void resolveCidUrls();
60
61 QString mHtml;
62 QString mExtraHead;
63 enum State {
64 Begun,
65 Queued,
66 Ended
67 } mState;
68 QMap<QByteArray, QUrl> mEmbeddedPartMap;
69};
70
71#endif // __MESSAGEVIEWER_FILEHTMLWRITER_H__
diff --git a/framework/domain/mimetreeparser/tests/CMakeLists.txt b/framework/domain/mimetreeparser/tests/CMakeLists.txt
new file mode 100644
index 00000000..d3549215
--- /dev/null
+++ b/framework/domain/mimetreeparser/tests/CMakeLists.txt
@@ -0,0 +1,10 @@
1add_definitions( -DMAIL_DATA_DIR="${CMAKE_CURRENT_SOURCE_DIR}/data" )
2include_directories(
3 ${CMAKE_CURRENT_BINARY_DIR}
4 ${CMAKE_CURRENT_SOURCE_DIR}/..
5 )
6
7add_executable(mimetreeparsertest interfacetest.cpp)
8add_test(mimetreeparsertest mimetreeparsertest)
9qt5_use_modules(mimetreeparsertest Core Test)
10target_link_libraries(mimetreeparsertest mimetreeparser) \ No newline at end of file
diff --git a/framework/domain/mimetreeparser/tests/data/alternative.mbox b/framework/domain/mimetreeparser/tests/data/alternative.mbox
new file mode 100644
index 00000000..a2c58591
--- /dev/null
+++ b/framework/domain/mimetreeparser/tests/data/alternative.mbox
@@ -0,0 +1,34 @@
1Return-Path: <konqi@example.org>
2Date: Wed, 8 Jun 2016 20:34:44 -0700
3From: Konqi <konqi@example.org>
4To: konqi@kde.org
5Subject: A random subject with alternative contenttype
6MIME-Version: 1.0
7Content-Type: multipart/alternative;
8 boundary="----=_Part_12345678_12345678"
9
10
11------=_Part_12345678_12345678
12Content-Type: text/plain; charset=utf-8
13Content-Transfer-Encoding: quoted-printable
14
15If you can see this text it means that your email client couldn't display o=
16ur newsletter properly.
17Please visit this link to view the newsletter on our website: http://www.go=
18g.com/newsletter/
19
20=2D GOG.com Team
21
22
23------=_Part_12345678_12345678
24Content-Transfer-Encoding: 7Bit
25Content-Type: text/html; charset="windows-1252"
26
27<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
28<html><head><meta name="qrichtext" content="1" /><style type="text/css">
29p, li { white-space: pre-wrap; }
30</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;">
31<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; -qt-user-state:0;">Some <span style=" font-weight:600;">HTML</span> text</p></body></html>
32
33
34------=_Part_12345678_12345678--
diff --git a/framework/domain/mimetreeparser/tests/data/html.mbox b/framework/domain/mimetreeparser/tests/data/html.mbox
new file mode 100644
index 00000000..eebd4283
--- /dev/null
+++ b/framework/domain/mimetreeparser/tests/data/html.mbox
@@ -0,0 +1,31 @@
1From foo@example.com Thu, 26 May 2011 01:16:54 +0100
2From: Thomas McGuire <foo@example.com>
3Subject: HTML test
4Date: Thu, 26 May 2011 01:16:54 +0100
5Message-ID: <1501334.pROlBb7MZF@herrwackelpudding.localhost>
6X-KMail-Transport: GMX
7X-KMail-Fcc: 28
8X-KMail-Drafts: 7
9X-KMail-Templates: 9
10User-Agent: KMail/4.6 beta5 (Linux/2.6.34.7-0.7-desktop; KDE/4.6.41; x86_64; git-0269848; 2011-04-19)
11MIME-Version: 1.0
12Content-Type: multipart/alternative; boundary="nextPart8606278.tpV19BTJKu"
13Content-Transfer-Encoding: 7Bit
14
15
16--nextPart8606278.tpV19BTJKu
17Content-Transfer-Encoding: 7Bit
18Content-Type: text/plain; charset="windows-1252"
19
20Some HTML text
21--nextPart8606278.tpV19BTJKu
22Content-Transfer-Encoding: 7Bit
23Content-Type: text/html; charset="windows-1252"
24
25<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
26<html><head><meta name="qrichtext" content="1" /><style type="text/css">
27p, li { white-space: pre-wrap; }
28</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;">
29<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; -qt-user-state:0;">Some <span style=" font-weight:600;">HTML</span> text</p></body></html>
30--nextPart8606278.tpV19BTJKu--
31
diff --git a/framework/domain/mimetreeparser/tests/data/htmlonly.mbox b/framework/domain/mimetreeparser/tests/data/htmlonly.mbox
new file mode 100644
index 00000000..e45b1c4d
--- /dev/null
+++ b/framework/domain/mimetreeparser/tests/data/htmlonly.mbox
@@ -0,0 +1,21 @@
1From foo@example.com Thu, 26 May 2011 01:16:54 +0100
2From: Thomas McGuire <foo@example.com>
3Subject: HTML test
4Date: Thu, 26 May 2011 01:16:54 +0100
5Message-ID: <1501334.pROlBb7MZF@herrwackelpudding.localhost>
6X-KMail-Transport: GMX
7X-KMail-Fcc: 28
8X-KMail-Drafts: 7
9X-KMail-Templates: 9
10User-Agent: KMail/4.6 beta5 (Linux/2.6.34.7-0.7-desktop; KDE/4.6.41; x86_64; git-0269848; 2011-04-19)
11MIME-Version: 1.0
12Content-Type: text/html
13Content-Transfer-Encoding: 7Bit
14
15<html>
16<head>
17</head>
18<body>
19<b>SOME</b> HTML text.
20</body>
21</html>
diff --git a/framework/domain/mimetreeparser/tests/data/htmlonlyexternal.mbox b/framework/domain/mimetreeparser/tests/data/htmlonlyexternal.mbox
new file mode 100644
index 00000000..4eb3e2c3
--- /dev/null
+++ b/framework/domain/mimetreeparser/tests/data/htmlonlyexternal.mbox
@@ -0,0 +1,21 @@
1From foo@example.com Thu, 26 May 2011 01:16:54 +0100
2From: Thomas McGuire <foo@example.com>
3Subject: HTML test
4Date: Thu, 26 May 2011 01:16:54 +0100
5Message-ID: <1501334.pROlBb7MZF@herrwackelpudding.localhost>
6X-KMail-Transport: GMX
7X-KMail-Fcc: 28
8X-KMail-Drafts: 7
9X-KMail-Templates: 9
10User-Agent: KMail/4.6 beta5 (Linux/2.6.34.7-0.7-desktop; KDE/4.6.41; x86_64; git-0269848; 2011-04-19)
11MIME-Version: 1.0
12Content-Type: text/html
13Content-Transfer-Encoding: 7Bit
14
15<html>
16<head>
17</head>
18<body>
19<b>SOME</b> HTML text. <img src="http://example.org/test.img" >
20</body>
21</html>
diff --git a/framework/domain/mimetreeparser/tests/data/plaintext.mbox b/framework/domain/mimetreeparser/tests/data/plaintext.mbox
new file mode 100644
index 00000000..c2e00a35
--- /dev/null
+++ b/framework/domain/mimetreeparser/tests/data/plaintext.mbox
@@ -0,0 +1,17 @@
1Return-Path: <konqi@example.org>
2Date: Wed, 8 Jun 2016 20:34:44 -0700
3From: Konqi <konqi@example.org>
4To: konqi@kde.org
5Subject: A random subject with alternative contenttype
6MIME-Version: 1.0
7Content-Type: text/plain; charset=utf-8
8Content-Transfer-Encoding: quoted-printable
9
10If you can see this text it means that your email client couldn't display o=
11ur newsletter properly.
12Please visit this link to view the newsletter on our website: http://www.go=
13g.com/newsletter/
14
15=2D GOG.com Team
16
17
diff --git a/framework/domain/mimetreeparser/tests/interfacetest.cpp b/framework/domain/mimetreeparser/tests/interfacetest.cpp
new file mode 100644
index 00000000..1e8c5302
--- /dev/null
+++ b/framework/domain/mimetreeparser/tests/interfacetest.cpp
@@ -0,0 +1,47 @@
1/*
2 Copyright (c) 2016 Sandro Knauß <knauss@kolabsystems.com>
3
4 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 the Free Software Foundation; either version 2 of the License, or (at your
7 option) any later version.
8
9 This library is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12 License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to the
16 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 02110-1301, USA.
18*/
19
20#include "interface.h"
21
22#include <QTest>
23
24QByteArray readMailFromFile(const QString &mailFile)
25{
26 QFile file(QLatin1String(MAIL_DATA_DIR) + QLatin1Char('/') + mailFile);
27 file.open(QIODevice::ReadOnly);
28 Q_ASSERT(file.isOpen());
29 return file.readAll();
30}
31
32
33class InterfaceTest : public QObject
34{
35 Q_OBJECT
36private slots:
37
38 void testTextMail()
39 {
40 Parser parser(readMailFromFile("plaintext.mbox"));
41 auto contentPart = parser.collectContentPart();
42 //QVERIFY((bool)contentPart);
43 }
44};
45
46QTEST_GUILESS_MAIN(InterfaceTest)
47#include "interfacetest.moc" \ No newline at end of file
diff --git a/framework/domain/mimetreeparser/test.cpp b/framework/domain/mimetreeparser/thoughts.txt
index 51aa9871..3340347a 100644
--- a/framework/domain/mimetreeparser/test.cpp
+++ b/framework/domain/mimetreeparser/thoughts.txt
@@ -23,26 +23,26 @@ ap1 == getPart("cid:12345678")
23(Html) == cp1.availableContent() 23(Html) == cp1.availableContent()
24 24
25# alternative msg + attachment 25# alternative msg + attachment
26* ContentPart(html=[TextPart("HTML"),], plaintext=[TextPart("Text"),]) => cp1 26* ContentPart(html=[Content("HTML"),], plaintext=[Content("Text"),]) => cp1
27* AttachmentPart => ap1 27* AttachmentPart => ap1
28 28
29(cp1) == collect<ContentPart>(select=NoEncapsulatedMessages) 29(cp1) == collect<ContentPart>(select=NoEncapsulatedMessages)
30(ap1) == collect<AttachmentParts>(select=NoEncapsulatedMessages) 30(ap1) == collect<AttachmentParts>(select=NoEncapsulatedMessages)
31 31
32(Html, PlainText) == cp1.availableContent() 32(Html, PlainText) == cp1.availableContent()
33[TextPart("HTML"),] == cp1.content(Html) 33[Content("HTML"),] == cp1.content(Html)
34[TextPart("Text"),] == cp1.content(Plaintext) 34[Content("Text"),] == cp1.content(Plaintext)
35 35
36# alternative msg with GPGInlin 36# alternative msg with GPGInlin
37* ContentPart( 37* ContentPart(
38 plaintext=[TextPart("Text"), TextPart("foo", encryption=(enc1))], 38 plaintext=[Content("Text"), Content("foo", encryption=(enc1))],
39 html=[TextPart("HTML"),] 39 html=[Content("HTML"),]
40 ) => cp1 40 ) => cp1
41 41
42(Html, PlainText) == cp1.availableContent() 42(Html, PlainText) == cp1.availableContent()
43 43
44[TextPart("HTML"),] == cp1.content(Html) 44[Content("HTML"),] == cp1.content(Html)
45[TextPart("Text"),TextPart("foo", encryption=(enc1))] == cp1.content(Plaintext) 45[Content("Text"),Content("foo", encryption=(enc1))] == cp1.content(Plaintext)
46 46
47 47
48# encrypted msg (not encrypted/error) with unencrypted attachment 48# encrypted msg (not encrypted/error) with unencrypted attachment
@@ -63,13 +63,13 @@ ap1 == getPart("cid:12345678")
63 63
64#INLINE GPG encrypted msg + attachment 64#INLINE GPG encrypted msg + attachment
65* ContentPart => cp1 with 65* ContentPart => cp1 with
66 plaintext=[TextPart, TextPart(encrytion = (enc1(rec1,rec2),)), TextPart(signed = (sig1,)), TextPart] 66 plaintext=[Content, Content(encrytion = (enc1(rec1,rec2),)), Content(signed = (sig1,)), Content]
67* AttachmentPart => ap1 67* AttachmentPart => ap1
68 68
69(cp1) == collect<ContentPart>(select=NoEncapsulatedMessages) 69(cp1) == collect<ContentPart>(select=NoEncapsulatedMessages)
70(ap1) == collect<AttachmentParts>(select=NoEncapsulatedMessages) 70(ap1) == collect<AttachmentParts>(select=NoEncapsulatedMessages)
71 71
72[TextPart, TextPart(encrytion = (enc1(rec1,rec2),)), TextPart(signed = (sig1,)), TextPart] == cp1.content(Plaintext) 72[Content, Content(encrytion = (enc1(rec1,rec2),)), Content(signed = (sig1,)), Content] == cp1.content(Plaintext)
73 73
74#forwared encrypted msg + attachments 74#forwared encrypted msg + attachments
75* ContentPart => cp1 75* ContentPart => cp1
@@ -77,8 +77,8 @@ ap1 == getPart("cid:12345678")
77 * Encrytion=(rec1,rec2) => enc1 77 * Encrytion=(rec1,rec2) => enc1
78 * Signature => sig1 78 * Signature => sig1
79 * ContentPart(encrytion = (enc1,), signature = (sig1,)) => cp2 79 * ContentPart(encrytion = (enc1,), signature = (sig1,)) => cp2
80 * TextPart(encrytion = (enc1,), signature = (sig1,)) 80 * Content(encrytion = (enc1,), signature = (sig1,))
81 * TextPart(encrytion = (enc1, enc2(rec3,rec4),), signature = (sig1,)) 81 * Content(encrytion = (enc1, enc2(rec3,rec4),), signature = (sig1,))
82 * AttachmentPart(encrytion = (enc1,), signature = (sig1,)) => ap1 82 * AttachmentPart(encrytion = (enc1,), signature = (sig1,)) => ap1
83* AttachmentPart => ap2 83* AttachmentPart => ap2
84 84
@@ -89,7 +89,7 @@ ap1 == getPart("cid:12345678")
89(ap1) = collect<AttachmentParts>(ep1, select=NoEncapsulatedMessages) 89(ap1) = collect<AttachmentParts>(ep1, select=NoEncapsulatedMessages)
90 90
91(cp1, cp2) == collect<ContentPart>() 91(cp1, cp2) == collect<ContentPart>()
92(ap1, ap2) == collect<AttachmentParts>()[TextPart, TextPart(encrytion = (enc1(rec1,rec2),)), TextPart(signed = (sig1,)), TextPart] 92(ap1, ap2) == collect<AttachmentParts>()[Content, Content(encrytion = (enc1(rec1,rec2),)), Content(signed = (sig1,)), Content]
93 93
94 94
95# plaintext msg + attachment + cert 95# plaintext msg + attachment + cert