mirror of
https://git.sr.ht/~phw/scotty
synced 2025-05-04 07:27:05 +02:00
Spotify: Loves export
This commit is contained in:
parent
ed9debc127
commit
2e6319d296
3 changed files with 212 additions and 38 deletions
|
@ -18,6 +18,7 @@ Scotty. If not, see <https://www.gnu.org/licenses/>.
|
|||
package spotify
|
||||
|
||||
import (
|
||||
"math"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
@ -128,51 +129,131 @@ func (b *SpotifyApiBackend) ExportListens(oldestTimestamp time.Time, results cha
|
|||
progress <- p.Complete()
|
||||
}
|
||||
|
||||
func (b *SpotifyApiBackend) 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.
|
||||
offset := math.MaxInt32
|
||||
perPage := MaxItemsPerGet
|
||||
|
||||
defer close(results)
|
||||
defer close(progress)
|
||||
|
||||
p := models.Progress{Total: int64(perPage)}
|
||||
|
||||
out:
|
||||
for {
|
||||
result, err := b.client.UserTracks(offset, perPage)
|
||||
if err != nil {
|
||||
progress <- p.Complete()
|
||||
results <- models.LovesResult{Error: err}
|
||||
return
|
||||
}
|
||||
|
||||
// The offset was higher then the actual number of tracks. Adjust the offset
|
||||
// and continue.
|
||||
if offset >= result.Total {
|
||||
p.Total = int64(result.Total)
|
||||
offset = result.Total - perPage
|
||||
if offset < 0 {
|
||||
offset = 0
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
count := len(result.Items)
|
||||
if count == 0 {
|
||||
break out
|
||||
}
|
||||
|
||||
loves := make(models.LovesList, 0, perPage)
|
||||
for _, track := range result.Items {
|
||||
love := track.ToLove()
|
||||
if love.Created.Unix() > oldestTimestamp.Unix() {
|
||||
p.Elapsed += 1
|
||||
loves = append(loves, love)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
sort.Sort(loves)
|
||||
results <- models.LovesResult{Loves: loves}
|
||||
progress <- p
|
||||
|
||||
if offset <= 0 {
|
||||
// This was the last request, no further results
|
||||
break out
|
||||
}
|
||||
|
||||
offset -= perPage
|
||||
if offset < 0 {
|
||||
offset = 0
|
||||
}
|
||||
}
|
||||
|
||||
progress <- p.Complete()
|
||||
}
|
||||
|
||||
func (l Listen) ToListen() models.Listen {
|
||||
track := l.Track
|
||||
listenedAt, _ := time.Parse(time.RFC3339, l.PlayedAt)
|
||||
listen := models.Listen{
|
||||
Track: models.Track{
|
||||
TrackName: track.Name,
|
||||
ReleaseName: track.Album.Name,
|
||||
ArtistNames: make([]string, 0, len(track.Artists)),
|
||||
Duration: time.Duration(track.DurationMs * int(time.Millisecond)),
|
||||
TrackNumber: track.TrackNumber,
|
||||
Isrc: track.ExternalIds.ISRC,
|
||||
AdditionalInfo: map[string]any{},
|
||||
},
|
||||
}
|
||||
|
||||
listen.ListenedAt, _ = time.Parse(time.RFC3339, l.PlayedAt)
|
||||
|
||||
for _, artist := range track.Artists {
|
||||
listen.Track.ArtistNames = append(listen.Track.ArtistNames, artist.Name)
|
||||
}
|
||||
|
||||
info := listen.AdditionalInfo
|
||||
if !l.Track.IsLocal {
|
||||
info["music_service"] = "spotify.com"
|
||||
}
|
||||
|
||||
if track.ExternalUrls.Spotify != "" {
|
||||
info["origin_url"] = track.ExternalUrls.Spotify
|
||||
info["spotify_id"] = track.ExternalUrls.Spotify
|
||||
}
|
||||
|
||||
if track.Album.ExternalUrls.Spotify != "" {
|
||||
info["spotify_album_id"] = track.Album.ExternalUrls.Spotify
|
||||
}
|
||||
|
||||
if len(track.Artists) > 0 {
|
||||
info["spotify_artist_ids"] = extractArtistIds(track.Artists)
|
||||
}
|
||||
|
||||
if len(track.Album.Artists) > 0 {
|
||||
info["spotify_album_artist_ids"] = extractArtistIds(track.Album.Artists)
|
||||
ListenedAt: listenedAt,
|
||||
Track: l.Track.ToTrack(),
|
||||
}
|
||||
|
||||
return listen
|
||||
}
|
||||
|
||||
func (t SavedTrack) ToLove() models.Love {
|
||||
addedAt, _ := time.Parse(time.RFC3339, t.AddedAt)
|
||||
love := models.Love{
|
||||
Created: addedAt,
|
||||
Track: t.Track.ToTrack(),
|
||||
}
|
||||
|
||||
return love
|
||||
}
|
||||
|
||||
func (t Track) ToTrack() models.Track {
|
||||
track := models.Track{
|
||||
TrackName: t.Name,
|
||||
ReleaseName: t.Album.Name,
|
||||
ArtistNames: make([]string, 0, len(t.Artists)),
|
||||
Duration: time.Duration(t.DurationMs * int(time.Millisecond)),
|
||||
TrackNumber: t.TrackNumber,
|
||||
Isrc: t.ExternalIds.ISRC,
|
||||
AdditionalInfo: map[string]any{},
|
||||
}
|
||||
|
||||
for _, artist := range t.Artists {
|
||||
track.ArtistNames = append(track.ArtistNames, artist.Name)
|
||||
}
|
||||
|
||||
info := track.AdditionalInfo
|
||||
if !t.IsLocal {
|
||||
info["music_service"] = "spotify.com"
|
||||
}
|
||||
|
||||
if t.ExternalUrls.Spotify != "" {
|
||||
info["origin_url"] = t.ExternalUrls.Spotify
|
||||
info["spotify_id"] = t.ExternalUrls.Spotify
|
||||
}
|
||||
|
||||
if t.Album.ExternalUrls.Spotify != "" {
|
||||
info["spotify_album_id"] = t.Album.ExternalUrls.Spotify
|
||||
}
|
||||
|
||||
if len(t.Artists) > 0 {
|
||||
info["spotify_artist_ids"] = extractArtistIds(t.Artists)
|
||||
}
|
||||
|
||||
if len(t.Album.Artists) > 0 {
|
||||
info["spotify_album_artist_ids"] = extractArtistIds(t.Album.Artists)
|
||||
}
|
||||
|
||||
return track
|
||||
}
|
||||
|
||||
func extractArtistIds(artists []Artist) []string {
|
||||
artistIds := make([]string, len(artists))
|
||||
for i, artist := range artists {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue