Mail-Graveyard/backend/05-imap-target.go
2026-07-05 20:51:22 +02:00

62 lines
1.8 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
}
func (t *imapTarget) Folders() ([]TargetFolder, error) {
return []TargetFolder{{Name: "INBOX"}}, nil
}
func (t *imapTarget) Delim() string {
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()
}