mox/export.go
Mechiel Lukkien bf8cfd9724
add debug logging about bstore db schema upgrades
bstore was updated to v0.0.6 to add this logging.
this simplifies some of the db-handling code in mtastsdb,tlsrptdb,dmarcdb. we
now call the package-level Init() and Close() in all tests properly.
2024-05-10 14:44:37 +02:00

79 lines
2.5 KiB
Go

package main
import (
"context"
"log"
"path/filepath"
"time"
"github.com/mjl-/bstore"
"github.com/mjl-/mox/store"
)
func cmdExportMaildir(c *cmd) {
c.params = "[-single] dst-dir account-path [mailbox]"
c.help = `Export one or all mailboxes from an account in maildir format.
Export bypasses a running mox instance. It opens the account mailbox/message
database file directly. This may block if a running mox instance also has the
database open, e.g. for IMAP connections. To export from a running instance, use
the accounts web page or webmail.
`
var single bool
c.flag.BoolVar(&single, "single", false, "export single mailbox, without any children. disabled if mailbox isn't specified.")
args := c.Parse()
xcmdExport(false, single, args, c)
}
func cmdExportMbox(c *cmd) {
c.params = "[-single] dst-dir account-path [mailbox]"
c.help = `Export messages from one or all mailboxes in an account in mbox format.
Using mbox is not recommended. Maildir is a better format.
Export bypasses a running mox instance. It opens the account mailbox/message
database file directly. This may block if a running mox instance also has the
database open, e.g. for IMAP connections. To export from a running instance, use
the accounts web page or webmail.
For mbox export, "mboxrd" is used where message lines starting with the magic
"From " string are escaped by prepending a >. All ">*From " are escaped,
otherwise reconstructing the original could lose a ">".
`
var single bool
c.flag.BoolVar(&single, "single", false, "export single mailbox, without any children. disabled if mailbox isn't specified.")
args := c.Parse()
xcmdExport(true, single, args, c)
}
func xcmdExport(mbox, single bool, args []string, c *cmd) {
if len(args) != 2 && len(args) != 3 {
c.Usage()
}
dst := args[0]
accountDir := args[1]
var mailbox string
if len(args) == 3 {
mailbox = args[2]
} else {
single = false
}
dbpath := filepath.Join(accountDir, "index.db")
opts := bstore.Options{Timeout: 5 * time.Second, Perm: 0660, RegisterLogger: c.log.Logger}
db, err := bstore.Open(context.Background(), dbpath, &opts, store.DBTypes...)
xcheckf(err, "open database %q", dbpath)
defer func() {
if err := db.Close(); err != nil {
log.Printf("closing db after export: %v", err)
}
}()
a := store.DirArchiver{Dir: dst}
err = store.ExportMessages(context.Background(), c.log, db, accountDir, a, !mbox, mailbox, !single)
xcheckf(err, "exporting messages")
err = a.Close()
xcheckf(err, "closing archiver")
}