diff options
Diffstat (limited to 'commands/compose/postpone.go')
-rw-r--r-- | commands/compose/postpone.go | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/commands/compose/postpone.go b/commands/compose/postpone.go new file mode 100644 index 0000000..44aa411 --- /dev/null +++ b/commands/compose/postpone.go @@ -0,0 +1,119 @@ +package compose + +import ( + "io" + "io/ioutil" + "time" + + "github.com/emersion/go-imap" + "github.com/miolini/datacounter" + "github.com/pkg/errors" + + "git.sr.ht/~sircmpwn/aerc/widgets" + "git.sr.ht/~sircmpwn/aerc/worker/types" +) + +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") + } + composer, _ := aerc.SelectedTab().(*widgets.Composer) + config := composer.Config() + + if config.Postpone == "" { + return errors.New("No Postpone location configured") + } + + aerc.Logger().Println("Postponing mail") + + header, _, err := composer.PrepareHeader() + 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() + dirs := aerc.SelectedAccount().Directories().List() + 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() { + errStr := <-errChan + if errStr != "" { + aerc.PushError(" " + errStr) + return + } + + aerc.RemoveTab(composer) + ctr := datacounter.NewWriterCounter(ioutil.Discard) + err = composer.WriteMessage(header, ctr) + if err != nil { + aerc.PushError(errors.Wrap(err, "WriteMessage").Error()) + composer.Close() + return + } + nbytes := int(ctr.Count()) + r, w := io.Pipe() + worker.PostAction(&types.AppendMessage{ + Destination: config.Postpone, + Flags: []string{imap.SeenFlag}, + Date: time.Now(), + Reader: r, + Length: int(nbytes), + }, func(msg types.WorkerMessage) { + switch msg := msg.(type) { + case *types.Done: + aerc.PushStatus("Message postponed.", 10*time.Second) + r.Close() + composer.Close() + case *types.Error: + aerc.PushError(" " + msg.Error.Error()) + r.Close() + composer.Close() + } + }) + composer.WriteMessage(header, w) + w.Close() + }() + + 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 +} |