diff --git a/lib/sc/init.go b/lib/sc/init.go index f0eb51c..5b3e154 100644 --- a/lib/sc/init.go +++ b/lib/sc/init.go @@ -468,36 +468,21 @@ func (p Playlist) FormatDescription() string { return desc } -type missingtrack struct { +type MissingTrack struct { ID int64 Index int } -func (p *Playlist) GetMissingTracks() error { +func GetTracks(ids string) ([]Track, error) { cid, err := GetClientID() if err != nil { - return err - } - - missing := []missingtrack{} - for i, track := range p.Tracks { - if track.Title == "" { - missing = append(missing, missingtrack{ID: track.ID, Index: i}) - } - } - - var st string - for i, track := range missing { - st += strconv.FormatInt(track.ID, 10) - if i != len(missing)-1 { - st += "," - } + return nil, err } req := fasthttp.AcquireRequest() defer fasthttp.ReleaseRequest(req) - req.SetRequestURI("https://api-v2.soundcloud.com/tracks?ids=" + st + "&client_id=" + cid) + req.SetRequestURI("https://api-v2.soundcloud.com/tracks?ids=" + ids + "&client_id=" + cid) req.Header.Set("User-Agent", cfg.UserAgent) req.Header.Set("Accept-Encoding", "gzip, deflate, br, zstd") @@ -506,7 +491,7 @@ func (p *Playlist) GetMissingTracks() error { err = DoWithRetry(req, resp) if err != nil { - return err + return nil, err } data, err := resp.BodyUncompressed() @@ -516,6 +501,49 @@ func (p *Playlist) GetMissingTracks() error { var res []Track err = cfg.JSON.Unmarshal(data, &res) + return res, err +} + +func JoinMissingTracks(missing []MissingTrack) (st string) { + for i, track := range missing { + st += strconv.FormatInt(track.ID, 10) + if i != len(missing)-1 { + st += "," + } + } + return +} + +func GetMissingTracks(missing []MissingTrack) (res []Track, next []MissingTrack, err error) { + if len(missing) > 50 { + next = missing[50:] + missing = missing[:50] + } + + res, err = GetTracks(JoinMissingTracks(missing)) + return +} + +func GetNextMissingTracks(raw string) (res []Track, next []string, err error) { + missing := strings.Split(raw, ",") + if len(missing) > 50 { + next = missing[50:] + missing = missing[:50] + } + + res, err = GetTracks(strings.Join(missing, ",")) + return +} + +func (p *Playlist) GetMissingTracks() error { + missing := []MissingTrack{} + for i, track := range p.Tracks { + if track.Title == "" { + missing = append(missing, MissingTrack{ID: track.ID, Index: i}) + } + } + + res, next, err := GetMissingTracks(missing) if err != nil { return err } @@ -528,5 +556,7 @@ func (p *Playlist) GetMissingTracks() error { } } + p.MissingTracks = JoinMissingTracks(next) + return nil } diff --git a/lib/sc/structs.go b/lib/sc/structs.go index c87873f..86d1f76 100644 --- a/lib/sc/structs.go +++ b/lib/sc/structs.go @@ -98,4 +98,6 @@ type Playlist struct { Album bool `json:"is_album"` Author User `json:"user"` Tracks []Track `json:"tracks"` + + MissingTracks string `json:"-"` } diff --git a/main.go b/main.go index 1143c54..d161867 100644 --- a/main.go +++ b/main.go @@ -6,6 +6,7 @@ import ( "fmt" "log" "net/url" + "strings" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/compress" @@ -112,6 +113,18 @@ func main() { return err } + p := c.Query("pagination") + if p != "" { + tracks, next, err := sc.GetNextMissingTracks(p) + if err != nil { + fmt.Printf("error getting %s playlist tracks from %s: %s\n", c.Params("playlist"), c.Params("user"), err) + return err + } + + playlist.Tracks = tracks + playlist.MissingTracks = strings.Join(next, ",") + } + c.Set("Content-Type", "text/html") return templates.Base(playlist.Title+" by "+playlist.Author.Username, templates.Playlist(playlist), templates.PlaylistEmbed(playlist)).Render(context.Background(), c) }) diff --git a/templates/playlist.templ b/templates/playlist.templ index 66abff7..352443c 100644 --- a/templates/playlist.templ +++ b/templates/playlist.templ @@ -4,6 +4,7 @@ import ( "github.com/maid-zone/soundcloak/lib/sc" "strings" "strconv" + "net/url" ) templ PlaylistEmbed(p sc.Playlist) { @@ -29,6 +30,9 @@ templ Playlist(p sc.Playlist) { } } + if len(p.MissingTracks) != 0 { + more tracks + }