giffer

Create .gif images from sites like youtube.com
Log | Files | Refs | LICENSE

commit 6868af5a8a169796590b2e7ff6595f2166445b77
parent 1b72b6aa385e027db5af090d15ef2a3295f3803b
Author: Jack Mordaunt <jackmordaunt@gmail.com>
Date:   Thu, 15 Nov 2018 12:32:37 +1300

[+] Automatically open and keep open a browser window for the app.

Diffstat:
Acmd/desktop/browser.go | 72++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mcmd/desktop/main.go | 52+++++++++++++++++++++++++++++++++++++---------------
2 files changed, 109 insertions(+), 15 deletions(-)

diff --git a/cmd/desktop/browser.go b/cmd/desktop/browser.go @@ -0,0 +1,72 @@ +package main + +import ( + "fmt" + "os/exec" + "runtime" + "time" + + "github.com/pkg/errors" +) + +// Browser opens the default browser for a given url. +type Browser struct { + OnErr func(error) + OnRestart func() + Loop bool + failed chan error +} + +// Open a browser window, re-opening it when closed if Loop is true. +// Note: open simply uses OS default application, which may not actually be a +// web browser. +func (b *Browser) Open(u string) error { + cmd := b.open(u) + if cmd == nil { + return fmt.Errorf("not implemented on this OS") + } + b.failed = make(chan error) + if b.OnErr == nil { + b.OnErr = func(error) {} + } + if b.OnRestart == nil { + b.OnRestart = func() {} + } + go func() { + for { + cmd := b.open(u) + if err := func() error { + if out, err := cmd.CombinedOutput(); err != nil { + return errors.Wrap(err, string(out)) + } + return nil + }(); err != nil { + b.failed <- err + } + if !b.Loop { + break + } + time.Sleep(time.Millisecond * 200) + b.OnRestart() + } + }() + go func() { + for err := range b.failed { + b.OnErr(err) + } + }() + return nil +} + +func (Browser) open(u string) *exec.Cmd { + var cmd *exec.Cmd + switch runtime.GOOS { + case "darwin": + cmd = exec.Command("open", u, "-W") + case "linux": + cmd = exec.Command("xdg-open", u) + case "windows": + cmd = exec.Command("start", "/wait", "", u) + } + return cmd +} diff --git a/cmd/desktop/main.go b/cmd/desktop/main.go @@ -6,6 +6,7 @@ import ( "log" "net/http" "net/url" + "sync" "time" "github.com/jackmordaunt/giffer" @@ -18,18 +19,22 @@ import ( ) var ( + host string port string devServer string verbose bool headless bool + browser bool static http.Handler // responsible for serving UI files. ) func init() { + flag.StringVar(&host, "host", "localhost", "host address to serve on") flag.StringVar(&port, "p", "8080", "port to serve on") flag.StringVar(&devServer, "dev-proxy", "", "proxy to forward to (eg, yarn run serve)") flag.BoolVar(&verbose, "v", false, "verbose mode") flag.BoolVar(&headless, "headless", false, "headless mode; run only the server") + flag.BoolVar(&browser, "browser", false, "open in default browser instead of webview; overriden by [headless]") flag.Parse() if devServer != "" { t, err := url.Parse(devServer) @@ -60,29 +65,46 @@ func main() { Verbose: verbose, } svr := &http.Server{ - Addr: fmt.Sprintf(":%s", port), + Addr: fmt.Sprintf("%s:%s", host, port), Handler: ui, WriteTimeout: 15 * time.Second, ReadTimeout: 15 * time.Second, } - if headless { + backend := sync.WaitGroup{} + defer backend.Wait() + backend.Add(1) + go func() { + defer backend.Done() if err := svr.ListenAndServe(); err != nil { log.Fatalf("ui server: %v", err) } + }() + if headless { return } - go func() { - if err := svr.ListenAndServe(); err != nil { - log.Fatalf("ui server: %v", err) + url := fmt.Sprintf("http://%s:%s", host, port) + if browser { + b := &Browser{ + OnErr: func(err error) { + log.Printf("browser: %v", err) + }, + Loop: true, + OnRestart: func() { + log.Printf("restarting browser") + }, } - }() - view := webview.New(webview.Settings{ - Title: "Giffer", - URL: fmt.Sprintf("http://localhost:%s", port), - Width: 800, - Height: 600, - Resizable: true, - Debug: true, - }) - view.Run() + if err := b.Open(url); err != nil { + log.Fatalf("opening browser: %v", err) + } + } else { + view := webview.New(webview.Settings{ + Title: "Giffer", + URL: url, + Width: 800, + Height: 600, + Resizable: true, + Debug: true, + }) + view.Run() + } }