diff options
author | René 'Necoro' Neumann <necoro@necoro.eu> | 2020-04-19 21:39:25 +0200 |
---|---|---|
committer | René 'Necoro' Neumann <necoro@necoro.eu> | 2020-04-19 21:39:25 +0200 |
commit | fe3d64998545eb4fbddb26e79eefeb3fa89bbbdd (patch) | |
tree | d8bb342b7a9eb53e6b683c464dbac5a75b0a3223 /internal/imap/client.go | |
parent | 9a40a801279041a2bffd2a8022f13e53ca6d36b9 (diff) | |
download | feed2imap-go-fe3d64998545eb4fbddb26e79eefeb3fa89bbbdd.tar.gz feed2imap-go-fe3d64998545eb4fbddb26e79eefeb3fa89bbbdd.tar.bz2 feed2imap-go-fe3d64998545eb4fbddb26e79eefeb3fa89bbbdd.zip |
Split client part to client.go
Diffstat (limited to 'internal/imap/client.go')
-rw-r--r-- | internal/imap/client.go | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/internal/imap/client.go b/internal/imap/client.go new file mode 100644 index 0000000..7440ed7 --- /dev/null +++ b/internal/imap/client.go @@ -0,0 +1,128 @@ +package imap + +import ( + "fmt" + "strings" + + "github.com/emersion/go-imap" + imapClient "github.com/emersion/go-imap/client" + + "github.com/Necoro/feed2imap-go/internal/log" +) + +type Client struct { + c *imapClient.Client + host string + folders folders + delimiter string + toplevel string +} + +type folders map[string]*imap.MailboxInfo + +func (f folders) contains(elem string) bool { + _, ok := f[elem] + return ok +} + +func (f folders) add(elem *imap.MailboxInfo) { + name := elem.Name + f[name] = elem +} + +func (client *Client) Disconnect() { + if client != nil { + connected := (client.c.State() & imap.ConnectedState) != 0 + _ = client.c.Logout() + + if connected { + log.Print("Disconnected from ", client.host) + } + } +} + +func (client *Client) FolderName(path []string) string { + return strings.Join(path, client.delimiter) +} + +func (client *Client) createFolder(folder string) error { + err := client.c.Create(folder) + if err != nil { + return fmt.Errorf("creating folder '%s': %w", folder, err) + } + + err = client.c.Subscribe(folder) + if err != nil { + return fmt.Errorf("subscribing to folder '%s': %w", folder, err) + } + + log.Printf("Created folder '%s'", folder) + + return nil +} + +func (client *Client) list(folder string) (*imap.MailboxInfo, int, error) { + mailboxes := make(chan *imap.MailboxInfo, 10) + done := make(chan error, 1) + go func() { + done <- client.c.List("", folder, mailboxes) + }() + + found := 0 + var mbox *imap.MailboxInfo + for m := range mailboxes { + if found == 0 { + mbox = m + } + found++ + } + + if err := <-done; err != nil { + return nil, 0, fmt.Errorf("while listing '%s': %w", folder, err) + } + + return mbox, found, nil +} + +func (client *Client) selectToplevel() (err error) { + err = client.EnsureFolder(client.toplevel) + + if err == nil { + _, err = client.c.Select(client.toplevel, false) + } + + return +} + +func (client *Client) fetchDelimiter() error { + mbox, _, err := client.list("") + if err != nil { + return err + } + + client.delimiter = mbox.Delimiter + return nil +} + +func (client *Client) EnsureFolder(folder string) error { + + if client.folders.contains(folder) { + return nil + } + + log.Printf("Checking for folder '%s'", folder) + + mbox, found, err := client.list(folder) + + switch { + case err != nil: + return err + case found == 0: + return client.createFolder(folder) + case found == 1: + client.folders.add(mbox) + return nil + default: + return fmt.Errorf("Found multiple folders matching '%s'.", folder) + } +} |