Skip to content

Commit

Permalink
fixes problem with spotify search
Browse files Browse the repository at this point in the history
spotify search requires auth since ~30-05-2017
adds better error handling / error messages
adds progress indicator for search requests on TTY
increases wait time for search requests to reduce failed requests due
to rate limits
  • Loading branch information
crohrer committed Jun 9, 2017
1 parent 6d3e38f commit 86dce02
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 14 deletions.
10 changes: 7 additions & 3 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,15 @@ function start(){
spotifyPlaylist.getAllTracks(playlistName)
.then(() => radioCrawler.getTracks(playlistName))
.then(radioTracks => radioCrawler.cleanTracks(radioTracks))
.then(cleanedTracks => spotifySearch.searchTracks(cleanedTracks))
.then(cleanedTracks => spotifySearch.searchTracks(cleanedTracks, playlistName))
.then(newTracks => spotifyPlaylist.addTracks(playlistName, newTracks))
.then(process.exit)
.catch(() => {
logger.log('exited due to error.', playlistName);
.catch((error) => {
let message = 'Unknown Error';
if(typeof error === 'string'){
message = error;
}
logger.log('exited due to error: ' + message, playlistName);
process.exit();
});
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "spotifyRadioPlaylist",
"version": "2.5.3",
"version": "2.5.4",
"license": "MIT",
"repository": {
"type": "git",
Expand Down
62 changes: 52 additions & 10 deletions spotifySearch.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,29 @@
var https = require('https');
var logger = require('./logger');
var spotifyHelper = require('./spotifyHelper');
var spotifyOAuth = require('./spotifyOAuth');
var Promise = require('bluebird');

/**
* searchTracks
* @param {Array} tracks
* @param {String} playlistName
* @returns {Promise}
*/
function searchTracks(tracks){
function searchTracks(tracks, playlistName){
var searchRequests = [];

console.log('Searching spotify for '+tracks.length+' tracks');
tracks.forEach(function(track, i){
searchRequests.push(sendSearchRequest(track, i * 100)); // timeout so we don't run into limits that fast
searchRequests.push(sendSearchRequest(track, i * 150, playlistName)); // timeout so we don't run into limits that fast
});
return Promise.all(searchRequests).then(results => results.filter(result => typeof result === 'string'));
return Promise.all(searchRequests)
.then(results => {
if(process.stdout.isTTY){
process.stdout.write('\n');
}
return results.filter(result => typeof result === 'string');
});
}

/**
Expand All @@ -28,24 +36,40 @@ function searchTracks(tracks){
* @param {string} track.artist in UPPERCASE
* @param {string} track.title in UPPERCASE,
* @param {int} [timeOut] waits for this time (ms) so we don't run into limits that fast
* @param {string} playlistName
* @returns {Promise}
*/
function sendSearchRequest(track, timeOut){
function sendSearchRequest(track, timeOut, playlistName){
var time = timeOut || 0;
return new Promise((resolve) => {
setTimeout(() => makeRequest(resolve), time);
return new Promise((resolve, reject) => {
setTimeout(() => makeRequest(resolve, reject), time);
});

/**
* @param {function} resolve Callback to resolve promise
* @param {function} reject
*/
function makeRequest(resolve){
function makeRequest(resolve, reject){
let accessToken = spotifyOAuth.getAccessToken();

if(accessToken === false || accessToken === ''){
return reject('no access token found');
}

var spotifySearchReq = https.request({
hostname: "api.spotify.com",
path: "/v1/search?type=track&q=artist:"+encodeURIComponent(track.artist+' ')+'track:'+encodeURIComponent(track.title)
path: "/v1/search?type=track&q=artist:"+encodeURIComponent(track.artist+' ')+'track:'+encodeURIComponent(track.title),
method: 'GET',
headers: {
'Authorization': 'Bearer '+ accessToken,
'Accept': 'application/json'
}
}, function(res){
spotifyHelper.checkForRateLimit(res, 'searching track', () => sendSearchRequest(track))
.then(() => {
spotifyHelper.checkForRateLimit(res, 'searching track', () => sendSearchRequest(track, 0, playlistName))
.then((rateLimitPromise) => {
if(rateLimitPromise){
return rateLimitPromise;
}
var jsonResponse = '';
res.on('data', function(chunk){
jsonResponse += chunk;
Expand All @@ -54,10 +78,27 @@ function sendSearchRequest(track, timeOut){
var spotifyPlaylist = require('./spotifyPlaylist'),
result = JSON.parse(jsonResponse);

if(result.error && result.error.status === 429){
return resolve(); // rateLimit is exceeded - this is already handled above by spotifyHelper
}

if(result.error){
let message = result.error.message || 'Unknown error while searching';
if(process.stdout.isTTY){
process.stdout.write('\n');
}
logger.log('Error searching for "'+ track.artist + ' - ' + track.title + '": ' + message, playlistName);
return resolve();
}

if(!result.tracks || !result.tracks.items) {
return resolve();
}

if(process.stdout.isTTY){
process.stdout.write('.');
}

result.tracks.items.some(function(item){ // iterate all items and break on success (return true)
var titleMatches = cleanString(item.name.toUpperCase()) === cleanString(track.title),
isAlreadyInPlaylist = spotifyPlaylist.tracks.indexOf(item.uri) > -1,
Expand All @@ -75,6 +116,7 @@ function sendSearchRequest(track, timeOut){
}

resolve(encodeURIComponent(item.uri));
return true;
});

resolve();
Expand Down

0 comments on commit 86dce02

Please sign in to comment.