From ef4466d0aec71fb12241f52ad3eb8065f5382d21 Mon Sep 17 00:00:00 2001 From: Vendicated Date: Fri, 17 Mar 2023 20:25:54 +0100 Subject: [PATCH] Add self update check --- constants.go | 12 +++++-- github_downloader.go | 77 ++++++++++++++++++++++++++------------------ gui.go | 49 +++++++++++++++++++++------- self_updater.go | 36 +++++++++++++++++++++ 4 files changed, 127 insertions(+), 47 deletions(-) create mode 100644 self_updater.go diff --git a/constants.go b/constants.go index 4172f43..66d81d0 100644 --- a/constants.go +++ b/constants.go @@ -25,10 +25,16 @@ import "image/color" var InstallerGitHash = "Unknown" var InstallerTag = "Unknown" +const ReleaseUrl = "https://api.github.com/repos/Vendicated/Vencord/releases/latest" +const InstallerReleaseUrl = "https://api.github.com/repos/Vencord/Installer/releases/latest" + +var UserAgent = "VencordInstaller/" + InstallerGitHash + " (https://github.com/Vendicated/VencordInstaller)" + var ( - DiscordGreen = color.RGBA{R: 0x2D, G: 0x7C, B: 0x46, A: 0xFF} - DiscordRed = color.RGBA{R: 0xEC, G: 0x41, B: 0x44, A: 0xFF} - DiscordBlue = color.RGBA{R: 0x58, G: 0x65, B: 0xF2, A: 0xFF} + DiscordGreen = color.RGBA{R: 0x2D, G: 0x7C, B: 0x46, A: 0xFF} + DiscordRed = color.RGBA{R: 0xEC, G: 0x41, B: 0x44, A: 0xFF} + DiscordBlue = color.RGBA{R: 0x58, G: 0x65, B: 0xF2, A: 0xFF} + DiscordYellow = color.RGBA{R: 0xf0, G: 0xb2, B: 0x32, A: 0xff} ) var LinuxDiscordNames = []string{ diff --git a/github_downloader.go b/github_downloader.go index 7f72eab..d1659ee 100644 --- a/github_downloader.go +++ b/github_downloader.go @@ -33,15 +33,14 @@ import ( ) type GithubRelease struct { - Name string `json:"name"` - Assets []struct { + Name string `json:"name"` + TagName string `json:"tag_name"` + Assets []struct { Name string `json:"name"` DownloadURL string `json:"browser_download_url"` } `json:"assets"` } -const releaseUrl = "https://api.github.com/repos/Vendicated/Vencord/releases/latest" - var ReleaseData GithubRelease var GithubError error var GithubDoneChan chan bool @@ -50,6 +49,42 @@ var InstalledHash = "None" var LatestHash = "Unknown" var IsDevInstall bool +func GetGithubRelease(url string) (*GithubRelease, error) { + fmt.Println("Fetching", url) + + req, err := http.NewRequest("GET", url, nil) + if err != nil { + fmt.Println("Failed to create Request", err) + return nil, err + } + + req.Header.Set("Accept", "application/vnd.github+json") + req.Header.Set("User-Agent", UserAgent) + + res, err := http.DefaultClient.Do(req) + if err != nil { + fmt.Println("Failed to send Request", err) + return nil, err + } + + defer res.Body.Close() + + if res.StatusCode >= 300 { + err = errors.New(res.Status) + fmt.Println("Github returned Non-OK status", GithubError) + return nil, err + } + + var data GithubRelease + + if err = json.NewDecoder(res.Body).Decode(&data); err != nil { + fmt.Println("Failed to decode GitHub JSON Response", err) + return nil, err + } + + return &data, nil +} + func InitGithubDownloader() { GithubDoneChan = make(chan bool, 1) @@ -66,40 +101,18 @@ func InitGithubDownloader() { GithubDoneChan <- GithubError == nil }() - fmt.Println("Fetching", releaseUrl) - req, err := http.NewRequest("GET", releaseUrl, nil) - if err != nil { - fmt.Println("Failed to create Request", err) - GithubError = err - return - } - - req.Header.Set("Accept", "application/vnd.github+json") - req.Header.Set("User-Agent", "VencordInstaller/"+InstallerGitHash+" (https://github.com/Vendicated/VencordInstaller)") - - res, err := http.DefaultClient.Do(req) + data, err := GetGithubRelease(ReleaseUrl) if err != nil { - fmt.Println("Failed to send Request", err) GithubError = err return } - defer res.Body.Close() + ReleaseData = *data - if res.StatusCode >= 300 { - GithubError = errors.New(res.Status) - fmt.Println("Github returned Non-OK status", GithubError) - return - } - - if GithubError = json.NewDecoder(res.Body).Decode(&ReleaseData); GithubError != nil { - fmt.Println("Failed to decode GitHub JSON Response", GithubError) - } else { - i := strings.LastIndex(ReleaseData.Name, " ") + 1 - LatestHash = ReleaseData.Name[i:] - fmt.Println("Finished fetching GitHub Data") - fmt.Println("Latest hash is", LatestHash, "Local Install is", Ternary(LatestHash == InstalledHash, "up to date!", "outdated!")) - } + i := strings.LastIndex(data.Name, " ") + 1 + LatestHash = data.Name[i:] + fmt.Println("Finished fetching GitHub Data") + fmt.Println("Latest hash is", LatestHash, "Local Install is", Ternary(LatestHash == InstalledHash, "up to date!", "outdated!")) }() // Check hash of installed version if exists diff --git a/gui.go b/gui.go index 445244e..0430847 100644 --- a/gui.go +++ b/gui.go @@ -6,6 +6,7 @@ import ( "errors" g "github.com/AllenDang/giu" "github.com/AllenDang/imgui-go" + "image/color" "os" path "path/filepath" "runtime" @@ -41,13 +42,18 @@ func main() { customChoiceIdx = len(discords) - win = g.NewMasterWindow("Vencord Installer", 1200, 800, 0) - win.Run(loop) - go func() { <-GithubDoneChan g.Update() }() + + go func() { + CheckSelfUpdate() + g.Update() + }() + + win = g.NewMasterWindow("Vencord Installer", 1200, 800, 0) + win.Run(loop) } type CondWidget struct { @@ -474,6 +480,25 @@ func renderInstaller() g.Widget { return layout } +func renderErrorCard(col color.Color, message string) g.Widget { + return g.Style(). + SetColor(g.StyleColorChildBg, col). + SetStyleFloat(g.StyleVarAlpha, 0.9). + SetStyle(g.StyleVarWindowPadding, 10, 10). + SetStyleFloat(g.StyleVarChildRounding, 5). + To( + g.Child(). + Size(g.Auto, 40). + Layout( + g.Row( + g.Style().SetColor(g.StyleColorText, color.Black).To( + g.Markdown(&message), + ), + ), + ), + ) +} + func loop() { g.PushWindowPadding(48, 48) @@ -515,7 +540,7 @@ func loop() { return g.Label("To customise this location, set the environment variable 'VENCORD_USER_DATA_DIR' and restart me").Wrapped(true) }, nil}, g.Dummy(0, 10), - g.Label("Installer Version: "+InstallerTag+" ("+InstallerGitHash+")"), + g.Label("Installer Version: "+InstallerTag+" ("+InstallerGitHash+")"+Ternary(IsInstallerOutdated, " - OUTDATED", "")), g.Label("Local Vencord Version: "+InstalledHash), &CondWidget{ GithubError == nil, @@ -525,15 +550,15 @@ func loop() { } return g.Label("Latest Vencord Version: " + LatestHash) }, func() g.Widget { - return g.Style(). - SetColor(g.StyleColorText, DiscordRed). - To( - g.Align(g.AlignCenter).To( - g.Label("Failed to fetch Info from GitHub: "+GithubError.Error()), - g.Label("Resolve this error, then restart me!"), - ), - ) + return renderErrorCard(DiscordRed, "Failed to fetch Info from GitHub: "+GithubError.Error()) + }, + }, + &CondWidget{ + IsInstallerOutdated, + func() g.Widget { + return renderErrorCard(DiscordYellow, "This Installer is outdated!"+GetInstallerDownloadMarkdown()) }, + nil, }, ), diff --git a/self_updater.go b/self_updater.go new file mode 100644 index 00000000..cff0a55 --- /dev/null +++ b/self_updater.go @@ -0,0 +1,36 @@ +package main + +import ( + "fmt" + "runtime" +) + +var IsInstallerOutdated = false + +func CheckSelfUpdate() { + fmt.Println("Checking for Installer Updates...") + + res, err := GetGithubRelease(InstallerReleaseUrl) + if err == nil { + IsInstallerOutdated = res.TagName != InstallerTag + } +} + +func GetInstallerDownloadLink() string { + switch runtime.GOOS { + case "windows": + return "https://github.com/Vencord/Installer/releases/latest/download/VencordInstaller.exe" + case "darwin": + return "https://github.com/Vencord/Installer/releases/latest/download/VencordInstaller.MacOS.zip" + default: + return "" + } +} + +func GetInstallerDownloadMarkdown() string { + link := GetInstallerDownloadLink() + if link == "" { + return "" + } + return " [Download the latest Installer](" + link + ")" +}