diff options
-rw-r--r-- | internal/imap/client.go | 75 | ||||
-rw-r--r-- | internal/imap/imap.go | 10 | ||||
-rw-r--r-- | main.go | 30 |
3 files changed, 80 insertions, 35 deletions
diff --git a/internal/imap/client.go b/internal/imap/client.go index 7569fb8..3f004e2 100644 --- a/internal/imap/client.go +++ b/internal/imap/client.go @@ -3,6 +3,7 @@ package imap import ( "fmt" "strings" + "time" "github.com/emersion/go-imap" imapClient "github.com/emersion/go-imap/client" @@ -13,21 +14,38 @@ import ( type Client struct { c *imapClient.Client host string - folders folders + mailboxes mailboxes delimiter string - toplevel string + toplevel Folder } -type folders map[string]*imap.MailboxInfo +type Folder struct { + str string + delimiter string +} +type mailboxes map[string]*imap.MailboxInfo + +func (f Folder) String() string { + return f.str +} + +func (f Folder) Append(other Folder) Folder { + if f.delimiter != other.delimiter { + panic("Delimiters do not match") + } + return Folder{ + str: f.str + f.delimiter + other.str, + delimiter: f.delimiter, + } +} -func (f folders) contains(elem string) bool { - _, ok := f[elem] +func (mbs mailboxes) contains(elem Folder) bool { + _, ok := mbs[elem.str] return ok } -func (f folders) add(elem *imap.MailboxInfo) { - name := elem.Name - f[name] = elem +func (mbs mailboxes) add(elem *imap.MailboxInfo) { + mbs[elem.Name] = elem } func (client *Client) Disconnect() { @@ -41,8 +59,15 @@ func (client *Client) Disconnect() { } } -func (client *Client) FolderName(path []string) string { - return strings.Join(path, client.delimiter) +func (client *Client) folderName(path []string) Folder { + return Folder{ + strings.Join(path, client.delimiter), + client.delimiter, + } +} + +func (client *Client) NewFolder(path []string) Folder { + return client.toplevel.Append(client.folderName(path)) } func (client *Client) createFolder(folder string) error { @@ -94,25 +119,33 @@ func (client *Client) fetchDelimiter() error { return nil } -func (client *Client) EnsureFolder(folder string) error { - - if client.folders.contains(folder) { +func (client *Client) EnsureFolder(folder Folder) error { + if client.mailboxes.contains(folder) { return nil } log.Printf("Checking for folder '%s'", folder) - mbox, found, err := client.list(folder) - - switch { - case err != nil: + mbox, found, err := client.list(folder.str) + if err != nil { return err - case found == 0: - return client.createFolder(folder) - case found == 1: - client.folders.add(mbox) + } + + if mbox != nil && mbox.Delimiter != folder.delimiter { + panic("Delimiters do not match") + } + + switch found { + case 0: + return client.createFolder(folder.str) + case 1: + client.mailboxes.add(mbox) return nil default: return fmt.Errorf("Found multiple folders matching '%s'.", folder) } } + +func (client *Client) PutMessage(folder Folder, message string, date time.Time) error { + return client.c.Append(folder.String(), nil, date, strings.NewReader(message)) +} diff --git a/internal/imap/imap.go b/internal/imap/imap.go index 2fd7580..f284f81 100644 --- a/internal/imap/imap.go +++ b/internal/imap/imap.go @@ -77,7 +77,7 @@ func Connect(url *url.URL) (*Client, error) { } } - var client = Client{c: c, host: url.Host, folders: folders{}} + var client = Client{c: c, host: url.Host, mailboxes: mailboxes{}} defer func() { if err != nil { @@ -113,11 +113,11 @@ func Connect(url *url.URL) (*Client, error) { return nil, fmt.Errorf("fetching delimiter: %w", err) } - client.toplevel = url.Path - if client.toplevel[0] == '/' { - client.toplevel = client.toplevel[1:] + toplevel := url.Path + if toplevel[0] == '/' { + toplevel = toplevel[1:] } - client.toplevel = client.FolderName(strings.Split(client.toplevel, "/")) + client.toplevel = client.folderName(strings.Split(toplevel, "/")) log.Printf("Determined '%s' as toplevel, with '%s' as delimiter", client.toplevel, client.delimiter) @@ -5,6 +5,7 @@ import ( "fmt" "net/url" "os" + "time" "github.com/Necoro/feed2imap-go/internal/feed" "github.com/Necoro/feed2imap-go/internal/imap" @@ -33,15 +34,6 @@ func run() error { feed.Parse(feeds) - for _, f := range feeds { - mails, err := f.ToMails(cfg) - if err != nil { - return err - } - _ = mails - break - } - imapUrl, err := url.Parse(cfg.Target) if err != nil { return fmt.Errorf("parsing 'target': %w", err) @@ -54,6 +46,26 @@ func run() error { defer c.Disconnect() + for _, f := range feeds { + mails, err := f.ToMails(cfg) + if err != nil { + return err + } + if len(mails) == 0 { + continue + } + folder := c.NewFolder(f.Target) + if err = c.EnsureFolder(folder); err != nil { + return err + } + for _, mail := range mails { + if err = c.PutMessage(folder, mail, time.Now()); err != nil { + return err + } // TODO + } + log.Printf("Uploaded %d messages to '%s' @ %s", len(mails), f.Name, folder) + } + return nil } |