From 64436e0787382d5c7fb3dae5b6128e1d93a77979 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Wed, 2 Aug 2017 16:52:45 -0600 Subject: Moved mailcomposing into mailtemplates so we can start testing it. --- framework/src/domain/composercontroller.cpp | 84 +------------------- framework/src/domain/mime/mailtemplates.cpp | 92 ++++++++++++++++++++++ framework/src/domain/mime/mailtemplates.h | 9 +++ .../src/domain/mime/tests/mailtemplatetest.cpp | 28 ++++++- 4 files changed, 126 insertions(+), 87 deletions(-) (limited to 'framework') diff --git a/framework/src/domain/composercontroller.cpp b/framework/src/domain/composercontroller.cpp index 3c2b7fc1..311c79f3 100644 --- a/framework/src/domain/composercontroller.cpp +++ b/framework/src/domain/composercontroller.cpp @@ -383,88 +383,6 @@ void ComposerController::recordForAutocompletion(const QByteArray &addrSpec, con } } -static KMime::Content *createAttachmentPart(const QByteArray &content, const QString &filename, bool isInline, const QByteArray &mimeType, const QString &name) -{ - - KMime::Content *part = new KMime::Content; - part->contentDisposition(true)->setFilename(filename); - if (isInline) { - part->contentDisposition(true)->setDisposition(KMime::Headers::CDinline); - } else { - part->contentDisposition(true)->setDisposition(KMime::Headers::CDattachment); - } - part->contentType(true)->setMimeType(mimeType); - part->contentType(true)->setName(name, "utf-8"); - //Just always encode attachments base64 so it's safe for binary data - part->contentTransferEncoding(true)->setEncoding(KMime::Headers::CEbase64); - part->setBody(content); - return part; -} - -static KMime::Content *createBodyPart(const QByteArray &body) { - auto mainMessage = new KMime::Content; - mainMessage->setBody(body); - mainMessage->contentType(true)->setMimeType("text/plain"); - return mainMessage; -} - -struct Attachment { - QString name; - QString filename; - QByteArray mimeType; - bool isInline; - QByteArray data; -}; - -static KMime::Message::Ptr createMessage(KMime::Message::Ptr existingMessage, const QStringList &to, const QStringList &cc, const QStringList &bcc, const KMime::Types::Mailbox &from, const QString &subject, const QString &body, const QList &attachments) -{ - auto mail = existingMessage; - if (!mail) { - mail = KMime::Message::Ptr::create(); - } - mail->to(true)->clear(); - applyAddresses(to, [&](const QByteArray &addrSpec, const QByteArray &displayName) { - mail->to(true)->addAddress(addrSpec, displayName); - }); - - mail->cc(true)->clear(); - applyAddresses(cc, [&](const QByteArray &addrSpec, const QByteArray &displayName) { - mail->cc(true)->addAddress(addrSpec, displayName); - }); - - mail->bcc(true)->clear(); - applyAddresses(bcc, [&](const QByteArray &addrSpec, const QByteArray &displayName) { - mail->bcc(true)->addAddress(addrSpec, displayName); - }); - - mail->from(true)->addAddress(from); - - mail->subject(true)->fromUnicodeString(subject, "utf-8"); - if (!mail->messageID()) { - mail->messageID(true)->generate("org.kde.kube"); - } - if (!mail->date(true)->dateTime().isValid()) { - mail->date(true)->setDateTime(QDateTime::currentDateTimeUtc()); - } - - if (!attachments.isEmpty()) { - mail->contentType(true)->setMimeType("multipart/mixed"); - mail->contentType()->setBoundary(KMime::multiPartBoundary()); - mail->contentTransferEncoding()->setEncoding(KMime::Headers::CE7Bit); - mail->setPreamble("This is a multi-part message in MIME format.\n"); - for (const auto &attachment : attachments) { - mail->addContent(createAttachmentPart(attachment.data, attachment.filename, attachment.isInline, attachment.mimeType, attachment.name)); - } - mail->addContent(createBodyPart(body.toUtf8())); - } else { - //FIXME same implementation as above for attachments - mail->setBody(body.toUtf8()); - } - - mail->assemble(); - return mail; -} - KMime::Message::Ptr ComposerController::assembleMessage() { applyAddresses(mToModel->stringList(), [&](const QByteArray &addrSpec, const QByteArray &displayName) { @@ -491,7 +409,7 @@ KMime::Message::Ptr ComposerController::assembleMessage() }; } } - return createMessage(mExistingMessage, mToModel->stringList(), mCcModel->stringList(), mBccModel->stringList(), getIdentity(), getSubject(), getBody(), attachments); + return MailTemplates::createMessage(mExistingMessage, mToModel->stringList(), mCcModel->stringList(), mBccModel->stringList(), getIdentity(), getSubject(), getBody(), attachments); } void ComposerController::updateSendAction() diff --git a/framework/src/domain/mime/mailtemplates.cpp b/framework/src/domain/mime/mailtemplates.cpp index 71a267a8..ce1cd52f 100644 --- a/framework/src/domain/mime/mailtemplates.cpp +++ b/framework/src/domain/mime/mailtemplates.cpp @@ -34,6 +34,7 @@ #include #include +#include #include @@ -885,3 +886,94 @@ QString MailTemplates::plaintextContent(const KMime::Message::Ptr &msg) } return plain; } + +static KMime::Content *createAttachmentPart(const QByteArray &content, const QString &filename, bool isInline, const QByteArray &mimeType, const QString &name) +{ + + KMime::Content *part = new KMime::Content; + part->contentDisposition(true)->setFilename(filename); + if (isInline) { + part->contentDisposition(true)->setDisposition(KMime::Headers::CDinline); + } else { + part->contentDisposition(true)->setDisposition(KMime::Headers::CDattachment); + } + part->contentType(true)->setMimeType(mimeType); + part->contentType(true)->setName(name, "utf-8"); + //Just always encode attachments base64 so it's safe for binary data + part->contentTransferEncoding(true)->setEncoding(KMime::Headers::CEbase64); + part->setBody(content); + return part; +} + +static KMime::Content *createBodyPart(const QByteArray &body) { + auto mainMessage = new KMime::Content; + mainMessage->setBody(body); + mainMessage->contentType(true)->setMimeType("text/plain"); + // return MailCrypto::sign(mainMessage, {}); + return mainMessage; +} + +static void applyAddresses(const QStringList &list, std::function callback) +{ + for (const auto &to : list) { + QByteArray displayName; + QByteArray addrSpec; + QByteArray comment; + KEmailAddress::splitAddress(to.toUtf8(), displayName, addrSpec, comment); + callback(addrSpec, displayName); + } +} + +// static void applyAddresses(const QString &list, std::function callback) +// { +// applyAddresses(KEmailAddress::splitAddressList(list), callback); +// } + +KMime::Message::Ptr MailTemplates::createMessage(KMime::Message::Ptr existingMessage, const QStringList &to, const QStringList &cc, const QStringList &bcc, const KMime::Types::Mailbox &from, const QString &subject, const QString &body, const QList &attachments) +{ + auto mail = existingMessage; + if (!mail) { + mail = KMime::Message::Ptr::create(); + } + mail->to(true)->clear(); + applyAddresses(to, [&](const QByteArray &addrSpec, const QByteArray &displayName) { + mail->to(true)->addAddress(addrSpec, displayName); + }); + + mail->cc(true)->clear(); + applyAddresses(cc, [&](const QByteArray &addrSpec, const QByteArray &displayName) { + mail->cc(true)->addAddress(addrSpec, displayName); + }); + + mail->bcc(true)->clear(); + applyAddresses(bcc, [&](const QByteArray &addrSpec, const QByteArray &displayName) { + mail->bcc(true)->addAddress(addrSpec, displayName); + }); + + mail->from(true)->addAddress(from); + + mail->subject(true)->fromUnicodeString(subject, "utf-8"); + if (!mail->messageID()) { + mail->messageID(true)->generate("org.kde.kube"); + } + if (!mail->date(true)->dateTime().isValid()) { + mail->date(true)->setDateTime(QDateTime::currentDateTimeUtc()); + } + + if (!attachments.isEmpty()) { + mail->contentType(true)->setMimeType("multipart/mixed"); + mail->contentType()->setBoundary(KMime::multiPartBoundary()); + mail->contentTransferEncoding()->setEncoding(KMime::Headers::CE7Bit); + mail->setPreamble("This is a multi-part message in MIME format.\n"); + for (const auto &attachment : attachments) { + mail->addContent(createAttachmentPart(attachment.data, attachment.filename, attachment.isInline, attachment.mimeType, attachment.name)); + } + mail->addContent(createBodyPart(body.toUtf8())); + } else { + //FIXME same implementation as above for attachments + mail->setBody(body.toUtf8()); + } + + mail->assemble(); + return mail; +} diff --git a/framework/src/domain/mime/mailtemplates.h b/framework/src/domain/mime/mailtemplates.h index 4f559bb6..773ded05 100644 --- a/framework/src/domain/mime/mailtemplates.h +++ b/framework/src/domain/mime/mailtemplates.h @@ -23,8 +23,17 @@ #include #include +struct Attachment { + QString name; + QString filename; + QByteArray mimeType; + bool isInline; + QByteArray data; +}; + namespace MailTemplates { void reply(const KMime::Message::Ptr &origMsg, const std::function &callback); QString plaintextContent(const KMime::Message::Ptr &origMsg); + KMime::Message::Ptr createMessage(KMime::Message::Ptr existingMessage, const QStringList &to, const QStringList &cc, const QStringList &bcc, const KMime::Types::Mailbox &from, const QString &subject, const QString &body, const QList &attachments); }; diff --git a/framework/src/domain/mime/tests/mailtemplatetest.cpp b/framework/src/domain/mime/tests/mailtemplatetest.cpp index e9752c9e..f393f1bd 100644 --- a/framework/src/domain/mime/tests/mailtemplatetest.cpp +++ b/framework/src/domain/mime/tests/mailtemplatetest.cpp @@ -58,7 +58,7 @@ private slots: QtWebEngine::initialize(); } - void testPlain() + void testPlainReply() { auto msg = readMail("plaintext.mbox"); KMime::Message::Ptr result; @@ -69,7 +69,7 @@ private slots: QCOMPARE(normalize(removeFirstLine(result->body())), normalize(msg->body())); } - void testHtml() + void testHtmlReply() { auto msg = readMail("html.mbox"); KMime::Message::Ptr result; @@ -80,7 +80,7 @@ private slots: QCOMPARE(unquote(removeFirstLine(result->body())), QLatin1String("HTML text")); } - void testMultipartSigned() + void testMultipartSignedReply() { auto msg = readMail("openpgp-signed-mailinglist.mbox"); KMime::Message::Ptr result; @@ -93,7 +93,7 @@ private slots: QVERIFY(content.contains("i noticed a new branch")); } - void testMultipartAlternative() + void testMultipartAlternativeReply() { auto msg = readMail("alternative.mbox"); KMime::Message::Ptr result; @@ -106,6 +106,26 @@ private slots: QCOMPARE(unquote(content), QLatin1String("If you can see this text it means that your email client couldn't display our newsletter properly.\nPlease visit this link to view the newsletter on our website: http://www.gog.com/newsletter/\n")); } + void testCreatePlainMail() + { + QStringList to = {{"to@example.org"}}; + QStringList cc = {{"cc@example.org"}};; + QStringList bcc = {{"bcc@example.org"}};; + KMime::Types::Mailbox from; + from.fromUnicodeString("from@example.org"); + QString subject = "subject"; + QString body = "body"; + QList attachments; + + auto result = MailTemplates::createMessage({}, to, cc, bcc, from, subject, body, attachments); + + QVERIFY(result); + auto content = removeFirstLine(result->body()); + QCOMPARE(result->subject()->asUnicodeString(), subject); + QCOMPARE(result->body(), body.toUtf8()); + QVERIFY(result->date(false)->dateTime().isValid()); + } + }; QTEST_MAIN(MailTemplateTest) -- cgit v1.2.3