Improve Deezer matching

This commit is contained in:
Jonathan Cremin 2017-05-07 20:57:12 +01:00
parent c5ea8f5b7a
commit 00ca82c851
3 changed files with 52 additions and 5 deletions

View file

@ -75,15 +75,22 @@ export function* lookupId(id, type) {
}
};
export function* search(data) {
export function* search(data, original={}) {
let cleanParam = function(str) {
return str.replace(/[\:\?\&]+/, '');
};
let query, album;
let {type} = data;
const various = data.artist.name === 'Various Artists' || data.artist.name === 'Various';
if (type === 'album') {
// Deezer is shitty about artists with these names, strip them instead
if (various) {
query = cleanParam(data.name);
} else {
query = cleanParam(data.artist.name) + ' ' + cleanParam(data.name);
}
album = data.name;
} else if (type === 'track') {
query = cleanParam(data.artist.name) + ' ' + cleanParam(data.albumName) + ' ' + cleanParam(data.name);
@ -91,8 +98,17 @@ export function* search(data) {
}
var path = '/search/' + type + '?q=' + encodeURIComponent(query);
let response = yield request.get(apiRoot + path);
if (response.body.data[0]) {
const name = original.name || data.name;
if (response.body.data.length > 0) {
let match;
if (!(match = exactMatch(name, response.body.data, data.type, various))) {
match = looseMatch(name, response.body.data, data.type, various);
}
return yield module.exports.lookupId(response.body.data[0].id, type);
} else {
var matches = album.match(/^[^\(\[]+/);
@ -103,9 +119,35 @@ export function* search(data) {
} else if (type === 'track') {
cleanedData.albumName = matches[0].trim();
}
return yield module.exports.search(cleanedData);
return yield module.exports.search(cleanedData, data);
} else {
return Promise.resolve({service: 'deezer'});
}
}
};
function exactMatch(needle, haystack, type, various) {
// try to find exact match
return haystack.find(function(entry) {
if (!entry[type] || (various && (entry.artist.name !== 'Various' || entry.artist.name !== 'Various Artists'))) {
return false;
}
entry = entry[type];
if (entry.title === needle) {
return entry;
}
});
}
function looseMatch(needle, haystack, type, various) {
// try to find exact match
return haystack.find(function(entry) {
if (!entry[type] || (various && (entry.artist.name !== 'Various' || entry.artist.name !== 'Various Artists'))) {
return false;
}
const name = entry[type].title || entry[type].name;
if (name.indexOf(needle) >= 0) {
return entry[type];
}
});
}

View file

@ -20,6 +20,11 @@ describe('Deezer', function(){
result.name.should.startWith('In Colour');
});
it('should find album with various artists by search', function* (){
const result = yield deezer.search({type: 'album', artist: {name: 'Various Artists'}, name: 'The Trevor Nelson Collection'});
result.name.should.equal('The Trevor Nelson Collection');
});
it('should find track by search', function* (){
const result = yield deezer.search({type: 'track', artist: {name: 'Deftones'}, albumName: 'Deftones', name: 'Hexagram'});
result.name.should.equal('Hexagram');

View file

@ -20,7 +20,7 @@ describe('Spotify', function(){
result.name.should.equal('Listen (Deluxe)');
});
it('should find album with colon in name by search', function* (){
it('should find album by various artists by search', function* (){
const result = yield spotify.search({type: 'album', artist: {name: 'Various Artists'}, name: 'The Get Down Part II: Original Soundtrack From The Netflix Original Series'});
result.name.should.equal('The Get Down Part II: Original Soundtrack From The Netflix Original Series');
});