From 08b259bd50155c53259ae60042c8626a3615a993 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Mon, 16 Dec 2019 15:40:30 +0100 Subject: Add attachments support to composer Closes: https://todo.sr.ht/~sircmpwn/koushin/13 --- plugins/base/handlers.go | 8 ++++++- plugins/base/public/compose.html | 9 +++++--- plugins/base/smtp.go | 49 ++++++++++++++++++++++++++++++++++++---- 3 files changed, 57 insertions(+), 9 deletions(-) diff --git a/plugins/base/handlers.go b/plugins/base/handlers.go index 133052c..e939cc5 100644 --- a/plugins/base/handlers.go +++ b/plugins/base/handlers.go @@ -270,7 +270,13 @@ func handleCompose(ectx echo.Context) error { msg.Text = ctx.FormValue("text") msg.InReplyTo = ctx.FormValue("in_reply_to") - err := ctx.Session.DoSMTP(func(c *smtp.Client) error { + form, err := ctx.MultipartForm() + if err != nil { + return fmt.Errorf("failed to get multipart form: %v", err) + } + msg.Attachments = form.File["attachments"] + + err = ctx.Session.DoSMTP(func(c *smtp.Client) error { return sendMessage(c, &msg) }) if err != nil { diff --git a/plugins/base/public/compose.html b/plugins/base/public/compose.html index 5f0b904..0e16acf 100644 --- a/plugins/base/public/compose.html +++ b/plugins/base/public/compose.html @@ -8,14 +8,14 @@

Compose new message

-
+ - +

- +

@@ -23,6 +23,9 @@


+ + +

diff --git a/plugins/base/smtp.go b/plugins/base/smtp.go index 9ade78f..81da6ef 100644 --- a/plugins/base/smtp.go +++ b/plugins/base/smtp.go @@ -4,6 +4,7 @@ import ( "bufio" "fmt" "io" + "mime/multipart" "strings" "time" @@ -26,17 +27,49 @@ func quote(r io.Reader) (string, error) { } type OutgoingMessage struct { - From string - To []string - Subject string - InReplyTo string - Text string + From string + To []string + Subject string + InReplyTo string + Text string + Attachments []*multipart.FileHeader } func (msg *OutgoingMessage) ToString() string { return strings.Join(msg.To, ", ") } +func writeAttachment(mw *mail.Writer, att *multipart.FileHeader) error { + var h mail.AttachmentHeader + h.Set("Content-Type", att.Header.Get("Content-Type")) + h.SetFilename(att.Filename) + + aw, err := mw.CreateAttachment(h) + if err != nil { + return fmt.Errorf("failed to create attachment: %v", err) + } + defer aw.Close() + + f, err := att.Open() + if err != nil { + return fmt.Errorf("failed to open attachment: %v", err) + } + defer f.Close() + + if _, err := io.Copy(aw, f); err != nil { + return fmt.Errorf("failed to write attachment: %v", err) + } + + if err := f.Close(); err != nil { + return fmt.Errorf("failed to close attachment: %v", err) + } + if err := aw.Close(); err != nil { + return fmt.Errorf("failed to close attachment writer: %v", err) + } + + return nil +} + func (msg *OutgoingMessage) WriteTo(w io.Writer) error { from := []*mail.Address{{"", msg.From}} @@ -78,6 +111,12 @@ func (msg *OutgoingMessage) WriteTo(w io.Writer) error { return fmt.Errorf("failed to close text part: %v", err) } + for _, att := range msg.Attachments { + if err := writeAttachment(mw, att); err != nil { + return err + } + } + if err := mw.Close(); err != nil { return fmt.Errorf("failed to close mail writer: %v", err) } -- cgit v1.2.3