From 0d8a389e05bfa3eaf7157554c02c636d40e1052c Mon Sep 17 00:00:00 2001 From: calzoneman Date: Sun, 7 Jun 2015 11:45:23 -0400 Subject: [PATCH] Remove YouTube v2 API fallback since v2 is dead --- config.template.yaml | 12 +- lib/config.js | 5 +- lib/get-info.js | 257 +------------------------------------------ 3 files changed, 16 insertions(+), 258 deletions(-) diff --git a/config.template.yaml b/config.template.yaml index 4da9d424..78782b1c 100644 --- a/config.template.yaml +++ b/config.template.yaml @@ -120,10 +120,14 @@ mail: # YouTube v3 API key # See https://developers.google.com/youtube/registering_an_application -# Google is closing the v2 API (which allowed anonymous requests) on -# April 20, 2015 so you must register a v3 API key now. -# NOTE: You must generate a Server key under Public API access, NOT a -# browser key. +# YouTube links will not work without this! +# Instructions: +# 1. Go to https://console.developers.google.com/project +# 2. Create a new API project +# 3. On the left sidebar, click "Credentials" under "APIs & auth" +# 4. Click "Create new Key" under "Public API access" +# 5. Click "Server key" +# 6. Under "APIs & auth" click "YouTube Data API" and then click "Enable API" youtube-v3-key: '' # Minutes between saving channel state to disk channel-save-interval: 5 diff --git a/lib/config.js b/lib/config.js index 9f49afe1..8239b7fb 100644 --- a/lib/config.js +++ b/lib/config.js @@ -352,9 +352,8 @@ function preprocessConfig(cfg) { require("cytube-mediaquery/lib/provider/youtube").setApiKey( cfg["youtube-v3-key"]); } else { - Logger.errlog.log("Warning: No YouTube v3 API key set. YouTube lookups will " + - "fall back to the v2 API, which is scheduled for closure soon after " + - "April 20, 2015. See " + + Logger.errlog.log("Warning: No YouTube v3 API key set. YouTube links will " + + "not work. See youtube-v3-key in config.template.yaml and " + "https://developers.google.com/youtube/registering_an_application for " + "information on registering an API key."); } diff --git a/lib/get-info.js b/lib/get-info.js index 52a36813..8b852119 100644 --- a/lib/get-info.js +++ b/lib/get-info.js @@ -66,7 +66,8 @@ var Getters = { /* youtube.com */ yt: function (id, callback) { if (!Config.get("youtube-v3-key")) { - return Getters.yt2(id, callback); + return callback("The YouTube API now requires an API key. Please see the " + + "documentation for youtube-v3-key in config.template.yaml"); } @@ -86,7 +87,8 @@ var Getters = { /* youtube.com playlists */ yp: function (id, callback) { if (!Config.get("youtube-v3-key")) { - return Getters.yp2(id, callback); + return callback("The YouTube API now requires an API key. Please see the " + + "documentation for youtube-v3-key in config.template.yaml"); } YouTube.lookupPlaylist(id).then(function (videos) { @@ -108,7 +110,8 @@ var Getters = { /* youtube.com search */ ytSearch: function (query, callback) { if (!Config.get("youtube-v3-key")) { - return Getters.ytSearch2(query.split(" "), callback); + return callback("The YouTube API now requires an API key. Please see the " + + "documentation for youtube-v3-key in config.template.yaml"); } YouTube.search(query).then(function (res) { @@ -730,254 +733,6 @@ var Getters = { var media = new Media(id, title, "--:--", "hb"); callback(false, media); }, - - /* youtube.com - old v2 API */ - yt2: function (id, callback) { - var sv = Server.getServer(); - - var m = id.match(/([\w-]{11})/); - if (m) { - id = m[1]; - } else { - callback("Invalid ID", null); - return; - } - - var options = { - host: "gdata.youtube.com", - port: 443, - path: "/feeds/api/videos/" + id + "?v=2&alt=json", - method: "GET", - dataType: "jsonp", - timeout: 1000 - }; - - if (Config.get("youtube-v2-key")) { - options.headers = { - "X-Gdata-Key": "key=" + Config.get("youtube-v2-key") - }; - } - - urlRetrieve(https, options, function (status, data) { - switch (status) { - case 200: - break; /* Request is OK, skip to handling data */ - case 400: - return callback("Invalid request", null); - case 403: - return callback("Private video", null); - case 404: - return callback("Video not found", null); - case 500: - case 503: - return callback("Service unavailable", null); - default: - return callback("HTTP " + status, null); - } - - var buffer = data; - try { - data = JSON.parse(data); - /* Check for embedding restrictions */ - if (data.entry.yt$accessControl) { - var ac = data.entry.yt$accessControl; - for (var i = 0; i < ac.length; i++) { - if (ac[i].action === "embed") { - if (ac[i].permission === "denied") { - callback("Embedding disabled", null); - return; - } - break; - } - } - } - - var seconds = data.entry.media$group.yt$duration.seconds; - var title = data.entry.title.$t; - var meta = {}; - /* Check for country restrictions */ - if (data.entry.media$group.media$restriction) { - var rest = data.entry.media$group.media$restriction; - if (rest.length > 0) { - if (rest[0].relationship === "deny") { - meta.restricted = rest[0].$t; - } - } - } - var media = new Media(id, title, seconds, "yt", meta); - callback(false, media); - } catch (e) { - // Gdata version 2 has the rather silly habit of - // returning error codes in XML when I explicitly asked - // for JSON - var m = buffer.match(/([^<]+)<\/internalReason>/); - if (m === null) - m = buffer.match(/([^<]+)<\/code>/); - - var err = e; - if (m) { - if(m[1] === "too_many_recent_calls") { - err = "YouTube is throttling the server right "+ - "now for making too many requests. "+ - "Please try again in a moment."; - } else { - err = m[1]; - } - } - - callback(err, null); - } - }); - }, - - /* youtube.com playlists - old v2 api */ - yp2: function (id, callback, url) { - /** - * NOTE: callback may be called multiple times, once for each <= 25 video - * batch of videos in the list. It will be called in order. - */ - var m = id.match(/([\w-]+)/); - if (m) { - id = m[1]; - } else { - callback("Invalid ID", null); - return; - } - var path = "/feeds/api/playlists/" + id + "?v=2&alt=json"; - /** - * NOTE: the third parameter, url, is used to chain this retriever - * multiple times to get all the videos from a playlist, as each - * request only returns 25 videos. - */ - if (url !== undefined) { - path = "/" + url.split("gdata.youtube.com")[1]; - } - - var options = { - host: "gdata.youtube.com", - port: 443, - path: path, - method: "GET", - dataType: "jsonp", - timeout: 1000 - }; - - if (Config.get("youtube-v2-key")) { - options.headers = { - "X-Gdata-Key": "key=" + Config.get("youtube-v2-key") - }; - } - - urlRetrieve(https, options, function (status, data) { - switch (status) { - case 200: - break; /* Request is OK, skip to handling data */ - case 400: - return callback("Invalid request", null); - case 403: - return callback("Private playlist", null); - case 404: - return callback("Playlist not found", null); - case 500: - case 503: - return callback("Service unavailable", null); - default: - return callback("HTTP " + status, null); - } - - try { - data = JSON.parse(data); - var vids = []; - for(var i in data.feed.entry) { - try { - /** - * FIXME: This should probably check for embed restrictions - * and country restrictions on each video in the list - */ - var item = data.feed.entry[i]; - var id = item.media$group.yt$videoid.$t; - var title = item.title.$t; - var seconds = item.media$group.yt$duration.seconds; - var media = new Media(id, title, seconds, "yt"); - vids.push(media); - } catch(e) { - } - } - - callback(false, vids); - - var links = data.feed.link; - for (var i in links) { - if (links[i].rel === "next") { - /* Look up the next batch of videos from the list */ - Getters["yp2"](id, callback, links[i].href); - } - } - } catch (e) { - callback(e, null); - } - - }); - }, - - /* youtube.com search - old v2 api */ - ytSearch2: function (terms, callback) { - /** - * terms is a list of words from the search query. Each word must be - * encoded properly for use in the request URI - */ - for (var i in terms) { - terms[i] = encodeURIComponent(terms[i]); - } - var query = terms.join("+"); - - var options = { - host: "gdata.youtube.com", - port: 443, - path: "/feeds/api/videos/?q=" + query + "&v=2&alt=json", - method: "GET", - dataType: "jsonp", - timeout: 1000 - }; - - if (Config.get("youtube-v2-key")) { - options.headers = { - "X-Gdata-Key": "key=" + Config.get("youtube-v2-key") - }; - } - - urlRetrieve(https, options, function (status, data) { - if (status !== 200) { - callback("YouTube search: HTTP " + status, null); - return; - } - - try { - data = JSON.parse(data); - var vids = []; - for(var i in data.feed.entry) { - try { - /** - * FIXME: This should probably check for embed restrictions - * and country restrictions on each video in the list - */ - var item = data.feed.entry[i]; - var id = item.media$group.yt$videoid.$t; - var title = item.title.$t; - var seconds = item.media$group.yt$duration.seconds; - var media = new Media(id, title, seconds, "yt"); - media.thumb = item.media$group.media$thumbnail[0]; - vids.push(media); - } catch(e) { - } - } - - callback(false, vids); - } catch(e) { - callback(e, null); - } - }); - }, }; /**