1
0
Fork 0
mirror of https://git.sr.ht/~rjarry/aerc synced 2025-11-05 08:51:55 +01:00
aerc/commands/account/recover.go
inwit a4a3581565 compose: create temp files in system's state dir
Instead of creating new mail files in the general temporary directory,
where they might be erased upon system restart, create them in
${XDG_STATE_HOME:-~/.local/state}/aerc/compose. Adjust :recover to find
those files automatically.

Changelog-changed: Temporary files for messages being composed now
 reside in the system's proper state home directory.
Signed-off-by: inwit <inwit@sindominio.net>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-10-30 21:17:44 +01:00

90 lines
1.9 KiB
Go

package account
import (
"bytes"
"errors"
"io"
"os"
"path/filepath"
"git.sr.ht/~rjarry/aerc/app"
"git.sr.ht/~rjarry/aerc/commands"
"git.sr.ht/~rjarry/aerc/config"
"git.sr.ht/~rjarry/aerc/lib/xdg"
)
type Recover struct {
Force bool `opt:"-f" desc:"Delete recovered file after opening the composer."`
Edit bool `opt:"-e" desc:"Force [compose].edit-headers = true."`
NoEdit bool `opt:"-E" desc:"Force [compose].edit-headers = false."`
File string `opt:"file" complete:"CompleteFile" desc:"Recover file path."`
}
func init() {
commands.Register(Recover{})
}
func (Recover) Description() string {
return "Resume composing a message that was not sent nor postponed."
}
func (Recover) Context() commands.CommandContext {
return commands.MESSAGE_LIST
}
func (Recover) Aliases() []string {
return []string{"recover"}
}
func (Recover) Options() string {
return "feE"
}
func (*Recover) CompleteFile(arg string) []string {
// file name of temp file is hard-coded in the NewComposer() function
composePath := xdg.StatePath("aerc", "compose")
files, err := filepath.Glob(
filepath.Join(composePath, "aerc-compose-*.eml"),
)
if err != nil {
return nil
}
return commands.FilterList(files, arg, nil)
}
func (r Recover) Execute(args []string) error {
file, err := os.Open(r.File)
if err != nil {
return err
}
defer file.Close()
data, err := io.ReadAll(file)
if err != nil {
return err
}
acct := app.SelectedAccount()
if acct == nil {
return errors.New("No account selected")
}
editHeaders := (config.Compose().EditHeaders || r.Edit) && !r.NoEdit
composer, err := app.NewComposer(acct,
acct.AccountConfig(), acct.Worker(), editHeaders,
"", nil, nil, bytes.NewReader(data))
if err != nil {
return err
}
composer.Tab = app.NewTab(composer, "Recovered")
// remove file if force flag is set
if r.Force {
err = os.Remove(r.File)
if err != nil {
return err
}
}
return nil
}