Finally finished giant ES6 refactor
This commit is contained in:
parent
c6d48cc424
commit
03e2666958
39 changed files with 553 additions and 635 deletions
|
@ -4,25 +4,19 @@ import fs from 'fs';
|
|||
var services = [];
|
||||
|
||||
fs.readdirSync(path.join(__dirname, 'services')).forEach(function(file) {
|
||||
var service = require(path.join(__dirname, 'services', file));
|
||||
const service = require(path.join(__dirname, 'services', file));
|
||||
if (service.search) {
|
||||
services.push(service);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = function(url) {
|
||||
|
||||
var matchedService;
|
||||
services.some(function(service) {
|
||||
matchedService = service.match(url) ? service : null;
|
||||
return matchedService;
|
||||
});
|
||||
|
||||
if (matchedService) {
|
||||
return matchedService.parseUrl(url).timeout(10000).then(function(result) {
|
||||
return matchedService.lookupId(result.id, result.type).then(function(item) {
|
||||
return item;
|
||||
});
|
||||
});
|
||||
export default function* (url) {
|
||||
let matchedService;
|
||||
for (let service of services) {
|
||||
matchedService = yield service.match(url);
|
||||
if (matchedService) {
|
||||
const result = yield service.parseUrl(url);
|
||||
return yield service.lookupId(result.id, result.type);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
|
||||
module.exports = [];
|
||||
const services = [];
|
||||
|
||||
fs.readdirSync(path.join(__dirname, 'services')).forEach(function(file) {
|
||||
var service = require(path.join(__dirname, 'services', file));
|
||||
if (service.search) {
|
||||
module.exports.push(service);
|
||||
services.push(service);
|
||||
}
|
||||
});
|
||||
|
||||
export default services;
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
import {parse} from 'url';
|
||||
import { parse } from 'url';
|
||||
import request from 'superagent';
|
||||
import 'superagent-bluebird-promise';
|
||||
import { match as urlMatch } from './url';
|
||||
|
||||
module.exports.id = 'deezer';
|
||||
export let id = 'deezer';
|
||||
|
||||
const apiRoot = 'https://api.deezer.com';
|
||||
|
||||
module.exports.match = require('./url').match;
|
||||
export const match = urlMatch;
|
||||
|
||||
module.exports.parseUrl = function(url) {
|
||||
export function parseUrl(url) {
|
||||
let matches = parse(url).path.match(/\/(album|track)[\/]+([^\/]+)/);
|
||||
|
||||
if (matches && matches[2]) {
|
||||
|
@ -18,7 +19,7 @@ module.exports.parseUrl = function(url) {
|
|||
}
|
||||
};
|
||||
|
||||
module.exports.lookupId = function* (id, type) {
|
||||
export function* lookupId(id, type) {
|
||||
let path = '/' + type + '/' + id;
|
||||
|
||||
let {body} = yield request.get(apiRoot + path).promise();
|
||||
|
@ -74,7 +75,7 @@ module.exports.lookupId = function* (id, type) {
|
|||
}
|
||||
};
|
||||
|
||||
module.exports.search = function* (data) {
|
||||
export function* search(data) {
|
||||
let cleanParam = function(str) {
|
||||
return str.replace(/[\:\?\&]+/, '');
|
||||
};
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
"use strict";
|
||||
var parse = require('url').parse;
|
||||
import { parse } from 'url';
|
||||
|
||||
module.exports.match = function(url) {
|
||||
var parsed = parse(url);
|
||||
export function* match(url) {
|
||||
const parsed = parse(url);
|
||||
if (!parsed.host.match(/deezer\.com$/)) {
|
||||
return false;
|
||||
}
|
||||
var matches = parsed.path.match(/\/(album|track)[\/]+([^\/]+)/);
|
||||
const matches = parsed.path.match(/\/(album|track)[\/]+([^\/]+)/);
|
||||
return matches.length > 1;
|
||||
};
|
||||
|
|
|
@ -1,148 +1,135 @@
|
|||
"use strict";
|
||||
import { parse } from 'url';
|
||||
import bluebird from 'bluebird';
|
||||
import PlayMusic from 'playmusic';
|
||||
import { match as urlMatch } from './url';
|
||||
|
||||
var parse = require("url").parse;
|
||||
var Promise = require("bluebird");
|
||||
var PlayMusic = require("playmusic");
|
||||
var pm = Promise.promisifyAll(new PlayMusic());
|
||||
const pm = bluebird.promisifyAll(new PlayMusic());
|
||||
|
||||
module.exports.id = "google";
|
||||
export let id = 'google';
|
||||
|
||||
if (!process.env.GOOGLE_EMAIL || !process.env.GOOGLE_PASSWORD) {
|
||||
console.warn("GOOGLE_EMAIL or GOOGLE_PASSWORD environment variables not found, deactivating Google Play Music.");
|
||||
console.warn('GOOGLE_EMAIL or GOOGLE_PASSWORD environment variables not found, deactivating Google Play Music.');
|
||||
}
|
||||
|
||||
var ready = pm.initAsync({email: process.env.GOOGLE_EMAIL, password: process.env.GOOGLE_PASSWORD}).catch(function(err) {
|
||||
let ready = pm.initAsync({email: process.env.GOOGLE_EMAIL, password: process.env.GOOGLE_PASSWORD}).catch(function(err) {
|
||||
console.log(err);
|
||||
});
|
||||
|
||||
module.exports.match = require("./url").match;
|
||||
export const match = urlMatch;
|
||||
|
||||
module.exports.parseUrl = function(url) {
|
||||
return ready.then(function() {
|
||||
var parsed = parse(url.replace(/\+/g, "%20"));
|
||||
var path = parsed.path;
|
||||
var hash = parsed.hash;
|
||||
if (hash) {
|
||||
var parts = hash.split("/");
|
||||
var type = parts[1];
|
||||
var id = parts[2];
|
||||
var artist = decodeURIComponent(parts[3]);
|
||||
var album = decodeURIComponent(parts[4]);
|
||||
export function* parseUrl(url) {
|
||||
yield ready;
|
||||
const parsed = parse(url.replace(/\+/g, '%20'));
|
||||
const path = parsed.path;
|
||||
const hash = parsed.hash;
|
||||
if (hash) {
|
||||
const parts = hash.split('/');
|
||||
const type = parts[1];
|
||||
const id = parts[2];
|
||||
const artist = decodeURIComponent(parts[3]);
|
||||
const album = decodeURIComponent(parts[4]);
|
||||
|
||||
if (type !== "album" && type !== "track") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (id.length > 0) {
|
||||
return {id: id, type: type};
|
||||
} else {
|
||||
return module.exports.search({type: type, name: album, artist: {name: artist}});
|
||||
}
|
||||
} else if(path) {
|
||||
var matches = path.match(/\/music\/m\/([\w]+)/);
|
||||
type = matches[1][0] === "T" ? "track" : "album";
|
||||
return module.exports.lookupId(matches[1], type);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.lookupId = function(id, type) {
|
||||
return ready.then(function() {
|
||||
if (type === "album") {
|
||||
return pm.getAlbumAsync(id, false).then(function(album) {
|
||||
return {
|
||||
service: "google",
|
||||
type: "album",
|
||||
id: album.albumId,
|
||||
name: album.name,
|
||||
streamUrl: "https://play.google.com/music/m/" + album.albumId + "?signup_if_needed=1",
|
||||
purchaseUrl: "https://play.google.com/store/music/album?id=" + album.albumId,
|
||||
artwork: {
|
||||
small: album.albumArtRef.replace("http:", "https:"),
|
||||
large: album.albumArtRef.replace("http:", "https:")
|
||||
},
|
||||
artist: {
|
||||
name: album.artist
|
||||
}
|
||||
};
|
||||
}, function(error) {
|
||||
throw error;
|
||||
});
|
||||
} else if (type === "track") {
|
||||
return pm.getAllAccessTrackAsync(id).then(function(track) {
|
||||
return {
|
||||
service: "google",
|
||||
type: "track",
|
||||
id: track.nid,
|
||||
name: track.title,
|
||||
streamUrl: "https://play.google.com/music/m/" + track.nid + "?signup_if_needed=1",
|
||||
purchaseUrl: "https://play.google.com/store/music/album?id=" + track.albumId,
|
||||
artwork: {
|
||||
small: track.albumArtRef[0].url.replace("http:", "https:"),
|
||||
large: track.albumArtRef[0].url.replace("http:", "https:")
|
||||
},
|
||||
album: {
|
||||
name: track.album
|
||||
},
|
||||
artist: {
|
||||
name: track.artist
|
||||
}
|
||||
};
|
||||
}, function(error) {
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.search = function(data) {
|
||||
return ready.then(function() {
|
||||
var query, album;
|
||||
var type = data.type;
|
||||
|
||||
if (type === "album") {
|
||||
query = data.artist.name + " " + data.name;
|
||||
album = data.name;
|
||||
} else if (type === "track") {
|
||||
query = data.artist.name + " " + data.album.name + " " + data.name;
|
||||
album = data.album.name;
|
||||
if (type !== 'album' && type !== 'track') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return pm.searchAsync(query, 5).then(function(result) {
|
||||
|
||||
if (!result.entries) {
|
||||
var matches = album.match(/^[^\(\[]+/);
|
||||
if (matches && matches[0] && matches[0] !== album) {
|
||||
var cleanedData = JSON.parse(JSON.stringify(data));
|
||||
if (type === "album") {
|
||||
cleanedData.name = matches[0].trim();
|
||||
} else if (type === "track") {
|
||||
cleanedData.album.name = matches[0].trim();
|
||||
}
|
||||
return module.exports.search(cleanedData);
|
||||
} else {
|
||||
return {service: "google"};
|
||||
}
|
||||
}
|
||||
result = result.entries.filter(function(entry) {
|
||||
return entry[type];
|
||||
}).sort(function(a, b) { // sort by match score
|
||||
return a.score < b.score;
|
||||
}).shift();
|
||||
|
||||
if (!result) {
|
||||
return {service: "google"};
|
||||
} else {
|
||||
var id;
|
||||
if (type === "album") {
|
||||
id = result.album.albumId;
|
||||
} else if (type === "track") {
|
||||
id = result.track.nid;
|
||||
}
|
||||
|
||||
return module.exports.lookupId(id, type);
|
||||
}
|
||||
});
|
||||
});
|
||||
if (id.length > 0) {
|
||||
return {id: id, type: type};
|
||||
} else {
|
||||
return yield search({type: type, name: album, artist: {name: artist}});
|
||||
}
|
||||
} else if(path) {
|
||||
const matches = path.match(/\/music\/m\/([\w]+)/);
|
||||
const type = matches[1][0] === 'T' ? 'track' : 'album';
|
||||
return yield lookupId(matches[1], type);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export function* lookupId(id, type) {
|
||||
yield ready;
|
||||
if (type === 'album') {
|
||||
const album = yield pm.getAlbumAsync(id, false);
|
||||
return {
|
||||
service: 'google',
|
||||
type: 'album',
|
||||
id: album.albumId,
|
||||
name: album.name,
|
||||
streamUrl: 'https://play.google.com/music/m/' + album.albumId + '?signup_if_needed=1',
|
||||
purchaseUrl: 'https://play.google.com/store/music/album?id=' + album.albumId,
|
||||
artwork: {
|
||||
small: album.albumArtRef.replace('http:', 'https:'),
|
||||
large: album.albumArtRef.replace('http:', 'https:')
|
||||
},
|
||||
artist: {
|
||||
name: album.artist
|
||||
}
|
||||
};
|
||||
} else if (type === 'track') {
|
||||
const track = yield pm.getAllAccessTrackAsync(id);
|
||||
return {
|
||||
service: 'google',
|
||||
type: 'track',
|
||||
id: track.nid,
|
||||
name: track.title,
|
||||
streamUrl: 'https://play.google.com/music/m/' + track.nid + '?signup_if_needed=1',
|
||||
purchaseUrl: 'https://play.google.com/store/music/album?id=' + track.albumId,
|
||||
artwork: {
|
||||
small: track.albumArtRef[0].url.replace('http:', 'https:'),
|
||||
large: track.albumArtRef[0].url.replace('http:', 'https:')
|
||||
},
|
||||
album: {
|
||||
name: track.album
|
||||
},
|
||||
artist: {
|
||||
name: track.artist
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export function* search(data) {
|
||||
yield ready;
|
||||
let query, album;
|
||||
const type = data.type;
|
||||
|
||||
if (type === 'album') {
|
||||
query = data.artist.name + ' ' + data.name;
|
||||
album = data.name;
|
||||
} else if (type === 'track') {
|
||||
query = data.artist.name + ' ' + data.album.name + ' ' + data.name;
|
||||
album = data.album.name;
|
||||
}
|
||||
|
||||
let result = yield pm.searchAsync(query, 5)
|
||||
|
||||
if (!result.entries) {
|
||||
const matches = album.match(/^[^\(\[]+/);
|
||||
if (matches && matches[0] && matches[0] !== album) {
|
||||
const cleanedData = JSON.parse(JSON.stringify(data));
|
||||
if (type === 'album') {
|
||||
cleanedData.name = matches[0].trim();
|
||||
} else if (type === 'track') {
|
||||
cleanedData.album.name = matches[0].trim();
|
||||
}
|
||||
return yield search(cleanedData);
|
||||
} else {
|
||||
return {service: 'google'};
|
||||
}
|
||||
}
|
||||
result = result.entries.filter(function(entry) {
|
||||
return entry[type];
|
||||
}).sort(function(a, b) { // sort by match score
|
||||
return a.score < b.score;
|
||||
}).shift();
|
||||
|
||||
if (!result) {
|
||||
return {service: 'google'};
|
||||
} else {
|
||||
if (type === 'album') {
|
||||
return yield lookupId(result.album.albumId, type);
|
||||
} else if (type === 'track') {
|
||||
return yield lookupId(result.track.nid, type);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
"use strict";
|
||||
var parse = require('url').parse;
|
||||
import { parse } from 'url';
|
||||
|
||||
module.exports.match = function(url) {
|
||||
export function* match(url) {
|
||||
var parsed = parse(url.replace(/\+/g, "%20"));
|
||||
if (!parsed.host.match(/play\.google\.com$/)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var path = parsed.path;
|
||||
var hash = parsed.hash;
|
||||
const path = parsed.path;
|
||||
const hash = parsed.hash;
|
||||
|
||||
if (hash) {
|
||||
var parts = hash.split("/");
|
||||
var id = parts[2];
|
||||
var artist = parts[3];
|
||||
const parts = hash.split("/");
|
||||
const id = parts[2];
|
||||
const artist = parts[3];
|
||||
|
||||
if (id.length > 0) {
|
||||
return true;
|
||||
|
@ -21,7 +20,7 @@ module.exports.match = function(url) {
|
|||
return true;
|
||||
}
|
||||
} else if(path) {
|
||||
var matches = path.match(/\/music\/m\/([\w]+)/);
|
||||
const matches = path.match(/\/music\/m\/([\w]+)/);
|
||||
if (matches[1]) {
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
import {parse} from 'url';
|
||||
import { parse } from 'url';
|
||||
import querystring from 'querystring';
|
||||
import request from 'superagent';
|
||||
import 'superagent-bluebird-promise';
|
||||
import { match as urlMatch } from './url';
|
||||
|
||||
module.exports.id = 'itunes';
|
||||
export let id = 'itunes';
|
||||
|
||||
const apiRoot = 'https://itunes.apple.com';
|
||||
|
||||
module.exports.match = require('./url').match;
|
||||
export const match = urlMatch;
|
||||
|
||||
module.exports.parseUrl = function* (url) {
|
||||
let parsed = parse(url);
|
||||
let matches = parsed.path.match(/[\/]?([\/]?[a-z]{2}?)?[\/]+album[\/]+([^\/]+)[\/]+([^\?]+)/);
|
||||
let query = querystring.parse(parsed.query);
|
||||
export function* parseUrl(url) {
|
||||
const parsed = parse(url);
|
||||
const matches = parsed.path.match(/[\/]?([\/]?[a-z]{2}?)?[\/]+album[\/]+([^\/]+)[\/]+([^\?]+)/);
|
||||
const query = querystring.parse(parsed.query);
|
||||
|
||||
if (matches) {
|
||||
let type = 'album';
|
||||
|
@ -23,11 +24,11 @@ module.exports.parseUrl = function* (url) {
|
|||
}
|
||||
return yield module.exports.lookupId(id, type, matches[1] || 'us');
|
||||
} else {
|
||||
return Promise.reject(new Error());
|
||||
throw new Error();
|
||||
}
|
||||
};
|
||||
|
||||
module.exports.lookupId = function* (id, type, cc) {
|
||||
export function* lookupId(id, type, cc) {
|
||||
if (String(id).match(/^[a-z]{2}/)) {
|
||||
cc = id.substr(0, 2);
|
||||
id = id.substr(2);
|
||||
|
@ -38,13 +39,13 @@ module.exports.lookupId = function* (id, type, cc) {
|
|||
path = '/' + cc + path;
|
||||
}
|
||||
|
||||
let response = yield request.get(apiRoot + path);
|
||||
const response = yield request.get(apiRoot + path);
|
||||
let result = JSON.parse(response.text);
|
||||
|
||||
if (!result.results || result.resultCount === 0 || !result.results[0].collectionId) {
|
||||
let error = new Error('Not Found');
|
||||
const error = new Error('Not Found');
|
||||
error.status = 404;
|
||||
return Promise.reject(error);
|
||||
throw error;
|
||||
} else {
|
||||
result = result.results[0];
|
||||
|
||||
|
@ -70,13 +71,13 @@ module.exports.lookupId = function* (id, type, cc) {
|
|||
};
|
||||
}
|
||||
|
||||
return Promise.resolve(item);
|
||||
return item;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports.search = function* (data) {
|
||||
export function* search(data) {
|
||||
let query, album, entity;
|
||||
let type = data.type;
|
||||
const type = data.type;
|
||||
|
||||
if (type === 'album') {
|
||||
query = data.artist.name + ' ' + data.name;
|
||||
|
@ -88,27 +89,27 @@ module.exports.search = function* (data) {
|
|||
entity = 'musicTrack';
|
||||
}
|
||||
|
||||
let path = '/search?term=' + encodeURIComponent(query) + '&media=music&entity=' + entity;
|
||||
let response = yield request.get(apiRoot + path);
|
||||
const path = '/search?term=' + encodeURIComponent(query) + '&media=music&entity=' + entity;
|
||||
const response = yield request.get(apiRoot + path);
|
||||
let result = JSON.parse(response.text);
|
||||
|
||||
if (!result.results[0]) {
|
||||
let matches = album.match(/^[^\(\[]+/);
|
||||
const matches = album.match(/^[^\(\[]+/);
|
||||
if (matches && matches[0] && matches[0] !== album) {
|
||||
let cleanedData = JSON.parse(JSON.stringify(data));
|
||||
const cleanedData = JSON.parse(JSON.stringify(data));
|
||||
if (type === 'album') {
|
||||
cleanedData.name = matches[0].trim();
|
||||
} else if (type === 'track') {
|
||||
cleanedData.album.name = matches[0].trim();
|
||||
}
|
||||
return yield module.exports.search(cleanedData);
|
||||
return yield search(cleanedData);
|
||||
} else {
|
||||
return Promise.resolve({service: 'itunes'});
|
||||
return {service: 'itunes'};
|
||||
}
|
||||
} else {
|
||||
result = result.results[0];
|
||||
|
||||
let item = {
|
||||
const item = {
|
||||
service: 'itunes',
|
||||
type: type,
|
||||
id: 'us' + result.collectionId,
|
||||
|
@ -129,6 +130,6 @@ module.exports.search = function* (data) {
|
|||
name: result.collectionName
|
||||
};
|
||||
}
|
||||
return Promise.resolve(item);
|
||||
return item;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
"use strict";
|
||||
var parse = require('url').parse;
|
||||
var querystring = require('querystring');
|
||||
import { parse } from 'url';
|
||||
import querystring from 'querystring';
|
||||
|
||||
module.exports.match = function(url, type) {
|
||||
var parsed = parse(url);
|
||||
export function* match(url, type) {
|
||||
const parsed = parse(url);
|
||||
|
||||
if (!parsed.host.match(/itunes.apple\.com$/)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var matches = parsed.path.match(/[\/]?([\/]?[a-z]{2}?)?[\/]+album[\/]+([^\/]+)[\/]+([^\?]+)/);
|
||||
var query = querystring.parse(parsed.query);
|
||||
const matches = parsed.path.match(/[\/]?([\/]?[a-z]{2}?)?[\/]+album[\/]+([^\/]+)[\/]+([^\?]+)/);
|
||||
const query = querystring.parse(parsed.query);
|
||||
|
||||
return !!matches[3];
|
||||
};
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { parse } from 'url';
|
||||
|
||||
export function match(url) {
|
||||
var parsed = parse(url);
|
||||
export function* match(url) {
|
||||
const parsed = parse(url);
|
||||
if (!parsed.host.match(/rd\.io$/) && !parsed.host.match(/rdio\.com$/)) {
|
||||
return false;
|
||||
}
|
||||
var regular = parsed.path.match(/[\/]*artist[\/]*([^\/]*)[\/]*album[\/]*([^\/]*)[\/]*([track]*)?[\/]*([^\/]*)/);
|
||||
var short = parsed.path.match(/[\/]*x[\/]*([^\/]*)/);
|
||||
const regular = parsed.path.match(/[\/]*artist[\/]*([^\/]*)[\/]*album[\/]*([^\/]*)[\/]*([track]*)?[\/]*([^\/]*)/);
|
||||
const short = parsed.path.match(/[\/]*x[\/]*([^\/]*)/);
|
||||
return (regular && !!regular[2]) || (short && !!short[1]);
|
||||
};
|
||||
|
|
|
@ -1,70 +1,70 @@
|
|||
"use strict";
|
||||
var parse = require('url').parse;
|
||||
var Promise = require('bluebird');
|
||||
var spotify = Promise.promisifyAll(require('spotify'));
|
||||
import { parse } from 'url';
|
||||
import bluebird from 'bluebird';
|
||||
import spotifyCB from 'spotify';
|
||||
const spotify = bluebird.promisifyAll(spotifyCB);
|
||||
import { match as urlMatch } from './url';
|
||||
|
||||
module.exports.id = "spotify";
|
||||
export let id = "spotify";
|
||||
|
||||
module.exports.match = require('./url').match;
|
||||
export const match = urlMatch;
|
||||
|
||||
module.exports.parseUrl = function(url) {
|
||||
export function* parseUrl(url) {
|
||||
var matches = parse(url).path.match(/\/(album|track)[\/]+([^\/]+)/);
|
||||
|
||||
if (matches && matches[2]) {
|
||||
return module.exports.lookupId(matches[2], matches[1]);
|
||||
return yield lookupId(matches[2], matches[1]);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.lookupId = function(id, type) {
|
||||
return spotify.lookupAsync({id: id, type: type}).then(function(data) {
|
||||
if (data.error) {
|
||||
var error = new Error("Not Found");
|
||||
error.status = 404;
|
||||
throw error;
|
||||
}
|
||||
export function* lookupId(id, type) {
|
||||
const data = yield spotify.lookupAsync({id: id, type: type});
|
||||
if (data.error) {
|
||||
var error = new Error("Not Found");
|
||||
error.status = 404;
|
||||
throw error;
|
||||
}
|
||||
|
||||
var artist = data.artists[0];
|
||||
var artist = data.artists[0];
|
||||
|
||||
if (type == "album") {
|
||||
return {
|
||||
service: "spotify",
|
||||
type: type,
|
||||
id: data.id,
|
||||
name: data.name,
|
||||
streamUrl: "https://play.spotify.com/" + type + "/" + data.id,
|
||||
purchaseUrl: null,
|
||||
artwork: {
|
||||
small: data.images[1].url.replace("http:", "https:"),
|
||||
large: data.images[0].url.replace("http:", "https:"),
|
||||
},
|
||||
artist: {
|
||||
name: artist.name
|
||||
}
|
||||
};
|
||||
} else if (type == "track") {
|
||||
return {
|
||||
service: "spotify",
|
||||
type: type,
|
||||
id: data.id,
|
||||
name: data.name,
|
||||
streamUrl: "https://play.spotify.com/" + type + "/" + data.id,
|
||||
purchaseUrl: null,
|
||||
artwork: {
|
||||
small: data.album.images[1].url.replace("http:", "https:"),
|
||||
large: data.album.images[0].url.replace("http:", "https:"),
|
||||
},
|
||||
artist: {
|
||||
name: artist.name
|
||||
},
|
||||
album: {
|
||||
name: data.album.name
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
if (type == "album") {
|
||||
return {
|
||||
service: "spotify",
|
||||
type: type,
|
||||
id: data.id,
|
||||
name: data.name,
|
||||
streamUrl: "https://play.spotify.com/" + type + "/" + data.id,
|
||||
purchaseUrl: null,
|
||||
artwork: {
|
||||
small: data.images[1].url.replace("http:", "https:"),
|
||||
large: data.images[0].url.replace("http:", "https:"),
|
||||
},
|
||||
artist: {
|
||||
name: artist.name
|
||||
}
|
||||
};
|
||||
} else if (type == "track") {
|
||||
return {
|
||||
service: "spotify",
|
||||
type: type,
|
||||
id: data.id,
|
||||
name: data.name,
|
||||
streamUrl: "https://play.spotify.com/" + type + "/" + data.id,
|
||||
purchaseUrl: null,
|
||||
artwork: {
|
||||
small: data.album.images[1].url.replace("http:", "https:"),
|
||||
large: data.album.images[0].url.replace("http:", "https:"),
|
||||
},
|
||||
artist: {
|
||||
name: artist.name
|
||||
},
|
||||
album: {
|
||||
name: data.album.name
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.search = function(data) {
|
||||
export function* search(data) {
|
||||
var cleanParam = function(str) {
|
||||
var chopChars = ['&', '[', '('];
|
||||
chopChars.forEach(function(chr) {
|
||||
|
@ -85,28 +85,26 @@ module.exports.search = function(data) {
|
|||
album = data.album.name;
|
||||
}
|
||||
|
||||
return spotify.searchAsync({query: query, type: type}).then(function(results) {
|
||||
if (!results[type + "s"].items[0]) {
|
||||
return {service: "spotify"};
|
||||
} else {
|
||||
var found;
|
||||
var choppedAlbum = data.type == "album" ? cleanParam(data.name) : cleanParam(data.album.name);
|
||||
if (!choppedAlbum.length) {
|
||||
return module.exports.lookupId(results[type + "s"].items[0].id, type);
|
||||
}
|
||||
|
||||
results[type + "s"].items.forEach(function(item) {
|
||||
var albumName = data.type == "album" ? item.name : item.album.name;
|
||||
var matches = albumName.match(/^[^\(\[]+/);
|
||||
if(choppedAlbum.indexOf(matches[0]) >= 0) {
|
||||
found = item;
|
||||
}
|
||||
});
|
||||
if (!found) {
|
||||
return {service: "spotify"};
|
||||
}
|
||||
return module.exports.lookupId(results[type + "s"].items[0].id, type);
|
||||
const results = yield spotify.searchAsync({query: query, type: type});
|
||||
if (!results[type + "s"].items[0]) {
|
||||
return {service: "spotify"};
|
||||
} else {
|
||||
let found;
|
||||
const choppedAlbum = data.type == "album" ? cleanParam(data.name) : cleanParam(data.album.name);
|
||||
if (!choppedAlbum.length) {
|
||||
return yield lookupId(results[type + "s"].items[0].id, type);
|
||||
}
|
||||
|
||||
});
|
||||
results[type + "s"].items.forEach(function(item) {
|
||||
const albumName = data.type == "album" ? item.name : item.album.name;
|
||||
const matches = albumName.match(/^[^\(\[]+/);
|
||||
if(choppedAlbum.indexOf(matches[0]) >= 0) {
|
||||
found = item;
|
||||
}
|
||||
});
|
||||
if (!found) {
|
||||
return {service: "spotify"};
|
||||
}
|
||||
return yield lookupId(results[type + "s"].items[0].id, type);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
"use strict";
|
||||
var parse = require('url').parse;
|
||||
import { parse } from 'url';
|
||||
|
||||
module.exports.match = function(url, type) {
|
||||
var parsed = parse(url);
|
||||
export function* match(url, type) {
|
||||
const parsed = parse(url);
|
||||
if (!parsed.host.match(/spotify\.com$/)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var matches = parse(url).path.match(/\/(album|track)[\/]+([^\/]+)/);
|
||||
const matches = parse(url).path.match(/\/(album|track)[\/]+([^\/]+)/);
|
||||
return matches && !!matches[2];
|
||||
};
|
||||
|
|
|
@ -1,40 +1,45 @@
|
|||
"use strict";
|
||||
var parse = require('url').parse;
|
||||
var Promise = require('bluebird');
|
||||
var request = require('superagent');
|
||||
require('superagent-bluebird-promise');
|
||||
import { parse } from 'url';
|
||||
import querystring from 'querystring';
|
||||
import request from 'superagent';
|
||||
import 'superagent-bluebird-promise';
|
||||
import { match as urlMatch } from './url';
|
||||
|
||||
module.exports.id = "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.");
|
||||
} else {
|
||||
}
|
||||
|
||||
var credentials = {
|
||||
const credentials = {
|
||||
clientId: process.env.XBOX_CLIENT_ID,
|
||||
clientSecret: process.env.XBOX_CLIENT_SECRET
|
||||
};
|
||||
|
||||
var apiRoot = "https://music.xboxlive.com/1/content";
|
||||
const apiRoot = "https://music.xboxlive.com/1/content";
|
||||
|
||||
var getAccessToken = function() {
|
||||
var authUrl = "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13";
|
||||
var scope = "http://music.xboxlive.com";
|
||||
var grantType = "client_credentials";
|
||||
|
||||
var data = {client_id: credentials.clientId, client_secret: credentials.clientSecret, scope: scope, grant_type: grantType};
|
||||
return request.post(authUrl).send(data).set('Content-type', 'application/x-www-form-urlencoded').promise().then(function(res) {
|
||||
return res.body.access_token;
|
||||
});
|
||||
function* getAccessToken() {
|
||||
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,
|
||||
client_secret: credentials.clientSecret,
|
||||
scope: scope,
|
||||
grant_type: grantType
|
||||
};
|
||||
const result = yield request.post(authUrl).send(data).set('Content-type', 'application/x-www-form-urlencoded').promise();
|
||||
return result.body.access_token;
|
||||
}
|
||||
|
||||
var formatResponse = function(res) {
|
||||
function formatResponse(res) {
|
||||
let result;
|
||||
if (res.body.Tracks) {
|
||||
var result = res.body.Tracks.Items[0];
|
||||
result = res.body.Tracks.Items[0];
|
||||
} else {
|
||||
var result = res.body.Albums.Items[0];
|
||||
result = res.body.Albums.Items[0];
|
||||
}
|
||||
var item = {
|
||||
let item = {
|
||||
service: "xbox",
|
||||
type: res.body.Tracks ? "track" : "album",
|
||||
id: result.Id,
|
||||
|
@ -55,37 +60,33 @@ var formatResponse = function(res) {
|
|||
return item;
|
||||
}
|
||||
|
||||
module.exports.match = require('./url').match;
|
||||
export const match = urlMatch;
|
||||
|
||||
module.exports.parseUrl = function(url) {
|
||||
var parsed = parse(url);
|
||||
var parts = parsed.path.split("/");
|
||||
var type = parts[1];
|
||||
var idMatches = parts[4].match(/[\w\-]+/);
|
||||
var id = idMatches[0];
|
||||
export function* parseUrl(url) {
|
||||
const parsed = parse(url);
|
||||
const parts = parsed.path.split("/");
|
||||
const type = parts[1];
|
||||
const idMatches = parts[4].match(/[\w\-]+/);
|
||||
const id = idMatches[0];
|
||||
if (!id) {
|
||||
return false;
|
||||
}
|
||||
return module.exports.lookupId("music." + id, type);
|
||||
return yield lookupId("music." + id, type);
|
||||
}
|
||||
|
||||
module.exports.lookupId = function(id, type) {
|
||||
return getAccessToken().then(function(access_token){
|
||||
var path = "/" + id + "/lookup";
|
||||
return request.get(apiRoot + path).set("Authorization", "Bearer " + access_token).promise().then(function(res) {
|
||||
return formatResponse(res);
|
||||
}, function(res) {
|
||||
return {service: "xbox"};
|
||||
});
|
||||
});
|
||||
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"};
|
||||
};
|
||||
|
||||
module.exports.search = function(data) {
|
||||
export function* search(data) {
|
||||
var cleanParam = function(str) {
|
||||
return str.replace(/[\:\?\&]+/, "");
|
||||
}
|
||||
var query, album;
|
||||
var type = data.type;
|
||||
let query, album;
|
||||
const type = data.type;
|
||||
|
||||
if (type == "album") {
|
||||
query = cleanParam(data.artist.name.substring(0, data.artist.name.indexOf('&'))) + " " + cleanParam(data.name);
|
||||
|
@ -94,14 +95,8 @@ module.exports.search = function(data) {
|
|||
query = cleanParam(data.artist.name.substring(0, data.artist.name.indexOf('&'))) + " " + cleanParam(data.name);
|
||||
album = data.album.name
|
||||
}
|
||||
return getAccessToken().then(function(access_token){
|
||||
var path = "/music/search?q=" + encodeURIComponent(query) + "&filters=" + type + "s";
|
||||
return request.get(apiRoot + path).set("Authorization", "Bearer " + access_token).promise().then(function(res) {
|
||||
return formatResponse(res);
|
||||
}, function(res) {
|
||||
return {service: "xbox"};
|
||||
});
|
||||
});
|
||||
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"};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
"use strict";
|
||||
var parse = require('url').parse;
|
||||
|
||||
module.exports.match = function(url, type) {
|
||||
var parsed = parse(url);
|
||||
import { parse } from 'url';
|
||||
|
||||
export function* match(url, type) {
|
||||
const parsed = parse(url);
|
||||
if (!parsed.host.match(/music.xbox.com$/)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var parts = parsed.path.split("/");
|
||||
|
||||
const parts = parsed.path.split("/");
|
||||
return (parts[1] == "album" || parts[1] == "track") && parts[4];
|
||||
};
|
||||
|
|
|
@ -1,20 +1,15 @@
|
|||
"use strict";
|
||||
var parse = require('url').parse;
|
||||
var Promise = require('bluebird');
|
||||
var request = require('superagent');
|
||||
require('superagent-bluebird-promise');
|
||||
import { parse } from 'url';
|
||||
import querystring from 'querystring';
|
||||
import request from 'superagent';
|
||||
import 'superagent-bluebird-promise';
|
||||
|
||||
var credentials = {
|
||||
const credentials = {
|
||||
key: process.env.YOUTUBE_KEY,
|
||||
};
|
||||
|
||||
var apiRoot = "https://www.googleapis.com/freebase/v1/topic";
|
||||
const apiRoot = "https://www.googleapis.com/freebase/v1/topic";
|
||||
|
||||
module.exports.get = function(topic) {
|
||||
return request.get(apiRoot + topic + "?key=" + credentials.key).promise().then(function(res) {
|
||||
return res.body;
|
||||
})
|
||||
export function* get(topic) {
|
||||
const result = yield request.get(apiRoot + topic + "?key=" + credentials.key).promise();
|
||||
return result.body;
|
||||
}
|
||||
|
||||
|
||||
module.exports.get("/m/0dwcrm_");
|
|
@ -1,139 +1,124 @@
|
|||
"use strict";
|
||||
var parse = require('url').parse;
|
||||
var freebase = require('./freebase');
|
||||
var querystring = require('querystring');
|
||||
var moment = require('moment');
|
||||
var Promise = require('bluebird');
|
||||
var request = require('superagent');
|
||||
require('superagent-bluebird-promise');
|
||||
import { parse } from 'url';
|
||||
import querystring from 'querystring';
|
||||
import moment from 'moment';
|
||||
import request from 'superagent';
|
||||
import 'superagent-bluebird-promise';
|
||||
import { match as urlMatch } from './url';
|
||||
import freebase from './freebase';
|
||||
|
||||
module.exports.id = "youtube";
|
||||
module.exports.id = 'youtube';
|
||||
|
||||
if (!process.env.YOUTUBE_KEY) {
|
||||
console.warn("YOUTUBE_KEY environment variable not found, deactivating Youtube.");
|
||||
} else {
|
||||
console.warn('YOUTUBE_KEY environment variable not found, deactivating Youtube.');
|
||||
}
|
||||
|
||||
var credentials = {
|
||||
const credentials = {
|
||||
key: process.env.YOUTUBE_KEY,
|
||||
};
|
||||
|
||||
var apiRoot = "https://www.googleapis.com/youtube/v3";
|
||||
const apiRoot = 'https://www.googleapis.com/youtube/v3';
|
||||
|
||||
module.exports.match = require('./url').match;
|
||||
export const match = urlMatch;
|
||||
|
||||
export function parseUrl(url) {
|
||||
const parsed = parse(url);
|
||||
const query = querystring.parse(parsed.query);
|
||||
let id = query.v;
|
||||
|
||||
module.exports.parseUrl = function(url) {
|
||||
var parsed = parse(url);
|
||||
var query = querystring.parse(parsed.query);
|
||||
var id = query.v;
|
||||
|
||||
if (!id) {
|
||||
id = parsed.path.substr(1);
|
||||
if (!id) {
|
||||
throw new Error();
|
||||
}
|
||||
}
|
||||
return module.exports.lookupId(id, "track");
|
||||
return lookupId(id, 'track');
|
||||
}
|
||||
|
||||
module.exports.lookupId = function(id, type) {
|
||||
|
||||
var path = "/videos?part=snippet%2CtopicDetails%2CcontentDetails&id=" + id + "&key=" + credentials.key;
|
||||
|
||||
return request.get(apiRoot + path).promise().then(function(res) {
|
||||
var item = res.body.items[0];
|
||||
if (item.topicDetails.topicIds) {
|
||||
var promises = [];
|
||||
var 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,
|
||||
}
|
||||
};
|
||||
item.topicDetails.topicIds.forEach(function(topicId) {
|
||||
promises.push(freebase.get(topicId).then(function(topic) {
|
||||
if (topic.property["/type/object/type"].values.some(function(value) {
|
||||
return value.text == "Musical Artist";
|
||||
})) {
|
||||
match.artist = {name: topic.property["/type/object/name"].values[0].text};
|
||||
} else if (topic.property["/type/object/type"].values.some(function(value) {
|
||||
return value.text == "Musical Recording";
|
||||
})) {
|
||||
//if (moment.duration(item.contentDetails.duration).asSeconds() < 900) {
|
||||
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 (topic.property["/type/object/type"].values.some(function(value) {
|
||||
return value.text == "Musical Album";
|
||||
})) {
|
||||
match.name = topic.property["/type/object/name"].values[0].text;
|
||||
match.type = "album";
|
||||
}
|
||||
}, function(err) {
|
||||
console.log(err)
|
||||
}));
|
||||
});
|
||||
return Promise.all(promises).then(function() {
|
||||
return match;
|
||||
}, function(err) {
|
||||
console.log(err)
|
||||
return {service: "youtube"};
|
||||
});
|
||||
} else {
|
||||
return {service: "youtube"};
|
||||
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,
|
||||
}
|
||||
}, function(err) {
|
||||
console.log(err)
|
||||
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;
|
||||
}
|
||||
} else if (musicalAlbum) {
|
||||
match.name = topic.property['/type/object/name'].values[0].text;
|
||||
match.type = 'album';
|
||||
}
|
||||
}
|
||||
return match;
|
||||
};
|
||||
|
||||
module.exports.search = function(data) {
|
||||
var query, album;
|
||||
var type = data.type;
|
||||
export function* search(data) {
|
||||
let query, album;
|
||||
const type = data.type;
|
||||
|
||||
if (type == "album") {
|
||||
query = data.artist.name + " " + data.name;
|
||||
if (type == 'album') {
|
||||
query = data.artist.name + ' ' + data.name;
|
||||
album = data.name;
|
||||
} else if (type == "track") {
|
||||
query = data.artist.name + " " + data.name;
|
||||
} else if (type == 'track') {
|
||||
query = data.artist.name + ' ' + data.name;
|
||||
album = data.album.name
|
||||
}
|
||||
|
||||
var path = "/search?part=snippet&q=" + encodeURIComponent(query) + "&type=video&videoCaption=any&videoCategoryId=10&key=" + credentials.key;
|
||||
const path = '/search?part=snippet&q=' + encodeURIComponent(query) + '&type=video&videoCaption=any&videoCategoryId=10&key=' + credentials.key;
|
||||
|
||||
return request.get(apiRoot + path).promise().then(function(res) {
|
||||
var result = res.body.items[0];
|
||||
const result = yield request.get(apiRoot + path).promise();
|
||||
const item = result.body.items[0];
|
||||
|
||||
if (!result) {
|
||||
return {service:"youtube", type: "video"};
|
||||
} else {
|
||||
return {
|
||||
service: "youtube",
|
||||
type: "video",
|
||||
id: result.id.videoId,
|
||||
name: result.snippet.title,
|
||||
streamUrl: "https://www.youtube.com/watch?v=" + result.id.videoId,
|
||||
purchaseUrl: null,
|
||||
artwork: {
|
||||
small: result.snippet.thumbnails.medium.url,
|
||||
large: result.snippet.thumbnails.high.url,
|
||||
}
|
||||
};
|
||||
}
|
||||
}, function(err) {
|
||||
console.log(err)
|
||||
return {service: "youtube"};
|
||||
});
|
||||
if (!item) {
|
||||
return {service:'youtube', type: 'video'};
|
||||
} else {
|
||||
return {
|
||||
service: 'youtube',
|
||||
type: 'video',
|
||||
id: item.id.videoId,
|
||||
name: item.snippet.title,
|
||||
streamUrl: 'https://www.youtube.com/watch?v=' + item.id.videoId,
|
||||
purchaseUrl: null,
|
||||
artwork: {
|
||||
small: item.snippet.thumbnails.medium.url,
|
||||
large: item.snippet.thumbnails.high.url,
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
"use strict";
|
||||
var parse = require("url").parse;
|
||||
var querystring = require('querystring');
|
||||
import { parse } from 'url';
|
||||
import querystring from 'querystring';
|
||||
|
||||
module.exports.match = function(url, type) {
|
||||
var parsed = parse(url);
|
||||
|
||||
export function* match(url, type) {
|
||||
const parsed = parse(url);
|
||||
if (parsed.host.match(/youtu\.be$/)) {
|
||||
return true;
|
||||
} else if (parsed.host.match(/youtube\.com$/)) {
|
||||
var query = querystring.parse(parsed.query);
|
||||
const query = querystring.parse(parsed.query);
|
||||
return !!query.v;
|
||||
}
|
||||
return false;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue