From f1724719ec893e1966e0f9d2334d1b268ec4d326 Mon Sep 17 00:00:00 2001 From: Nonoo Date: Sun, 1 Oct 2023 11:32:22 +0200 Subject: [PATCH] Auto download yt-dlp if not found in path --- main.go | 10 ++++++ params.go | 5 --- run.sh | 1 + vercheck.go | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 107 insertions(+), 8 deletions(-) diff --git a/main.go b/main.go index 3dee3cb..70cd668 100644 --- a/main.go +++ b/main.go @@ -6,6 +6,7 @@ import ( "net" "net/url" "os" + "os/exec" "strings" "time" @@ -13,6 +14,7 @@ import ( "github.com/gotd/td/telegram/message" "github.com/gotd/td/telegram/uploader" "github.com/gotd/td/tg" + "github.com/wader/goutubedl" "golang.org/x/exp/slices" ) @@ -160,6 +162,14 @@ func main() { telegramUploader = uploader.NewUploader(api).WithProgress(dlUploader) telegramSender = message.NewSender(api).WithUploader(telegramUploader) + goutubedl.Path, err = exec.LookPath(goutubedl.Path) + if err != nil { + goutubedl.Path, err = ytdlpDownloadLatest(ctx) + if err != nil { + panic(fmt.Sprint("error: ", err)) + } + } + dlQueue.Init(ctx) dispatcher.OnNewMessage(handleMsg) diff --git a/params.go b/params.go index 3631b16..144b825 100644 --- a/params.go +++ b/params.go @@ -4,7 +4,6 @@ import ( "flag" "fmt" "os" - "os/exec" "strconv" "strings" @@ -79,10 +78,6 @@ func (p *paramsType) Init() error { if goutubedl.Path == "" { goutubedl.Path = "yt-dlp" } - goutubedl.Path, err = exec.LookPath(goutubedl.Path) - if err != nil { - return fmt.Errorf("yt-dlp not found") - } if allowedUserIDs == "" { allowedUserIDs = os.Getenv("ALLOWED_USERIDS") diff --git a/run.sh b/run.sh index d1b4b00..d9ee67b 100755 --- a/run.sh +++ b/run.sh @@ -14,4 +14,5 @@ ALLOWED_USERIDS=$ALLOWED_USERIDS \ ADMIN_USERIDS=$ADMIN_USERIDS \ ALLOWED_GROUPIDS=$ALLOWED_GROUPIDS \ MAX_SIZE=$MAX_SIZE \ +YTDLP_PATH=$YTDLP_PATH \ $bin diff --git a/vercheck.go b/vercheck.go index e9f9dec..e77200e 100644 --- a/vercheck.go +++ b/vercheck.go @@ -2,7 +2,12 @@ package main import ( "context" + "encoding/json" "fmt" + "io" + "net/http" + "os" + "path/filepath" "time" "github.com/google/go-github/v53/github" @@ -11,12 +16,100 @@ import ( const ytdlpVersionCheckTimeout = time.Second * 10 -func ytdlpVersionCheck(ctx context.Context) (latestVersion, currentVersion string, err error) { +func ytdlpGetLatestRelease(ctx context.Context) (release *github.RepositoryRelease, err error) { client := github.NewClient(nil) - release, _, err := client.Repositories.GetLatestRelease(ctx, "yt-dlp", "yt-dlp") + release, _, err = client.Repositories.GetLatestRelease(ctx, "yt-dlp", "yt-dlp") if err != nil { - return "", "", fmt.Errorf("getting latest yt-dlp version: %w", err) + return nil, fmt.Errorf("getting latest yt-dlp version: %w", err) + } + return release, nil +} + +type ytdlpGithubReleaseAsset struct { + Name string `json:"name"` + URL string `json:"browser_download_url"` +} + +func ytdlpGetLatestReleaseURL(ctx context.Context) (url string, err error) { + release, err := ytdlpGetLatestRelease(ctx) + if err != nil { + return "", err + } + + assetsURL := release.GetAssetsURL() + if assetsURL == "" { + return "", fmt.Errorf("downloading latest yt-dlp: no assets url") + } + + resp, err := http.Get(assetsURL) + if err != nil { + return "", fmt.Errorf("downloading latest yt-dlp: %w", err) + } + + body, err := io.ReadAll(resp.Body) + if err != nil { + return "", fmt.Errorf("downloading latest yt-dlp: %w", err) + } + defer resp.Body.Close() + + var assets []ytdlpGithubReleaseAsset + err = json.Unmarshal(body, &assets) + if err != nil { + return "", fmt.Errorf("downloading latest yt-dlp: %w", err) + } + + if len(assets) == 0 { + return "", fmt.Errorf("downloading latest yt-dlp: no release assets") + } + + for _, asset := range assets { + if asset.Name == "yt-dlp" { + url = asset.URL + break + } + } + if url == "" { + return "", fmt.Errorf("downloading latest yt-dlp: no release asset url") + } + return url, nil +} + +func ytdlpDownloadLatest(ctx context.Context) (path string, err error) { + url, err := ytdlpGetLatestReleaseURL(ctx) + if err != nil { + return "", err + } + + resp, err := http.Get(url) + if err != nil { + return "", fmt.Errorf("downloading latest yt-dlp: %w", err) + } + defer resp.Body.Close() + + file, err := os.Create(filepath.Join(os.TempDir(), "yt-dlp")) + if err != nil { + return "", fmt.Errorf("downloading latest yt-dlp: %w", err) + } + defer file.Close() + + _, err = io.Copy(file, resp.Body) + if err != nil { + return "", err + } + + err = os.Chmod(file.Name(), 0755) + if err != nil { + panic(err) + } + + return file.Name(), nil +} + +func ytdlpVersionCheck(ctx context.Context) (latestVersion, currentVersion string, err error) { + release, err := ytdlpGetLatestRelease(ctx) + if err != nil { + return "", "", err } latestVersion = release.GetTagName()