chore: rebuild external ui updater

This commit is contained in:
wwqgtxx 2024-10-05 13:40:00 +08:00
parent c63a851bba
commit 9286e21026
4 changed files with 74 additions and 56 deletions

View File

@ -14,24 +14,69 @@ import (
"github.com/metacubex/mihomo/log" "github.com/metacubex/mihomo/log"
) )
var ( type UIUpdater struct {
ExternalUIURL string externalUIURL string
ExternalUIPath string externalUIPath string
AutoDownloadUI bool autoDownloadUI bool
)
var xdMutex sync.Mutex mutex sync.Mutex
}
func DownloadUI() error { var DefaultUiUpdater = &UIUpdater{}
xdMutex.Lock()
defer xdMutex.Unlock()
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 { if err != nil {
return fmt.Errorf("prepare UI path failed: %w", err) return fmt.Errorf("prepare UI path failed: %w", err)
} }
data, err := downloadForBytes(ExternalUIURL) data, err := downloadForBytes(u.externalUIURL)
if err != nil { if err != nil {
return fmt.Errorf("can't download file: %w", err) return fmt.Errorf("can't download file: %w", err)
} }
@ -42,7 +87,7 @@ func DownloadUI() error {
} }
defer os.Remove(saved) defer os.Remove(saved)
err = cleanup(ExternalUIPath) err = cleanup(u.externalUIPath)
if err != nil { if err != nil {
if !os.IsNotExist(err) { if !os.IsNotExist(err) {
return fmt.Errorf("cleanup exist file error: %w", 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) return fmt.Errorf("can't extract zip file: %w", err)
} }
err = os.Rename(unzipFolder, ExternalUIPath) err = os.Rename(unzipFolder, u.externalUIPath)
if err != nil { if err != nil {
return fmt.Errorf("rename UI folder failed: %w", err) return fmt.Errorf("rename UI folder failed: %w", err)
} }
return nil return nil
} }
func prepareUIPath() error { func (u *UIUpdater) prepareUIPath() error {
if _, err := os.Stat(ExternalUIPath); os.IsNotExist(err) { if _, err := os.Stat(u.externalUIPath); os.IsNotExist(err) {
log.Infoln("dir %s does not exist, creating", ExternalUIPath) log.Infoln("dir %s does not exist, creating", u.externalUIPath)
if err := os.MkdirAll(ExternalUIPath, os.ModePerm); err != nil { if err := os.MkdirAll(u.externalUIPath, os.ModePerm); err != nil {
log.Warnln("create dir %s error: %s", ExternalUIPath, err) log.Warnln("create dir %s error: %s", u.externalUIPath, err)
} }
} }
return nil return nil

View File

@ -7,7 +7,6 @@ import (
"net" "net"
"net/netip" "net/netip"
"net/url" "net/url"
"path"
"strings" "strings"
"time" "time"
@ -105,6 +104,8 @@ type Controller struct {
ExternalControllerUnix string ExternalControllerUnix string
ExternalControllerPipe string ExternalControllerPipe string
ExternalUI string ExternalUI string
ExternalUIURL string
ExternalUIName string
ExternalDohServer string ExternalDohServer string
Secret string Secret string
Cors Cors Cors Cors
@ -718,33 +719,10 @@ func parseGeneral(cfg *RawConfig) (*General, error) {
mihomoHttp.SetUA(cfg.GlobalUA) mihomoHttp.SetUA(cfg.GlobalUA)
resource.SetETag(cfg.ETagSupport) resource.SetETag(cfg.ETagSupport)
if cfg.KeepAliveIdle != 0 { keepalive.SetKeepAliveIdle(time.Duration(cfg.KeepAliveIdle) * time.Second)
keepalive.SetKeepAliveIdle(time.Duration(cfg.KeepAliveIdle) * time.Second) keepalive.SetKeepAliveInterval(time.Duration(cfg.KeepAliveInterval) * time.Second)
}
if cfg.KeepAliveInterval != 0 {
keepalive.SetKeepAliveInterval(time.Duration(cfg.KeepAliveInterval) * time.Second)
}
keepalive.SetDisableKeepAlive(cfg.DisableKeepAlive) 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{ return &General{
Inbound: Inbound{ Inbound: Inbound{
Port: cfg.Port, Port: cfg.Port,
@ -790,6 +768,8 @@ func parseController(cfg *RawConfig) (*Controller, error) {
return &Controller{ return &Controller{
ExternalController: cfg.ExternalController, ExternalController: cfg.ExternalController,
ExternalUI: cfg.ExternalUI, ExternalUI: cfg.ExternalUI,
ExternalUIURL: cfg.ExternalUIURL,
ExternalUIName: cfg.ExternalUIName,
Secret: cfg.Secret, Secret: cfg.Secret,
ExternalControllerPipe: cfg.ExternalControllerPipe, ExternalControllerPipe: cfg.ExternalControllerPipe,
ExternalControllerUnix: cfg.ExternalControllerUnix, ExternalControllerUnix: cfg.ExternalControllerUnix,

View File

@ -117,7 +117,7 @@ func ApplyConfig(cfg *config.Config, force bool) {
runtime.GC() runtime.GC()
tunnel.OnRunning() tunnel.OnRunning()
hcCompatibleProvider(cfg.Providers) hcCompatibleProvider(cfg.Providers)
initExternalUI() initExternalUI(cfg.Controller)
resolver.ResetConnection() resolver.ResetConnection()
} }
@ -394,16 +394,9 @@ func updateTunnels(tunnels []LC.Tunnel) {
listener.PatchTunnel(tunnels, tunnel.Tunnel) listener.PatchTunnel(tunnels, tunnel.Tunnel)
} }
func initExternalUI() { func initExternalUI(controller *config.Controller) {
if updater.AutoDownloadUI { updater.DefaultUiUpdater = updater.NewUiUpdater(controller.ExternalUI, controller.ExternalUIURL, controller.ExternalUIName)
dirEntries, _ := os.ReadDir(updater.ExternalUIPath) updater.DefaultUiUpdater.AutoDownloadUI()
if len(dirEntries) > 0 {
log.Infoln("UI already exists, skip downloading")
} else {
log.Infoln("External UI downloading ...")
updater.DownloadUI()
}
}
} }
func updateGeneral(general *config.General) { func updateGeneral(general *config.General) {

View File

@ -47,7 +47,7 @@ func upgradeCore(w http.ResponseWriter, r *http.Request) {
} }
func updateUI(w http.ResponseWriter, r *http.Request) { func updateUI(w http.ResponseWriter, r *http.Request) {
err := updater.DownloadUI() err := updater.DefaultUiUpdater.DownloadUI()
if err != nil { if err != nil {
log.Warnln("%s", err) log.Warnln("%s", err)
render.Status(r, http.StatusInternalServerError) render.Status(r, http.StatusInternalServerError)