Last.fm music provider (#73)

This commit is contained in:
Raphaël Thériault
2021-01-22 15:40:38 -05:00
committed by GitHub
parent be806eaf94
commit 7ef8e65951
7 changed files with 151 additions and 2 deletions

View File

@@ -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

View File

@@ -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:

View File

@@ -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}`))

View File

@@ -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

View File

@@ -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",

View File

@@ -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}

View File

@@ -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,
}], }],