mirror of https://github.com/adamdruppe/arsd.git
handle base64 html email
This commit is contained in:
parent
b777074e88
commit
c70ce55098
73
email.d
73
email.d
|
@ -11,20 +11,23 @@ import arsd.characterencodings;
|
||||||
|
|
||||||
// SEE ALSO: std.net.curl.SMTP
|
// SEE ALSO: std.net.curl.SMTP
|
||||||
|
|
||||||
|
///
|
||||||
struct RelayInfo {
|
struct RelayInfo {
|
||||||
string server;
|
string server; ///
|
||||||
string username;
|
string username; ///
|
||||||
string password;
|
string password; ///
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
struct MimeAttachment {
|
struct MimeAttachment {
|
||||||
string type;
|
string type; ///
|
||||||
string filename;
|
string filename; ///
|
||||||
const(void)[] content;
|
const(void)[] content; ///
|
||||||
string id;
|
string id; ///
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// For OUTGOING email
|
||||||
class EmailMessage {
|
class EmailMessage {
|
||||||
void setHeader(string name, string value) {
|
void setHeader(string name, string value) {
|
||||||
headers ~= name ~ ": " ~ value;
|
headers ~= name ~ ": " ~ value;
|
||||||
|
@ -224,6 +227,7 @@ class EmailMessage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
void email(string to, string subject, string message, string from, RelayInfo mailServer = RelayInfo("smtp://localhost")) {
|
void email(string to, string subject, string message, string from, RelayInfo mailServer = RelayInfo("smtp://localhost")) {
|
||||||
auto msg = new EmailMessage();
|
auto msg = new EmailMessage();
|
||||||
msg.from = from;
|
msg.from = from;
|
||||||
|
@ -237,7 +241,7 @@ void email(string to, string subject, string message, string from, RelayInfo mai
|
||||||
|
|
||||||
import std.conv;
|
import std.conv;
|
||||||
|
|
||||||
// for reading
|
/// for reading
|
||||||
class MimePart {
|
class MimePart {
|
||||||
string[] headers;
|
string[] headers;
|
||||||
immutable(ubyte)[] content;
|
immutable(ubyte)[] content;
|
||||||
|
@ -520,12 +524,15 @@ class MimeContainer {
|
||||||
}
|
}
|
||||||
|
|
||||||
import std.algorithm : startsWith;
|
import std.algorithm : startsWith;
|
||||||
|
///
|
||||||
class IncomingEmailMessage {
|
class IncomingEmailMessage {
|
||||||
|
///
|
||||||
this(string[] lines) {
|
this(string[] lines) {
|
||||||
auto lns = cast(immutable(ubyte)[][])lines;
|
auto lns = cast(immutable(ubyte)[][])lines;
|
||||||
this(lns, false);
|
this(lns, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
this(ref immutable(ubyte)[][] mboxLines, bool asmbox=true) {
|
this(ref immutable(ubyte)[][] mboxLines, bool asmbox=true) {
|
||||||
|
|
||||||
enum ParseState {
|
enum ParseState {
|
||||||
|
@ -745,6 +752,14 @@ class IncomingEmailMessage {
|
||||||
foreach (char ch; textMessageBody) if (ch > ' ' && ch < 127) mmb ~= ch;
|
foreach (char ch; textMessageBody) if (ch > ' ' && ch < 127) mmb ~= ch;
|
||||||
textMessageBody = convertToUtf8Lossy(Base64.decode(mmb), charset);
|
textMessageBody = convertToUtf8Lossy(Base64.decode(mmb), charset);
|
||||||
}
|
}
|
||||||
|
if(htmlMessageBody.length) {
|
||||||
|
// alas, phobos' base64 decoder cannot accept ranges, so we have to allocate here
|
||||||
|
char[] mmb;
|
||||||
|
mmb.reserve(htmlMessageBody.length);
|
||||||
|
foreach (char ch; htmlMessageBody) if (ch > ' ' && ch < 127) mmb ~= ch;
|
||||||
|
htmlMessageBody = convertToUtf8Lossy(Base64.decode(mmb), charset);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// nothing needed
|
// nothing needed
|
||||||
|
@ -758,6 +773,7 @@ class IncomingEmailMessage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
@property bool hasGPGSignature () const nothrow @trusted @nogc {
|
@property bool hasGPGSignature () const nothrow @trusted @nogc {
|
||||||
MimePart mime = cast(MimePart)gpgmime; // sorry
|
MimePart mime = cast(MimePart)gpgmime; // sorry
|
||||||
if (mime is null) return false;
|
if (mime is null) return false;
|
||||||
|
@ -768,6 +784,7 @@ class IncomingEmailMessage {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
ubyte[] extractGPGData () const nothrow @trusted {
|
ubyte[] extractGPGData () const nothrow @trusted {
|
||||||
if (!hasGPGSignature) return null;
|
if (!hasGPGSignature) return null;
|
||||||
MimePart mime = cast(MimePart)gpgmime; // sorry
|
MimePart mime = cast(MimePart)gpgmime; // sorry
|
||||||
|
@ -800,29 +817,46 @@ class IncomingEmailMessage {
|
||||||
return cast(ubyte[])res;
|
return cast(ubyte[])res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
immutable(ubyte)[] extractGPGSignature () const nothrow @safe @nogc {
|
immutable(ubyte)[] extractGPGSignature () const nothrow @safe @nogc {
|
||||||
if (!hasGPGSignature) return null;
|
if (!hasGPGSignature) return null;
|
||||||
return gpgmime.stuff[1].content;
|
return gpgmime.stuff[1].content;
|
||||||
}
|
}
|
||||||
|
|
||||||
string[string] headers;
|
string[string] headers; ///
|
||||||
|
|
||||||
string subject;
|
string subject; ///
|
||||||
|
|
||||||
string htmlMessageBody;
|
string htmlMessageBody; ///
|
||||||
string textMessageBody;
|
string textMessageBody; ///
|
||||||
|
|
||||||
string from;
|
string from; ///
|
||||||
string to;
|
string to; ///
|
||||||
|
|
||||||
bool textAutoConverted;
|
bool textAutoConverted; ///
|
||||||
|
|
||||||
MimeAttachment[] attachments;
|
MimeAttachment[] attachments; ///
|
||||||
|
|
||||||
// gpg signature fields
|
// gpg signature fields
|
||||||
string gpgalg;
|
string gpgalg; ///
|
||||||
string gpgproto;
|
string gpgproto; ///
|
||||||
MimePart gpgmime;
|
MimePart gpgmime; ///
|
||||||
|
|
||||||
|
string fromEmailAddress() {
|
||||||
|
auto i = from.indexOf("<");
|
||||||
|
if(i == -1)
|
||||||
|
return from;
|
||||||
|
auto e = from.indexOf(">");
|
||||||
|
return from[i + 1 .. e];
|
||||||
|
}
|
||||||
|
|
||||||
|
string toEmailAddress() {
|
||||||
|
auto i = to.indexOf("<");
|
||||||
|
if(i == -1)
|
||||||
|
return to;
|
||||||
|
auto e = to.indexOf(">");
|
||||||
|
return to[i + 1 .. e];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MboxMessages {
|
struct MboxMessages {
|
||||||
|
@ -851,6 +885,7 @@ struct MboxMessages {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
MboxMessages processMboxData(immutable(ubyte)[] data) {
|
MboxMessages processMboxData(immutable(ubyte)[] data) {
|
||||||
return MboxMessages(data);
|
return MboxMessages(data);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue