summaryrefslogtreecommitdiffstats
path: root/framework/src/domain/messageparser_new.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/domain/messageparser_new.cpp')
-rw-r--r--framework/src/domain/messageparser_new.cpp486
1 files changed, 486 insertions, 0 deletions
diff --git a/framework/src/domain/messageparser_new.cpp b/framework/src/domain/messageparser_new.cpp
new file mode 100644
index 00000000..cb399523
--- /dev/null
+++ b/framework/src/domain/messageparser_new.cpp
@@ -0,0 +1,486 @@
1/*
2 Copyright (c) 2016 Sandro Knauß <knauss@kolabsys.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 "messageparser.h"
21#include "mimetreeparser/interface.h"
22
23#include <QDebug>
24
25Q_DECLARE_METATYPE(Part *)
26Q_DECLARE_METATYPE(Content *)
27Q_DECLARE_METATYPE(Signature *)
28Q_DECLARE_METATYPE(Encryption *)
29
30class Entry;
31
32class NewModelPrivate
33{
34public:
35 NewModelPrivate(NewModel *q_ptr, const std::shared_ptr<Parser> &parser);
36 ~NewModelPrivate();
37
38 void createTree();
39
40 QSharedPointer<QVariant> getVar(const std::shared_ptr<Signature> &sig);
41 QSharedPointer<QVariant> getVar(const std::shared_ptr<Encryption> &enc);
42 QSharedPointer<QVariant> getVar(const std::shared_ptr<Part> &part);
43 QSharedPointer<QVariant> getVar(Part *part);
44 QSharedPointer<QVariant> getVar(const std::shared_ptr<Content> &content);
45 QSharedPointer<QVariant> getVar(Content *content);
46
47 int getPos(Signature *sig);
48 int getPos(Encryption *enc);
49 int getPos(Part *part);
50 int getPos(Content *content);
51
52 NewModel *q;
53 QVector<Part::Ptr> mParts;
54 std::unique_ptr<Entry> mRoot;
55
56 std::shared_ptr<Parser> mParser;
57private:
58 QMap<std::shared_ptr<Signature>, QSharedPointer<QVariant>> mSignatureMap;
59 QMap<std::shared_ptr<Encryption>, QSharedPointer<QVariant>> mEncryptionMap;
60 QMap<Part *, QSharedPointer<QVariant>> mPartMap;
61 QMap<Content *, QSharedPointer<QVariant>> mCMap;
62};
63
64class Entry
65{
66public:
67 Entry(NewModelPrivate *model)
68 : mParent(nullptr)
69 , mNewModelPrivate(model)
70 {
71 }
72
73 ~Entry()
74 {
75 foreach(auto child, mChildren) {
76 delete child;
77 }
78 mChildren.clear();
79 }
80
81 void addChild(Entry *entry)
82 {
83 mChildren.append(entry);
84 entry->mParent = this;
85 }
86
87 Entry *addSignatures(QVector<Signature::Ptr> signatures)
88 {
89 auto ret = this;
90 foreach(const auto &sig, signatures) {
91 auto entry = new Entry(mNewModelPrivate);
92 entry->mData = mNewModelPrivate->getVar(sig);
93 ret->addChild(entry);
94 ret = entry;
95 }
96 return ret;
97 }
98
99 Entry *addEncryptions(QVector<Encryption::Ptr> encryptions)
100 {
101 auto ret = this;
102 foreach(const auto &enc, encryptions) {
103 auto entry = new Entry(mNewModelPrivate);
104 entry->mData = mNewModelPrivate->getVar(enc);
105 ret->addChild(entry);
106 ret = entry;
107 }
108 return ret;
109 }
110
111 Entry *addPart(Part *part)
112 {
113 auto entry = new Entry(mNewModelPrivate);
114 entry->mData = mNewModelPrivate->getVar(part);
115 addChild(entry);
116
117 foreach(const auto &content, part->content()) {
118 auto _entry = entry;
119 _entry = _entry->addEncryptions(content->encryptions().mid(part->encryptions().size()));
120 _entry = _entry->addSignatures(content->signatures().mid(part->signatures().size()));
121 auto c = new Entry(mNewModelPrivate);
122 c->mData = mNewModelPrivate->getVar(content);
123 _entry->addChild(c);
124 }
125// foreach(const auto &content, part->availableContents()) {
126// foreach(const auto &contentPart, part->content(content)) {
127// auto _entry = entry;
128// _entry = _entry->addEncryptions(contentPart->encryptions().mid(part->encryptions().size()));
129// _entry = _entry->addSignatures(contentPart->signatures().mid(part->signatures().size()));
130// auto c = new Entry(mNewModelPrivate);
131// c->mData = mNewModelPrivate->getVar(contentPart);
132// _entry->addChild(c);
133// }
134// }
135 foreach(const auto &sp, part->subParts()) {
136 auto _entry = entry;
137 _entry = _entry->addEncryptions(sp->encryptions().mid(part->encryptions().size()));
138 _entry = _entry->addSignatures(sp->signatures().mid(part->signatures().size()));
139 _entry->addPart(sp.get());
140 }
141 return entry;
142 }
143
144 int pos()
145 {
146 if(!mParent) {
147 return -1;
148 }
149 int i=0;
150 foreach(const auto &child, mParent->mChildren) {
151 if (child == this) {
152 return i;
153 }
154 i++;
155 }
156 return -1;
157 }
158
159 QSharedPointer<QVariant> mData;
160
161 Entry *mParent;
162 QVector<Entry *> mChildren;
163 NewModelPrivate *mNewModelPrivate;
164};
165
166
167NewModelPrivate::NewModelPrivate(NewModel *q_ptr, const std::shared_ptr<Parser> &parser)
168 : q(q_ptr)
169 , mRoot(std::unique_ptr<Entry>(new Entry(this)))
170 , mParser(parser)
171{
172 mParts = mParser->collectContentParts();
173 createTree();
174}
175
176NewModelPrivate::~NewModelPrivate()
177{
178}
179
180void NewModelPrivate::createTree()
181{
182 auto root = mRoot.get();
183 auto parent = root;
184 Part *pPart = nullptr;
185 QVector<Signature::Ptr> signatures;
186 QVector<Encryption::Ptr> encryptions;
187 foreach(const auto part, mParts) {
188 auto _parent = parent;
189 if (pPart != part->parent()) {
190 auto _parent = root;
191 _parent = _parent->addEncryptions(part->parent()->encryptions());
192 _parent = _parent->addSignatures(part->parent()->signatures());
193 signatures = part->parent()->signatures();
194 encryptions = part->parent()->encryptions();
195 parent = _parent;
196 pPart = part->parent();
197 }
198 _parent = _parent->addEncryptions(part->encryptions().mid(encryptions.size()));
199 _parent = _parent->addSignatures(part->signatures().mid(signatures.size()));
200 _parent->addPart(part.get());
201 }
202}
203
204QSharedPointer<QVariant> NewModelPrivate::getVar(const std::shared_ptr<Signature> &sig)
205{
206 if (!mSignatureMap.contains(sig)) {
207 auto var = new QVariant();
208 var->setValue(sig.get());
209 mSignatureMap.insert(sig, QSharedPointer<QVariant>(var));
210 }
211 return mSignatureMap.value(sig);
212}
213
214QSharedPointer<QVariant> NewModelPrivate::getVar(const std::shared_ptr<Encryption> &enc)
215{
216 if (!mEncryptionMap.contains(enc)) {
217 auto var = new QVariant();
218 var->setValue(enc.get());
219 mEncryptionMap.insert(enc, QSharedPointer<QVariant>(var));
220 }
221 return mEncryptionMap.value(enc);
222}
223
224QSharedPointer<QVariant> NewModelPrivate::getVar(const std::shared_ptr<Part> &part)
225{
226 return getVar(part.get());
227}
228
229QSharedPointer<QVariant> NewModelPrivate::getVar(Part *part)
230{
231 if (!mPartMap.contains(part)) {
232 auto var = new QVariant();
233 var->setValue(part);
234 mPartMap.insert(part, QSharedPointer<QVariant>(var));
235 }
236 return mPartMap.value(part);
237}
238
239QSharedPointer<QVariant> NewModelPrivate::getVar(const std::shared_ptr<Content> &content)
240{
241 return getVar(content.get());
242}
243
244QSharedPointer<QVariant> NewModelPrivate::getVar(Content *content)
245{
246 if (!mCMap.contains(content)) {
247 auto var = new QVariant();
248 var->setValue(content);
249 mCMap.insert(content, QSharedPointer<QVariant>(var));
250 }
251 return mCMap.value(content);
252}
253
254int NewModelPrivate::getPos(Signature *signature)
255{
256 const auto first = mParts.first();
257 int i = 0;
258 foreach(const auto &sig, first->signatures()) {
259 if (sig.get() == signature) {
260 break;
261 }
262 i++;
263 }
264 return i;
265}
266
267int NewModelPrivate::getPos(Encryption *encryption)
268{
269 const auto first = mParts.first();
270 int i = 0;
271 foreach(const auto &enc, first->encryptions()) {
272 if (enc.get() == encryption) {
273 break;
274 }
275 i++;
276 }
277 return i;
278}
279
280int NewModelPrivate::getPos(Part *part)
281{
282 int i = 0;
283 foreach(const auto &p, mParts) {
284 if (p.get() == part) {
285 break;
286 }
287 i++;
288 }
289 return i;
290}
291
292int NewModelPrivate::getPos(Content *content)
293{
294 int i = 0;
295 foreach(const auto &c, content->parent()->content()) {
296 if (c.get() == content) {
297 break;
298 }
299 i++;
300 }
301 return i;
302}
303
304NewModel::NewModel(std::shared_ptr<Parser> parser)
305 : d(std::unique_ptr<NewModelPrivate>(new NewModelPrivate(this, parser)))
306{
307}
308
309NewModel::~NewModel()
310{
311}
312
313QHash<int, QByteArray> NewModel::roleNames() const
314{
315 QHash<int, QByteArray> roles;
316 roles[TypeRole] = "type";
317 roles[ContentRole] = "content";
318 roles[IsEmbededRole] = "embeded";
319 roles[SecurityLevelRole] = "securityLevel";
320 roles[EncryptionErrorType] = "errorType";
321 roles[EncryptionErrorString] = "errorString";
322 return roles;
323}
324
325QModelIndex NewModel::index(int row, int column, const QModelIndex &parent) const
326{
327 if (row < 0 || column != 0) {
328 return QModelIndex();
329 }
330 Entry *entry = d->mRoot.get();
331 if (parent.isValid()) {
332 entry = static_cast<Entry *>(parent.internalPointer());
333 }
334
335 if (row < entry->mChildren.size()) {
336 return createIndex(row, column, entry->mChildren.at(row));
337 }
338 return QModelIndex();
339}
340
341QVariant NewModel::data(const QModelIndex &index, int role) const
342{
343 if (!index.isValid()) {
344 switch (role) {
345 case Qt::DisplayRole:
346 return QString("root");
347 case IsEmbededRole:
348 return false;
349 }
350 return QVariant();
351 }
352
353 if (index.internalPointer()) {
354 const auto entry = static_cast<Entry *>(index.internalPointer());
355 const auto _data = entry->mData;
356 if (entry == d->mRoot.get()|| !_data) {
357 switch (role) {
358 case Qt::DisplayRole:
359 return QString("root");
360 case IsEmbededRole:
361 return false;
362 }
363 return QVariant();
364 }
365 if (_data->userType() == qMetaTypeId<Signature *>()) {
366 const auto signature = _data->value<Signature *>();
367 int i = d->getPos(signature);
368 switch(role) {
369 case Qt::DisplayRole:
370 return QStringLiteral("Signature%1").arg(i);
371 case TypeRole:
372 return QStringLiteral("Signature");
373 case SecurityLevelRole:
374 return QStringLiteral("RED");
375 case IsEmbededRole:
376 return data(index.parent(), IsEmbededRole);
377 }
378 } else if (_data->userType() == qMetaTypeId<Encryption *>()) {
379 const auto encryption = _data->value<Encryption *>();
380 int i = d->getPos(encryption);
381 switch(role) {
382 case Qt::DisplayRole:
383 return QStringLiteral("Encryption%1").arg(i);
384 case TypeRole:
385 return QStringLiteral("Encryption");
386 case SecurityLevelRole:
387 return QStringLiteral("GREEN");
388 case IsEmbededRole:
389 return data(index.parent(), IsEmbededRole);
390 case EncryptionErrorType:
391 {
392 switch(encryption->errorType()) {
393 case Encryption::NoError:
394 return QString();
395 case Encryption::PassphraseError:
396 return QStringLiteral("PassphraseError");
397 case Encryption::KeyMissing:
398 return QStringLiteral("KeyMissing");
399 default:
400 return QStringLiteral("UnknownError");
401 }
402 }
403 case EncryptionErrorString:
404 return encryption->errorString();
405 }
406 } else if (_data->userType() == qMetaTypeId<Part *>()) {
407 const auto part = _data->value<Part *>();
408 switch (role) {
409 case Qt::DisplayRole:
410 case TypeRole:
411 return QString::fromLatin1(part->type());
412 case IsEmbededRole:
413 return data(index.parent(), IsEmbededRole);
414 }
415 } else if (_data->userType() == qMetaTypeId<Content *>()) {
416 const auto content = _data->value<Content *>();
417 int i = d->getPos(content);
418 switch(role) {
419 case Qt::DisplayRole:
420 return QStringLiteral("Content%1").arg(i);
421 case TypeRole:
422 return QString::fromLatin1(content->type());
423 case IsEmbededRole:
424 return data(index.parent(), IsEmbededRole);
425 case ContentRole: {
426 auto text = content->encodedContent();
427 if (data(index, TypeRole).toString() == "HtmlContent") {
428 const auto rx = QRegExp("(src)\\s*=\\s*(\"|')(cid:[^\"']+)\\2");
429 int pos = 0;
430 while ((pos = rx.indexIn(text, pos)) != -1) {
431 const auto link = QUrl(rx.cap(3).toUtf8());
432 pos += rx.matchedLength();
433 const auto repl = d->mParser->getPart(link);
434 if (!repl) {
435 continue;
436 }
437 const auto content = repl->content();
438 if(content.size() < 1) {
439 continue;
440 }
441 const auto mailMime = content.first()->mailMime();
442 const auto mimetype = mailMime->mimetype().name();
443 if (mimetype.startsWith("image/")) {
444 const auto data = content.first()->content();
445 text.replace(rx.cap(0), QString("src=\"data:%1;base64,%2\"").arg(mimetype, QString::fromLatin1(data.toBase64())));
446 }
447 }
448 }
449 return text;
450 }
451 }
452 }
453 }
454 return QVariant();
455}
456
457QModelIndex NewModel::parent(const QModelIndex &index) const
458{
459 if (!index.internalPointer()) {
460 return QModelIndex();
461 }
462 const auto entry = static_cast<Entry *>(index.internalPointer());
463 if (entry->mParent && entry->mParent != d->mRoot.get()) {
464 return createIndex(entry->pos(), 0, entry->mParent);
465 }
466 return QModelIndex();
467}
468
469int NewModel::rowCount(const QModelIndex &parent) const
470{
471 if (!parent.isValid()) {
472 return d->mRoot->mChildren.size();
473 } else {
474 if (!parent.internalPointer()) {
475 return 0;
476 }
477 const auto entry = static_cast<Entry *>(parent.internalPointer());
478 return entry->mChildren.size();
479 }
480 return 0;
481}
482
483int NewModel::columnCount(const QModelIndex &parent) const
484{
485 return 1;
486}