chore: update counts to allow unix timeframe

This commit is contained in:
Gabe Farrell 2025-12-29 16:02:55 -05:00
parent dfe3b5c90d
commit ef27dce5e3
6 changed files with 69 additions and 33 deletions

View file

@ -42,35 +42,35 @@ func StatsHandler(store db.DB) http.HandlerFunc {
l.Debug().Msgf("StatsHandler: Fetching statistics for period '%s'", period) l.Debug().Msgf("StatsHandler: Fetching statistics for period '%s'", period)
listens, err := store.CountListens(r.Context(), period) listens, err := store.CountListens(r.Context(), db.Timeframe{Period: period})
if err != nil { if err != nil {
l.Err(err).Msg("StatsHandler: Failed to fetch listen count") l.Err(err).Msg("StatsHandler: Failed to fetch listen count")
utils.WriteError(w, "failed to get listens: "+err.Error(), http.StatusInternalServerError) utils.WriteError(w, "failed to get listens: "+err.Error(), http.StatusInternalServerError)
return return
} }
tracks, err := store.CountTracks(r.Context(), period) tracks, err := store.CountTracks(r.Context(), db.Timeframe{Period: period})
if err != nil { if err != nil {
l.Err(err).Msg("StatsHandler: Failed to fetch track count") l.Err(err).Msg("StatsHandler: Failed to fetch track count")
utils.WriteError(w, "failed to get tracks: "+err.Error(), http.StatusInternalServerError) utils.WriteError(w, "failed to get tracks: "+err.Error(), http.StatusInternalServerError)
return return
} }
albums, err := store.CountAlbums(r.Context(), period) albums, err := store.CountAlbums(r.Context(), db.Timeframe{Period: period})
if err != nil { if err != nil {
l.Err(err).Msg("StatsHandler: Failed to fetch album count") l.Err(err).Msg("StatsHandler: Failed to fetch album count")
utils.WriteError(w, "failed to get albums: "+err.Error(), http.StatusInternalServerError) utils.WriteError(w, "failed to get albums: "+err.Error(), http.StatusInternalServerError)
return return
} }
artists, err := store.CountArtists(r.Context(), period) artists, err := store.CountArtists(r.Context(), db.Timeframe{Period: period})
if err != nil { if err != nil {
l.Err(err).Msg("StatsHandler: Failed to fetch artist count") l.Err(err).Msg("StatsHandler: Failed to fetch artist count")
utils.WriteError(w, "failed to get artists: "+err.Error(), http.StatusInternalServerError) utils.WriteError(w, "failed to get artists: "+err.Error(), http.StatusInternalServerError)
return return
} }
timeListenedS, err := store.CountTimeListened(r.Context(), period) timeListenedS, err := store.CountTimeListened(r.Context(), db.Timeframe{Period: period})
if err != nil { if err != nil {
l.Err(err).Msg("StatsHandler: Failed to fetch time listened") l.Err(err).Msg("StatsHandler: Failed to fetch time listened")
utils.WriteError(w, "failed to get time listened: "+err.Error(), http.StatusInternalServerError) utils.WriteError(w, "failed to get time listened: "+err.Error(), http.StatusInternalServerError)

View file

@ -326,13 +326,13 @@ func TestImportKoito(t *testing.T) {
_, err = store.GetTrack(ctx, db.GetTrackOpts{Title: "GIRI GIRI", ArtistIDs: []int32{artist.ID}}) _, err = store.GetTrack(ctx, db.GetTrackOpts{Title: "GIRI GIRI", ArtistIDs: []int32{artist.ID}})
require.NoError(t, err) require.NoError(t, err)
count, err := store.CountTracks(ctx, db.PeriodAllTime) count, err := store.CountTracks(ctx, db.Timeframe{Period: db.PeriodAllTime})
require.NoError(t, err) require.NoError(t, err)
assert.EqualValues(t, 4, count) assert.EqualValues(t, 4, count)
count, err = store.CountAlbums(ctx, db.PeriodAllTime) count, err = store.CountAlbums(ctx, db.Timeframe{Period: db.PeriodAllTime})
require.NoError(t, err) require.NoError(t, err)
assert.EqualValues(t, 3, count) assert.EqualValues(t, 3, count)
count, err = store.CountArtists(ctx, db.PeriodAllTime) count, err = store.CountArtists(ctx, db.Timeframe{Period: db.PeriodAllTime})
require.NoError(t, err) require.NoError(t, err)
assert.EqualValues(t, 6, count) assert.EqualValues(t, 6, count)

View file

@ -63,11 +63,11 @@ type DB interface {
DeleteSession(ctx context.Context, sessionId uuid.UUID) error DeleteSession(ctx context.Context, sessionId uuid.UUID) error
DeleteApiKey(ctx context.Context, id int32) error DeleteApiKey(ctx context.Context, id int32) error
// Count // Count
CountListens(ctx context.Context, period Period) (int64, error) CountListens(ctx context.Context, timeframe Timeframe) (int64, error)
CountTracks(ctx context.Context, period Period) (int64, error) CountTracks(ctx context.Context, timeframe Timeframe) (int64, error)
CountAlbums(ctx context.Context, period Period) (int64, error) CountAlbums(ctx context.Context, timeframe Timeframe) (int64, error)
CountArtists(ctx context.Context, period Period) (int64, error) CountArtists(ctx context.Context, timeframe Timeframe) (int64, error)
CountTimeListened(ctx context.Context, period Period) (int64, error) CountTimeListened(ctx context.Context, timeframe Timeframe) (int64, error)
CountTimeListenedToItem(ctx context.Context, opts TimeListenedOpts) (int64, error) CountTimeListenedToItem(ctx context.Context, opts TimeListenedOpts) (int64, error)
CountUsers(ctx context.Context) (int64, error) CountUsers(ctx context.Context) (int64, error)
// Search // Search

View file

@ -6,6 +6,12 @@ import (
// should this be in db package ??? // should this be in db package ???
type Timeframe struct {
Period Period
T1u int64
T2u int64
}
type Period string type Period string
const ( const (

View file

@ -10,9 +10,15 @@ import (
"github.com/gabehf/koito/internal/repository" "github.com/gabehf/koito/internal/repository"
) )
func (p *Psql) CountListens(ctx context.Context, period db.Period) (int64, error) { func (p *Psql) CountListens(ctx context.Context, timeframe db.Timeframe) (int64, error) {
t2 := time.Now() var t1, t2 time.Time
t1 := db.StartTimeFromPeriod(period) if timeframe.T1u == 0 && timeframe.T2u == 0 {
t2 = time.Now()
t1 = db.StartTimeFromPeriod(timeframe.Period)
} else {
t1 = time.Unix(timeframe.T1u, 0)
t2 = time.Unix(timeframe.T2u, 0)
}
count, err := p.q.CountListens(ctx, repository.CountListensParams{ count, err := p.q.CountListens(ctx, repository.CountListensParams{
ListenedAt: t1, ListenedAt: t1,
ListenedAt_2: t2, ListenedAt_2: t2,
@ -23,9 +29,15 @@ func (p *Psql) CountListens(ctx context.Context, period db.Period) (int64, error
return count, nil return count, nil
} }
func (p *Psql) CountTracks(ctx context.Context, period db.Period) (int64, error) { func (p *Psql) CountTracks(ctx context.Context, timeframe db.Timeframe) (int64, error) {
t2 := time.Now() var t1, t2 time.Time
t1 := db.StartTimeFromPeriod(period) if timeframe.T1u == 0 && timeframe.T2u == 0 {
t2 = time.Now()
t1 = db.StartTimeFromPeriod(timeframe.Period)
} else {
t1 = time.Unix(timeframe.T1u, 0)
t2 = time.Unix(timeframe.T2u, 0)
}
count, err := p.q.CountTopTracks(ctx, repository.CountTopTracksParams{ count, err := p.q.CountTopTracks(ctx, repository.CountTopTracksParams{
ListenedAt: t1, ListenedAt: t1,
ListenedAt_2: t2, ListenedAt_2: t2,
@ -36,9 +48,15 @@ func (p *Psql) CountTracks(ctx context.Context, period db.Period) (int64, error)
return count, nil return count, nil
} }
func (p *Psql) CountAlbums(ctx context.Context, period db.Period) (int64, error) { func (p *Psql) CountAlbums(ctx context.Context, timeframe db.Timeframe) (int64, error) {
t2 := time.Now() var t1, t2 time.Time
t1 := db.StartTimeFromPeriod(period) if timeframe.T1u == 0 && timeframe.T2u == 0 {
t2 = time.Now()
t1 = db.StartTimeFromPeriod(timeframe.Period)
} else {
t1 = time.Unix(timeframe.T1u, 0)
t2 = time.Unix(timeframe.T2u, 0)
}
count, err := p.q.CountTopReleases(ctx, repository.CountTopReleasesParams{ count, err := p.q.CountTopReleases(ctx, repository.CountTopReleasesParams{
ListenedAt: t1, ListenedAt: t1,
ListenedAt_2: t2, ListenedAt_2: t2,
@ -49,9 +67,15 @@ func (p *Psql) CountAlbums(ctx context.Context, period db.Period) (int64, error)
return count, nil return count, nil
} }
func (p *Psql) CountArtists(ctx context.Context, period db.Period) (int64, error) { func (p *Psql) CountArtists(ctx context.Context, timeframe db.Timeframe) (int64, error) {
t2 := time.Now() var t1, t2 time.Time
t1 := db.StartTimeFromPeriod(period) if timeframe.T1u == 0 && timeframe.T2u == 0 {
t2 = time.Now()
t1 = db.StartTimeFromPeriod(timeframe.Period)
} else {
t1 = time.Unix(timeframe.T1u, 0)
t2 = time.Unix(timeframe.T2u, 0)
}
count, err := p.q.CountTopArtists(ctx, repository.CountTopArtistsParams{ count, err := p.q.CountTopArtists(ctx, repository.CountTopArtistsParams{
ListenedAt: t1, ListenedAt: t1,
ListenedAt_2: t2, ListenedAt_2: t2,
@ -62,9 +86,15 @@ func (p *Psql) CountArtists(ctx context.Context, period db.Period) (int64, error
return count, nil return count, nil
} }
func (p *Psql) CountTimeListened(ctx context.Context, period db.Period) (int64, error) { func (p *Psql) CountTimeListened(ctx context.Context, timeframe db.Timeframe) (int64, error) {
t2 := time.Now() var t1, t2 time.Time
t1 := db.StartTimeFromPeriod(period) if timeframe.T1u == 0 && timeframe.T2u == 0 {
t2 = time.Now()
t1 = db.StartTimeFromPeriod(timeframe.Period)
} else {
t1 = time.Unix(timeframe.T1u, 0)
t2 = time.Unix(timeframe.T2u, 0)
}
count, err := p.q.CountTimeListened(ctx, repository.CountTimeListenedParams{ count, err := p.q.CountTimeListened(ctx, repository.CountTimeListenedParams{
ListenedAt: t1, ListenedAt: t1,
ListenedAt_2: t2, ListenedAt_2: t2,

View file

@ -15,7 +15,7 @@ func TestCountListens(t *testing.T) {
// Test CountListens // Test CountListens
period := db.PeriodWeek period := db.PeriodWeek
count, err := store.CountListens(ctx, period) count, err := store.CountListens(ctx, db.Timeframe{Period: period})
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, int64(1), count, "expected listens count to match inserted data") assert.Equal(t, int64(1), count, "expected listens count to match inserted data")
@ -28,7 +28,7 @@ func TestCountTracks(t *testing.T) {
// Test CountTracks // Test CountTracks
period := db.PeriodMonth period := db.PeriodMonth
count, err := store.CountTracks(ctx, period) count, err := store.CountTracks(ctx, db.Timeframe{Period: period})
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, int64(2), count, "expected tracks count to match inserted data") assert.Equal(t, int64(2), count, "expected tracks count to match inserted data")
@ -41,7 +41,7 @@ func TestCountAlbums(t *testing.T) {
// Test CountAlbums // Test CountAlbums
period := db.PeriodYear period := db.PeriodYear
count, err := store.CountAlbums(ctx, period) count, err := store.CountAlbums(ctx, db.Timeframe{Period: period})
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, int64(3), count, "expected albums count to match inserted data") assert.Equal(t, int64(3), count, "expected albums count to match inserted data")
@ -54,7 +54,7 @@ func TestCountArtists(t *testing.T) {
// Test CountArtists // Test CountArtists
period := db.PeriodAllTime period := db.PeriodAllTime
count, err := store.CountArtists(ctx, period) count, err := store.CountArtists(ctx, db.Timeframe{Period: period})
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, int64(4), count, "expected artists count to match inserted data") assert.Equal(t, int64(4), count, "expected artists count to match inserted data")
@ -67,7 +67,7 @@ func TestCountTimeListened(t *testing.T) {
// Test CountTimeListened // Test CountTimeListened
period := db.PeriodMonth period := db.PeriodMonth
count, err := store.CountTimeListened(ctx, period) count, err := store.CountTimeListened(ctx, db.Timeframe{Period: period})
require.NoError(t, err) require.NoError(t, err)
// 3 listens in past month, each 100 seconds // 3 listens in past month, each 100 seconds
assert.Equal(t, int64(300), count, "expected total time listened to match inserted data") assert.Equal(t, int64(300), count, "expected total time listened to match inserted data")