Renamed Backend.FromConfig to Backend.InitConfig and added error handling

This commit is contained in:
Philipp Wolfer 2025-04-29 10:03:28 +02:00
parent aad542850a
commit 0f4b04c641
No known key found for this signature in database
GPG key ID: 8FDF744D4919943B
21 changed files with 60 additions and 48 deletions

View file

@ -123,7 +123,11 @@ func backendWithConfig(config config.ServiceConfig) (models.Backend, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return backend.FromConfig(&config), nil err = backend.InitConfig(&config)
if err != nil {
return nil, err
}
return backend, nil
} }
func ImplementsInterface[T interface{}](backend *models.Backend) (bool, string) { func ImplementsInterface[T interface{}](backend *models.Backend) (bool, string) {

View file

@ -49,10 +49,10 @@ func (b *DeezerApiBackend) Options() []models.BackendOption {
}} }}
} }
func (b *DeezerApiBackend) FromConfig(config *config.ServiceConfig) models.Backend { func (b *DeezerApiBackend) InitConfig(config *config.ServiceConfig) error {
b.clientId = config.GetString("client-id") b.clientId = config.GetString("client-id")
b.clientSecret = config.GetString("client-secret") b.clientSecret = config.GetString("client-secret")
return b return nil
} }
func (b *DeezerApiBackend) OAuth2Strategy(redirectUrl *url.URL) auth.OAuth2Strategy { func (b *DeezerApiBackend) OAuth2Strategy(redirectUrl *url.URL) auth.OAuth2Strategy {

View file

@ -35,13 +35,14 @@ var (
testTrack []byte testTrack []byte
) )
func TestFromConfig(t *testing.T) { func TestInitConfig(t *testing.T) {
c := viper.New() c := viper.New()
c.Set("client-id", "someclientid") c.Set("client-id", "someclientid")
c.Set("client-secret", "someclientsecret") c.Set("client-secret", "someclientsecret")
service := config.NewServiceConfig("test", c) service := config.NewServiceConfig("test", c)
backend := (&deezer.DeezerApiBackend{}).FromConfig(&service) backend := deezer.DeezerApiBackend{}
assert.IsType(t, &deezer.DeezerApiBackend{}, backend) err := backend.InitConfig(&service)
assert.NoError(t, err)
} }
func TestListenAsListen(t *testing.T) { func TestListenAsListen(t *testing.T) {

View file

@ -29,8 +29,8 @@ func (b *DumpBackend) Name() string { return "dump" }
func (b *DumpBackend) Options() []models.BackendOption { return nil } func (b *DumpBackend) Options() []models.BackendOption { return nil }
func (b *DumpBackend) FromConfig(config *config.ServiceConfig) models.Backend { func (b *DumpBackend) InitConfig(config *config.ServiceConfig) error {
return b return nil
} }
func (b *DumpBackend) StartImport() error { return nil } func (b *DumpBackend) StartImport() error { return nil }

View file

@ -51,13 +51,13 @@ func (b *FunkwhaleApiBackend) Options() []models.BackendOption {
}} }}
} }
func (b *FunkwhaleApiBackend) FromConfig(config *config.ServiceConfig) models.Backend { func (b *FunkwhaleApiBackend) InitConfig(config *config.ServiceConfig) error {
b.client = NewClient( b.client = NewClient(
config.GetString("server-url"), config.GetString("server-url"),
config.GetString("token"), config.GetString("token"),
) )
b.username = config.GetString("username") b.username = config.GetString("username")
return b return nil
} }
func (b *FunkwhaleApiBackend) ExportListens(oldestTimestamp time.Time, results chan models.ListensResult, progress chan models.Progress) { func (b *FunkwhaleApiBackend) ExportListens(oldestTimestamp time.Time, results chan models.ListensResult, progress chan models.Progress) {

View file

@ -27,12 +27,13 @@ import (
"go.uploadedlobster.com/scotty/internal/config" "go.uploadedlobster.com/scotty/internal/config"
) )
func TestFromConfig(t *testing.T) { func TestInitConfig(t *testing.T) {
c := viper.New() c := viper.New()
c.Set("token", "thetoken") c.Set("token", "thetoken")
service := config.NewServiceConfig("test", c) service := config.NewServiceConfig("test", c)
backend := (&funkwhale.FunkwhaleApiBackend{}).FromConfig(&service) backend := funkwhale.FunkwhaleApiBackend{}
assert.IsType(t, &funkwhale.FunkwhaleApiBackend{}, backend) err := backend.InitConfig(&service)
assert.NoError(t, err)
} }
func TestFunkwhaleListeningAsListen(t *testing.T) { func TestFunkwhaleListeningAsListen(t *testing.T) {

View file

@ -60,7 +60,7 @@ func (b *JSPFBackend) Options() []models.BackendOption {
}} }}
} }
func (b *JSPFBackend) FromConfig(config *config.ServiceConfig) models.Backend { func (b *JSPFBackend) InitConfig(config *config.ServiceConfig) error {
b.filePath = config.GetString("file-path") b.filePath = config.GetString("file-path")
b.append = config.GetBool("append", true) b.append = config.GetBool("append", true)
b.playlist = jspf.Playlist{ b.playlist = jspf.Playlist{
@ -75,7 +75,7 @@ func (b *JSPFBackend) FromConfig(config *config.ServiceConfig) models.Backend {
}, },
}, },
} }
return b return nil
} }
func (b *JSPFBackend) StartImport() error { func (b *JSPFBackend) StartImport() error {

View file

@ -26,13 +26,14 @@ import (
"go.uploadedlobster.com/scotty/internal/config" "go.uploadedlobster.com/scotty/internal/config"
) )
func TestFromConfig(t *testing.T) { func TestInitConfig(t *testing.T) {
c := viper.New() c := viper.New()
c.Set("file-path", "/foo/bar.jspf") c.Set("file-path", "/foo/bar.jspf")
c.Set("title", "My Playlist") c.Set("title", "My Playlist")
c.Set("username", "outsidecontext") c.Set("username", "outsidecontext")
c.Set("identifier", "http://example.com/playlist1") c.Set("identifier", "http://example.com/playlist1")
service := config.NewServiceConfig("test", c) service := config.NewServiceConfig("test", c)
backend := (&jspf.JSPFBackend{}).FromConfig(&service) backend := jspf.JSPFBackend{}
assert.IsType(t, &jspf.JSPFBackend{}, backend) err := backend.InitConfig(&service)
assert.NoError(t, err)
} }

View file

@ -61,12 +61,12 @@ func (b *LastfmApiBackend) Options() []models.BackendOption {
}} }}
} }
func (b *LastfmApiBackend) FromConfig(config *config.ServiceConfig) models.Backend { func (b *LastfmApiBackend) InitConfig(config *config.ServiceConfig) error {
clientId := config.GetString("client-id") clientId := config.GetString("client-id")
clientSecret := config.GetString("client-secret") clientSecret := config.GetString("client-secret")
b.client = lastfm.New(clientId, clientSecret) b.client = lastfm.New(clientId, clientSecret)
b.username = config.GetString("username") b.username = config.GetString("username")
return b return nil
} }
func (b *LastfmApiBackend) StartImport() error { return nil } func (b *LastfmApiBackend) StartImport() error { return nil }

