From 9286e21026d5343622dc0678166fbf075e910d79 Mon Sep 17 00:00:00 2001 From: wwqgtxx Date: Sat, 5 Oct 2024 13:40:00 +0800 Subject: [PATCH] chore: rebuild external ui updater --- component/updater/update_ui.go | 81 ++++++++++++++++++++++++++-------- config/config.go | 32 +++----------- hub/executor/executor.go | 15 ++----- hub/route/upgrade.go | 2 +- 4 files changed, 74 insertions(+), 56 deletions(-) diff --git a/component/updater/update_ui.go b/component/updater/update_ui.go index 29081761a..48d6536c1 100644 --- a/component/updater/update_ui.go +++ b/component/updater/update_ui.go @@ -14,24 +14,69 @@ import ( "github.com/metacubex/mihomo/log" ) -var ( - ExternalUIURL string - ExternalUIPath string - AutoDownloadUI bool -) +type UIUpdater struct { + externalUIURL string + externalUIPath string + autoDownloadUI bool -var xdMutex sync.Mutex + mutex sync.Mutex +} -func DownloadUI() error { - xdMutex.Lock() - defer xdMutex.Unlock() +var DefaultUiUpdater = &UIUpdater{} - err := prepareUIPath() +func NewUiUpdater(externalUI, externalUIURL, externalUIName string) *UIUpdater { + updater := &UIUpdater{} + // checkout externalUI exist + if externalUI != "" { + updater.autoDownloadUI = true + updater.externalUIPath = C.Path.Resolve(externalUI) + } else { + // default externalUI path + updater.externalUIPath = path.Join(C.Path.HomeDir(), "ui") + } + + // checkout UIpath/name exist + if externalUIName != "" { + updater.autoDownloadUI = true + updater.externalUIPath = path.Join(updater.externalUIPath, externalUIName) + } + + if externalUIURL != "" { + updater.externalUIURL = externalUIURL + } + return updater +} + +func (u *UIUpdater) AutoDownloadUI() { + u.mutex.Lock() + defer u.mutex.Unlock() + if u.autoDownloadUI { + dirEntries, _ := os.ReadDir(u.externalUIPath) + if len(dirEntries) > 0 { + log.Infoln("UI already exists, skip downloading") + } else { + log.Infoln("External UI downloading ...") + err := u.downloadUI() + if err != nil { + log.Errorln("Error downloading UI:", err) + } + } + } +} + +func (u *UIUpdater) DownloadUI() error { + u.mutex.Lock() + defer u.mutex.Unlock() + return u.downloadUI() +} + +func (u *UIUpdater) downloadUI() error { + err := u.prepareUIPath() if err != nil { return fmt.Errorf("prepare UI path failed: %w", err) } - data, err := downloadForBytes(ExternalUIURL) + data, err := downloadForBytes(u.externalUIURL) if err != nil { return fmt.Errorf("can't download file: %w", err) } @@ -42,7 +87,7 @@ func DownloadUI() error { } defer os.Remove(saved) - err = cleanup(ExternalUIPath) + err = cleanup(u.externalUIPath) if err != nil { if !os.IsNotExist(err) { return fmt.Errorf("cleanup exist file error: %w", err) @@ -54,18 +99,18 @@ func DownloadUI() error { return fmt.Errorf("can't extract zip file: %w", err) } - err = os.Rename(unzipFolder, ExternalUIPath) + err = os.Rename(unzipFolder, u.externalUIPath) if err != nil { return fmt.Errorf("rename UI folder failed: %w", err) } return nil } -func prepareUIPath() error { - if _, err := os.Stat(ExternalUIPath); os.IsNotExist(err) { - log.Infoln("dir %s does not exist, creating", ExternalUIPath) - if err := os.MkdirAll(ExternalUIPath, os.ModePerm); err != nil { - log.Warnln("create dir %s error: %s", ExternalUIPath, err) +func (u *UIUpdater) prepareUIPath() error { + if _, err := os.Stat(u.externalUIPath); os.IsNotExist(err) { + log.Infoln("dir %s does not exist, creating", u.externalUIPath) + if err := os.MkdirAll(u.externalUIPath, os.ModePerm); err != nil { + log.Warnln("create dir %s error: %s", u.externalUIPath, err) } } return nil diff --git a/config/config.go b/config/config.go index 3ca57a459..c1d70e81c 100644 --- a/config/config.go +++ b/config/config.go @@ -7,7 +7,6 @@ import ( "net" "net/netip" "net/url" - "path" "strings" "time" @@ -105,6 +104,8 @@ type Controller struct { ExternalControllerUnix string ExternalControllerPipe string ExternalUI string + ExternalUIURL string + ExternalUIName string ExternalDohServer string Secret string Cors Cors @@ -718,33 +719,10 @@ func parseGeneral(cfg *RawConfig) (*General, error) { mihomoHttp.SetUA(cfg.GlobalUA) resource.SetETag(cfg.ETagSupport) - if cfg.KeepAliveIdle != 0 { - keepalive.SetKeepAliveIdle(time.Duration(cfg.KeepAliveIdle) * time.Second) - } - if cfg.KeepAliveInterval != 0 { - keepalive.SetKeepAliveInterval(time.Duration(cfg.KeepAliveInterval) * time.Second) - } + keepalive.SetKeepAliveIdle(time.Duration(cfg.KeepAliveIdle) * time.Second) + keepalive.SetKeepAliveInterval(time.Duration(cfg.KeepAliveInterval) * time.Second) keepalive.SetDisableKeepAlive(cfg.DisableKeepAlive) - // checkout externalUI exist - if cfg.ExternalUI != "" { - updater.AutoDownloadUI = true - updater.ExternalUIPath = C.Path.Resolve(cfg.ExternalUI) - } else { - // default externalUI path - updater.ExternalUIPath = path.Join(C.Path.HomeDir(), "ui") - } - - // checkout UIpath/name exist - if cfg.ExternalUIName != "" { - updater.AutoDownloadUI = true - updater.ExternalUIPath = path.Join(updater.ExternalUIPath, cfg.ExternalUIName) - } - - if cfg.ExternalUIURL != "" { - updater.ExternalUIURL = cfg.ExternalUIURL - } - return &General{ Inbound: Inbound{ Port: cfg.Port, @@ -790,6 +768,8 @@ func parseController(cfg *RawConfig) (*Controller, error) { return &Controller{ ExternalController: cfg.ExternalController, ExternalUI: cfg.ExternalUI, + ExternalUIURL: cfg.ExternalUIURL, + ExternalUIName: cfg.ExternalUIName, Secret: cfg.Secret, ExternalControllerPipe: cfg.ExternalControllerPipe, ExternalControllerUnix: cfg.ExternalControllerUnix, diff --git a/hub/executor/executor.go b/hub/executor/executor.go index b8d9cddb9..0492c430f 100644 --- a/hub/executor/executor.go +++ b/hub/executor/executor.go @@ -117,7 +117,7 @@ func ApplyConfig(cfg *config.Config, force bool) { runtime.GC() tunnel.OnRunning() hcCompatibleProvider(cfg.Providers) - initExternalUI() + initExternalUI(cfg.Controller) resolver.ResetConnection() } @@ -394,16 +394,9 @@ func updateTunnels(tunnels []LC.Tunnel) { listener.PatchTunnel(tunnels, tunnel.Tunnel) } -func initExternalUI() { - if updater.AutoDownloadUI { - dirEntries, _ := os.ReadDir(updater.ExternalUIPath) - if len(dirEntries) > 0 { - log.Infoln("UI already exists, skip downloading") - } else { - log.Infoln("External UI downloading ...") - updater.DownloadUI() - } - } +func initExternalUI(controller *config.Controller) { + updater.DefaultUiUpdater = updater.NewUiUpdater(controller.ExternalUI, controller.ExternalUIURL, controller.ExternalUIName) + updater.DefaultUiUpdater.AutoDownloadUI() } func updateGeneral(general *config.General) { diff --git a/hub/route/upgrade.go b/hub/route/upgrade.go index 25c326ddd..2fed3f676 100644 --- a/hub/route/upgrade.go +++ b/hub/route/upgrade.go @@ -47,7 +47,7 @@ func upgradeCore(w http.ResponseWriter, r *http.Request) { } func updateUI(w http.ResponseWriter, r *http.Request) { - err := updater.DownloadUI() + err := updater.DefaultUiUpdater.DownloadUI() if err != nil { log.Warnln("%s", err) render.Status(r, http.StatusInternalServerError)