102 lines
2.9 KiB
Go
102 lines
2.9 KiB
Go
package main
|
|
|
|
import (
|
|
"embed"
|
|
"flag"
|
|
"io/fs"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
|
|
"mail-graveyard/backend"
|
|
)
|
|
|
|
//go:embed frontend-js/dist/*
|
|
var frontend embed.FS
|
|
|
|
func main() {
|
|
runOnce := flag.String("run", "", "einen Umzugs-Job einmalig ausfuehren (Konto-Name oder 'all'), ohne Web-UI")
|
|
runFolders := flag.String("folders", "", "optionale kommaseparierte Ordnerliste fuer -run (CLI-Abnahme/Teilumzug)")
|
|
watch := flag.Bool("watch", false, "Delta-Sync in Schleife bis Stop (Cutover-Fenster)")
|
|
watchInterval := flag.Duration("watch-interval", 60*time.Second, "Pause zwischen Watch-Durchlaeufen")
|
|
seedAccount := flag.String("seed-account", "", "Konto aus lokaler JSON-Datei in die DB schreiben (nur CLI/Test)")
|
|
checkAccount := flag.String("check-account", "", "Konto-Logins pruefen und INBOX zaehlen, ohne zu kopieren")
|
|
reindex := flag.String("reindex", "", "Archiv-mbox-Index fuer Konto/Archiv oder 'all' neu aufbauen")
|
|
dedupTarget := flag.String("dedup-target", "", "Ziel-Postfach nach Message-ID-Dubletten scannen (Dry-Run ohne --apply)")
|
|
apply := flag.Bool("apply", false, "Scharfe Ausfuehrung fuer riskante Wartungsbefehle wie --dedup-target")
|
|
initDB := flag.Bool("init-db", false, "SQLite-DB neu anlegen, falls db_path noch nicht existiert")
|
|
flag.Parse()
|
|
|
|
if err := backend.LoadConfig("config.json"); err != nil {
|
|
log.Fatalf("config: %v", err)
|
|
}
|
|
if err := backend.ConnectDB(*initDB); err != nil {
|
|
log.Fatalf("database: %v", err)
|
|
}
|
|
if err := backend.InitAuth(); err != nil {
|
|
log.Fatalf("auth: %v", err)
|
|
}
|
|
|
|
if *seedAccount != "" {
|
|
must(backend.SeedAccountFromFile(*seedAccount))
|
|
return
|
|
}
|
|
if *checkAccount != "" {
|
|
must(backend.CheckAccount(*checkAccount))
|
|
return
|
|
}
|
|
if *reindex != "" {
|
|
must(backend.ReindexArchives(*reindex))
|
|
return
|
|
}
|
|
if *dedupTarget != "" {
|
|
report, err := backend.DedupTarget(*dedupTarget, splitOptionalList(*runFolders), *apply)
|
|
if err != nil {
|
|
must(err)
|
|
}
|
|
backend.LogTargetDedupReport(report)
|
|
return
|
|
}
|
|
|
|
// CLI-Modus: ohne Web laufen lassen (Cronjob / Cutover).
|
|
if *runOnce != "" {
|
|
if strings.TrimSpace(*runFolders) != "" {
|
|
if *watch {
|
|
log.Fatal("-folders kann nicht mit -watch kombiniert werden")
|
|
}
|
|
must(backend.RunMigrationFolders(*runOnce, strings.Split(*runFolders, ",")))
|
|
return
|
|
}
|
|
must(backend.RunMigration(*runOnce, *watch, *watchInterval))
|
|
return
|
|
}
|
|
|
|
dist, err := fs.Sub(frontend, "frontend-js/dist")
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
mux := http.NewServeMux()
|
|
mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.FS(dist))))
|
|
backend.RegisterRoutes(mux)
|
|
|
|
addr := backend.Cfg.Bind + ":" + backend.Cfg.Port
|
|
log.Printf("Mail-Graveyard listening on %s", addr)
|
|
log.Fatal(http.ListenAndServe(addr, backend.AuthMiddleware(mux)))
|
|
}
|
|
|
|
func must(err error) {
|
|
if err != nil {
|
|
log.Print(err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
func splitOptionalList(value string) []string {
|
|
if strings.TrimSpace(value) == "" {
|
|
return nil
|
|
}
|
|
return strings.Split(value, ",")
|
|
}
|