aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--go.mod1
-rw-r--r--go.sum2
-rw-r--r--plugins/base/handlers.go46
-rw-r--r--plugins/base/plugin.go2
-rw-r--r--plugins/base/public/message.html10
5 files changed, 59 insertions, 2 deletions
diff --git a/go.mod b/go.mod
index 9cd983b..5b738dc 100644
--- a/go.mod
+++ b/go.mod
@@ -4,6 +4,7 @@ go 1.13
require (
github.com/emersion/go-imap v1.0.3-0.20191213134403-f1c945935a36
+ github.com/emersion/go-imap-move v0.0.0-20190710073258-6e5a51a5b342
github.com/emersion/go-message v0.10.8
github.com/emersion/go-sasl v0.0.0-20191210011802-430746ea8b9b
github.com/emersion/go-smtp v0.12.1
diff --git a/go.sum b/go.sum
index b3e2bbe..585c322 100644
--- a/go.sum
+++ b/go.sum
@@ -8,6 +8,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumC
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/emersion/go-imap v1.0.3-0.20191213134403-f1c945935a36 h1:CrPKMqbfsFwzOFqqXd43j40NfCKJUgm6niLJhklQkrA=
github.com/emersion/go-imap v1.0.3-0.20191213134403-f1c945935a36/go.mod h1:TjT+1ncDso8j/VXeUHcZeQknho5hjyQLqEIybJJjjDI=
+github.com/emersion/go-imap-move v0.0.0-20190710073258-6e5a51a5b342 h1:5p1t3e1PomYgLWwEwhwEU5kVBwcyAcVrOpexv8AeZx0=
+github.com/emersion/go-imap-move v0.0.0-20190710073258-6e5a51a5b342/go.mod h1:QuMaZcKFDVI0yCrnAbPLfbwllz1wtOrZH8/vZ5yzp4w=
github.com/emersion/go-message v0.10.8 h1:1l1Vb+0By9U1ITTH3FgKfJQWQ9sTI3N1smPe6SS3QXY=
github.com/emersion/go-message v0.10.8/go.mod h1:C4jnca5HOTo4bGN9YdqNQM9sITuT3Y0K6bSUw9RklvY=
github.com/emersion/go-sasl v0.0.0-20190817083125-240c8404624e h1:ba7YsgX5OV8FjGi5ZWml8Jng6oBrJAb3ahqWMJ5Ce8Q=
diff --git a/plugins/base/handlers.go b/plugins/base/handlers.go
index 8e9971a..d77cd4a 100644
--- a/plugins/base/handlers.go
+++ b/plugins/base/handlers.go
@@ -12,6 +12,7 @@ import (
"git.sr.ht/~emersion/koushin"
"github.com/emersion/go-imap"
imapclient "github.com/emersion/go-imap/client"
+ imapmove "github.com/emersion/go-imap-move"
"github.com/emersion/go-message"
"github.com/emersion/go-smtp"
"github.com/labstack/echo/v4"
@@ -120,6 +121,7 @@ func handleLogout(ectx echo.Context) error {
type MessageRenderData struct {
koushin.RenderData
+ Mailboxes []*imap.MailboxInfo
Mailbox *imap.MailboxStatus
Message *IMAPMessage
Body string
@@ -138,14 +140,20 @@ func handleGetPart(ctx *koushin.Context, raw bool) error {
return echo.NewHTTPError(http.StatusBadRequest, err)
}
+ var mailboxes []*imap.MailboxInfo
var msg *IMAPMessage
var part *message.Entity
var mbox *imap.MailboxStatus
err = ctx.Session.DoIMAP(func(c *imapclient.Client) error {
var err error
- msg, part, err = getMessagePart(c, mboxName, uid, partPath)
+ if mailboxes, err = listMailboxes(c); err != nil {
+ return err
+ }
+ if msg, part, err = getMessagePart(c, mboxName, uid, partPath); err != nil {
+ return err
+ }
mbox = c.Mailbox()
- return err
+ return nil
})
if err != nil {
return err
@@ -187,6 +195,7 @@ func handleGetPart(ctx *koushin.Context, raw bool) error {
return ctx.Render(http.StatusOK, "message.html", &MessageRenderData{
RenderData: *koushin.NewRenderData(ctx),
+ Mailboxes: mailboxes,
Mailbox: mbox,
Message: msg,
Body: body,
@@ -296,3 +305,36 @@ func handleCompose(ectx echo.Context) error {
Message: &msg,
})
}
+
+func handleMove(ectx echo.Context) error {
+ ctx := ectx.(*koushin.Context)
+
+ mboxName, uid, err := parseMboxAndUid(ctx.Param("mbox"), ctx.Param("uid"))
+ if err != nil {
+ return echo.NewHTTPError(http.StatusBadRequest, err)
+ }
+
+ to := ctx.FormValue("to")
+
+ err = ctx.Session.DoIMAP(func(c *imapclient.Client) error {
+ mc := imapmove.NewClient(c)
+
+ if err := ensureMailboxSelected(c, mboxName); err != nil {
+ return err
+ }
+
+ var seqSet imap.SeqSet
+ seqSet.AddNum(uid)
+ if err := mc.UidMoveWithFallback(&seqSet, to); err != nil {
+ return fmt.Errorf("failed to move message: %v", err)
+ }
+
+ // TODO: get the UID of the message in the destination mailbox with UIDPLUS
+ return nil
+ })
+ if err != nil {
+ return err
+ }
+
+ return ctx.Redirect(http.StatusFound, fmt.Sprintf("/mailbox/%v", to))
+}
diff --git a/plugins/base/plugin.go b/plugins/base/plugin.go
index 7c2aeaf..7eaf00c 100644
--- a/plugins/base/plugin.go
+++ b/plugins/base/plugin.go
@@ -45,5 +45,7 @@ func init() {
p.GET("/message/:mbox/:uid/reply", handleCompose)
p.POST("/message/:mbox/:uid/reply", handleCompose)
+ p.POST("/message/:mbox/:uid/move", handleMove)
+
koushin.RegisterPlugin(p.Plugin())
}
diff --git a/plugins/base/public/message.html b/plugins/base/public/message.html
index 729937d..2a0ab71 100644
--- a/plugins/base/public/message.html
+++ b/plugins/base/public/message.html
@@ -16,6 +16,16 @@
{{end}}
</h2>
+<form method="post" action="{{.Message.Uid}}/move">
+ <label for="move-to">Move to:</label>
+ <select name="to" id="move-to">
+ {{range .Mailboxes}}
+ <option {{if eq .Name $.Mailbox.Name}}selected{{end}}>{{.Name}}</option>
+ {{end}}
+ </select>
+ <input type="submit" value="Move">
+</form>
+
{{define "message-part-tree"}}
{{/* nested templates can't access the parent's context */}}
{{$ = index . 0}}