move everything to swagger client
This commit is contained in:
parent
3e4ba4038d
commit
db76ad4754
1 changed files with 147 additions and 114 deletions
261
lib/api.js
261
lib/api.js
|
|
@ -1,12 +1,17 @@
|
|||
require('es6-shim');
|
||||
|
||||
/************************ DEPENDENCIES *****************************/
|
||||
var util = require('util'),
|
||||
OAuth = require('oauth'),
|
||||
bunyan = require('bunyan'),
|
||||
request = require('request');
|
||||
swagger = require('swagger-client');
|
||||
|
||||
var proto = API.prototype;
|
||||
exports = module.exports = API;
|
||||
|
||||
function handleError(reject, res) {
|
||||
reject(res.obj.message);
|
||||
};
|
||||
|
||||
/************************* CONSTRUCTOR ****************************/
|
||||
function API(config) {
|
||||
|
||||
|
|
@ -27,129 +32,157 @@ proto.username = false;
|
|||
proto.password = false;
|
||||
proto.access_token = false;
|
||||
proto.refresh_token = false;
|
||||
proto.api_url = 'https://api.npr.org/';
|
||||
proto.auth_endpoint = 'authorization/v2/authorize';
|
||||
proto.token_endpoint = 'authorization/v2/token';
|
||||
proto.recommendation_endpoint = 'listening/v2/recommendations';
|
||||
proto.api = false;
|
||||
proto.swagger_url = 'https://api.npr.org/documentation/beryllium/api-docs';
|
||||
|
||||
/***************************** AUTH *******************************/
|
||||
proto.authenticate = function(cb) {
|
||||
|
||||
this.getAccessToken()
|
||||
.then(cb)
|
||||
.catch(function(err) {
|
||||
this.log.error(err);
|
||||
cb();
|
||||
}.bind(this));
|
||||
|
||||
};
|
||||
|
||||
proto.getAccessToken = function() {
|
||||
proto.getClient = function() {
|
||||
|
||||
var self = this;
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
|
||||
if(self.access_token)
|
||||
return resolve(self.access_token);
|
||||
if(self.api)
|
||||
return resolve(self.api);
|
||||
|
||||
if(! self.client_id)
|
||||
return reject('OAuth Client ID not supplied');
|
||||
|
||||
if(! self.client_secret)
|
||||
return reject('OAuth Client Secret not supplied');
|
||||
|
||||
if(! self.username)
|
||||
return reject('NPR username not supplied');
|
||||
|
||||
if(! self.password)
|
||||
return reject('NPR password not supplied');
|
||||
|
||||
var oauth2 = new OAuth.OAuth2(
|
||||
self.client_id,
|
||||
self.client_secret,
|
||||
self.api_url,
|
||||
self.auth_endpoint,
|
||||
self.token_endpoint,
|
||||
{ 'User-Agent': 'Raspberry Pi'}
|
||||
);
|
||||
|
||||
var oauth_cb = function(err, access_token, refresh_token, results) {
|
||||
|
||||
if(err)
|
||||
return reject(err);
|
||||
|
||||
self.access_token = access_token;
|
||||
self.refresh_token = refresh_token;
|
||||
|
||||
self.log.debug('access token', self.access_token);
|
||||
self.log.debug('refresh token', self.refresh_token);
|
||||
self.log.debug('results', results);
|
||||
|
||||
return resolve(access_token);
|
||||
|
||||
};
|
||||
|
||||
var oauth_params = {
|
||||
grant_type: 'password',
|
||||
username: self.username,
|
||||
password: self.password
|
||||
};
|
||||
|
||||
oauth2.getOAuthAccessToken('', oauth_params, oauth_cb);
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
/*********************** RECOMMENDATIONS **************************/
|
||||
|
||||
proto.getRecommendations = function(channel) {
|
||||
|
||||
var self = this;
|
||||
|
||||
channel = channel || 'npr';
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
|
||||
if(! self.access_token)
|
||||
return reject('access token not available');
|
||||
|
||||
var options = {
|
||||
url: self.api_url + self.recommendation_endpoint,
|
||||
json: true,
|
||||
qs: {
|
||||
channel: channel
|
||||
},
|
||||
headers: {
|
||||
'User-Agent': 'Raspberry Pi',
|
||||
'Authorization': 'Bearer ' + self.access_token
|
||||
var api = new swagger({
|
||||
url: self.swagger_url,
|
||||
success: function() {
|
||||
self.api = api;
|
||||
resolve(self.api);
|
||||
}
|
||||
};
|
||||
|
||||
request(options, function(err, response, body) {
|
||||
|
||||
if(err)
|
||||
return reject(err);
|
||||
|
||||
if(response.statusCode !== 200)
|
||||
return reject(body);
|
||||
|
||||
var urls = body.items.map(function(item) {
|
||||
|
||||
return item.links.audio.map(function(a) {
|
||||
return a.href;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
urls = [].concat.apply([], urls);
|
||||
|
||||
resolve(urls);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
/***************************** AUTH *******************************/
|
||||
proto.getAccessToken = function() {
|
||||
|
||||
var self = this;
|
||||
|
||||
var promise = function() {
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
|
||||
if(self.access_token)
|
||||
return resolve(self.access_token);
|
||||
|
||||
if(! self.client_id)
|
||||
return reject('OAuth Client ID not supplied');
|
||||
|
||||
if(! self.client_secret)
|
||||
return reject('OAuth Client Secret not supplied');
|
||||
|
||||
if(! self.username)
|
||||
return reject('NPR username not supplied');
|
||||
|
||||
if(! self.password)
|
||||
return reject('NPR password not supplied');
|
||||
|
||||
var args = {
|
||||
client_id: self.client_id,
|
||||
client_secret: self.client_secret,
|
||||
grant_type: 'password',
|
||||
username: self.username,
|
||||
password: self.password
|
||||
};
|
||||
|
||||
self.api.authorization.createToken(args, function(res) {
|
||||
|
||||
self.access_token = res.obj.access_token;
|
||||
self.log.debug('access token', self.access_token);
|
||||
resolve(self.access_token);
|
||||
|
||||
}, handleError.bind(this, reject));
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
return this.getClient().then(promise);
|
||||
|
||||
};
|
||||
|
||||
/*********************** LISTENING **************************/
|
||||
proto.getRecommendation = function(channel) {
|
||||
|
||||
var promise = function(urls) {
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
|
||||
if(! urls || urls.length < 1)
|
||||
return reject('could not retrieve a recommendation');
|
||||
|
||||
resolve(urls[0]);
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
return this.getRecommendations(channel, 1).then(promise);
|
||||
|
||||
};
|
||||
|
||||
proto.getRecommendations = function(channel, limit) {
|
||||
|
||||
var self = this;
|
||||
|
||||
channel = channel || 'npr';
|
||||
limit = limit || 5;
|
||||
|
||||
var promise = function() {
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
|
||||
if(! self.api)
|
||||
return reject('API client not ready');
|
||||
|
||||
if(! self.access_token)
|
||||
return reject('missing access token');
|
||||
|
||||
var args = {
|
||||
Authorization: 'Bearer ' + self.access_token,
|
||||
channel: channel
|
||||
};
|
||||
|
||||
self.api.listening.getRecommendations(args, function(res) {
|
||||
|
||||
if(! res.obj.items || res.obj.items.length < 1)
|
||||
return reject('unable to retrieve recommendations');
|
||||
|
||||
var urls = res.obj.items.map(function(item) {
|
||||
|
||||
// try aac
|
||||
var audio = item.links.audio.find(function(a) {
|
||||
return a['content-type'] == 'audio/aac';
|
||||
});
|
||||
|
||||
// try mp3 as backup
|
||||
if(! audio) {
|
||||
audio = item.links.audio.find(function(a) {
|
||||
return a['content-type'] == 'audio/mp3';
|
||||
});
|
||||
}
|
||||
|
||||
return audio.href;
|
||||
|
||||
});
|
||||
|
||||
if(urls.length < 1)
|
||||
return reject('unable to retrieve recommendations');
|
||||
|
||||
urls = urls.slice(0, limit);
|
||||
|
||||
resolve(urls);
|
||||
|
||||
}, handleError.bind(this, reject));
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
return this.getAccessToken().then(promise);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue