From ab234f550623eaea1d5a68b93cf31c596f3b9449 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Tue, 12 May 2015 17:27:34 -0700 Subject: [PATCH 01/58] fixed youtubeplaylist spec --- spec/lib/video_info/providers/youtube_playlist_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/lib/video_info/providers/youtube_playlist_spec.rb b/spec/lib/video_info/providers/youtube_playlist_spec.rb index fc2d7d33..c05521aa 100644 --- a/spec/lib/video_info/providers/youtube_playlist_spec.rb +++ b/spec/lib/video_info/providers/youtube_playlist_spec.rb @@ -44,6 +44,7 @@ context "with playlist PL9hW1uS6HUftLdHI6RIsaf", :vcr do let(:videos) { [ + VideoInfo.new('http://www.youtube.com/watch?v=Oi67QjrXy2w'), VideoInfo.new('http://www.youtube.com/watch?v=_Bt3-WsHfB0'), VideoInfo.new('http://www.youtube.com/watch?v=9g2U12SsRns'), VideoInfo.new('http://www.youtube.com/watch?v=8b0aEoxqqC0'), From 08a7bd1c4c652aae3b0c739690268f0c27e8bdb4 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Fri, 15 May 2015 07:08:54 -0700 Subject: [PATCH 02/58] fixed youtubeplaylist#available? --- lib/video_info/providers/youtubeplaylist.rb | 2 +- spec/lib/video_info/providers/youtube_playlist_spec.rb | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/video_info/providers/youtubeplaylist.rb b/lib/video_info/providers/youtubeplaylist.rb index b94b8f64..dadb7172 100644 --- a/lib/video_info/providers/youtubeplaylist.rb +++ b/lib/video_info/providers/youtubeplaylist.rb @@ -41,7 +41,7 @@ def _url_regex end def _api_path - "/feeds/api/playlists/#{playlist_id}?v=2&alt=json" + "/youtube/v3/playlistItems?part=contentDetails&playlistId=#{playlist_id}&key=#{api_key}" end def _playlist_video_ids diff --git a/spec/lib/video_info/providers/youtube_playlist_spec.rb b/spec/lib/video_info/providers/youtube_playlist_spec.rb index c05521aa..dc740883 100644 --- a/spec/lib/video_info/providers/youtube_playlist_spec.rb +++ b/spec/lib/video_info/providers/youtube_playlist_spec.rb @@ -1,6 +1,9 @@ require 'spec_helper' describe VideoInfo::Providers::YoutubePlaylist do + before(:all) do + VideoInfo.provider_api_keys = { youtube: 'AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0' } + end describe ".usable?" do subject { VideoInfo::Providers::YoutubePlaylist.usable?(url) } From 1a9f5b3ccfb75c16cf1472f1237e4612aa2fc686 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Fri, 15 May 2015 07:28:08 -0700 Subject: [PATCH 03/58] fixed more specs! --- lib/video_info/providers/youtubeplaylist.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/video_info/providers/youtubeplaylist.rb b/lib/video_info/providers/youtubeplaylist.rb index dadb7172..b9931357 100644 --- a/lib/video_info/providers/youtubeplaylist.rb +++ b/lib/video_info/providers/youtubeplaylist.rb @@ -41,7 +41,7 @@ def _url_regex end def _api_path - "/youtube/v3/playlistItems?part=contentDetails&playlistId=#{playlist_id}&key=#{api_key}" + "/youtube/v3/playlists?part=snippet&id=#{playlist_id}&key=#{api_key}" end def _playlist_video_ids From 28c1100712edc83c253622cbedb5fca2505f8eab Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Fri, 15 May 2015 08:01:55 -0700 Subject: [PATCH 04/58] getting there... --- lib/video_info/providers/youtubeplaylist.rb | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/video_info/providers/youtubeplaylist.rb b/lib/video_info/providers/youtubeplaylist.rb index b9931357..b16dd737 100644 --- a/lib/video_info/providers/youtubeplaylist.rb +++ b/lib/video_info/providers/youtubeplaylist.rb @@ -29,11 +29,11 @@ def description private def _playlist_entry - data['feed'] + data['items'] end - def _video_entry - _playlist_entry + def _playlist_items + data['items'] end def _url_regex @@ -45,12 +45,13 @@ def _api_path end def _playlist_video_ids - return [] unless _playlist_entry['entry'] - _playlist_entry['entry'].map do |entry| - entry['media$group']['yt$videoid']['$t'] + return [] unless _playlist_items[0] + _playlist_items.map do |item| + # ugly hack! + thumbnail_url = item['snippet']['thumbnails']['default']['url'] + thumbnail_url.split('https://i.ytimg.com/vi/')[1].split('/default.jpg')[0] end end - end end end From 2ad1a71adb6e0384e88524d1013156c529d61e02 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Fri, 15 May 2015 23:21:15 -0700 Subject: [PATCH 05/58] fixed YoutubePlaylist#Description --- lib/video_info/providers/youtubeplaylist.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/video_info/providers/youtubeplaylist.rb b/lib/video_info/providers/youtubeplaylist.rb index b16dd737..b823d5a8 100644 --- a/lib/video_info/providers/youtubeplaylist.rb +++ b/lib/video_info/providers/youtubeplaylist.rb @@ -8,6 +8,10 @@ def self.usable?(url) url =~ /((youtube\.com)\/playlist)|((youtube\.com)\/embed\/videoseries)/ end + def description + data['items'][0]['snippet']['description'] + end + def videos _playlist_video_ids.map do |entry_id| VideoInfo.new("http://www.youtube.com/watch?v=#{entry_id}") @@ -18,10 +22,6 @@ def embed_url "//www.youtube.com/embed/videoseries?list=#{playlist_id}" end - def description - _playlist_entry['subtitle']['$t'] - end - %w[date keywords duration view_count].each do |method| define_method(method) { nil } end From 155a770efcd6182556175dd285d371acdb3f81de Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Sun, 17 May 2015 02:32:43 -0700 Subject: [PATCH 06/58] fixed another spec --- lib/video_info/providers/youtubeplaylist.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/video_info/providers/youtubeplaylist.rb b/lib/video_info/providers/youtubeplaylist.rb index b823d5a8..8172830a 100644 --- a/lib/video_info/providers/youtubeplaylist.rb +++ b/lib/video_info/providers/youtubeplaylist.rb @@ -45,7 +45,7 @@ def _api_path end def _playlist_video_ids - return [] unless _playlist_items[0] + return [] unless _playlist_items[1] _playlist_items.map do |item| # ugly hack! thumbnail_url = item['snippet']['thumbnails']['default']['url'] From d9100b43197f3e64d3393086bedae8502ea376f3 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Sun, 17 May 2015 03:20:03 -0700 Subject: [PATCH 07/58] removed ugly hack --- lib/video_info/provider.rb | 4 ++-- lib/video_info/providers/youtubeplaylist.rb | 22 ++++++++++++++++----- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/lib/video_info/provider.rb b/lib/video_info/provider.rb index bc8d8dea..1475b829 100644 --- a/lib/video_info/provider.rb +++ b/lib/video_info/provider.rb @@ -56,8 +56,8 @@ def _clean_options(options) options end - def _set_data_from_api - uri = open(_api_url, options) + def _set_data_from_api(api_url = _api_url) + uri = open(api_url, options) MultiJson.load(uri.read) end diff --git a/lib/video_info/providers/youtubeplaylist.rb b/lib/video_info/providers/youtubeplaylist.rb index 8172830a..e0a2421d 100644 --- a/lib/video_info/providers/youtubeplaylist.rb +++ b/lib/video_info/providers/youtubeplaylist.rb @@ -3,6 +3,7 @@ module Providers class YoutubePlaylist < Youtube alias_method :playlist_id, :video_id + attr_accessor :playlist_items_data def self.usable?(url) url =~ /((youtube\.com)\/playlist)|((youtube\.com)\/embed\/videoseries)/ @@ -26,6 +27,7 @@ def embed_url define_method(method) { nil } end + private def _playlist_entry @@ -44,12 +46,22 @@ def _api_path "/youtube/v3/playlists?part=snippet&id=#{playlist_id}&key=#{api_key}" end + def _playlist_items_api_path + "/youtube/v3/playlistItems?part=snippet&playlistId=#{playlist_id}&fields=items&key=#{api_key}" + end + + def _playlist_items_api_url + "https://#{_api_base}#{_playlist_items_api_path}" + end + + def _playlist_items_data + @playlist_items_data ||= _set_data_from_api(_playlist_items_api_url) + end + def _playlist_video_ids - return [] unless _playlist_items[1] - _playlist_items.map do |item| - # ugly hack! - thumbnail_url = item['snippet']['thumbnails']['default']['url'] - thumbnail_url.split('https://i.ytimg.com/vi/')[1].split('/default.jpg')[0] + return [] unless _playlist_items_data + _playlist_items_data['items'].map do |item| + item['snippet']['resourceId']['videoId'] end end end From 1df4f0d40477e13da48bffc2ace08d4e5ef33bdf Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Sun, 17 May 2015 03:26:15 -0700 Subject: [PATCH 08/58] Removed unnecessary code calling #map on an empty array returns an empty array, so no reason to have a check for it --- lib/video_info/providers/youtubeplaylist.rb | 1 - .../with_invalid_playlist/_available_/.yml | 57 ++ .../with_valid_playlist/_available_/.yml | 85 ++ .../_videos/.yml | 568 +++++++++++++ .../_description/.yml | 101 +++ .../_thumbnail_large/.yml | 101 +++ .../_thumbnail_medium/.yml | 101 +++ .../_thumbnail_small/.yml | 101 +++ .../_title/.yml | 101 +++ .../_videos/.yml | 795 ++++++++++++++++++ 10 files changed, 2010 insertions(+), 1 deletion(-) diff --git a/lib/video_info/providers/youtubeplaylist.rb b/lib/video_info/providers/youtubeplaylist.rb index e0a2421d..6cee48d5 100644 --- a/lib/video_info/providers/youtubeplaylist.rb +++ b/lib/video_info/providers/youtubeplaylist.rb @@ -59,7 +59,6 @@ def _playlist_items_data end def _playlist_video_ids - return [] unless _playlist_items_data _playlist_items_data['items'].map do |item| item['snippet']['resourceId']['videoId'] end diff --git a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/_available_/with_invalid_playlist/_available_/.yml b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/_available_/with_invalid_playlist/_available_/.yml index 7691b1ab..54d2354c 100644 --- a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/_available_/with_invalid_playlist/_available_/.yml +++ b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/_available_/with_invalid_playlist/_available_/.yml @@ -43,4 +43,61 @@ http_interactions: string: '' http_version: recorded_at: Mon, 09 Mar 2015 14:06:54 GMT +- request: + method: get + uri: https://www.googleapis.com/youtube/v3/playlists?id=PLA575C81A1FBC04CF_invalid&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Expires: + - Sun, 17 May 2015 10:27:44 GMT + Date: + - Sun, 17 May 2015 10:27:44 GMT + Cache-Control: + - private, max-age=0, must-revalidate, no-transform + Etag: + - '"NO6QTeg0-3ShswIeqLchQ_mzWJs/ZLdVv1yknYCGRyTYfR9cqqqg-3c"' + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '192' + Server: + - GSE + Alternate-Protocol: + - 443:quic,p=1 + body: + encoding: UTF-8 + string: | + { + "kind": "youtube#playlistListResponse", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/ZLdVv1yknYCGRyTYfR9cqqqg-3c\"", + "pageInfo": { + "totalResults": 0, + "resultsPerPage": 0 + }, + "items": [] + } + http_version: + recorded_at: Sun, 17 May 2015 10:25:36 GMT recorded_with: VCR 2.9.3 diff --git a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/_available_/with_valid_playlist/_available_/.yml b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/_available_/with_valid_playlist/_available_/.yml index bc978e42..0de1b2ae 100644 --- a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/_available_/with_valid_playlist/_available_/.yml +++ b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/_available_/with_valid_playlist/_available_/.yml @@ -53,4 +53,89 @@ http_interactions: string: '' http_version: recorded_at: Mon, 09 Mar 2015 14:06:53 GMT +- request: + method: get + uri: https://www.googleapis.com/youtube/v3/playlists?id=PLA575C81A1FBC04CF&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Expires: + - Sun, 17 May 2015 10:27:44 GMT + Date: + - Sun, 17 May 2015 10:27:44 GMT + Cache-Control: + - private, max-age=0, must-revalidate, no-transform + Etag: + - '"NO6QTeg0-3ShswIeqLchQ_mzWJs/775uqayGKfvufZcffd_1ekvmfO0"' + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '881' + Server: + - GSE + Alternate-Protocol: + - 443:quic,p=1 + body: + encoding: UTF-8 + string: | + { + "kind": "youtube#playlistListResponse", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/775uqayGKfvufZcffd_1ekvmfO0\"", + "pageInfo": { + "totalResults": 1, + "resultsPerPage": 1 + }, + "items": [ + { + "kind": "youtube#playlist", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/LWX5mzkRf8mBLPLSjS1m-HQOnbo\"", + "id": "PLA575C81A1FBC04CF", + "snippet": { + "publishedAt": "2010-01-07T22:20:45.000Z", + "channelId": "UC2y5oKUfkQJDKO7cM_OIc3w", + "title": "the century of self", + "description": "", + "thumbnails": { + "default": { + "url": "https://i.ytimg.com/vi/default.jpg" + }, + "medium": { + "url": "https://i.ytimg.com/vi/default.jpg" + }, + "high": { + "url": "https://i.ytimg.com/vi/default.jpg" + } + }, + "channelTitle": "Chris Szanto", + "localized": { + "title": "the century of self", + "description": "" + } + } + } + ] + } + http_version: + recorded_at: Sun, 17 May 2015 10:25:35 GMT recorded_with: VCR 2.9.3 diff --git a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL0E8117603D70E10A_in_embed_path/_videos/.yml b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL0E8117603D70E10A_in_embed_path/_videos/.yml index 214d4bd4..d0e433d1 100644 --- a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL0E8117603D70E10A_in_embed_path/_videos/.yml +++ b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL0E8117603D70E10A_in_embed_path/_videos/.yml @@ -58,4 +58,572 @@ http_interactions: War","type":"plain"}},"yt$playlistId":{"$t":"PL0E8117603D70E10A"}}}' http_version: recorded_at: Mon, 09 Mar 2015 14:06:55 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/vs/playlistitems?id=PL0E8117603D70E10A&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 404 + message: Not Found + headers: + Cache-Control: + - no-cache, no-store, max-age=0, must-revalidate + Pragma: + - no-cache + Expires: + - Fri, 01 Jan 1990 00:00:00 GMT + Date: + - Sun, 17 May 2015 09:58:56 GMT + Vary: + - Origin + - X-Origin + Content-Type: + - text/html; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '29' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: Not Found + http_version: + recorded_at: Sun, 17 May 2015 09:56:47 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/v3/playlistitems?id=PL0E8117603D70E10A&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 404 + message: Not Found + headers: + Cache-Control: + - no-cache, no-store, max-age=0, must-revalidate + Pragma: + - no-cache + Expires: + - Fri, 01 Jan 1990 00:00:00 GMT + Date: + - Sun, 17 May 2015 09:59:26 GMT + Vary: + - Origin + - X-Origin + Content-Type: + - text/html; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '29' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: Not Found + http_version: + recorded_at: Sun, 17 May 2015 09:57:17 GMT +- request: + method: get + uri: https://www.googleapis.com/youtube/v3/playlistitems?id=PL0E8117603D70E10A&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 404 + message: Not Found + headers: + Cache-Control: + - no-cache, no-store, max-age=0, must-revalidate + Pragma: + - no-cache + Expires: + - Fri, 01 Jan 1990 00:00:00 GMT + Date: + - Sun, 17 May 2015 10:00:12 GMT + Vary: + - Origin + - X-Origin + Content-Type: + - text/html; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Server: + - GSE + Alternate-Protocol: + - 443:quic,p=1 + Transfer-Encoding: + - chunked + body: + encoding: ASCII-8BIT + string: Not Found + http_version: + recorded_at: Sun, 17 May 2015 09:58:04 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/v3/playlistitems?key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet&playlistId=PL0E8117603D70E10A + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 404 + message: Not Found + headers: + Cache-Control: + - no-cache, no-store, max-age=0, must-revalidate + Pragma: + - no-cache + Expires: + - Fri, 01 Jan 1990 00:00:00 GMT + Date: + - Sun, 17 May 2015 10:00:40 GMT + Vary: + - Origin + - X-Origin + Content-Type: + - text/html; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '29' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: Not Found + http_version: + recorded_at: Sun, 17 May 2015 09:58:31 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/v3/playlistitems?part=snippet&playlistId=PL0E8117603D70E10A + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 404 + message: Not Found + headers: + Cache-Control: + - no-cache, no-store, max-age=0, must-revalidate + Pragma: + - no-cache + Expires: + - Fri, 01 Jan 1990 00:00:00 GMT + Date: + - Sun, 17 May 2015 10:01:02 GMT + Vary: + - Origin + - X-Origin + Content-Type: + - text/html; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '29' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: Not Found + http_version: + recorded_at: Sun, 17 May 2015 09:58:53 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=PL0E8117603D70E10A + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 403 + message: Forbidden + headers: + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + Date: + - Sun, 17 May 2015 10:01:11 GMT + Expires: + - Sun, 17 May 2015 10:01:11 GMT + Cache-Control: + - private, max-age=0 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '131' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: '{"error":{"errors":[{"domain":"global","reason":"sslRequired","message":"SSL + is required to perform this operation."}],"code":403,"message":"SSL is required + to perform this operation."}}' + http_version: + recorded_at: Sun, 17 May 2015 09:59:02 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/v3/playlistItems?key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet&playlistId=PL0E8117603D70E10A + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 403 + message: Forbidden + headers: + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + Date: + - Sun, 17 May 2015 10:01:28 GMT + Expires: + - Sun, 17 May 2015 10:01:28 GMT + Cache-Control: + - private, max-age=0 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '131' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: '{"error":{"errors":[{"domain":"global","reason":"sslRequired","message":"SSL + is required to perform this operation."}],"code":403,"message":"SSL is required + to perform this operation."}}' + http_version: + recorded_at: Sun, 17 May 2015 09:59:19 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/v3/playlistItems?key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=contentDetails&playlistId=PL0E8117603D70E10A + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 403 + message: Forbidden + headers: + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + Date: + - Sun, 17 May 2015 10:01:57 GMT + Expires: + - Sun, 17 May 2015 10:01:57 GMT + Cache-Control: + - private, max-age=0 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '131' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: '{"error":{"errors":[{"domain":"global","reason":"sslRequired","message":"SSL + is required to perform this operation."}],"code":403,"message":"SSL is required + to perform this operation."}}' + http_version: + recorded_at: Sun, 17 May 2015 09:59:49 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/v3/playlistItems?fields=items&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet&playlistId=PL0E8117603D70E10A + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 403 + message: Forbidden + headers: + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + Date: + - Sun, 17 May 2015 10:03:19 GMT + Expires: + - Sun, 17 May 2015 10:03:19 GMT + Cache-Control: + - private, max-age=0 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '131' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: '{"error":{"errors":[{"domain":"global","reason":"sslRequired","message":"SSL + is required to perform this operation."}],"code":403,"message":"SSL is required + to perform this operation."}}' + http_version: + recorded_at: Sun, 17 May 2015 10:01:10 GMT +- request: + method: get + uri: https://www.googleapis.com/youtube/v3/playlists?id=PL0E8117603D70E10A&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Expires: + - Sun, 17 May 2015 10:07:23 GMT + Date: + - Sun, 17 May 2015 10:07:23 GMT + Cache-Control: + - private, max-age=0, must-revalidate, no-transform + Etag: + - '"NO6QTeg0-3ShswIeqLchQ_mzWJs/AlXCLK8j0l_yW1_HEVHfG1w1HHY"' + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '860' + Server: + - GSE + Alternate-Protocol: + - 443:quic,p=1 + body: + encoding: UTF-8 + string: | + { + "kind": "youtube#playlistListResponse", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/AlXCLK8j0l_yW1_HEVHfG1w1HHY\"", + "pageInfo": { + "totalResults": 1, + "resultsPerPage": 1 + }, + "items": [ + { + "kind": "youtube#playlist", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/x_Bt3sI6005uthvRF1yFLlWNFy0\"", + "id": "PL0E8117603D70E10A", + "snippet": { + "publishedAt": "2009-10-29T17:42:53.000Z", + "channelId": "UCw9KftjwRV1cQqzcUnqzGmA", + "title": "Anthrax War", + "description": "", + "thumbnails": { + "default": { + "url": "https://i.ytimg.com/vi/default.jpg" + }, + "medium": { + "url": "https://i.ytimg.com/vi/default.jpg" + }, + "high": { + "url": "https://i.ytimg.com/vi/default.jpg" + } + }, + "channelTitle": "sprword", + "localized": { + "title": "Anthrax War", + "description": "" + } + } + } + ] + } + http_version: + recorded_at: Sun, 17 May 2015 10:05:14 GMT +- request: + method: get + uri: https://www.googleapis.com/youtube/v3/playlistItems?fields=items&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet&playlistId=PL0E8117603D70E10A + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Expires: + - Sun, 17 May 2015 10:27:46 GMT + Date: + - Sun, 17 May 2015 10:27:46 GMT + Cache-Control: + - private, max-age=0, must-revalidate, no-transform + Etag: + - '"NO6QTeg0-3ShswIeqLchQ_mzWJs/3cxjRXf86G9z5Bg7rup3QfCgrxM"' + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '17' + Server: + - GSE + Alternate-Protocol: + - 443:quic,p=1 + body: + encoding: UTF-8 + string: | + { + "items": [] + } + http_version: + recorded_at: Sun, 17 May 2015 10:25:37 GMT recorded_with: VCR 2.9.3 diff --git a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_description/.yml b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_description/.yml index 82f321e5..ef433480 100644 --- a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_description/.yml +++ b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_description/.yml @@ -93,4 +93,105 @@ http_interactions: Copyright Basics (Global)","type":"plain"},"yt$aspectRatio":{"$t":"widescreen"},"yt$duration":{"seconds":"342"},"yt$uploaded":{"$t":"2013-12-02T23:22:20.000Z"},"yt$uploaderId":{"$t":"UCMDQxm7cUx3yXkfeHa5zJIQ"},"yt$videoid":{"$t":"OQVHWsTHcoc"}},"yt$statistics":{"favoriteCount":"0","viewCount":"1177513"},"yt$position":{"$t":5}}]}}' http_version: recorded_at: Mon, 09 Mar 2015 14:06:54 GMT +- request: + method: get + uri: https://www.googleapis.com/youtube/v3/playlists?id=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Expires: + - Sun, 17 May 2015 10:27:45 GMT + Date: + - Sun, 17 May 2015 10:27:45 GMT + Cache-Control: + - private, max-age=0, must-revalidate, no-transform + Etag: + - '"NO6QTeg0-3ShswIeqLchQ_mzWJs/O7xY08pMODVOI02ahJhG-SRbxcw"' + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '1486' + Server: + - GSE + Alternate-Protocol: + - 443:quic,p=1 + body: + encoding: UTF-8 + string: | + { + "kind": "youtube#playlistListResponse", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/O7xY08pMODVOI02ahJhG-SRbxcw\"", + "pageInfo": { + "totalResults": 1, + "resultsPerPage": 1 + }, + "items": [ + { + "kind": "youtube#playlist", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/tXBNzpf3TuQUOT7zeYiB3hhPWYc\"", + "id": "PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr", + "snippet": { + "publishedAt": "2013-08-09T05:09:51.000Z", + "channelId": "UCMDQxm7cUx3yXkfeHa5zJIQ", + "title": "YouTube Policy and Copyright", + "description": "Learn more about copyright basics, flagging, and the YouTube community.", + "thumbnails": { + "default": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/default.jpg", + "width": 120, + "height": 90 + }, + "medium": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/mqdefault.jpg", + "width": 320, + "height": 180 + }, + "high": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/hqdefault.jpg", + "width": 480, + "height": 360 + }, + "standard": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/sddefault.jpg", + "width": 640, + "height": 480 + }, + "maxres": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/maxresdefault.jpg", + "width": 1280, + "height": 720 + } + }, + "channelTitle": "YouTube Help", + "localized": { + "title": "YouTube Policy and Copyright", + "description": "Learn more about copyright basics, flagging, and the YouTube community." + } + } + } + ] + } + http_version: + recorded_at: Sun, 17 May 2015 10:25:36 GMT recorded_with: VCR 2.9.3 diff --git a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_thumbnail_large/.yml b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_thumbnail_large/.yml index 82f321e5..6996708c 100644 --- a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_thumbnail_large/.yml +++ b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_thumbnail_large/.yml @@ -93,4 +93,105 @@ http_interactions: Copyright Basics (Global)","type":"plain"},"yt$aspectRatio":{"$t":"widescreen"},"yt$duration":{"seconds":"342"},"yt$uploaded":{"$t":"2013-12-02T23:22:20.000Z"},"yt$uploaderId":{"$t":"UCMDQxm7cUx3yXkfeHa5zJIQ"},"yt$videoid":{"$t":"OQVHWsTHcoc"}},"yt$statistics":{"favoriteCount":"0","viewCount":"1177513"},"yt$position":{"$t":5}}]}}' http_version: recorded_at: Mon, 09 Mar 2015 14:06:54 GMT +- request: + method: get + uri: https://www.googleapis.com/youtube/v3/playlists?id=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Expires: + - Sun, 17 May 2015 10:27:46 GMT + Date: + - Sun, 17 May 2015 10:27:46 GMT + Cache-Control: + - private, max-age=0, must-revalidate, no-transform + Etag: + - '"NO6QTeg0-3ShswIeqLchQ_mzWJs/O7xY08pMODVOI02ahJhG-SRbxcw"' + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '1486' + Server: + - GSE + Alternate-Protocol: + - 443:quic,p=1 + body: + encoding: UTF-8 + string: | + { + "kind": "youtube#playlistListResponse", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/O7xY08pMODVOI02ahJhG-SRbxcw\"", + "pageInfo": { + "totalResults": 1, + "resultsPerPage": 1 + }, + "items": [ + { + "kind": "youtube#playlist", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/tXBNzpf3TuQUOT7zeYiB3hhPWYc\"", + "id": "PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr", + "snippet": { + "publishedAt": "2013-08-09T05:09:51.000Z", + "channelId": "UCMDQxm7cUx3yXkfeHa5zJIQ", + "title": "YouTube Policy and Copyright", + "description": "Learn more about copyright basics, flagging, and the YouTube community.", + "thumbnails": { + "default": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/default.jpg", + "width": 120, + "height": 90 + }, + "medium": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/mqdefault.jpg", + "width": 320, + "height": 180 + }, + "high": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/hqdefault.jpg", + "width": 480, + "height": 360 + }, + "standard": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/sddefault.jpg", + "width": 640, + "height": 480 + }, + "maxres": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/maxresdefault.jpg", + "width": 1280, + "height": 720 + } + }, + "channelTitle": "YouTube Help", + "localized": { + "title": "YouTube Policy and Copyright", + "description": "Learn more about copyright basics, flagging, and the YouTube community." + } + } + } + ] + } + http_version: + recorded_at: Sun, 17 May 2015 10:25:37 GMT recorded_with: VCR 2.9.3 diff --git a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_thumbnail_medium/.yml b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_thumbnail_medium/.yml index 82f321e5..ef433480 100644 --- a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_thumbnail_medium/.yml +++ b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_thumbnail_medium/.yml @@ -93,4 +93,105 @@ http_interactions: Copyright Basics (Global)","type":"plain"},"yt$aspectRatio":{"$t":"widescreen"},"yt$duration":{"seconds":"342"},"yt$uploaded":{"$t":"2013-12-02T23:22:20.000Z"},"yt$uploaderId":{"$t":"UCMDQxm7cUx3yXkfeHa5zJIQ"},"yt$videoid":{"$t":"OQVHWsTHcoc"}},"yt$statistics":{"favoriteCount":"0","viewCount":"1177513"},"yt$position":{"$t":5}}]}}' http_version: recorded_at: Mon, 09 Mar 2015 14:06:54 GMT +- request: + method: get + uri: https://www.googleapis.com/youtube/v3/playlists?id=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Expires: + - Sun, 17 May 2015 10:27:45 GMT + Date: + - Sun, 17 May 2015 10:27:45 GMT + Cache-Control: + - private, max-age=0, must-revalidate, no-transform + Etag: + - '"NO6QTeg0-3ShswIeqLchQ_mzWJs/O7xY08pMODVOI02ahJhG-SRbxcw"' + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '1486' + Server: + - GSE + Alternate-Protocol: + - 443:quic,p=1 + body: + encoding: UTF-8 + string: | + { + "kind": "youtube#playlistListResponse", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/O7xY08pMODVOI02ahJhG-SRbxcw\"", + "pageInfo": { + "totalResults": 1, + "resultsPerPage": 1 + }, + "items": [ + { + "kind": "youtube#playlist", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/tXBNzpf3TuQUOT7zeYiB3hhPWYc\"", + "id": "PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr", + "snippet": { + "publishedAt": "2013-08-09T05:09:51.000Z", + "channelId": "UCMDQxm7cUx3yXkfeHa5zJIQ", + "title": "YouTube Policy and Copyright", + "description": "Learn more about copyright basics, flagging, and the YouTube community.", + "thumbnails": { + "default": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/default.jpg", + "width": 120, + "height": 90 + }, + "medium": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/mqdefault.jpg", + "width": 320, + "height": 180 + }, + "high": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/hqdefault.jpg", + "width": 480, + "height": 360 + }, + "standard": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/sddefault.jpg", + "width": 640, + "height": 480 + }, + "maxres": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/maxresdefault.jpg", + "width": 1280, + "height": 720 + } + }, + "channelTitle": "YouTube Help", + "localized": { + "title": "YouTube Policy and Copyright", + "description": "Learn more about copyright basics, flagging, and the YouTube community." + } + } + } + ] + } + http_version: + recorded_at: Sun, 17 May 2015 10:25:36 GMT recorded_with: VCR 2.9.3 diff --git a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_thumbnail_small/.yml b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_thumbnail_small/.yml index 82f321e5..ef433480 100644 --- a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_thumbnail_small/.yml +++ b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_thumbnail_small/.yml @@ -93,4 +93,105 @@ http_interactions: Copyright Basics (Global)","type":"plain"},"yt$aspectRatio":{"$t":"widescreen"},"yt$duration":{"seconds":"342"},"yt$uploaded":{"$t":"2013-12-02T23:22:20.000Z"},"yt$uploaderId":{"$t":"UCMDQxm7cUx3yXkfeHa5zJIQ"},"yt$videoid":{"$t":"OQVHWsTHcoc"}},"yt$statistics":{"favoriteCount":"0","viewCount":"1177513"},"yt$position":{"$t":5}}]}}' http_version: recorded_at: Mon, 09 Mar 2015 14:06:54 GMT +- request: + method: get + uri: https://www.googleapis.com/youtube/v3/playlists?id=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Expires: + - Sun, 17 May 2015 10:27:45 GMT + Date: + - Sun, 17 May 2015 10:27:45 GMT + Cache-Control: + - private, max-age=0, must-revalidate, no-transform + Etag: + - '"NO6QTeg0-3ShswIeqLchQ_mzWJs/O7xY08pMODVOI02ahJhG-SRbxcw"' + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '1486' + Server: + - GSE + Alternate-Protocol: + - 443:quic,p=1 + body: + encoding: UTF-8 + string: | + { + "kind": "youtube#playlistListResponse", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/O7xY08pMODVOI02ahJhG-SRbxcw\"", + "pageInfo": { + "totalResults": 1, + "resultsPerPage": 1 + }, + "items": [ + { + "kind": "youtube#playlist", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/tXBNzpf3TuQUOT7zeYiB3hhPWYc\"", + "id": "PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr", + "snippet": { + "publishedAt": "2013-08-09T05:09:51.000Z", + "channelId": "UCMDQxm7cUx3yXkfeHa5zJIQ", + "title": "YouTube Policy and Copyright", + "description": "Learn more about copyright basics, flagging, and the YouTube community.", + "thumbnails": { + "default": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/default.jpg", + "width": 120, + "height": 90 + }, + "medium": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/mqdefault.jpg", + "width": 320, + "height": 180 + }, + "high": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/hqdefault.jpg", + "width": 480, + "height": 360 + }, + "standard": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/sddefault.jpg", + "width": 640, + "height": 480 + }, + "maxres": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/maxresdefault.jpg", + "width": 1280, + "height": 720 + } + }, + "channelTitle": "YouTube Help", + "localized": { + "title": "YouTube Policy and Copyright", + "description": "Learn more about copyright basics, flagging, and the YouTube community." + } + } + } + ] + } + http_version: + recorded_at: Sun, 17 May 2015 10:25:36 GMT recorded_with: VCR 2.9.3 diff --git a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_title/.yml b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_title/.yml index 90a06a3c..da18c146 100644 --- a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_title/.yml +++ b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_title/.yml @@ -95,4 +95,105 @@ http_interactions: Copyright Basics (Global)","type":"plain"},"yt$aspectRatio":{"$t":"widescreen"},"yt$duration":{"seconds":"342"},"yt$uploaded":{"$t":"2013-12-02T23:22:20.000Z"},"yt$uploaderId":{"$t":"UCMDQxm7cUx3yXkfeHa5zJIQ"},"yt$videoid":{"$t":"OQVHWsTHcoc"}},"yt$statistics":{"favoriteCount":"0","viewCount":"1177513"},"yt$position":{"$t":5}}]}}' http_version: recorded_at: Mon, 09 Mar 2015 14:06:54 GMT +- request: + method: get + uri: https://www.googleapis.com/youtube/v3/playlists?id=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Expires: + - Sun, 17 May 2015 10:27:45 GMT + Date: + - Sun, 17 May 2015 10:27:45 GMT + Cache-Control: + - private, max-age=0, must-revalidate, no-transform + Etag: + - '"NO6QTeg0-3ShswIeqLchQ_mzWJs/O7xY08pMODVOI02ahJhG-SRbxcw"' + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '1486' + Server: + - GSE + Alternate-Protocol: + - 443:quic,p=1 + body: + encoding: UTF-8 + string: | + { + "kind": "youtube#playlistListResponse", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/O7xY08pMODVOI02ahJhG-SRbxcw\"", + "pageInfo": { + "totalResults": 1, + "resultsPerPage": 1 + }, + "items": [ + { + "kind": "youtube#playlist", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/tXBNzpf3TuQUOT7zeYiB3hhPWYc\"", + "id": "PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr", + "snippet": { + "publishedAt": "2013-08-09T05:09:51.000Z", + "channelId": "UCMDQxm7cUx3yXkfeHa5zJIQ", + "title": "YouTube Policy and Copyright", + "description": "Learn more about copyright basics, flagging, and the YouTube community.", + "thumbnails": { + "default": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/default.jpg", + "width": 120, + "height": 90 + }, + "medium": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/mqdefault.jpg", + "width": 320, + "height": 180 + }, + "high": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/hqdefault.jpg", + "width": 480, + "height": 360 + }, + "standard": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/sddefault.jpg", + "width": 640, + "height": 480 + }, + "maxres": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/maxresdefault.jpg", + "width": 1280, + "height": 720 + } + }, + "channelTitle": "YouTube Help", + "localized": { + "title": "YouTube Policy and Copyright", + "description": "Learn more about copyright basics, flagging, and the YouTube community." + } + } + } + ] + } + http_version: + recorded_at: Sun, 17 May 2015 10:25:36 GMT recorded_with: VCR 2.9.3 diff --git a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_videos/.yml b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_videos/.yml index 82f321e5..f206bbfd 100644 --- a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_videos/.yml +++ b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_videos/.yml @@ -93,4 +93,799 @@ http_interactions: Copyright Basics (Global)","type":"plain"},"yt$aspectRatio":{"$t":"widescreen"},"yt$duration":{"seconds":"342"},"yt$uploaded":{"$t":"2013-12-02T23:22:20.000Z"},"yt$uploaderId":{"$t":"UCMDQxm7cUx3yXkfeHa5zJIQ"},"yt$videoid":{"$t":"OQVHWsTHcoc"}},"yt$statistics":{"favoriteCount":"0","viewCount":"1177513"},"yt$position":{"$t":5}}]}}' http_version: recorded_at: Mon, 09 Mar 2015 14:06:54 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/vs/playlistitems?id=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 404 + message: Not Found + headers: + Cache-Control: + - no-cache, no-store, max-age=0, must-revalidate + Pragma: + - no-cache + Expires: + - Fri, 01 Jan 1990 00:00:00 GMT + Date: + - Sun, 17 May 2015 09:58:55 GMT + Vary: + - Origin + - X-Origin + Content-Type: + - text/html; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '29' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: Not Found + http_version: + recorded_at: Sun, 17 May 2015 09:56:46 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/v3/playlistitems?id=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 404 + message: Not Found + headers: + Cache-Control: + - no-cache, no-store, max-age=0, must-revalidate + Pragma: + - no-cache + Expires: + - Fri, 01 Jan 1990 00:00:00 GMT + Date: + - Sun, 17 May 2015 09:59:26 GMT + Vary: + - Origin + - X-Origin + Content-Type: + - text/html; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '29' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: Not Found + http_version: + recorded_at: Sun, 17 May 2015 09:57:17 GMT +- request: + method: get + uri: https://www.googleapis.com/youtube/v3/playlistitems?id=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 404 + message: Not Found + headers: + Cache-Control: + - no-cache, no-store, max-age=0, must-revalidate + Pragma: + - no-cache + Expires: + - Fri, 01 Jan 1990 00:00:00 GMT + Date: + - Sun, 17 May 2015 10:00:12 GMT + Vary: + - Origin + - X-Origin + Content-Type: + - text/html; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Server: + - GSE + Alternate-Protocol: + - 443:quic,p=1 + Transfer-Encoding: + - chunked + body: + encoding: ASCII-8BIT + string: Not Found + http_version: + recorded_at: Sun, 17 May 2015 09:58:03 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/v3/playlistitems?key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet&playlistId=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 404 + message: Not Found + headers: + Cache-Control: + - no-cache, no-store, max-age=0, must-revalidate + Pragma: + - no-cache + Expires: + - Fri, 01 Jan 1990 00:00:00 GMT + Date: + - Sun, 17 May 2015 10:00:40 GMT + Vary: + - Origin + - X-Origin + Content-Type: + - text/html; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '29' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: Not Found + http_version: + recorded_at: Sun, 17 May 2015 09:58:31 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/v3/playlistitems?part=snippet&playlistId=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 404 + message: Not Found + headers: + Cache-Control: + - no-cache, no-store, max-age=0, must-revalidate + Pragma: + - no-cache + Expires: + - Fri, 01 Jan 1990 00:00:00 GMT + Date: + - Sun, 17 May 2015 10:01:01 GMT + Vary: + - Origin + - X-Origin + Content-Type: + - text/html; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '29' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: Not Found + http_version: + recorded_at: Sun, 17 May 2015 09:58:53 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 403 + message: Forbidden + headers: + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + Date: + - Sun, 17 May 2015 10:01:11 GMT + Expires: + - Sun, 17 May 2015 10:01:11 GMT + Cache-Control: + - private, max-age=0 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '131' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: '{"error":{"errors":[{"domain":"global","reason":"sslRequired","message":"SSL + is required to perform this operation."}],"code":403,"message":"SSL is required + to perform this operation."}}' + http_version: + recorded_at: Sun, 17 May 2015 09:59:02 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/v3/playlistItems?key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet&playlistId=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 403 + message: Forbidden + headers: + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + Date: + - Sun, 17 May 2015 10:01:28 GMT + Expires: + - Sun, 17 May 2015 10:01:28 GMT + Cache-Control: + - private, max-age=0 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '131' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: '{"error":{"errors":[{"domain":"global","reason":"sslRequired","message":"SSL + is required to perform this operation."}],"code":403,"message":"SSL is required + to perform this operation."}}' + http_version: + recorded_at: Sun, 17 May 2015 09:59:19 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/v3/playlistItems?key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=contentDetails&playlistId=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 403 + message: Forbidden + headers: + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + Date: + - Sun, 17 May 2015 10:01:57 GMT + Expires: + - Sun, 17 May 2015 10:01:57 GMT + Cache-Control: + - private, max-age=0 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '131' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: '{"error":{"errors":[{"domain":"global","reason":"sslRequired","message":"SSL + is required to perform this operation."}],"code":403,"message":"SSL is required + to perform this operation."}}' + http_version: + recorded_at: Sun, 17 May 2015 09:59:48 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/v3/playlistItems?fields=items&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet&playlistId=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 403 + message: Forbidden + headers: + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + Date: + - Sun, 17 May 2015 10:03:19 GMT + Expires: + - Sun, 17 May 2015 10:03:19 GMT + Cache-Control: + - private, max-age=0 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '131' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: '{"error":{"errors":[{"domain":"global","reason":"sslRequired","message":"SSL + is required to perform this operation."}],"code":403,"message":"SSL is required + to perform this operation."}}' + http_version: + recorded_at: Sun, 17 May 2015 10:01:10 GMT +- request: + method: get + uri: https://www.googleapis.com/youtube/v3/playlists?id=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Expires: + - Sun, 17 May 2015 10:07:23 GMT + Date: + - Sun, 17 May 2015 10:07:23 GMT + Cache-Control: + - private, max-age=0, must-revalidate, no-transform + Etag: + - '"NO6QTeg0-3ShswIeqLchQ_mzWJs/O7xY08pMODVOI02ahJhG-SRbxcw"' + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '1486' + Server: + - GSE + Alternate-Protocol: + - 443:quic,p=1 + body: + encoding: UTF-8 + string: | + { + "kind": "youtube#playlistListResponse", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/O7xY08pMODVOI02ahJhG-SRbxcw\"", + "pageInfo": { + "totalResults": 1, + "resultsPerPage": 1 + }, + "items": [ + { + "kind": "youtube#playlist", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/tXBNzpf3TuQUOT7zeYiB3hhPWYc\"", + "id": "PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr", + "snippet": { + "publishedAt": "2013-08-09T05:09:51.000Z", + "channelId": "UCMDQxm7cUx3yXkfeHa5zJIQ", + "title": "YouTube Policy and Copyright", + "description": "Learn more about copyright basics, flagging, and the YouTube community.", + "thumbnails": { + "default": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/default.jpg", + "width": 120, + "height": 90 + }, + "medium": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/mqdefault.jpg", + "width": 320, + "height": 180 + }, + "high": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/hqdefault.jpg", + "width": 480, + "height": 360 + }, + "standard": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/sddefault.jpg", + "width": 640, + "height": 480 + }, + "maxres": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/maxresdefault.jpg", + "width": 1280, + "height": 720 + } + }, + "channelTitle": "YouTube Help", + "localized": { + "title": "YouTube Policy and Copyright", + "description": "Learn more about copyright basics, flagging, and the YouTube community." + } + } + } + ] + } + http_version: + recorded_at: Sun, 17 May 2015 10:05:14 GMT +- request: + method: get + uri: https://www.googleapis.com/youtube/v3/playlistItems?fields=items&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet&playlistId=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Expires: + - Sun, 17 May 2015 10:27:46 GMT + Date: + - Sun, 17 May 2015 10:27:46 GMT + Cache-Control: + - private, max-age=0, must-revalidate, no-transform + Etag: + - '"NO6QTeg0-3ShswIeqLchQ_mzWJs/0-dRuoFefu59MRZrJ9OQJh1wEio"' + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '6724' + Server: + - GSE + Alternate-Protocol: + - 443:quic,p=1 + body: + encoding: UTF-8 + string: | + { + "items": [ + { + "kind": "youtube#playlistItem", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/K-gvAWZR6aZKd0do3Xn3MtdmfGM\"", + "id": "PLa0L99Uc4VSCXhwLjoLzxv8xxws5JLbfTP3YqbDI0DxQ", + "snippet": { + "publishedAt": "2015-04-22T21:47:21.000Z", + "channelId": "UCMDQxm7cUx3yXkfeHa5zJIQ", + "title": "Account termination on YouTube", + "description": "Learn more about account termination in the YouTube Help Center: https://support.google.com/youtube/answer/2802168", + "thumbnails": { + "default": { + "url": "https://i.ytimg.com/vi/Oi67QjrXy2w/default.jpg", + "width": 120, + "height": 90 + }, + "medium": { + "url": "https://i.ytimg.com/vi/Oi67QjrXy2w/mqdefault.jpg", + "width": 320, + "height": 180 + }, + "high": { + "url": "https://i.ytimg.com/vi/Oi67QjrXy2w/hqdefault.jpg", + "width": 480, + "height": 360 + }, + "standard": { + "url": "https://i.ytimg.com/vi/Oi67QjrXy2w/sddefault.jpg", + "width": 640, + "height": 480 + }, + "maxres": { + "url": "https://i.ytimg.com/vi/Oi67QjrXy2w/maxresdefault.jpg", + "width": 1280, + "height": 720 + } + }, + "channelTitle": "YouTube Help", + "playlistId": "PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr", + "position": 0, + "resourceId": { + "kind": "youtube#video", + "videoId": "Oi67QjrXy2w" + } + } + }, + { + "kind": "youtube#playlistItem", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/9EB6BjQI7LVTh8ZS5KAmyhTIlTI\"", + "id": "PLa0L99Uc4VSCXhwLjoLzxvw2SdI2zb8sl0kYOz9dDFO0", + "snippet": { + "publishedAt": "2015-04-22T21:48:43.000Z", + "channelId": "UCMDQxm7cUx3yXkfeHa5zJIQ", + "title": "YouTube Copyright Basics (Global)", + "description": "", + "thumbnails": { + "default": { + "url": "https://i.ytimg.com/vi/OQVHWsTHcoc/default.jpg", + "width": 120, + "height": 90 + }, + "medium": { + "url": "https://i.ytimg.com/vi/OQVHWsTHcoc/mqdefault.jpg", + "width": 320, + "height": 180 + }, + "high": { + "url": "https://i.ytimg.com/vi/OQVHWsTHcoc/hqdefault.jpg", + "width": 480, + "height": 360 + }, + "standard": { + "url": "https://i.ytimg.com/vi/OQVHWsTHcoc/sddefault.jpg", + "width": 640, + "height": 480 + } + }, + "channelTitle": "YouTube Help", + "playlistId": "PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr", + "position": 1, + "resourceId": { + "kind": "youtube#video", + "videoId": "OQVHWsTHcoc" + } + } + }, + { + "kind": "youtube#playlistItem", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/FtVY3O5dQ8V9f_gX2fAT2V2BcRE\"", + "id": "PLa0L99Uc4VSCXhwLjoLzxvzeL5__87gFCq75gAaFE6gY", + "snippet": { + "publishedAt": "2013-09-13T16:49:50.000Z", + "channelId": "UCMDQxm7cUx3yXkfeHa5zJIQ", + "title": "Buying YouTube views through third-party services", + "description": "Viewcounts serve as a way to recognize and surface great content. Since views are so important, it's no surprise that an ecosystem of businesses has evolved around artificially helping creators get and create YouTube views, likes, and subscribers.\n\nHowever, paying for views obtained through some of these companies could be a violation of our terms, which exist, in part, to make sure the views on any YouTube video come from real, genuine people.\n\nPlease visit our Help Center article for more info!\n\nhttps://support.google.com/youtube/answer/3399767", + "thumbnails": { + "default": { + "url": "https://i.ytimg.com/vi/_Bt3-WsHfB0/default.jpg", + "width": 120, + "height": 90 + }, + "medium": { + "url": "https://i.ytimg.com/vi/_Bt3-WsHfB0/mqdefault.jpg", + "width": 320, + "height": 180 + }, + "high": { + "url": "https://i.ytimg.com/vi/_Bt3-WsHfB0/hqdefault.jpg", + "width": 480, + "height": 360 + }, + "standard": { + "url": "https://i.ytimg.com/vi/_Bt3-WsHfB0/sddefault.jpg", + "width": 640, + "height": 480 + }, + "maxres": { + "url": "https://i.ytimg.com/vi/_Bt3-WsHfB0/maxresdefault.jpg", + "width": 1280, + "height": 720 + } + }, + "channelTitle": "YouTube Help", + "playlistId": "PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr", + "position": 2, + "resourceId": { + "kind": "youtube#video", + "videoId": "_Bt3-WsHfB0" + } + } + }, + { + "kind": "youtube#playlistItem", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/aZB_rEa-HGKt3gO7mbYt_rv2DGM\"", + "id": "PLa0L99Uc4VSCXhwLjoLzxv5JvZLgV8BItvSbpyhS9_p8", + "snippet": { + "publishedAt": "2013-08-09T05:09:51.000Z", + "channelId": "UCMDQxm7cUx3yXkfeHa5zJIQ", + "title": "YouTube Content ID", + "description": "Learn more about YouTube's Content ID system.", + "thumbnails": { + "default": { + "url": "https://i.ytimg.com/vi/9g2U12SsRns/default.jpg", + "width": 120, + "height": 90 + }, + "medium": { + "url": "https://i.ytimg.com/vi/9g2U12SsRns/mqdefault.jpg", + "width": 320, + "height": 180 + }, + "high": { + "url": "https://i.ytimg.com/vi/9g2U12SsRns/hqdefault.jpg", + "width": 480, + "height": 360 + } + }, + "channelTitle": "YouTube Help", + "playlistId": "PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr", + "position": 3, + "resourceId": { + "kind": "youtube#video", + "videoId": "9g2U12SsRns" + } + } + }, + { + "kind": "youtube#playlistItem", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/9AILAwA-TinybwmctvWPN47Ii34\"", + "id": "PLa0L99Uc4VSCXhwLjoLzxv4Zz231WHvzzM2lBS3jjPZs", + "snippet": { + "publishedAt": "2013-08-09T05:09:51.000Z", + "channelId": "UCMDQxm7cUx3yXkfeHa5zJIQ", + "title": "Reporting and Policy Enforcement on YouTube", + "description": "This video explains the basics of reporting on YouTube. \n\nTo learn more about reporting, policies and safety please visit our Policy and Safety hub, http://www.youtube.com/yt/policyandsafety/", + "thumbnails": { + "default": { + "url": "https://i.ytimg.com/vi/6c3mHikRz0I/default.jpg", + "width": 120, + "height": 90 + }, + "medium": { + "url": "https://i.ytimg.com/vi/6c3mHikRz0I/mqdefault.jpg", + "width": 320, + "height": 180 + }, + "high": { + "url": "https://i.ytimg.com/vi/6c3mHikRz0I/hqdefault.jpg", + "width": 480, + "height": 360 + }, + "standard": { + "url": "https://i.ytimg.com/vi/6c3mHikRz0I/sddefault.jpg", + "width": 640, + "height": 480 + }, + "maxres": { + "url": "https://i.ytimg.com/vi/6c3mHikRz0I/maxresdefault.jpg", + "width": 1280, + "height": 720 + } + }, + "channelTitle": "YouTube Help", + "playlistId": "PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr", + "position": 4, + "resourceId": { + "kind": "youtube#video", + "videoId": "6c3mHikRz0I" + } + } + } + ] + } + http_version: + recorded_at: Sun, 17 May 2015 10:25:37 GMT recorded_with: VCR 2.9.3 From de23edbcb24d5d8050d4bfc3126408df538f4119 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Sun, 17 May 2015 03:28:58 -0700 Subject: [PATCH 09/58] fixed houndci warning --- lib/video_info/providers/youtubeplaylist.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/video_info/providers/youtubeplaylist.rb b/lib/video_info/providers/youtubeplaylist.rb index 6cee48d5..85e2becc 100644 --- a/lib/video_info/providers/youtubeplaylist.rb +++ b/lib/video_info/providers/youtubeplaylist.rb @@ -27,7 +27,6 @@ def embed_url define_method(method) { nil } end - private def _playlist_entry From ca174a7c1af43e11e6c1353ef7489d74a6bd5ecc Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Sat, 23 May 2015 08:16:49 -0700 Subject: [PATCH 10/58] added YoutubePlaylistAPI module --- lib/video_info/providers/youtubeplaylist.rb | 8 ++++++++ lib/video_info/providers/youtubeplaylist_api.rb | 5 +++++ 2 files changed, 13 insertions(+) create mode 100644 lib/video_info/providers/youtubeplaylist_api.rb diff --git a/lib/video_info/providers/youtubeplaylist.rb b/lib/video_info/providers/youtubeplaylist.rb index 85e2becc..0caf6067 100644 --- a/lib/video_info/providers/youtubeplaylist.rb +++ b/lib/video_info/providers/youtubeplaylist.rb @@ -1,3 +1,5 @@ +require_relative 'youtubeplaylist_api' + class VideoInfo module Providers class YoutubePlaylist < Youtube @@ -5,6 +7,12 @@ class YoutubePlaylist < Youtube alias_method :playlist_id, :video_id attr_accessor :playlist_items_data + def initialize(url, options = {}) + extend YoutubePlaylistAPI + + super(url, options) + end + def self.usable?(url) url =~ /((youtube\.com)\/playlist)|((youtube\.com)\/embed\/videoseries)/ end diff --git a/lib/video_info/providers/youtubeplaylist_api.rb b/lib/video_info/providers/youtubeplaylist_api.rb new file mode 100644 index 00000000..f1a33753 --- /dev/null +++ b/lib/video_info/providers/youtubeplaylist_api.rb @@ -0,0 +1,5 @@ +class VideoInfo + module YoutubePlaylistAPI + + end +end From 10a7d260f1410a5233dcffd4378d6ec6cb68187d Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Sat, 23 May 2015 08:18:04 -0700 Subject: [PATCH 11/58] moved public methods out of YoutubePlaylist --- lib/video_info/providers/youtubeplaylist.rb | 10 ---------- lib/video_info/providers/youtubeplaylist_api.rb | 8 ++++++++ 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/lib/video_info/providers/youtubeplaylist.rb b/lib/video_info/providers/youtubeplaylist.rb index 0caf6067..e8639317 100644 --- a/lib/video_info/providers/youtubeplaylist.rb +++ b/lib/video_info/providers/youtubeplaylist.rb @@ -17,16 +17,6 @@ def self.usable?(url) url =~ /((youtube\.com)\/playlist)|((youtube\.com)\/embed\/videoseries)/ end - def description - data['items'][0]['snippet']['description'] - end - - def videos - _playlist_video_ids.map do |entry_id| - VideoInfo.new("http://www.youtube.com/watch?v=#{entry_id}") - end - end - def embed_url "//www.youtube.com/embed/videoseries?list=#{playlist_id}" end diff --git a/lib/video_info/providers/youtubeplaylist_api.rb b/lib/video_info/providers/youtubeplaylist_api.rb index f1a33753..57b0c434 100644 --- a/lib/video_info/providers/youtubeplaylist_api.rb +++ b/lib/video_info/providers/youtubeplaylist_api.rb @@ -1,5 +1,13 @@ class VideoInfo module YoutubePlaylistAPI + def description + data['items'][0]['snippet']['description'] + end + def videos + _playlist_video_ids.map do |entry_id| + VideoInfo.new("http://www.youtube.com/watch?v=#{entry_id}") + end + end end end From 06c985a9cac245b97ec5158aaf6c4e861dbbd164 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Sat, 23 May 2015 08:20:58 -0700 Subject: [PATCH 12/58] moved private functions to YoutubePlaylistAPI module --- lib/video_info/providers/youtubeplaylist.rb | 31 ------------------ .../providers/youtubeplaylist_api.rb | 32 +++++++++++++++++++ 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/lib/video_info/providers/youtubeplaylist.rb b/lib/video_info/providers/youtubeplaylist.rb index e8639317..21cf6841 100644 --- a/lib/video_info/providers/youtubeplaylist.rb +++ b/lib/video_info/providers/youtubeplaylist.rb @@ -3,7 +3,6 @@ class VideoInfo module Providers class YoutubePlaylist < Youtube - alias_method :playlist_id, :video_id attr_accessor :playlist_items_data @@ -27,39 +26,9 @@ def embed_url private - def _playlist_entry - data['items'] - end - - def _playlist_items - data['items'] - end - def _url_regex /youtube.com\/playlist\?p=(\S*)|youtube.com\/embed\/videoseries\?list=([a-zA-Z0-9-]*)/ end - - def _api_path - "/youtube/v3/playlists?part=snippet&id=#{playlist_id}&key=#{api_key}" - end - - def _playlist_items_api_path - "/youtube/v3/playlistItems?part=snippet&playlistId=#{playlist_id}&fields=items&key=#{api_key}" - end - - def _playlist_items_api_url - "https://#{_api_base}#{_playlist_items_api_path}" - end - - def _playlist_items_data - @playlist_items_data ||= _set_data_from_api(_playlist_items_api_url) - end - - def _playlist_video_ids - _playlist_items_data['items'].map do |item| - item['snippet']['resourceId']['videoId'] - end - end end end end diff --git a/lib/video_info/providers/youtubeplaylist_api.rb b/lib/video_info/providers/youtubeplaylist_api.rb index 57b0c434..ef61f843 100644 --- a/lib/video_info/providers/youtubeplaylist_api.rb +++ b/lib/video_info/providers/youtubeplaylist_api.rb @@ -9,5 +9,37 @@ def videos VideoInfo.new("http://www.youtube.com/watch?v=#{entry_id}") end end + + private + + def _playlist_entry + data['items'] + end + + def _playlist_items + data['items'] + end + + def _api_path + "/youtube/v3/playlists?part=snippet&id=#{playlist_id}&key=#{api_key}" + end + + def _playlist_items_api_path + "/youtube/v3/playlistItems?part=snippet&playlistId=#{playlist_id}&fields=items&key=#{api_key}" + end + + def _playlist_items_api_url + "https://#{_api_base}#{_playlist_items_api_path}" + end + + def _playlist_items_data + @playlist_items_data ||= _set_data_from_api(_playlist_items_api_url) + end + + def _playlist_video_ids + _playlist_items_data['items'].map do |item| + item['snippet']['resourceId']['videoId'] + end + end end end From 3160e97b08b9b7d5f55ddaa5b5a8be351c3b2738 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Sat, 23 May 2015 08:44:45 -0700 Subject: [PATCH 13/58] separated YoutubePlaylistAPI spec from YoutubePlaylist spec --- .../providers/youtube_playlist_api_spec.rb | 170 ++++++++++++++++++ .../providers/youtube_playlist_spec.rb | 4 - 2 files changed, 170 insertions(+), 4 deletions(-) create mode 100644 spec/lib/video_info/providers/youtube_playlist_api_spec.rb diff --git a/spec/lib/video_info/providers/youtube_playlist_api_spec.rb b/spec/lib/video_info/providers/youtube_playlist_api_spec.rb new file mode 100644 index 00000000..dc740883 --- /dev/null +++ b/spec/lib/video_info/providers/youtube_playlist_api_spec.rb @@ -0,0 +1,170 @@ +require 'spec_helper' + +describe VideoInfo::Providers::YoutubePlaylist do + before(:all) do + VideoInfo.provider_api_keys = { youtube: 'AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0' } + end + + describe ".usable?" do + subject { VideoInfo::Providers::YoutubePlaylist.usable?(url) } + + context "with youtube.com/playlist url" do + let(:url) { 'http://www.youtube.com/playlist?p=PLA575C81A1FBC04CF' } + it { is_expected.to be_truthy } + end + + context "with youtube.com url" do + let(:url) { 'http://www.youtube.com/watch?v=Xp6CXF' } + it { is_expected.to be_falsey } + end + + context "with other url" do + let(:url) { 'http://example.com/video1' } + it { is_expected.to be_falsey } + end + end + + describe "#available?" do + context "with valid playlist", :vcr do + subject { VideoInfo.new('http://www.youtube.com/playlist?p=PLA575C81A1FBC04CF') } + + describe '#available?' do + subject { super().available? } + it { is_expected.to be_truthy } + end + end + + context "with invalid playlist", :vcr do + subject { VideoInfo.new('http://www.youtube.com/playlist?p=PLA575C81A1FBC04CF_invalid') } + + describe '#available?' do + subject { super().available? } + it { is_expected.to be_falsey } + end + end + end + + context "with playlist PL9hW1uS6HUftLdHI6RIsaf", :vcr do + let(:videos) { + [ + VideoInfo.new('http://www.youtube.com/watch?v=Oi67QjrXy2w'), + VideoInfo.new('http://www.youtube.com/watch?v=_Bt3-WsHfB0'), + VideoInfo.new('http://www.youtube.com/watch?v=9g2U12SsRns'), + VideoInfo.new('http://www.youtube.com/watch?v=8b0aEoxqqC0'), + VideoInfo.new('http://www.youtube.com/watch?v=6c3mHikRz0I'), + VideoInfo.new('http://www.youtube.com/watch?v=OQVHWsTHcoc') + ] + } + subject { VideoInfo.new('http://www.youtube.com/playlist?p=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr') } + + describe '#provider' do + subject { super().provider } + it { is_expected.to eq 'YouTube' } + end + + describe '#playlist_id' do + subject { super().playlist_id } + it { is_expected.to eq 'PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr' } + end + + describe '#url' do + subject { super().url } + it { is_expected.to eq 'http://www.youtube.com/playlist?p=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr' } + end + + describe '#embed_url' do + subject { super().embed_url } + it { is_expected.to eq '//www.youtube.com/embed/videoseries?list=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr' } + end + + describe '#embed_code' do + subject { super().embed_code } + it { is_expected.to eq '' } + end + + describe '#title' do + subject { super().title } + it { is_expected.to eq 'YouTube Policy and Copyright' } + end + + describe '#description' do + subject { super().description } + it { is_expected.to eq 'Learn more about copyright basics, flagging, and the YouTube community.' } + end + + describe '#keywords' do + subject { super().keywords } + it { is_expected.to be_nil } + end + + describe '#duration' do + subject { super().duration } + it { is_expected.to be_nil } + end + + describe '#width' do + subject { super().width } + it { is_expected.to be_nil } + end + + describe '#height' do + subject { super().height } + it { is_expected.to be_nil } + end + + describe '#date' do + subject { super().date } + it { is_expected.to be_nil } + end + + describe '#thumbnail_small' do + subject { super().thumbnail_small } + it { is_expected.to eq 'https://i.ytimg.com/vi/8b0aEoxqqC0/default.jpg' } + end + + describe '#thumbnail_medium' do + subject { super().thumbnail_medium } + it { is_expected.to eq 'https://i.ytimg.com/vi/8b0aEoxqqC0/mqdefault.jpg' } + end + + describe '#thumbnail_large' do + subject { super().thumbnail_large } + it { is_expected.to eq 'https://i.ytimg.com/vi/8b0aEoxqqC0/hqdefault.jpg' } + end + + describe '#videos' do + subject { super().videos } + it { is_expected.to match_array(videos) } + end + + describe '#view_count' do + subject { super().view_count } + it { is_expected.to be_nil } + end + end + + context "with playlist PL0E8117603D70E10A in embed path", :vcr do + subject { VideoInfo.new('http://www.youtube.com/embed/videoseries?list=PL0E8117603D70E10A') } + + describe '#playlist_id' do + subject { super().playlist_id } + it { is_expected.to eq 'PL0E8117603D70E10A' } + end + + describe '#videos' do + subject { super().videos } + it { is_expected.to eq [] } + end + end + + context "with playlist PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr in embed path", :vcr do + subject { VideoInfo.new('http://www.youtube.com/embed/videoseries?list=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr') } + + describe '#playlist_id' do + subject { super().playlist_id } + it { is_expected.to eq 'PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr' } + end + end + + +end diff --git a/spec/lib/video_info/providers/youtube_playlist_spec.rb b/spec/lib/video_info/providers/youtube_playlist_spec.rb index dc740883..d4b935c3 100644 --- a/spec/lib/video_info/providers/youtube_playlist_spec.rb +++ b/spec/lib/video_info/providers/youtube_playlist_spec.rb @@ -1,10 +1,6 @@ require 'spec_helper' describe VideoInfo::Providers::YoutubePlaylist do - before(:all) do - VideoInfo.provider_api_keys = { youtube: 'AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0' } - end - describe ".usable?" do subject { VideoInfo::Providers::YoutubePlaylist.usable?(url) } From 3f32ef3011c23189e4715f47a424d9c6ea76e7b5 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Sat, 23 May 2015 08:46:51 -0700 Subject: [PATCH 14/58] explicitly clear out API keys in youotube_playlist_spec --- spec/lib/video_info/providers/youtube_playlist_spec.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/lib/video_info/providers/youtube_playlist_spec.rb b/spec/lib/video_info/providers/youtube_playlist_spec.rb index d4b935c3..291af33e 100644 --- a/spec/lib/video_info/providers/youtube_playlist_spec.rb +++ b/spec/lib/video_info/providers/youtube_playlist_spec.rb @@ -1,6 +1,10 @@ require 'spec_helper' describe VideoInfo::Providers::YoutubePlaylist do + before(:all) do + VideoInfo.provider_api_keys = {} + end + describe ".usable?" do subject { VideoInfo::Providers::YoutubePlaylist.usable?(url) } From 5059cc2674b3a0ad040fa54ca8a007b508072981 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Fri, 29 May 2015 14:59:39 -0700 Subject: [PATCH 15/58] added YoutubePlaylistScraper --- lib/video_info/providers/youtubeplaylist.rb | 7 ++++++- lib/video_info/providers/youtubeplaylist_scraper.rb | 7 +++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 lib/video_info/providers/youtubeplaylist_scraper.rb diff --git a/lib/video_info/providers/youtubeplaylist.rb b/lib/video_info/providers/youtubeplaylist.rb index 21cf6841..81587003 100644 --- a/lib/video_info/providers/youtubeplaylist.rb +++ b/lib/video_info/providers/youtubeplaylist.rb @@ -1,4 +1,5 @@ require_relative 'youtubeplaylist_api' +require_relative 'youtubeplaylist_scraper' class VideoInfo module Providers @@ -7,7 +8,11 @@ class YoutubePlaylist < Youtube attr_accessor :playlist_items_data def initialize(url, options = {}) - extend YoutubePlaylistAPI + if VideoInfo.provider_api_keys[:youtube].nil? + extend YoutubePlaylistScraper + else + extend YoutubePlaylistAPI + end super(url, options) end diff --git a/lib/video_info/providers/youtubeplaylist_scraper.rb b/lib/video_info/providers/youtubeplaylist_scraper.rb new file mode 100644 index 00000000..2bd3e85d --- /dev/null +++ b/lib/video_info/providers/youtubeplaylist_scraper.rb @@ -0,0 +1,7 @@ +class VideoInfo + module Providers + module YoutubePlaylistScraper + + end + end +end From d5fb1f976bb2ec33401f3ef42418103ca792a86f Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Fri, 29 May 2015 15:40:02 -0700 Subject: [PATCH 16/58] implemented description in YoutubePlaylistScraper --- .../providers/youtubeplaylist_scraper.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/video_info/providers/youtubeplaylist_scraper.rb b/lib/video_info/providers/youtubeplaylist_scraper.rb index 2bd3e85d..1bc403d7 100644 --- a/lib/video_info/providers/youtubeplaylist_scraper.rb +++ b/lib/video_info/providers/youtubeplaylist_scraper.rb @@ -1,7 +1,23 @@ +require 'nokogiri' +require 'open-uri' +require 'open_uri_redirections' + class VideoInfo module Providers module YoutubePlaylistScraper + def description + data.css('meta')[1].values[1] + end + + private + + def _set_data_from_api(api_url = _api_url) + Nokogiri::HTML(open(api_url, :allow_redirections => :safe)) + end + def _api_url + @url + end end end end From 63c1b33101f2ebd05a953c2fee642b12c3754aa5 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Fri, 29 May 2015 15:51:22 -0700 Subject: [PATCH 17/58] implemented title --- lib/video_info/providers/youtubeplaylist_scraper.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/video_info/providers/youtubeplaylist_scraper.rb b/lib/video_info/providers/youtubeplaylist_scraper.rb index 1bc403d7..4671e6b5 100644 --- a/lib/video_info/providers/youtubeplaylist_scraper.rb +++ b/lib/video_info/providers/youtubeplaylist_scraper.rb @@ -8,6 +8,10 @@ module YoutubePlaylistScraper def description data.css('meta')[1].values[1] end + + def title + data.css('meta')[0].values[1] + end private From a3789b4fcc853fd293e97dcb09e189a9698bc43a Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Fri, 29 May 2015 15:57:52 -0700 Subject: [PATCH 18/58] made things a bit more generic --- lib/video_info/providers/youtubeplaylist_scraper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/video_info/providers/youtubeplaylist_scraper.rb b/lib/video_info/providers/youtubeplaylist_scraper.rb index 4671e6b5..2e6b3c7d 100644 --- a/lib/video_info/providers/youtubeplaylist_scraper.rb +++ b/lib/video_info/providers/youtubeplaylist_scraper.rb @@ -6,11 +6,11 @@ class VideoInfo module Providers module YoutubePlaylistScraper def description - data.css('meta')[1].values[1] + data.css('meta').find { |m| m.values[0] == 'description' }.values[1] end def title - data.css('meta')[0].values[1] + data.css('meta').find { |m| m.values[0] == 'title' }.values[1] end private From 41bf3d2f86e813e3aa9e3654a8a7b2d86acfe8f0 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Fri, 29 May 2015 16:00:27 -0700 Subject: [PATCH 19/58] added nokogiri and open_uri_redirections as dependencies --- video_info.gemspec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/video_info.gemspec b/video_info.gemspec index c06cde7e..c9fd7039 100644 --- a/video_info.gemspec +++ b/video_info.gemspec @@ -24,6 +24,8 @@ Gem::Specification.new do |s| s.add_dependency 'multi_json' s.add_dependency 'htmlentities' s.add_dependency 'iso8601' + s.add_dependency 'nokogiri' + s.add_dependency 'open_uri_redirections' s.add_development_dependency 'bundler', '>= 1.3.5' s.add_development_dependency 'rake' From 66cde866afa21943712f96e01cdd4d8b822843e0 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Fri, 29 May 2015 16:19:00 -0700 Subject: [PATCH 20/58] videos now raises an error --- lib/video_info/providers/youtubeplaylist_scraper.rb | 4 ++++ spec/lib/video_info/providers/youtube_playlist_spec.rb | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/video_info/providers/youtubeplaylist_scraper.rb b/lib/video_info/providers/youtubeplaylist_scraper.rb index 2e6b3c7d..69e3b8a6 100644 --- a/lib/video_info/providers/youtubeplaylist_scraper.rb +++ b/lib/video_info/providers/youtubeplaylist_scraper.rb @@ -12,6 +12,10 @@ def description def title data.css('meta').find { |m| m.values[0] == 'title' }.values[1] end + + def videos + raise NotImplementedError + end private diff --git a/spec/lib/video_info/providers/youtube_playlist_spec.rb b/spec/lib/video_info/providers/youtube_playlist_spec.rb index 291af33e..0efbe0e1 100644 --- a/spec/lib/video_info/providers/youtube_playlist_spec.rb +++ b/spec/lib/video_info/providers/youtube_playlist_spec.rb @@ -134,7 +134,7 @@ describe '#videos' do subject { super().videos } - it { is_expected.to match_array(videos) } + it { expect { subject}.to raise_error(NotImplementedError) } end describe '#view_count' do @@ -153,7 +153,7 @@ describe '#videos' do subject { super().videos } - it { is_expected.to eq [] } + it { expect { subject }.to raise_error(NotImplementedError) } end end From 8e24937b8fc81565fe64aa709022698fb3c825ea Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Fri, 29 May 2015 16:20:46 -0700 Subject: [PATCH 21/58] added a message to #videos error --- lib/video_info/providers/youtubeplaylist_scraper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/video_info/providers/youtubeplaylist_scraper.rb b/lib/video_info/providers/youtubeplaylist_scraper.rb index 69e3b8a6..172a3217 100644 --- a/lib/video_info/providers/youtubeplaylist_scraper.rb +++ b/lib/video_info/providers/youtubeplaylist_scraper.rb @@ -14,7 +14,7 @@ def title end def videos - raise NotImplementedError + raise(NotImplementedError, 'To access videos, you must provide an API key to VideoInfo.provider_api_keys') end private From a921d52f3ae898e4f0799b2178815b7a7a5f9557 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Tue, 12 May 2015 17:27:34 -0700 Subject: [PATCH 22/58] fixed youtubeplaylist spec --- spec/lib/video_info/providers/youtube_playlist_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/lib/video_info/providers/youtube_playlist_spec.rb b/spec/lib/video_info/providers/youtube_playlist_spec.rb index fc2d7d33..c05521aa 100644 --- a/spec/lib/video_info/providers/youtube_playlist_spec.rb +++ b/spec/lib/video_info/providers/youtube_playlist_spec.rb @@ -44,6 +44,7 @@ context "with playlist PL9hW1uS6HUftLdHI6RIsaf", :vcr do let(:videos) { [ + VideoInfo.new('http://www.youtube.com/watch?v=Oi67QjrXy2w'), VideoInfo.new('http://www.youtube.com/watch?v=_Bt3-WsHfB0'), VideoInfo.new('http://www.youtube.com/watch?v=9g2U12SsRns'), VideoInfo.new('http://www.youtube.com/watch?v=8b0aEoxqqC0'), From 364dcc9d159755eea66ca6368d257ff103e47415 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Fri, 15 May 2015 07:08:54 -0700 Subject: [PATCH 23/58] fixed youtubeplaylist#available? --- lib/video_info/providers/youtubeplaylist.rb | 2 +- spec/lib/video_info/providers/youtube_playlist_spec.rb | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/video_info/providers/youtubeplaylist.rb b/lib/video_info/providers/youtubeplaylist.rb index b94b8f64..dadb7172 100644 --- a/lib/video_info/providers/youtubeplaylist.rb +++ b/lib/video_info/providers/youtubeplaylist.rb @@ -41,7 +41,7 @@ def _url_regex end def _api_path - "/feeds/api/playlists/#{playlist_id}?v=2&alt=json" + "/youtube/v3/playlistItems?part=contentDetails&playlistId=#{playlist_id}&key=#{api_key}" end def _playlist_video_ids diff --git a/spec/lib/video_info/providers/youtube_playlist_spec.rb b/spec/lib/video_info/providers/youtube_playlist_spec.rb index c05521aa..dc740883 100644 --- a/spec/lib/video_info/providers/youtube_playlist_spec.rb +++ b/spec/lib/video_info/providers/youtube_playlist_spec.rb @@ -1,6 +1,9 @@ require 'spec_helper' describe VideoInfo::Providers::YoutubePlaylist do + before(:all) do + VideoInfo.provider_api_keys = { youtube: 'AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0' } + end describe ".usable?" do subject { VideoInfo::Providers::YoutubePlaylist.usable?(url) } From aabab468b5e8db94f7902f7101a1e066a471eb56 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Fri, 15 May 2015 07:28:08 -0700 Subject: [PATCH 24/58] fixed more specs! --- lib/video_info/providers/youtubeplaylist.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/video_info/providers/youtubeplaylist.rb b/lib/video_info/providers/youtubeplaylist.rb index dadb7172..b9931357 100644 --- a/lib/video_info/providers/youtubeplaylist.rb +++ b/lib/video_info/providers/youtubeplaylist.rb @@ -41,7 +41,7 @@ def _url_regex end def _api_path - "/youtube/v3/playlistItems?part=contentDetails&playlistId=#{playlist_id}&key=#{api_key}" + "/youtube/v3/playlists?part=snippet&id=#{playlist_id}&key=#{api_key}" end def _playlist_video_ids From c100c0a6085e2a074918c19d20ee9b1ad2506edd Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Fri, 15 May 2015 08:01:55 -0700 Subject: [PATCH 25/58] getting there... --- lib/video_info/providers/youtubeplaylist.rb | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/video_info/providers/youtubeplaylist.rb b/lib/video_info/providers/youtubeplaylist.rb index b9931357..b16dd737 100644 --- a/lib/video_info/providers/youtubeplaylist.rb +++ b/lib/video_info/providers/youtubeplaylist.rb @@ -29,11 +29,11 @@ def description private def _playlist_entry - data['feed'] + data['items'] end - def _video_entry - _playlist_entry + def _playlist_items + data['items'] end def _url_regex @@ -45,12 +45,13 @@ def _api_path end def _playlist_video_ids - return [] unless _playlist_entry['entry'] - _playlist_entry['entry'].map do |entry| - entry['media$group']['yt$videoid']['$t'] + return [] unless _playlist_items[0] + _playlist_items.map do |item| + # ugly hack! + thumbnail_url = item['snippet']['thumbnails']['default']['url'] + thumbnail_url.split('https://i.ytimg.com/vi/')[1].split('/default.jpg')[0] end end - end end end From 2b442f803d06c79e4c0b3fac0c3a8c11b6ea927a Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Fri, 15 May 2015 23:21:15 -0700 Subject: [PATCH 26/58] fixed YoutubePlaylist#Description --- lib/video_info/providers/youtubeplaylist.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/video_info/providers/youtubeplaylist.rb b/lib/video_info/providers/youtubeplaylist.rb index b16dd737..b823d5a8 100644 --- a/lib/video_info/providers/youtubeplaylist.rb +++ b/lib/video_info/providers/youtubeplaylist.rb @@ -8,6 +8,10 @@ def self.usable?(url) url =~ /((youtube\.com)\/playlist)|((youtube\.com)\/embed\/videoseries)/ end + def description + data['items'][0]['snippet']['description'] + end + def videos _playlist_video_ids.map do |entry_id| VideoInfo.new("http://www.youtube.com/watch?v=#{entry_id}") @@ -18,10 +22,6 @@ def embed_url "//www.youtube.com/embed/videoseries?list=#{playlist_id}" end - def description - _playlist_entry['subtitle']['$t'] - end - %w[date keywords duration view_count].each do |method| define_method(method) { nil } end From 8e204399b3eb167ae5da40a8379df5fd9259bd8a Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Sun, 17 May 2015 02:32:43 -0700 Subject: [PATCH 27/58] fixed another spec --- lib/video_info/providers/youtubeplaylist.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/video_info/providers/youtubeplaylist.rb b/lib/video_info/providers/youtubeplaylist.rb index b823d5a8..8172830a 100644 --- a/lib/video_info/providers/youtubeplaylist.rb +++ b/lib/video_info/providers/youtubeplaylist.rb @@ -45,7 +45,7 @@ def _api_path end def _playlist_video_ids - return [] unless _playlist_items[0] + return [] unless _playlist_items[1] _playlist_items.map do |item| # ugly hack! thumbnail_url = item['snippet']['thumbnails']['default']['url'] From 60148e82e494eb9c0d0808037196e34c490c0871 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Sun, 17 May 2015 03:20:03 -0700 Subject: [PATCH 28/58] removed ugly hack --- lib/video_info/provider.rb | 4 ++-- lib/video_info/providers/youtubeplaylist.rb | 22 ++++++++++++++++----- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/lib/video_info/provider.rb b/lib/video_info/provider.rb index bc8d8dea..1475b829 100644 --- a/lib/video_info/provider.rb +++ b/lib/video_info/provider.rb @@ -56,8 +56,8 @@ def _clean_options(options) options end - def _set_data_from_api - uri = open(_api_url, options) + def _set_data_from_api(api_url = _api_url) + uri = open(api_url, options) MultiJson.load(uri.read) end diff --git a/lib/video_info/providers/youtubeplaylist.rb b/lib/video_info/providers/youtubeplaylist.rb index 8172830a..e0a2421d 100644 --- a/lib/video_info/providers/youtubeplaylist.rb +++ b/lib/video_info/providers/youtubeplaylist.rb @@ -3,6 +3,7 @@ module Providers class YoutubePlaylist < Youtube alias_method :playlist_id, :video_id + attr_accessor :playlist_items_data def self.usable?(url) url =~ /((youtube\.com)\/playlist)|((youtube\.com)\/embed\/videoseries)/ @@ -26,6 +27,7 @@ def embed_url define_method(method) { nil } end + private def _playlist_entry @@ -44,12 +46,22 @@ def _api_path "/youtube/v3/playlists?part=snippet&id=#{playlist_id}&key=#{api_key}" end + def _playlist_items_api_path + "/youtube/v3/playlistItems?part=snippet&playlistId=#{playlist_id}&fields=items&key=#{api_key}" + end + + def _playlist_items_api_url + "https://#{_api_base}#{_playlist_items_api_path}" + end + + def _playlist_items_data + @playlist_items_data ||= _set_data_from_api(_playlist_items_api_url) + end + def _playlist_video_ids - return [] unless _playlist_items[1] - _playlist_items.map do |item| - # ugly hack! - thumbnail_url = item['snippet']['thumbnails']['default']['url'] - thumbnail_url.split('https://i.ytimg.com/vi/')[1].split('/default.jpg')[0] + return [] unless _playlist_items_data + _playlist_items_data['items'].map do |item| + item['snippet']['resourceId']['videoId'] end end end From 362f4cffd4b882e76ccf3dee16b5dc9f4776f875 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Sun, 17 May 2015 03:26:15 -0700 Subject: [PATCH 29/58] Removed unnecessary code calling #map on an empty array returns an empty array, so no reason to have a check for it --- lib/video_info/providers/youtubeplaylist.rb | 1 - .../with_invalid_playlist/_available_/.yml | 57 ++ .../with_valid_playlist/_available_/.yml | 85 ++ .../_videos/.yml | 568 +++++++++++++ .../_description/.yml | 101 +++ .../_thumbnail_large/.yml | 101 +++ .../_thumbnail_medium/.yml | 101 +++ .../_thumbnail_small/.yml | 101 +++ .../_title/.yml | 101 +++ .../_videos/.yml | 795 ++++++++++++++++++ 10 files changed, 2010 insertions(+), 1 deletion(-) diff --git a/lib/video_info/providers/youtubeplaylist.rb b/lib/video_info/providers/youtubeplaylist.rb index e0a2421d..6cee48d5 100644 --- a/lib/video_info/providers/youtubeplaylist.rb +++ b/lib/video_info/providers/youtubeplaylist.rb @@ -59,7 +59,6 @@ def _playlist_items_data end def _playlist_video_ids - return [] unless _playlist_items_data _playlist_items_data['items'].map do |item| item['snippet']['resourceId']['videoId'] end diff --git a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/_available_/with_invalid_playlist/_available_/.yml b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/_available_/with_invalid_playlist/_available_/.yml index 7691b1ab..54d2354c 100644 --- a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/_available_/with_invalid_playlist/_available_/.yml +++ b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/_available_/with_invalid_playlist/_available_/.yml @@ -43,4 +43,61 @@ http_interactions: string: '' http_version: recorded_at: Mon, 09 Mar 2015 14:06:54 GMT +- request: + method: get + uri: https://www.googleapis.com/youtube/v3/playlists?id=PLA575C81A1FBC04CF_invalid&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Expires: + - Sun, 17 May 2015 10:27:44 GMT + Date: + - Sun, 17 May 2015 10:27:44 GMT + Cache-Control: + - private, max-age=0, must-revalidate, no-transform + Etag: + - '"NO6QTeg0-3ShswIeqLchQ_mzWJs/ZLdVv1yknYCGRyTYfR9cqqqg-3c"' + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '192' + Server: + - GSE + Alternate-Protocol: + - 443:quic,p=1 + body: + encoding: UTF-8 + string: | + { + "kind": "youtube#playlistListResponse", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/ZLdVv1yknYCGRyTYfR9cqqqg-3c\"", + "pageInfo": { + "totalResults": 0, + "resultsPerPage": 0 + }, + "items": [] + } + http_version: + recorded_at: Sun, 17 May 2015 10:25:36 GMT recorded_with: VCR 2.9.3 diff --git a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/_available_/with_valid_playlist/_available_/.yml b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/_available_/with_valid_playlist/_available_/.yml index bc978e42..0de1b2ae 100644 --- a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/_available_/with_valid_playlist/_available_/.yml +++ b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/_available_/with_valid_playlist/_available_/.yml @@ -53,4 +53,89 @@ http_interactions: string: '' http_version: recorded_at: Mon, 09 Mar 2015 14:06:53 GMT +- request: + method: get + uri: https://www.googleapis.com/youtube/v3/playlists?id=PLA575C81A1FBC04CF&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Expires: + - Sun, 17 May 2015 10:27:44 GMT + Date: + - Sun, 17 May 2015 10:27:44 GMT + Cache-Control: + - private, max-age=0, must-revalidate, no-transform + Etag: + - '"NO6QTeg0-3ShswIeqLchQ_mzWJs/775uqayGKfvufZcffd_1ekvmfO0"' + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '881' + Server: + - GSE + Alternate-Protocol: + - 443:quic,p=1 + body: + encoding: UTF-8 + string: | + { + "kind": "youtube#playlistListResponse", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/775uqayGKfvufZcffd_1ekvmfO0\"", + "pageInfo": { + "totalResults": 1, + "resultsPerPage": 1 + }, + "items": [ + { + "kind": "youtube#playlist", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/LWX5mzkRf8mBLPLSjS1m-HQOnbo\"", + "id": "PLA575C81A1FBC04CF", + "snippet": { + "publishedAt": "2010-01-07T22:20:45.000Z", + "channelId": "UC2y5oKUfkQJDKO7cM_OIc3w", + "title": "the century of self", + "description": "", + "thumbnails": { + "default": { + "url": "https://i.ytimg.com/vi/default.jpg" + }, + "medium": { + "url": "https://i.ytimg.com/vi/default.jpg" + }, + "high": { + "url": "https://i.ytimg.com/vi/default.jpg" + } + }, + "channelTitle": "Chris Szanto", + "localized": { + "title": "the century of self", + "description": "" + } + } + } + ] + } + http_version: + recorded_at: Sun, 17 May 2015 10:25:35 GMT recorded_with: VCR 2.9.3 diff --git a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL0E8117603D70E10A_in_embed_path/_videos/.yml b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL0E8117603D70E10A_in_embed_path/_videos/.yml index 214d4bd4..d0e433d1 100644 --- a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL0E8117603D70E10A_in_embed_path/_videos/.yml +++ b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL0E8117603D70E10A_in_embed_path/_videos/.yml @@ -58,4 +58,572 @@ http_interactions: War","type":"plain"}},"yt$playlistId":{"$t":"PL0E8117603D70E10A"}}}' http_version: recorded_at: Mon, 09 Mar 2015 14:06:55 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/vs/playlistitems?id=PL0E8117603D70E10A&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 404 + message: Not Found + headers: + Cache-Control: + - no-cache, no-store, max-age=0, must-revalidate + Pragma: + - no-cache + Expires: + - Fri, 01 Jan 1990 00:00:00 GMT + Date: + - Sun, 17 May 2015 09:58:56 GMT + Vary: + - Origin + - X-Origin + Content-Type: + - text/html; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '29' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: Not Found + http_version: + recorded_at: Sun, 17 May 2015 09:56:47 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/v3/playlistitems?id=PL0E8117603D70E10A&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 404 + message: Not Found + headers: + Cache-Control: + - no-cache, no-store, max-age=0, must-revalidate + Pragma: + - no-cache + Expires: + - Fri, 01 Jan 1990 00:00:00 GMT + Date: + - Sun, 17 May 2015 09:59:26 GMT + Vary: + - Origin + - X-Origin + Content-Type: + - text/html; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '29' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: Not Found + http_version: + recorded_at: Sun, 17 May 2015 09:57:17 GMT +- request: + method: get + uri: https://www.googleapis.com/youtube/v3/playlistitems?id=PL0E8117603D70E10A&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 404 + message: Not Found + headers: + Cache-Control: + - no-cache, no-store, max-age=0, must-revalidate + Pragma: + - no-cache + Expires: + - Fri, 01 Jan 1990 00:00:00 GMT + Date: + - Sun, 17 May 2015 10:00:12 GMT + Vary: + - Origin + - X-Origin + Content-Type: + - text/html; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Server: + - GSE + Alternate-Protocol: + - 443:quic,p=1 + Transfer-Encoding: + - chunked + body: + encoding: ASCII-8BIT + string: Not Found + http_version: + recorded_at: Sun, 17 May 2015 09:58:04 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/v3/playlistitems?key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet&playlistId=PL0E8117603D70E10A + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 404 + message: Not Found + headers: + Cache-Control: + - no-cache, no-store, max-age=0, must-revalidate + Pragma: + - no-cache + Expires: + - Fri, 01 Jan 1990 00:00:00 GMT + Date: + - Sun, 17 May 2015 10:00:40 GMT + Vary: + - Origin + - X-Origin + Content-Type: + - text/html; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '29' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: Not Found + http_version: + recorded_at: Sun, 17 May 2015 09:58:31 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/v3/playlistitems?part=snippet&playlistId=PL0E8117603D70E10A + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 404 + message: Not Found + headers: + Cache-Control: + - no-cache, no-store, max-age=0, must-revalidate + Pragma: + - no-cache + Expires: + - Fri, 01 Jan 1990 00:00:00 GMT + Date: + - Sun, 17 May 2015 10:01:02 GMT + Vary: + - Origin + - X-Origin + Content-Type: + - text/html; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '29' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: Not Found + http_version: + recorded_at: Sun, 17 May 2015 09:58:53 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=PL0E8117603D70E10A + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 403 + message: Forbidden + headers: + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + Date: + - Sun, 17 May 2015 10:01:11 GMT + Expires: + - Sun, 17 May 2015 10:01:11 GMT + Cache-Control: + - private, max-age=0 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '131' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: '{"error":{"errors":[{"domain":"global","reason":"sslRequired","message":"SSL + is required to perform this operation."}],"code":403,"message":"SSL is required + to perform this operation."}}' + http_version: + recorded_at: Sun, 17 May 2015 09:59:02 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/v3/playlistItems?key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet&playlistId=PL0E8117603D70E10A + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 403 + message: Forbidden + headers: + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + Date: + - Sun, 17 May 2015 10:01:28 GMT + Expires: + - Sun, 17 May 2015 10:01:28 GMT + Cache-Control: + - private, max-age=0 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '131' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: '{"error":{"errors":[{"domain":"global","reason":"sslRequired","message":"SSL + is required to perform this operation."}],"code":403,"message":"SSL is required + to perform this operation."}}' + http_version: + recorded_at: Sun, 17 May 2015 09:59:19 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/v3/playlistItems?key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=contentDetails&playlistId=PL0E8117603D70E10A + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 403 + message: Forbidden + headers: + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + Date: + - Sun, 17 May 2015 10:01:57 GMT + Expires: + - Sun, 17 May 2015 10:01:57 GMT + Cache-Control: + - private, max-age=0 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '131' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: '{"error":{"errors":[{"domain":"global","reason":"sslRequired","message":"SSL + is required to perform this operation."}],"code":403,"message":"SSL is required + to perform this operation."}}' + http_version: + recorded_at: Sun, 17 May 2015 09:59:49 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/v3/playlistItems?fields=items&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet&playlistId=PL0E8117603D70E10A + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 403 + message: Forbidden + headers: + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + Date: + - Sun, 17 May 2015 10:03:19 GMT + Expires: + - Sun, 17 May 2015 10:03:19 GMT + Cache-Control: + - private, max-age=0 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '131' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: '{"error":{"errors":[{"domain":"global","reason":"sslRequired","message":"SSL + is required to perform this operation."}],"code":403,"message":"SSL is required + to perform this operation."}}' + http_version: + recorded_at: Sun, 17 May 2015 10:01:10 GMT +- request: + method: get + uri: https://www.googleapis.com/youtube/v3/playlists?id=PL0E8117603D70E10A&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Expires: + - Sun, 17 May 2015 10:07:23 GMT + Date: + - Sun, 17 May 2015 10:07:23 GMT + Cache-Control: + - private, max-age=0, must-revalidate, no-transform + Etag: + - '"NO6QTeg0-3ShswIeqLchQ_mzWJs/AlXCLK8j0l_yW1_HEVHfG1w1HHY"' + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '860' + Server: + - GSE + Alternate-Protocol: + - 443:quic,p=1 + body: + encoding: UTF-8 + string: | + { + "kind": "youtube#playlistListResponse", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/AlXCLK8j0l_yW1_HEVHfG1w1HHY\"", + "pageInfo": { + "totalResults": 1, + "resultsPerPage": 1 + }, + "items": [ + { + "kind": "youtube#playlist", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/x_Bt3sI6005uthvRF1yFLlWNFy0\"", + "id": "PL0E8117603D70E10A", + "snippet": { + "publishedAt": "2009-10-29T17:42:53.000Z", + "channelId": "UCw9KftjwRV1cQqzcUnqzGmA", + "title": "Anthrax War", + "description": "", + "thumbnails": { + "default": { + "url": "https://i.ytimg.com/vi/default.jpg" + }, + "medium": { + "url": "https://i.ytimg.com/vi/default.jpg" + }, + "high": { + "url": "https://i.ytimg.com/vi/default.jpg" + } + }, + "channelTitle": "sprword", + "localized": { + "title": "Anthrax War", + "description": "" + } + } + } + ] + } + http_version: + recorded_at: Sun, 17 May 2015 10:05:14 GMT +- request: + method: get + uri: https://www.googleapis.com/youtube/v3/playlistItems?fields=items&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet&playlistId=PL0E8117603D70E10A + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Expires: + - Sun, 17 May 2015 10:27:46 GMT + Date: + - Sun, 17 May 2015 10:27:46 GMT + Cache-Control: + - private, max-age=0, must-revalidate, no-transform + Etag: + - '"NO6QTeg0-3ShswIeqLchQ_mzWJs/3cxjRXf86G9z5Bg7rup3QfCgrxM"' + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '17' + Server: + - GSE + Alternate-Protocol: + - 443:quic,p=1 + body: + encoding: UTF-8 + string: | + { + "items": [] + } + http_version: + recorded_at: Sun, 17 May 2015 10:25:37 GMT recorded_with: VCR 2.9.3 diff --git a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_description/.yml b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_description/.yml index 82f321e5..ef433480 100644 --- a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_description/.yml +++ b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_description/.yml @@ -93,4 +93,105 @@ http_interactions: Copyright Basics (Global)","type":"plain"},"yt$aspectRatio":{"$t":"widescreen"},"yt$duration":{"seconds":"342"},"yt$uploaded":{"$t":"2013-12-02T23:22:20.000Z"},"yt$uploaderId":{"$t":"UCMDQxm7cUx3yXkfeHa5zJIQ"},"yt$videoid":{"$t":"OQVHWsTHcoc"}},"yt$statistics":{"favoriteCount":"0","viewCount":"1177513"},"yt$position":{"$t":5}}]}}' http_version: recorded_at: Mon, 09 Mar 2015 14:06:54 GMT +- request: + method: get + uri: https://www.googleapis.com/youtube/v3/playlists?id=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Expires: + - Sun, 17 May 2015 10:27:45 GMT + Date: + - Sun, 17 May 2015 10:27:45 GMT + Cache-Control: + - private, max-age=0, must-revalidate, no-transform + Etag: + - '"NO6QTeg0-3ShswIeqLchQ_mzWJs/O7xY08pMODVOI02ahJhG-SRbxcw"' + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '1486' + Server: + - GSE + Alternate-Protocol: + - 443:quic,p=1 + body: + encoding: UTF-8 + string: | + { + "kind": "youtube#playlistListResponse", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/O7xY08pMODVOI02ahJhG-SRbxcw\"", + "pageInfo": { + "totalResults": 1, + "resultsPerPage": 1 + }, + "items": [ + { + "kind": "youtube#playlist", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/tXBNzpf3TuQUOT7zeYiB3hhPWYc\"", + "id": "PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr", + "snippet": { + "publishedAt": "2013-08-09T05:09:51.000Z", + "channelId": "UCMDQxm7cUx3yXkfeHa5zJIQ", + "title": "YouTube Policy and Copyright", + "description": "Learn more about copyright basics, flagging, and the YouTube community.", + "thumbnails": { + "default": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/default.jpg", + "width": 120, + "height": 90 + }, + "medium": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/mqdefault.jpg", + "width": 320, + "height": 180 + }, + "high": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/hqdefault.jpg", + "width": 480, + "height": 360 + }, + "standard": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/sddefault.jpg", + "width": 640, + "height": 480 + }, + "maxres": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/maxresdefault.jpg", + "width": 1280, + "height": 720 + } + }, + "channelTitle": "YouTube Help", + "localized": { + "title": "YouTube Policy and Copyright", + "description": "Learn more about copyright basics, flagging, and the YouTube community." + } + } + } + ] + } + http_version: + recorded_at: Sun, 17 May 2015 10:25:36 GMT recorded_with: VCR 2.9.3 diff --git a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_thumbnail_large/.yml b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_thumbnail_large/.yml index 82f321e5..6996708c 100644 --- a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_thumbnail_large/.yml +++ b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_thumbnail_large/.yml @@ -93,4 +93,105 @@ http_interactions: Copyright Basics (Global)","type":"plain"},"yt$aspectRatio":{"$t":"widescreen"},"yt$duration":{"seconds":"342"},"yt$uploaded":{"$t":"2013-12-02T23:22:20.000Z"},"yt$uploaderId":{"$t":"UCMDQxm7cUx3yXkfeHa5zJIQ"},"yt$videoid":{"$t":"OQVHWsTHcoc"}},"yt$statistics":{"favoriteCount":"0","viewCount":"1177513"},"yt$position":{"$t":5}}]}}' http_version: recorded_at: Mon, 09 Mar 2015 14:06:54 GMT +- request: + method: get + uri: https://www.googleapis.com/youtube/v3/playlists?id=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Expires: + - Sun, 17 May 2015 10:27:46 GMT + Date: + - Sun, 17 May 2015 10:27:46 GMT + Cache-Control: + - private, max-age=0, must-revalidate, no-transform + Etag: + - '"NO6QTeg0-3ShswIeqLchQ_mzWJs/O7xY08pMODVOI02ahJhG-SRbxcw"' + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '1486' + Server: + - GSE + Alternate-Protocol: + - 443:quic,p=1 + body: + encoding: UTF-8 + string: | + { + "kind": "youtube#playlistListResponse", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/O7xY08pMODVOI02ahJhG-SRbxcw\"", + "pageInfo": { + "totalResults": 1, + "resultsPerPage": 1 + }, + "items": [ + { + "kind": "youtube#playlist", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/tXBNzpf3TuQUOT7zeYiB3hhPWYc\"", + "id": "PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr", + "snippet": { + "publishedAt": "2013-08-09T05:09:51.000Z", + "channelId": "UCMDQxm7cUx3yXkfeHa5zJIQ", + "title": "YouTube Policy and Copyright", + "description": "Learn more about copyright basics, flagging, and the YouTube community.", + "thumbnails": { + "default": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/default.jpg", + "width": 120, + "height": 90 + }, + "medium": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/mqdefault.jpg", + "width": 320, + "height": 180 + }, + "high": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/hqdefault.jpg", + "width": 480, + "height": 360 + }, + "standard": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/sddefault.jpg", + "width": 640, + "height": 480 + }, + "maxres": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/maxresdefault.jpg", + "width": 1280, + "height": 720 + } + }, + "channelTitle": "YouTube Help", + "localized": { + "title": "YouTube Policy and Copyright", + "description": "Learn more about copyright basics, flagging, and the YouTube community." + } + } + } + ] + } + http_version: + recorded_at: Sun, 17 May 2015 10:25:37 GMT recorded_with: VCR 2.9.3 diff --git a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_thumbnail_medium/.yml b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_thumbnail_medium/.yml index 82f321e5..ef433480 100644 --- a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_thumbnail_medium/.yml +++ b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_thumbnail_medium/.yml @@ -93,4 +93,105 @@ http_interactions: Copyright Basics (Global)","type":"plain"},"yt$aspectRatio":{"$t":"widescreen"},"yt$duration":{"seconds":"342"},"yt$uploaded":{"$t":"2013-12-02T23:22:20.000Z"},"yt$uploaderId":{"$t":"UCMDQxm7cUx3yXkfeHa5zJIQ"},"yt$videoid":{"$t":"OQVHWsTHcoc"}},"yt$statistics":{"favoriteCount":"0","viewCount":"1177513"},"yt$position":{"$t":5}}]}}' http_version: recorded_at: Mon, 09 Mar 2015 14:06:54 GMT +- request: + method: get + uri: https://www.googleapis.com/youtube/v3/playlists?id=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Expires: + - Sun, 17 May 2015 10:27:45 GMT + Date: + - Sun, 17 May 2015 10:27:45 GMT + Cache-Control: + - private, max-age=0, must-revalidate, no-transform + Etag: + - '"NO6QTeg0-3ShswIeqLchQ_mzWJs/O7xY08pMODVOI02ahJhG-SRbxcw"' + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '1486' + Server: + - GSE + Alternate-Protocol: + - 443:quic,p=1 + body: + encoding: UTF-8 + string: | + { + "kind": "youtube#playlistListResponse", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/O7xY08pMODVOI02ahJhG-SRbxcw\"", + "pageInfo": { + "totalResults": 1, + "resultsPerPage": 1 + }, + "items": [ + { + "kind": "youtube#playlist", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/tXBNzpf3TuQUOT7zeYiB3hhPWYc\"", + "id": "PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr", + "snippet": { + "publishedAt": "2013-08-09T05:09:51.000Z", + "channelId": "UCMDQxm7cUx3yXkfeHa5zJIQ", + "title": "YouTube Policy and Copyright", + "description": "Learn more about copyright basics, flagging, and the YouTube community.", + "thumbnails": { + "default": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/default.jpg", + "width": 120, + "height": 90 + }, + "medium": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/mqdefault.jpg", + "width": 320, + "height": 180 + }, + "high": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/hqdefault.jpg", + "width": 480, + "height": 360 + }, + "standard": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/sddefault.jpg", + "width": 640, + "height": 480 + }, + "maxres": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/maxresdefault.jpg", + "width": 1280, + "height": 720 + } + }, + "channelTitle": "YouTube Help", + "localized": { + "title": "YouTube Policy and Copyright", + "description": "Learn more about copyright basics, flagging, and the YouTube community." + } + } + } + ] + } + http_version: + recorded_at: Sun, 17 May 2015 10:25:36 GMT recorded_with: VCR 2.9.3 diff --git a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_thumbnail_small/.yml b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_thumbnail_small/.yml index 82f321e5..ef433480 100644 --- a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_thumbnail_small/.yml +++ b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_thumbnail_small/.yml @@ -93,4 +93,105 @@ http_interactions: Copyright Basics (Global)","type":"plain"},"yt$aspectRatio":{"$t":"widescreen"},"yt$duration":{"seconds":"342"},"yt$uploaded":{"$t":"2013-12-02T23:22:20.000Z"},"yt$uploaderId":{"$t":"UCMDQxm7cUx3yXkfeHa5zJIQ"},"yt$videoid":{"$t":"OQVHWsTHcoc"}},"yt$statistics":{"favoriteCount":"0","viewCount":"1177513"},"yt$position":{"$t":5}}]}}' http_version: recorded_at: Mon, 09 Mar 2015 14:06:54 GMT +- request: + method: get + uri: https://www.googleapis.com/youtube/v3/playlists?id=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Expires: + - Sun, 17 May 2015 10:27:45 GMT + Date: + - Sun, 17 May 2015 10:27:45 GMT + Cache-Control: + - private, max-age=0, must-revalidate, no-transform + Etag: + - '"NO6QTeg0-3ShswIeqLchQ_mzWJs/O7xY08pMODVOI02ahJhG-SRbxcw"' + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '1486' + Server: + - GSE + Alternate-Protocol: + - 443:quic,p=1 + body: + encoding: UTF-8 + string: | + { + "kind": "youtube#playlistListResponse", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/O7xY08pMODVOI02ahJhG-SRbxcw\"", + "pageInfo": { + "totalResults": 1, + "resultsPerPage": 1 + }, + "items": [ + { + "kind": "youtube#playlist", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/tXBNzpf3TuQUOT7zeYiB3hhPWYc\"", + "id": "PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr", + "snippet": { + "publishedAt": "2013-08-09T05:09:51.000Z", + "channelId": "UCMDQxm7cUx3yXkfeHa5zJIQ", + "title": "YouTube Policy and Copyright", + "description": "Learn more about copyright basics, flagging, and the YouTube community.", + "thumbnails": { + "default": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/default.jpg", + "width": 120, + "height": 90 + }, + "medium": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/mqdefault.jpg", + "width": 320, + "height": 180 + }, + "high": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/hqdefault.jpg", + "width": 480, + "height": 360 + }, + "standard": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/sddefault.jpg", + "width": 640, + "height": 480 + }, + "maxres": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/maxresdefault.jpg", + "width": 1280, + "height": 720 + } + }, + "channelTitle": "YouTube Help", + "localized": { + "title": "YouTube Policy and Copyright", + "description": "Learn more about copyright basics, flagging, and the YouTube community." + } + } + } + ] + } + http_version: + recorded_at: Sun, 17 May 2015 10:25:36 GMT recorded_with: VCR 2.9.3 diff --git a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_title/.yml b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_title/.yml index 90a06a3c..da18c146 100644 --- a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_title/.yml +++ b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_title/.yml @@ -95,4 +95,105 @@ http_interactions: Copyright Basics (Global)","type":"plain"},"yt$aspectRatio":{"$t":"widescreen"},"yt$duration":{"seconds":"342"},"yt$uploaded":{"$t":"2013-12-02T23:22:20.000Z"},"yt$uploaderId":{"$t":"UCMDQxm7cUx3yXkfeHa5zJIQ"},"yt$videoid":{"$t":"OQVHWsTHcoc"}},"yt$statistics":{"favoriteCount":"0","viewCount":"1177513"},"yt$position":{"$t":5}}]}}' http_version: recorded_at: Mon, 09 Mar 2015 14:06:54 GMT +- request: + method: get + uri: https://www.googleapis.com/youtube/v3/playlists?id=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Expires: + - Sun, 17 May 2015 10:27:45 GMT + Date: + - Sun, 17 May 2015 10:27:45 GMT + Cache-Control: + - private, max-age=0, must-revalidate, no-transform + Etag: + - '"NO6QTeg0-3ShswIeqLchQ_mzWJs/O7xY08pMODVOI02ahJhG-SRbxcw"' + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '1486' + Server: + - GSE + Alternate-Protocol: + - 443:quic,p=1 + body: + encoding: UTF-8 + string: | + { + "kind": "youtube#playlistListResponse", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/O7xY08pMODVOI02ahJhG-SRbxcw\"", + "pageInfo": { + "totalResults": 1, + "resultsPerPage": 1 + }, + "items": [ + { + "kind": "youtube#playlist", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/tXBNzpf3TuQUOT7zeYiB3hhPWYc\"", + "id": "PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr", + "snippet": { + "publishedAt": "2013-08-09T05:09:51.000Z", + "channelId": "UCMDQxm7cUx3yXkfeHa5zJIQ", + "title": "YouTube Policy and Copyright", + "description": "Learn more about copyright basics, flagging, and the YouTube community.", + "thumbnails": { + "default": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/default.jpg", + "width": 120, + "height": 90 + }, + "medium": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/mqdefault.jpg", + "width": 320, + "height": 180 + }, + "high": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/hqdefault.jpg", + "width": 480, + "height": 360 + }, + "standard": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/sddefault.jpg", + "width": 640, + "height": 480 + }, + "maxres": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/maxresdefault.jpg", + "width": 1280, + "height": 720 + } + }, + "channelTitle": "YouTube Help", + "localized": { + "title": "YouTube Policy and Copyright", + "description": "Learn more about copyright basics, flagging, and the YouTube community." + } + } + } + ] + } + http_version: + recorded_at: Sun, 17 May 2015 10:25:36 GMT recorded_with: VCR 2.9.3 diff --git a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_videos/.yml b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_videos/.yml index 82f321e5..f206bbfd 100644 --- a/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_videos/.yml +++ b/spec/fixtures/vcr_cassettes/VideoInfo_Providers_YoutubePlaylist/with_playlist_PL9hW1uS6HUftLdHI6RIsaf/_videos/.yml @@ -93,4 +93,799 @@ http_interactions: Copyright Basics (Global)","type":"plain"},"yt$aspectRatio":{"$t":"widescreen"},"yt$duration":{"seconds":"342"},"yt$uploaded":{"$t":"2013-12-02T23:22:20.000Z"},"yt$uploaderId":{"$t":"UCMDQxm7cUx3yXkfeHa5zJIQ"},"yt$videoid":{"$t":"OQVHWsTHcoc"}},"yt$statistics":{"favoriteCount":"0","viewCount":"1177513"},"yt$position":{"$t":5}}]}}' http_version: recorded_at: Mon, 09 Mar 2015 14:06:54 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/vs/playlistitems?id=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 404 + message: Not Found + headers: + Cache-Control: + - no-cache, no-store, max-age=0, must-revalidate + Pragma: + - no-cache + Expires: + - Fri, 01 Jan 1990 00:00:00 GMT + Date: + - Sun, 17 May 2015 09:58:55 GMT + Vary: + - Origin + - X-Origin + Content-Type: + - text/html; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '29' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: Not Found + http_version: + recorded_at: Sun, 17 May 2015 09:56:46 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/v3/playlistitems?id=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 404 + message: Not Found + headers: + Cache-Control: + - no-cache, no-store, max-age=0, must-revalidate + Pragma: + - no-cache + Expires: + - Fri, 01 Jan 1990 00:00:00 GMT + Date: + - Sun, 17 May 2015 09:59:26 GMT + Vary: + - Origin + - X-Origin + Content-Type: + - text/html; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '29' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: Not Found + http_version: + recorded_at: Sun, 17 May 2015 09:57:17 GMT +- request: + method: get + uri: https://www.googleapis.com/youtube/v3/playlistitems?id=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 404 + message: Not Found + headers: + Cache-Control: + - no-cache, no-store, max-age=0, must-revalidate + Pragma: + - no-cache + Expires: + - Fri, 01 Jan 1990 00:00:00 GMT + Date: + - Sun, 17 May 2015 10:00:12 GMT + Vary: + - Origin + - X-Origin + Content-Type: + - text/html; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Server: + - GSE + Alternate-Protocol: + - 443:quic,p=1 + Transfer-Encoding: + - chunked + body: + encoding: ASCII-8BIT + string: Not Found + http_version: + recorded_at: Sun, 17 May 2015 09:58:03 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/v3/playlistitems?key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet&playlistId=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 404 + message: Not Found + headers: + Cache-Control: + - no-cache, no-store, max-age=0, must-revalidate + Pragma: + - no-cache + Expires: + - Fri, 01 Jan 1990 00:00:00 GMT + Date: + - Sun, 17 May 2015 10:00:40 GMT + Vary: + - Origin + - X-Origin + Content-Type: + - text/html; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '29' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: Not Found + http_version: + recorded_at: Sun, 17 May 2015 09:58:31 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/v3/playlistitems?part=snippet&playlistId=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 404 + message: Not Found + headers: + Cache-Control: + - no-cache, no-store, max-age=0, must-revalidate + Pragma: + - no-cache + Expires: + - Fri, 01 Jan 1990 00:00:00 GMT + Date: + - Sun, 17 May 2015 10:01:01 GMT + Vary: + - Origin + - X-Origin + Content-Type: + - text/html; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '29' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: Not Found + http_version: + recorded_at: Sun, 17 May 2015 09:58:53 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 403 + message: Forbidden + headers: + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + Date: + - Sun, 17 May 2015 10:01:11 GMT + Expires: + - Sun, 17 May 2015 10:01:11 GMT + Cache-Control: + - private, max-age=0 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '131' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: '{"error":{"errors":[{"domain":"global","reason":"sslRequired","message":"SSL + is required to perform this operation."}],"code":403,"message":"SSL is required + to perform this operation."}}' + http_version: + recorded_at: Sun, 17 May 2015 09:59:02 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/v3/playlistItems?key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet&playlistId=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 403 + message: Forbidden + headers: + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + Date: + - Sun, 17 May 2015 10:01:28 GMT + Expires: + - Sun, 17 May 2015 10:01:28 GMT + Cache-Control: + - private, max-age=0 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '131' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: '{"error":{"errors":[{"domain":"global","reason":"sslRequired","message":"SSL + is required to perform this operation."}],"code":403,"message":"SSL is required + to perform this operation."}}' + http_version: + recorded_at: Sun, 17 May 2015 09:59:19 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/v3/playlistItems?key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=contentDetails&playlistId=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 403 + message: Forbidden + headers: + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + Date: + - Sun, 17 May 2015 10:01:57 GMT + Expires: + - Sun, 17 May 2015 10:01:57 GMT + Cache-Control: + - private, max-age=0 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '131' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: '{"error":{"errors":[{"domain":"global","reason":"sslRequired","message":"SSL + is required to perform this operation."}],"code":403,"message":"SSL is required + to perform this operation."}}' + http_version: + recorded_at: Sun, 17 May 2015 09:59:48 GMT +- request: + method: get + uri: http://www.googleapis.com/youtube/v3/playlistItems?fields=items&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet&playlistId=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 403 + message: Forbidden + headers: + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + Date: + - Sun, 17 May 2015 10:03:19 GMT + Expires: + - Sun, 17 May 2015 10:03:19 GMT + Cache-Control: + - private, max-age=0 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '131' + Server: + - GSE + Alternate-Protocol: + - 80:quic,p=1 + body: + encoding: ASCII-8BIT + string: '{"error":{"errors":[{"domain":"global","reason":"sslRequired","message":"SSL + is required to perform this operation."}],"code":403,"message":"SSL is required + to perform this operation."}}' + http_version: + recorded_at: Sun, 17 May 2015 10:01:10 GMT +- request: + method: get + uri: https://www.googleapis.com/youtube/v3/playlists?id=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Expires: + - Sun, 17 May 2015 10:07:23 GMT + Date: + - Sun, 17 May 2015 10:07:23 GMT + Cache-Control: + - private, max-age=0, must-revalidate, no-transform + Etag: + - '"NO6QTeg0-3ShswIeqLchQ_mzWJs/O7xY08pMODVOI02ahJhG-SRbxcw"' + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '1486' + Server: + - GSE + Alternate-Protocol: + - 443:quic,p=1 + body: + encoding: UTF-8 + string: | + { + "kind": "youtube#playlistListResponse", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/O7xY08pMODVOI02ahJhG-SRbxcw\"", + "pageInfo": { + "totalResults": 1, + "resultsPerPage": 1 + }, + "items": [ + { + "kind": "youtube#playlist", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/tXBNzpf3TuQUOT7zeYiB3hhPWYc\"", + "id": "PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr", + "snippet": { + "publishedAt": "2013-08-09T05:09:51.000Z", + "channelId": "UCMDQxm7cUx3yXkfeHa5zJIQ", + "title": "YouTube Policy and Copyright", + "description": "Learn more about copyright basics, flagging, and the YouTube community.", + "thumbnails": { + "default": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/default.jpg", + "width": 120, + "height": 90 + }, + "medium": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/mqdefault.jpg", + "width": 320, + "height": 180 + }, + "high": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/hqdefault.jpg", + "width": 480, + "height": 360 + }, + "standard": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/sddefault.jpg", + "width": 640, + "height": 480 + }, + "maxres": { + "url": "https://i.ytimg.com/vi/8b0aEoxqqC0/maxresdefault.jpg", + "width": 1280, + "height": 720 + } + }, + "channelTitle": "YouTube Help", + "localized": { + "title": "YouTube Policy and Copyright", + "description": "Learn more about copyright basics, flagging, and the YouTube community." + } + } + } + ] + } + http_version: + recorded_at: Sun, 17 May 2015 10:05:14 GMT +- request: + method: get + uri: https://www.googleapis.com/youtube/v3/playlistItems?fields=items&key=AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0&part=snippet&playlistId=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - VideoInfo/2.4.2 + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Expires: + - Sun, 17 May 2015 10:27:46 GMT + Date: + - Sun, 17 May 2015 10:27:46 GMT + Cache-Control: + - private, max-age=0, must-revalidate, no-transform + Etag: + - '"NO6QTeg0-3ShswIeqLchQ_mzWJs/0-dRuoFefu59MRZrJ9OQJh1wEio"' + Vary: + - Origin + - X-Origin + Content-Type: + - application/json; charset=UTF-8 + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '6724' + Server: + - GSE + Alternate-Protocol: + - 443:quic,p=1 + body: + encoding: UTF-8 + string: | + { + "items": [ + { + "kind": "youtube#playlistItem", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/K-gvAWZR6aZKd0do3Xn3MtdmfGM\"", + "id": "PLa0L99Uc4VSCXhwLjoLzxv8xxws5JLbfTP3YqbDI0DxQ", + "snippet": { + "publishedAt": "2015-04-22T21:47:21.000Z", + "channelId": "UCMDQxm7cUx3yXkfeHa5zJIQ", + "title": "Account termination on YouTube", + "description": "Learn more about account termination in the YouTube Help Center: https://support.google.com/youtube/answer/2802168", + "thumbnails": { + "default": { + "url": "https://i.ytimg.com/vi/Oi67QjrXy2w/default.jpg", + "width": 120, + "height": 90 + }, + "medium": { + "url": "https://i.ytimg.com/vi/Oi67QjrXy2w/mqdefault.jpg", + "width": 320, + "height": 180 + }, + "high": { + "url": "https://i.ytimg.com/vi/Oi67QjrXy2w/hqdefault.jpg", + "width": 480, + "height": 360 + }, + "standard": { + "url": "https://i.ytimg.com/vi/Oi67QjrXy2w/sddefault.jpg", + "width": 640, + "height": 480 + }, + "maxres": { + "url": "https://i.ytimg.com/vi/Oi67QjrXy2w/maxresdefault.jpg", + "width": 1280, + "height": 720 + } + }, + "channelTitle": "YouTube Help", + "playlistId": "PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr", + "position": 0, + "resourceId": { + "kind": "youtube#video", + "videoId": "Oi67QjrXy2w" + } + } + }, + { + "kind": "youtube#playlistItem", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/9EB6BjQI7LVTh8ZS5KAmyhTIlTI\"", + "id": "PLa0L99Uc4VSCXhwLjoLzxvw2SdI2zb8sl0kYOz9dDFO0", + "snippet": { + "publishedAt": "2015-04-22T21:48:43.000Z", + "channelId": "UCMDQxm7cUx3yXkfeHa5zJIQ", + "title": "YouTube Copyright Basics (Global)", + "description": "", + "thumbnails": { + "default": { + "url": "https://i.ytimg.com/vi/OQVHWsTHcoc/default.jpg", + "width": 120, + "height": 90 + }, + "medium": { + "url": "https://i.ytimg.com/vi/OQVHWsTHcoc/mqdefault.jpg", + "width": 320, + "height": 180 + }, + "high": { + "url": "https://i.ytimg.com/vi/OQVHWsTHcoc/hqdefault.jpg", + "width": 480, + "height": 360 + }, + "standard": { + "url": "https://i.ytimg.com/vi/OQVHWsTHcoc/sddefault.jpg", + "width": 640, + "height": 480 + } + }, + "channelTitle": "YouTube Help", + "playlistId": "PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr", + "position": 1, + "resourceId": { + "kind": "youtube#video", + "videoId": "OQVHWsTHcoc" + } + } + }, + { + "kind": "youtube#playlistItem", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/FtVY3O5dQ8V9f_gX2fAT2V2BcRE\"", + "id": "PLa0L99Uc4VSCXhwLjoLzxvzeL5__87gFCq75gAaFE6gY", + "snippet": { + "publishedAt": "2013-09-13T16:49:50.000Z", + "channelId": "UCMDQxm7cUx3yXkfeHa5zJIQ", + "title": "Buying YouTube views through third-party services", + "description": "Viewcounts serve as a way to recognize and surface great content. Since views are so important, it's no surprise that an ecosystem of businesses has evolved around artificially helping creators get and create YouTube views, likes, and subscribers.\n\nHowever, paying for views obtained through some of these companies could be a violation of our terms, which exist, in part, to make sure the views on any YouTube video come from real, genuine people.\n\nPlease visit our Help Center article for more info!\n\nhttps://support.google.com/youtube/answer/3399767", + "thumbnails": { + "default": { + "url": "https://i.ytimg.com/vi/_Bt3-WsHfB0/default.jpg", + "width": 120, + "height": 90 + }, + "medium": { + "url": "https://i.ytimg.com/vi/_Bt3-WsHfB0/mqdefault.jpg", + "width": 320, + "height": 180 + }, + "high": { + "url": "https://i.ytimg.com/vi/_Bt3-WsHfB0/hqdefault.jpg", + "width": 480, + "height": 360 + }, + "standard": { + "url": "https://i.ytimg.com/vi/_Bt3-WsHfB0/sddefault.jpg", + "width": 640, + "height": 480 + }, + "maxres": { + "url": "https://i.ytimg.com/vi/_Bt3-WsHfB0/maxresdefault.jpg", + "width": 1280, + "height": 720 + } + }, + "channelTitle": "YouTube Help", + "playlistId": "PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr", + "position": 2, + "resourceId": { + "kind": "youtube#video", + "videoId": "_Bt3-WsHfB0" + } + } + }, + { + "kind": "youtube#playlistItem", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/aZB_rEa-HGKt3gO7mbYt_rv2DGM\"", + "id": "PLa0L99Uc4VSCXhwLjoLzxv5JvZLgV8BItvSbpyhS9_p8", + "snippet": { + "publishedAt": "2013-08-09T05:09:51.000Z", + "channelId": "UCMDQxm7cUx3yXkfeHa5zJIQ", + "title": "YouTube Content ID", + "description": "Learn more about YouTube's Content ID system.", + "thumbnails": { + "default": { + "url": "https://i.ytimg.com/vi/9g2U12SsRns/default.jpg", + "width": 120, + "height": 90 + }, + "medium": { + "url": "https://i.ytimg.com/vi/9g2U12SsRns/mqdefault.jpg", + "width": 320, + "height": 180 + }, + "high": { + "url": "https://i.ytimg.com/vi/9g2U12SsRns/hqdefault.jpg", + "width": 480, + "height": 360 + } + }, + "channelTitle": "YouTube Help", + "playlistId": "PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr", + "position": 3, + "resourceId": { + "kind": "youtube#video", + "videoId": "9g2U12SsRns" + } + } + }, + { + "kind": "youtube#playlistItem", + "etag": "\"NO6QTeg0-3ShswIeqLchQ_mzWJs/9AILAwA-TinybwmctvWPN47Ii34\"", + "id": "PLa0L99Uc4VSCXhwLjoLzxv4Zz231WHvzzM2lBS3jjPZs", + "snippet": { + "publishedAt": "2013-08-09T05:09:51.000Z", + "channelId": "UCMDQxm7cUx3yXkfeHa5zJIQ", + "title": "Reporting and Policy Enforcement on YouTube", + "description": "This video explains the basics of reporting on YouTube. \n\nTo learn more about reporting, policies and safety please visit our Policy and Safety hub, http://www.youtube.com/yt/policyandsafety/", + "thumbnails": { + "default": { + "url": "https://i.ytimg.com/vi/6c3mHikRz0I/default.jpg", + "width": 120, + "height": 90 + }, + "medium": { + "url": "https://i.ytimg.com/vi/6c3mHikRz0I/mqdefault.jpg", + "width": 320, + "height": 180 + }, + "high": { + "url": "https://i.ytimg.com/vi/6c3mHikRz0I/hqdefault.jpg", + "width": 480, + "height": 360 + }, + "standard": { + "url": "https://i.ytimg.com/vi/6c3mHikRz0I/sddefault.jpg", + "width": 640, + "height": 480 + }, + "maxres": { + "url": "https://i.ytimg.com/vi/6c3mHikRz0I/maxresdefault.jpg", + "width": 1280, + "height": 720 + } + }, + "channelTitle": "YouTube Help", + "playlistId": "PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr", + "position": 4, + "resourceId": { + "kind": "youtube#video", + "videoId": "6c3mHikRz0I" + } + } + } + ] + } + http_version: + recorded_at: Sun, 17 May 2015 10:25:37 GMT recorded_with: VCR 2.9.3 From c275ea93828cc9b37eedd40306c22b027c51e3a4 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Sun, 17 May 2015 03:28:58 -0700 Subject: [PATCH 30/58] fixed houndci warning --- lib/video_info/providers/youtubeplaylist.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/video_info/providers/youtubeplaylist.rb b/lib/video_info/providers/youtubeplaylist.rb index 6cee48d5..85e2becc 100644 --- a/lib/video_info/providers/youtubeplaylist.rb +++ b/lib/video_info/providers/youtubeplaylist.rb @@ -27,7 +27,6 @@ def embed_url define_method(method) { nil } end - private def _playlist_entry From e5ec2f89338080e2fa0e51854d99bd54ec60094a Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Sat, 23 May 2015 08:16:49 -0700 Subject: [PATCH 31/58] added YoutubePlaylistAPI module --- lib/video_info/providers/youtubeplaylist.rb | 8 ++++++++ lib/video_info/providers/youtubeplaylist_api.rb | 5 +++++ 2 files changed, 13 insertions(+) create mode 100644 lib/video_info/providers/youtubeplaylist_api.rb diff --git a/lib/video_info/providers/youtubeplaylist.rb b/lib/video_info/providers/youtubeplaylist.rb index 85e2becc..0caf6067 100644 --- a/lib/video_info/providers/youtubeplaylist.rb +++ b/lib/video_info/providers/youtubeplaylist.rb @@ -1,3 +1,5 @@ +require_relative 'youtubeplaylist_api' + class VideoInfo module Providers class YoutubePlaylist < Youtube @@ -5,6 +7,12 @@ class YoutubePlaylist < Youtube alias_method :playlist_id, :video_id attr_accessor :playlist_items_data + def initialize(url, options = {}) + extend YoutubePlaylistAPI + + super(url, options) + end + def self.usable?(url) url =~ /((youtube\.com)\/playlist)|((youtube\.com)\/embed\/videoseries)/ end diff --git a/lib/video_info/providers/youtubeplaylist_api.rb b/lib/video_info/providers/youtubeplaylist_api.rb new file mode 100644 index 00000000..f1a33753 --- /dev/null +++ b/lib/video_info/providers/youtubeplaylist_api.rb @@ -0,0 +1,5 @@ +class VideoInfo + module YoutubePlaylistAPI + + end +end From ffa8d0a02649966bb61537026c6f354b0f5064a1 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Sat, 23 May 2015 08:18:04 -0700 Subject: [PATCH 32/58] moved public methods out of YoutubePlaylist --- lib/video_info/providers/youtubeplaylist.rb | 10 ---------- lib/video_info/providers/youtubeplaylist_api.rb | 8 ++++++++ 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/lib/video_info/providers/youtubeplaylist.rb b/lib/video_info/providers/youtubeplaylist.rb index 0caf6067..e8639317 100644 --- a/lib/video_info/providers/youtubeplaylist.rb +++ b/lib/video_info/providers/youtubeplaylist.rb @@ -17,16 +17,6 @@ def self.usable?(url) url =~ /((youtube\.com)\/playlist)|((youtube\.com)\/embed\/videoseries)/ end - def description - data['items'][0]['snippet']['description'] - end - - def videos - _playlist_video_ids.map do |entry_id| - VideoInfo.new("http://www.youtube.com/watch?v=#{entry_id}") - end - end - def embed_url "//www.youtube.com/embed/videoseries?list=#{playlist_id}" end diff --git a/lib/video_info/providers/youtubeplaylist_api.rb b/lib/video_info/providers/youtubeplaylist_api.rb index f1a33753..57b0c434 100644 --- a/lib/video_info/providers/youtubeplaylist_api.rb +++ b/lib/video_info/providers/youtubeplaylist_api.rb @@ -1,5 +1,13 @@ class VideoInfo module YoutubePlaylistAPI + def description + data['items'][0]['snippet']['description'] + end + def videos + _playlist_video_ids.map do |entry_id| + VideoInfo.new("http://www.youtube.com/watch?v=#{entry_id}") + end + end end end From 5fbc3cd66a0a67db58c6a880e7918f255f0bc284 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Sat, 23 May 2015 08:20:58 -0700 Subject: [PATCH 33/58] moved private functions to YoutubePlaylistAPI module --- lib/video_info/providers/youtubeplaylist.rb | 31 ------------------ .../providers/youtubeplaylist_api.rb | 32 +++++++++++++++++++ 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/lib/video_info/providers/youtubeplaylist.rb b/lib/video_info/providers/youtubeplaylist.rb index e8639317..21cf6841 100644 --- a/lib/video_info/providers/youtubeplaylist.rb +++ b/lib/video_info/providers/youtubeplaylist.rb @@ -3,7 +3,6 @@ class VideoInfo module Providers class YoutubePlaylist < Youtube - alias_method :playlist_id, :video_id attr_accessor :playlist_items_data @@ -27,39 +26,9 @@ def embed_url private - def _playlist_entry - data['items'] - end - - def _playlist_items - data['items'] - end - def _url_regex /youtube.com\/playlist\?p=(\S*)|youtube.com\/embed\/videoseries\?list=([a-zA-Z0-9-]*)/ end - - def _api_path - "/youtube/v3/playlists?part=snippet&id=#{playlist_id}&key=#{api_key}" - end - - def _playlist_items_api_path - "/youtube/v3/playlistItems?part=snippet&playlistId=#{playlist_id}&fields=items&key=#{api_key}" - end - - def _playlist_items_api_url - "https://#{_api_base}#{_playlist_items_api_path}" - end - - def _playlist_items_data - @playlist_items_data ||= _set_data_from_api(_playlist_items_api_url) - end - - def _playlist_video_ids - _playlist_items_data['items'].map do |item| - item['snippet']['resourceId']['videoId'] - end - end end end end diff --git a/lib/video_info/providers/youtubeplaylist_api.rb b/lib/video_info/providers/youtubeplaylist_api.rb index 57b0c434..ef61f843 100644 --- a/lib/video_info/providers/youtubeplaylist_api.rb +++ b/lib/video_info/providers/youtubeplaylist_api.rb @@ -9,5 +9,37 @@ def videos VideoInfo.new("http://www.youtube.com/watch?v=#{entry_id}") end end + + private + + def _playlist_entry + data['items'] + end + + def _playlist_items + data['items'] + end + + def _api_path + "/youtube/v3/playlists?part=snippet&id=#{playlist_id}&key=#{api_key}" + end + + def _playlist_items_api_path + "/youtube/v3/playlistItems?part=snippet&playlistId=#{playlist_id}&fields=items&key=#{api_key}" + end + + def _playlist_items_api_url + "https://#{_api_base}#{_playlist_items_api_path}" + end + + def _playlist_items_data + @playlist_items_data ||= _set_data_from_api(_playlist_items_api_url) + end + + def _playlist_video_ids + _playlist_items_data['items'].map do |item| + item['snippet']['resourceId']['videoId'] + end + end end end From c876c0f980b0235482c2533b58b10f6e3af5c0a1 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Sat, 23 May 2015 08:44:45 -0700 Subject: [PATCH 34/58] separated YoutubePlaylistAPI spec from YoutubePlaylist spec --- .../providers/youtube_playlist_api_spec.rb | 170 ++++++++++++++++++ .../providers/youtube_playlist_spec.rb | 4 - 2 files changed, 170 insertions(+), 4 deletions(-) create mode 100644 spec/lib/video_info/providers/youtube_playlist_api_spec.rb diff --git a/spec/lib/video_info/providers/youtube_playlist_api_spec.rb b/spec/lib/video_info/providers/youtube_playlist_api_spec.rb new file mode 100644 index 00000000..dc740883 --- /dev/null +++ b/spec/lib/video_info/providers/youtube_playlist_api_spec.rb @@ -0,0 +1,170 @@ +require 'spec_helper' + +describe VideoInfo::Providers::YoutubePlaylist do + before(:all) do + VideoInfo.provider_api_keys = { youtube: 'AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0' } + end + + describe ".usable?" do + subject { VideoInfo::Providers::YoutubePlaylist.usable?(url) } + + context "with youtube.com/playlist url" do + let(:url) { 'http://www.youtube.com/playlist?p=PLA575C81A1FBC04CF' } + it { is_expected.to be_truthy } + end + + context "with youtube.com url" do + let(:url) { 'http://www.youtube.com/watch?v=Xp6CXF' } + it { is_expected.to be_falsey } + end + + context "with other url" do + let(:url) { 'http://example.com/video1' } + it { is_expected.to be_falsey } + end + end + + describe "#available?" do + context "with valid playlist", :vcr do + subject { VideoInfo.new('http://www.youtube.com/playlist?p=PLA575C81A1FBC04CF') } + + describe '#available?' do + subject { super().available? } + it { is_expected.to be_truthy } + end + end + + context "with invalid playlist", :vcr do + subject { VideoInfo.new('http://www.youtube.com/playlist?p=PLA575C81A1FBC04CF_invalid') } + + describe '#available?' do + subject { super().available? } + it { is_expected.to be_falsey } + end + end + end + + context "with playlist PL9hW1uS6HUftLdHI6RIsaf", :vcr do + let(:videos) { + [ + VideoInfo.new('http://www.youtube.com/watch?v=Oi67QjrXy2w'), + VideoInfo.new('http://www.youtube.com/watch?v=_Bt3-WsHfB0'), + VideoInfo.new('http://www.youtube.com/watch?v=9g2U12SsRns'), + VideoInfo.new('http://www.youtube.com/watch?v=8b0aEoxqqC0'), + VideoInfo.new('http://www.youtube.com/watch?v=6c3mHikRz0I'), + VideoInfo.new('http://www.youtube.com/watch?v=OQVHWsTHcoc') + ] + } + subject { VideoInfo.new('http://www.youtube.com/playlist?p=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr') } + + describe '#provider' do + subject { super().provider } + it { is_expected.to eq 'YouTube' } + end + + describe '#playlist_id' do + subject { super().playlist_id } + it { is_expected.to eq 'PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr' } + end + + describe '#url' do + subject { super().url } + it { is_expected.to eq 'http://www.youtube.com/playlist?p=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr' } + end + + describe '#embed_url' do + subject { super().embed_url } + it { is_expected.to eq '//www.youtube.com/embed/videoseries?list=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr' } + end + + describe '#embed_code' do + subject { super().embed_code } + it { is_expected.to eq '' } + end + + describe '#title' do + subject { super().title } + it { is_expected.to eq 'YouTube Policy and Copyright' } + end + + describe '#description' do + subject { super().description } + it { is_expected.to eq 'Learn more about copyright basics, flagging, and the YouTube community.' } + end + + describe '#keywords' do + subject { super().keywords } + it { is_expected.to be_nil } + end + + describe '#duration' do + subject { super().duration } + it { is_expected.to be_nil } + end + + describe '#width' do + subject { super().width } + it { is_expected.to be_nil } + end + + describe '#height' do + subject { super().height } + it { is_expected.to be_nil } + end + + describe '#date' do + subject { super().date } + it { is_expected.to be_nil } + end + + describe '#thumbnail_small' do + subject { super().thumbnail_small } + it { is_expected.to eq 'https://i.ytimg.com/vi/8b0aEoxqqC0/default.jpg' } + end + + describe '#thumbnail_medium' do + subject { super().thumbnail_medium } + it { is_expected.to eq 'https://i.ytimg.com/vi/8b0aEoxqqC0/mqdefault.jpg' } + end + + describe '#thumbnail_large' do + subject { super().thumbnail_large } + it { is_expected.to eq 'https://i.ytimg.com/vi/8b0aEoxqqC0/hqdefault.jpg' } + end + + describe '#videos' do + subject { super().videos } + it { is_expected.to match_array(videos) } + end + + describe '#view_count' do + subject { super().view_count } + it { is_expected.to be_nil } + end + end + + context "with playlist PL0E8117603D70E10A in embed path", :vcr do + subject { VideoInfo.new('http://www.youtube.com/embed/videoseries?list=PL0E8117603D70E10A') } + + describe '#playlist_id' do + subject { super().playlist_id } + it { is_expected.to eq 'PL0E8117603D70E10A' } + end + + describe '#videos' do + subject { super().videos } + it { is_expected.to eq [] } + end + end + + context "with playlist PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr in embed path", :vcr do + subject { VideoInfo.new('http://www.youtube.com/embed/videoseries?list=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr') } + + describe '#playlist_id' do + subject { super().playlist_id } + it { is_expected.to eq 'PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr' } + end + end + + +end diff --git a/spec/lib/video_info/providers/youtube_playlist_spec.rb b/spec/lib/video_info/providers/youtube_playlist_spec.rb index dc740883..d4b935c3 100644 --- a/spec/lib/video_info/providers/youtube_playlist_spec.rb +++ b/spec/lib/video_info/providers/youtube_playlist_spec.rb @@ -1,10 +1,6 @@ require 'spec_helper' describe VideoInfo::Providers::YoutubePlaylist do - before(:all) do - VideoInfo.provider_api_keys = { youtube: 'AIzaSyA6PYwSr1EnLFUFy1cZDk3Ifb0rxeJaeZ0' } - end - describe ".usable?" do subject { VideoInfo::Providers::YoutubePlaylist.usable?(url) } From 8ea0d3b267fc25868cd269acf90e3125c313380e Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Sat, 23 May 2015 08:46:51 -0700 Subject: [PATCH 35/58] explicitly clear out API keys in youotube_playlist_spec --- spec/lib/video_info/providers/youtube_playlist_spec.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/lib/video_info/providers/youtube_playlist_spec.rb b/spec/lib/video_info/providers/youtube_playlist_spec.rb index d4b935c3..291af33e 100644 --- a/spec/lib/video_info/providers/youtube_playlist_spec.rb +++ b/spec/lib/video_info/providers/youtube_playlist_spec.rb @@ -1,6 +1,10 @@ require 'spec_helper' describe VideoInfo::Providers::YoutubePlaylist do + before(:all) do + VideoInfo.provider_api_keys = {} + end + describe ".usable?" do subject { VideoInfo::Providers::YoutubePlaylist.usable?(url) } From 826c0d4f923f52f0f6795b18e5a53064572af8c8 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Fri, 29 May 2015 14:59:39 -0700 Subject: [PATCH 36/58] added YoutubePlaylistScraper --- lib/video_info/providers/youtubeplaylist.rb | 7 ++++++- lib/video_info/providers/youtubeplaylist_scraper.rb | 7 +++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 lib/video_info/providers/youtubeplaylist_scraper.rb diff --git a/lib/video_info/providers/youtubeplaylist.rb b/lib/video_info/providers/youtubeplaylist.rb index 21cf6841..81587003 100644 --- a/lib/video_info/providers/youtubeplaylist.rb +++ b/lib/video_info/providers/youtubeplaylist.rb @@ -1,4 +1,5 @@ require_relative 'youtubeplaylist_api' +require_relative 'youtubeplaylist_scraper' class VideoInfo module Providers @@ -7,7 +8,11 @@ class YoutubePlaylist < Youtube attr_accessor :playlist_items_data def initialize(url, options = {}) - extend YoutubePlaylistAPI + if VideoInfo.provider_api_keys[:youtube].nil? + extend YoutubePlaylistScraper + else + extend YoutubePlaylistAPI + end super(url, options) end diff --git a/lib/video_info/providers/youtubeplaylist_scraper.rb b/lib/video_info/providers/youtubeplaylist_scraper.rb new file mode 100644 index 00000000..2bd3e85d --- /dev/null +++ b/lib/video_info/providers/youtubeplaylist_scraper.rb @@ -0,0 +1,7 @@ +class VideoInfo + module Providers + module YoutubePlaylistScraper + + end + end +end From 37642de74c7b35eb10b32a55698cb5ec424135d0 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Fri, 29 May 2015 15:40:02 -0700 Subject: [PATCH 37/58] implemented description in YoutubePlaylistScraper --- .../providers/youtubeplaylist_scraper.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/video_info/providers/youtubeplaylist_scraper.rb b/lib/video_info/providers/youtubeplaylist_scraper.rb index 2bd3e85d..1bc403d7 100644 --- a/lib/video_info/providers/youtubeplaylist_scraper.rb +++ b/lib/video_info/providers/youtubeplaylist_scraper.rb @@ -1,7 +1,23 @@ +require 'nokogiri' +require 'open-uri' +require 'open_uri_redirections' + class VideoInfo module Providers module YoutubePlaylistScraper + def description + data.css('meta')[1].values[1] + end + + private + + def _set_data_from_api(api_url = _api_url) + Nokogiri::HTML(open(api_url, :allow_redirections => :safe)) + end + def _api_url + @url + end end end end From 3eddb0e44f7a5379c945ac464f5f7bccd0789724 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Fri, 29 May 2015 15:51:22 -0700 Subject: [PATCH 38/58] implemented title --- lib/video_info/providers/youtubeplaylist_scraper.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/video_info/providers/youtubeplaylist_scraper.rb b/lib/video_info/providers/youtubeplaylist_scraper.rb index 1bc403d7..4671e6b5 100644 --- a/lib/video_info/providers/youtubeplaylist_scraper.rb +++ b/lib/video_info/providers/youtubeplaylist_scraper.rb @@ -8,6 +8,10 @@ module YoutubePlaylistScraper def description data.css('meta')[1].values[1] end + + def title + data.css('meta')[0].values[1] + end private From 03752cc6b9e0df5b6100d6335e963bcede469351 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Fri, 29 May 2015 15:57:52 -0700 Subject: [PATCH 39/58] made things a bit more generic --- lib/video_info/providers/youtubeplaylist_scraper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/video_info/providers/youtubeplaylist_scraper.rb b/lib/video_info/providers/youtubeplaylist_scraper.rb index 4671e6b5..2e6b3c7d 100644 --- a/lib/video_info/providers/youtubeplaylist_scraper.rb +++ b/lib/video_info/providers/youtubeplaylist_scraper.rb @@ -6,11 +6,11 @@ class VideoInfo module Providers module YoutubePlaylistScraper def description - data.css('meta')[1].values[1] + data.css('meta').find { |m| m.values[0] == 'description' }.values[1] end def title - data.css('meta')[0].values[1] + data.css('meta').find { |m| m.values[0] == 'title' }.values[1] end private From fbd98080d9a8be581be5dea2dd86a4102e98e778 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Fri, 29 May 2015 16:00:27 -0700 Subject: [PATCH 40/58] added nokogiri and open_uri_redirections as dependencies --- video_info.gemspec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/video_info.gemspec b/video_info.gemspec index c06cde7e..c9fd7039 100644 --- a/video_info.gemspec +++ b/video_info.gemspec @@ -24,6 +24,8 @@ Gem::Specification.new do |s| s.add_dependency 'multi_json' s.add_dependency 'htmlentities' s.add_dependency 'iso8601' + s.add_dependency 'nokogiri' + s.add_dependency 'open_uri_redirections' s.add_development_dependency 'bundler', '>= 1.3.5' s.add_development_dependency 'rake' From 8bf47e401b904ad3d979131d1bca525f4fb190b5 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Fri, 29 May 2015 16:19:00 -0700 Subject: [PATCH 41/58] videos now raises an error --- lib/video_info/providers/youtubeplaylist_scraper.rb | 4 ++++ spec/lib/video_info/providers/youtube_playlist_spec.rb | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/video_info/providers/youtubeplaylist_scraper.rb b/lib/video_info/providers/youtubeplaylist_scraper.rb index 2e6b3c7d..69e3b8a6 100644 --- a/lib/video_info/providers/youtubeplaylist_scraper.rb +++ b/lib/video_info/providers/youtubeplaylist_scraper.rb @@ -12,6 +12,10 @@ def description def title data.css('meta').find { |m| m.values[0] == 'title' }.values[1] end + + def videos + raise NotImplementedError + end private diff --git a/spec/lib/video_info/providers/youtube_playlist_spec.rb b/spec/lib/video_info/providers/youtube_playlist_spec.rb index 291af33e..0efbe0e1 100644 --- a/spec/lib/video_info/providers/youtube_playlist_spec.rb +++ b/spec/lib/video_info/providers/youtube_playlist_spec.rb @@ -134,7 +134,7 @@ describe '#videos' do subject { super().videos } - it { is_expected.to match_array(videos) } + it { expect { subject}.to raise_error(NotImplementedError) } end describe '#view_count' do @@ -153,7 +153,7 @@ describe '#videos' do subject { super().videos } - it { is_expected.to eq [] } + it { expect { subject }.to raise_error(NotImplementedError) } end end From 17bdb1950abb23d7a09a702b89e25d3de66e1eb2 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Fri, 29 May 2015 16:20:46 -0700 Subject: [PATCH 42/58] added a message to #videos error --- lib/video_info/providers/youtubeplaylist_scraper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/video_info/providers/youtubeplaylist_scraper.rb b/lib/video_info/providers/youtubeplaylist_scraper.rb index 69e3b8a6..172a3217 100644 --- a/lib/video_info/providers/youtubeplaylist_scraper.rb +++ b/lib/video_info/providers/youtubeplaylist_scraper.rb @@ -14,7 +14,7 @@ def title end def videos - raise NotImplementedError + raise(NotImplementedError, 'To access videos, you must provide an API key to VideoInfo.provider_api_keys') end private From fdb1ffd2fc7aba832cf03889e0c2f4cecc924caf Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Fri, 29 May 2015 16:39:08 -0700 Subject: [PATCH 43/58] implemented thumbnail_medium --- lib/video_info/providers/youtubeplaylist_scraper.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/video_info/providers/youtubeplaylist_scraper.rb b/lib/video_info/providers/youtubeplaylist_scraper.rb index 172a3217..80cae64b 100644 --- a/lib/video_info/providers/youtubeplaylist_scraper.rb +++ b/lib/video_info/providers/youtubeplaylist_scraper.rb @@ -16,6 +16,10 @@ def title def videos raise(NotImplementedError, 'To access videos, you must provide an API key to VideoInfo.provider_api_keys') end + + def thumbnail_medium + 'https:' + data.css('div.pl-header-thumb img').attr('src').value + end private From af6874ef47c461910fb0f699f40e8f9f85b39258 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Fri, 29 May 2015 16:43:04 -0700 Subject: [PATCH 44/58] implemented thumbnail_small --- lib/video_info/providers/youtubeplaylist_scraper.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/video_info/providers/youtubeplaylist_scraper.rb b/lib/video_info/providers/youtubeplaylist_scraper.rb index 80cae64b..fbf2dc83 100644 --- a/lib/video_info/providers/youtubeplaylist_scraper.rb +++ b/lib/video_info/providers/youtubeplaylist_scraper.rb @@ -17,10 +17,15 @@ def videos raise(NotImplementedError, 'To access videos, you must provide an API key to VideoInfo.provider_api_keys') end + def thumbnail_small + thumbnail_medium.sub('mqdefault.jpg', 'default.jpg') + end + def thumbnail_medium 'https:' + data.css('div.pl-header-thumb img').attr('src').value end + private def _set_data_from_api(api_url = _api_url) From c59488107252a9328dbc51dac78997f45b4aa4f1 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Fri, 29 May 2015 16:43:49 -0700 Subject: [PATCH 45/58] implemented thumbnail_large --- lib/video_info/providers/youtubeplaylist_scraper.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/video_info/providers/youtubeplaylist_scraper.rb b/lib/video_info/providers/youtubeplaylist_scraper.rb index fbf2dc83..1fc30484 100644 --- a/lib/video_info/providers/youtubeplaylist_scraper.rb +++ b/lib/video_info/providers/youtubeplaylist_scraper.rb @@ -24,7 +24,10 @@ def thumbnail_small def thumbnail_medium 'https:' + data.css('div.pl-header-thumb img').attr('src').value end - + + def thumbnail_large + thumbnail_medium.sub('mqdefault.jpg', 'hqdefault.jpg') + end private From 1eb9c2ff358c33827833ae4cfae52b338e34ba7d Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Sun, 31 May 2015 14:10:18 -0700 Subject: [PATCH 46/58] implemeneted #available? --- lib/video_info/providers/youtubeplaylist_scraper.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/video_info/providers/youtubeplaylist_scraper.rb b/lib/video_info/providers/youtubeplaylist_scraper.rb index 1fc30484..45abbea7 100644 --- a/lib/video_info/providers/youtubeplaylist_scraper.rb +++ b/lib/video_info/providers/youtubeplaylist_scraper.rb @@ -30,11 +30,15 @@ def thumbnail_large end private - + + def available? + !data.css('div#page').attr('class').value.include?('oops-content') + end + def _set_data_from_api(api_url = _api_url) Nokogiri::HTML(open(api_url, :allow_redirections => :safe)) end - + def _api_url @url end From be91fd91bd564844faf37b0bb132a89b44811389 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Mon, 1 Jun 2015 01:02:12 -0700 Subject: [PATCH 47/58] initial oga switch --- lib/video_info/providers/youtubeplaylist_scraper.rb | 4 ++-- video_info.gemspec | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/video_info/providers/youtubeplaylist_scraper.rb b/lib/video_info/providers/youtubeplaylist_scraper.rb index 45abbea7..79a0ced8 100644 --- a/lib/video_info/providers/youtubeplaylist_scraper.rb +++ b/lib/video_info/providers/youtubeplaylist_scraper.rb @@ -1,4 +1,4 @@ -require 'nokogiri' +require 'oga' require 'open-uri' require 'open_uri_redirections' @@ -36,7 +36,7 @@ def available? end def _set_data_from_api(api_url = _api_url) - Nokogiri::HTML(open(api_url, :allow_redirections => :safe)) + Oga.parse_html(open(api_url, :allow_redirections => :safe)) end def _api_url diff --git a/video_info.gemspec b/video_info.gemspec index c9fd7039..b9f9b26f 100644 --- a/video_info.gemspec +++ b/video_info.gemspec @@ -24,7 +24,7 @@ Gem::Specification.new do |s| s.add_dependency 'multi_json' s.add_dependency 'htmlentities' s.add_dependency 'iso8601' - s.add_dependency 'nokogiri' + s.add_dependency 'oga' s.add_dependency 'open_uri_redirections' s.add_development_dependency 'bundler', '>= 1.3.5' From 006580919f0ad3a6f9b62c915baba59855b4f0ec Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Mon, 1 Jun 2015 01:03:24 -0700 Subject: [PATCH 48/58] fixed thumbnails --- lib/video_info/providers/youtubeplaylist_scraper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/video_info/providers/youtubeplaylist_scraper.rb b/lib/video_info/providers/youtubeplaylist_scraper.rb index 79a0ced8..79802a5c 100644 --- a/lib/video_info/providers/youtubeplaylist_scraper.rb +++ b/lib/video_info/providers/youtubeplaylist_scraper.rb @@ -22,7 +22,7 @@ def thumbnail_small end def thumbnail_medium - 'https:' + data.css('div.pl-header-thumb img').attr('src').value + 'https:' + data.css('div.pl-header-thumb img').attr('src')[0].value end def thumbnail_large From d8815414503608618ba5be2cbad7094119dd72d0 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Mon, 1 Jun 2015 01:10:35 -0700 Subject: [PATCH 49/58] fixed #title and #description --- lib/video_info/providers/youtubeplaylist_scraper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/video_info/providers/youtubeplaylist_scraper.rb b/lib/video_info/providers/youtubeplaylist_scraper.rb index 79802a5c..76f18880 100644 --- a/lib/video_info/providers/youtubeplaylist_scraper.rb +++ b/lib/video_info/providers/youtubeplaylist_scraper.rb @@ -6,11 +6,11 @@ class VideoInfo module Providers module YoutubePlaylistScraper def description - data.css('meta').find { |m| m.values[0] == 'description' }.values[1] + data.css('meta').find { |m| m.attr('name').value == 'description' }.attr('content').value end def title - data.css('meta').find { |m| m.values[0] == 'title' }.values[1] + data.css('meta').find { |m| m.attr('name').value == 'title' }.attr('content').value end def videos From b6307734bc7d6be822fcb3792aec79f9ee120642 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Mon, 1 Jun 2015 01:14:19 -0700 Subject: [PATCH 50/58] cleaned up #description and #title --- .../providers/youtubeplaylist_scraper.rb | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/video_info/providers/youtubeplaylist_scraper.rb b/lib/video_info/providers/youtubeplaylist_scraper.rb index 76f18880..3591b270 100644 --- a/lib/video_info/providers/youtubeplaylist_scraper.rb +++ b/lib/video_info/providers/youtubeplaylist_scraper.rb @@ -6,11 +6,23 @@ class VideoInfo module Providers module YoutubePlaylistScraper def description - data.css('meta').find { |m| m.attr('name').value == 'description' }.attr('content').value + meta_nodes = data.css('meta') + + description_node = meta_nodes.detect do + |m| m.attr('name').value == 'description' + end + + description_node.attr('content').value end def title - data.css('meta').find { |m| m.attr('name').value == 'title' }.attr('content').value + meta_nodes = data.css('meta') + + title_node = meta_nodes.detect do + |m| m.attr('name').value == 'title' + end + + title_node.attr('content').value end def videos From faa1ca8ad5d262336dc1ccd901364b05aa0594da Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Mon, 1 Jun 2015 01:15:16 -0700 Subject: [PATCH 51/58] fixed #available --- lib/video_info/providers/youtubeplaylist_scraper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/video_info/providers/youtubeplaylist_scraper.rb b/lib/video_info/providers/youtubeplaylist_scraper.rb index 3591b270..e95bee3b 100644 --- a/lib/video_info/providers/youtubeplaylist_scraper.rb +++ b/lib/video_info/providers/youtubeplaylist_scraper.rb @@ -44,7 +44,7 @@ def thumbnail_large private def available? - !data.css('div#page').attr('class').value.include?('oops-content') + !data.css('div#page').attr('class')[0].value.include?('oops-content') end def _set_data_from_api(api_url = _api_url) From dc34145f8d36b1dcac2426fd24b56291a07bf740 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Mon, 1 Jun 2015 01:17:26 -0700 Subject: [PATCH 52/58] removed tab --- lib/video_info/providers/youtubeplaylist_scraper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/video_info/providers/youtubeplaylist_scraper.rb b/lib/video_info/providers/youtubeplaylist_scraper.rb index e95bee3b..4a3f4b44 100644 --- a/lib/video_info/providers/youtubeplaylist_scraper.rb +++ b/lib/video_info/providers/youtubeplaylist_scraper.rb @@ -26,7 +26,7 @@ def title end def videos - raise(NotImplementedError, 'To access videos, you must provide an API key to VideoInfo.provider_api_keys') + raise(NotImplementedError, 'To access videos, you must provide an API key to VideoInfo.provider_api_keys') end def thumbnail_small From 3db5c9967ac787faa9f84f0bf8ce7344397fc78a Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Mon, 1 Jun 2015 01:22:10 -0700 Subject: [PATCH 53/58] more tabs i missed... --- lib/video_info/providers/youtubeplaylist.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/video_info/providers/youtubeplaylist.rb b/lib/video_info/providers/youtubeplaylist.rb index 81587003..d70534fa 100644 --- a/lib/video_info/providers/youtubeplaylist.rb +++ b/lib/video_info/providers/youtubeplaylist.rb @@ -8,11 +8,11 @@ class YoutubePlaylist < Youtube attr_accessor :playlist_items_data def initialize(url, options = {}) - if VideoInfo.provider_api_keys[:youtube].nil? - extend YoutubePlaylistScraper - else - extend YoutubePlaylistAPI - end + if VideoInfo.provider_api_keys[:youtube].nil? + extend YoutubePlaylistScraper + else + extend YoutubePlaylistAPI + end super(url, options) end From 933a2fe79de93e1a9c6fcead3a9aeba02831531c Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Mon, 1 Jun 2015 01:28:31 -0700 Subject: [PATCH 54/58] somehow i missed more tabs...... --- .../providers/youtubeplaylist_scraper.rb | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/lib/video_info/providers/youtubeplaylist_scraper.rb b/lib/video_info/providers/youtubeplaylist_scraper.rb index 4a3f4b44..3dcf4a34 100644 --- a/lib/video_info/providers/youtubeplaylist_scraper.rb +++ b/lib/video_info/providers/youtubeplaylist_scraper.rb @@ -6,23 +6,23 @@ class VideoInfo module Providers module YoutubePlaylistScraper def description - meta_nodes = data.css('meta') + meta_nodes = data.css('meta') - description_node = meta_nodes.detect do - |m| m.attr('name').value == 'description' - end + description_node = meta_nodes.detect do + |m| m.attr('name').value == 'description' + end - description_node.attr('content').value + description_node.attr('content').value end def title - meta_nodes = data.css('meta') - - title_node = meta_nodes.detect do - |m| m.attr('name').value == 'title' - end - - title_node.attr('content').value + meta_nodes = data.css('meta') + + title_node = meta_nodes.detect do + |m| m.attr('name').value == 'title' + end + + title_node.attr('content').value end def videos @@ -30,29 +30,29 @@ def videos end def thumbnail_small - thumbnail_medium.sub('mqdefault.jpg', 'default.jpg') + thumbnail_medium.sub('mqdefault.jpg', 'default.jpg') end def thumbnail_medium - 'https:' + data.css('div.pl-header-thumb img').attr('src')[0].value + 'https:' + data.css('div.pl-header-thumb img').attr('src')[0].value end def thumbnail_large - thumbnail_medium.sub('mqdefault.jpg', 'hqdefault.jpg') + thumbnail_medium.sub('mqdefault.jpg', 'hqdefault.jpg') end private def available? - !data.css('div#page').attr('class')[0].value.include?('oops-content') + !data.css('div#page').attr('class')[0].value.include?('oops-content') end def _set_data_from_api(api_url = _api_url) - Oga.parse_html(open(api_url, :allow_redirections => :safe)) + Oga.parse_html(open(api_url, :allow_redirections => :safe)) end def _api_url - @url + @url end end end From 69b16f0bdb62a880c7f8c7d5d43dfe1e78bb332d Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Mon, 1 Jun 2015 01:31:16 -0700 Subject: [PATCH 55/58] fixed trailing whitespace... --- .../providers/youtubeplaylist_scraper.rb | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/video_info/providers/youtubeplaylist_scraper.rb b/lib/video_info/providers/youtubeplaylist_scraper.rb index 3dcf4a34..d5841f12 100644 --- a/lib/video_info/providers/youtubeplaylist_scraper.rb +++ b/lib/video_info/providers/youtubeplaylist_scraper.rb @@ -8,27 +8,27 @@ module YoutubePlaylistScraper def description meta_nodes = data.css('meta') - description_node = meta_nodes.detect do + description_node = meta_nodes.detect do |m| m.attr('name').value == 'description' end description_node.attr('content').value end - + def title meta_nodes = data.css('meta') - + title_node = meta_nodes.detect do |m| m.attr('name').value == 'title' end - + title_node.attr('content').value end - + def videos raise(NotImplementedError, 'To access videos, you must provide an API key to VideoInfo.provider_api_keys') end - + def thumbnail_small thumbnail_medium.sub('mqdefault.jpg', 'default.jpg') end @@ -36,21 +36,21 @@ def thumbnail_small def thumbnail_medium 'https:' + data.css('div.pl-header-thumb img').attr('src')[0].value end - + def thumbnail_large thumbnail_medium.sub('mqdefault.jpg', 'hqdefault.jpg') end private - + def available? !data.css('div#page').attr('class')[0].value.include?('oops-content') end - + def _set_data_from_api(api_url = _api_url) Oga.parse_html(open(api_url, :allow_redirections => :safe)) end - + def _api_url @url end From 217511249da0577a613d9546028d772696753a8c Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Mon, 1 Jun 2015 01:32:13 -0700 Subject: [PATCH 56/58] fixed block argument violation --- lib/video_info/providers/youtubeplaylist_scraper.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/video_info/providers/youtubeplaylist_scraper.rb b/lib/video_info/providers/youtubeplaylist_scraper.rb index d5841f12..ef11cfca 100644 --- a/lib/video_info/providers/youtubeplaylist_scraper.rb +++ b/lib/video_info/providers/youtubeplaylist_scraper.rb @@ -8,8 +8,8 @@ module YoutubePlaylistScraper def description meta_nodes = data.css('meta') - description_node = meta_nodes.detect do - |m| m.attr('name').value == 'description' + description_node = meta_nodes.detect do |m| + m.attr('name').value == 'description' end description_node.attr('content').value @@ -18,8 +18,8 @@ def description def title meta_nodes = data.css('meta') - title_node = meta_nodes.detect do - |m| m.attr('name').value == 'title' + title_node = meta_nodes.detect do |m| + m.attr('name').value == 'title' end title_node.attr('content').value From 9e540743cbaddbc2f5f780cdfe9981aebc6c2f5f Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Mon, 1 Jun 2015 04:55:01 -0700 Subject: [PATCH 57/58] marked #videos spec as pending --- spec/lib/video_info/providers/youtube_playlist_api_spec.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/spec/lib/video_info/providers/youtube_playlist_api_spec.rb b/spec/lib/video_info/providers/youtube_playlist_api_spec.rb index dc740883..78ea3d62 100644 --- a/spec/lib/video_info/providers/youtube_playlist_api_spec.rb +++ b/spec/lib/video_info/providers/youtube_playlist_api_spec.rb @@ -134,7 +134,10 @@ describe '#videos' do subject { super().videos } - it { is_expected.to match_array(videos) } + it 'returns list of videos in playlist' do + pending "waiting for bug in Youtube API to be fixed" + is_expected.to match_array(videos) + end end describe '#view_count' do From 70d6cdd8a6464e6d9256c7a04f8ea2c24576d8d6 Mon Sep 17 00:00:00 2001 From: Vincent Heuken Date: Mon, 1 Jun 2015 04:56:09 -0700 Subject: [PATCH 58/58] made a style mistake last commit --- spec/lib/video_info/providers/youtube_playlist_api_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/lib/video_info/providers/youtube_playlist_api_spec.rb b/spec/lib/video_info/providers/youtube_playlist_api_spec.rb index 78ea3d62..7df47687 100644 --- a/spec/lib/video_info/providers/youtube_playlist_api_spec.rb +++ b/spec/lib/video_info/providers/youtube_playlist_api_spec.rb @@ -135,7 +135,7 @@ describe '#videos' do subject { super().videos } it 'returns list of videos in playlist' do - pending "waiting for bug in Youtube API to be fixed" + pending("waiting for bug in Youtube API to be fixed") is_expected.to match_array(videos) end end