Commit fcaa3f62 authored by Sandro Knauß's avatar Sandro Knauß

Move MailmanBodyPart to own file

parent 9ff7e96e
......@@ -9,6 +9,7 @@ add_definitions(-DTRANSLATION_DOMAIN=\"libmimetreeparser\")
include_directories(${GPGME_INCLUDES})
set(libmimetreeparser_main_SRCS
bodyformatter/mailman.cpp
interfaces/bodypartformatter.cpp
job/kleojobexecutor.cpp
viewer/attachmentstrategy.cpp
......
/*
Copyright (c) 2016 Sandro Knauß <sknauss@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#include "mailman.h"
#include "viewer/objecttreeparser.h"
#include "viewer/messagepart.h"
#include <KMime/Content>
#include "mimetreeparser_debug.h"
using namespace MessageViewer;
const MailmanBodyPartFormatter *MailmanBodyPartFormatter::self;
const Interface::BodyPartFormatter *MailmanBodyPartFormatter::create() {
if ( !self ) {
self = new MailmanBodyPartFormatter();
}
return self;
}
Interface::BodyPartFormatter::Result MailmanBodyPartFormatter::format(Interface::BodyPart *part, HtmlWriter *writer) const {
Q_UNUSED(writer)
const auto p = process(*part);
const auto mp = static_cast<MessagePart *>(p.data());
if (mp) {
mp->html(false);
return Ok;
}
return Failed;
}
/**
1. Create a new partNode using 'content' data and Content-Description
found in 'cntDesc'.
2. Parse the 'node' to display the content.
*/
MimeMessagePart::Ptr createAndParseTempNode(Interface::BodyPart &part, KMime::Content *parentNode, const char *content, const char *cntDesc)
{
KMime::Content *newNode = new KMime::Content();
newNode->setContent(KMime::CRLFtoLF(content));
newNode->parse();
if (!newNode->head().isEmpty()) {
newNode->contentDescription()->from7BitString(cntDesc);
}
part.nodeHelper()->attachExtraContent(parentNode, newNode);
return MimeMessagePart::Ptr(new MimeMessagePart(part.objectTreeParser(), newNode, false));
}
bool MailmanBodyPartFormatter::isMailmanMessage(KMime::Content* curNode) const
{
if (!curNode || curNode->head().isEmpty()) {
return false;
}
if (curNode->hasHeader("X-Mailman-Version")) {
return true;
}
if (curNode->hasHeader("X-Mailer")) {
KMime::Headers::Base *header = curNode->headerByType("X-Mailer");
if (header->asUnicodeString().contains(QStringLiteral("MAILMAN"), Qt::CaseInsensitive)) {
return true;
}
}
return false;
}
Interface::MessagePart::Ptr MailmanBodyPartFormatter::process(Interface::BodyPart &part) const
{
KMime::Content *curNode = part.content();
if (!isMailmanMessage(curNode)) {
return MessagePart::Ptr();
}
const QString str = QString::fromLatin1(curNode->decodedContent());
//###
const QLatin1String delim1("--__--__--\n\nMessage:");
const QLatin1String delim2("--__--__--\r\n\r\nMessage:");
const QLatin1String delimZ2("--__--__--\n\n_____________");
const QLatin1String delimZ1("--__--__--\r\n\r\n_____________");
QString partStr, digestHeaderStr;
int thisDelim = str.indexOf(delim1, Qt::CaseInsensitive);
if (thisDelim == -1) {
thisDelim = str.indexOf(delim2, Qt::CaseInsensitive);
}
if (thisDelim == -1) {
return MessagePart::Ptr();
}
int nextDelim = str.indexOf(delim1, thisDelim + 1, Qt::CaseInsensitive);
if (-1 == nextDelim) {
nextDelim = str.indexOf(delim2, thisDelim + 1, Qt::CaseInsensitive);
}
if (-1 == nextDelim) {
nextDelim = str.indexOf(delimZ1, thisDelim + 1, Qt::CaseInsensitive);
}
if (-1 == nextDelim) {
nextDelim = str.indexOf(delimZ2, thisDelim + 1, Qt::CaseInsensitive);
}
if (nextDelim < 0) {
return MessagePart::Ptr();
}
//if ( curNode->mRoot )
// curNode = curNode->mRoot;
// at least one message found: build a mime tree
digestHeaderStr = QStringLiteral("Content-Type: text/plain\nContent-Description: digest header\n\n");
digestHeaderStr += str.midRef(0, thisDelim);
MessagePartList::Ptr mpl(new MessagePartList(part.objectTreeParser()));
mpl->appendMessagePart(createAndParseTempNode(part, part.topLevelContent(), digestHeaderStr.toLatin1(), "Digest Header"));
//mReader->queueHtml("<br><hr><br>");
// temporarily change curent node's Content-Type
// to get our embedded RfC822 messages properly inserted
curNode->contentType()->setMimeType("multipart/digest");
while (-1 < nextDelim) {
int thisEoL = str.indexOf(QLatin1String("\nMessage:"), thisDelim, Qt::CaseInsensitive);
if (-1 < thisEoL) {
thisDelim = thisEoL + 1;
} else {
thisEoL = str.indexOf(QLatin1String("\n_____________"), thisDelim, Qt::CaseInsensitive);
if (-1 < thisEoL) {
thisDelim = thisEoL + 1;
}
}
thisEoL = str.indexOf(QLatin1Char('\n'), thisDelim);
if (-1 < thisEoL) {
thisDelim = thisEoL + 1;
} else {
thisDelim = thisDelim + 1;
}
//while( thisDelim < cstr.size() && '\n' == cstr[thisDelim] )
// ++thisDelim;
partStr = QStringLiteral("Content-Type: message/rfc822\nContent-Description: embedded message\n\n");
partStr += str.midRef(thisDelim, nextDelim - thisDelim);
QString subject = QStringLiteral("embedded message");
QString subSearch = QStringLiteral("\nSubject:");
int subPos = partStr.indexOf(subSearch, 0, Qt::CaseInsensitive);
if (-1 < subPos) {
subject = partStr.mid(subPos + subSearch.length());
thisEoL = subject.indexOf(QLatin1Char('\n'));
if (-1 < thisEoL) {
subject.truncate(thisEoL);
}
}
qCDebug(MIMETREEPARSER_LOG) << " embedded message found: \"" << subject;
mpl->appendMessagePart(createAndParseTempNode(part, part.topLevelContent(), partStr.toLatin1(), subject.toLatin1()));
//mReader->queueHtml("<br><hr><br>");
thisDelim = nextDelim + 1;
nextDelim = str.indexOf(delim1, thisDelim, Qt::CaseInsensitive);
if (-1 == nextDelim) {
nextDelim = str.indexOf(delim2, thisDelim, Qt::CaseInsensitive);
}
if (-1 == nextDelim) {
nextDelim = str.indexOf(delimZ1, thisDelim, Qt::CaseInsensitive);
}
if (-1 == nextDelim) {
nextDelim = str.indexOf(delimZ2, thisDelim, Qt::CaseInsensitive);
}
}
// reset curent node's Content-Type
curNode->contentType()->setMimeType("text/plain");
int thisEoL = str.indexOf(QLatin1String("_____________"), thisDelim);
if (-1 < thisEoL) {
thisDelim = thisEoL;
thisEoL = str.indexOf(QLatin1Char('\n'), thisDelim);
if (-1 < thisEoL) {
thisDelim = thisEoL + 1;
}
} else {
thisDelim = thisDelim + 1;
}
partStr = QStringLiteral("Content-Type: text/plain\nContent-Description: digest footer\n\n");
partStr += str.midRef(thisDelim);
mpl->appendMessagePart(createAndParseTempNode(part, part.topLevelContent(), partStr.toLatin1(), "Digest Footer"));
return mpl;
}
/*
Copyright (c) 2016 Sandro Knauß <sknauss@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#ifndef __MIMETREEPARSER_BODYFORAMATTER_MAILMAN_H__
#define __MIMETREEPARSER_BODYFORAMATTER_MAILMAN_H__
#include "interfaces/bodypartformatter.h"
#include "interfaces/bodypart.h"
namespace MessageViewer
{
class MailmanBodyPartFormatter : public Interface::BodyPartFormatter
{
static const MailmanBodyPartFormatter *self;
public:
Interface::MessagePart::Ptr process(Interface::BodyPart &part) const Q_DECL_OVERRIDE;
Interface::BodyPartFormatter::Result format(Interface::BodyPart *, HtmlWriter *) const Q_DECL_OVERRIDE;
using Interface::BodyPartFormatter::format;
static const Interface::BodyPartFormatter *create();
private:
bool isMailmanMessage(KMime::Content *curNode) const;
};
}
#endif
\ No newline at end of file
......@@ -31,6 +31,8 @@
#include "mimetreeparser_debug.h"
#include "bodyformatter/mailman.h"
#include "interfaces/bodypartformatter.h"
#include "interfaces/bodypart.h"
......@@ -186,7 +188,6 @@ Interface::BodyPartFormatter::Result MessageRfc822BodyPartFormatter::format(Inte
}
CREATE_BODY_PART_FORMATTER(TextPlain)
CREATE_BODY_PART_FORMATTER(Mailman)
CREATE_BODY_PART_FORMATTER(TextHtml)
CREATE_BODY_PART_FORMATTER(ApplicationPkcs7Mime)
......
......@@ -218,28 +218,6 @@ bool ObjectTreeParser::printing() const
return mPrinting;
}
MimeMessagePart::Ptr ObjectTreeParser::createAndParseTempNode(KMime::Content *parentNode, const char *content, const char *cntDesc)
{
// qCDebug(MIMETREEPARSER_LOG) << "CONTENT: " << QByteArray( content ).left( 100 ) << " CNTDESC: " << cntDesc;
KMime::Content *newNode = new KMime::Content();
newNode->setContent(KMime::CRLFtoLF(content));
newNode->parse();
/*
qCDebug(MIMETREEPARSER_LOG) << "MEDIATYPE: " << newNode->contentType()->mediaType() << newNode->contentType()->mimeType() ;
qCDebug(MIMETREEPARSER_LOG) << "DECODEDCONTENT: " << newNode->decodedContent().left(400);
qCDebug(MIMETREEPARSER_LOG) << "ENCODEDCONTENT: " << newNode->encodedContent().left(400);
qCDebug(MIMETREEPARSER_LOG) << "BODY: " << newNode->body().left(400);
*/
if (!newNode->head().isEmpty()) {
newNode->contentDescription()->from7BitString(cntDesc);
}
mNodeHelper->attachExtraContent(parentNode, newNode);
return MimeMessagePart::Ptr(new MimeMessagePart(this, newNode, false));
}
//-----------------------------------------------------------------------------
void ObjectTreeParser::parseObjectTree(KMime::Content *node)
......@@ -758,137 +736,6 @@ MessagePart::Ptr ObjectTreeParser::processTextHtmlSubtype(KMime::Content *curNod
return mp;
}
bool ObjectTreeParser::isMailmanMessage(KMime::Content *curNode)
{
if (!curNode || curNode->head().isEmpty()) {
return false;
}
if (curNode->hasHeader("X-Mailman-Version")) {
return true;
}
if (curNode->hasHeader("X-Mailer")) {
KMime::Headers::Base *header = curNode->headerByType("X-Mailer");
if (header->asUnicodeString().contains(QStringLiteral("MAILMAN"), Qt::CaseInsensitive)) {
return true;
}
}
return false;
}
MessagePart::Ptr ObjectTreeParser::processMailmanSubtype(KMime::Content *curNode, ProcessResult &result)
{
Q_UNUSED(result);
if (!isMailmanMessage(curNode)) {
return MessagePart::Ptr();
}
const QString str = QString::fromLatin1(curNode->decodedContent());
//###
const QLatin1String delim1("--__--__--\n\nMessage:");
const QLatin1String delim2("--__--__--\r\n\r\nMessage:");
const QLatin1String delimZ2("--__--__--\n\n_____________");
const QLatin1String delimZ1("--__--__--\r\n\r\n_____________");
QString partStr, digestHeaderStr;
int thisDelim = str.indexOf(delim1, Qt::CaseInsensitive);
if (thisDelim == -1) {
thisDelim = str.indexOf(delim2, Qt::CaseInsensitive);
}
if (thisDelim == -1) {
return MessagePart::Ptr();
}
int nextDelim = str.indexOf(delim1, thisDelim + 1, Qt::CaseInsensitive);
if (-1 == nextDelim) {
nextDelim = str.indexOf(delim2, thisDelim + 1, Qt::CaseInsensitive);
}
if (-1 == nextDelim) {
nextDelim = str.indexOf(delimZ1, thisDelim + 1, Qt::CaseInsensitive);
}
if (-1 == nextDelim) {
nextDelim = str.indexOf(delimZ2, thisDelim + 1, Qt::CaseInsensitive);
}
if (nextDelim < 0) {
return MessagePart::Ptr();
}
//if ( curNode->mRoot )
// curNode = curNode->mRoot;
// at least one message found: build a mime tree
digestHeaderStr = QStringLiteral("Content-Type: text/plain\nContent-Description: digest header\n\n");
digestHeaderStr += str.midRef(0, thisDelim);
MessagePartList::Ptr mpl(new MessagePartList(this));
mpl->appendMessagePart(createAndParseTempNode(mTopLevelContent, digestHeaderStr.toLatin1(), "Digest Header"));
//mReader->queueHtml("<br><hr><br>");
// temporarily change curent node's Content-Type
// to get our embedded RfC822 messages properly inserted
curNode->contentType()->setMimeType("multipart/digest");
while (-1 < nextDelim) {
int thisEoL = str.indexOf(QLatin1String("\nMessage:"), thisDelim, Qt::CaseInsensitive);
if (-1 < thisEoL) {
thisDelim = thisEoL + 1;
} else {
thisEoL = str.indexOf(QLatin1String("\n_____________"), thisDelim, Qt::CaseInsensitive);
if (-1 < thisEoL) {
thisDelim = thisEoL + 1;
}
}
thisEoL = str.indexOf(QLatin1Char('\n'), thisDelim);
if (-1 < thisEoL) {
thisDelim = thisEoL + 1;
} else {
thisDelim = thisDelim + 1;
}
//while( thisDelim < cstr.size() && '\n' == cstr[thisDelim] )
// ++thisDelim;
partStr = QStringLiteral("Content-Type: message/rfc822\nContent-Description: embedded message\n\n");
partStr += str.midRef(thisDelim, nextDelim - thisDelim);
QString subject = QStringLiteral("embedded message");
QString subSearch = QStringLiteral("\nSubject:");
int subPos = partStr.indexOf(subSearch, 0, Qt::CaseInsensitive);
if (-1 < subPos) {
subject = partStr.mid(subPos + subSearch.length());
thisEoL = subject.indexOf(QLatin1Char('\n'));
if (-1 < thisEoL) {
subject.truncate(thisEoL);
}
}
qCDebug(MIMETREEPARSER_LOG) << " embedded message found: \"" << subject;
mpl->appendMessagePart(createAndParseTempNode(mTopLevelContent, partStr.toLatin1(), subject.toLatin1()));
//mReader->queueHtml("<br><hr><br>");
thisDelim = nextDelim + 1;
nextDelim = str.indexOf(delim1, thisDelim, Qt::CaseInsensitive);
if (-1 == nextDelim) {
nextDelim = str.indexOf(delim2, thisDelim, Qt::CaseInsensitive);
}
if (-1 == nextDelim) {
nextDelim = str.indexOf(delimZ1, thisDelim, Qt::CaseInsensitive);
}
if (-1 == nextDelim) {
nextDelim = str.indexOf(delimZ2, thisDelim, Qt::CaseInsensitive);
}
}
// reset curent node's Content-Type
curNode->contentType()->setMimeType("text/plain");
int thisEoL = str.indexOf(QLatin1String("_____________"), thisDelim);
if (-1 < thisEoL) {
thisDelim = thisEoL;
thisEoL = str.indexOf(QLatin1Char('\n'), thisDelim);
if (-1 < thisEoL) {
thisDelim = thisEoL + 1;
}
} else {
thisDelim = thisDelim + 1;
}
partStr = QStringLiteral("Content-Type: text/plain\nContent-Description: digest footer\n\n");
partStr += str.midRef(thisDelim);
mpl->appendMessagePart(createAndParseTempNode(mTopLevelContent, partStr.toLatin1(), "Digest Footer"));
return mpl;
}
void ObjectTreeParser::extractNodeInfos(KMime::Content *curNode, bool isFirstTextPart)
{
......
......@@ -357,12 +357,6 @@ private:
MessagePartPtr defaultHandling(KMime::Content *node, ProcessResult &result);
/** 1. Create a new partNode using 'content' data and Content-Description
found in 'cntDesc'.
2. Parse the 'node' to display the content.
*/
MimeMessagePartPtr createAndParseTempNode(KMime::Content *parentNode, const char *content, const char *cntDesc);
/** Writes out the information contained in a GpgME::ImportResult */
void writeCertificateImportResult(const GpgME::ImportResult &res);
......@@ -385,7 +379,6 @@ public:// (during refactoring)
MessagePartPtr processTextHtmlSubtype(KMime::Content *node, ProcessResult &result);
MessagePartPtr processTextPlainSubtype(KMime::Content *node, ProcessResult &result);
MessagePartPtr processMailmanSubtype(KMime::Content *node, ProcessResult &result);
MessagePartPtr processMultiPartMixedSubtype(KMime::Content *node, ProcessResult &result);
MessagePartPtr processMultiPartAlternativeSubtype(KMime::Content *node, ProcessResult &result);
......@@ -396,8 +389,6 @@ public:// (during refactoring)
void writePartIcon(KMime::Content *msgPart, bool inlineImage = false);
bool isMailmanMessage(KMime::Content *curNode);
/** Change the string to `quoted' html (meaning, that the quoted
part of the message get italized */
QString quotedHTML(const QString &pos, bool decorate);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment