Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file.
10 changes: 10 additions & 0 deletions api/fixture_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,16 @@ var (
"image_url": nil,
}

trackTrendingScoreBaseRow = map[string]any{
"track_id": nil,
"type": "TRACKS",
"genre": nil,
"version": "pnagD",
"time_range": nil,
"score": nil,
"created_at": time.Now(),
}

connectedWalletsBaseRow = map[string]any{
"id": nil,
"user_id": nil,
Expand Down
2 changes: 2 additions & 0 deletions api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ func NewApiServer(config Config) *ApiServer {
// Tracks
g.Get("/tracks", app.v1Tracks)

g.Get("/tracks/trending", app.v1Trending)

g.Use("/tracks/:trackId", app.requireTrackIdMiddleware)
g.Get("/tracks/:trackId", app.v1Track)
g.Get("/tracks/:trackId/reposts", app.v1TracksReposts)
Expand Down
1 change: 1 addition & 0 deletions api/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ func TestMain(m *testing.M) {
insertFixtures("follows", followBaseRow, "testdata/follow_fixtures.csv")
insertFixtures("reposts", repostBaseRow, "testdata/repost_fixtures.csv")
insertFixtures("developer_apps", developerAppBaseRow, "testdata/developer_app_fixtures.csv")
insertFixtures("track_trending_scores", trackTrendingScoreBaseRow, "testdata/track_trending_scores_fixtures.csv")
insertFixtures("associated_wallets", connectedWalletsBaseRow, "testdata/connected_wallets_fixtures.csv")

// index to es / os
Expand Down
13 changes: 7 additions & 6 deletions api/testdata/track_fixtures.csv
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
track_id,owner_id,title,is_unlisted,stream_conditions,download_conditions
200,2,Culca Canyon,f,,
201,2,Turkey Time DEMO,t,,
300,3,Follow Gated Download,f,,"{""follow_user_id"": 3}"
301,3,Pay Gated Download,f,,"{""usdc_purchase"": {""price"": 135, ""splits"": [{""user_id"": 3, ""percentage"": 100.0}]}}"
302,3,Tip Gated Stream,f," {""tip_user_id"": 859175075}",
track_id,genre,owner_id,title,is_unlisted,stream_conditions,download_conditions
200,Electronic,2,Culca Canyon,f,,
201,Alternative,2,Turkey Time DEMO,t,,
202,Alternative,2,Turkey Time (live),f,,
300,Electronic,3,Follow Gated Download,f,,"{""follow_user_id"": 3}"
301,Electronic,3,Pay Gated Download,f,,"{""usdc_purchase"": {""price"": 135, ""splits"": [{""user_id"": 3, ""percentage"": 100.0}]}}"
302,Electronic,3,Tip Gated Stream,f," {""tip_user_id"": 859175075}",
7 changes: 7 additions & 0 deletions api/testdata/track_trending_scores_fixtures.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
track_id,genre,time_range,score
200,Electronic,week,1.0
200,Electronic,allTime,5.0
201,Alternative,week,2.0
202,Alternative,week,2.0
300,Electronic,week,3.0
300,Electronic,allTime,3.0
62 changes: 62 additions & 0 deletions api/v1_trending.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package api

import (
"bridgerton.audius.co/api/dbv1"
"github.com/gofiber/fiber/v2"
"github.com/jackc/pgx/v5"
)

func (app *ApiServer) v1Trending(c *fiber.Ctx) error {
myId := c.Locals("myId")

// SQL query with conditional genre filter
sql := `
SELECT track_trending_scores.track_id
FROM track_trending_scores
LEFT JOIN tracks
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this be a full join?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i dont think so. if there's no scores for a track, we probably don't care about it

ON tracks.track_id = track_trending_scores.track_id
AND tracks.is_delete = false
AND tracks.is_unlisted = false
AND tracks.is_available = true
WHERE type = 'TRACKS'
AND version = 'pnagD'
AND time_range = @timeRange
AND (@genre = '' OR track_trending_scores.genre = @genre)
ORDER BY
score DESC,
track_id DESC
LIMIT @limit
OFFSET @offset
`

args := pgx.NamedArgs{}
args["limit"] = c.Query("limit", "100")
args["offset"] = c.Query("offset", "0")
args["timeRange"] = c.Query("timeRange", "week")
args["genre"] = c.Query("genre", "")

rows, err := app.pool.Query(c.Context(), sql, args)
if err != nil {
return err
}

type trackTrendingRow struct {
TrackId int32 `json:"track_id"`
}

trackIds, err := pgx.CollectRows(rows, pgx.RowTo[int32])
if err != nil {
return err
}

tracks, err := app.queries.FullTracks(c.Context(), dbv1.GetTracksParams{
Ids: trackIds,
MyID: myId,
})

if err != nil {
return err
}

return v1TracksResponse(c, tracks)
}
54 changes: 54 additions & 0 deletions api/v1_trending_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package api

import (
"testing"

"bridgerton.audius.co/api/dbv1"
"bridgerton.audius.co/trashid"
"github.com/stretchr/testify/assert"
)

func TestGetTrending(t *testing.T) {
var resp struct {
Data []dbv1.FullTrack
}
status, _ := testGet(t, "/v1/tracks/trending", &resp)
assert.Equal(t, 200, status)

assert.Equal(t, trashid.MustEncodeHashID(300), resp.Data[0].ID)
assert.Equal(t, "Electronic", resp.Data[0].Genre.String)

assert.Equal(t, trashid.MustEncodeHashID(202), resp.Data[1].ID)
assert.Equal(t, "Alternative", resp.Data[1].Genre.String)

assert.Equal(t, trashid.MustEncodeHashID(200), resp.Data[2].ID)
assert.Equal(t, "Electronic", resp.Data[2].Genre.String)
}

func TestGetTrendingElectronic(t *testing.T) {
var resp struct {
Data []dbv1.FullTrack
}
status, _ := testGet(t, "/v1/tracks/trending?genre=Electronic", &resp)
assert.Equal(t, 200, status)

assert.Equal(t, "eYRWn", resp.Data[0].ID)
assert.Equal(t, "Electronic", resp.Data[0].Genre.String)

assert.Equal(t, "eYJyn", resp.Data[1].ID)
assert.Equal(t, "Electronic", resp.Data[1].Genre.String)
}

func TestGetTrendingAllTime(t *testing.T) {
var resp struct {
Data []dbv1.FullTrack
}
status, _ := testGet(t, "/v1/tracks/trending?timeRange=allTime", &resp)
assert.Equal(t, 200, status)

assert.Equal(t, "eYJyn", resp.Data[0].ID)
assert.Equal(t, "Electronic", resp.Data[0].Genre.String)

assert.Equal(t, "eYRWn", resp.Data[1].ID)
assert.Equal(t, "Electronic", resp.Data[1].Genre.String)
}
Loading