From e040c3fac767176ee34f0ca04f26457cceb0f152 Mon Sep 17 00:00:00 2001 From: c9s Date: Mon, 22 Feb 2021 13:43:59 +0800 Subject: [PATCH] add webview program --- cmd/bbgo-webview/main.go | 160 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 cmd/bbgo-webview/main.go diff --git a/cmd/bbgo-webview/main.go b/cmd/bbgo-webview/main.go new file mode 100644 index 000000000..f0eff2e36 --- /dev/null +++ b/cmd/bbgo-webview/main.go @@ -0,0 +1,160 @@ +package main + +import ( + "context" + "flag" + "net" + "os" + "os/signal" + "path/filepath" + "strconv" + "time" + + "github.com/joho/godotenv" + "github.com/webview/webview" + + log "github.com/sirupsen/logrus" + + "github.com/c9s/bbgo/pkg/bbgo" + "github.com/c9s/bbgo/pkg/cmd" + "github.com/c9s/bbgo/pkg/server" +) + +func main() { + noChangeDir := false + flag.BoolVar(&noChangeDir, "no-chdir", false, "do not change directory") + flag.Parse() + + if !noChangeDir { + ep, err := os.Executable() + if err != nil { + log.Fatalln("failed to find the current executable:", err) + } + + resourceDir := filepath.Join(filepath.Dir(ep), "..", "Resources") + if _, err := os.Stat(resourceDir); err == nil { + err = os.Chdir(resourceDir) + if err != nil { + log.Fatalln("chdir error:", err) + } + } + } + + dotenvFile := ".env.local" + if _, err := os.Stat(dotenvFile); err == nil { + if err := godotenv.Load(dotenvFile); err != nil { + log.WithError(err).Error("error loading dotenv file") + return + } + } + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + debug, _ := strconv.ParseBool(os.Getenv("DEBUG_WEBVIEW")) + view := webview.New(debug) + defer view.Destroy() + + view.SetTitle("BBGO") + view.SetSize(1024, 780, webview.HintNone) + + configFile := "bbgo.yaml" + var setup *server.Setup + var userConfig *bbgo.Config + + _, err := os.Stat(configFile) + if os.IsNotExist(err) { + setup = &server.Setup{ + Context: ctx, + Cancel: cancel, + Token: "", + BeforeRestart: func() { + view.Destroy() + }, + } + userConfig = &bbgo.Config{ + Notifications: nil, + Persistence: nil, + Sessions: nil, + ExchangeStrategies: nil, + } + } else { + userConfig, err = bbgo.Load(configFile, true) + if err != nil { + log.WithError(err).Error("can not load config file") + return + } + } + + environ := bbgo.NewEnvironment() + trader := bbgo.NewTrader(environ) + + // we could initialize the environment from the settings + if setup == nil { + if err := cmd.BootstrapEnvironment(ctx, environ, userConfig); err != nil { + log.WithError(err).Error("failed to bootstrap environment") + return + } + + // we could initialize the environment from the settings + go func() { + if err := environ.Sync(ctx); err != nil { + log.WithError(err).Error("failed to sync data") + return + } + + if err := trader.Configure(userConfig); err != nil { + log.WithError(err).Error("failed to configure trader") + return + } + + // for setup mode, we don't start the trader + if err := trader.Run(ctx); err != nil { + log.WithError(err).Error("failed to start trader") + } + }() + } + + // find a free port for binding the server + ln, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + log.WithError(err).Error("can not bind listener") + return + } + + defer ln.Close() + + baseURL := "http://" + ln.Addr().String() + + srv := &server.Server{ + Config: userConfig, + Environ: environ, + Trader: trader, + OpenInBrowser: false, + Setup: setup, + } + + go func() { + if err := srv.RunWithListener(ctx, ln); err != nil { + log.WithError(err).Errorf("server error") + } + }() + + log.Infof("pinging the server at %s", baseURL) + server.PingUntil(ctx, time.Second, baseURL, func() { + log.Infof("got pong, navigate to %s", baseURL) + view.Navigate(baseURL) + view.Run() + }) + + // Wait until the interrupt signal arrives or browser window is closed + sigc := make(chan os.Signal) + signal.Notify(sigc, os.Interrupt) + + select { + case <-sigc: + } + + log.Println("exiting...") + view.Destroy() +}