Skip to content

Commit 34c850a

Browse files
committed
feat: add spotify integration
1 parent a225bc6 commit 34c850a

File tree

9 files changed

+213
-7
lines changed

9 files changed

+213
-7
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ const metascraper = require('metascraper')([
205205
| [`metascraper-title`](https://github.com/microlinkhq/metascraper/tree/master/packages/metascraper-title) | [![npm](https://img.shields.io/npm/v/metascraper-title.svg?style=flat-square)](https://www.npmjs.com/package/metascraper-title) | [![Dependency Status](https://david-dm.org/microlinkhq/metascraper.svg?path=packages/metascraper-title&style=flat-square)](https://david-dm.org/microlinkhq/metascraper?path=packages/metascraper-title) |
206206
| [`metascraper-uol`](https://github.com/microlinkhq/metascraper/tree/master/packages/metascraper-uol) | [![npm](https://img.shields.io/npm/v/metascraper-uol.svg?style=flat-square)](https://www.npmjs.com/package/metascraper-uol) | [![Dependency Status](https://david-dm.org/microlinkhq/metascraper.svg?path=packages/metascraper-uol&style=flat-square)](https://david-dm.org/microlinkhq/metascraper?path=packages/metascraper-uol) |
207207
| [`metascraper-url`](https://github.com/microlinkhq/metascraper/tree/master/packages/metascraper-url) | [![npm](https://img.shields.io/npm/v/metascraper-url.svg?style=flat-square)](https://www.npmjs.com/package/metascraper-url) | [![Dependency Status](https://david-dm.org/microlinkhq/metascraper.svg?path=packages/metascraper-url&style=flat-square)](https://david-dm.org/microlinkhq/metascraper?path=packages/metascraper-url) |
208+
| [`metascraper-spotify`](https://github.com/microlinkhq/metascraper/tree/master/packages/metascraper-spotify) | [![npm](https://img.shields.io/npm/v/metascraper-spotify.svg?style=flat-square)](https://www.npmjs.com/package/metascraper-spotify) | [![Dependency Status](https://david-dm.org/microlinkhq/metascraper.svg?path=packages/metascraper-spotify&style=flat-square)](https://david-dm.org/microlinkhq/metascraper?path=packages/metascraper-spotify) |
208209
| [`metascraper-video`](https://github.com/microlinkhq/metascraper/tree/master/packages/metascraper-video) | [![npm](https://img.shields.io/npm/v/metascraper-video.svg?style=flat-square)](https://www.npmjs.com/package/metascraper-video) | [![Dependency Status](https://david-dm.org/microlinkhq/metascraper.svg?path=packages/metascraper-video&style=flat-square)](https://david-dm.org/microlinkhq/metascraper?path=packages/metascraper-video) |
209210
| [`metascraper-youtube`](https://github.com/microlinkhq/metascraper/tree/master/packages/metascraper-youtube) | [![npm](https://img.shields.io/npm/v/metascraper-youtube.svg?style=flat-square)](https://www.npmjs.com/package/metascraper-youtube) | [![Dependency Status](https://david-dm.org/microlinkhq/metascraper.svg?path=packages/metascraper-youtube&style=flat-square)](https://david-dm.org/microlinkhq/metascraper?path=packages/metascraper-youtube) |
210211

packages/metascraper-helpers/index.js

+7-7
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,11 @@ const protocol = url => {
130130
return protocol.replace(':', '')
131131
}
132132

133-
const isMediaTypeUrl = (url, type, opts) =>
134-
isUrl(url, opts) && isMediaTypeExtension(url, type)
133+
const isMediaTypeUrl = (url, type, { ext, ...opts } = {}) =>
134+
isUrl(url, opts) && isMediaTypeExtension(url, type, ext)
135135

136-
const isMediaTypeExtension = (url, type) =>
137-
eq(type, get(EXTENSIONS, extension(url)))
136+
const isMediaTypeExtension = (url, type, ext) =>
137+
eq(type, get(EXTENSIONS, ext || extension(url)))
138138

139139
const isMediaUrl = (url, opts) =>
140140
isImageUrl(url, opts) || isVideoUrl(url, opts) || isAudioUrl(url, opts)
@@ -252,12 +252,12 @@ const logo = url
252252

253253
const video = (value, opts) => {
254254
const urlValue = url(value, opts)
255-
return isVideoUrl(urlValue) && urlValue
255+
return isVideoUrl(urlValue, opts) && urlValue
256256
}
257257

258258
const audio = (value, opts) => {
259259
const urlValue = url(value, opts)
260-
return isAudioUrl(urlValue) && urlValue
260+
return isAudioUrl(urlValue, opts) && urlValue
261261
}
262262

263263
const validator = {
@@ -279,7 +279,7 @@ const toRule = (fn, opts) => rule => ({ htmlDom, url }) => {
279279
return fn(value, { url, ...opts })
280280
}
281281

282-
const composeRule = (fn, opts) => ({ from, to = from }) => async ({
282+
const composeRule = fn => ({ from, to = from, ...opts }) => async ({
283283
htmlDom,
284284
url
285285
}) => {

packages/metascraper-spotify/.npmrc

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
unsafe-perm=true
2+
save-prefix=~
3+
shrinkwrap=false
4+
save=false
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# metascraper-spotify
2+
3+
[![npm](https://img.shields.io/npm/v/metascraper-spotify.svg?style=flat-square)](https://www.npmjs.com/package/metascraper-spotify)
4+
[![Dependency Status](https://david-dm.org/microlinkhq/metascraper.svg?path=packages/metascraper-spotify&style=flat-square)](https://david-dm.org/microlinkhq/metascraper?path=packages/metascraper-spotify)
5+
6+
> metascraper integration with Spotify.
7+
8+
## Install
9+
10+
```bash
11+
$ npm install metascraper-spotify --save
12+
```
13+
14+
## License
15+
16+
**metascraper-spotify** © [microlink.io](https://microlink.io), Released under the [MIT](https://github.com/microlinkhq/metascraper-spotify/blob/master/LICENSE.md) License.<br>
17+
Authored and maintained by microlink.io with help from [contributors](https://github.com/microlinkhq/metascraper-spotify/contributors).
18+
19+
> [microlink.io](https://microlink.io) · GitHub [@microlink.io](https://github.com/microlinkhq) · Twitter [@microlinkhq](https://twitter.com/microlinkhq)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
exports['ad5bbc912b5260028b5775ba6d03a0697592ead84acc359f25f38a214815d660 1'] = {
2+
"title": "Immaterial",
3+
"image": "https://i.scdn.co/image/d6f496a6708d22a2f867e5acb84afb0eb0b07bc1",
4+
"audio": "https://p.scdn.co/mp3-preview/6be8eb12ff18ae09b7a6d38ff1e5327fd128a74e?cid=a46f5c5745a14fbf826186da8da5ecc3",
5+
"url": "https://open.spotify.com/track/5nTtCOCds6I0PHMNtqelas",
6+
"author": "SOPHIE",
7+
"date": null,
8+
"description": null,
9+
"lang": null,
10+
"logo": "https://embed.spotify.com/favicon.ico",
11+
"publisher": null
12+
}
13+
14+
exports['ad5bbc912b5260028b5775ba6d03a0697592ead84acc359f25f38a214815d660 2'] = {
15+
"title": "Immaterial",
16+
"image": "https://i.scdn.co/image/d6f496a6708d22a2f867e5acb84afb0eb0b07bc1",
17+
"audio": "https://p.scdn.co/mp3-preview/6be8eb12ff18ae09b7a6d38ff1e5327fd128a74e?cid=a46f5c5745a14fbf826186da8da5ecc3",
18+
"url": "https://open.spotify.com/track/5nTtCOCds6I0PHMNtqelas",
19+
"author": "SOPHIE",
20+
"date": null,
21+
"description": null,
22+
"lang": null,
23+
"logo": "https://open.spotify.com/favicon.ico",
24+
"publisher": null
25+
}
26+
27+
exports['ad5bbc912b5260028b5775ba6d03a0697592ead84acc359f25f38a214815d660 3'] = {
28+
"title": "Thrones",
29+
"image": "https://i.scdn.co/image/ab67616d0000b273b2e2e8384aa498c6579ecba4",
30+
"audio": "https://p.scdn.co/mp3-preview/610d2f2de94a751446d9fea3e8b7485693edf72e?cid=a46f5c5745a14fbf826186da8da5ecc3",
31+
"url": "https://open.spotify.com/track/6YqroNoDYeQAOUMpdmim9M",
32+
"author": "Chuki Beats",
33+
"date": null,
34+
"description": null,
35+
"lang": null,
36+
"logo": "https://open.spotify.com/favicon.ico",
37+
"publisher": null
38+
}
39+
40+
exports['ad5bbc912b5260028b5775ba6d03a0697592ead84acc359f25f38a214815d660 4'] = {
41+
"title": "The Days",
42+
"image": "https://i.scdn.co/image/ab67616d0000b273b9591cb18806aabd30d78aa8",
43+
"audio": "https://p.scdn.co/mp3-preview/48a8445c3d6ad4b895fe04ab92acac0cbe6b9c69?cid=a46f5c5745a14fbf826186da8da5ecc3",
44+
"url": "https://open.spotify.com/track/5Iy2Jj87Ha0C0IBlNE1I4y",
45+
"author": "Avicii",
46+
"date": null,
47+
"description": null,
48+
"lang": null,
49+
"logo": "https://play.spotify.com/favicon.ico",
50+
"publisher": null
51+
}
52+

packages/metascraper-spotify/index.js

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
'use strict'
2+
3+
const { composeRule } = require('@metascraper/helpers')
4+
const { getPreview } = require('spotify-url-info')
5+
const spotifyUri = require('spotify-uri')
6+
const memoizeOne = require('memoize-one')
7+
8+
const memoFn = (newArgs, oldArgs) => newArgs[1] === oldArgs[1]
9+
10+
const spotify = memoizeOne(($, url) => getPreview(url), memoFn)
11+
12+
const getSpotify = composeRule(spotify)
13+
14+
const isValidUrl = url => !!spotifyUri(url).id
15+
16+
module.exports = () => {
17+
const rules = {
18+
title: getSpotify({ from: 'title' }),
19+
image: getSpotify({ from: 'image' }),
20+
audio: getSpotify({ from: 'audio', ext: 'mp3' }),
21+
url: getSpotify({ from: 'link', to: 'url' }),
22+
author: getSpotify({ from: 'artist', to: 'author' })
23+
}
24+
25+
rules.test = ({ url }) => isValidUrl(url)
26+
27+
return rules
28+
}
29+
30+
module.exports.isValidUrl = isValidUrl
+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{
2+
"name": "metascraper-spotify",
3+
"description": "metascraper integration with Spotify",
4+
"homepage": "https://nicedoc.io/microlinkhq/metascraper/packages/metascraper-spotify",
5+
"version": "0.0.0",
6+
"main": "index.js",
7+
"repository": {
8+
"type": "git",
9+
"url": "git+https://github.com/microlinkhq/metascraper-spotify.git"
10+
},
11+
"bugs": {
12+
"url": "https://github.com/microlinkhq/metascraper-spotify/issues"
13+
},
14+
"keywords": [
15+
"audio",
16+
"metascraper",
17+
"spotify"
18+
],
19+
"dependencies": {
20+
"@metascraper/helpers": "^5.7.21",
21+
"memoize-one": "~5.1.1",
22+
"spotify-uri": "~1.0.0",
23+
"spotify-url-info": "~1.3.0"
24+
},
25+
"devDependencies": {
26+
"mocha": "latest",
27+
"should": "latest",
28+
"snap-shot": "latest",
29+
"standard": "latest"
30+
},
31+
"engines": {
32+
"node": ">= 8"
33+
},
34+
"files": [
35+
"index.js"
36+
],
37+
"scripts": {
38+
"test": "NODE_PATH=.. TZ=UTC NODE_ENV=test mocha test"
39+
},
40+
"license": "MIT",
41+
"standard": {
42+
"env": [
43+
"mocha"
44+
]
45+
}
46+
}
+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
'use strict'
2+
3+
const snapshot = require('snap-shot')
4+
const should = require('should')
5+
6+
const metascraperSpotify = require('metascraper-spotify')
7+
8+
const { isValidUrl } = metascraperSpotify
9+
10+
const metascraper = require('metascraper')([
11+
metascraperSpotify(),
12+
require('metascraper-author')(),
13+
require('metascraper-date')(),
14+
require('metascraper-description')(),
15+
require('metascraper-image')(),
16+
require('metascraper-lang')(),
17+
require('metascraper-logo')(),
18+
require('metascraper-logo-favicon')(),
19+
require('metascraper-publisher')(),
20+
require('metascraper-title')(),
21+
require('metascraper-url')()
22+
])
23+
24+
const spotifyUrls = [
25+
'https://embed.spotify.com/?uri=spotify:track:5nTtCOCds6I0PHMNtqelas',
26+
'https://open.spotify.com/track/5nTtCOCds6I0PHMNtqelas',
27+
'https://open.spotify.com/track/6YqroNoDYeQAOUMpdmim9M?si=_-aA_80kSligZ0SN6VsboA',
28+
'https://play.spotify.com/track/4th1RQAelzqgY7wL53UGQt'
29+
]
30+
31+
describe('metascraper-spotify', () => {
32+
describe('.isvalidUrl', () => {
33+
spotifyUrls.forEach(url => {
34+
it(url, () => {
35+
should(isValidUrl(url)).be.true()
36+
})
37+
})
38+
})
39+
40+
describe('extract metadata', () => {
41+
spotifyUrls.forEach(url => {
42+
it(url, async () => {
43+
const meta = await metascraper({ url })
44+
snapshot(meta)
45+
})
46+
})
47+
})
48+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
--require should
2+
--reporter spec
3+
--timeout 120000
4+
--slow 300
5+
--bail
6+
--recursive

0 commit comments

Comments
 (0)