Updated all import/export interfaces

This commit is contained in:
Philipp Wolfer 2023-11-15 19:24:12 +01:00
parent 729a3d0ed0
commit ab04eb1123
No known key found for this signature in database
GPG key ID: 8FDF744D4919943B
12 changed files with 247 additions and 167 deletions

View file

@ -23,7 +23,7 @@ package listenbrainz
import (
"fmt"
"slices"
"sort"
"time"
"github.com/spf13/viper"
@ -42,16 +42,21 @@ func (b ListenBrainzApiBackend) FromConfig(config *viper.Viper) models.Backend {
return b
}
func (b ListenBrainzApiBackend) ExportListens(oldestTimestamp time.Time) ([]models.Listen, error) {
func (b ListenBrainzApiBackend) ExportListens(oldestTimestamp time.Time, results chan models.ListensResult) {
maxTime := time.Now()
minTime := time.Unix(0, 0)
listens := make([]models.Listen, 0, 2*MaxItemsPerGet)
defer close(results)
// FIXME: Optimize by fetching the listens in reverse listen time order
listens := make(models.ListensList, 0, 2*MaxItemsPerGet)
out:
for {
result, err := b.client.GetListens(b.username, maxTime, minTime)
if err != nil {
return nil, err
results <- models.ListensResult{Error: err}
return
}
count := len(result.Payload.Listens)
@ -73,19 +78,21 @@ out:
}
}
slices.Reverse(listens)
return listens, nil
sort.Sort(listens)
results <- models.ListensResult{Listens: listens}
}
func (b ListenBrainzApiBackend) ExportLoves(oldestTimestamp time.Time) ([]models.Love, error) {
func (b ListenBrainzApiBackend) ExportLoves(oldestTimestamp time.Time, results chan models.LovesResult) {
offset := 0
loves := make([]models.Love, 0, 2*MaxItemsPerGet)
defer close(results)
loves := make(models.LovesList, 0, 2*MaxItemsPerGet)
out:
for {
result, err := b.client.GetFeedback(b.username, 1, offset)
if err != nil {
return nil, err
results <- models.LovesResult{Error: err}
return
}
count := len(result.Feedback)
@ -105,69 +112,79 @@ out:
offset += MaxItemsPerGet
}
slices.Reverse(loves)
return loves, nil
sort.Sort(loves)
results <- models.LovesResult{Loves: loves}
}
func (b ListenBrainzApiBackend) ImportLoves(loves []models.Love, oldestTimestamp time.Time) (models.ImportResult, error) {
result := models.ImportResult{
TotalCount: len(loves),
ImportCount: 0,
func (b ListenBrainzApiBackend) ImportLoves(results chan models.LovesResult, oldestTimestamp time.Time) (models.ImportResult, error) {
importResult := models.ImportResult{
LastTimestamp: oldestTimestamp,
ImportErrors: make([]string, 0),
}
existingLoves, err := b.ExportLoves(time.Unix(0, 0))
if err != nil {
return result, err
existingLovesChan := make(chan models.LovesResult)
go b.ExportLoves(time.Unix(0, 0), existingLovesChan)
existingLoves := <-existingLovesChan
if existingLoves.Error != nil {
results <- models.LovesResult{Error: existingLoves.Error}
close(results)
}
existingMbids := make(map[string]bool, len(existingLoves))
for _, love := range existingLoves {
existingMbids := make(map[string]bool, len(existingLoves.Loves))
for _, love := range existingLoves.Loves {
existingMbids[string(love.RecordingMbid)] = true
}
for _, love := range loves {
if love.Created.Unix() <= oldestTimestamp.Unix() {
continue
for result := range results {
if result.Error != nil {
return importResult, result.Error
}
recordingMbid := string(love.RecordingMbid)
importResult.TotalCount += len(result.Loves)
if recordingMbid == "" {
lookup, err := b.client.Lookup(love.TrackName, love.ArtistName())
if err == nil {
recordingMbid = lookup.RecordingMbid
for _, love := range result.Loves {
if love.Created.Unix() <= oldestTimestamp.Unix() {
continue
}
}
if recordingMbid != "" {
ok := false
errMsg := ""
if existingMbids[recordingMbid] {
ok = true
} else {
resp, err := b.client.SendFeedback(Feedback{
RecordingMbid: recordingMbid,
Score: 1,
})
ok = err == nil && resp.Status == "ok"
if err != nil {
errMsg = err.Error()
recordingMbid := string(love.RecordingMbid)
if recordingMbid == "" {
lookup, err := b.client.Lookup(love.TrackName, love.ArtistName())
if err == nil {
recordingMbid = lookup.RecordingMbid
}
}
if ok {
result.UpdateTimestamp(love.Created)
result.ImportCount += 1
} else {
msg := fmt.Sprintf("Failed import of \"%s\" by %s: %v",
love.TrackName, love.ArtistName(), errMsg)
result.ImportErrors = append(result.ImportErrors, msg)
if recordingMbid != "" {
ok := false
errMsg := ""
if existingMbids[recordingMbid] {
ok = true
} else {
resp, err := b.client.SendFeedback(Feedback{
RecordingMbid: recordingMbid,
Score: 1,
})
ok = err == nil && resp.Status == "ok"
if err != nil {
errMsg = err.Error()
}
}
if ok {
importResult.UpdateTimestamp(love.Created)
importResult.ImportCount += 1
} else {
msg := fmt.Sprintf("Failed import of \"%s\" by %s: %v",
love.TrackName, love.ArtistName(), errMsg)
importResult.ImportErrors = append(importResult.ImportErrors, msg)
}
}
}
}
return result, nil
return importResult, nil
}
func (lbListen Listen) ToListen() models.Listen {