Add attachments support to composer

Closes: https://todo.sr.ht/~sircmpwn/koushin/13
This commit is contained in:
Simon Ser 2019-12-16 15:40:30 +01:00
parent 7f48702b83
commit 08b259bd50
No known key found for this signature in database
GPG key ID: 0FDE7BE0E88F5E48
3 changed files with 57 additions and 9 deletions

View file

@ -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 {

View file

@ -8,14 +8,14 @@
<h2>Compose new message</h2>
<form method="post" action="">
<form method="post" action="" enctype="multipart/form-data">
<input type="hidden" name="in_reply_to" value="{{.Message.InReplyTo}}">
<label for="from">From:</label>
<input type="email" name="from" id="from" value="{{.Message.From}}">
<input type="email" name="from" id="from" required value="{{.Message.From}}">
<br><br>
<label for="to">To:</label>
<input type="email" name="to" id="to" multiple value="{{.Message.ToString}}">
<input type="email" name="to" id="to" multiple required value="{{.Message.ToString}}">
<br><br>
<label for="subject">Subject:</label>
<input type="text" name="subject" id="subject" value="{{.Message.Subject}}">
@ -23,6 +23,9 @@
<label for="text">Body:</label><br>
<textarea name="text" id="text" cols="80" rows="20">{{.Message.Text}}</textarea>
<br><br>
<label for="attachments">Attachments:</label>
<input type="file" name="attachments" id="attachments" multiple>
<br><br>
<input type="submit" value="Send">
</form>

View file

@ -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)
}