From 7629c5aa8ebc413c0b2a3a7edac9262b36b011b8 Mon Sep 17 00:00:00 2001 From: MrMelon54 Date: Mon, 11 Sep 2023 22:42:51 +0100 Subject: [PATCH] Add better list and fetch actions --- api/api.go | 26 ----------------- imap/client.go | 75 +++++++++++++++++++++++++++----------------------- 2 files changed, 40 insertions(+), 61 deletions(-) diff --git a/api/api.go b/api/api.go index fce1107..ccaac43 100644 --- a/api/api.go +++ b/api/api.go @@ -3,7 +3,6 @@ package api import ( "bytes" "encoding/json" - "github.com/1f349/lotus/imap" "github.com/gorilla/websocket" "github.com/julienschmidt/httprouter" "log" @@ -141,28 +140,3 @@ func apiError(rw http.ResponseWriter, code int, m string) { "error": m, }) } - -type IcCallback[T any] func(rw http.ResponseWriter, req *http.Request, params httprouter.Params, cli *imap.Client, t T) error - -func imapClient[T any](recv Imap, cb IcCallback[T]) AuthCallback { - return func(rw http.ResponseWriter, req *http.Request, params httprouter.Params, b AuthClaims) { - if req.Body == nil { - rw.WriteHeader(http.StatusBadRequest) - return - } - var t T - if json.NewDecoder(req.Body).Decode(&t) != nil { - rw.WriteHeader(http.StatusBadRequest) - return - } - cli, err := recv.MakeClient(b.Subject) - if err != nil { - rw.WriteHeader(http.StatusInternalServerError) - return - } - err = cb(rw, req, params, cli, t) - if err != nil { - log.Println("[ImapClient] Error:", err) - } - } -} diff --git a/imap/client.go b/imap/client.go index f85c162..279b010 100644 --- a/imap/client.go +++ b/imap/client.go @@ -1,9 +1,10 @@ package imap import ( + "errors" "github.com/emersion/go-imap" "github.com/emersion/go-imap/client" - "time" + "strconv" ) var imapStatusFlags = []imap.StatusItem{ @@ -18,6 +19,8 @@ type Client struct { ic *client.Client } +var ErrInvalidArguments = errors.New("invalid arguments") + func (c *Client) HandleWS(action string, args []string) (map[string]any, error) { switch action { case "copy": @@ -26,23 +29,42 @@ func (c *Client) HandleWS(action string, args []string) (map[string]any, error) // TODO: implementation case "delete": // TODO: implementation - case "select": - // TODO: implementation - case "fetch": - // TODO: implementation case "list": - a := make([]*imap.MailboxInfo, 0) - b := make(chan *imap.MailboxInfo, 10) - go func() { - for info := range b { - a = append(a, info) - } - }() - err := c.ic.List(args[0], args[1], b) + if len(args) != 2 { + return nil, ErrInvalidArguments + } + + // do list + list, err := c.list(args[0], args[1]) if err != nil { return nil, err } - return map[string]any{"info": a}, nil + return map[string]any{"type": "list", "value": list}, nil + case "fetch": + if len(args) != 4 { + return nil, ErrInvalidArguments + } + + // parse numeric parameters + arg1i, err := strconv.Atoi(args[1]) + if err != nil { + return nil, err + } + arg2i, err := strconv.Atoi(args[2]) + if err != nil { + return nil, err + } + arg3i, err := strconv.Atoi(args[3]) + if err != nil { + return nil, err + } + + // do fetch + fetch, err := c.fetch(args[0], uint32(arg1i), uint32(arg2i), uint32(arg3i)) + if err != nil { + return nil, err + } + return map[string]any{"type": "fetch", "value": fetch}, nil case "move": // TODO: implementation case "rename": @@ -52,27 +74,10 @@ func (c *Client) HandleWS(action string, args []string) (map[string]any, error) case "status": // TODO: implementation } - _ = args - return map[string]any{"Error": "Not implemented"}, nil + return map[string]any{"error": "Not implemented"}, nil } -func (c *Client) Append(name string, flags []string, date time.Time, msg imap.Literal) error { - return c.ic.Append(name, flags, date, msg) -} - -func (c *Client) Copy(seqset *imap.SeqSet, dest string) error { - return c.ic.Copy(seqset, dest) -} - -func (c *Client) Create(name string) error { - return c.ic.Create(name) -} - -func (c *Client) Delete(name string) error { - return c.ic.Delete(name) -} - -func (c *Client) Fetch(folder string, start, end, limit uint32) ([]*imap.Message, error) { +func (c *Client) fetch(folder string, start, end, limit uint32) ([]*imap.Message, error) { // select the mailbox mbox, err := c.ic.Select(folder, false) if err != nil { @@ -92,7 +97,7 @@ func (c *Client) Fetch(folder string, start, end, limit uint32) ([]*imap.Message messages := make(chan *imap.Message, limit) done := make(chan error, 1) go func() { - done <- c.ic.Fetch(seqSet, []imap.FetchItem{imap.FetchEnvelope}, messages) + done <- c.ic.Fetch(seqSet, []imap.FetchItem{imap.FetchEnvelope, imap.FetchUid, imap.FetchFlags}, messages) }() out := make([]*imap.Message, 0, limit) @@ -105,7 +110,7 @@ func (c *Client) Fetch(folder string, start, end, limit uint32) ([]*imap.Message return out, nil } -func (c *Client) List(ref, name string) ([]*imap.MailboxInfo, error) { +func (c *Client) list(ref, name string) ([]*imap.MailboxInfo, error) { infos := make(chan *imap.MailboxInfo, 1) done := make(chan error, 1) go func() {