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
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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) {
|
||||
httpmock.ActivateNonDefault(client)
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ THE SOFTWARE.
|
|||
package maloja
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -32,6 +33,7 @@ import (
|
|||
|
||||
type MalojaApiBackend struct {
|
||||
client Client
|
||||
nofix bool
|
||||
}
|
||||
|
||||
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("token"),
|
||||
)
|
||||
b.nofix = config.GetBool("nofix")
|
||||
return b
|
||||
}
|
||||
|
||||
|
@ -75,6 +78,42 @@ out:
|
|||
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 {
|
||||
track := s.Track
|
||||
listen := models.Listen{
|
||||
|
|
|
@ -21,12 +21,23 @@ THE SOFTWARE.
|
|||
*/
|
||||
package maloja
|
||||
|
||||
type GenericResult struct {
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
type GetScrobblesResult struct {
|
||||
Status string `json:"status"`
|
||||
GenericResult
|
||||
List []Scrobble `json:"list"`
|
||||
Pagination Pagination `json:"pagination"`
|
||||
}
|
||||
|
||||
type NewScrobbleResult struct {
|
||||
GenericResult
|
||||
Track Track `json:"track"`
|
||||
Description string `json:"desc"`
|
||||
Error Error `json:"error"`
|
||||
}
|
||||
|
||||
type Scrobble struct {
|
||||
ListenedAt int64 `json:"time"`
|
||||
Duration int64 `json:"duration"`
|
||||
|
@ -36,6 +47,19 @@ type Scrobble struct {
|
|||
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 {
|
||||
Title string `json:"title"`
|
||||
Artists []string `json:"artists"`
|
||||
|
@ -54,3 +78,9 @@ type Pagination struct {
|
|||
NextPage string `json:"next_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