Skip to content

Commit

Permalink
Adding update-yt-dlp cmd to setup/update yt-dlp tools
Browse files Browse the repository at this point in the history
  • Loading branch information
boggydigital committed Dec 10, 2024
1 parent f646148 commit 881fbdf
Show file tree
Hide file tree
Showing 5 changed files with 234 additions and 0 deletions.
3 changes: 3 additions & 0 deletions cli-commands.txt
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,7 @@ sync

test-dependencies

update-yt-dlp
force

version
227 changes: 227 additions & 0 deletions cli/update_yt_dlp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
package cli

import (
"encoding/json"
"errors"
"github.com/arelate/southern_light/github_integration"
"github.com/boggydigital/dolo"
"github.com/boggydigital/nod"
"github.com/boggydigital/pathways"
"github.com/boggydigital/yet/paths"
"io"
"net/http"
"net/url"
"os"
"path/filepath"
"runtime"
"strings"
)

const (
ytDlpOwnerRepo = "yt-dlp/yt-dlp"
ytDlpLinuxAsset = "yt-dlp_linux_aarch64"
ytDlpMacOsAsset = "yt-dlp_macos"
relYtDlpPluginsDir = ".yt-dlp/plugins"
)

const (
ytDlpGetPotOwnerRepo = "coletdjnz/yt-dlp-get-pot"
ytDlpGetPotAsset = "yt-dlp-get-pot.zip"
)

const (
ytDlpPotProviderOwnerRepo = "Brainicism/bgutil-ytdlp-pot-provider"
ytDlpPotProviderAsset = "bgutil-ytdlp-pot-provider.zip"
)

func UpdateYtDlpHandler(u *url.URL) error {

force := u.Query().Has("force")

return UpdateYtDlp(force)
}

func UpdateYtDlp(force bool) error {

uyda := nod.Begin("updating yt-dlp and plugins...")
defer uyda.EndWithResult("done")

ytDlpDir, err := pathways.GetAbsDir(paths.YtDlp)
if err != nil {
return uyda.EndWithError(err)
}

userHomeDir, err := os.UserHomeDir()
if err != nil {
return uyda.EndWithError(err)
}

ytDlpPluginsDir := filepath.Join(userHomeDir, relYtDlpPluginsDir)

dc := dolo.DefaultClient

// update yt-dlp

latestYtDlpRelease, err := getLatestGitHubRelease(ytDlpOwnerRepo)
if err != nil {
return uyda.EndWithError(err)
}

var ytDlpAsset string
switch runtime.GOOS {
case "darwin":
ytDlpAsset = ytDlpMacOsAsset
case "linux":
ytDlpAsset = ytDlpLinuxAsset
default:
return uyda.EndWithError(errors.New("yet only supports macOS and Linux"))
}

if err := downloadAsset(ytDlpDir, latestYtDlpRelease, ytDlpAsset, dc, force); err != nil {
return uyda.EndWithError(err)
}

// update yt-dlp-get-pot

latestYtDlpGetPotRelease, err := getLatestGitHubRelease(ytDlpGetPotOwnerRepo)
if err != nil {
return uyda.EndWithError(err)
}

if err := downloadAsset(ytDlpDir, latestYtDlpGetPotRelease, ytDlpGetPotAsset, dc, force); err != nil {
return uyda.EndWithError(err)
}

if err := copyYtDlpPlugin(ytDlpDir, ytDlpPluginsDir, ytDlpGetPotAsset, force); err != nil {
return uyda.EndWithError(err)
}

// update bgutil-ytdlp-pot-provider

latestYtDlpPotProviderRelease, err := getLatestGitHubRelease(ytDlpPotProviderOwnerRepo)
if err != nil {
return uyda.EndWithError(err)
}

if err := downloadAsset(ytDlpDir, latestYtDlpPotProviderRelease, ytDlpPotProviderAsset, dc, force); err != nil {
return uyda.EndWithError(err)
}

if err := copyYtDlpPlugin(ytDlpDir, ytDlpPluginsDir, ytDlpPotProviderAsset, force); err != nil {
return uyda.EndWithError(err)
}

return nil
}

