open: simplify code
There is no need for convoluted channels and other async fanciness. Expose a single XDGOpen static function that runs a command and returns an error if any. Caller is responsible of running this in an async goroutine if needed. Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Tim Culverhouse <tim@timculverhouse.com> Acked-by: Moritz Poldrack <moritz@poldrack.dev>
This commit is contained in:
parent
8e53d33061
commit
92ba132d70
3 changed files with 19 additions and 73 deletions
|
@ -183,9 +183,11 @@ func unsubscribeHTTP(aerc *widgets.Aerc, u *url.URL) error {
|
||||||
aerc.CloseDialog()
|
aerc.CloseDialog()
|
||||||
switch option {
|
switch option {
|
||||||
case "Yes":
|
case "Yes":
|
||||||
if err := lib.NewXDGOpen(u.String()).Start(); err != nil {
|
go func() {
|
||||||
aerc.PushError("Unsubscribe:" + err.Error())
|
if err := lib.XDGOpen(u.String()); err != nil {
|
||||||
}
|
aerc.PushError("Unsubscribe:" + err.Error())
|
||||||
|
}
|
||||||
|
}()
|
||||||
default:
|
default:
|
||||||
aerc.PushError("Unsubscribe: link will not be opened")
|
aerc.PushError("Unsubscribe: link will not be opened")
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,11 +5,9 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"mime"
|
"mime"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.sr.ht/~rjarry/aerc/commands"
|
"git.sr.ht/~rjarry/aerc/commands"
|
||||||
"git.sr.ht/~rjarry/aerc/lib"
|
"git.sr.ht/~rjarry/aerc/lib"
|
||||||
"git.sr.ht/~rjarry/aerc/logging"
|
|
||||||
"git.sr.ht/~rjarry/aerc/widgets"
|
"git.sr.ht/~rjarry/aerc/widgets"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -40,8 +38,8 @@ func (Open) Execute(aerc *widgets.Aerc, args []string) error {
|
||||||
if args[0] == "open-link" && len(args) > 1 {
|
if args[0] == "open-link" && len(args) > 1 {
|
||||||
if link := args[1]; link != "" {
|
if link := args[1]; link != "" {
|
||||||
go func() {
|
go func() {
|
||||||
if err := lib.NewXDGOpen(link).Start(); err != nil {
|
if err := lib.XDGOpen(link); err != nil {
|
||||||
aerc.PushError(fmt.Sprintf("%s: %s", args[0], err.Error()))
|
aerc.PushError("open: " + err.Error())
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
@ -64,34 +62,20 @@ func (Open) Execute(aerc *widgets.Aerc, args []string) error {
|
||||||
aerc.PushError(err.Error())
|
aerc.PushError(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer tmpFile.Close()
|
|
||||||
|
|
||||||
_, err = io.Copy(tmpFile, reader)
|
_, err = io.Copy(tmpFile, reader)
|
||||||
|
tmpFile.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
aerc.PushError(err.Error())
|
aerc.PushError(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
xdg := lib.NewXDGOpen(tmpFile.Name())
|
|
||||||
// pass through any arguments the user provided to the underlying handler
|
|
||||||
if len(args) > 1 {
|
|
||||||
xdg.SetArgs(args[1:])
|
|
||||||
}
|
|
||||||
err = xdg.Start()
|
|
||||||
if err != nil {
|
|
||||||
aerc.PushError(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
go func() {
|
go func() {
|
||||||
defer logging.PanicHandler()
|
err = lib.XDGOpen(tmpFile.Name())
|
||||||
|
|
||||||
err := xdg.Wait()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
aerc.PushError(err.Error())
|
aerc.PushError("open: " + err.Error())
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
aerc.PushStatus("Opened", 10*time.Second)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
58
lib/open.go
58
lib/open.go
|
@ -1,65 +1,25 @@
|
||||||
package lib
|
package lib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"git.sr.ht/~rjarry/aerc/logging"
|
"git.sr.ht/~rjarry/aerc/logging"
|
||||||
)
|
)
|
||||||
|
|
||||||
var openBin string = "xdg-open"
|
func XDGOpen(uri string) error {
|
||||||
|
openBin := "xdg-open"
|
||||||
func init() {
|
|
||||||
if runtime.GOOS == "darwin" {
|
if runtime.GOOS == "darwin" {
|
||||||
openBin = "open"
|
openBin = "open"
|
||||||
}
|
}
|
||||||
}
|
args := []string{openBin, uri}
|
||||||
|
logging.Infof("running command: %v", args)
|
||||||
type xdgOpen struct {
|
cmd := exec.Command(args[0], args[1:]...)
|
||||||
args []string
|
out, err := cmd.CombinedOutput()
|
||||||
errCh chan (error)
|
logging.Debugf("command: %v exited. err=%v out=%s", args, err, out)
|
||||||
cmd *exec.Cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewXDGOpen returns a handler for opening a file via the system handler xdg-open
|
|
||||||
// or comparable tools on other OSs than Linux
|
|
||||||
func NewXDGOpen(filename string) *xdgOpen {
|
|
||||||
errch := make(chan error, 1)
|
|
||||||
return &xdgOpen{
|
|
||||||
errCh: errch,
|
|
||||||
args: []string{filename},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetArgs sets additional arguments to the open command prior to the filename
|
|
||||||
func (xdg *xdgOpen) SetArgs(args []string) {
|
|
||||||
args = append([]string{}, args...) // don't overwrite array of caller
|
|
||||||
filename := xdg.args[len(xdg.args)-1]
|
|
||||||
xdg.args = append(args, filename) //nolint:gocritic // intentional append to different slice
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start the open handler.
|
|
||||||
// Returns an error if the command could not be started.
|
|
||||||
// Use Wait to wait for the commands completion and to check the error.
|
|
||||||
func (xdg *xdgOpen) Start() error {
|
|
||||||
xdg.cmd = exec.Command(openBin, xdg.args...)
|
|
||||||
err := xdg.cmd.Start()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
xdg.errCh <- err // for callers that just check the error from Wait()
|
return fmt.Errorf("%v: %w", args, err)
|
||||||
close(xdg.errCh)
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
go func() {
|
|
||||||
defer logging.PanicHandler()
|
|
||||||
|
|
||||||
xdg.errCh <- xdg.cmd.Wait()
|
|
||||||
close(xdg.errCh)
|
|
||||||
}()
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for the xdg-open command to complete
|
|
||||||
// The xdgOpen must have been started
|
|
||||||
func (xdg *xdgOpen) Wait() error {
|
|
||||||
return <-xdg.errCh
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue