2020-04-24 11:42:21 +02:00
|
|
|
package compose
|
|
|
|
|
|
|
|
import (
|
2022-07-05 21:42:42 +02:00
|
|
|
"bytes"
|
2020-04-24 11:42:21 +02:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/miolini/datacounter"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
|
2022-03-22 09:52:27 +01:00
|
|
|
"git.sr.ht/~rjarry/aerc/logging"
|
2021-11-05 10:19:46 +01:00
|
|
|
"git.sr.ht/~rjarry/aerc/models"
|
|
|
|
"git.sr.ht/~rjarry/aerc/widgets"
|
|
|
|
"git.sr.ht/~rjarry/aerc/worker/types"
|
2020-04-24 11:42:21 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
type Postpone struct{}
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
register(Postpone{})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (Postpone) Aliases() []string {
|
|
|
|
return []string{"postpone"}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (Postpone) Complete(aerc *widgets.Aerc, args []string) []string {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (Postpone) Execute(aerc *widgets.Aerc, args []string) error {
|
|
|
|
if len(args) != 1 {
|
|
|
|
return errors.New("Usage: postpone")
|
|
|
|
}
|
2022-02-25 00:21:06 +01:00
|
|
|
acct := aerc.SelectedAccount()
|
|
|
|
if acct == nil {
|
|
|
|
return errors.New("No account selected")
|
|
|
|
}
|
2022-07-14 18:29:56 +02:00
|
|
|
tab := aerc.SelectedTab()
|
|
|
|
if tab == nil {
|
|
|
|
return errors.New("No tab selected")
|
|
|
|
}
|
|
|
|
composer, _ := tab.Content.(*widgets.Composer)
|
2020-04-24 11:42:21 +02:00
|
|
|
config := composer.Config()
|
2022-07-14 18:29:56 +02:00
|
|
|
tabName := tab.Name
|
2020-04-24 11:42:21 +02:00
|
|
|
|
|
|
|
if config.Postpone == "" {
|
|
|
|
return errors.New("No Postpone location configured")
|
|
|
|
}
|
|
|
|
|
|
|
|
aerc.Logger().Println("Postponing mail")
|
|
|
|
|
2020-11-10 20:27:30 +01:00
|
|
|
header, err := composer.PrepareHeader()
|
2020-04-24 11:42:21 +02:00
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "PrepareHeader")
|
|
|
|
}
|
|
|
|
header.SetContentType("text/plain", map[string]string{"charset": "UTF-8"})
|
|
|
|
header.Set("Content-Transfer-Encoding", "quoted-printable")
|
|
|
|
worker := composer.Worker()
|
2022-02-25 00:21:06 +01:00
|
|
|
dirs := acct.Directories().List()
|
2020-04-24 11:42:21 +02:00
|
|
|
alreadyCreated := false
|
|
|
|
for _, dir := range dirs {
|
|
|
|
if dir == config.Postpone {
|
|
|
|
alreadyCreated = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
errChan := make(chan string)
|
|
|
|
|
|
|
|
// run this as a goroutine so we can make other progress. The message
|
|
|
|
// will be saved once the directory is created.
|
|
|
|
go func() {
|
2022-03-22 09:52:27 +01:00
|
|
|
defer logging.PanicHandler()
|
|
|
|
|
2020-04-24 11:42:21 +02:00
|
|
|
errStr := <-errChan
|
|
|
|
if errStr != "" {
|
2021-01-30 13:51:32 +01:00
|
|
|
aerc.PushError(errStr)
|
2020-04-24 11:42:21 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-02-04 13:18:52 +01:00
|
|
|
handleErr := func(err error) {
|
|
|
|
aerc.PushError(err.Error())
|
|
|
|
aerc.Logger().Println("Postponing failed:", err)
|
|
|
|
aerc.NewTab(composer, tabName)
|
|
|
|
}
|
|
|
|
|
2020-04-24 11:42:21 +02:00
|
|
|
aerc.RemoveTab(composer)
|
2022-07-05 21:42:42 +02:00
|
|
|
var buf bytes.Buffer
|
|
|
|
ctr := datacounter.NewWriterCounter(&buf)
|
2020-04-24 11:42:21 +02:00
|
|
|
err = composer.WriteMessage(header, ctr)
|
|
|
|
if err != nil {
|
2022-02-04 13:18:52 +01:00
|
|
|
handleErr(errors.Wrap(err, "WriteMessage"))
|
2020-04-24 11:42:21 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
nbytes := int(ctr.Count())
|
|
|
|
worker.PostAction(&types.AppendMessage{
|
|
|
|
Destination: config.Postpone,
|
2020-04-24 11:42:22 +02:00
|
|
|
Flags: []models.Flag{models.SeenFlag},
|
2020-04-24 11:42:21 +02:00
|
|
|
Date: time.Now(),
|
2022-07-05 21:42:42 +02:00
|
|
|
Reader: &buf,
|
2020-04-24 11:42:21 +02:00
|
|
|
Length: int(nbytes),
|
|
|
|
}, func(msg types.WorkerMessage) {
|
|
|
|
switch msg := msg.(type) {
|
|
|
|
case *types.Done:
|
2020-05-28 16:32:32 +02:00
|
|
|
aerc.PushStatus("Message postponed.", 10*time.Second)
|
2020-04-24 11:42:21 +02:00
|
|
|
composer.Close()
|
|
|
|
case *types.Error:
|
2022-02-04 13:18:52 +01:00
|
|
|
handleErr(msg.Error)
|
2020-04-24 11:42:21 +02:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}()
|
|
|
|
|
|
|
|
if !alreadyCreated {
|
|
|
|
// to synchronise the creating of the directory
|
|
|
|
worker.PostAction(&types.CreateDirectory{
|
|
|
|
Directory: config.Postpone,
|
|
|
|
}, func(msg types.WorkerMessage) {
|
|
|
|
switch msg := msg.(type) {
|
|
|
|
case *types.Done:
|
|
|
|
errChan <- ""
|
|
|
|
case *types.Error:
|
|
|
|
errChan <- msg.Error.Error()
|
|
|
|
}
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
errChan <- ""
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|