func getLatestGitHubRelease(ownerRepo string) (*github_integration.GitHubRelease, error) {

gra := nod.Begin(" getting the latest GitHub release for %s...", ownerRepo)
defer gra.EndWithResult("done")

owner, repo, ok := strings.Cut(ownerRepo, "/")
if !ok {
return nil, gra.EndWithError(errors.New("invalid owner/repo " + ownerRepo))
}

ytDlpReleasesUrl := github_integration.ReleasesUrl(owner, repo)

resp, err := http.Get(ytDlpReleasesUrl.String())
if err != nil {
return nil, gra.EndWithError(err)
}
defer resp.Body.Close()

if resp.StatusCode < 200 || resp.StatusCode > 299 {
return nil, gra.EndWithError(errors.New(resp.Status))
}

var releases []github_integration.GitHubRelease
if err := json.NewDecoder(resp.Body).Decode(&releases); err != nil {
return nil, gra.EndWithError(err)
}

if len(releases) > 0 {
latestRelease := &releases[0]
gra.EndWithResult("found %s", latestRelease.Name)
return latestRelease, nil
}

return nil, gra.EndWithError(errors.New("latest release not found for " + ownerRepo))
}

func downloadAsset(dstDir string, release *github_integration.GitHubRelease, assetName string, dc *dolo.Client, force bool) error {

daa := nod.NewProgress(" downloading %s...", assetName)
defer daa.EndWithResult("done")

dstAssetFilename := filepath.Join(dstDir, assetName)
if _, err := os.Stat(dstAssetFilename); err == nil && !force {
daa.EndWithResult("already exists")
return nil
}

var desiredAsset *github_integration.GitHubAsset

for _, asset := range release.Assets {
if asset.Name == assetName {
desiredAsset = &asset
break
}
}

if desiredAsset == nil {
return daa.EndWithError(errors.New("cannot locate asset in the provided release"))
}

assetUrl, err := url.Parse(desiredAsset.BrowserDownloadUrl)
if err != nil {
return daa.EndWithError(err)
}

return dc.Download(assetUrl, force, daa, dstDir)
}

func copyYtDlpPlugin(srcDir, dstDir, pluginFilename string, force bool) error {

cpa := nod.Begin(" copying yt-dlp plugin %s...", pluginFilename)
defer cpa.EndWithResult("done")

if _, err := os.Stat(dstDir); os.IsNotExist(err) {
if err := os.MkdirAll(dstDir, 0755); err != nil {
return cpa.EndWithError(err)
}
}

dstFilename := filepath.Join(dstDir, pluginFilename)

if _, err := os.Stat(dstFilename); err == nil {
if force {
if err := os.Remove(dstFilename); err != nil {
return cpa.EndWithError(err)
}
} else {
cpa.EndWithResult("already exists")
return nil
}
}

srcFilename := filepath.Join(srcDir, pluginFilename)
srcFile, err := os.Open(srcFilename)
if err != nil {
return cpa.EndWithError(err)
}
defer srcFile.Close()

dstFile, err := os.Create(dstFilename)
if err != nil {
return cpa.EndWithError(err)
}
defer dstFile.Close()

if _, err := io.Copy(dstFile, srcFile); err != nil {
return cpa.EndWithError(err)
}

return nil
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ require (
)

require (
github.com/arelate/southern_light v0.1.52 // indirect
github.com/boggydigital/match_node v0.1.17 // indirect
github.com/boggydigital/wits v0.2.3 // indirect
golang.org/x/net v0.32.0 // indirect
Expand Down
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ func main() {
"serve": cli.ServeHandler,
"sync": cli.SyncHandler,
"test-dependencies": cli.TestDependenciesHandler,
"update-yt-dlp": cli.UpdateYtDlpHandler,
"version": cli.VersionHandler,
})

Expand Down
2 changes: 2 additions & 0 deletions paths/dirs.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const (
Posters pathways.AbsDir = "posters"
Captions pathways.AbsDir = "captions"
Players pathways.AbsDir = "players"
YtDlp pathways.AbsDir = "yt-dlp"
)

var AllAbsDirs = []pathways.AbsDir{
Expand All @@ -24,4 +25,5 @@ var AllAbsDirs = []pathways.AbsDir{
Posters,
Captions,
Players,
YtDlp,
}

0 comments on commit 881fbdf

Please sign in to comment.