From 901bbf0706e22ee37ee4f940b274f40b412261b7 Mon Sep 17 00:00:00 2001 From: bytedream Date: Fri, 13 May 2022 19:22:17 +0200 Subject: [PATCH 1/2] Add update command --- cmd/crunchyroll-go/cmd/update.go | 134 +++++++++++++++++++++++++++++++ crunchyroll-go.1 | 9 +++ 2 files changed, 143 insertions(+) create mode 100644 cmd/crunchyroll-go/cmd/update.go diff --git a/cmd/crunchyroll-go/cmd/update.go b/cmd/crunchyroll-go/cmd/update.go new file mode 100644 index 0000000..4c7aaad --- /dev/null +++ b/cmd/crunchyroll-go/cmd/update.go @@ -0,0 +1,134 @@ +package cmd + +import ( + "encoding/json" + "fmt" + "github.com/spf13/cobra" + "io" + "os" + "os/exec" + "runtime" + "strings" +) + +var ( + updateInstallFlag bool +) + +var updateCmd = &cobra.Command{ + Use: "update", + Short: "Check if updates are available", + Args: cobra.MaximumNArgs(0), + + RunE: func(cmd *cobra.Command, args []string) error { + return update() + }, +} + +func init() { + updateCmd.Flags().BoolVarP(&updateInstallFlag, + "install", + "i", + false, + "If set and a new version is available, the new version gets installed") + + rootCmd.AddCommand(updateCmd) +} + +func update() error { + var release map[string]interface{} + + resp, err := client.Get("https://api.github.com/repos/ByteDream/crunchyroll-go/releases/latest") + if err != nil { + return err + } + defer resp.Body.Close() + if err = json.NewDecoder(resp.Body).Decode(&release); err != nil { + return err + } + releaseVersion := strings.TrimPrefix(release["tag_name"].(string), "v") + + if Version == "development" { + out.Info("Development version, update service not available") + return nil + } + + latestRelease := strings.SplitN(releaseVersion, ".", 4) + if len(latestRelease) != 3 { + return fmt.Errorf("latest tag name (%s) is not parsable", releaseVersion) + } + + internalVersion := strings.SplitN(Version, ".", 4) + if len(internalVersion) != 3 { + return fmt.Errorf("internal version (%s) is not parsable", Version) + } + + var hasUpdate bool + for i := 0; i < 3; i++ { + if latestRelease[i] < internalVersion[i] { + out.Info("Local version (%s) is newer than version in latest release (%s)", Version, releaseVersion) + return nil + } else if latestRelease[i] > internalVersion[i] { + hasUpdate = true + } + } + + if !hasUpdate { + out.Info("Version is up-to-date") + return nil + } + + out.Info("A new version is available (%s). Installed version is %s: https://github.com/ByteDream/crunchyroll-go/releases/tag/v%s", releaseVersion, Version, releaseVersion) + + if updateInstallFlag { + if runtime.GOARCH != "amd64" { + return fmt.Errorf("invalid architecture found (%s), only amd64 is currently supported for automatic updating. "+ + "You have to update manually (https://github.com/ByteDream/crunchyroll-go)", runtime.GOARCH) + } + + var downloadFile string + switch runtime.GOOS { + case "linux": + yayCommand := exec.Command("pacman -Q crunchyroll-go") + if yayCommand.Run() == nil && yayCommand.ProcessState.Success() { + out.Info("crunchyroll-go was probably installed via an Arch Linux AUR helper (like yay). Updating via this AUR helper is recommended") + return nil + } + downloadFile = fmt.Sprintf("crunchy-v%s_linux", releaseVersion) + case "darwin": + downloadFile = fmt.Sprintf("crunchy-v%s_darwin", releaseVersion) + case "windows": + downloadFile = fmt.Sprintf("crunchy-v%s_windows.exe", releaseVersion) + default: + return fmt.Errorf("invalid operation system found (%s), only linux, windows and darwin / macos are currently supported. "+ + "You have to update manually (https://github.com/ByteDream/crunchyroll-go)", runtime.GOOS) + } + + out.SetProgress("Updating executable %s", os.Args[0]) + + perms, err := os.Stat(os.Args[0]) + if err != nil { + return err + } + os.Remove(os.Args[0]) + executeFile, err := os.OpenFile(os.Args[0], os.O_CREATE|os.O_WRONLY, perms.Mode()) + if err != nil { + return err + } + defer executeFile.Close() + + resp, err := client.Get(fmt.Sprintf("https://github.com/ByteDream/crunchyroll-go/releases/download/v%s/%s", releaseVersion, downloadFile)) + if err != nil { + return err + } + defer resp.Body.Close() + + if _, err = io.Copy(executeFile, resp.Body); err != nil { + return err + } + + out.StopProgress("Updated executable %s", os.Args[0]) + } + + return nil +} diff --git a/crunchyroll-go.1 b/crunchyroll-go.1 index 558aa23..576c291 100644 --- a/crunchyroll-go.1 +++ b/crunchyroll-go.1 @@ -13,6 +13,8 @@ crunchyroll-go login [\fB--persistent\fR] [\fB--session-id\fR \fISESSION_ID\fR] crunchyroll-go download [\fB-a\fR \fIAUDIO\fR] [\fB-s\fR \fISUBTITLE\fR] [\fB-d\fR \fIDIRECTORY\fR] [\fB-o\fR \fIOUTPUT\fR] [\fB-r\fR \fIRESOLUTION\fR] [\fB-g\fR \fIGOROUTINES\fR] \fIURLs...\fR .br crunchyroll-go archive [\fB-l\fR \fILANGUAGE\fR] [\fB-d\fR \fIDIRECTORY\fR] [\fB-o\fR \fIOUTPUT\fR] [\fB-m\fR \fIMERGE BEHAVIOR\fR] [\fB-c\fR \fICOMPRESS\fR] [\fB-r\fR \fIRESOLUTION\fR] [\fB-g\fR \fIGOROUTINES\fR] \fIURLs...\fR +.br +crunchyroll-go update [\fB-i\fR \fIINSTALL\fR] .SH DESCRIPTION .TP @@ -141,6 +143,13 @@ The video resolution. Can either be specified via the pixels (e.g. 1920x1080), t \fB-g, --goroutines GOROUTINES\fR Sets the number of parallel downloads for the segments the final video is made of. Default is the number of cores the computer has. +.SH UPDATE COMMAND +Checks if a newer version is available. +.TP + +\fB-i, --install INSTALL\fR +If given, the command tries to update the executable with the newer version (if a newer is available). + .SH URL OPTIONS If you want to download only specific episode of a series, you could either pass every single episode url to the downloader (which is fine for 1 - 3 episodes) or use filtering. It works pretty simple, just put a specific pattern surrounded by square brackets at the end of the url from the anime you want to download. A season and / or episode as well as a range from where to where episodes should be downloaded can be specified. From 608e03bc11925c9bb78ad6a0b4efbf4137a34c6e Mon Sep 17 00:00:00 2001 From: bytedream Date: Wed, 18 May 2022 22:21:49 +0200 Subject: [PATCH 2/2] Add better update output --- cmd/crunchyroll-go/cmd/update.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cmd/crunchyroll-go/cmd/update.go b/cmd/crunchyroll-go/cmd/update.go index 4c7aaad..c8512e6 100644 --- a/cmd/crunchyroll-go/cmd/update.go +++ b/cmd/crunchyroll-go/cmd/update.go @@ -63,10 +63,12 @@ func update() error { return fmt.Errorf("internal version (%s) is not parsable", Version) } + out.Info("Installed version is %s", Version) + var hasUpdate bool for i := 0; i < 3; i++ { if latestRelease[i] < internalVersion[i] { - out.Info("Local version (%s) is newer than version in latest release (%s)", Version, releaseVersion) + out.Info("Local version is newer than version in latest release (%s)", releaseVersion) return nil } else if latestRelease[i] > internalVersion[i] { hasUpdate = true @@ -78,7 +80,7 @@ func update() error { return nil } - out.Info("A new version is available (%s). Installed version is %s: https://github.com/ByteDream/crunchyroll-go/releases/tag/v%s", releaseVersion, Version, releaseVersion) + out.Info("A new version is available (%s): https://github.com/ByteDream/crunchyroll-go/releases/tag/v%s", releaseVersion, releaseVersion) if updateInstallFlag { if runtime.GOARCH != "amd64" {