move everything to swagger client

This commit is contained in:
Todd Treece 2015-07-30 15:02:48 -04:00
parent 3e4ba4038d
commit db76ad4754

View file

@ -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);
};