aboutsummaryrefslogtreecommitdiff
path: root/internal/imap/client.go
diff options
context:
space:
mode:
authorRené 'Necoro' Neumann <necoro@necoro.eu>2020-04-23 20:48:17 +0200
committerRené 'Necoro' Neumann <necoro@necoro.eu>2020-04-23 20:48:17 +0200
commitc883470c2ef977b8675b12428591bb003694e235 (patch)
tree09cd8fa950594e1ea13aa52492ce8116e07ef30b /internal/imap/client.go
parent6bd87a567ef481b922f6baec2b475ec376c45443 (diff)
downloadfeed2imap-go-c883470c2ef977b8675b12428591bb003694e235.tar.gz
feed2imap-go-c883470c2ef977b8675b12428591bb003694e235.tar.bz2
feed2imap-go-c883470c2ef977b8675b12428591bb003694e235.zip
Restructure imap pkg
Diffstat (limited to 'internal/imap/client.go')
-rw-r--r--internal/imap/client.go202
1 files changed, 4 insertions, 198 deletions
diff --git a/internal/imap/client.go b/internal/imap/client.go
index 5e2546b..404c03e 100644
--- a/internal/imap/client.go
+++ b/internal/imap/client.go
@@ -1,12 +1,6 @@
package imap
import (
- "fmt"
- "strings"
- "sync"
- "time"
-
- "github.com/emersion/go-imap"
imapClient "github.com/emersion/go-imap/client"
"github.com/Necoro/feed2imap-go/internal/log"
@@ -20,75 +14,21 @@ type connConf struct {
toplevel Folder
}
-type connection struct {
- *connConf
- mailboxes *mailboxes
- c *imapClient.Client
-}
-
-type mailboxes struct {
- mb map[string]*imap.MailboxInfo
- mu sync.RWMutex
-}
-
type Client struct {
connConf
- mailboxes mailboxes
+ mailboxes *mailboxes
commander *commander
connections [numberConns]*connection
nextFreeIndex int
}
-type Folder struct {
- str string
- delimiter string
-}
-
-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 (mbs *mailboxes) contains(elem Folder) bool {
- mbs.mu.RLock()
- defer mbs.mu.RUnlock()
-
- _, ok := mbs.mb[elem.str]
- return ok
-}
-
-func (mbs *mailboxes) add(elem *imap.MailboxInfo) {
- mbs.mu.Lock()
- defer mbs.mu.Unlock()
-
- mbs.mb[elem.Name] = elem
-}
-
-func (conn *connection) Disconnect() bool {
- if conn != nil {
- connected := (conn.c.State() & imap.ConnectedState) != 0
- _ = conn.c.Logout()
- return connected
- }
- return false
-}
-
func (client *Client) Disconnect() {
if client != nil {
client.stopCommander()
connected := false
for _, conn := range client.connections {
- connected = conn.Disconnect() || connected
+ connected = conn.disconnect() || connected
}
if connected {
@@ -97,116 +37,6 @@ func (client *Client) Disconnect() {
}
}
-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 (conn *connection) createFolder(folder string) error {
- err := conn.c.Create(folder)
- if err != nil {
- return fmt.Errorf("creating folder '%s': %w", folder, err)
- }
-
- err = conn.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 (conn *connection) list(folder string) (*imap.MailboxInfo, int, error) {
- mailboxes := make(chan *imap.MailboxInfo, 10)
- done := make(chan error, 1)
- go func() {
- done <- conn.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 (conn *connection) fetchDelimiter() (string, error) {
- mbox, _, err := conn.list("")
- if err != nil {
- return "", err
- }
-
- return mbox.Delimiter, nil
-}
-
-func (conn *connection) ensureFolder(folder Folder) error {
- if conn.mailboxes.contains(folder) {
- return nil
- }
-
- log.Printf("Checking for folder '%s'", folder)
-
- mbox, found, err := conn.list(folder.str)
- if err != nil {
- return err
- }
-
- if mbox != nil && mbox.Delimiter != folder.delimiter {
- panic("Delimiters do not match")
- }
-
- switch found {
- case 0:
- return conn.createFolder(folder.str)
- case 1:
- conn.mailboxes.add(mbox)
- return nil
- default:
- return fmt.Errorf("Found multiple folders matching '%s'.", folder)
- }
-}
-
-func (client *Client) EnsureFolder(folder Folder) error {
- return client.commander.execute(ensureCommando{folder})
-}
-
-func (conn *connection) putMessages(folder Folder, messages []string) error {
- if len(messages) == 0 {
- return nil
- }
-
- now := time.Now()
- for _, msg := range messages {
- reader := strings.NewReader(msg)
- if err := conn.c.Append(folder.str, nil, now, reader); err != nil {
- return fmt.Errorf("uploading message to %s: %w", folder, err)
- }
- }
-
- return nil
-}
-
-func (client *Client) PutMessages(folder Folder, messages []string) error {
- return client.commander.execute(addCommando{folder, messages})
-}
-
func (client *Client) createConnection(c *imapClient.Client) *connection{
if client.nextFreeIndex >= len(client.connections) {
panic("Too many connections")
@@ -214,7 +44,7 @@ func (client *Client) createConnection(c *imapClient.Client) *connection{
conn := &connection{
connConf: &client.connConf,
- mailboxes: &client.mailboxes,
+ mailboxes: client.mailboxes,
c: c,
}
@@ -224,30 +54,6 @@ func (client *Client) createConnection(c *imapClient.Client) *connection{
return conn
}
-func (conn *connection) startTls() error {
- hasStartTls, err := conn.c.SupportStartTLS()
- if err != nil {
- return fmt.Errorf("checking for starttls for %s: %w", conn.host, err)
- }
-
- if hasStartTls {
- if err = conn.c.StartTLS(nil); err != nil {
- return fmt.Errorf("enabling starttls for %s: %w", conn.host, err)
- }
-
- log.Print("Connected to ", conn.host, " (STARTTLS)")
- } else {
- log.Print("Connected to ", conn.host, " (Plain)")
- }
-
- return nil
-}
-
func NewClient() *Client {
- return &Client{
- mailboxes: mailboxes{
- mb: map[string]*imap.MailboxInfo{},
- mu: sync.RWMutex{},
- },
- }
+ return &Client{mailboxes: NewMailboxes()}
} \ No newline at end of file