Add update command

This commit is contained in:
bytedream 2022-05-13 19:22:17 +02:00
parent 3ee53c0cab
commit 901bbf0706
2 changed files with 143 additions and 0 deletions

View file

@ -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
}

View file

@ -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 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 .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 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 .SH DESCRIPTION
.TP .TP
@ -141,6 +143,13 @@ The video resolution. Can either be specified via the pixels (e.g. 1920x1080), t
\fB-g, --goroutines GOROUTINES\fR \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. 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 .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. 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. 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.