package gui import ( "encoding/json" "io/ioutil" "net/http" "time" "github.com/UnnoTed/go-appindicator" "github.com/UnnoTed/wireguird/gui/get" "github.com/gotk3/gotk3/glib" "github.com/gotk3/gotk3/gtk" "github.com/rs/zerolog/log" "golang.zx2c4.com/wireguard/wgctrl" ) const ( Version = "1.1.0" Repo = "https://github.com/UnnoTed/wireguird" TunnelsPath = "/etc/wireguard/" IconPath = "/opt/wireguird/Icon/" ) var ( settingsWindow *gtk.Window editorWindow *gtk.Window application *gtk.Application indicator *appindicator.Indicator builder *gtk.Builder window *gtk.ApplicationWindow header *gtk.HeaderBar wgc *wgctrl.Client updateTicker *time.Ticker ) func Create(app *gtk.Application, b *gtk.Builder, w *gtk.ApplicationWindow, ind *appindicator.Indicator) error { application = app get.Builder = b indicator = ind builder = b window = w var err error header, err = get.HeaderBar("main_header") if err != nil { return err } wgc, err = wgctrl.New() if err != nil { ShowError(w, err) return err } ds, err := wgc.Devices() if err != nil { ShowError(w, err) return err } indicator.SetIcon("wireguard_off") for _, d := range ds { header.SetSubtitle("Connected to " + d.Name) indicator.SetIcon("wg_connected") } if _, err := createEditor("", false); err != nil { return err } if _, err := createSettings(false); err != nil { return err } t := &Tunnels{} if err := t.Create(); err != nil { return err } if Settings.CheckUpdates { go func() { time.Sleep(60 * time.Second) if err := updateCheck(); err != nil { log.Error().Err(err).Msg("error on update check") } updateTicker = time.NewTicker(24 * time.Hour) defer updateTicker.Stop() for { select { case <-updateTicker.C: if err := updateCheck(); err != nil { log.Error().Err(err).Msg("error on update check") } } } }() } window.HideOnDelete() return nil } func ShowError(win *gtk.ApplicationWindow, err error, info ...string) { if err == nil { return } glib.IdleAdd(func() { wlog("ERROR", err.Error()) dlg := gtk.MessageDialogNew(win, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, "%s", err.Error()) dlg.SetTitle("Error") dlg.Run() dlg.Destroy() }) } func createEditor(name string, show bool) (*gtk.Window, error) { if editorWindow == nil { var err error editorWindow, err = get.Window("editor_window") if err != nil { log.Error().Err(err).Msg("error getting main_window") return nil, err } // prevents having to re-create the editor window editorWindow.HideOnDelete() } if show { ne, err := get.Entry("editor_name") if err != nil { return nil, err } ne.SetText(name) editorWindow.SetTitle("Edit tunnel - " + name) editorWindow.ShowAll() } return editorWindow, nil } func createSettings(show bool) (*gtk.Window, error) { if settingsWindow == nil { var err error settingsWindow, err = get.Window("settings_window") if err != nil { log.Error().Err(err).Msg("error getting main_window") return nil, err } // prevents having to re-create the settings window settingsWindow.HideOnDelete() } if show { settingsWindow.SetTitle("Wireguird - Settings") settingsWindow.ShowAll() } return settingsWindow, nil } func updateCheck() error { log.Info().Msg("Checking for updates") resp, err := http.Get("https://api.github.com/repos/UnnoTed/wireguird/releases") if err != nil { return err } data, err := ioutil.ReadAll(resp.Body) if err != nil { return err } j := []map[string]interface{}{} if err := json.Unmarshal(data, &j); err != nil { return err } log.Info().Interface("json", j).Msg("response") if len(j) > 0 { latest := j[0] if tagName, ok := latest["tag_name"].(string); ok && tagName != "v"+Version { glib.IdleAdd(func() { d := gtk.MessageDialogNew(window, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, "Wireguird: update available => "+tagName) defer d.Destroy() d.Run() }) } } return nil }