mirror of
https://git.sr.ht/~phw/scotty
synced 2025-04-16 10:09:28 +02:00
Maloja listens import
This commit is contained in:
parent
ca745038e3
commit
5a85987476
5 changed files with 118 additions and 1 deletions
|
@ -61,3 +61,18 @@ func (c Client) GetScrobbles(page int, perPage int) (result GetScrobblesResult,
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c Client) NewScrobble(scrobble NewScrobble) (result NewScrobbleResult, err error) {
|
||||||
|
const path = "/apis/mlj_1/newscrobble"
|
||||||
|
scrobble.Key = c.token
|
||||||
|
response, err := c.HttpClient.R().
|
||||||
|
SetBody(scrobble).
|
||||||
|
SetResult(&result).
|
||||||
|
Post(path)
|
||||||
|
|
||||||
|
if response.StatusCode() != 200 {
|
||||||
|
err = errors.New(response.String())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -57,6 +57,29 @@ func TestGetScrobbles(t *testing.T) {
|
||||||
assert.Equal(int64(558), result.List[0].Duration)
|
assert.Equal(int64(558), result.List[0].Duration)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNewScrobble(t *testing.T) {
|
||||||
|
server := "https://maloja.example.com"
|
||||||
|
client := maloja.NewClient(server, "thetoken")
|
||||||
|
httpmock.ActivateNonDefault(client.HttpClient.GetClient())
|
||||||
|
|
||||||
|
responder, err := httpmock.NewJsonResponder(200, httpmock.File("testdata/newscrobble-result.json"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
url := server + "/apis/mlj_1/newscrobble"
|
||||||
|
httpmock.RegisterResponder("POST", url, responder)
|
||||||
|
|
||||||
|
scrobble := maloja.NewScrobble{
|
||||||
|
Title: "Oweynagat",
|
||||||
|
Artist: "Dool",
|
||||||
|
Time: 1699574369,
|
||||||
|
}
|
||||||
|
result, err := client.NewScrobble(scrobble)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, "success", result.Status)
|
||||||
|
}
|
||||||
|
|
||||||
func setupHttpMock(t *testing.T, client *http.Client, url string, testDataPath string) {
|
func setupHttpMock(t *testing.T, client *http.Client, url string, testDataPath string) {
|
||||||
httpmock.ActivateNonDefault(client)
|
httpmock.ActivateNonDefault(client)
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ THE SOFTWARE.
|
||||||
package maloja
|
package maloja
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -32,6 +33,7 @@ import (
|
||||||
|
|
||||||
type MalojaApiBackend struct {
|
type MalojaApiBackend struct {
|
||||||
client Client
|
client Client
|
||||||
|
nofix bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b MalojaApiBackend) FromConfig(config *viper.Viper) models.Backend {
|
func (b MalojaApiBackend) FromConfig(config *viper.Viper) models.Backend {
|
||||||
|
@ -39,6 +41,7 @@ func (b MalojaApiBackend) FromConfig(config *viper.Viper) models.Backend {
|
||||||
config.GetString("server-url"),
|
config.GetString("server-url"),
|
||||||
config.GetString("token"),
|
config.GetString("token"),
|
||||||
)
|
)
|
||||||
|
b.nofix = config.GetBool("nofix")
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +78,42 @@ out:
|
||||||
return listens, nil
|
return listens, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b MalojaApiBackend) ImportListens(listens []models.Listen, oldestTimestamp time.Time) (models.ImportResult, error) {
|
||||||
|
result := models.ImportResult{
|
||||||
|
TotalCount: len(listens),
|
||||||
|
ImportCount: 0,
|
||||||
|
LastTimestamp: oldestTimestamp,
|
||||||
|
}
|
||||||
|
for _, listen := range listens {
|
||||||
|
if listen.ListenedAt.Unix() <= oldestTimestamp.Unix() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
scrobble := NewScrobble{
|
||||||
|
Title: listen.TrackName,
|
||||||
|
Artists: listen.ArtistNames,
|
||||||
|
Album: listen.ReleaseName,
|
||||||
|
Duration: int64(listen.PlaybackDuration.Seconds()),
|
||||||
|
Length: int64(listen.Duration.Seconds()),
|
||||||
|
Time: listen.ListenedAt.Unix(),
|
||||||
|
Nofix: b.nofix,
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := b.client.NewScrobble(scrobble)
|
||||||
|
if err != nil {
|
||||||
|
return result, err
|
||||||
|
} else if resp.Status != "success" {
|
||||||
|
return result, errors.New(resp.Error.Description)
|
||||||
|
}
|
||||||
|
|
||||||
|
if listen.ListenedAt.Unix() > result.LastTimestamp.Unix() {
|
||||||
|
result.LastTimestamp = listen.ListenedAt
|
||||||
|
}
|
||||||
|
result.ImportCount += 1
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s Scrobble) ToListen() models.Listen {
|
func (s Scrobble) ToListen() models.Listen {
|
||||||
track := s.Track
|
track := s.Track
|
||||||
listen := models.Listen{
|
listen := models.Listen{
|
||||||
|
|
|
@ -21,12 +21,23 @@ THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package maloja
|
package maloja
|
||||||
|
|
||||||
|
type GenericResult struct {
|
||||||
|
Status string `json:"status"`
|
||||||
|
}
|
||||||
|
|
||||||
type GetScrobblesResult struct {
|
type GetScrobblesResult struct {
|
||||||
Status string `json:"status"`
|
GenericResult
|
||||||
List []Scrobble `json:"list"`
|
List []Scrobble `json:"list"`
|
||||||
Pagination Pagination `json:"pagination"`
|
Pagination Pagination `json:"pagination"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type NewScrobbleResult struct {
|
||||||
|
GenericResult
|
||||||
|
Track Track `json:"track"`
|
||||||
|
Description string `json:"desc"`
|
||||||
|
Error Error `json:"error"`
|
||||||
|
}
|
||||||
|
|
||||||
type Scrobble struct {
|
type Scrobble struct {
|
||||||
ListenedAt int64 `json:"time"`
|
ListenedAt int64 `json:"time"`
|
||||||
Duration int64 `json:"duration"`
|
Duration int64 `json:"duration"`
|
||||||
|
@ -36,6 +47,19 @@ type Scrobble struct {
|
||||||
Track Track `json:"track"`
|
Track Track `json:"track"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type NewScrobble struct {
|
||||||
|
Key string `json:"key"`
|
||||||
|
Artist string `json:"artist,omitempty"`
|
||||||
|
Artists []string `json:"artists,omitempty"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Album string `json:"album,omitempty"`
|
||||||
|
AlbumArtists []string `json:"albumartists,omitempty"`
|
||||||
|
Duration int64 `json:"duration,omitempty"`
|
||||||
|
Length int64 `json:"length,omitempty"`
|
||||||
|
Time int64 `json:"time,omitempty"`
|
||||||
|
Nofix bool `json:"nofix,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
type Track struct {
|
type Track struct {
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
Artists []string `json:"artists"`
|
Artists []string `json:"artists"`
|
||||||
|
@ -54,3 +78,9 @@ type Pagination struct {
|
||||||
NextPage string `json:"next_page"`
|
NextPage string `json:"next_page"`
|
||||||
PrevPage string `json:"prev_page"`
|
PrevPage string `json:"prev_page"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Error struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
Value string `json:"value"`
|
||||||
|
Description string `json:"desc"`
|
||||||
|
}
|
||||||
|
|
10
backends/maloja/testdata/newscrobble-result.json
vendored
Normal file
10
backends/maloja/testdata/newscrobble-result.json
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"status": "success",
|
||||||
|
"track": {
|
||||||
|
"artists": [
|
||||||
|
"Dool"
|
||||||
|
],
|
||||||
|
"title": "Oweynagat"
|
||||||
|
},
|
||||||
|
"desc": "Scrobbled Oweynagat by Dool"
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue