-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspotify.js
334 lines (250 loc) · 10.4 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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
//liberries
//loading the spotify wrapper
var SpotifyWebApi = require('spotify-web-api-node');
//file reading
var fs = require("fs");
//removeAccents
var removeAccents = require("remove-accents")
/*****************************
This "class" handles getting the spotify account set up,
and getting the song information for a given playlist
*****************************/
"use strict";
// the "class" itself
//base class, no extends
class HandleSpotify{
//constructor is literally named constructor for some reason
constructor() {
//variables
this.scopes = ['user-read-private', 'user-read-email'],
this.redirectUri = 'http://localhost:8888/callback',
this.clientId = '5ddacffa892542a08bd9927c226dad43',
this.clientSecret = '45b90caa6aae43ddbd969bdc3982f5b4',
this.state = 'some-state-of-my-choice',
this.accessCode = '',
this.refreshCode = '';
//credentials for creation
this.credentials = {
clientId : this.clientId,
clientSecret : this.clientSecret,
redirectUri : this.redirectUri
}
//temp code that was returned
this.code = ''
// creating the wrapper app
this.spotifyApi = new SpotifyWebApi(this.credentials);
}
//checking if the data file for spotify cred info exists
checkSpotifyDataFile(callback) {
//checking file exists
fs.existsSync('spotifyData.json') ? this.loadSpotifyData(callback) : this.createSpotifyData()
}
//for when running for the first time
//creating spotify data
createSpotifyData() {
//get and print the url
// Create the authorization URL
this.authorizeURL = this.spotifyApi.createAuthorizeURL(scopes, state);
//console log url
console.log("The authorization URL is: \n")
console.log(authorizeURL)
console.log("\n")
//starting the server
this.server = http.createServer(function(request, response) {
//responding on the page
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Thanks for authorizing, James!");
//parsing the request url to get the code
//getting the url from request
//getting query from url
this.queryData = url.parse(request.url, true).query;
//getting code data from queryData
code = queryData.code
// console.log("\n\n" + code + "\n\n" )
//need to get access and refresh codes with our new code
// Retrieve an access token and a refresh token
this.spotifyApi.authorizationCodeGrant(code)
.then(function(data) {
// console.log('The token expires in ' + data.body['expires_in']);
// console.log('The access token is ' + data.body['access_token']);
// console.log('The refresh token is ' + data.body['refresh_token']);
// Set the access token on the API object to use it in later calls
this.spotifyApi.setAccessToken(data.body['access_token']);
this.spotifyApi.setRefreshToken(data.body['refresh_token']);
//storing access and refresh codes
this.accessCode = data.body['access_token']
this.refreshCode = data.body['refresh_token']
//writing to file
//storing in JSON
this.dataObject = JSON.stringify({accessCode : accessCode, refreshCode : refreshCode})
fs.writeFile( "spotifyData.json", dataObject, "utf8", function(err) {
if (!err) {
console.log("\nSaved successfully\n")
} else {
console.log("\nNot saved successfully!\n")
}
//shutting down either way
// Shutting down! run again
server.shutdown(function() {
console.log('Everything is cleanly shutdown.');
console.log("Run again!")
});
} );
}.bind(this), function(err) {
console.log('Something went wrong!', err);
});
response.end();
//and close the server either way
// server.close()
})
//for shutting down
server = require('http-shutdown')(server);
//listening server
server.listen(8888)
}
//if it's already been run, load the data from the file
loadSpotifyData(callback) {
// reading the saved spotify data
this.spotData = require("./spotifyData.json");
//data is already parsed
//read and store
this.accessCode = this.spotData.accessCode
this.refreshCode = this.spotData.refreshCode
//set
this.spotifyApi.setAccessToken(this.accessCode);
this.spotifyApi.setRefreshToken(this.refreshCode);
//refreshing codes
// clientId, clientSecret and refreshToken has been set on the api object previous to this call.
this.spotifyApi.refreshAccessToken()
.then(function(data) {
console.log('The access token has been refreshed!');
// Save the access token so that it's used in future calls
this.spotifyApi.setAccessToken(data.body['access_token']);
//callback
callback && callback()
}.bind(this), function(err) {
console.log('Could not refresh access token', err);
});
}
//this function handles paging through all of the spotify api returns with 100 songs each
getSongsHandler(tracksObj, user, id, index, max, callback, callbackFailure) {
// Get tracks in a playlist from the index
this.spotifyApi.getPlaylistTracks(user, id, { 'offset' : index, 'fields' : 'items' })
.then(function(data) {
//push array to tracksObj
for (let song of data.body.items) {
tracksObj.push(song)
}
//return through callback if index >= max
if (index >= max) {
callback && callback(tracksObj)
} else {
//if the index < max there's still songs
//increment index and call function song
index += 100
//call this function again
this.getSongsHandler(tracksObj, user, id, index, max, callback, callbackFailure)
}
}.bind(this), function(err) {
console.log('Something went wrong! in getSongsHandler', err);
//callback failure
//if no playlist edm for some reason
//unncomment
callbackFailure && callbackFailure(err)
});
}
//processing converting all the song objects to the string to search deezer with
handleSongStrings(tracksObj) {
//variables
//array of songs + artists
this.songsArr = []
for (var i = 0; i < tracksObj.length; i++) {
// console.log(tracksObj[i])
var tempSearchName = ""
//getting the two artist names
//storing temporarily
var tempArtistName = "";
//need to loop through them
for (let iter of tracksObj[i].track.artists) {
tempArtistName = tempArtistName.concat(iter.name + " ")
}
//temp edited name to remove unicode characters
var tempEditedName = tracksObj[i].track.name + " " + tempArtistName
tempEditedName = tempEditedName.replace(/["“‘”’’]/g, "'");
tempEditedName = removeAccents.remove(tempEditedName)
console.log(tempEditedName)
//temp object that holds both normal song name and edited song name
var tempObj = {rawSongName: tracksObj[i].track.name, editedSongName: tempEditedName}
//pushing to songsArr
this.songsArr.push(tempObj)
}
return this.songsArr;
}
//get playlist specified in argument from user
getPlaylist(user, playlistName, callback) {
//variables for this function
//id of the playlist
this.playlistID;
//how many songs there are, to page through them
this.songCount;
//the raw objects of individual tracks from the playlist
this.trackObjects = [];
// Get my playlists user jolaroux
this.spotifyApi.getUserPlaylists(user)
.then(function(data) {
// console.log('Retrieved playlists', data.body.items);
// console.log(data.body.items.length)
//get ID of playlist EDM
for (let playlist of data.body.items) {
//if it's the right playlist
if (playlist.name == playlistName) {
//have the id of playlist now
this.playlistID = playlist.id
//have song count too
this.songCount = playlist.tracks.total
console.log(this.songCount + " songs in playlist " + playlistName)
}
}
//getting tracks in playlist
//need to loop through songCount and call get100Songs until the playlist empty
this.index = 0;
//storing the song objects strings of song + artist
this.songObjects = [];
//tracksObj, user, id, index, max, callback, callbackFailure
this.getSongsHandler(this.trackObjects, user, this.playlistID, this.index, this.songCount,
//callback success
function(trackObjects) {
//formatting the strings to search deezer
this.songObjects = this.handleSongStrings(trackObjects)
//printing for now
// for (let o of songObjects) {
// console.log(o)
// }
this.writeTo(this.songObjects, './spotifySongs.json')
//pass back through callback
callback && callback(this.songObjects)
}.bind(this),
//callback failure
function (err) {
console.log(err)
}
)
}.bind(this),function(err) {
console.log('Something went wrong!', err);
//callback failure
//if no playlist edm for some reason
//unncomment
callbackFailure && callbackFailure()
});
}
//writes array to file sent
writeTo(arr, file) {
fs.writeFile(file, JSON.stringify(arr), 'utf8', function(err) {
if (err) {
console.log(err)
}
})
}
}
//exporting?
module.exports = HandleSpotify