83 lines
2.3 KiB
Go
83 lines
2.3 KiB
Go
package backend
|
|
|
|
import "strings"
|
|
|
|
// TargetMailbox = das Ziel-Postfach (neuer Host). Der Umzug schreibt hier per
|
|
// IMAP APPEND hinein -- NICHT per SMTP. APPEND erhaelt Ordner, Flags und
|
|
// Original-Datum; SMTP wuerde alles als "neu/ungelesen" mit falschem Datum
|
|
// zustellen und die Ordnerstruktur zerstoeren.
|
|
type TargetMailbox interface {
|
|
Folders() ([]TargetFolder, error) // vorhandene Ziel-Ordner (fuer Rollen-Zuordnung)
|
|
Delim() string // Hierarchie-Trenner des Ziels
|
|
EnsureFolder(name string) error // anlegen + subscriben, falls fehlt
|
|
Append(folder string, m RawMessage) error // mit m.Flags und m.InternalDate
|
|
Close() error
|
|
}
|
|
|
|
// OpenIMAPTarget verbindet das Ziel per go-imap/v2 (Security wie Quelle, siehe
|
|
// a.DstSecurity/a.DstInsecure; meist "tls").
|
|
func OpenIMAPTarget(a Account) (TargetMailbox, error) {
|
|
c, err := dialIMAP(a.DstHost, a.DstPort, a.DstSecurity, a.DstInsecure)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if err := c.login(a.DstUser, a.DstPass); err != nil {
|
|
_ = c.Close()
|
|
return nil, err
|
|
}
|
|
return &imapTarget{c: c}, nil
|
|
}
|
|
|
|
type imapTarget struct {
|
|
c *simpleIMAP
|
|
delim string
|
|
}
|
|
|
|
func (t *imapTarget) Folders() ([]TargetFolder, error) {
|
|
boxes, err := t.c.listMailboxes()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
folders := make([]TargetFolder, 0, len(boxes))
|
|
for _, box := range boxes {
|
|
if t.delim == "" && box.Delim != "" {
|
|
t.delim = box.Delim
|
|
}
|
|
if hasIMAPAttr(box.Attrs, `\Noselect`) {
|
|
continue
|
|
}
|
|
folders = append(folders, TargetFolder{Name: box.Name, Attrs: box.Attrs})
|
|
}
|
|
if len(folders) == 0 {
|
|
folders = append(folders, TargetFolder{Name: "INBOX"})
|
|
}
|
|
return folders, nil
|
|
}
|
|
|
|
func (t *imapTarget) Delim() string {
|
|
if t.delim != "" {
|
|
return t.delim
|
|
}
|
|
return "/"
|
|
}
|
|
|
|
func (t *imapTarget) EnsureFolder(name string) error {
|
|
if name == "INBOX" {
|
|
return nil
|
|
}
|
|
if err := t.c.simple("CREATE " + imapQuote(name)); err != nil {
|
|
if !strings.Contains(strings.ToLower(err.Error()), "exist") && !strings.Contains(strings.ToLower(err.Error()), "already") {
|
|
return err
|
|
}
|
|
}
|
|
_ = t.c.simple("SUBSCRIBE " + imapQuote(name))
|
|
return nil
|
|
}
|
|
|
|
func (t *imapTarget) Append(folder string, m RawMessage) error {
|
|
return t.c.appendMessage(folder, m)
|
|
}
|
|
|
|
func (t *imapTarget) Close() error {
|
|
return t.c.Close()
|
|
}
|