View file

@ -56,13 +56,13 @@ func (b *ListenBrainzApiBackend) Options() []models.BackendOption {
}} }}
} }
func (b *ListenBrainzApiBackend) FromConfig(config *config.ServiceConfig) models.Backend { func (b *ListenBrainzApiBackend) InitConfig(config *config.ServiceConfig) error {
b.client = NewClient(config.GetString("token")) b.client = NewClient(config.GetString("token"))
b.mbClient = *musicbrainzws2.NewClient(version.AppName, version.AppVersion) b.mbClient = *musicbrainzws2.NewClient(version.AppName, version.AppVersion)
b.client.MaxResults = MaxItemsPerGet b.client.MaxResults = MaxItemsPerGet
b.username = config.GetString("username") b.username = config.GetString("username")
b.checkDuplicates = config.GetBool("check-duplicate-listens", false) b.checkDuplicates = config.GetBool("check-duplicate-listens", false)
return b return nil
} }
func (b *ListenBrainzApiBackend) StartImport() error { return nil } func (b *ListenBrainzApiBackend) StartImport() error { return nil }

View file

@ -28,12 +28,13 @@ import (
"go.uploadedlobster.com/scotty/internal/config" "go.uploadedlobster.com/scotty/internal/config"
) )
func TestFromConfig(t *testing.T) { func TestInitConfig(t *testing.T) {
c := viper.New() c := viper.New()
c.Set("token", "thetoken") c.Set("token", "thetoken")
service := config.NewServiceConfig("test", c) service := config.NewServiceConfig("test", c)
backend := (&listenbrainz.ListenBrainzApiBackend{}).FromConfig(&service) backend := listenbrainz.ListenBrainzApiBackend{}
assert.IsType(t, &listenbrainz.ListenBrainzApiBackend{}, backend) err := backend.InitConfig(&service)
assert.NoError(t, err)
} }
func TestListenBrainzListenAsListen(t *testing.T) { func TestListenBrainzListenAsListen(t *testing.T) {

View file

@ -51,13 +51,13 @@ func (b *MalojaApiBackend) Options() []models.BackendOption {
}} }}
} }
func (b *MalojaApiBackend) FromConfig(config *config.ServiceConfig) models.Backend { func (b *MalojaApiBackend) InitConfig(config *config.ServiceConfig) error {
b.client = NewClient( b.client = NewClient(
config.GetString("server-url"), config.GetString("server-url"),
config.GetString("token"), config.GetString("token"),
) )
b.nofix = config.GetBool("nofix", false) b.nofix = config.GetBool("nofix", false)
return b return nil
} }
func (b *MalojaApiBackend) StartImport() error { return nil } func (b *MalojaApiBackend) StartImport() error { return nil }

