From 1249238d3abd35c7aef3183b3a59403db1a65fa4 Mon Sep 17 00:00:00 2001 From: Philipp Wolfer Date: Sun, 26 Nov 2023 12:22:11 +0100 Subject: [PATCH] lastfm: loves export --- internal/backends/lastfm/lastfm.go | 80 +++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/internal/backends/lastfm/lastfm.go b/internal/backends/lastfm/lastfm.go index 0b8c957..f215654 100644 --- a/internal/backends/lastfm/lastfm.go +++ b/internal/backends/lastfm/lastfm.go @@ -17,6 +17,9 @@ package lastfm import ( "net/url" + "sort" + "strconv" + "time" "github.com/shkh/lastfm-go/lastfm" "github.com/spf13/viper" @@ -25,8 +28,11 @@ import ( "golang.org/x/oauth2" ) +const MaxItemsPerGet = 50 + type LastfmApiBackend struct { - client *lastfm.Api + client *lastfm.Api + username string } func (b *LastfmApiBackend) Name() string { return "lastfm" } @@ -35,6 +41,7 @@ func (b *LastfmApiBackend) FromConfig(config *viper.Viper) models.Backend { clientId := config.GetString("client-id") clientSecret := config.GetString("client-secret") b.client = lastfm.New(clientId, clientSecret) + b.username = config.GetString("username") return b } @@ -52,3 +59,74 @@ func (b *LastfmApiBackend) OAuth2Setup(token oauth2.TokenSource) error { } return b.client.LoginWithToken(t.AccessToken) } + +func (b *LastfmApiBackend) ExportLoves(oldestTimestamp time.Time, results chan models.LovesResult, progress chan models.Progress) { + // Choose a high offset, we attempt to search the loves backwards starting + // at the oldest one. + page := 1 + perPage := MaxItemsPerGet + + defer close(results) + + loves := make(models.LovesList, 0, 2*MaxItemsPerGet) + p := models.Progress{Total: int64(perPage)} + var totalCount int + +out: + for { + result, err := b.client.User.GetLovedTracks(lastfm.P{ + "user": b.username, + "limit": MaxItemsPerGet, + "page": page, + }) + if err != nil { + progress <- p.Complete() + results <- models.LovesResult{Error: err} + return + } + + p.Total = int64(result.Total) + count := len(result.Tracks) + if count == 0 { + break out + } + + for _, track := range result.Tracks { + timestamp, err := strconv.ParseInt(track.Date.Uts, 10, 64) + if err != nil { + progress <- p.Complete() + results <- models.LovesResult{Error: err} + return + } + if timestamp > oldestTimestamp.Unix() { + totalCount += 1 + love := models.Love{ + Created: time.Unix(timestamp, 0), + UserName: result.User, + RecordingMbid: models.MBID(track.Mbid), + Track: models.Track{ + TrackName: track.Name, + ArtistNames: []string{track.Artist.Name}, + RecordingMbid: models.MBID(track.Mbid), + ArtistMbids: []models.MBID{models.MBID(track.Artist.Mbid)}, + AdditionalInfo: models.AdditionalInfo{ + "lastfm_url": track.Url, + }, + }, + } + loves = append(loves, love) + } else { + break out + } + } + + p.Elapsed += int64(count) + progress <- p + + page += 1 + } + + sort.Sort(loves) + results <- models.LovesResult{Loves: loves, Total: totalCount} + progress <- p.Complete() +}