Refactor more, fix and design 404

This commit is contained in:
Jonathan Cremin 2015-08-21 18:33:50 +01:00
parent 7de374e00b
commit 8521baa6d9
11 changed files with 223 additions and 138 deletions

View file

@ -4,10 +4,13 @@ import request from 'superagent';
import 'superagent-bluebird-promise';
import { match as urlMatch } from './url';
export let id = "xbox";
import debuglog from 'debug';
const debug = debuglog('match.audio:xbox');
export let id = 'xbox';
if (!process.env.XBOX_CLIENT_ID || !process.env.XBOX_CLIENT_SECRET) {
console.warn("XBOX_CLIENT_ID and XBOX_CLIENT_SECRET environment variables not found, deactivating Xbox Music.");
console.warn('XBOX_CLIENT_ID and XBOX_CLIENT_SECRET environment variables not found, deactivating Xbox Music.');
}
const credentials = {
@ -15,12 +18,12 @@ const credentials = {
clientSecret: process.env.XBOX_CLIENT_SECRET
};
const apiRoot = "https://music.xboxlive.com/1/content";
const apiRoot = 'https://music.xboxlive.com/1/content';
function* getAccessToken() {
const authUrl = "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13";
const scope = "http://music.xboxlive.com";
const grantType = "client_credentials";
const authUrl = 'https://datamarket.accesscontrol.windows.net/v2/OAuth2-13';
const scope = 'http://music.xboxlive.com';
const grantType = 'client_credentials';
const data = {
client_id: credentials.clientId,
@ -28,7 +31,7 @@ function* getAccessToken() {
scope: scope,
grant_type: grantType
};
const result = yield request.post(authUrl).send(data).set('Content-type', 'application/x-www-form-urlencoded').promise();
const result = yield request.post(authUrl).timeout(10000).send(data).set('Content-type', 'application/x-www-form-urlencoded').promise();
return result.body.access_token;
}
@ -39,16 +42,16 @@ function formatResponse(res) {
} else {
result = res.body.Albums.Items[0];
}
let item = {
service: "xbox",
type: res.body.Tracks ? "track" : "album",
const item = {
service: 'xbox',
type: res.body.Tracks ? 'track' : 'album',
id: result.Id,
name: result.Name,
streamUrl: result.Link,
purchaseUrl: null,
artwork: {
small: result.ImageUrl.replace("http://", "https://") + "&w=250&h=250",
large: result.ImageUrl.replace("http://", "https://") + "&w=500&h=250"
small: result.ImageUrl.replace('http://', 'https://') + '&w=250&h=250',
large: result.ImageUrl.replace('http://', 'https://') + '&w=500&h=250'
},
artist: {
name: result.Artists[0].Artist.Name
@ -60,43 +63,60 @@ function formatResponse(res) {
return item;
}
function* apiCall(path) {
const access_token = yield getAccessToken();
return request.get(apiRoot + path).timeout(10000).set('Authorization', 'Bearer ' + access_token).promise();
}
export const match = urlMatch;
export function* parseUrl(url) {
const parsed = parse(url);
const parts = parsed.path.split("/");
const parts = parsed.path.split('/');
const type = parts[1];
const idMatches = parts[4].match(/[\w\-]+/);
const id = idMatches[0];
if (!id) {
return false;
}
return yield lookupId("music." + id, type);
return yield lookupId('music.' + id, type);
}
export function* lookupId(id, type) {
const access_token = yield getAccessToken();
const path = "/" + id + "/lookup";
const result = yield request.get(apiRoot + path).set("Authorization", "Bearer " + access_token).promise();
return result ? formatResponse(result) : {service: "xbox"};
const path = '/' + id + '/lookup';
try {
const result = yield apiCall(path);
return formatResponse(result);
} catch (e) {
if (e.status !== 404) {
debug(e.body);
}
return {service: 'xbox'};
}
};
export function* search(data) {
var cleanParam = function(str) {
return str.replace(/[\:\?\&]+/, "");
return str.replace(/[\:\?\&\(\)\[\]]+/g, '');
}
let query, album;
const type = data.type;
if (type == "album") {
query = cleanParam(data.artist.name.substring(0, data.artist.name.indexOf('&'))) + " " + cleanParam(data.name);
if (type == 'album') {
query = cleanParam(data.artist.name.substring(0, data.artist.name.indexOf('&'))) + ' ' + cleanParam(data.name);
album = data.name;
} else if (type == "track") {
query = cleanParam(data.artist.name.substring(0, data.artist.name.indexOf('&'))) + " " + cleanParam(data.name);
} else if (type == 'track') {
query = cleanParam(data.artist.name.substring(0, data.artist.name.indexOf('&'))) + ' ' + cleanParam(data.name);
album = data.album.name
}
const access_token = yield getAccessToken();
const path = "/music/search?q=" + encodeURIComponent(query) + "&filters=" + type + "s";
const result = yield request.get(apiRoot + path).set("Authorization", "Bearer " + access_token).promise()
return result ? formatResponse(result) : {service: "xbox"};
const path = '/music/search?q=' + encodeURIComponent(query) + '&filters=' + type + 's';
try {
const result = yield apiCall(path);
return formatResponse(result);
} catch (e) {
if (e.status !== 404) {
debug(e.body);
}
return {service: 'xbox'};
}
};

View file

@ -6,6 +6,6 @@ export function* match(url, type) {
return false;
}
const parts = parsed.path.split("/");
return (parts[1] == "album" || parts[1] == "track") && parts[4];
const parts = parsed.path.split('/');
return (parts[1] == 'album' || parts[1] == 'track') && parts[4];
};

View file

@ -7,9 +7,9 @@ const credentials = {
key: process.env.YOUTUBE_KEY,
};
const apiRoot = "https://www.googleapis.com/freebase/v1/topic";
const apiRoot = 'https://www.googleapis.com/freebase/v1/topic';
export function* get(topic) {
const result = yield request.get(apiRoot + topic + "?key=" + credentials.key).promise();
const result = yield request.get(apiRoot + topic + '?key=' + credentials.key).promise();
return result.body;
}

View file

@ -6,6 +6,9 @@ import 'superagent-bluebird-promise';
import { match as urlMatch } from './url';
import freebase from './freebase';
import debuglog from 'debug';
const debug = debuglog('match.audio:youtube');
module.exports.id = 'youtube';
if (!process.env.YOUTUBE_KEY) {
@ -37,55 +40,58 @@ export function parseUrl(url) {
export function* lookupId(id, type) {
const path = '/videos?part=snippet%2CtopicDetails%2CcontentDetails&id=' + id + '&key=' + credentials.key;
const result = yield request.get(apiRoot + path).promise();
const item = res.body.items[0];
if (!item.topicDetails.topicIds) {
return {service: 'youtube'};
}
const promises = [];
const match = {
id: id,
service: 'youtube',
name: item.snippet.title,
type: 'track',
album: {name: ''},
streamUrl: 'https://youtu.be/' + id,
purchaseUrl: null,
artwork: {
small: item.snippet.thumbnails.medium.url,
large: item.snippet.thumbnails.high.url,
try {
const result = yield request.get(apiRoot + path).promise();
const item = result.body.items[0];
if (!item.topicDetails.topicIds) {
return {service: 'youtube'};
}
};
for (let topic of yield freebase.get(topicId)) {
const musicalArtist = topic.property['/type/object/type'].values.some((value) => {
return value.text == 'Musical Artist';
});
const musicalRecording = topic.property['/type/object/type'].values.some(function(value) {
return value.text == 'Musical Recording';
});
const musicalAlbum = topic.property['/type/object/type'].values.some(function(value) {
return value.text == 'Musical Album';
})
if (musicalArtist) {
match.artist = {name: topic.property['/type/object/name'].values[0].text};
} else if (musicalRecording) {
match.name = topic.property['/type/object/name'].values[0].text;
if (topic.property['/music/recording/releases']) {
match.type = 'album';
match.album.name = topic.property['/music/recording/releases'].values[0].text;
const match = {
id: id,
service: 'youtube',
name: item.snippet.title,
type: 'track',
album: {name: ''},
streamUrl: 'https://youtu.be/' + id,
purchaseUrl: null,
artwork: {
small: item.snippet.thumbnails.medium.url,
large: item.snippet.thumbnails.high.url,
}
};
for (let topic of yield freebase.get(topicId)) {
const musicalArtist = topic.property['/type/object/type'].values.some((value) => {
return value.text == 'Musical Artist';
});
const musicalRecording = topic.property['/type/object/type'].values.some(function(value) {
return value.text == 'Musical Recording';
});
const musicalAlbum = topic.property['/type/object/type'].values.some(function(value) {
return value.text == 'Musical Album';
})
if (musicalArtist) {
match.artist = {name: topic.property['/type/object/name'].values[0].text};
} else if (musicalRecording) {
match.name = topic.property['/type/object/name'].values[0].text;
if (topic.property['/music/recording/releases']) {
match.type = 'album';
match.album.name = topic.property['/music/recording/releases'].values[0].text;
}
} else if (musicalAlbum) {
match.name = topic.property['/type/object/name'].values[0].text;
match.type = 'album';
}
} else if (musicalAlbum) {
match.name = topic.property['/type/object/name'].values[0].text;
match.type = 'album';
}
return match;
} catch (e) {
debug(e.body);
return {'service': 'youtube'};
}
return match;
};
export function* search(data) {
@ -101,7 +107,6 @@ export function* search(data) {
}
const path = '/search?part=snippet&q=' + encodeURIComponent(query) + '&type=video&videoCaption=any&videoCategoryId=10&key=' + credentials.key;
const result = yield request.get(apiRoot + path).promise();
const item = result.body.items[0];