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
90 changes: 56 additions & 34 deletions api/dbv1/full_playlists.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package dbv1

import (
"context"
"fmt"

"bridgerton.audius.co/trashid"
"github.com/jackc/pgx/v5/pgtype"
Expand All @@ -10,12 +11,13 @@ import (
type FullPlaylist struct {
GetPlaylistsRow

ID string `json:"id"`
Artwork *SquareImage `json:"artwork"`
UserID trashid.HashId `json:"user_id"`
User FullUser `json:"user"`
Tracks []FullTrack `json:"tracks"`
Access Access `json:"access"`
ID string `json:"id"`
Artwork *SquareImage `json:"artwork"`
UserID trashid.HashId `json:"user_id"`
User FullUser `json:"user"`
Tracks []FullTrack `json:"tracks"`
Access Access `json:"access"`
Permalink string `json:"permalink"`

FolloweeReposts []*FolloweeRepost `json:"followee_reposts"`
FolloweeFavorites []*FolloweeFavorite `json:"followee_favorites"`
Expand Down Expand Up @@ -89,6 +91,13 @@ func (q *Queries) FullPlaylistsKeyed(ctx context.Context, arg GetPlaylistsParams
streamAccess := q.GetPlaylistAccess(ctx, arg.MyID.(int32), playlist.StreamConditions, &playlist, &user)
downloadAccess := streamAccess

var playlistType string
if playlist.IsAlbum {
playlistType = "album"
} else {
playlistType = "playlist"
}

playlistMap[playlist.PlaylistID] = FullPlaylist{
GetPlaylistsRow: playlist,
ID: id,
Expand All @@ -99,6 +108,7 @@ func (q *Queries) FullPlaylistsKeyed(ctx context.Context, arg GetPlaylistsParams
FolloweeFavorites: fullFolloweeFavorites(playlist.FolloweeFavorites),
FolloweeReposts: fullFolloweeReposts(playlist.FolloweeReposts),
PlaylistContents: fullPlaylistContents,
Permalink: fmt.Sprintf("/%s/%s/%s", user.Handle.String, playlistType, playlist.Slug.String),
AddedTimestamps: fullPlaylistContents,
Access: Access{
Stream: streamAccess,
Expand Down Expand Up @@ -129,20 +139,22 @@ func (q *Queries) FullPlaylists(ctx context.Context, arg GetPlaylistsParams) ([]
}

type MinPlaylist struct {
ID string `json:"id"`
PlaylistName pgtype.Text `json:"playlist_name"`
PlaylistOwnerID int32 `json:"playlist_owner_id"`
PlaylistID int32 `json:"playlist_id"`
Artwork *SquareImage `json:"artwork"`
Description *string `json:"description"`
PlaylistContents interface{} `json:"playlist_contents"`
IsAlbum bool `json:"is_album"`
IsPrivate bool `json:"is_private"`
FavoriteCount int32 `json:"favorite_count"`
RepostCount int32 `json:"repost_count"`
UserID trashid.HashId `json:"user_id"`
User MinUser `json:"user"`
Tracks []MinTrack `json:"tracks"`
ID string `json:"id"`
PlaylistName pgtype.Text `json:"playlist_name"`
Artwork *SquareImage `json:"artwork"`
Access Access `json:"access"`
Description string `json:"description"`
IsImageAutogenerated bool `json:"is_image_autogenerated"`
Upc string `json:"upc"`
DdexApp string `json:"ddex_app"`
PlaylistContents interface{} `json:"playlist_contents"`
TrackCount int32 `json:"track_count"`
TotalPlayCount int64 `json:"total_play_count"`
IsAlbum bool `json:"is_album"`
FavoriteCount int32 `json:"favorite_count"`
RepostCount int32 `json:"repost_count"`
User MinUser `json:"user"`
Permalink string `json:"permalink"`
}

func ToMinPlaylist(fullPlaylist FullPlaylist) MinPlaylist {
Expand All @@ -152,20 +164,30 @@ func ToMinPlaylist(fullPlaylist FullPlaylist) MinPlaylist {
}

return MinPlaylist{
ID: fullPlaylist.ID,
PlaylistName: fullPlaylist.PlaylistName,
PlaylistOwnerID: fullPlaylist.PlaylistOwnerID,
PlaylistID: fullPlaylist.PlaylistID,
Artwork: fullPlaylist.Artwork,
PlaylistContents: fullPlaylist.PlaylistContents,
Description: nil,
IsAlbum: false,
IsPrivate: false,
FavoriteCount: 0,
RepostCount: 0,
UserID: fullPlaylist.UserID,
User: ToMinUser(fullPlaylist.User),
Tracks: minTracks,
ID: fullPlaylist.ID,
PlaylistName: fullPlaylist.PlaylistName,
Artwork: fullPlaylist.Artwork,
Access: fullPlaylist.Access,
Upc: fullPlaylist.Upc.String,
DdexApp: fullPlaylist.DdexApp.String,
PlaylistContents: fullPlaylist.PlaylistContents,
Description: fullPlaylist.Description.String,
IsImageAutogenerated: fullPlaylist.IsImageAutogenerated,
IsAlbum: fullPlaylist.IsAlbum,
TrackCount: int32(len(fullPlaylist.Tracks)),
TotalPlayCount: func() int64 {
var total int64
for _, track := range fullPlaylist.Tracks {
if track.PlayCount.Valid {
total += track.PlayCount.Int64
}
}
return total
}(),
FavoriteCount: int32(fullPlaylist.FavoriteCount.Int32),
RepostCount: int32(fullPlaylist.RepostCount.Int32),
User: ToMinUser(fullPlaylist.User),
Permalink: fullPlaylist.Permalink,
}
}

Expand Down
13 changes: 11 additions & 2 deletions api/dbv1/get_playlists.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions api/dbv1/queries/get_playlists.sql
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
SELECT
-- artwork
p.description,
-- permalink
-- id
p.is_album,
p.is_delete,
Expand All @@ -11,6 +10,8 @@ SELECT
p.is_scheduled_release,
p.is_stream_gated,
p.stream_conditions,
p.upc,
p.ddex_app,
-- is_streamable,

coalesce(playlist_image_sizes_multihash, playlist_image_multihash) as artwork,
Expand All @@ -20,6 +21,7 @@ SELECT
p.playlist_id,
p.playlist_owner_id,
p.playlist_contents,
playlist_routes.slug as slug,

p.blocknumber,

Expand Down Expand Up @@ -96,6 +98,7 @@ SELECT

FROM playlists p
JOIN aggregate_playlist using (playlist_id)
LEFT JOIN playlist_routes on p.playlist_id = playlist_routes.playlist_id and playlist_routes.is_current = true
WHERE is_delete = false
and playlist_id = ANY(@ids::int[])
and p.playlist_id = ANY(@ids::int[])
;
6 changes: 4 additions & 2 deletions api/response_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,16 @@ func v1UsersResponse(c *fiber.Ctx, users []dbv1.FullUser) error {
})
}

// Note: playlist response returned an array even though it's a single playlist
// Done for backwards compatibility. Would be nice to get rid of this.
func v1PlaylistResponse(c *fiber.Ctx, playlist dbv1.FullPlaylist) error {
if c.Locals("isFull").(bool) {
return c.JSON(fiber.Map{
"data": playlist,
"data": []dbv1.FullPlaylist{playlist},
})
}
return c.JSON(fiber.Map{
"data": dbv1.ToMinPlaylist(playlist),
"data": []dbv1.MinPlaylist{dbv1.ToMinPlaylist(playlist)},
})
}

Expand Down
16 changes: 8 additions & 8 deletions api/v1_playlist_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,33 @@ import (

func TestGetPlaylist(t *testing.T) {
var playlistResponse struct {
Data dbv1.FullPlaylist
Data []dbv1.FullPlaylist
}

status, body := testGet(t, "/v1/full/playlists/7eP5n", &playlistResponse)
assert.Equal(t, 200, status)

jsonAssert(t, body, map[string]string{
"data.id": "7eP5n",
"data.playlist_name": "First",
"data.0.id": "7eP5n",
"data.0.playlist_name": "First",
})
}

func TestGetPlaylistFollowDownloadAccess(t *testing.T) {
var playlistResponse struct {
Data dbv1.FullPlaylist
Data []dbv1.FullPlaylist
}
// No access
_, body1 := testGet(t, "/v1/full/playlists/ML51L", &playlistResponse)
jsonAssert(t, body1, map[string]string{
"data.playlist_name": "Follow Gated Stream",
"data.access": `{"stream":false,"download":false}`,
"data.0.playlist_name": "Follow Gated Stream",
"data.0.access": `{"stream":false,"download":false}`,
})

// With access
_, body2 := testGet(t, "/v1/full/playlists/ML51L?user_id=ELKzn", &playlistResponse)
jsonAssert(t, body2, map[string]string{
"data.playlist_name": "Follow Gated Stream",
"data.access": `{"stream":true,"download":true}`,
"data.0.playlist_name": "Follow Gated Stream",
"data.0.access": `{"stream":true,"download":true}`,
})
}
Loading