summaryrefslogtreecommitdiffstats
path: root/framework
diff options
context:
space:
mode:
Diffstat (limited to 'framework')
-rw-r--r--framework/src/domain/composercontroller.cpp84
-rw-r--r--framework/src/domain/mime/mailtemplates.cpp92
-rw-r--r--framework/src/domain/mime/mailtemplates.h9
-rw-r--r--framework/src/domain/mime/tests/mailtemplatetest.cpp28
4 files changed, 126 insertions, 87 deletions
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
383 } 383 }
384} 384}
385 385
386static KMime::Content *createAttachmentPart(const QByteArray &content, const QString &filename, bool isInline, const QByteArray &mimeType, const QString &name)
387{
388
389 KMime::Content *part = new KMime::Content;
390 part->contentDisposition(true)->setFilename(filename);
391 if (isInline) {
392 part->contentDisposition(true)->setDisposition(KMime::Headers::CDinline);
393 } else {
394 part->contentDisposition(true)->setDisposition(KMime::Headers::CDattachment);
395 }
396 part->contentType(true)->setMimeType(mimeType);
397 part->contentType(true)->setName(name, "utf-8");
398 //Just always encode attachments base64 so it's safe for binary data
399 part->contentTransferEncoding(true)->setEncoding(KMime::Headers::CEbase64);
400 part->setBody(content);
401 return part;
402}
403
404static KMime::Content *createBodyPart(const QByteArray &body) {
405 auto mainMessage = new KMime::Content;
406 mainMessage->setBody(body);
407 mainMessage->contentType(true)->setMimeType("text/plain");
408 return mainMessage;
409}
410
411struct Attachment {
412 QString name;
413 QString filename;
414 QByteArray mimeType;
415 bool isInline;
416 QByteArray data;
417};
418
419static 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<Attachment> &attachments)
420{
421 auto mail = existingMessage;
422 if (!mail) {
423 mail = KMime::Message::Ptr::create();
424 }
425 mail->to(true)->clear();
426 applyAddresses(to, [&](const QByteArray &addrSpec, const QByteArray &displayName) {
427 mail->to(true)->addAddress(addrSpec, displayName);
428 });
429
430 mail->cc(true)->clear();
431 applyAddresses(cc, [&](const QByteArray &addrSpec, const QByteArray &displayName) {
432 mail->cc(true)->addAddress(addrSpec, displayName);
433 });
434
435 mail->bcc(true)->clear();
436 applyAddresses(bcc, [&](const QByteArray &addrSpec, const QByteArray &displayName) {
437 mail->bcc(true)->addAddress(addrSpec, displayName);
438 });
439
440 mail->from(true)->addAddress(from);
441
442 mail->subject(true)->fromUnicodeString(subject, "utf-8");
443 if (!mail->messageID()) {
444 mail->messageID(true)->generate("org.kde.kube");
445 }
446 if (!mail->date(true)->dateTime().isValid()) {
447 mail->date(true)->setDateTime(QDateTime::currentDateTimeUtc());
448 }
449
450 if (!attachments.isEmpty()) {
451 mail->contentType(true)->setMimeType("multipart/mixed");
452 mail->contentType()->setBoundary(KMime::multiPartBoundary());
453 mail->contentTransferEncoding()->setEncoding(KMime::Headers::CE7Bit);
454 mail->setPreamble("This is a multi-part message in MIME format.\n");
455 for (const auto &attachment : attachments) {
456 mail->addContent(createAttachmentPart(attachment.data, attachment.filename, attachment.isInline, attachment.mimeType, attachment.name));
457 }
458 mail->addContent(createBodyPart(body.toUtf8()));
459 } else {
460 //FIXME same implementation as above for attachments
461 mail->setBody(body.toUtf8());
462 }
463
464 mail->assemble();
465 return mail;
466}
467
468KMime::Message::Ptr ComposerController::assembleMessage() 386KMime::Message::Ptr ComposerController::assembleMessage()
469{ 387{
470 applyAddresses(mToModel->stringList(), [&](const QByteArray &addrSpec, const QByteArray &displayName) { 388 applyAddresses(mToModel->stringList(), [&](const QByteArray &addrSpec, const QByteArray &displayName) {
@@ -491,7 +409,7 @@ KMime::Message::Ptr ComposerController::assembleMessage()
491 }; 409 };
492 } 410 }
493 } 411 }
494 return createMessage(mExistingMessage, mToModel->stringList(), mCcModel->stringList(), mBccModel->stringList(), getIdentity(), getSubject(), getBody(), attachments); 412 return MailTemplates::createMessage(mExistingMessage, mToModel->stringList(), mCcModel->stringList(), mBccModel->stringList(), getIdentity(), getSubject(), getBody(), attachments);
495} 413}
496 414
497void ComposerController::updateSendAction() 415void 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 @@
34 34
35#include <KCodecs/KCharsets> 35#include <KCodecs/KCharsets>
36#include <KMime/Types> 36#include <KMime/Types>
37#include <KCodecs/KEmailAddress>
37 38
38#include <mimetreeparser/objecttreeparser.h> 39#include <mimetreeparser/objecttreeparser.h>
39 40
@@ -885,3 +886,94 @@ QString MailTemplates::plaintextContent(const KMime::Message::Ptr &msg)
885 } 886 }
886 return plain; 887 return plain;
887} 888}
889
890static KMime::Content *createAttachmentPart(const QByteArray &content, const QString &filename, bool isInline, const QByteArray &mimeType, const QString &name)
891{
892
893 KMime::Content *part = new KMime::Content;
894 part->contentDisposition(true)->setFilename(filename);
895 if (isInline) {
896 part->contentDisposition(true)->setDisposition(KMime::Headers::CDinline);
897 } else {
898 part->contentDisposition(true)->setDisposition(KMime::Headers::CDattachment);
899 }
900 part->contentType(true)->setMimeType(mimeType);
901 part->contentType(true)->setName(name, "utf-8");
902 //Just always encode attachments base64 so it's safe for binary data
903 part->contentTransferEncoding(true)->setEncoding(KMime::Headers::CEbase64);
904 part->setBody(content);
905 return part;
906}
907
908static KMime::Content *createBodyPart(const QByteArray &body) {
909 auto mainMessage = new KMime::Content;
910 mainMessage->setBody(body);
911 mainMessage->contentType(true)->setMimeType("text/plain");
912 // return MailCrypto::sign(mainMessage, {});
913 return mainMessage;
914}
915
916static void applyAddresses(const QStringList &list, std::function<void(const QByteArray &, const QByteArray &)> callback)
917{
918 for (const auto &to : list) {
919 QByteArray displayName;
920 QByteArray addrSpec;
921 QByteArray comment;
922 KEmailAddress::splitAddress(to.toUtf8(), displayName, addrSpec, comment);
923 callback(addrSpec, displayName);
924 }
925}
926
927// static void applyAddresses(const QString &list, std::function<void(const QByteArray &, const QByteArray &)> callback)
928// {
929// applyAddresses(KEmailAddress::splitAddressList(list), callback);
930// }
931
932KMime::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<Attachment> &attachments)
933{
934 auto mail = existingMessage;
935 if (!mail) {
936 mail = KMime::Message::Ptr::create();
937 }
938 mail->to(true)->clear();
939 applyAddresses(to, [&](const QByteArray &addrSpec, const QByteArray &displayName) {
940 mail->to(true)->addAddress(addrSpec, displayName);
941 });
942
943 mail->cc(true)->clear();
944 applyAddresses(cc, [&](const QByteArray &addrSpec, const QByteArray &displayName) {
945 mail->cc(true)->addAddress(addrSpec, displayName);
946 });
947
948 mail->bcc(true)->clear();
949 applyAddresses(bcc, [&](const QByteArray &addrSpec, const QByteArray &displayName) {
950 mail->bcc(true)->addAddress(addrSpec, displayName);
951 });
952
953 mail->from(true)->addAddress(from);
954
955 mail->subject(true)->fromUnicodeString(subject, "utf-8");
956 if (!mail->messageID()) {
957 mail->messageID(true)->generate("org.kde.kube");
958 }
959 if (!mail->date(true)->dateTime().isValid()) {
960 mail->date(true)->setDateTime(QDateTime::currentDateTimeUtc());
961 }
962
963 if (!attachments.isEmpty()) {
964 mail->contentType(true)->setMimeType("multipart/mixed");
965 mail->contentType()->setBoundary(KMime::multiPartBoundary());
966 mail->contentTransferEncoding()->setEncoding(KMime::Headers::CE7Bit);
967 mail->setPreamble("This is a multi-part message in MIME format.\n");
968 for (const auto &attachment : attachments) {
969 mail->addContent(createAttachmentPart(attachment.data, attachment.filename, attachment.isInline, attachment.mimeType, attachment.name));
970 }
971 mail->addContent(createBodyPart(body.toUtf8()));
972 } else {
973 //FIXME same implementation as above for attachments
974 mail->setBody(body.toUtf8());
975 }
976
977 mail->assemble();
978 return mail;
979}
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 @@
23#include <KMime/Message> 23#include <KMime/Message>
24#include <functional> 24#include <functional>
25 25
26struct Attachment {
27 QString name;
28 QString filename;
29 QByteArray mimeType;
30 bool isInline;
31 QByteArray data;
32};
33
26namespace MailTemplates 34namespace MailTemplates
27{ 35{
28 void reply(const KMime::Message::Ptr &origMsg, const std::function<void(const KMime::Message::Ptr &result)> &callback); 36 void reply(const KMime::Message::Ptr &origMsg, const std::function<void(const KMime::Message::Ptr &result)> &callback);
29 QString plaintextContent(const KMime::Message::Ptr &origMsg); 37 QString plaintextContent(const KMime::Message::Ptr &origMsg);
38 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<Attachment> &attachments);
30}; 39};
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:
58 QtWebEngine::initialize(); 58 QtWebEngine::initialize();
59 } 59 }
60 60
61 void testPlain() 61 void testPlainReply()
62 { 62 {
63 auto msg = readMail("plaintext.mbox"); 63 auto msg = readMail("plaintext.mbox");
64 KMime::Message::Ptr result; 64 KMime::Message::Ptr result;
@@ -69,7 +69,7 @@ private slots:
69 QCOMPARE(normalize(removeFirstLine(result->body())), normalize(msg->body())); 69 QCOMPARE(normalize(removeFirstLine(result->body())), normalize(msg->body()));
70 } 70 }
71 71
72 void testHtml() 72 void testHtmlReply()
73 { 73 {
74 auto msg = readMail("html.mbox"); 74 auto msg = readMail("html.mbox");
75 KMime::Message::Ptr result; 75 KMime::Message::Ptr result;
@@ -80,7 +80,7 @@ private slots:
80 QCOMPARE(unquote(removeFirstLine(result->body())), QLatin1String("HTML text")); 80 QCOMPARE(unquote(removeFirstLine(result->body())), QLatin1String("HTML text"));
81 } 81 }
82 82
83 void testMultipartSigned() 83 void testMultipartSignedReply()
84 { 84 {
85 auto msg = readMail("openpgp-signed-mailinglist.mbox"); 85 auto msg = readMail("openpgp-signed-mailinglist.mbox");
86 KMime::Message::Ptr result; 86 KMime::Message::Ptr result;
@@ -93,7 +93,7 @@ private slots:
93 QVERIFY(content.contains("i noticed a new branch")); 93 QVERIFY(content.contains("i noticed a new branch"));
94 } 94 }
95 95
96 void testMultipartAlternative() 96 void testMultipartAlternativeReply()
97 { 97 {
98 auto msg = readMail("alternative.mbox"); 98 auto msg = readMail("alternative.mbox");
99 KMime::Message::Ptr result; 99 KMime::Message::Ptr result;
@@ -106,6 +106,26 @@ private slots:
106 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")); 106 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"));
107 } 107 }
108 108
109 void testCreatePlainMail()
110 {
111 QStringList to = {{"to@example.org"}};
112 QStringList cc = {{"cc@example.org"}};;
113 QStringList bcc = {{"bcc@example.org"}};;
114 KMime::Types::Mailbox from;
115 from.fromUnicodeString("from@example.org");
116 QString subject = "subject";
117 QString body = "body";
118 QList<Attachment> attachments;
119
120 auto result = MailTemplates::createMessage({}, to, cc, bcc, from, subject, body, attachments);
121
122 QVERIFY(result);
123 auto content = removeFirstLine(result->body());
124 QCOMPARE(result->subject()->asUnicodeString(), subject);
125 QCOMPARE(result->body(), body.toUtf8());
126 QVERIFY(result->date(false)->dateTime().isValid());
127 }
128
109}; 129};
110 130
111QTEST_MAIN(MailTemplateTest) 131QTEST_MAIN(MailTemplateTest)