Add youtube to results, persist to mongo

This commit is contained in:
Jonathan Cremin 2014-12-05 16:26:01 +00:00
parent d675ac4e9f
commit f20fecf0d0
7 changed files with 125 additions and 31 deletions

View file

@ -19,6 +19,5 @@ This is in super early development and is incapable of handling getting dugg, ne
On the immediate todo list: On the immediate todo list:
* Use album release year for additional sanity check on matches * 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 * 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 * 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
View file

@ -8,6 +8,7 @@ var session = require('express-session');
var cookieParser = require('cookie-parser'); var cookieParser = require('cookie-parser');
var flash = require('connect-flash'); var flash = require('connect-flash');
var bodyParser = require('body-parser'); var bodyParser = require('body-parser');
var pmongo = require('promised-mongo');
var search = require('./routes/search'); var search = require('./routes/search');
var share = require('./routes/share'); var share = require('./routes/share');
@ -34,6 +35,19 @@ app.use(session({
app.use(flash()); app.use(flash());
app.use(express.static(path.join(__dirname, 'public'))); 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 // force SSL
app.get('*', function(req,res,next) { app.get('*', function(req,res,next) {
if (req.headers['cf-visitor'] && req.headers['cf-visitor'] != '{"scheme":"https"}') { if (req.headers['cf-visitor'] && req.headers['cf-visitor'] != '{"scheme":"https"}') {

50
lib/services/youtube.js Normal file
View 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;
};

View file

@ -20,6 +20,7 @@
"helmet": "^0.5.2", "helmet": "^0.5.2",
"morgan": "~1.3.0", "morgan": "~1.3.0",
"playmusic": "^1.1.0", "playmusic": "^1.1.0",
"promised-mongo": "^0.11.1",
"q": "^1.1.2", "q": "^1.1.2",
"rdio": "^1.5.2", "rdio": "^1.5.2",
"serve-favicon": "~2.1.3", "serve-favicon": "~2.1.3",

View file

@ -107,3 +107,24 @@ h3 {
.service-link img { .service-link img {
margin-bottom: 7px; 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;
}

View file

@ -21,11 +21,10 @@ module.exports = function(req, res) {
var itemId = req.params.id; var itemId = req.params.id;
var promises = []; var promises = [];
if (cache[serviceId][type + "-" + itemId]) { req.db.matches.findOne({item_id:serviceId + itemId}).then(function(doc) {
res.render(type, {page: type, items: cache[serviceId][type + "-" + itemId]}); if (doc) {
return; 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) { for (var id in services) {
@ -47,11 +46,16 @@ module.exports = function(req, res) {
return !a.id || !b.id; return !a.id || !b.id;
}).sort(function(a, b) { }).sort(function(a, b) {
return !a.streamUrl || b.streamUrl; return !a.streamUrl || b.streamUrl;
}).sort(function(a, b) {
return a.type == "video" && b.type != "video";
}); });
items.unshift(item); items.unshift(item);
req.db.matches.save({item_id:serviceId + itemId, items:items});
cache[serviceId][type + "-" + itemId] = items; cache[serviceId][type + "-" + itemId] = items;
res.render(type, {page: type, items: items}); res.render(type, {page: type, items: items});
}); });
}); });
}
});
}; };

View file

@ -17,10 +17,15 @@
</div> </div>
<div class="row"> <div class="row">
<% for (var i=0;i < items.length;i++) { var album = items[i]; %> <% 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="service <%= i==0 ? "source-service" : "" %>">
<div class="matching-from"><%= i==0 ? "Found matches using this link" : "" %></div> <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> <a href="<%= album.streamUrl %>"><img src="<%= album.artwork %>" class="img-rounded album-artwork" width="100%"></a>
<div class="service-link"> <div class="service-link">
<a href="<%= album.streamUrl %>"><img src="/images/<%= album.service %>.png" class="img-rounded"></a> <a href="<%= album.streamUrl %>"><img src="/images/<%= album.service %>.png" class="img-rounded"></a>