mirror of
https://git.sr.ht/~phw/scotty
synced 2025-04-24 21:47:55 +02:00
Move models to separate package
This allows easier reuse and better separation of code without introducing circular dependencies
This commit is contained in:
parent
cdddf89a3e
commit
9d97e324aa
8 changed files with 43 additions and 37 deletions
|
@ -26,6 +26,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
"go.uploadedlobster.com/scotty/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DumpBackend struct{}
|
type DumpBackend struct{}
|
||||||
|
@ -34,7 +35,7 @@ func (b DumpBackend) FromConfig(config *viper.Viper) Backend {
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b DumpBackend) ImportListens(listens []Listen, oldestTimestamp time.Time) (ImportResult, error) {
|
func (b DumpBackend) ImportListens(listens []models.Listen, oldestTimestamp time.Time) (ImportResult, error) {
|
||||||
result := ImportResult{
|
result := ImportResult{
|
||||||
Count: len(listens),
|
Count: len(listens),
|
||||||
LastTimestamp: oldestTimestamp,
|
LastTimestamp: oldestTimestamp,
|
||||||
|
|
|
@ -29,6 +29,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
"go.uploadedlobster.com/scotty/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Backend interface {
|
type Backend interface {
|
||||||
|
@ -36,19 +37,19 @@ type Backend interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ListenExport interface {
|
type ListenExport interface {
|
||||||
ExportListens(oldestTimestamp time.Time) ([]Listen, error)
|
ExportListens(oldestTimestamp time.Time) ([]models.Listen, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type ListenImport interface {
|
type ListenImport interface {
|
||||||
ImportListens(listens []Listen, oldestTimestamp time.Time) (ImportResult, error)
|
ImportListens(listens []models.Listen, oldestTimestamp time.Time) (ImportResult, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type LovesExport interface {
|
type LovesExport interface {
|
||||||
ExportLoves(oldestTimestamp time.Time) ([]Love, error)
|
ExportLoves(oldestTimestamp time.Time) ([]models.Love, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type LovesImport interface {
|
type LovesImport interface {
|
||||||
ExportLoves(loves []Love, oldestTimestamp time.Time) (ImportResult, error)
|
ExportLoves(loves []models.Love, oldestTimestamp time.Time) (ImportResult, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type ImportResult struct {
|
type ImportResult struct {
|
||||||
|
|
|
@ -27,6 +27,7 @@ import (
|
||||||
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"go.uploadedlobster.com/scotty/backends/listenbrainz"
|
"go.uploadedlobster.com/scotty/backends/listenbrainz"
|
||||||
|
"go.uploadedlobster.com/scotty/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ListenBrainzApiBackend struct {
|
type ListenBrainzApiBackend struct {
|
||||||
|
@ -41,10 +42,10 @@ func (b ListenBrainzApiBackend) FromConfig(config *viper.Viper) Backend {
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b ListenBrainzApiBackend) ExportListens(oldestTimestamp time.Time) ([]Listen, error) {
|
func (b ListenBrainzApiBackend) ExportListens(oldestTimestamp time.Time) ([]models.Listen, error) {
|
||||||
maxTime := time.Now()
|
maxTime := time.Now()
|
||||||
minTime := time.Unix(0, 0)
|
minTime := time.Unix(0, 0)
|
||||||
listens := make([]Listen, 0)
|
listens := make([]models.Listen, 0)
|
||||||
|
|
||||||
out:
|
out:
|
||||||
for {
|
for {
|
||||||
|
@ -63,7 +64,7 @@ out:
|
||||||
|
|
||||||
for _, listen := range result.Payload.Listens {
|
for _, listen := range result.Payload.Listens {
|
||||||
if listen.ListenedAt > oldestTimestamp.Unix() {
|
if listen.ListenedAt > oldestTimestamp.Unix() {
|
||||||
listens = append(listens, Listen{}.FromListenBrainz(listen))
|
listens = append(listens, ListenFromListenBrainz(listen))
|
||||||
} else {
|
} else {
|
||||||
// result contains listens older then oldestTimestamp,
|
// result contains listens older then oldestTimestamp,
|
||||||
// we can stop requesting more
|
// we can stop requesting more
|
||||||
|
@ -76,20 +77,20 @@ out:
|
||||||
return listens, nil
|
return listens, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l Listen) FromListenBrainz(lbListen listenbrainz.Listen) Listen {
|
func ListenFromListenBrainz(lbListen listenbrainz.Listen) models.Listen {
|
||||||
track := lbListen.TrackMetadata
|
track := lbListen.TrackMetadata
|
||||||
listen := Listen{
|
listen := models.Listen{
|
||||||
ListenedAt: time.Unix(lbListen.ListenedAt, 0),
|
ListenedAt: time.Unix(lbListen.ListenedAt, 0),
|
||||||
UserName: lbListen.UserName,
|
UserName: lbListen.UserName,
|
||||||
Track: Track{
|
Track: models.Track{
|
||||||
TrackName: track.TrackName,
|
TrackName: track.TrackName,
|
||||||
ReleaseName: track.ReleaseName,
|
ReleaseName: track.ReleaseName,
|
||||||
ArtistNames: []string{track.ArtistName},
|
ArtistNames: []string{track.ArtistName},
|
||||||
Duration: track.Duration(),
|
Duration: track.Duration(),
|
||||||
TrackNumber: track.TrackNumber(),
|
TrackNumber: track.TrackNumber(),
|
||||||
RecordingMbid: MBID(track.RecordingMbid()),
|
RecordingMbid: models.MBID(track.RecordingMbid()),
|
||||||
ReleaseMbid: MBID(track.ReleaseMbid()),
|
ReleaseMbid: models.MBID(track.ReleaseMbid()),
|
||||||
ReleaseGroupMbid: MBID(track.ReleaseGroupMbid()),
|
ReleaseGroupMbid: models.MBID(track.ReleaseGroupMbid()),
|
||||||
Isrc: track.Isrc(),
|
Isrc: track.Isrc(),
|
||||||
AdditionalInfo: track.AdditionalInfo,
|
AdditionalInfo: track.AdditionalInfo,
|
||||||
},
|
},
|
||||||
|
|
|
@ -28,6 +28,7 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"go.uploadedlobster.com/scotty/backends"
|
"go.uploadedlobster.com/scotty/backends"
|
||||||
"go.uploadedlobster.com/scotty/backends/listenbrainz"
|
"go.uploadedlobster.com/scotty/backends/listenbrainz"
|
||||||
|
"go.uploadedlobster.com/scotty/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestListenFromListenBrainz(t *testing.T) {
|
func TestListenFromListenBrainz(t *testing.T) {
|
||||||
|
@ -49,7 +50,7 @@ func TestListenFromListenBrainz(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
listen := backends.Listen{}.FromListenBrainz(lbListen)
|
listen := backends.ListenFromListenBrainz(lbListen)
|
||||||
assert.Equal(t, time.Unix(1699289873, 0), listen.ListenedAt)
|
assert.Equal(t, time.Unix(1699289873, 0), listen.ListenedAt)
|
||||||
assert.Equal(t, lbListen.UserName, listen.UserName)
|
assert.Equal(t, lbListen.UserName, listen.UserName)
|
||||||
assert.Equal(t, time.Duration(528235*time.Millisecond), listen.Duration)
|
assert.Equal(t, time.Duration(528235*time.Millisecond), listen.Duration)
|
||||||
|
@ -58,9 +59,9 @@ func TestListenFromListenBrainz(t *testing.T) {
|
||||||
assert.Equal(t, []string{lbListen.TrackMetadata.ArtistName}, listen.ArtistNames)
|
assert.Equal(t, []string{lbListen.TrackMetadata.ArtistName}, listen.ArtistNames)
|
||||||
assert.Equal(t, 8, listen.TrackNumber)
|
assert.Equal(t, 8, listen.TrackNumber)
|
||||||
assert.Equal(t, 8, listen.TrackNumber)
|
assert.Equal(t, 8, listen.TrackNumber)
|
||||||
assert.Equal(t, backends.MBID("e225fb84-dc9a-419e-adcd-9890f59ec432"), listen.RecordingMbid)
|
assert.Equal(t, models.MBID("e225fb84-dc9a-419e-adcd-9890f59ec432"), listen.RecordingMbid)
|
||||||
assert.Equal(t, backends.MBID("d7f22677-9803-4d21-ba42-081b633a6f68"), listen.ReleaseMbid)
|
assert.Equal(t, models.MBID("d7f22677-9803-4d21-ba42-081b633a6f68"), listen.ReleaseMbid)
|
||||||
assert.Equal(t, backends.MBID("80aca1ee-aa51-41be-9f75-024710d92ff4"), listen.ReleaseGroupMbid)
|
assert.Equal(t, models.MBID("80aca1ee-aa51-41be-9f75-024710d92ff4"), listen.ReleaseGroupMbid)
|
||||||
assert.Equal(t, "DES561720901", listen.Isrc)
|
assert.Equal(t, "DES561720901", listen.Isrc)
|
||||||
assert.Equal(t, lbListen.TrackMetadata.AdditionalInfo["foo"], listen.AdditionalInfo["foo"])
|
assert.Equal(t, lbListen.TrackMetadata.AdditionalInfo["foo"], listen.AdditionalInfo["foo"])
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ import (
|
||||||
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"go.uploadedlobster.com/scotty/backends/maloja"
|
"go.uploadedlobster.com/scotty/backends/maloja"
|
||||||
|
"go.uploadedlobster.com/scotty/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MalojaApiBackend struct {
|
type MalojaApiBackend struct {
|
||||||
|
@ -42,11 +43,11 @@ func (b MalojaApiBackend) FromConfig(config *viper.Viper) Backend {
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b MalojaApiBackend) ExportListens(oldestTimestamp time.Time) ([]Listen, error) {
|
func (b MalojaApiBackend) ExportListens(oldestTimestamp time.Time) ([]models.Listen, error) {
|
||||||
page := 0
|
page := 0
|
||||||
perPage := 1000
|
perPage := 1000
|
||||||
|
|
||||||
listens := make([]Listen, 0)
|
listens := make([]models.Listen, 0)
|
||||||
|
|
||||||
out:
|
out:
|
||||||
for {
|
for {
|
||||||
|
@ -62,7 +63,7 @@ out:
|
||||||
|
|
||||||
for _, listen := range result.Listens {
|
for _, listen := range result.Listens {
|
||||||
if listen.ListenedAt > oldestTimestamp.Unix() {
|
if listen.ListenedAt > oldestTimestamp.Unix() {
|
||||||
listens = append(listens, Listen{}.FromMaloja(listen))
|
listens = append(listens, ListenFromMaloja(listen))
|
||||||
} else {
|
} else {
|
||||||
break out
|
break out
|
||||||
}
|
}
|
||||||
|
@ -75,12 +76,12 @@ out:
|
||||||
return listens, nil
|
return listens, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l Listen) FromMaloja(mlListen maloja.Listen) Listen {
|
func ListenFromMaloja(mlListen maloja.Listen) models.Listen {
|
||||||
track := mlListen.Track
|
track := mlListen.Track
|
||||||
listen := Listen{
|
listen := models.Listen{
|
||||||
ListenedAt: time.Unix(mlListen.ListenedAt, 0),
|
ListenedAt: time.Unix(mlListen.ListenedAt, 0),
|
||||||
PlaybackDuration: time.Duration(mlListen.Duration * int64(time.Second)),
|
PlaybackDuration: time.Duration(mlListen.Duration * int64(time.Second)),
|
||||||
Track: Track{
|
Track: models.Track{
|
||||||
TrackName: track.Title,
|
TrackName: track.Title,
|
||||||
ReleaseName: track.Album.Title,
|
ReleaseName: track.Album.Title,
|
||||||
ArtistNames: track.Artists,
|
ArtistNames: track.Artists,
|
||||||
|
|
|
@ -33,6 +33,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
"go.uploadedlobster.com/scotty/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ScrobblerLogBackend struct {
|
type ScrobblerLogBackend struct {
|
||||||
|
@ -46,7 +47,7 @@ func (b ScrobblerLogBackend) FromConfig(config *viper.Viper) Backend {
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b ScrobblerLogBackend) ExportListens(oldestTimestamp time.Time) ([]Listen, error) {
|
func (b ScrobblerLogBackend) ExportListens(oldestTimestamp time.Time) ([]models.Listen, error) {
|
||||||
file, err := os.Open(b.filePath)
|
file, err := os.Open(b.filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -65,7 +66,7 @@ func (b ScrobblerLogBackend) ExportListens(oldestTimestamp time.Time) ([]Listen,
|
||||||
// Row length is often flexible
|
// Row length is often flexible
|
||||||
tsvReader.FieldsPerRecord = -1
|
tsvReader.FieldsPerRecord = -1
|
||||||
|
|
||||||
listens := make([]Listen, 0)
|
listens := make([]models.Listen, 0)
|
||||||
for {
|
for {
|
||||||
// A row is:
|
// A row is:
|
||||||
// artistName releaseName trackName trackNumber duration rating timestamp recordingMbid
|
// artistName releaseName trackName trackNumber duration rating timestamp recordingMbid
|
||||||
|
@ -101,7 +102,7 @@ func (b ScrobblerLogBackend) ExportListens(oldestTimestamp time.Time) ([]Listen,
|
||||||
return listens, nil
|
return listens, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b ScrobblerLogBackend) ImportListens(listens []Listen, oldestTimestamp time.Time) (ImportResult, error) {
|
func (b ScrobblerLogBackend) ImportListens(listens []models.Listen, oldestTimestamp time.Time) (ImportResult, error) {
|
||||||
result := ImportResult{
|
result := ImportResult{
|
||||||
Count: 0,
|
Count: 0,
|
||||||
LastTimestamp: oldestTimestamp,
|
LastTimestamp: oldestTimestamp,
|
||||||
|
@ -195,8 +196,8 @@ func writeHeader(writer io.Writer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func rowToListen(row []string, client string) (Listen, error) {
|
func rowToListen(row []string, client string) (models.Listen, error) {
|
||||||
var listen Listen
|
var listen models.Listen
|
||||||
trackNumber, err := strconv.Atoi(row[3])
|
trackNumber, err := strconv.Atoi(row[3])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return listen, err
|
return listen, err
|
||||||
|
@ -212,14 +213,14 @@ func rowToListen(row []string, client string) (Listen, error) {
|
||||||
return listen, err
|
return listen, err
|
||||||
}
|
}
|
||||||
|
|
||||||
listen = Listen{
|
listen = models.Listen{
|
||||||
Track: Track{
|
Track: models.Track{
|
||||||
ArtistNames: []string{row[0]},
|
ArtistNames: []string{row[0]},
|
||||||
ReleaseName: row[1],
|
ReleaseName: row[1],
|
||||||
TrackName: row[2],
|
TrackName: row[2],
|
||||||
TrackNumber: trackNumber,
|
TrackNumber: trackNumber,
|
||||||
Duration: time.Duration(duration * int(time.Second)),
|
Duration: time.Duration(duration * int(time.Second)),
|
||||||
AdditionalInfo: AdditionalInfo{
|
AdditionalInfo: models.AdditionalInfo{
|
||||||
"rockbox_rating": row[5],
|
"rockbox_rating": row[5],
|
||||||
"media_player": client,
|
"media_player": client,
|
||||||
},
|
},
|
||||||
|
@ -228,7 +229,7 @@ func rowToListen(row []string, client string) (Listen, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(row) > 7 {
|
if len(row) > 7 {
|
||||||
listen.Track.RecordingMbid = MBID(row[7])
|
listen.Track.RecordingMbid = models.MBID(row[7])
|
||||||
}
|
}
|
||||||
|
|
||||||
return listen, nil
|
return listen, nil
|
||||||
|
|
|
@ -19,7 +19,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package backends
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
|
@ -19,17 +19,17 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package backends_test
|
package models_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"go.uploadedlobster.com/scotty/backends"
|
"go.uploadedlobster.com/scotty/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestTrackArtistName(t *testing.T) {
|
func TestTrackArtistName(t *testing.T) {
|
||||||
track := backends.Track{
|
track := models.Track{
|
||||||
ArtistNames: []string{
|
ArtistNames: []string{
|
||||||
"Foo",
|
"Foo",
|
||||||
"Bar",
|
"Bar",
|
Loading…
Add table
Add a link
Reference in a new issue