mirror of
https://github.com/gabehf/Koito.git
synced 2026-03-09 07:28:55 -07:00
feat: Rewind (#116)
* wip * chore: update counts to allow unix timeframe * feat: add db functions for counting new items * wip: endpoint working * wip * wip: initial ui done * add header, adjust ui * add time listened toggle * fix layout, year param * param fixes
This commit is contained in:
parent
c0a8c64243
commit
d4ac96f780
64 changed files with 2252 additions and 1055 deletions
141
internal/summary/summary.go
Normal file
141
internal/summary/summary.go
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
package summary
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/gabehf/koito/internal/db"
|
||||
"github.com/gabehf/koito/internal/models"
|
||||
)
|
||||
|
||||
type Summary struct {
|
||||
Title string `json:"title,omitempty"`
|
||||
TopArtists []*models.Artist `json:"top_artists"` // ListenCount and TimeListened are overriden with stats from timeframe
|
||||
TopAlbums []*models.Album `json:"top_albums"` // ListenCount and TimeListened are overriden with stats from timeframe
|
||||
TopTracks []*models.Track `json:"top_tracks"` // ListenCount and TimeListened are overriden with stats from timeframe
|
||||
MinutesListened int `json:"minutes_listened"`
|
||||
AvgMinutesPerDay int `json:"avg_minutes_listened_per_day"`
|
||||
Plays int `json:"plays"`
|
||||
AvgPlaysPerDay float32 `json:"avg_plays_per_day"`
|
||||
UniqueTracks int `json:"unique_tracks"`
|
||||
UniqueAlbums int `json:"unique_albums"`
|
||||
UniqueArtists int `json:"unique_artists"`
|
||||
NewTracks int `json:"new_tracks"`
|
||||
NewAlbums int `json:"new_albums"`
|
||||
NewArtists int `json:"new_artists"`
|
||||
}
|
||||
|
||||
func GenerateSummary(ctx context.Context, store db.DB, userId int32, timeframe db.Timeframe, title string) (summary *Summary, err error) {
|
||||
// l := logger.FromContext(ctx)
|
||||
|
||||
summary = new(Summary)
|
||||
|
||||
topArtists, err := store.GetTopArtistsPaginated(ctx, db.GetItemsOpts{Page: 1, Limit: 5, From: timeframe.T1u, To: timeframe.T2u, Period: timeframe.Period})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GenerateSummary: %w", err)
|
||||
}
|
||||
summary.TopArtists = topArtists.Items
|
||||
// replace ListenCount and TimeListened with stats from timeframe
|
||||
for i, artist := range summary.TopArtists {
|
||||
timelistened, err := store.CountTimeListenedToItem(ctx, db.TimeListenedOpts{ArtistID: artist.ID, Timeframe: timeframe})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GenerateSummary: %w", err)
|
||||
}
|
||||
listens, err := store.CountListensToItem(ctx, db.TimeListenedOpts{ArtistID: artist.ID, Timeframe: timeframe})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GenerateSummary: %w", err)
|
||||
}
|
||||
summary.TopArtists[i].TimeListened = timelistened
|
||||
summary.TopArtists[i].ListenCount = listens
|
||||
}
|
||||
|
||||
topAlbums, err := store.GetTopAlbumsPaginated(ctx, db.GetItemsOpts{Page: 1, Limit: 5, From: timeframe.T1u, To: timeframe.T2u, Period: timeframe.Period})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GenerateSummary: %w", err)
|
||||
}
|
||||
summary.TopAlbums = topAlbums.Items
|
||||
// replace ListenCount and TimeListened with stats from timeframe
|
||||
for i, album := range summary.TopAlbums {
|
||||
timelistened, err := store.CountTimeListenedToItem(ctx, db.TimeListenedOpts{AlbumID: album.ID, Timeframe: timeframe})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GenerateSummary: %w", err)
|
||||
}
|
||||
listens, err := store.CountListensToItem(ctx, db.TimeListenedOpts{AlbumID: album.ID, Timeframe: timeframe})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GenerateSummary: %w", err)
|
||||
}
|
||||
summary.TopAlbums[i].TimeListened = timelistened
|
||||
summary.TopAlbums[i].ListenCount = listens
|
||||
}
|
||||
|
||||
topTracks, err := store.GetTopTracksPaginated(ctx, db.GetItemsOpts{Page: 1, Limit: 5, From: timeframe.T1u, To: timeframe.T2u, Period: timeframe.Period})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GenerateSummary: %w", err)
|
||||
}
|
||||
summary.TopTracks = topTracks.Items
|
||||
// replace ListenCount and TimeListened with stats from timeframe
|
||||
for i, track := range summary.TopTracks {
|
||||
timelistened, err := store.CountTimeListenedToItem(ctx, db.TimeListenedOpts{TrackID: track.ID, Timeframe: timeframe})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GenerateSummary: %w", err)
|
||||
}
|
||||
listens, err := store.CountListensToItem(ctx, db.TimeListenedOpts{TrackID: track.ID, Timeframe: timeframe})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GenerateSummary: %w", err)
|
||||
}
|
||||
summary.TopTracks[i].TimeListened = timelistened
|
||||
summary.TopTracks[i].ListenCount = listens
|
||||
}
|
||||
|
||||
t1, t2 := db.TimeframeToTimeRange(timeframe)
|
||||
daycount := int(t2.Sub(t1).Hours() / 24)
|
||||
// bandaid
|
||||
if daycount == 0 {
|
||||
daycount = 1
|
||||
}
|
||||
|
||||
tmp, err := store.CountTimeListened(ctx, timeframe)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GenerateSummary: %w", err)
|
||||
}
|
||||
summary.MinutesListened = int(tmp) / 60
|
||||
summary.AvgMinutesPerDay = summary.MinutesListened / daycount
|
||||
tmp, err = store.CountListens(ctx, timeframe)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GenerateSummary: %w", err)
|
||||
}
|
||||
summary.Plays = int(tmp)
|
||||
summary.AvgPlaysPerDay = float32(summary.Plays) / float32(daycount)
|
||||
tmp, err = store.CountTracks(ctx, timeframe)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GenerateSummary: %w", err)
|
||||
}
|
||||
summary.UniqueTracks = int(tmp)
|
||||
tmp, err = store.CountAlbums(ctx, timeframe)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GenerateSummary: %w", err)
|
||||
}
|
||||
summary.UniqueAlbums = int(tmp)
|
||||
tmp, err = store.CountArtists(ctx, timeframe)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GenerateSummary: %w", err)
|
||||
}
|
||||
summary.UniqueArtists = int(tmp)
|
||||
tmp, err = store.CountNewTracks(ctx, timeframe)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GenerateSummary: %w", err)
|
||||
}
|
||||
summary.NewTracks = int(tmp)
|
||||
tmp, err = store.CountNewAlbums(ctx, timeframe)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GenerateSummary: %w", err)
|
||||
}
|
||||
summary.NewAlbums = int(tmp)
|
||||
tmp, err = store.CountNewArtists(ctx, timeframe)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GenerateSummary: %w", err)
|
||||
}
|
||||
summary.NewArtists = int(tmp)
|
||||
|
||||
return summary, nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue