Skip to content

Commit

Permalink
add track.song api
Browse files Browse the repository at this point in the history
  • Loading branch information
sangazh committed Jan 6, 2021
1 parent 3bd9ca0 commit 96886f9
Show file tree
Hide file tree
Showing 15 changed files with 200 additions and 562 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
config.toml
log/*
go.sum
xiami/song.json
59 changes: 0 additions & 59 deletions app/temp.go

This file was deleted.

35 changes: 0 additions & 35 deletions app/temp_test.go

This file was deleted.

14 changes: 1 addition & 13 deletions config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,4 @@ title = "Xiami and Last.fm Example"
recording = "/recording"

[xiami]
domain = "http://www.xiami.com"
spm = ""
user_id = 0
checked_at = 0

[xiami.cookie]
_unsign_token = ""
_xiamitoken = ""
member_auth = ""
x5sec = ""

[xiami.url]
recent = "/space/charts-recent/u/"
file = "xiami/song.json"
2 changes: 1 addition & 1 deletion lastfm/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ func authPage() string {
// Session keys have an infinite lifetime by default
func session() error {
v := url.Values{}
v.Set("method", "auth.session")
v.Set("method", "auth.getSession")
v.Set("api_key", apiKey)
v.Set("token", token)
sig := signature(&v)
Expand Down
96 changes: 0 additions & 96 deletions lastfm/lastfm.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@ import (
"io/ioutil"
"log"
"net/http"
"net/url"
"os"

"xiamiToLastfm/musicbrainz"
"xiamiToLastfm/xiami"
)

// QuitChan: an empty channel used to signal main channel to stop.
Expand All @@ -20,98 +16,6 @@ var (
QuitChan chan struct{}
)

// https://www.last.fm/api/show/track.scrobble
type ScrobbleParams struct {
Artist []string `json:"artist,omitempty"`
Track []string `json:"track,omitempty"`
Timestamp []string `json:"timestamp,omitempty"`
Album []string `json:"album,omitempty"`
TrackNumber []string `json:"trackNumber,omitempty"`
Mbid []string `json:"mbid,omitempty"` //The MusicBrainz Track ID
AlbumArtist []string `json:"albumArtist,omitempty"`
DurationInSeconds []string `json:"duration,omitempty"`
ApiKey string `json:"api_key"`
ApiSig string `json:"api_sig"`
Sk string `json:"sk"`
Format string `json:"format"`
Method string `json:"method"`
}

// Send scrobble info to last.fm server
// https://www.last.fm/api/show/track.scrobble
func Scrobble(xm xiami.Track) error {
log.Println("lastfm.Scrobble playedChan track: ", xm)

v := url.Values{}
v.Set("artist[0]", xm.Artist)
v.Set("album[0]", xm.Album)
v.Set("track[0]", xm.Title)

if mbid, ok := musicbrainz.MbID(xm.Title, xm.Artist, xm.Album); ok {
v.Set("mbid[0]", string(mbid))
}

v.Set("timestamp[0]", fmt.Sprint(xm.Timestamp))
v.Set("method", "track.scrobble")
v.Set("sk", sk)
v.Set("api_key", apiKey)
sig := signature(&v)
v.Set("api_sig", sig)
v.Set("format", "json")

respData, err := postRequest(v.Encode())
if err != nil {
//if failed, insert back to channel
return err
}

accepted, ignored := scrobbleResponse(respData)
log.Printf("last.fm: Scrobble succese: accepted - %d, ignored - %d\n", accepted, ignored)
fmt.Printf("scrobbled:\t %s - %s \n", xm.Title, xm.Artist)

return nil
}

func scrobbleResponse(data []byte) (accepted, ignored int) {
type response struct {
Data struct {
Msg struct {
Accepted int `json:"accepted"`
Ignored int `json:"ignored"`
} `json:"@attr"`
} `json:"scrobbles"`
}

var resp response
json.Unmarshal(data, &resp)
return resp.Data.Msg.Accepted, resp.Data.Msg.Ignored
}

// Update nowplaying
// https://www.last.fm/api/show/track.updateNowPlaying
func UpdateNowPlaying(xm xiami.Track) error {
log.Println("last.fm: nowPlayingChan track: ", xm)

v := url.Values{}
v.Set("method", "track.updateNowPlaying")
v.Set("sk", sk)
v.Set("api_key", apiKey)
v.Set("artist", xm.Artist)
v.Set("album", xm.Album)
v.Set("track", xm.Title)
sig := signature(&v)
v.Set("api_sig", sig)
v.Set("format", "json")

if _, err := postRequest(v.Encode()); err != nil {
//if failed, as discard.
return err
}

fmt.Printf("updated:\t %s - %s \n", xm.Title, xm.Artist)
return nil
}

func getRequest(url string) ([]byte, error) {
log.Println("last.fm: getRequest url: ", url)
res, err := http.Get(url)
Expand Down
7 changes: 4 additions & 3 deletions lastfm/lastfm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ func TestStartScrobble(t *testing.T) {
}
playedChan <- track

assert.Equal(t, nil, Scrobble(playedChan))
assert.Equal(t, nil, Scrobble(track))
}

func TestUpdateNowPlaying(t *testing.T) {
Expand All @@ -149,7 +149,7 @@ func TestUpdateNowPlaying(t *testing.T) {
Timestamp: 1523328000,
}
nowPlayingChan <- track
assert.Equal(t, nil, UpdateNowPlaying(nowPlayingChan))
assert.Equal(t, nil, UpdateNowPlaying(track))
}

func TestRenderScrobbleResp(t *testing.T) {
Expand Down Expand Up @@ -180,7 +180,8 @@ func TestHandleError(t *testing.T) {
}

func TestGetSession(t *testing.T) {
session()
err := session()
assert.Nil(t, err)
}

func init() {
Expand Down
103 changes: 103 additions & 0 deletions lastfm/scrobble.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package lastfm

import (
"encoding/json"
"fmt"
"log"
"net/url"

"xiamiToLastfm/musicbrainz"
"xiamiToLastfm/xiami"
)

// https://www.last.fm/api/show/track.scrobble
type ScrobbleParams struct {
Artist []string `json:"artist,omitempty"`
Track []string `json:"track,omitempty"`
Timestamp []string `json:"timestamp,omitempty"`
Album []string `json:"album,omitempty"`
TrackNumber []string `json:"trackNumber,omitempty"`
Mbid []string `json:"mbid,omitempty"` //The MusicBrainz Track ID
AlbumArtist []string `json:"albumArtist,omitempty"`
DurationInSeconds []string `json:"duration,omitempty"`
ApiKey string `json:"api_key"`
ApiSig string `json:"api_sig"`
Sk string `json:"sk"`
Format string `json:"format"`
Method string `json:"method"`
}

// Send scrobble info to last.fm server
// https://www.last.fm/api/show/track.scrobble
func Scrobble(xm xiami.Track) error {
log.Println("lastfm.Scrobble playedChan track: ", xm)

v := url.Values{}
v.Set("artist[0]", xm.Artist)
v.Set("album[0]", xm.Album)
v.Set("track[0]", xm.Title)

if mbid, ok := musicbrainz.MbID(xm.Title, xm.Artist, xm.Album); ok {
v.Set("mbid[0]", string(mbid))
}

v.Set("timestamp[0]", fmt.Sprint(xm.Timestamp))
v.Set("method", "track.scrobble")
v.Set("sk", sk)
v.Set("api_key", apiKey)
sig := signature(&v)
v.Set("api_sig", sig)
v.Set("format", "json")

respData, err := postRequest(v.Encode())
if err != nil {
//if failed, insert back to channel
return err
}

accepted, ignored := scrobbleResponse(respData)
log.Printf("last.fm: Scrobble succese: accepted - %d, ignored - %d\n", accepted, ignored)
fmt.Printf("scrobbled:\t %s - %s \n", xm.Title, xm.Artist)

return nil
}

func scrobbleResponse(data []byte) (accepted, ignored int) {
type response struct {
Data struct {
Msg struct {
Accepted int `json:"accepted"`
Ignored int `json:"ignored"`
} `json:"@attr"`
} `json:"scrobbles"`
}

var resp response
json.Unmarshal(data, &resp)
return resp.Data.Msg.Accepted, resp.Data.Msg.Ignored
}

// Update nowplaying
// https://www.last.fm/api/show/track.updateNowPlaying
func UpdateNowPlaying(xm xiami.Track) error {
log.Println("last.fm: nowPlayingChan track: ", xm)

v := url.Values{}
v.Set("method", "track.updateNowPlaying")
v.Set("sk", sk)
v.Set("api_key", apiKey)
v.Set("artist", xm.Artist)
v.Set("album", xm.Album)
v.Set("track", xm.Title)
sig := signature(&v)
v.Set("api_sig", sig)
v.Set("format", "json")

if _, err := postRequest(v.Encode()); err != nil {
//if failed, as discard.
return err
}

fmt.Printf("updated:\t %s - %s \n", xm.Title, xm.Artist)
return nil
}
Loading

0 comments on commit 96886f9

Please sign in to comment.