-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathspotify.js
123 lines (105 loc) · 3.25 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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
const SpotifyWebApi = require('spotify-web-api-node');
const highland = require('highland');
const { debug, error } = require('./log');
let api = null;
function login(clientId, clientSecret, { logger } = {}) {
return new Promise(function (resolve, reject) {
if (!!api) {
resolve(api);
return;
}
debug(logger, `Spotify login`);
api = new SpotifyWebApi({ clientId, clientSecret });
debug(logger, 'Granting credentials...');
// Retrieve an access token.
api.clientCredentialsGrant().then(
function (data) {
// Save the access token so that it's used in future calls
api.setAccessToken(data.body['access_token']);
debug(logger, 'Spotify login successful');
resolve(api);
},
function (err) {
error(
logger,
`Something went wrong when retrieving an access token: ${err.message}`
);
debug(logger, `Stack trace:\n${err.stack}`);
reject(err);
}
);
});
}
function getTrack(trackId, { logger } = {}) {
debug(logger, `Fetch track: ${trackId}`);
return api.getTrack(trackId).then(trackResponse => {
const track = trackResponse.body;
debug(logger, `Success: ${track.name}`);
return track;
});
}
function getPlaylist(playlistId, { logger } = {}) {
debug(logger, `Fetch playlist: ${playlistId}`);
return api.getPlaylist(playlistId).then(playlistResponse => {
const playlist = playlistResponse.body;
debug(logger, `Success: ${playlist.name}`);
return playlist;
});
}
function getAllUserPlaylists(username, { logger } = {}) {
debug(logger, `Fetching playlists of ${username}`);
return createPaginationStream(
function getPlaylistTracks(options) {
return api.getUserPlaylists(username, options);
},
{ logger }
);
}
function getAllPlaylistTracks(playlistId, { logger } = {}) {
debug(logger, `Fetching playlist tracks (${playlistId})`);
return createPaginationStream(
function getPlaylistTracks(options) {
return api.getPlaylistTracks(playlistId, options);
},
{ logger }
);
}
function createPaginationStream(endpointFn, { logger } = {}) {
let offset = 0;
let limit = 20;
let totalItemsCount = undefined;
let loadedItemsCount = 0;
return highland(function (push, next) {
if (loadedItemsCount === 0)
debug(logger, `Fetch paginated: "${endpointFn.name}"`);
debug(logger, `Fetch paginated: loading ${offset}..${offset + limit}`);
endpointFn({ limit, offset })
.then(data => {
offset += limit;
totalItemsCount = data.body.total;
loadedItemsCount += data.body.items.length;
debug(
logger,
`Fetch paginated: loaded ${loadedItemsCount}/${totalItemsCount}`
);
debug(logger, `Fetch paginated: pushing down the stream`);
// put the items down to the stream
push(null, data.body.items);
if (loadedItemsCount >= totalItemsCount) {
debug(logger, `Fetch paginated: all finish`);
push(null, highland.nil);
} else {
debug(logger, `Fetch paginated: next page`);
next();
}
})
.catch(err => push(err));
});
}
module.exports = {
login,
getTrack,
getPlaylist,
getAllUserPlaylists,
getAllPlaylistTracks,
};