Update service images for retina, remove rdio :(
|
@ -1,168 +0,0 @@
|
|||
import { parse } from 'url';
|
||||
import bluebird from 'bluebird';
|
||||
import rdioInit from 'rdio';
|
||||
import { match as urlMatch } from './url';
|
||||
|
||||
export let id = 'rdio';
|
||||
|
||||
if (!process.env.RDIO_CLIENT_ID || !process.env.RDIO_CLIENT_SECRET) {
|
||||
console.warn('RDIO_CLIENT_ID or RDIO_CLIENT_SECRET environment constiables not found, deactivating Rdio.');
|
||||
}
|
||||
|
||||
const Rdio = rdioInit({
|
||||
rdio: {
|
||||
clientId: process.env.RDIO_CLIENT_ID,
|
||||
clientSecret: process.env.RDIO_CLIENT_SECRET,
|
||||
}
|
||||
});
|
||||
|
||||
const rdio = bluebird.promisifyAll(new Rdio());
|
||||
|
||||
export const match = urlMatch;
|
||||
|
||||
export function* lookupId(id) {
|
||||
yield rdio.getClientTokenAsync();
|
||||
const response = yield rdio.requestAsync({method: 'getObjectFromShortCode', short_code: id}, false);
|
||||
const result = response.result;
|
||||
const parsedShortUrl = parse(result.shortUrl);
|
||||
const rid = parsedShortUrl.path.replace('/x/', '').replace('/', '');
|
||||
const type = result.album ? 'track' : 'album';
|
||||
|
||||
const item = {
|
||||
service: 'rdio',
|
||||
type: type,
|
||||
id: rid,
|
||||
name: result.name,
|
||||
streamUrl: result.shortUrl,
|
||||
purchaseUrl: null,
|
||||
artwork: {
|
||||
small: result.icon.replace('square-200', 'square-250').replace('http:', 'https:'),
|
||||
large: result.icon.replace('square-200', 'square-600').replace('http:', 'https:')
|
||||
},
|
||||
artist: {
|
||||
name: result.artist
|
||||
}
|
||||
};
|
||||
if (type === 'track') {
|
||||
item.album = {
|
||||
name: result.album
|
||||
};
|
||||
}
|
||||
return item;
|
||||
};
|
||||
|
||||
export function* parseUrl(url) {
|
||||
const parsedUrl = parse(url);
|
||||
|
||||
let query, args;
|
||||
|
||||
if (parsedUrl.host === 'rd.io') {
|
||||
query = {
|
||||
method: 'getObjectFromShortCode',
|
||||
short_code: parsedUrl.path.replace('/x/', '').replace('/', '')
|
||||
};
|
||||
} else if (parsedUrl.host.match(/rdio\.com$/)) {
|
||||
query = {
|
||||
method: 'getObjectFromUrl',
|
||||
url: parsedUrl.path
|
||||
};
|
||||
} else {
|
||||
const error = new Error('Not Found');
|
||||
error.status = 404;
|
||||
throw error;
|
||||
}
|
||||
|
||||
yield rdio.getClientTokenAsync();
|
||||
const response = yield rdio.requestAsync(query, false);
|
||||
const result = response.result;
|
||||
const parsedShortUrl = parse(result.shortUrl);
|
||||
const id = parsedShortUrl.path.replace('/x/', '').replace('/', '');
|
||||
const type = result.album ? 'track' : 'album';
|
||||
const item = {
|
||||
service: 'rdio',
|
||||
type: type,
|
||||
id: id,
|
||||
name: result.name,
|
||||
streamUrl: result.shortUrl,
|
||||
purchaseUrl: null,
|
||||
artwork: {
|
||||
small: result.icon.replace('square-200', 'square-250').replace('http:', 'https:'),
|
||||
large: result.icon.replace('square-200', 'square-600').replace('http:', 'https:')
|
||||
},
|
||||
artist: {
|
||||
name: result.artist
|
||||
}
|
||||
};
|
||||
if (type === 'track') {
|
||||
item.album = {
|
||||
name: result.album
|
||||
};
|
||||
}
|
||||
return item;
|
||||
};
|
||||
|
||||
export function* search(data) {
|
||||
let query, albumClean;
|
||||
const type = data.type;
|
||||
|
||||
if (type === 'album') {
|
||||
query = data.artist.name + ' ' + data.name;
|
||||
albumClean = data.name.match(/([^\(\[]+)/)[0];
|
||||
} else if (type === 'track') {
|
||||
query = data.artist.name + ' ' + data.album.name + ' ' + data.name;
|
||||
try {
|
||||
albumClean = data.album.name.match(/([^\(\[]+)/)[0];
|
||||
} catch(e) {
|
||||
albumClean = '';
|
||||
}
|
||||
}
|
||||
|
||||
yield rdio.getClientTokenAsync();
|
||||
const response = yield rdio.requestAsync({method: 'search', query: query, types: type}, false);
|
||||
const result = response.result.results.filter(function(item) {
|
||||
if (type === 'album' && item.name.match(/([^\(\[]+)/)[0] === albumClean) {
|
||||
return item;
|
||||
} else if (type === 'track' && (item.album.match(/([^\(\[]+)/)[0] === albumClean || !albumClean)) {
|
||||
return item;
|
||||
}
|
||||
}).shift();
|
||||
|
||||
if (!result) {
|
||||
const matches = albumClean.match(/^[^\(\[]+/);
|
||||
if (matches && matches[0] && matches[0] !== albumClean) {
|
||||
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 module.exports.search(cleanedData);
|
||||
} else {
|
||||
return {service: 'rdio'};
|
||||
}
|
||||
} else {
|
||||
const parsedShortUrl = parse(result.shortUrl);
|
||||
const id = parsedShortUrl.path.replace('/x/', '').replace('/', '');
|
||||
const item = {
|
||||
service: 'rdio',
|
||||
type: type,
|
||||
id: id,
|
||||
name: result.name,
|
||||
streamUrl: result.shortUrl,
|
||||
purchaseUrl: null,
|
||||
artwork: {
|
||||
small: result.icon.replace('square-200', 'square-250').replace('http:', 'https:'),
|
||||
large: result.icon.replace('square-200', 'square-600').replace('http:', 'https:')
|
||||
},
|
||||
artist: {
|
||||
name: result.artist
|
||||
}
|
||||
};
|
||||
if (type === 'track') {
|
||||
item.album = {
|
||||
name: result.album
|
||||
};
|
||||
}
|
||||
return item;
|
||||
}
|
||||
};
|
|
@ -1,11 +0,0 @@
|
|||
import { parse } from 'url';
|
||||
|
||||
export function* match(url) {
|
||||
const parsed = parse(url);
|
||||
if (!parsed.host.match(/rd\.io$/) && !parsed.host.match(/rdio\.com$/)) {
|
||||
return false;
|
||||
}
|
||||
const regular = parsed.path.match(/[\/]*artist[\/]*([^\/]*)[\/]*album[\/]*([^\/]*)[\/]*([track]*)?[\/]*([^\/]*)/);
|
||||
const short = parsed.path.match(/[\/]*x[\/]*([^\/]*)/);
|
||||
return (regular && !!regular[2]) || (short && !!short[1]);
|
||||
};
|
11
package.json
|
@ -17,13 +17,12 @@
|
|||
"npm": "^3.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"babel": "~6.1.18",
|
||||
"babel-cli": "^6.2.0",
|
||||
"babel-core": "^6.2.1",
|
||||
"babel-plugin-syntax-jsx": "^6.1.18",
|
||||
"babel-plugin-transform-es2015-arrow-functions": "^6.1.18",
|
||||
"babel": "^6.1.18",
|
||||
"babel-cli": "^6.3.13",
|
||||
"babel-core": "^6.3.13",
|
||||
"babel-plugin-syntax-jsx": "^6.3.13",
|
||||
"babel-plugin-transform-es2015-arrow-functions": "^6.3.13",
|
||||
"babel-plugin-transform-es2015-block-scoped-functions": "^6.1.18",
|
||||
"babel-plugin-transform-es2015-block-scoping": "^6.1.18",
|
||||
"babel-plugin-transform-es2015-classes": "^6.2.2",
|
||||
"babel-plugin-transform-es2015-computed-properties": "^6.1.18",
|
||||
"babel-plugin-transform-es2015-constants": "^6.1.4",
|
||||
|
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 7.9 KiB |
Before Width: | Height: | Size: 5 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 7.8 KiB |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 6.1 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 7.7 KiB |
|
@ -136,6 +136,7 @@ h3 {
|
|||
|
||||
.service {
|
||||
padding: 40px 10px 10px 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.matching-from {
|
||||
position: absolute;
|
||||
|
@ -152,7 +153,6 @@ h3 {
|
|||
width: 100%;
|
||||
height: 0;
|
||||
padding-bottom: 100%;
|
||||
margin-bottom: 10px;
|
||||
background-repeat: none;
|
||||
background-size: cover;
|
||||
border-radius: 5px;
|
||||
|
@ -211,7 +211,7 @@ h3 {
|
|||
text-decoration: none;
|
||||
}
|
||||
.service-link img {
|
||||
margin-bottom: 7px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.error {
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
import 'should';
|
||||
import * as rdio from '../../lib/services/rdio';
|
||||
|
||||
describe('Rdio', function(){
|
||||
describe('lookupId', function(){
|
||||
it('should find album by ID', function* (){
|
||||
const result = yield rdio.lookupId('Qj4NXr0');
|
||||
result.name.should.equal('Listen (Deluxe)');
|
||||
});
|
||||
});
|
||||
|
||||
describe('search', function(){
|
||||
it('should find album by search', function* (){
|
||||
const result = yield rdio.search({type: 'album', artist: {name: 'David Guetta'}, name: 'Listen (Deluxe)'});
|
||||
result.name.should.equal('Listen (Deluxe)');
|
||||
});
|
||||
});
|
||||
|
||||
describe('parseUrl', function(){
|
||||
it('should parse regular url into album object', function* (){
|
||||
const result = yield rdio.parseUrl('https://www.rdio.com/artist/David_Guetta/album/Listen_(Deluxe)/');
|
||||
result.name.should.equal('Listen (Deluxe)');
|
||||
});
|
||||
|
||||
it('should parse short url into album object', function* (){
|
||||
const result = yield rdio.parseUrl('http://rd.io/x/Qj4NXr0/');
|
||||
result.name.should.equal('Listen (Deluxe)');
|
||||
});
|
||||
});
|
||||
});
|
|
@ -39,7 +39,7 @@ const MusicItem = React.createClass({
|
|||
return (
|
||||
<div className='col-md-3 col-xs-6'>
|
||||
<div className={'service' + (this.props.inc === 0 ? ' source-service' : '')}>
|
||||
<div className='matching-from hidden-xs'>{this.props.inc === 0 ? 'Found matches using this link' : ''}</div>
|
||||
<div className='matching-from'>{this.props.inc === 0 ? 'Found matches using' : ''}</div>
|
||||
<a href={this.props.item.streamUrl || this.props.item.purchaseUrl}>
|
||||
<div className={this.props.item.service === 'youtube' ? 'artwork-youtube artwork' : 'artwork'} style={{backgroundImage: 'url(' + this.props.item.artwork.small + ')'}}>
|
||||
</div>
|
||||
|
@ -47,11 +47,11 @@ const MusicItem = React.createClass({
|
|||
{this.props.item.service === 'youtube' && this.props.inc > 0 ? this.props.item.name : ''}
|
||||
</div>
|
||||
</a>
|
||||
<div className='service-link'>
|
||||
<a href={this.props.item.streamUrl || this.props.item.purchaseUrl}>
|
||||
<img src={'/images/' + this.props.item.service + '.png'} className='img-rounded' />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className='service-link'>
|
||||
<a href={this.props.item.streamUrl || this.props.item.purchaseUrl}>
|
||||
<img src={'/images/' + this.props.item.service + '.png'} />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|