Add youtube to results, persist to mongo
This commit is contained in:
parent
d675ac4e9f
commit
f20fecf0d0
7 changed files with 125 additions and 31 deletions
|
@ -19,6 +19,5 @@ This is in super early development and is incapable of handling getting dugg, ne
|
|||
On the immediate todo list:
|
||||
|
||||
* Use album release year for additional sanity check on matches
|
||||
* Maybe drop everything from the first left-hand bracket in album names to improve matches **after** failing to get a good match
|
||||
* Handle expected and unexpected errors better than the current crash-fest
|
||||
* Add some kind of persistence or caching so it could take a pummeling and not get me banned from the various services
|
||||
|
|
14
app.js
14
app.js
|
@ -8,6 +8,7 @@ var session = require('express-session');
|
|||
var cookieParser = require('cookie-parser');
|
||||
var flash = require('connect-flash');
|
||||
var bodyParser = require('body-parser');
|
||||
var pmongo = require('promised-mongo');
|
||||
|
||||
var search = require('./routes/search');
|
||||
var share = require('./routes/share');
|
||||
|
@ -34,6 +35,19 @@ app.use(session({
|
|||
app.use(flash());
|
||||
app.use(express.static(path.join(__dirname, 'public')));
|
||||
|
||||
var db;
|
||||
if (process.env.MONGOHQ_URL) {
|
||||
console.log("Connecting to MongoHQ")
|
||||
db = pmongo(process.env.MONGOHQ_URL, ['matches']);
|
||||
} else {
|
||||
db = pmongo('match-audio', ['matches']);
|
||||
}
|
||||
|
||||
app.use(function(req, res, next) {
|
||||
req.db = res.db = db;
|
||||
next();
|
||||
})
|
||||
|
||||
// force SSL
|
||||
app.get('*', function(req,res,next) {
|
||||
if (req.headers['cf-visitor'] && req.headers['cf-visitor'] != '{"scheme":"https"}') {
|
||||
|
|
50
lib/services/youtube.js
Normal file
50
lib/services/youtube.js
Normal file
|
@ -0,0 +1,50 @@
|
|||
"use strict";
|
||||
var parse = require('url').parse;
|
||||
var request = require('superagent');
|
||||
var Q = require('q');
|
||||
|
||||
module.exports.id = "youtube";
|
||||
|
||||
if (!process.env.YOUTUBE_KEY) {
|
||||
console.warn("YOUTUBE_KEY environment variable not found, deactivating Youtube.");
|
||||
return;
|
||||
}
|
||||
|
||||
var credentials = {
|
||||
key: process.env.YOUTUBE_KEY,
|
||||
};
|
||||
|
||||
var apiRoot = "https://www.googleapis.com/youtube/v3";
|
||||
|
||||
module.exports.match = function(url, type) {
|
||||
return false;
|
||||
};
|
||||
|
||||
module.exports.search = function(data) {
|
||||
var deferred = Q.defer();
|
||||
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
|
||||
}
|
||||
|
||||
var path = "/search?part=snippet&q=" + encodeURIComponent(query) + "&type=video&videoCaption=any&key=" + credentials.key;
|
||||
request.get(apiRoot + path, function(res) {
|
||||
var result = res.body.items[0];
|
||||
deferred.resolve({
|
||||
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: result.snippet.thumbnails.medium.url,
|
||||
});
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
|
@ -20,6 +20,7 @@
|
|||
"helmet": "^0.5.2",
|
||||
"morgan": "~1.3.0",
|
||||
"playmusic": "^1.1.0",
|
||||
"promised-mongo": "^0.11.1",
|
||||
"q": "^1.1.2",
|
||||
"rdio": "^1.5.2",
|
||||
"serve-favicon": "~2.1.3",
|
||||
|
|
|
@ -107,3 +107,24 @@ h3 {
|
|||
.service-link img {
|
||||
margin-bottom: 7px;
|
||||
}
|
||||
|
||||
.js-video {
|
||||
height: 0;
|
||||
padding-top: 25px;
|
||||
padding-bottom: 67.5%;
|
||||
margin-bottom: 10px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.js-video.widescreen {
|
||||
padding-bottom: 57.25%;
|
||||
}
|
||||
|
||||
.js-video embed, .js-video iframe, .js-video object, .js-video video {
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
}
|
||||
|
|
|
@ -21,37 +21,41 @@ module.exports = function(req, res) {
|
|||
var itemId = req.params.id;
|
||||
var promises = [];
|
||||
|
||||
if (cache[serviceId][type + "-" + itemId]) {
|
||||
res.render(type, {page: type, items: cache[serviceId][type + "-" + itemId]});
|
||||
return;
|
||||
}
|
||||
req.db.matches.findOne({item_id:serviceId + itemId}).then(function(doc) {
|
||||
if (doc) {
|
||||
res.render(type, {page: type, items: doc.items});
|
||||
} else {
|
||||
services[serviceId].lookupId(itemId, type).then(function(item) {
|
||||
|
||||
services[serviceId].lookupId(itemId, type).then(function(item) {
|
||||
|
||||
for (var id in services) {
|
||||
if (id != serviceId) {
|
||||
promises.push(Q.timeout(services[id].search(item), 5000));
|
||||
}
|
||||
}
|
||||
|
||||
Q.allSettled(promises).then(function(results) {
|
||||
var items = results.map(function(result) {
|
||||
if (result.state == "fulfilled") {
|
||||
return result.value;
|
||||
for (var id in services) {
|
||||
if (id != serviceId) {
|
||||
promises.push(Q.timeout(services[id].search(item), 5000));
|
||||
}
|
||||
}
|
||||
}).filter(function(result) {
|
||||
return result || false;
|
||||
});
|
||||
|
||||
items.sort(function(a, b) {
|
||||
return !a.id || !b.id;
|
||||
}).sort(function(a, b) {
|
||||
return !a.streamUrl || b.streamUrl;
|
||||
});
|
||||
Q.allSettled(promises).then(function(results) {
|
||||
var items = results.map(function(result) {
|
||||
if (result.state == "fulfilled") {
|
||||
return result.value;
|
||||
}
|
||||
}).filter(function(result) {
|
||||
return result || false;
|
||||
});
|
||||
|
||||
items.unshift(item);
|
||||
cache[serviceId][type + "-" + itemId] = items;
|
||||
res.render(type, {page: type, items: items});
|
||||
});
|
||||
items.sort(function(a, b) {
|
||||
return !a.id || !b.id;
|
||||
}).sort(function(a, b) {
|
||||
return !a.streamUrl || b.streamUrl;
|
||||
}).sort(function(a, b) {
|
||||
return a.type == "video" && b.type != "video";
|
||||
});
|
||||
|
||||
items.unshift(item);
|
||||
req.db.matches.save({item_id:serviceId + itemId, items:items});
|
||||
cache[serviceId][type + "-" + itemId] = items;
|
||||
res.render(type, {page: type, items: items});
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
@ -17,10 +17,15 @@
|
|||
</div>
|
||||
<div class="row">
|
||||
<% for (var i=0;i < items.length;i++) { var album = items[i]; %>
|
||||
<div class="col-md-3 col-xs-6">
|
||||
<% if (album.type != "video") { %><div class="col-md-3 col-xs-6"><% } else { %><div class="col-md-6 col-xs-12"><% } %>
|
||||
<div class="service <%= i==0 ? "source-service" : "" %>">
|
||||
<div class="matching-from"><%= i==0 ? "Found matches using this link" : "" %></div>
|
||||
<% if (album.streamUrl) { %>
|
||||
<% if (album.type == "video") { %>
|
||||
<div class="js-video widescreen">
|
||||
<iframe width="100%" src="//www.youtube.com/embed/<%= album.id %>" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
<a href="https://www.youtube.com/results?search_query=<%= items[0].name %> <%= items[0].artist.name %>">More Youtube matches</a>
|
||||
<% } else if (album.streamUrl) { %>
|
||||
<a href="<%= album.streamUrl %>"><img src="<%= album.artwork %>" class="img-rounded album-artwork" width="100%"></a>
|
||||
<div class="service-link">
|
||||
<a href="<%= album.streamUrl %>"><img src="/images/<%= album.service %>.png" class="img-rounded"></a>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue