Decouple archive mailboxes from accounts

This commit is contained in:
DonVoo 2026-07-13 02:28:38 +02:00
parent 0bb49019b6
commit 8d2838aea7
4 changed files with 130 additions and 46 deletions

View file

@ -35,7 +35,7 @@ type Account struct {
DstInsecure bool `json:"dst_insecure"`
DstUser string `json:"dst_user"` // archiv-hans-peter@dr-gold.com
DstPass string `json:"dst_pass"`
MboxDir string `json:"mbox_dir"` // Unterordner unter Cfg.MboxRoot; leer = Cfg.MboxRoot/Name
MboxDir string `json:"mbox_dir"` // optionaler Name aus archive_mailboxes unter Cfg.MboxRoot
Active bool `json:"active"`
}
@ -54,6 +54,8 @@ type AppUser struct {
//
// accounts(...) -- die Umzugs-Zeilen (oben), inkl.
// src_security/src_insecure etc.
// archive_mailboxes(name) -- lokale/importierte Archiv-mboxen,
// unabhaengig von Quell/Ziel-Konten.
// folder_map(account_id, src, dst) -- optionales manuelles Umbenennen
// (Vorrang vor der Rollen-Automatik
// aus 11-folders.go)
@ -94,6 +96,11 @@ func ConnectDB() error {
mbox_dir TEXT NOT NULL DEFAULT '',
active INTEGER NOT NULL DEFAULT 1
)`,
`CREATE TABLE IF NOT EXISTS archive_mailboxes(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
)`,
`CREATE TABLE IF NOT EXISTS folder_map(
id INTEGER PRIMARY KEY AUTOINCREMENT,
account_id INTEGER NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
@ -153,6 +160,10 @@ func ConnectDB() error {
_ = db.Close()
return err
}
if err := seedArchiveMailboxesFromFS(); err != nil {
_ = db.Close()
return err
}
return nil
}
@ -393,6 +404,58 @@ func DeleteAccount(name string) error {
return err
}
func ListArchiveMailboxes() ([]string, error) {
rows, err := DB.Query(`SELECT name FROM archive_mailboxes ORDER BY lower(name), name`)
if err != nil {
return nil, err
}
defer rows.Close()
var out []string
for rows.Next() {
var name string
if err := rows.Scan(&name); err != nil {
return nil, err
}
out = append(out, name)
}
return out, rows.Err()
}
func SaveArchiveMailbox(name string) error {
name = strings.TrimSpace(name)
if name == "" {
return fmt.Errorf("Name der Archiv-Mailbox fehlt.")
}
_, err := DB.Exec(`INSERT OR IGNORE INTO archive_mailboxes(name) VALUES(?)`, name)
return err
}
func DeleteArchiveMailbox(name string) error {
_, err := DB.Exec(`DELETE FROM archive_mailboxes WHERE name=?`, strings.TrimSpace(name))
return err
}
func seedArchiveMailboxesFromFS() error {
if Cfg.MboxRoot == "" {
return nil
}
entries, err := os.ReadDir(Cfg.MboxRoot)
if os.IsNotExist(err) {
return nil
}
if err != nil {
return err
}
for _, entry := range entries {
if entry.IsDir() {
if err := SaveArchiveMailbox(entry.Name()); err != nil {
return err
}
}
}
return nil
}
func AlreadyCopied(accountID int64, folder, messageID string) (bool, error) {
if messageID == "" {
return false, nil
@ -468,9 +531,7 @@ func normalizeAccount(a *Account) {
a.DstPort = 143
}
}
if a.MboxDir == "" {
a.MboxDir = a.Name
}
a.MboxDir = strings.TrimSpace(a.MboxDir)
}
func scanAppUser(s appUserScanner) (AppUser, error) {