diff --git a/cmd/trello2mail/email.go b/cmd/trello2mail/email.go index 4cfb087..807d6a8 100644 --- a/cmd/trello2mail/email.go +++ b/cmd/trello2mail/email.go @@ -1,21 +1,35 @@ package main +// TODO: use https://github.com/domodwyer/mailyak as a base lib + import ( "bytes" + "encoding/base64" "fmt" - "github.com/davecgh/go-spew/spew" + // "github.com/davecgh/go-spew/spew" "strings" // "log" // "strconv" + "math/rand" "net/mail" ) type EmailHeaders map[string]string -type EmailBody string type EmailCtx struct { - Headers EmailHeaders - Body EmailBody + Headers EmailHeaders + BodyPlain string + BodyHtml string +} + +const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + +func RandStringBytes(n int) string { + b := make([]byte, n) + for i := range b { + b[i] = letterBytes[rand.Intn(len(letterBytes))] + } + return string(b) } func (headers EmailHeaders) String() string { @@ -26,14 +40,6 @@ func (headers EmailHeaders) String() string { return buffer.String() } -func (body EmailBody) String() string { - res := string(body) - if false { - spew.Dump(res) - } - return res -} - func NewEmail() *EmailCtx { email := EmailCtx{} email.Headers = make(EmailHeaders) @@ -46,23 +52,57 @@ func encodeRFC2047(text string) string { return strings.Trim(addr.String(), " \"<@>") } -func (email *EmailCtx) MakeHeaders(config EmailConfig) { +func (email *EmailCtx) SetHeaders(config EmailConfig) { email.Headers["Return-Path"] = config.From email.Headers["From"] = config.From email.Headers["To"] = config.To email.Headers["Subject"] = encodeRFC2047(config.Subject) - // email.Headers["Content-Type"] = "text/plain; charset=\"us-ascii\";" - email.Headers["Content-Type"] = "text/plain; charset=\"utf-8\";" - email.Headers["Content-Transfer-Encoding"] = "base64" + email.Headers["Content-Transfer-Encoding"] = "quoted-printable" email.Headers["MIME-Version"] = "1.0" return } -func (email *EmailCtx) MakeBody(content string) { - email.Body = EmailBody(content) - if false { - spew.Dump(email.Body) - } +func (email *EmailCtx) SetBody(html string, plain string) { + email.BodyPlain = plain + email.BodyHtml = html return } + +func (email *EmailCtx) String() string { + var buffer bytes.Buffer + mixBoundary := RandStringBytes(16) + altBoundary := RandStringBytes(16) + + buffer.WriteString(email.Headers.String()) + buffer.WriteString(fmt.Sprintf("Content-Type: multipart/mixed;\r\n boundary=\"%s\"\r\n", mixBoundary)) + buffer.WriteString("\r\n") + + buffer.WriteString(fmt.Sprintf("--%s\r\n", mixBoundary)) + buffer.WriteString(fmt.Sprintf("Content-Type: multipart/alternative;\r\n boundary=\"%s\"\r\n", altBoundary)) + buffer.WriteString("\r\n") + + buffer.WriteString(fmt.Sprintf("--%s\r\n", altBoundary)) + buffer.WriteString(fmt.Sprintf("Content-Type: text/plain; charset=\"utf-8\"\r\n")) + buffer.WriteString(fmt.Sprintf("Content-Transfer-Encoding: base64\r\n")) + buffer.WriteString("\r\n") + buffer.WriteString(base64.StdEncoding.EncodeToString([]byte(email.BodyPlain))) + buffer.WriteString("\r\n") + buffer.WriteString("\r\n") + + buffer.WriteString(fmt.Sprintf("--%s\r\n", altBoundary)) + buffer.WriteString(fmt.Sprintf("Content-Type: text/html; charset=\"utf-8\"\r\n")) + buffer.WriteString(fmt.Sprintf("Content-Transfer-Encoding: base64\r\n")) + buffer.WriteString("\r\n") + buffer.WriteString(base64.StdEncoding.EncodeToString([]byte(email.BodyHtml))) + buffer.WriteString("\r\n") + buffer.WriteString("\r\n") + + buffer.WriteString(fmt.Sprintf("--%s--\r\n", altBoundary)) + buffer.WriteString("\r\n") + + buffer.WriteString(fmt.Sprintf("--%s--\r\n", mixBoundary)) + buffer.WriteString("\r\n") + + return buffer.String() +} diff --git a/cmd/trello2mail/main.go b/cmd/trello2mail/main.go index c2b1322..ac2b1a7 100644 --- a/cmd/trello2mail/main.go +++ b/cmd/trello2mail/main.go @@ -1,8 +1,9 @@ package main import ( -// "gopkg.in/russross/blackfriday.v2" -// "github.com/davecgh/go-spew/spew" + "fmt" + // "gopkg.in/russross/blackfriday.v2" + // "github.com/davecgh/go-spew/spew" ) func main() { @@ -14,11 +15,13 @@ func main() { trelloCtx := NewTrello(config.Trello.Token) trelloBoard := trelloCtx.GetBoard(config.Trello.Url) trelloMarkdown := trelloBoard.ExportToMarkdown() + trelloHtml := trelloBoard.ExportToHtml() + config.Email.Subject = fmt.Sprintf("Daily mail for %s", trelloBoard.Name) // Create email enveloppe email := NewEmail() - email.MakeHeaders(config.Email) - email.MakeBody(trelloMarkdown) + email.SetHeaders(config.Email) + email.SetBody(trelloHtml, trelloMarkdown) // Connect and send email transport := NewTransport(config.Smtp) diff --git a/cmd/trello2mail/transport.go b/cmd/trello2mail/transport.go index 534b711..32fba2b 100644 --- a/cmd/trello2mail/transport.go +++ b/cmd/trello2mail/transport.go @@ -3,7 +3,6 @@ package main import ( "bytes" "crypto/tls" - "encoding/base64" "fmt" "log" "net/smtp" @@ -122,11 +121,7 @@ func (ctx *TransportCtx) Send(email *EmailCtx) { } defer wc.Close() - var buffer bytes.Buffer - buffer.WriteString(email.Headers.String()) - buffer.WriteString("\r\n") - buffer.WriteString(base64.StdEncoding.EncodeToString([]byte(email.Body.String()))) - + buffer := bytes.NewBufferString(email.String()) if _, err = buffer.WriteTo(wc); err != nil { log.Panic(err) } diff --git a/cmd/trello2mail/trello.go b/cmd/trello2mail/trello.go index e420c8f..af6b13b 100644 --- a/cmd/trello2mail/trello.go +++ b/cmd/trello2mail/trello.go @@ -4,8 +4,6 @@ import ( "bytes" "fmt" "github.com/adlio/trello" - // "github.com/davecgh/go-spew/spew" - "gopkg.in/russross/blackfriday.v2" "log" "net/url" @@ -24,8 +22,9 @@ type TrelloCtx struct { } type TrelloBoard struct { - Ctx *TrelloCtx - Ptr *trello.Board + Ctx *TrelloCtx + Ptr *trello.Board + Name string } func runcmd(command string) string { @@ -75,10 +74,8 @@ func (ctx *TrelloCtx) GetBoard(boardUrl string) TrelloBoard { } boardId := strings.Split(parsedUrl.Path, "/")[2] - // spew.Dump(boardId) board, err := ctx.Client.GetBoard(boardId, trello.Defaults()) - // spew.Dump(board) - return TrelloBoard{Ctx: ctx, Ptr: board} + return TrelloBoard{Ctx: ctx, Ptr: board, Name: board.Name} } func (board *TrelloBoard) ExportToMarkdown() string { @@ -108,7 +105,6 @@ func (board *TrelloBoard) ExportToMarkdown() string { for _, card := range cards { text := fmt.Sprintf("* %s\n", card.Name) markdown.WriteString(text) - // spew.Dump(card) } } return markdown.String()