From 5d5d90d3f6a077ff3ac8e513f9c92e76981d3138 Mon Sep 17 00:00:00 2001 From: Urko Date: Fri, 2 Jun 2023 03:24:12 +0200 Subject: [PATCH] feat: handle multiple providers --- internal/providers/huawei.go | 112 +++++++++++++++++++++++++++++ internal/providers/nucom.go | 129 ++++++++++++++++++++++++++++++++++ internal/switcher/switcher.go | 108 +++++----------------------- main.go | 33 ++------- pkg/provider/provider.go | 6 ++ pkg/switcher/switcher.go | 5 -- 6 files changed, 272 insertions(+), 121 deletions(-) create mode 100644 internal/providers/huawei.go create mode 100644 internal/providers/nucom.go create mode 100644 pkg/provider/provider.go delete mode 100644 pkg/switcher/switcher.go diff --git a/internal/providers/huawei.go b/internal/providers/huawei.go new file mode 100644 index 0000000..5104452 --- /dev/null +++ b/internal/providers/huawei.go @@ -0,0 +1,112 @@ +package providers + +import ( + "fmt" + "log" + "time" + + "github.com/go-rod/rod" +) + +type Huawei struct { + usernameID string + userpasswordID string + loginText string + skipText string + netID string + netWlanID string + mainFrameID string + wlanEnableID string + page *rod.Page +} + +func NewHuawei(page *rod.Page) Huawei { + return Huawei{ + usernameID: "#username", + userpasswordID: "#userpassword", + loginText: "Login", + skipText: "Skip", + netID: "#Net", + netWlanID: "#Net-WLAN", + mainFrameID: "#mainFrame", + wlanEnableID: "#wlanEnable", + page: page, + } +} + +func (p *Huawei) Login(user, pass string) error { + username, err := p.page.Element(p.usernameID) + if err != nil { + return fmt.Errorf("page.Element %s: %s", p.userpasswordID, err) + } + username.MustInput(user) + log.Println(p.usernameID, "DONE") + + userpassword, err := p.page.Element(p.userpasswordID) + if err != nil { + return fmt.Errorf("page.Element %s: %s", p.userpasswordID, err) + } + userpassword.MustInput(pass) + log.Println(p.userpasswordID, "DONE") + + login, err := p.page.Element(`input[value="` + p.loginText + `"]`) + if err != nil { + return fmt.Errorf("page.Element %s: %s", p.loginText, err) + } + login.MustClick() + log.Println(p.loginText, "DONE") + + skip, err := p.page.Element(`input[value="` + p.skipText + `"]`) + if err != nil { + return fmt.Errorf("page.Element %s: %s", p.skipText, err) + } + skip.MustClick() + log.Println(p.skipText, "DONE") + + return nil +} + +func (p Huawei) SwitchWIFI() error { + net, err := p.page.Element(p.netID) + if err != nil { + return fmt.Errorf("page.Element %s: %s", p.netID, err) + } + net.MustClick() + log.Println(p.netID, "DONE") + + netWlan, err := p.page.Element(p.netWlanID) + if err != nil { + return fmt.Errorf("page.Element %s: %s", p.netWlanID, err) + } + netWlan.MustClick() + log.Println(p.netWlanID, "DONE") + + frameElement, err := p.page.Element(p.mainFrameID) + if err != nil { + return fmt.Errorf("page.Element %s: %s", p.mainFrameID, err) + } + + mainFrame, err := frameElement.Frame() + if err != nil { + return fmt.Errorf("frameElement.Frame: %s", err) + } + + wlanEnable, err := mainFrame.Element(p.wlanEnableID) + if err != nil { + return fmt.Errorf("mainFrame.Element %s: %s", p.wlanEnableID, err) + } + wlanEnable.MustClick() + log.Println(p.wlanEnableID, "DONE") + + sysSubmitID := "#sysSubmit" + sysSubmit, err := mainFrame.Element(sysSubmitID) + if err != nil { + return fmt.Errorf("mainFrame.Element %s: %s", sysSubmitID, err) + } + sysSubmit.MustClick() + log.Println(sysSubmitID, "DONE") + + // TODO: improve this and wait until something should happens (refresh) + time.Sleep(time.Second * 3) + return nil +} diff --git a/internal/providers/nucom.go b/internal/providers/nucom.go new file mode 100644 index 0000000..fb6634d --- /dev/null +++ b/internal/providers/nucom.go @@ -0,0 +1,129 @@ +package providers + +import ( + "fmt" + "log" + "time" + + "github.com/go-rod/rod" +) + +type Nucom struct { + usernameName string + passwordName string + loginSubmitID string + wirelessTabID string + wirelessMenuText string + configureWarningID string + wifiRadioID string + saveID string + radioOff string + radioOn string + page *rod.Page +} + +func NewNucom(page *rod.Page) Nucom { + return Nucom{ + usernameName: "loginUser", + passwordName: "loginPass", + loginSubmitID: "btnApply", + wirelessTabID: "menu_wireless", + wirelessMenuText: "Básico", + configureWarningID: "Configurar ahora", + wifiRadioID: "radiohiddenButton", + radioOff: "Apagada", + radioOn: "Encendida", + saveID: "basicApply", + page: page, + } +} + +func (p Nucom) Login(user, pass string) error { + username, err := p.page.Element(`input[name="` + p.usernameName + `"]`) + if err != nil { + return fmt.Errorf("page.Element %s: %s", p.passwordName, err) + } + username.MustInput(user) + log.Println(p.usernameName, "DONE") + + userpassword, err := p.page.Element(`input[name="` + p.passwordName + `"]`) + if err != nil { + return fmt.Errorf("page.Element %s: %s", p.passwordName, err) + } + userpassword.MustInput(pass) + log.Println(p.passwordName, "DONE") + + login, err := p.page.Element(`input[id="` + p.loginSubmitID + `"]`) + if err != nil { + return fmt.Errorf("page.Element %s: %s", p.loginSubmitID, err) + } + login.MustClick() + log.Println(p.loginSubmitID, "DONE") + return nil +} + +func (p Nucom) SwitchWIFI() error { + wirelessMenu, err := p.page.Element(`a[id="` + p.wirelessTabID + `"]`) + if err != nil { + return fmt.Errorf("page.Element %s: %s", p.wirelessTabID, err) + } + wirelessMenu.MustClick() + log.Println(p.wirelessTabID, "DONE") + time.Sleep(time.Millisecond * 500) + log.Println(p.page.MustInfo().URL) + + isOn, _, err := p.page.Has(`[id="basicRadioButton"]`) + if err != nil { + return fmt.Errorf("page.Element %s: %s", p.wifiRadioID, err) + } + log.Println("is on", isOn) + if !isOn { + warningButton, err := p.page.Element(`[value="` + p.configureWarningID + `"]`) + if err != nil { + return fmt.Errorf("page.Element %s: %s", p.configureWarningID, err) + } + warningButton.MustClick() + log.Println(warningButton, "DONE") + } + wifiRadios, err := p.page.Elements(`[name="radiohiddenButton"]`) + if err != nil { + return fmt.Errorf("page.Element %s: %s", p.wifiRadioID, err) + } + + if len(wifiRadios) != 2 { + return fmt.Errorf("radios not found") + } + offChecked := wifiRadios[0].MustProperty("checked") + + log.Println("wifiRadios[0]", wifiRadios[0].MustProperty("checked")) + log.Println("wifiRadios[1]", wifiRadios[1].MustProperty("checked")) + log.Println("offChecked.Bool()", offChecked.Bool()) + if offChecked.Bool() { + wifiRadios[1].MustClick() + } else { + wifiRadios[0].MustClick() + } + + wifiRadios, err = p.page.Elements(`[name="radiohiddenButton"]`) + if err != nil { + return fmt.Errorf("page.Element %s: %s", p.wifiRadioID, err) + } + offChecked, err = wifiRadios[0].Property("checked") + if err != nil { + return fmt.Errorf("page.Element %s: %s", p.wifiRadioID, err) + } + + log.Println("offChecked.Bool() AFTER CHECK", offChecked.Bool()) + log.Println(p.wifiRadioID, "DONE") + + time.Sleep(time.Millisecond * 500) + + saveButton, err := p.page.Element(`input[id="` + p.saveID + `"]`) + if err != nil { + return fmt.Errorf("page.Element %s: %s", p.saveID, err) + } + saveButton.MustClick() + log.Println(p.saveID, "DONE") + + return nil +} diff --git a/internal/switcher/switcher.go b/internal/switcher/switcher.go index 4326ec7..13bde29 100644 --- a/internal/switcher/switcher.go +++ b/internal/switcher/switcher.go @@ -2,116 +2,44 @@ package switcher import ( "fmt" - "log" - "time" "gitea.urkob.com/urko/go-wifi-switcher/cfg" + "gitea.urkob.com/urko/go-wifi-switcher/pkg/provider" "github.com/go-rod/rod" ) type switcher struct { - remoteControlBrowserUrl string - config *cfg.Config + Browser *rod.Browser + Page *rod.Page + config *cfg.Config } -var ( - usernameID = "#username" - userpasswordID = "#userpassword" - loginText = "Login" - skipText = "Skip" - netID = "#Net" - netWlanID = "#Net-WLAN" - mainFrameID = "#mainFrame" - wlanEnableID = "#wlanEnable" -) - func NewSwitcher(remoteControlBrowserUrl string, config *cfg.Config) switcher { - return switcher{ - remoteControlBrowserUrl: remoteControlBrowserUrl, - config: config, - } -} - -func (s switcher) SwitchWIFI() error { browser := rod.New(). - ControlURL(s.remoteControlBrowserUrl). + ControlURL(remoteControlBrowserUrl). MustConnect(). MustIgnoreCertErrors(true) - defer browser.MustClose() + page := browser.MustPage(config.Page) - page := browser.MustPage(s.config.Page) - - defer page.Close() - - username, err := page.Element(usernameID) - if err != nil { - return fmt.Errorf("page.Element %s: %s", userpasswordID, err) + return switcher{ + Browser: browser, + Page: page, + config: config, } - username.MustInput(s.config.AdminUser) - log.Println(usernameID, "DONE") +} - userpassword, err := page.Element(userpasswordID) - if err != nil { - return fmt.Errorf("page.Element %s: %s", userpasswordID, err) - } - userpassword.MustInput(s.config.Password) - log.Println(userpasswordID, "DONE") +func (s switcher) SwitchWIFI(prv provider.ProviderIface) error { + defer s.Browser.MustClose() + defer s.Page.Close() - login, err := page.Element(`input[value="` + loginText + `"]`) - if err != nil { - return fmt.Errorf("page.Element %s: %s", loginText, err) - } - login.MustClick() - log.Println(loginText, "DONE") - - skip, err := page.Element(`input[value="` + skipText + `"]`) - if err != nil { - return fmt.Errorf("page.Element %s: %s", skipText, err) - } - skip.MustClick() - log.Println(skipText, "DONE") - - net, err := page.Element(netID) - if err != nil { - return fmt.Errorf("page.Element %s: %s", netID, err) - } - net.MustClick() - log.Println(netID, "DONE") - - netWlan, err := page.Element(netWlanID) - if err != nil { - return fmt.Errorf("page.Element %s: %s", netWlanID, err) - } - netWlan.MustClick() - log.Println(netWlanID, "DONE") - - frameElement, err := page.Element(mainFrameID) - if err != nil { - return fmt.Errorf("page.Element %s: %s", mainFrameID, err) + if err := prv.Login(s.config.AdminUser, s.config.Password); err != nil { + return fmt.Errorf("prv.Login %w", err) } - mainFrame, err := frameElement.Frame() - if err != nil { - return fmt.Errorf("frameElement.Frame: %s", err) + if err := prv.SwitchWIFI(); err != nil { + return fmt.Errorf("prv.SwitchWIFI %w", err) } - wlanEnable, err := mainFrame.Element(wlanEnableID) - if err != nil { - return fmt.Errorf("mainFrame.Element %s: %s", wlanEnableID, err) - } - wlanEnable.MustClick() - log.Println(wlanEnableID, "DONE") - - sysSubmitID := "#sysSubmit" - sysSubmit, err := mainFrame.Element(sysSubmitID) - if err != nil { - return fmt.Errorf("mainFrame.Element %s: %s", sysSubmitID, err) - } - sysSubmit.MustClick() - log.Println(sysSubmitID, "DONE") - - // TODO: improve this and wait until something should happens (refresh) - time.Sleep(time.Second * 3) return nil } diff --git a/main.go b/main.go index c92bb7b..26c8e8c 100644 --- a/main.go +++ b/main.go @@ -8,15 +8,13 @@ import ( "time" "gitea.urkob.com/urko/go-wifi-switcher/cfg" + "gitea.urkob.com/urko/go-wifi-switcher/internal/providers" "gitea.urkob.com/urko/go-wifi-switcher/internal/switcher" - pkgswitcher "gitea.urkob.com/urko/go-wifi-switcher/pkg/switcher" "github.com/go-rod/rod/lib/launcher" "github.com/go-rod/rod/lib/utils" "github.com/ysmood/leakless" ) -var sw pkgswitcher.SwitcherIface - func main() { envFile := "" if os.Getenv("ENV") != "prod" { @@ -40,6 +38,7 @@ func main() { var lc *launcher.Launcher var remoteControlBrowserURL string + log.Println("config", config) if config.Bin != "" { lc = launcher.New().Bin(config.Bin) remoteControlBrowserURL = lc.MustLaunch() @@ -57,30 +56,12 @@ func main() { remoteControlBrowserURL = launcher.MustResolveURL(<-parser.URL) } - sw = switcher.NewSwitcher(remoteControlBrowserURL, config) - if err := sw.SwitchWIFI(); err != nil { - log.Println("sw.SwitchWIFI", err) - err := retry(5, time.Second*5, sw.SwitchWIFI) - if err != nil { - log.Fatalln("couldn't retry:", err) - } + sw := switcher.NewSwitcher(remoteControlBrowserURL, config) + prv := providers.NewNucom(sw.Page) + err := sw.SwitchWIFI(prv) + if err != nil { + panic(err) } log.Println("task completed") } - -func retry(attempts int, sleep time.Duration, f func() error) error { - var err error - for i := 0; i < attempts; i++ { - if i > 0 { - log.Println("retrying after error:", err) - time.Sleep(sleep) - sleep *= 2 - } - err = f() - if err == nil { - return nil - } - } - return fmt.Errorf("after %d attempts, last error: %s", attempts, err) -} diff --git a/pkg/provider/provider.go b/pkg/provider/provider.go new file mode 100644 index 0000000..0c394e5 --- /dev/null +++ b/pkg/provider/provider.go @@ -0,0 +1,6 @@ +package provider + +type ProviderIface interface { + Login(user, pass string) error + SwitchWIFI() error +} diff --git a/pkg/switcher/switcher.go b/pkg/switcher/switcher.go deleted file mode 100644 index 882c15e..0000000 --- a/pkg/switcher/switcher.go +++ /dev/null @@ -1,5 +0,0 @@ -package switcher - -type SwitcherIface interface { - SwitchWIFI() error -}