diff --git a/internal/backends/deezer/deezer.go b/internal/backends/deezer/deezer.go
index f3e3d37..c38f4e7 100644
--- a/internal/backends/deezer/deezer.go
+++ b/internal/backends/deezer/deezer.go
@@ -78,9 +78,7 @@ func (b *DeezerApiBackend) OAuth2Setup(token oauth2.TokenSource) error {
return nil
}
-func (b *DeezerApiBackend) ExportListens(oldestTimestamp time.Time, results chan models.ListensResult, progress chan models.TransferProgress) {
- ctx := context.TODO()
-
+func (b *DeezerApiBackend) ExportListens(ctx context.Context, oldestTimestamp time.Time, results chan models.ListensResult, progress chan models.TransferProgress) {
// Choose a high offset, we attempt to search the loves backwards starting
// at the oldest one.
offset := math.MaxInt32
@@ -156,9 +154,7 @@ out:
progress <- p
}
-func (b *DeezerApiBackend) ExportLoves(oldestTimestamp time.Time, results chan models.LovesResult, progress chan models.TransferProgress) {
- ctx := context.TODO()
-
+func (b *DeezerApiBackend) ExportLoves(ctx context.Context, oldestTimestamp time.Time, results chan models.LovesResult, progress chan models.TransferProgress) {
// Choose a high offset, we attempt to search the loves backwards starting
// at the oldest one.
offset := math.MaxInt32
diff --git a/internal/backends/export.go b/internal/backends/export.go
index 0deebc6..29ae595 100644
--- a/internal/backends/export.go
+++ b/internal/backends/export.go
@@ -40,7 +40,7 @@ func (p ListensExportProcessor) Process(ctx context.Context, wg *sync.WaitGroup,
wg.Add(1)
defer wg.Done()
defer close(results)
- p.Backend.ExportListens(oldestTimestamp, results, progress)
+ p.Backend.ExportListens(ctx, oldestTimestamp, results, progress)
}
type LovesExportProcessor struct {
@@ -55,5 +55,5 @@ func (p LovesExportProcessor) Process(ctx context.Context, wg *sync.WaitGroup, o
wg.Add(1)
defer wg.Done()
defer close(results)
- p.Backend.ExportLoves(oldestTimestamp, results, progress)
+ p.Backend.ExportLoves(ctx, oldestTimestamp, results, progress)
}
diff --git a/internal/backends/funkwhale/funkwhale.go b/internal/backends/funkwhale/funkwhale.go
index 434716f..d9632a6 100644
--- a/internal/backends/funkwhale/funkwhale.go
+++ b/internal/backends/funkwhale/funkwhale.go
@@ -61,8 +61,7 @@ func (b *FunkwhaleApiBackend) InitConfig(config *config.ServiceConfig) error {
return nil
}
-func (b *FunkwhaleApiBackend) ExportListens(oldestTimestamp time.Time, results chan models.ListensResult, progress chan models.TransferProgress) {
- ctx := context.TODO()
+func (b *FunkwhaleApiBackend) ExportListens(ctx context.Context, oldestTimestamp time.Time, results chan models.ListensResult, progress chan models.TransferProgress) {
page := 1
perPage := MaxItemsPerGet
@@ -119,8 +118,7 @@ out:
results <- models.ListensResult{Items: listens}
}
-func (b *FunkwhaleApiBackend) ExportLoves(oldestTimestamp time.Time, results chan models.LovesResult, progress chan models.TransferProgress) {
- ctx := context.TODO()
+func (b *FunkwhaleApiBackend) ExportLoves(ctx context.Context, oldestTimestamp time.Time, results chan models.LovesResult, progress chan models.TransferProgress) {
page := 1
perPage := MaxItemsPerGet
diff --git a/internal/backends/jspf/jspf.go b/internal/backends/jspf/jspf.go
index 0e200f2..77fed4b 100644
--- a/internal/backends/jspf/jspf.go
+++ b/internal/backends/jspf/jspf.go
@@ -18,6 +18,7 @@ Scotty. If not, see .
package jspf
import (
+ "context"
"errors"
"os"
"sort"
@@ -93,7 +94,7 @@ func (b *JSPFBackend) FinishImport() error {
return b.writeJSPF()
}
-func (b *JSPFBackend) ExportListens(oldestTimestamp time.Time, results chan models.ListensResult, progress chan models.TransferProgress) {
+func (b *JSPFBackend) ExportListens(ctx context.Context, oldestTimestamp time.Time, results chan models.ListensResult, progress chan models.TransferProgress) {
err := b.readJSPF()
p := models.TransferProgress{
Export: &models.Progress{},
@@ -132,7 +133,7 @@ func (b *JSPFBackend) ImportListens(export models.ListensResult, importResult mo
return importResult, nil
}
-func (b *JSPFBackend) ExportLoves(oldestTimestamp time.Time, results chan models.LovesResult, progress chan models.TransferProgress) {
+func (b *JSPFBackend) ExportLoves(ctx context.Context, oldestTimestamp time.Time, results chan models.LovesResult, progress chan models.TransferProgress) {
err := b.readJSPF()
p := models.TransferProgress{
Export: &models.Progress{},
diff --git a/internal/backends/lastfm/lastfm.go b/internal/backends/lastfm/lastfm.go
index d262ada..3de75d1 100644
--- a/internal/backends/lastfm/lastfm.go
+++ b/internal/backends/lastfm/lastfm.go
@@ -16,6 +16,7 @@ Scotty. If not, see .
package lastfm
import (
+ "context"
"fmt"
"net/url"
"sort"
@@ -88,7 +89,7 @@ func (b *LastfmApiBackend) OAuth2Setup(token oauth2.TokenSource) error {
return nil
}
-func (b *LastfmApiBackend) ExportListens(oldestTimestamp time.Time, results chan models.ListensResult, progress chan models.TransferProgress) {
+func (b *LastfmApiBackend) ExportListens(ctx context.Context, oldestTimestamp time.Time, results chan models.ListensResult, progress chan models.TransferProgress) {
page := MaxPage
minTime := oldestTimestamp
perPage := MaxItemsPerGet
@@ -102,6 +103,15 @@ func (b *LastfmApiBackend) ExportListens(oldestTimestamp time.Time, results chan
out:
for page > 0 {
+ select {
+ case <-ctx.Done():
+ results <- models.ListensResult{Error: ctx.Err()}
+ p.Export.Abort()
+ progress <- p
+ return
+ default:
+ }
+
args := lastfm.P{
"user": b.username,
"limit": MaxListensPerGet,
@@ -258,7 +268,7 @@ func (b *LastfmApiBackend) ImportListens(export models.ListensResult, importResu
return importResult, nil
}
-func (b *LastfmApiBackend) ExportLoves(oldestTimestamp time.Time, results chan models.LovesResult, progress chan models.TransferProgress) {
+func (b *LastfmApiBackend) ExportLoves(ctx context.Context, oldestTimestamp time.Time, results chan models.LovesResult, progress chan models.TransferProgress) {
// Choose a high offset, we attempt to search the loves backwards starting
// at the oldest one.
page := 1
@@ -274,6 +284,15 @@ func (b *LastfmApiBackend) ExportLoves(oldestTimestamp time.Time, results chan m
out:
for {
+ select {
+ case <-ctx.Done():
+ results <- models.LovesResult{Error: ctx.Err()}
+ p.Export.Abort()
+ progress <- p
+ return
+ default:
+ }
+
result, err := b.client.User.GetLovedTracks(lastfm.P{
"user": b.username,
"limit": MaxItemsPerGet,
diff --git a/internal/backends/listenbrainz/listenbrainz.go b/internal/backends/listenbrainz/listenbrainz.go
index 9f269a2..ca1c0f0 100644
--- a/internal/backends/listenbrainz/listenbrainz.go
+++ b/internal/backends/listenbrainz/listenbrainz.go
@@ -73,8 +73,7 @@ func (b *ListenBrainzApiBackend) InitConfig(config *config.ServiceConfig) error
func (b *ListenBrainzApiBackend) StartImport() error { return nil }
func (b *ListenBrainzApiBackend) FinishImport() error { return nil }
-func (b *ListenBrainzApiBackend) ExportListens(oldestTimestamp time.Time, results chan models.ListensResult, progress chan models.TransferProgress) {
- ctx := context.TODO()
+func (b *ListenBrainzApiBackend) ExportListens(ctx context.Context, oldestTimestamp time.Time, results chan models.ListensResult, progress chan models.TransferProgress) {
startTime := time.Now()
minTime := oldestTimestamp
if minTime.Unix() < 1 {
@@ -201,8 +200,7 @@ func (b *ListenBrainzApiBackend) ImportListens(export models.ListensResult, impo
return importResult, nil
}
-func (b *ListenBrainzApiBackend) ExportLoves(oldestTimestamp time.Time, results chan models.LovesResult, progress chan models.TransferProgress) {
- ctx := context.TODO()
+func (b *ListenBrainzApiBackend) ExportLoves(ctx context.Context, oldestTimestamp time.Time, results chan models.LovesResult, progress chan models.TransferProgress) {
exportChan := make(chan models.LovesResult)
p := models.TransferProgress{
Export: &models.Progress{},
diff --git a/internal/backends/maloja/maloja.go b/internal/backends/maloja/maloja.go
index 4a4965e..8642924 100644
--- a/internal/backends/maloja/maloja.go
+++ b/internal/backends/maloja/maloja.go
@@ -64,8 +64,7 @@ func (b *MalojaApiBackend) InitConfig(config *config.ServiceConfig) error {
func (b *MalojaApiBackend) StartImport() error { return nil }
func (b *MalojaApiBackend) FinishImport() error { return nil }
-func (b *MalojaApiBackend) ExportListens(oldestTimestamp time.Time, results chan models.ListensResult, progress chan models.TransferProgress) {
- ctx := context.TODO()
+func (b *MalojaApiBackend) ExportListens(ctx context.Context, oldestTimestamp time.Time, results chan models.ListensResult, progress chan models.TransferProgress) {
page := 0
perPage := MaxItemsPerGet
diff --git a/internal/backends/scrobblerlog/scrobblerlog.go b/internal/backends/scrobblerlog/scrobblerlog.go
index 6454b7b..c7eb636 100644
--- a/internal/backends/scrobblerlog/scrobblerlog.go
+++ b/internal/backends/scrobblerlog/scrobblerlog.go
@@ -17,6 +17,7 @@ Scotty. If not, see .
package scrobblerlog
import (
+ "context"
"fmt"
"os"
"sort"
@@ -129,7 +130,7 @@ func (b *ScrobblerLogBackend) FinishImport() error {
return b.file.Close()
}
-func (b *ScrobblerLogBackend) ExportListens(oldestTimestamp time.Time, results chan models.ListensResult, progress chan models.TransferProgress) {
+func (b *ScrobblerLogBackend) ExportListens(ctx context.Context, oldestTimestamp time.Time, results chan models.ListensResult, progress chan models.TransferProgress) {
file, err := os.Open(b.filePath)
p := models.TransferProgress{
Export: &models.Progress{},
diff --git a/internal/backends/spotify/spotify.go b/internal/backends/spotify/spotify.go
index 73434b3..b00ebba 100644
--- a/internal/backends/spotify/spotify.go
+++ b/internal/backends/spotify/spotify.go
@@ -96,8 +96,7 @@ func (b *SpotifyApiBackend) OAuth2Setup(token oauth2.TokenSource) error {
return nil
}
-func (b *SpotifyApiBackend) ExportListens(oldestTimestamp time.Time, results chan models.ListensResult, progress chan models.TransferProgress) {
- ctx := context.TODO()
+func (b *SpotifyApiBackend) ExportListens(ctx context.Context, oldestTimestamp time.Time, results chan models.ListensResult, progress chan models.TransferProgress) {
startTime := time.Now()
minTime := oldestTimestamp
@@ -164,8 +163,7 @@ func (b *SpotifyApiBackend) ExportListens(oldestTimestamp time.Time, results cha
progress <- p
}
-func (b *SpotifyApiBackend) ExportLoves(oldestTimestamp time.Time, results chan models.LovesResult, progress chan models.TransferProgress) {
- ctx := context.TODO()
+func (b *SpotifyApiBackend) ExportLoves(ctx context.Context, oldestTimestamp time.Time, results chan models.LovesResult, progress chan models.TransferProgress) {
// Choose a high offset, we attempt to search the loves backwards starting
// at the oldest one.
offset := math.MaxInt32
diff --git a/internal/backends/spotifyhistory/spotifyhistory.go b/internal/backends/spotifyhistory/spotifyhistory.go
index d5c87bb..9a1ab2b 100644
--- a/internal/backends/spotifyhistory/spotifyhistory.go
+++ b/internal/backends/spotifyhistory/spotifyhistory.go
@@ -18,6 +18,7 @@ Scotty. If not, see .
package spotifyhistory
import (
+ "context"
"os"
"path"
"path/filepath"
@@ -72,7 +73,7 @@ func (b *SpotifyHistoryBackend) InitConfig(config *config.ServiceConfig) error {
return nil
}
-func (b *SpotifyHistoryBackend) ExportListens(oldestTimestamp time.Time, results chan models.ListensResult, progress chan models.TransferProgress) {
+func (b *SpotifyHistoryBackend) ExportListens(ctx context.Context, oldestTimestamp time.Time, results chan models.ListensResult, progress chan models.TransferProgress) {
files, err := filepath.Glob(path.Join(b.dirPath, historyFileGlob))
p := models.TransferProgress{
Export: &models.Progress{},
@@ -89,11 +90,20 @@ func (b *SpotifyHistoryBackend) ExportListens(oldestTimestamp time.Time, results
fileCount := int64(len(files))
p.Export.Total = fileCount
for i, filePath := range files {
- history, err := readHistoryFile(filePath)
- if err != nil {
+ select {
+ case <-ctx.Done():
+ results <- models.ListensResult{Error: ctx.Err()}
p.Export.Abort()
progress <- p
+ return
+ default:
+ }
+
+ history, err := readHistoryFile(filePath)
+ if err != nil {
results <- models.ListensResult{Error: err}
+ p.Export.Abort()
+ progress <- p
return
}
listens := history.AsListenList(ListenListOptions{
diff --git a/internal/backends/subsonic/subsonic.go b/internal/backends/subsonic/subsonic.go
index 2098688..aa1b1e3 100644
--- a/internal/backends/subsonic/subsonic.go
+++ b/internal/backends/subsonic/subsonic.go
@@ -17,6 +17,7 @@ Scotty. If not, see .
package subsonic
import (
+ "context"
"net/http"
"sort"
"time"
@@ -63,7 +64,7 @@ func (b *SubsonicApiBackend) InitConfig(config *config.ServiceConfig) error {
return nil
}
-func (b *SubsonicApiBackend) ExportLoves(oldestTimestamp time.Time, results chan models.LovesResult, progress chan models.TransferProgress) {
+func (b *SubsonicApiBackend) ExportLoves(ctx context.Context, oldestTimestamp time.Time, results chan models.LovesResult, progress chan models.TransferProgress) {
err := b.client.Authenticate(b.password)
p := models.TransferProgress{
Export: &models.Progress{},
diff --git a/internal/models/interfaces.go b/internal/models/interfaces.go
index bb97dac..2b45d18 100644
--- a/internal/models/interfaces.go
+++ b/internal/models/interfaces.go
@@ -17,6 +17,7 @@ Scotty. If not, see .
package models
import (
+ "context"
"time"
// "go.uploadedlobster.com/scotty/internal/auth"
@@ -55,7 +56,7 @@ type ListensExport interface {
// Returns a list of all listens newer then oldestTimestamp.
// The returned list of listens is supposed to be ordered by the
// Listen.ListenedAt timestamp, with the oldest entry first.
- ExportListens(oldestTimestamp time.Time, results chan ListensResult, progress chan TransferProgress)
+ ExportListens(ctx context.Context, oldestTimestamp time.Time, results chan ListensResult, progress chan TransferProgress)
}
// Must be implemented by services supporting the import of listens.
@@ -73,7 +74,7 @@ type LovesExport interface {
// Returns a list of all loves newer then oldestTimestamp.
// The returned list of listens is supposed to be ordered by the
// Love.Created timestamp, with the oldest entry first.
- ExportLoves(oldestTimestamp time.Time, results chan LovesResult, progress chan TransferProgress)
+ ExportLoves(ctx context.Context, oldestTimestamp time.Time, results chan LovesResult, progress chan TransferProgress)
}
// Must be implemented by services supporting the import of loves.