diff --git a/cagette.hxml b/cagette.hxml
index 7671435..743b8c3 100644
--- a/cagette.hxml
+++ b/cagette.hxml
@@ -21,6 +21,7 @@
-lib tink_streams:0.2.1
-lib tink_syntaxhub:0.4.3
-lib tink_typecrawler:0.7.0
+-lib thx.text:0.2.1
## GIT
# -lib sugoi:git:https://git.artcode.re/cagetters/sugoi.git
diff --git a/lang/master/tpl/messages/default.mtt b/lang/master/tpl/messages/default.mtt
index b4e4d09..7ae734d 100644
--- a/lang/master/tpl/messages/default.mtt
+++ b/lang/master/tpl/messages/default.mtt
@@ -29,7 +29,7 @@
::_("Send an e-mail")::
-
+
::raw form::
diff --git a/src/controller/Messages.hx b/src/controller/Messages.hx
index 9a6f41c..4cb0cc2 100755
--- a/src/controller/Messages.hx
+++ b/src/controller/Messages.hx
@@ -51,7 +51,7 @@ class Messages extends Controller {
// send mail confirmation link
var e = new sugoi.mail.Mail();
- e.setSender(App.config.get("default_email"));
+ e.setSender(App.config.get("default_email"), t._("Cagette.net"));
e.setSubject(subject);
var replyTo = form.getValueOf("senderMail");
@@ -62,8 +62,6 @@ class Messages extends Controller {
for (x in mails)
e.addRecipient(x);
- // sender : default email ( explicitly tells that the server send an email on behalf of the user )
- // e.setHeader("Sender", App.config.get("default_email"));
var text:String = form.getValueOf("text");
var html = app.processTemplate("mail/message.mtt", {text: text, group: app.user.amap, list: getListName(listId)});
e.setHtmlBody(html);
@@ -84,6 +82,8 @@ class Messages extends Controller {
lm.insert();
throw Ok("/messages", t._("The message has been sent"));
+ } else {
+ App.log('Administrator #${app.user.id} <${senderName}> prepares sending an email from choices list');
}
view.form = form;
diff --git a/src/sugoi/mail/Mail.hx b/src/sugoi/mail/Mail.hx
index aa90aa9..862fbb9 100644
--- a/src/sugoi/mail/Mail.hx
+++ b/src/sugoi/mail/Mail.hx
@@ -1,45 +1,53 @@
package sugoi.mail;
+
using Lambda;
-class Mail implements IMail
-{
-
- public var title : String;
- public var htmlBody : String;
- public var textBody : String;
- var headers : Map;
- var sender : {name:String,email:String,?userId:Int};
- var recipients : Array<{name:String,email:String,?userId:Int}>;
-
-
-
+class Mail implements IMail {
+ public var title:String;
+ public var htmlBody:String;
+ public var textBody:String;
+
+ var headers:Map;
+ var sender:{name:String, email:String, ?userId:Int};
+ var recipients:Array<{name:String, email:String, ?userId:Int}>;
+
+ static public function fromString(name:String, email:String) {
+ if (name == null)
+ return email;
+ else {
+ var finalName = thx.text.Diactrics.clean(name);
+ return '${finalName} <${email}>';
+ }
+ }
+
public function new() {
recipients = [];
headers = new Map();
}
-
- public function getRecipients(){
+
+ public function getRecipients() {
return recipients;
}
-
- public function setSender(email, ?name,?userId) {
- if(!isValid(email)) throw "invalid sender email : \""+email+"\"";
-
- sender = {name:name,email:email,userId:userId};
+
+ public function setSender(email, ?name, ?userId) {
+ if (!isValid(email))
+ throw "invalid sender email : \"" + email + "\"";
+
+ sender = {name: name, email: email, userId: userId};
return this;
}
-
+
public function setReplyTo(email, ?name) {
- if(!isValid(email)) throw "invalid reply-to email : \""+email+"\"";
-
- setHeader("Reply-To","<"+email+">"+(name==null?"":name));
+ if (!isValid(email))
+ throw "invalid reply-to email : \"" + email + "\"";
+ setHeader("Reply-To", fromString(name, email));
}
-
+
public function setSubject(s:String) {
title = s;
return this;
}
-
+
/**
* can add one or more recipient
* @param email
@@ -47,11 +55,12 @@ class Mail implements IMail
* @param ?userId
*/
public function addRecipient(email:String, ?name:String, ?userId:Int) {
- if(!isValid(email)) throw "invalid recipient \""+email+"\"";
- recipients.push( {email:email, name:name, userId:userId } );
+ if (!isValid(email))
+ throw "invalid recipient \"" + email + "\"";
+ recipients.push({email: email, name: name, userId: userId});
return this;
}
-
+
/**
* alias to addRecipient()
* @param email
@@ -62,24 +71,24 @@ class Mail implements IMail
addRecipient(email, name, userId);
return this;
}
-
- public static function isValid( addr : String ){
+
+ public static function isValid(addr:String) {
var reg = ~/^[^()<>@,;:\\"\[\]\s[:cntrl:]]+@[A-Z0-9][A-Z0-9-]*(\.[A-Z0-9][A-Z0-9-]*)*\.(xn--[A-Z0-9]+|[A-Z]{2,8})$/i;
return addr != null && reg.match(addr);
}
-
+
public function setHeader(k:String, v:String) {
headers.set(k, v);
return this;
}
-
+
/**
* generate a custom key for transactionnal emails, valid during the current day
*/
public function getKey() {
- return haxe.crypto.Md5.encode(App.config.get("key")+recipients[0].email+(Date.now().getDate())).substr(0,12);
+ return haxe.crypto.Md5.encode(App.config.get("key") + recipients[0].email + (Date.now().getDate())).substr(0, 12);
}
-
+
/**
* render html from a template + vars
* @param tpl A Template path
@@ -88,7 +97,8 @@ class Mail implements IMail
public function setHtmlBodyWithTemplate(tpl, ctx:Dynamic) {
var app = App.current;
var tpl = app.loadTemplate(tpl);
- if( ctx == null ) ctx = { };
+ if (ctx == null)
+ ctx = {};
ctx.HOST = App.config.HOST;
ctx.key = getKey();
ctx.senderName = sender.name;
@@ -98,28 +108,27 @@ class Mail implements IMail
ctx.recipients = recipients;
CSSInlining(ctx);
htmlBody = tpl.execute(ctx);
-
}
-
+
public function setHtmlBody(s) {
htmlBody = s;
return this;
}
-
- public function setTextBodyWithTemplate(tpl, ctx:Dynamic) {
+
+ public function setTextBodyWithTemplate(tpl, ctx:Dynamic) {
var app = App.current;
var tpl = app.loadTemplate(tpl);
- if( ctx == null ) ctx = { };
+ if (ctx == null)
+ ctx = {};
ctx.HOST = App.config.HOST;
ctx.key = getKey();
textBody = tpl.execute(ctx);
return this;
}
-
function CSSInlining(ctx) {
// CSS inlining
- var css : Map> = new Map();
+ var css:Map> = new Map();
ctx.addStyle = function(sel:String, style:String) {
sel = sel.toLowerCase();
if (css.exists(sel))
@@ -130,11 +139,11 @@ class Mail implements IMail
}
var applyStyleRec = null;
applyStyleRec = function(x:Xml) {
- if (x.nodeType==Xml.Element) {
+ if (x.nodeType == Xml.Element) {
var name = x.nodeName.toLowerCase();
- if( css.exists(name) )
- if (x.get("style")!=null)
- x.set("style", x.get("style")+";"+css.get(name).join(";"));
+ if (css.exists(name))
+ if (x.get("style") != null)
+ x.set("style", x.get("style") + ";" + css.get(name).join(";"));
else
x.set("style", css.get(name).join(";"));
for (n in x)
@@ -143,40 +152,38 @@ class Mail implements IMail
}
ctx.applyStyle = function(raw:String) {
var x = Xml.parse(raw);
- for(n in x)
+ for (n in x)
applyStyleRec(n);
return x.toString();
}
}
-
-
- public function getSubject(){
+
+ public function getSubject() {
return title;
}
- public function getTitle(){
+ public function getTitle() {
return getSubject();
}
-
- public function getHtmlBody(){
+
+ public function getHtmlBody() {
return htmlBody;
}
-
- public function getTextBody(){
+
+ public function getTextBody() {
return textBody;
}
-
- public function setTextBody(t){
+
+ public function setTextBody(t) {
textBody = t;
return this;
}
-
- public function getHeaders(){
+
+ public function getHeaders() {
return headers;
}
-
- public function getSender(){
+
+ public function getSender() {
return sender;
}
-
-}
\ No newline at end of file
+}
diff --git a/src/sugoi/mail/SendEmailMailer.hx b/src/sugoi/mail/SendEmailMailer.hx
index 7335824..fd298b8 100644
--- a/src/sugoi/mail/SendEmailMailer.hx
+++ b/src/sugoi/mail/SendEmailMailer.hx
@@ -40,17 +40,13 @@ class SendEmailMailer implements IMailer {
return mailer;
}
- private function fromString(name:String, email:String) {
- return (name == null) ? email : '${name} <${email}>';
- }
-
public function send(e:sugoi.mail.IMail, ?params:Dynamic, ?callback:MailerResult->Void) {
var to:String;
var bcc:String;
var recipientCounts = e.getRecipients().length;
if (recipientCounts > 1) {
- to = fromString(e.getSender().name, e.getSender().email);
+ to = sugoi.mail.Mail.fromString(e.getSender().name, e.getSender().email);
bcc = [for (i in e.getRecipients()) i.email].join(",");
App.log('recipients has been transformed to ${recipientCounts} bcc');
App.log(bcc);
@@ -72,26 +68,35 @@ class SendEmailMailer implements IMailer {
"-o",
"message-format=html",
"-o",
- "X-Mailer=CagettePei",
+ "message-header=X-Mailer: CagettePei",
"-f",
- fromString(e.getSender().name, e.getSender().email),
+ sugoi.mail.Mail.fromString(e.getSender().name, e.getSender().email),
"-t",
to,
"-bcc",
bcc,
"-u",
e.getSubject(),
- "-m",
- '${e.getHtmlBody()}',
];
+ // FIME: deal with replyTo
+ if (e.getHeaders().exists("Reply-To")) {
+ var replyTo = e.getHeaders()["Reply-To"];
+ App.log('replyTo "$replyTo" detected');
+ args.push("-o");
+ args.push('message-header=Reply-To: ${replyTo}');
+ }
+
+ args.push("-m");
+ args.push('${e.getHtmlBody()}');
+
// if (App.config.DEBUG)
// App.log('args=${args.join(" ")}');
var exitCode = Sys.command("sendemail", args);
// var exitCode = 0;
- var summary = 'email from="${fromString(e.getSender().name, e.getSender().email)}"> subject=<${e.getSubject()}>';
+ var summary = 'email from="${sugoi.mail.Mail.fromString(e.getSender().name, e.getSender().email)}" subject=<${e.getSubject()}>';
if (exitCode == 0)
App.log('$summary successfully sent');
else
diff --git a/src/sugoi/mail/SmtpMailer.hx b/src/sugoi/mail/SmtpMailer.hx
deleted file mode 100644
index aa52f5d..0000000
--- a/src/sugoi/mail/SmtpMailer.hx
+++ /dev/null
@@ -1,68 +0,0 @@
-package sugoi.mail;
-import tink.core.Future;
-import tink.core.Noise;
-import sugoi.mail.IMailer;
-import smtpmailer.Address;
-
-/**
- * Send emails thru SMTP by using ben merckx's library
- * @ref https://github.com/benmerckx/smtpmailer
- */
-class SmtpMailer implements IMailer
-{
- var m : smtpmailer.SmtpMailer;
-
- public function new(){}
-
- public function init(?conf:{smtp_host:String,smtp_port:Int,smtp_user:String,smtp_pass:String}) :IMailer
- {
- m = new smtpmailer.SmtpMailer({
- host: conf.smtp_host,
- port: conf.smtp_port,
- auth: {
- username: conf.smtp_user,
- password: conf.smtp_pass
- }
- });
-
- return this;
- }
-
- public function send(e:sugoi.mail.IMail,?params:Dynamic,?callback:MailerResult->Void)
- {
- var surprise = m.send({
- subject: e.getSubject(),
- /*from: e.getSender().email,
- to: Lambda.array(Lambda.map(e.getRecipients(), function(x) return smtpmailer.Address.ofString(x.email) )),
- //headers : e.getHeaders(),*/
- from: new Address({address:e.getSender().email}),
- to: Lambda.array(Lambda.map(e.getRecipients(), function(x) return new Address({address:x.email}) )),
- headers : e.getHeaders(),
- content: {
- text: e.getTextBody(),
- html: e.getHtmlBody()
- }/*,
- attachments: []*/
- });
-
-
- if (callback != null){
-
- surprise.handle(function(s){
-
- var map = new MailerResult();
-
- switch(s){
- case Success(_):
- map.set("*",Success(Sent));
-
- case Failure(e):
- map.set("*",Failure(GenericError(e)));
- }
-
- callback(map);
- });
- }
- }
-
-}
\ No newline at end of file