aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRené 'Necoro' Neumann <necoro@necoro.eu>2020-04-21 22:20:20 +0200
committerRené 'Necoro' Neumann <necoro@necoro.eu>2020-04-21 22:20:20 +0200
commit89f46e31998dd62a52d7dd07b16f1d81d9597e3e (patch)
tree7bb463d986804601c04c01f2855eb15293a1a7ee
parent1845873048e1f2c3499e75a4e5cbbe8d1247170d (diff)
downloadfeed2imap-go-89f46e31998dd62a52d7dd07b16f1d81d9597e3e.tar.gz
feed2imap-go-89f46e31998dd62a52d7dd07b16f1d81d9597e3e.tar.bz2
feed2imap-go-89f46e31998dd62a52d7dd07b16f1d81d9597e3e.zip
Upload mails to imap
-rw-r--r--internal/imap/client.go75
-rw-r--r--internal/imap/imap.go10
-rw-r--r--main.go30
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)
diff --git a/main.go b/main.go
index af75fb7..8e4b64f 100644
--- a/main.go
+++ b/main.go
@@ -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
}