Skip to content

Commit 9cdb29e

Browse files
authored
Add total track downloads (#728)
1 parent 5a50b27 commit 9cdb29e

7 files changed

Lines changed: 140 additions & 1 deletion

api/dbv1/get_user_track_download_count_total.sql.go

Lines changed: 37 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
-- name: GetUserTrackDownloadCountTotal :one
2+
-- Total download count for all tracks (and stems) owned by the user.
3+
-- Each download event is counted once.
4+
SELECT count(*)::bigint AS total_download_count
5+
FROM track_downloads d
6+
WHERE EXISTS (
7+
SELECT 1
8+
FROM tracks t
9+
WHERE t.owner_id = @user_id
10+
AND t.is_current = true
11+
AND t.is_delete = false
12+
AND (
13+
(t.stem_of IS NULL AND d.parent_track_id = t.track_id)
14+
OR (t.stem_of IS NOT NULL
15+
AND (t.stem_of->>'parent_track_id')::int = d.parent_track_id
16+
AND d.track_id = t.track_id)
17+
)
18+
);

api/server.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,7 @@ func NewApiServer(config config.Config) *ApiServer {
422422
g.Get("/users/:userId/tags", app.v1UsersTags)
423423
g.Get("/users/:userId/tracks", app.v1UserTracks)
424424
g.Get("/users/:userId/tracks/count", app.v1UserTracksCount)
425+
g.Get("/users/:userId/tracks/download_count", app.v1UserTracksDownloadCount)
425426
g.Get("/users/:userId/tracks/remixed", app.v1UserTracksRemixed)
426427
g.Get("/users/:userId/albums", app.v1UserAlbums)
427428
g.Get("/users/:userId/playlists", app.v1UserPlaylists)

api/swagger/swagger-v1.yaml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6726,6 +6726,33 @@ paths:
67266726
"500":
67276727
description: Server error
67286728
content: {}
6729+
/users/{id}/tracks/download_count:
6730+
get:
6731+
tags:
6732+
- users
6733+
description: Gets the total download count for all tracks (and stems) owned by the user. Use for dashboard "Downloads" tile.
6734+
operationId: Get User Tracks Download Count
6735+
security:
6736+
- {}
6737+
- OAuth2:
6738+
- read
6739+
parameters:
6740+
- name: id
6741+
in: path
6742+
description: A User ID
6743+
required: true
6744+
schema:
6745+
type: string
6746+
responses:
6747+
"200":
6748+
description: Success
6749+
content:
6750+
application/json:
6751+
schema:
6752+
$ref: "#/components/schemas/user_tracks_download_count_response"
6753+
"500":
6754+
description: Server error
6755+
content: {}
67296756
/users/{id}/tracks/remixed:
67306757
get:
67316758
tags:
@@ -11161,6 +11188,15 @@ components:
1116111188
download_count:
1116211189
type: integer
1116311190
description: Full track + all stems (parent) or stem-only (stem)
11191+
user_tracks_download_count_response:
11192+
type: object
11193+
required:
11194+
- data
11195+
properties:
11196+
data:
11197+
type: integer
11198+
format: int64
11199+
description: Total download count for all tracks (and stems) owned by the user
1116411200
create_user_response:
1116511201
type: object
1116611202
properties:

api/v1_track_download_count_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@ package api
22

33
import (
44
"context"
5+
"fmt"
56
"testing"
67

8+
"api.audius.co/trashid"
9+
710
"github.com/stretchr/testify/assert"
811
"github.com/stretchr/testify/require"
912
"github.com/tidwall/gjson"
@@ -55,3 +58,24 @@ func TestV1TracksDownloadCounts(t *testing.T) {
5558
assert.Equal(t, int64(2), byID["eYJyn"], "eYJyn download_count")
5659
assert.Equal(t, int64(0), byID["eYZmn"], "eYZmn download_count")
5760
}
61+
62+
func TestV1UserTracksDownloadCount(t *testing.T) {
63+
app := testAppWithFixtures(t)
64+
ctx := context.Background()
65+
require.NotNil(t, app.writePool, "test requires write pool")
66+
67+
// Track 200 (eYJyn) is owned by user 2. Insert two download rows.
68+
_, err := app.writePool.Exec(ctx, `
69+
INSERT INTO track_downloads (txhash, blocknumber, parent_track_id, track_id, user_id)
70+
VALUES ('tx-user-total-1', 101, 200, 200, 1), ('tx-user-total-2', 101, 200, 200, 2)
71+
`)
72+
require.NoError(t, err)
73+
74+
user2Hash := trashid.MustEncodeHashID(2)
75+
url := fmt.Sprintf("/v1/full/users/%s/tracks/download_count", user2Hash)
76+
status, body := testGet(t, app, url, nil)
77+
assert.Equal(t, 200, status)
78+
jsonAssert(t, body, map[string]any{
79+
"data": 2,
80+
})
81+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package api
2+
3+
import (
4+
"github.com/gofiber/fiber/v2"
5+
)
6+
7+
// v1UserTracksDownloadCount returns the total download count for all tracks
8+
// (and stems) owned by the user. Use this for dashboard "Downloads" tile
9+
// instead of summing per-track counts client-side.
10+
//
11+
// GET /v1/full/users/:userId/tracks/download_count
12+
func (app *ApiServer) v1UserTracksDownloadCount(c *fiber.Ctx) error {
13+
userId := app.getUserId(c)
14+
15+
total, err := app.queries.GetUserTrackDownloadCountTotal(c.Context(), userId)
16+
if err != nil {
17+
return err
18+
}
19+
20+
return c.JSON(fiber.Map{
21+
"data": total,
22+
})
23+
}

config/config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ func init() {
109109
Cfg.DelegatePrivateKey = "13422b9affd75ff80f94f1ea394e6a6097830cb58cda2d3542f37464ecaee7df"
110110
}
111111
Cfg.AntiAbuseOracles = []string{"http://audius-discovery-provider-1"}
112-
Cfg.ArchiverNodes = []string{"http://audius-discovery-provider-1"}
112+
Cfg.ArchiverNodes = []string{"https://archiver.audius.engineering"}
113113
Cfg.Rewards = core_config.MakeRewards(core_config.DevClaimAuthorities, core_config.DevRewardExtensions)
114114
Cfg.AudiusdURL = "https://node1.oap.devnet"
115115
Cfg.ChainId = "openaudio-devnet"

0 commit comments

Comments
 (0)