-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathspotify.js
58 lines (47 loc) · 1.61 KB
/
spotify.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// https://api.spotify.com/v1/search?q=${query}&type=artist --> artists: {items: []}
// https://api.spotify.com/v1/artists/${id}/related-artists --> artists: []
const Either = require('data.either')
const request = require('request')
const Task = require('data.task')
const { List } = require('immutable-ext')
// #region Spotify
const httpGet = url =>
new Task((rej, res) =>
request(url, (error, response, body) => (error ? rej(error) : res(body)))
)
const getJSON = url =>
httpGet(url)
.map(parse)
.chain(eitherToTask)
const parse = Either.try(JSON.parse)
const first = xs => Either.fromNullable(xs[0])
const eitherToTask = e => e.fold(Task.rejected, Task.of)
// Task -> Either -> Artist
const findArtist = name =>
getJSON(`https://api.spotify.com/v1/search?q=${name}&type=artist`)
.map(result => result.artists.items)
.map(first)
.map(eitherToTask)
// Task -> [Artist]
const relatedArtists = id =>
getJSON(`https://api.spotify.com/v1/artists/${id}/related-artists`).map(
result => result.artists
)
// #endregion
const argv = new Task((_, res) => res(process.argv))
const names = argv.map(args => args.slice(2))
const Intersection = xs => ({
xs,
concat: ({ xs: ys }) => Intersection(xs.filter(x => ys.some(y => x === y)))
})
const related = name =>
findArtist(name)
.map(artist => artist.id)
.chain(relatedArtists)
.map(artists => artists.map(artist => artist.name))
const artistIntersection = rels => rels.foldMap(Intersection).xs
const main = names =>
List(names)
.traverse(Task.of, related)
.map(artistIntersection)
names.chain(main).fork(console.error, console.log)