Last.fm music provider (#73)
This commit is contained in:
committed by
GitHub
parent
be806eaf94
commit
7ef8e65951
38
README.md
38
README.md
@@ -901,6 +901,13 @@ Finish the plugin setup by adding the following to your workflow:
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Last.fm</summary>
|
||||||
|
|
||||||
|
This mode is not supported for now.
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
#### Recently played mode
|
#### Recently played mode
|
||||||
@@ -994,6 +1001,37 @@ With your `client_id`, `client_secret` and `refresh_token` you can finish the pl
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Last.fm</summary>
|
||||||
|
|
||||||
|
Obtain a Last.fm API key.
|
||||||
|
|
||||||
|
To do so, you can simply [create an API account](https://www.last.fm/api/account/create) or [use an existing one](https://www.last.fm/api/accounts).
|
||||||
|
|
||||||
|
Finish the plugin setup by adding the following to your workflow:
|
||||||
|
```yaml
|
||||||
|
- uses: lowlighter/metrics@latest
|
||||||
|
with:
|
||||||
|
# ... other options
|
||||||
|
plugin_music: yes
|
||||||
|
plugin_music_provider: lastfm
|
||||||
|
plugin_music_token: ${{ secrets.LASTFM_API_KEY }}
|
||||||
|
plugin_music_mode: recent
|
||||||
|
plugin_music_limit: 4
|
||||||
|
```
|
||||||
|
|
||||||
|
It is possible to use a different Last.fm username from your GitHub account by using `plugin_music_user` option.
|
||||||
|
|
||||||
|
Add the following to your workflow:
|
||||||
|
```yaml
|
||||||
|
- uses: lowlighter/metrics@latest
|
||||||
|
with:
|
||||||
|
# ... other options
|
||||||
|
plugin_music_user: ********
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
### 🈷️ Languages
|
### 🈷️ Languages
|
||||||
|
|||||||
@@ -240,6 +240,7 @@ inputs:
|
|||||||
# Supported values are :
|
# Supported values are :
|
||||||
# - "apple" for Apple Music
|
# - "apple" for Apple Music
|
||||||
# - "spotify" for Spotify
|
# - "spotify" for Spotify
|
||||||
|
# - "lastfm" for Last.fm
|
||||||
plugin_music_provider:
|
plugin_music_provider:
|
||||||
description: Name of the music provider you're using
|
description: Name of the music provider you're using
|
||||||
default: ""
|
default: ""
|
||||||
@@ -248,6 +249,7 @@ inputs:
|
|||||||
# This may be required depending on the music provider and the mode you use
|
# This may be required depending on the music provider and the mode you use
|
||||||
# - "apple" : not required
|
# - "apple" : not required
|
||||||
# - "spotify" : required for "recent" mode, format is "client_id, client_secret, refresh_token"
|
# - "spotify" : required for "recent" mode, format is "client_id, client_secret, refresh_token"
|
||||||
|
# - "lastfm" : required, format is "api_key"
|
||||||
plugin_music_token:
|
plugin_music_token:
|
||||||
description: Music provider personal token
|
description: Music provider personal token
|
||||||
default: ""
|
default: ""
|
||||||
@@ -272,6 +274,12 @@ inputs:
|
|||||||
description: Number of tracks to display
|
description: Number of tracks to display
|
||||||
default: 4
|
default: 4
|
||||||
|
|
||||||
|
# Music service username
|
||||||
|
# Leave empty to default to the login "user"'s GitHub account
|
||||||
|
plugin_music_user:
|
||||||
|
description: "Music provider username"
|
||||||
|
default: ""
|
||||||
|
|
||||||
# Posts plugin
|
# Posts plugin
|
||||||
# Display recent posts from an external source
|
# Display recent posts from an external source
|
||||||
plugin_posts:
|
plugin_posts:
|
||||||
|
|||||||
@@ -180,7 +180,7 @@
|
|||||||
if (plugins.music.enabled) {
|
if (plugins.music.enabled) {
|
||||||
plugins.music.token = input.string("plugin_music_token")
|
plugins.music.token = input.string("plugin_music_token")
|
||||||
info("Music token", plugins.music.token, {token:true})
|
info("Music token", plugins.music.token, {token:true})
|
||||||
for (const option of ["provider", "mode", "playlist"])
|
for (const option of ["provider", "mode", "playlist", "user"])
|
||||||
info(`Music ${option}`, q[`music.${option}`] = input.string(`plugin_music_${option}`))
|
info(`Music ${option}`, q[`music.${option}`] = input.string(`plugin_music_${option}`))
|
||||||
for (const option of ["limit"])
|
for (const option of ["limit"])
|
||||||
info(`Music ${option}`, q[`music.${option}`] = input.number(`plugin_music_${option}`))
|
info(`Music ${option}`, q[`music.${option}`] = input.number(`plugin_music_${option}`))
|
||||||
|
|||||||
@@ -1083,6 +1083,69 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//Last.fm api
|
||||||
|
if (/^https:..ws.audioscrobbler.com/.test(url)) {
|
||||||
|
//Get recently played tracks
|
||||||
|
if (/user.getrecenttracks/.test(url)) {
|
||||||
|
console.debug(`metrics/compute/mocks > mocking lastfm api result > ${url}`)
|
||||||
|
const artist = faker.random.word()
|
||||||
|
const album = faker.random.words(3)
|
||||||
|
const track = faker.random.words(5)
|
||||||
|
const date = faker.date.recent()
|
||||||
|
return ({
|
||||||
|
status:200,
|
||||||
|
data:{
|
||||||
|
recenttracks:{
|
||||||
|
"@attr":{
|
||||||
|
page:"1",
|
||||||
|
perPage:"1",
|
||||||
|
user:"RJ",
|
||||||
|
total:"100",
|
||||||
|
pages:"100",
|
||||||
|
},
|
||||||
|
track:[
|
||||||
|
{
|
||||||
|
artist:{
|
||||||
|
mbid:"",
|
||||||
|
"#text":artist,
|
||||||
|
},
|
||||||
|
album:{
|
||||||
|
mbid:"",
|
||||||
|
"#text":album,
|
||||||
|
},
|
||||||
|
image:[
|
||||||
|
{
|
||||||
|
size:"small",
|
||||||
|
"#text":faker.image.abstract(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
size:"medium",
|
||||||
|
"#text":faker.image.abstract(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
size:"large",
|
||||||
|
"#text":faker.image.abstract(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
size:"extralarge",
|
||||||
|
"#text":faker.image.abstract(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
streamable:"0",
|
||||||
|
date:{
|
||||||
|
uts:Math.floor(date.getTime() / 1000),
|
||||||
|
"#text":date.toUTCString().slice(5, 22),
|
||||||
|
},
|
||||||
|
url:faker.internet.url(),
|
||||||
|
name:track,
|
||||||
|
mbid:"",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
//Twitter api
|
//Twitter api
|
||||||
if (/^https:..api.twitter.com/.test(url)) {
|
if (/^https:..api.twitter.com/.test(url)) {
|
||||||
//Get user profile
|
//Get user profile
|
||||||
|
|||||||
@@ -94,8 +94,10 @@
|
|||||||
"habits.days":{text:"Max events age", type:"number", min:1, max:30},
|
"habits.days":{text:"Max events age", type:"number", min:1, max:30},
|
||||||
"habits.facts":{text:"Display facts", type:"boolean"},
|
"habits.facts":{text:"Display facts", type:"boolean"},
|
||||||
"habits.charts":{text:"Display charts", type:"boolean"},
|
"habits.charts":{text:"Display charts", type:"boolean"},
|
||||||
|
"music.provider":{text:"Provider", placeholder:"spotify"},
|
||||||
"music.playlist":{text:"Playlist url", placeholder:"https://embed.music.apple.com/en/playlist/"},
|
"music.playlist":{text:"Playlist url", placeholder:"https://embed.music.apple.com/en/playlist/"},
|
||||||
"music.limit":{text:"Limit", type:"number", min:1, max:100},
|
"music.limit":{text:"Limit", type:"number", min:1, max:100},
|
||||||
|
"music.user":{text:"Username", placeholder:"(default to GitHub login)"},
|
||||||
"posts.limit":{text:"Limit", type:"number", min:1, max:30},
|
"posts.limit":{text:"Limit", type:"number", min:1, max:30},
|
||||||
"posts.user":{text:"Username", placeholder:"(default to GitHub login)"},
|
"posts.user":{text:"Username", placeholder:"(default to GitHub login)"},
|
||||||
"posts.source":{text:"Source", type:"select", values:["dev.to"]},
|
"posts.source":{text:"Source", type:"select", values:["dev.to"]},
|
||||||
@@ -124,8 +126,10 @@
|
|||||||
"habits.days":14,
|
"habits.days":14,
|
||||||
"habits.facts":true,
|
"habits.facts":true,
|
||||||
"habits.charts":false,
|
"habits.charts":false,
|
||||||
|
"music.provider":"",
|
||||||
"music.playlist":"",
|
"music.playlist":"",
|
||||||
"music.limit":4,
|
"music.limit":4,
|
||||||
|
"music.user":"",
|
||||||
"posts.limit":4,
|
"posts.limit":4,
|
||||||
"posts.user":"",
|
"posts.user":"",
|
||||||
"posts.source":"dev.to",
|
"posts.source":"dev.to",
|
||||||
|
|||||||
@@ -8,6 +8,10 @@
|
|||||||
name:"Spotify",
|
name:"Spotify",
|
||||||
embed:/^https:..open.spotify.com.embed.playlist/,
|
embed:/^https:..open.spotify.com.embed.playlist/,
|
||||||
},
|
},
|
||||||
|
lastfm:{
|
||||||
|
name:"Last.fm",
|
||||||
|
embed:/^\b$/,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
//Supported modes
|
//Supported modes
|
||||||
@@ -30,7 +34,7 @@
|
|||||||
}
|
}
|
||||||
let tracks = null
|
let tracks = null
|
||||||
//Parameters override
|
//Parameters override
|
||||||
let {"music.provider":provider = "", "music.mode":mode = "", "music.playlist":playlist = null, "music.limit":limit = 4} = q
|
let {"music.provider":provider = "", "music.mode":mode = "", "music.playlist":playlist = null, "music.limit":limit = 4, "music.user":user = login} = q
|
||||||
//Auto-guess parameters
|
//Auto-guess parameters
|
||||||
if ((playlist)&&(!mode))
|
if ((playlist)&&(!mode))
|
||||||
mode = "playlist"
|
mode = "playlist"
|
||||||
@@ -156,6 +160,33 @@
|
|||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
//Last.fm
|
||||||
|
case "lastfm":{
|
||||||
|
//API call and parse tracklist
|
||||||
|
try {
|
||||||
|
console.debug(`metrics/compute/${login}/plugins > music > querying lastfm api`)
|
||||||
|
tracks = (await imports.axios.get(`https://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=${user}&api_key=${token}&limit=${limit}&format=json`, {headers:{
|
||||||
|
"Accept":"application/json",
|
||||||
|
"User-Agent":"lowlighter/metrics"}
|
||||||
|
})).data.recenttracks.track.map((track) => ({
|
||||||
|
name:track.name,
|
||||||
|
artist:track.artist["#text"],
|
||||||
|
artwork:track.image.reverse()[0]["#text"],
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
//Handle errors
|
||||||
|
catch (error) {
|
||||||
|
if (error.isAxiosError) {
|
||||||
|
const status = error.response?.status
|
||||||
|
const description = error.response.data?.message ?? null
|
||||||
|
const message = `API returned ${status}${description ? ` (${description})` : ""}`
|
||||||
|
error = error.response?.data ?? null
|
||||||
|
throw {error:{message, instance:error}, ...raw}
|
||||||
|
}
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
//Unsupported
|
//Unsupported
|
||||||
default:
|
default:
|
||||||
throw {error:{message:`Unsupported mode "${mode}" for provider "${provider}"`}, ...raw}
|
throw {error:{message:`Unsupported mode "${mode}" for provider "${provider}"`}, ...raw}
|
||||||
|
|||||||
@@ -127,6 +127,11 @@
|
|||||||
plugin_music:true,
|
plugin_music:true,
|
||||||
plugin_music_provider: "spotify",
|
plugin_music_provider: "spotify",
|
||||||
}, {skip:["terminal", "repository"]}],
|
}, {skip:["terminal", "repository"]}],
|
||||||
|
["Music plugin (recent - lastfm)", {
|
||||||
|
plugin_music:true,
|
||||||
|
plugin_music_provider: "lastfm",
|
||||||
|
plugin_music_user: "RJ",
|
||||||
|
}, {skip:["terminal", "repository"]}],
|
||||||
["Language plugin (default)", {
|
["Language plugin (default)", {
|
||||||
plugin_languages:true,
|
plugin_languages:true,
|
||||||
}],
|
}],
|
||||||
|
|||||||
Reference in New Issue
Block a user