View file

@ -26,12 +26,13 @@ import (
"go.uploadedlobster.com/scotty/internal/config" "go.uploadedlobster.com/scotty/internal/config"
) )
func TestFromConfig(t *testing.T) { func TestInitConfig(t *testing.T) {
c := viper.New() c := viper.New()
c.Set("token", "thetoken") c.Set("token", "thetoken")
service := config.NewServiceConfig("test", c) service := config.NewServiceConfig("test", c)
backend := (&maloja.MalojaApiBackend{}).FromConfig(&service) backend := maloja.MalojaApiBackend{}
assert.IsType(t, &maloja.MalojaApiBackend{}, backend) err := backend.InitConfig(&service)
assert.NoError(t, err)
} }
func TestScrobbleAsListen(t *testing.T) { func TestScrobbleAsListen(t *testing.T) {

View file

@ -56,7 +56,7 @@ func (b *ScrobblerLogBackend) Options() []models.BackendOption {
}} }}
} }
func (b *ScrobblerLogBackend) FromConfig(config *config.ServiceConfig) models.Backend { func (b *ScrobblerLogBackend) InitConfig(config *config.ServiceConfig) error {
b.filePath = config.GetString("file-path") b.filePath = config.GetString("file-path")
b.includeSkipped = config.GetBool("include-skipped", false) b.includeSkipped = config.GetBool("include-skipped", false)
b.append = config.GetBool("append", true) b.append = config.GetBool("append", true)
@ -64,7 +64,7 @@ func (b *ScrobblerLogBackend) FromConfig(config *config.ServiceConfig) models.Ba
TZ: scrobblerlog.TZ_UTC, TZ: scrobblerlog.TZ_UTC,
Client: "Rockbox unknown $Revision$", Client: "Rockbox unknown $Revision$",
} }
return b return nil
} }
func (b *ScrobblerLogBackend) StartImport() error { func (b *ScrobblerLogBackend) StartImport() error {

View file

@ -25,10 +25,11 @@ import (
"go.uploadedlobster.com/scotty/internal/config" "go.uploadedlobster.com/scotty/internal/config"
) )
func TestFromConfig(t *testing.T) { func TestInitConfig(t *testing.T) {
c := viper.New() c := viper.New()
c.Set("token", "thetoken") c.Set("token", "thetoken")
service := config.NewServiceConfig("test", c) service := config.NewServiceConfig("test", c)
backend := (&scrobblerlog.ScrobblerLogBackend{}).FromConfig(&service) backend := scrobblerlog.ScrobblerLogBackend{}
assert.IsType(t, &scrobblerlog.ScrobblerLogBackend{}, backend) err := backend.InitConfig(&service)
assert.NoError(t, err)
} }

View file

@ -52,10 +52,10 @@ func (b *SpotifyApiBackend) Options() []models.BackendOption {
}} }}
} }
func (b *SpotifyApiBackend) FromConfig(config *config.ServiceConfig) models.Backend { func (b *SpotifyApiBackend) InitConfig(config *config.ServiceConfig) error {
b.clientId = config.GetString("client-id") b.clientId = config.GetString("client-id")
b.clientSecret = config.GetString("client-secret") b.clientSecret = config.GetString("client-secret")
return b return nil
} }
func (b *SpotifyApiBackend) OAuth2Strategy(redirectUrl *url.URL) auth.OAuth2Strategy { func (b *SpotifyApiBackend) OAuth2Strategy(redirectUrl *url.URL) auth.OAuth2Strategy {

View file

@ -38,13 +38,14 @@ var (
testTrack []byte testTrack []byte
) )
func TestFromConfig(t *testing.T) { func TestInitConfig(t *testing.T) {
c := viper.New() c := viper.New()
c.Set("client-id", "someclientid") c.Set("client-id", "someclientid")
c.Set("client-secret", "someclientsecret") c.Set("client-secret", "someclientsecret")
service := config.NewServiceConfig("test", c) service := config.NewServiceConfig("test", c)
backend := (&spotify.SpotifyApiBackend{}).FromConfig(&service) backend := spotify.SpotifyApiBackend{}
assert.IsType(t, &spotify.SpotifyApiBackend{}, backend) err := backend.InitConfig(&service)
assert.NoError(t, err)
} }
func TestSpotifyListenAsListen(t *testing.T) { func TestSpotifyListenAsListen(t *testing.T) {

View file

@ -64,12 +64,12 @@ func (b *SpotifyHistoryBackend) Options() []models.BackendOption {
}} }}
} }
func (b *SpotifyHistoryBackend) FromConfig(config *config.ServiceConfig) models.Backend { func (b *SpotifyHistoryBackend) InitConfig(config *config.ServiceConfig) error {
b.dirPath = config.GetString("dir-path") b.dirPath = config.GetString("dir-path")
b.ignoreIncognito = config.GetBool("ignore-incognito", true) b.ignoreIncognito = config.GetBool("ignore-incognito", true)
b.ignoreSkipped = config.GetBool("ignore-skipped", false) b.ignoreSkipped = config.GetBool("ignore-skipped", false)
b.skippedMinSeconds = config.GetInt("ignore-min-duration-seconds", 30) b.skippedMinSeconds = config.GetInt("ignore-min-duration-seconds", 30)
return b return nil
} }
func (b *SpotifyHistoryBackend) ExportListens(oldestTimestamp time.Time, results chan models.ListensResult, progress chan models.Progress) { func (b *SpotifyHistoryBackend) ExportListens(oldestTimestamp time.Time, results chan models.ListensResult, progress chan models.Progress) {

View file

@ -52,7 +52,7 @@ func (b *SubsonicApiBackend) Options() []models.BackendOption {
}} }}
} }
func (b *SubsonicApiBackend) FromConfig(config *config.ServiceConfig) models.Backend { func (b *SubsonicApiBackend) InitConfig(config *config.ServiceConfig) error {
b.client = subsonic.Client{ b.client = subsonic.Client{
Client: &http.Client{}, Client: &http.Client{},
BaseUrl: config.GetString("server-url"), BaseUrl: config.GetString("server-url"),
@ -60,7 +60,7 @@ func (b *SubsonicApiBackend) FromConfig(config *config.ServiceConfig) models.Bac
ClientName: version.AppName, ClientName: version.AppName,
} }
b.password = config.GetString("token") b.password = config.GetString("token")
return b return nil
} }
func (b *SubsonicApiBackend) ExportLoves(oldestTimestamp time.Time, results chan models.LovesResult, progress chan models.Progress) { func (b *SubsonicApiBackend) ExportLoves(oldestTimestamp time.Time, results chan models.LovesResult, progress chan models.Progress) {

View file

@ -27,13 +27,14 @@ import (
"go.uploadedlobster.com/scotty/internal/config" "go.uploadedlobster.com/scotty/internal/config"
) )
func TestFromConfig(t *testing.T) { func TestInitConfig(t *testing.T) {
c := viper.New() c := viper.New()
c.Set("server-url", "https://subsonic.example.com") c.Set("server-url", "https://subsonic.example.com")
c.Set("token", "thetoken") c.Set("token", "thetoken")
service := config.NewServiceConfig("test", c) service := config.NewServiceConfig("test", c)
backend := (&subsonic.SubsonicApiBackend{}).FromConfig(&service) backend := subsonic.SubsonicApiBackend{}
assert.IsType(t, &subsonic.SubsonicApiBackend{}, backend) err := backend.InitConfig(&service)
assert.NoError(t, err)
} }
func TestSongToLove(t *testing.T) { func TestSongToLove(t *testing.T) {

View file

@ -30,7 +30,7 @@ type Backend interface {
Name() string Name() string
// Initialize the backend from a config. // Initialize the backend from a config.
FromConfig(config *config.ServiceConfig) Backend InitConfig(config *config.ServiceConfig) error
// Return configuration options // Return configuration options
Options() []BackendOption Options() []BackendOption