diff --git a/modules/lastfm/lastfm.js b/modules/lastfm/lastfm.js index 9dbdfc1..1ad9813 100644 --- a/modules/lastfm/lastfm.js +++ b/modules/lastfm/lastfm.js @@ -280,22 +280,41 @@ var lastfm = function(dbot) { 'artist': track.artist['#text'] }); } - dbot.api.youtube.search(term, function(body) { - if(_.isObject(body) && _.has(body, 'items') && body.items.length > 0) { - var link = body.items[0].id.videoId - if(link) { - output += ' - http://youtu.be/' + link; - } + + async.parallel({ + youtube: function(cb) { + dbot.api.youtube.search(term, function(body) { + if(_.isObject(body) && _.has(body, 'items') && body.items.length > 0) { + var link = body.items[0].id.videoId + if(link) { + cb(null,"https://youtu.be/" + link); + } else { + cb(null, undefined); + } + } + }); + }, + spotify: function(cb) { + dbot.api.spotify.spotifySearch(term, function(body, url, uri) { + if(body) { + cb(null, { url:url, uri:uri }); + } else { + cb(null, undefined); + } + }); } - - /* dbot.api.spotify.spotifySearch(term, function(body, t) { - if(body) { - output += ' - ' + t; - } - - });*/ + }, function(err, results) { + if (results.youtube || results.spotify) output += " - " + + if (results.youtube) output += results.youtube; + if (results.spotify) { + if (results.youtube) output += " | "; + output += results.spotify.url + " - " + results.spotify.uri; + } + event.reply(output); }); + } else { if(err == 'no_user') { event.reply('Unknown LastFM user.'); diff --git a/modules/spotify/README.md b/modules/spotify/README.md index ec0839f..5e2d0b4 100644 --- a/modules/spotify/README.md +++ b/modules/spotify/README.md @@ -6,6 +6,10 @@ Various Spotify functionality. This module posts information on Spotify links, as well as providing Spotify search functionality. +### config.json +Edit the "api_key_clientid" setting with your Spotify API client ID. Edit the +"api_key_clientsecret" setting with your Spotify API client secret. + ## Commands ### ~spotify [query] diff --git a/modules/spotify/config.json b/modules/spotify/config.json index 0b1135b..4eb225e 100644 --- a/modules/spotify/config.json +++ b/modules/spotify/config.json @@ -1,5 +1,7 @@ { "dependencies": [ "link" ], "ignorable": true, - "outputPrefix": "\u00039spotify\u000f" + "outputPrefix": "\u00039spotify\u000f", + "api_key_clientid": "blah", + "api_key_clientsecret": "blah" } diff --git a/modules/spotify/spotify.js b/modules/spotify/spotify.js index 72e6743..419c31b 100644 --- a/modules/spotify/spotify.js +++ b/modules/spotify/spotify.js @@ -21,16 +21,15 @@ var spotify = function(dbot) { this.spotifyText = '\u00039spotify\u000f'; this.spotifyAuthUrl = 'https://accounts.spotify.com/api/token'; - // ClientID and ClientSecret come from the spotify developer center; you will need to supply your own. - this.spotifyClientID = 'e2491c50879a4d7f900dcefcc74b7c90'; - this.spotifyClientSecret = 'b29da299612e4e659099ab3367ffa3f4'; - this.spotifyAuth = new Buffer(this.spotifyClientID + ":" + this.spotifyClientSecret).toString("base64"); - + this.auth = false; + this.authenticate = function(callback) { + this.auth = this.auth || new Buffer(this.config.api_key_clientid + ":" + this.config.api_key_clientsecret).toString("base64"); + request({ url: this.spotifyAuthUrl, method: "POST", - headers: { Authorization: "Basic " + this.spotifyAuth }, + headers: { Authorization: "Basic " + this.auth }, form: { grant_type: "client_credentials" } }, function(error, response, body) { if (!error && response.statusCode == 200) { @@ -83,11 +82,9 @@ var spotify = function(dbot) { }, function(error, response, body) { if(!error && response.statusCode == 200) { if(_.has(body, 'tracks') && body.tracks.items[0] && _.has(body.tracks.items[0], 'href')) { - var t = body.tracks.items[0].href; - ///*t = t.replace(/:/g, '/'); - t = t.replace(/api.spotify.com\/v1\/tracks/, - 'open.spotify.com/track'); - callback(body, t); + var url = body.tracks.items[0].href; + url = url.replace(/api.spotify.com\/v1\/tracks/, 'open.spotify.com/track'); + callback(body, url, body.tracks.items[0].uri); } else { callback(false); } @@ -132,7 +129,8 @@ var spotify = function(dbot) { function(a) { return a.name }).join(', '), 'album': body.tracks.items[0].album.name, 'track': body.tracks.items[0].name, - 'url': t + 'url': t, + 'uri': body.tracks.items[0].uri })); } else { event.reply(dbot.t('not-found')); diff --git a/modules/youtube/strings.json b/modules/youtube/strings.json index 51a3b55..251d7f7 100644 --- a/modules/youtube/strings.json +++ b/modules/youtube/strings.json @@ -4,6 +4,11 @@ "it": "[{title} di {author} — \u000312▶\u000f{plays} ({minutes}:{seconds}) (\u00039▲{likes}\u000f|\u000312{dislikes}▼\u000f)]", "de": "[{title} von {author} — \u000312▶\u000f{plays} ({minutes}:{seconds}) (\u00039▲{likes}\u000f|\u000312{dislikes}▼\u000f)]" }, + + "yt_playlist": { + "en": "[{title} by {author} - \u000312▶\u000f{videos} videos\u000f)]" + }, + "yt_noresults": { "en": "No results found.", "it": "Nessun risultato.", diff --git a/modules/youtube/youtube.js b/modules/youtube/youtube.js index 0bd73d9..154d1e1 100644 --- a/modules/youtube/youtube.js +++ b/modules/youtube/youtube.js @@ -10,14 +10,16 @@ var youtube = function(dbot) { this.LinkRegex = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/; this.api = { - 'search': function(term, callback) { + 'search': function(term, callback, type) { + type = type || "video" var qs = _.clone(this.params); request.get(this.ApiRoot + 'search', { 'qs': { 'key': this.config.api_key, 'q': term, 'maxResults': 1, - 'part': "snippet" + 'part': "snippet", + 'type': type }, 'json': true }, function(error, response, body) { @@ -58,10 +60,25 @@ var youtube = function(dbot) { } return res; - }.bind(this) + }.bind(this), + + 'formatPlaylistLink': function(v) { + var res = dbot.t('yt_playlist', { + 'title': v.snippet.title, + 'author': v.snippet.channelTitle, + 'videos': v.contentDetails.itemCount + }); + + if (v.id) { + res += " - https://www.youtube.com/playlist?list=" + v.id; + } + + return res; + } }; this.commands = { + // search for a youtube video '~yt': function(event) { this.api.search(event.input[1], function(body) { if(_.isObject(body) && _.has(body, 'items') && body.items.length > 0) { @@ -81,10 +98,34 @@ var youtube = function(dbot) { } else { event.reply(dbot.t('yt_noresults')); } - }.bind(this)); + }.bind(this), "video"); + }, + + // search for a youtube playlist + '~ytpl': function(event) { + this.api.search(event.input[1], function(body) { + if(_.isObject(body) && _.has(body, 'items') && body.items.length > 0) { + request.get(this.ApiRoot + 'playlists' , { + 'qs': { + 'key': this.config.api_key, + 'id': body.items[0].id.playlistId, + 'maxResults': 1, + 'part': "snippet,contentDetails" + }, + 'json': true + }, function(error, response, body) { + if(_.isObject(body) && _.has(body, 'items') && body.items.length > 0) { + event.reply(this.internalAPI.formatPlaylistLink(body.items[0])); + } + }.bind(this)); + } else { + event.reply(dbot.t('yt_noresults')); + } + }.bind(this), "playlist"); } }; this.commands['~yt'].regex = [/^yt (.+)$/, 2]; + this.commands['~ytpl'].regex = [/^ytpl (.+)$/, 2]; this.onLoad = function() { dbot.api.link.addHandler(this.name, this.LinkRegex,