summaryrefslogtreecommitdiffstats
path: root/framework/src/domain/mime/mimetreeparser/mailman.cpp
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2017-05-29 16:17:04 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2017-06-04 12:57:04 +0200
commite452707fdfbd61be1e5633b516b653b7337e7865 (patch)
tree1e1d4b48ebf8d381f292436f2ba04b8763edc5de /framework/src/domain/mime/mimetreeparser/mailman.cpp
parent5a1033bdace740799a6e03389bee30e5a4de5d44 (diff)
downloadkube-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/mimetreeparser/mailman.cpp')
-rw-r--r--framework/src/domain/mime/mimetreeparser/mailman.cpp172
1 files changed, 172 insertions, 0 deletions
diff --git a/framework/src/domain/mime/mimetreeparser/mailman.cpp b/framework/src/domain/mime/mimetreeparser/mailman.cpp
new file mode 100644
index 00000000..0ef3b7ba
--- /dev/null
+++ b/framework/src/domain/mime/mimetreeparser/mailman.cpp
@@ -0,0 +1,172 @@
1/*
2 Copyright (c) 2016 Sandro Knauß <sknauss@kde.org>
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 "mailman.h"
21
22#include "utils.h"
23
24#include "objecttreeparser.h"
25#include "messagepart.h"
26
27#include <KMime/Content>
28
29#include "mimetreeparser_debug.h"
30
31using namespace MimeTreeParser;
32
33const MailmanBodyPartFormatter *MailmanBodyPartFormatter::self;
34
35const Interface::BodyPartFormatter *MailmanBodyPartFormatter::create()
36{
37 if (!self) {
38 self = new MailmanBodyPartFormatter();
39 }
40 return self;
41}
42
43bool MailmanBodyPartFormatter::isMailmanMessage(KMime::Content *curNode) const
44{
45 if (!curNode || curNode->head().isEmpty()) {
46 return false;
47 }
48 if (curNode->hasHeader("X-Mailman-Version")) {
49 return true;
50 }
51 if (KMime::Headers::Base *header = curNode->headerByType("X-Mailer")) {
52 if (header->asUnicodeString().contains(QStringLiteral("MAILMAN"), Qt::CaseInsensitive)) {
53 return true;
54 }
55 }
56 return false;
57}
58
59MessagePart::Ptr MailmanBodyPartFormatter::process(Interface::BodyPart &part) const
60{
61 KMime::Content *curNode = part.content();
62
63 if (!isMailmanMessage(curNode)) {
64 return MessagePart::Ptr();
65 }
66
67 const QString str = QString::fromLatin1(curNode->decodedContent());
68
69 //###
70 const QLatin1String delim1("--__--__--\n\nMessage:");
71 const QLatin1String delim2("--__--__--\r\n\r\nMessage:");
72 const QLatin1String delimZ2("--__--__--\n\n_____________");
73 const QLatin1String delimZ1("--__--__--\r\n\r\n_____________");
74 QString partStr, digestHeaderStr;
75 int thisDelim = str.indexOf(delim1, Qt::CaseInsensitive);
76 if (thisDelim == -1) {
77 thisDelim = str.indexOf(delim2, Qt::CaseInsensitive);
78 }
79 if (thisDelim == -1) {
80 return MessagePart::Ptr();
81 }
82
83 int nextDelim = str.indexOf(delim1, thisDelim + 1, Qt::CaseInsensitive);
84 if (-1 == nextDelim) {
85 nextDelim = str.indexOf(delim2, thisDelim + 1, Qt::CaseInsensitive);
86 }
87 if (-1 == nextDelim) {
88 nextDelim = str.indexOf(delimZ1, thisDelim + 1, Qt::CaseInsensitive);
89 }
90 if (-1 == nextDelim) {
91 nextDelim = str.indexOf(delimZ2, thisDelim + 1, Qt::CaseInsensitive);
92 }
93 if (nextDelim < 0) {
94 return MessagePart::Ptr();
95 }
96
97 //if ( curNode->mRoot )
98 // curNode = curNode->mRoot;
99
100 // at least one message found: build a mime tree
101 digestHeaderStr = QStringLiteral("Content-Type: text/plain\nContent-Description: digest header\n\n");
102 digestHeaderStr += str.midRef(0, thisDelim);
103
104 MessagePartList::Ptr mpl(new MessagePartList(part.objectTreeParser()));
105 mpl->appendSubPart(createAndParseTempNode(part, part.topLevelContent(), digestHeaderStr.toLatin1().constData(), "Digest Header"));
106 //mReader->queueHtml("<br><hr><br>");
107 // temporarily change curent node's Content-Type
108 // to get our embedded RfC822 messages properly inserted
109 curNode->contentType()->setMimeType("multipart/digest");
110 while (-1 < nextDelim) {
111 int thisEoL = str.indexOf(QLatin1String("\nMessage:"), thisDelim, Qt::CaseInsensitive);
112 if (-1 < thisEoL) {
113 thisDelim = thisEoL + 1;
114 } else {
115 thisEoL = str.indexOf(QLatin1String("\n_____________"), thisDelim, Qt::CaseInsensitive);
116 if (-1 < thisEoL) {
117 thisDelim = thisEoL + 1;
118 }
119 }
120 thisEoL = str.indexOf(QLatin1Char('\n'), thisDelim);
121 if (-1 < thisEoL) {
122 thisDelim = thisEoL + 1;
123 } else {
124 thisDelim = thisDelim + 1;
125 }
126 //while( thisDelim < cstr.size() && '\n' == cstr[thisDelim] )
127 // ++thisDelim;
128
129 partStr = QStringLiteral("Content-Type: message/rfc822\nContent-Description: embedded message\n\n");
130 partStr += str.midRef(thisDelim, nextDelim - thisDelim);
131 QString subject = QStringLiteral("embedded message");
132 QString subSearch = QStringLiteral("\nSubject:");
133 int subPos = partStr.indexOf(subSearch, 0, Qt::CaseInsensitive);
134 if (-1 < subPos) {
135 subject = partStr.mid(subPos + subSearch.length());
136 thisEoL = subject.indexOf(QLatin1Char('\n'));
137 if (-1 < thisEoL) {
138 subject.truncate(thisEoL);
139 }
140 }
141 qCDebug(MIMETREEPARSER_LOG) << " embedded message found: \"" << subject;
142 mpl->appendSubPart(createAndParseTempNode(part, part.topLevelContent(), partStr.toLatin1().constData(), subject.toLatin1().constData()));
143 //mReader->queueHtml("<br><hr><br>");
144 thisDelim = nextDelim + 1;
145 nextDelim = str.indexOf(delim1, thisDelim, Qt::CaseInsensitive);
146 if (-1 == nextDelim) {
147 nextDelim = str.indexOf(delim2, thisDelim, Qt::CaseInsensitive);
148 }
149 if (-1 == nextDelim) {
150 nextDelim = str.indexOf(delimZ1, thisDelim, Qt::CaseInsensitive);
151 }
152 if (-1 == nextDelim) {
153 nextDelim = str.indexOf(delimZ2, thisDelim, Qt::CaseInsensitive);
154 }
155 }
156 // reset curent node's Content-Type
157 curNode->contentType()->setMimeType("text/plain");
158 int thisEoL = str.indexOf(QLatin1String("_____________"), thisDelim);
159 if (-1 < thisEoL) {
160 thisDelim = thisEoL;
161 thisEoL = str.indexOf(QLatin1Char('\n'), thisDelim);
162 if (-1 < thisEoL) {
163 thisDelim = thisEoL + 1;
164 }
165 } else {
166 thisDelim = thisDelim + 1;
167 }
168 partStr = QStringLiteral("Content-Type: text/plain\nContent-Description: digest footer\n\n");
169 partStr += str.midRef(thisDelim);
170 mpl->appendSubPart(createAndParseTempNode(part, part.topLevelContent(), partStr.toLatin1().constData(), "Digest Footer"));
171 return mpl;
172}