paginate large playlists

This commit is contained in:
Laptop
2024-09-15 13:10:11 +03:00
parent 41e7a70b94
commit 9bfd873c9c
8 changed files with 73 additions and 24 deletions

View File

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

View File

@@ -98,4 +98,6 @@ type Playlist struct {
Album bool `json:"is_album"`
Author User `json:"user"`
Tracks []Track `json:"tracks"`
MissingTracks string `json:"-"`
}

13
main.go
View File

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

View File

@@ -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) {
}
}
</div>
if len(p.MissingTracks) != 0 {
<a href={templ.URL("?pagination="+url.QueryEscape(p.MissingTracks))} rel="noreferrer">more tracks</a>
}
<div>
if p.TagList != "" {

View File

@@ -14,5 +14,5 @@ templ SearchPlaylists(p *sc.Paginated[sc.Playlist]) {
<h1><a href={ templ.URL("/" + playlist.Author.Permalink + "/sets/" + playlist.Permalink) }>{ playlist.Title }</a></h1>
}
<a href={ templ.URL("?type=playlists&pagination=" + url.QueryEscape(strings.Split(p.Next, "/playlists")[1])) }>more playlists</a>
<a href={ templ.URL("?type=playlists&pagination=" + url.QueryEscape(strings.Split(p.Next, "/playlists")[1])) } rel="noreferrer">more playlists</a>
}

View File

@@ -13,5 +13,5 @@ templ SearchTracks(p *sc.Paginated[sc.Track]) {
<h1><a href={ templ.URL("/" + track.Author.Permalink + "/" + track.Permalink) }>{ track.Title }</a></h1>
}
<a href={ templ.URL("?type=tracks&pagination=" + url.QueryEscape(strings.Split(p.Next, "/tracks")[1])) }>more tracks</a>
<a href={ templ.URL("?type=tracks&pagination=" + url.QueryEscape(strings.Split(p.Next, "/tracks")[1])) } rel="noreferrer">more tracks</a>
}

View File

@@ -13,5 +13,5 @@ templ SearchUsers(p *sc.Paginated[sc.User]) {
<h1><a href={ templ.URL("/" + user.Permalink) }>{ user.Username }</a></h1>
}
<a href={ templ.URL("?type=users&pagination=" + url.QueryEscape(strings.Split(p.Next, "/users")[1])) }>more users</a>
<a href={ templ.URL("?type=users&pagination=" + url.QueryEscape(strings.Split(p.Next, "/users")[1])) } rel="noreferrer">more users</a>
}

View File

@@ -45,7 +45,7 @@ templ User(u sc.User, p *sc.Paginated[sc.Track]) {
</div>
}
</div>
<a href={ templ.URL("?pagination=" + url.QueryEscape(strings.Split(p.Next, "/tracks")[1])) }>more tracks</a>
<a href={ templ.URL("?pagination=" + url.QueryEscape(strings.Split(p.Next, "/tracks")[1])) } rel="noreferrer">more tracks</a>
} else {
<h1>no more tracks</h1>
}