yt 0.11.3 → 0.11.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +23 -1
- data/lib/yt.rb +1 -0
- data/lib/yt/actions/base.rb +12 -0
- data/lib/yt/actions/list.rb +21 -3
- data/lib/yt/collections/annotations.rb +0 -6
- data/lib/yt/collections/assets.rb +0 -4
- data/lib/yt/collections/authentications.rb +2 -2
- data/lib/yt/collections/claims.rb +1 -5
- data/lib/yt/collections/content_details.rb +2 -4
- data/lib/yt/collections/content_owner_details.rb +2 -5
- data/lib/yt/collections/content_owners.rb +4 -0
- data/lib/yt/collections/device_flows.rb +3 -2
- data/lib/yt/collections/ids.rb +2 -2
- data/lib/yt/collections/live_streaming_details.rb +2 -5
- data/lib/yt/collections/ownerships.rb +2 -2
- data/lib/yt/collections/partnered_channels.rb +1 -1
- data/lib/yt/collections/policies.rb +0 -4
- data/lib/yt/collections/ratings.rb +2 -2
- data/lib/yt/collections/references.rb +0 -4
- data/lib/yt/collections/resources.rb +2 -24
- data/lib/yt/collections/resumable_sessions.rb +2 -2
- data/lib/yt/collections/snippets.rb +10 -11
- data/lib/yt/collections/statistics_sets.rb +2 -4
- data/lib/yt/collections/statuses.rb +7 -14
- data/lib/yt/collections/subscriptions.rb +2 -6
- data/lib/yt/collections/user_infos.rb +0 -6
- data/lib/yt/collections/videos.rb +16 -10
- data/lib/yt/models/playlist.rb +0 -9
- data/lib/yt/models/request.rb +11 -3
- data/lib/yt/models/resource.rb +8 -13
- data/lib/yt/models/video.rb +0 -10
- data/lib/yt/version.rb +1 -1
- data/spec/requests/as_account/account_spec.rb +11 -1
- data/spec/requests/as_account/channel_spec.rb +8 -0
- data/spec/requests/as_server_app/videos_spec.rb +8 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d4252625265d920e49c56abd24211d37be9881ba
|
4
|
+
data.tar.gz: 620dceb9f5722aa8108a06dcc5bc665386a3d1ee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 529db7f3f2bc51ccbabd6a42c320406b87f1320877fe182b04f86d087febc406d65fcd9baa16def7dcfd49997cf6394f149634b26d8dcd9172cf19f71b45363e
|
7
|
+
data.tar.gz: c6357576d740ca80c940392f6794f739715703a660bdc9a1987ea90a68b8ce7d5ef47013ea63e0d85af5175be69684d88bd28ddb6c90da1bca2a822a197b7868
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,11 @@ For more information about changelogs, check
|
|
6
6
|
[Keep a Changelog](http://keepachangelog.com) and
|
7
7
|
[Vandamme](http://tech-angels.github.io/vandamme).
|
8
8
|
|
9
|
+
## 0.11.4 - 2014-08-27
|
10
|
+
|
11
|
+
* [ENHANCEMENT] Add Video search even by id, chart or rating
|
12
|
+
* [FEATURE] Add `ActiveSupport::Notification` to inspect HTTP requests
|
13
|
+
|
9
14
|
## 0.11.3 - 2014-08-21
|
10
15
|
|
11
16
|
* [FEATURE] Add `update` method to Asset model
|
data/README.md
CHANGED
@@ -41,7 +41,7 @@ To install on your system, run
|
|
41
41
|
|
42
42
|
To use inside a bundled Ruby project, add this line to the Gemfile:
|
43
43
|
|
44
|
-
gem 'yt', '~> 0.11.
|
44
|
+
gem 'yt', '~> 0.11.4'
|
45
45
|
|
46
46
|
Since the gem follows [Semantic Versioning](http://semver.org),
|
47
47
|
indicating the full version in your Gemfile (~> *major*.*minor*.*patch*)
|
@@ -74,6 +74,7 @@ account.videos.first #=> #<Yt::Models::Video @id=...>
|
|
74
74
|
|
75
75
|
account.upload_video 'my_video.mp4', title: 'My new video', privacy_status: 'private'
|
76
76
|
account.upload_video 'http://example.com/remote.m4v', title: 'My other video', tags: ['music']
|
77
|
+
|
77
78
|
```
|
78
79
|
|
79
80
|
*The methods above require to be authenticated as a YouTube account (see below).*
|
@@ -422,6 +423,8 @@ Use [Yt::Collections::Videos](http://rubydoc.info/github/Fullscreen/yt/master/Yt
|
|
422
423
|
videos = Yt::Collections::Videos.new
|
423
424
|
videos.where(order: 'viewCount').first.title #=> "PSY - GANGNAM STYLE"
|
424
425
|
videos.where(q: 'Fullscreen CreatorPlatform', safe_search: 'none').size #=> 324
|
426
|
+
videos.where(chart: 'mostPopular', video_category_id: 44).first.title #=> "SINISTER - Trailer"
|
427
|
+
videos.where(id: 'MESycYJytkU,invalid').map(&:title) #=> ["Fullscreen Creator Platform"]
|
425
428
|
```
|
426
429
|
|
427
430
|
*The methods above do not require authentication.*
|
@@ -511,6 +514,25 @@ ad_options.update ad_formats: %w(standard_instream long) #=> true
|
|
511
514
|
|
512
515
|
*The methods above require to be authenticated as the video’s content owner (see below).*
|
513
516
|
|
517
|
+
Instrumentation
|
518
|
+
===============
|
519
|
+
|
520
|
+
Yt leverages [Active Support Instrumentation](http://edgeguides.rubyonrails.org/active_support_instrumentation.html) to provide a hook which developers can use to be notified when HTTP requests to YouTube are made. This hook may be used to track the number of requests over time, monitor quota usage, provide an audit trail, or track how long a specific request takes to complete.
|
521
|
+
|
522
|
+
Subscribe to the `request.yt` notification within your application:
|
523
|
+
|
524
|
+
```ruby
|
525
|
+
ActiveSupport::Notifications.subscribe 'request.yt' do |*args|
|
526
|
+
event = ActiveSupport::Notifications::Event.new(*args)
|
527
|
+
|
528
|
+
event.payload[:request_uri] #=> #<URI::HTTPS URL:https://www.googleapis.com/youtube/v3/channels?id=UCxO1tY8h1AhOz0T4ENwmpow&part=snippet>
|
529
|
+
event.payload[:method] #=> :get
|
530
|
+
event.payload[:response] #=> #<Net::HTTPOK 200 OK readbody=true>
|
531
|
+
|
532
|
+
event.end #=> 2014-08-22 16:57:17 -0700
|
533
|
+
event.duration #=> 141.867 (ms)
|
534
|
+
end
|
535
|
+
```
|
514
536
|
|
515
537
|
Configuring your app
|
516
538
|
====================
|
data/lib/yt.rb
CHANGED
@@ -8,6 +8,7 @@ require 'yt/models/playlist'
|
|
8
8
|
require 'yt/models/playlist_item'
|
9
9
|
require 'yt/models/video'
|
10
10
|
require 'yt/models/ownership'
|
11
|
+
require 'yt/models/advertising_options_set'
|
11
12
|
|
12
13
|
# An object-oriented Ruby client for YouTube.
|
13
14
|
# Helps creating applications that need to interact with YouTube objects.
|
data/lib/yt/actions/base.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# encoding: UTF-8
|
1
2
|
module Yt
|
2
3
|
module Actions
|
3
4
|
# Abstract module that contains methods common to every action
|
@@ -14,6 +15,17 @@ module Yt
|
|
14
15
|
def underscore(value)
|
15
16
|
value.to_s.underscore.to_sym
|
16
17
|
end
|
18
|
+
|
19
|
+
# @return [Hash] the original hash with angle brackets characters in its
|
20
|
+
# values replaced with similar Unicode characters accepted by Youtube.
|
21
|
+
# @see https://support.google.com/youtube/answer/57404?hl=en
|
22
|
+
def sanitize_brackets!(source)
|
23
|
+
case source
|
24
|
+
when String then source.gsub('<', '‹').gsub('>', '›')
|
25
|
+
when Array then source.map{|string| sanitize_brackets! string}
|
26
|
+
when Hash then source.each{|k,v| source[k] = sanitize_brackets! v}
|
27
|
+
end
|
28
|
+
end
|
17
29
|
end
|
18
30
|
end
|
19
31
|
end
|
data/lib/yt/actions/list.rb
CHANGED
@@ -42,10 +42,28 @@ module Yt
|
|
42
42
|
@items[(@last_index +=1) -1]
|
43
43
|
end
|
44
44
|
|
45
|
-
|
45
|
+
def resource_class
|
46
|
+
resource_name = list_resources.singularize
|
47
|
+
require "yt/models/#{resource_name.underscore}"
|
48
|
+
"Yt::Models::#{resource_name}".constantize
|
49
|
+
end
|
50
|
+
|
51
|
+
# @return [resource_class] a new resource initialized with one
|
52
|
+
# of the items returned by asking YouTube for a list of resources.
|
53
|
+
# Can be overwritten by subclasses that initialize instance with
|
54
|
+
# a different set of parameters.
|
46
55
|
def new_item(data)
|
56
|
+
resource_class.new attributes_for_new_item(data)
|
57
|
+
end
|
58
|
+
|
59
|
+
# @private
|
60
|
+
# Can be overwritten by subclasses that initialize instance with
|
61
|
+
# a different set of parameters.
|
62
|
+
def attributes_for_new_item(data)
|
63
|
+
{data: data, auth: @auth}
|
47
64
|
end
|
48
65
|
|
66
|
+
|
49
67
|
def more_pages?
|
50
68
|
@last_index.zero? || !@page_token.nil?
|
51
69
|
end
|
@@ -74,7 +92,7 @@ module Yt
|
|
74
92
|
end
|
75
93
|
|
76
94
|
def list_params
|
77
|
-
path = "/youtube/v3/#{list_resources.
|
95
|
+
path = "/youtube/v3/#{list_resources.camelize :lower}"
|
78
96
|
|
79
97
|
{}.tap do |params|
|
80
98
|
params[:method] = :get
|
@@ -89,7 +107,7 @@ module Yt
|
|
89
107
|
end
|
90
108
|
|
91
109
|
def list_resources
|
92
|
-
self.class
|
110
|
+
self.class.to_s.demodulize
|
93
111
|
end
|
94
112
|
end
|
95
113
|
end
|
@@ -12,12 +12,6 @@ module Yt
|
|
12
12
|
|
13
13
|
private
|
14
14
|
|
15
|
-
# @return [Yt::Models::Annotation] a new annotation initialized with one
|
16
|
-
# of the items returned by asking YouTube for a list of annotations.
|
17
|
-
def new_item(data)
|
18
|
-
Yt::Annotation.new data: data
|
19
|
-
end
|
20
|
-
|
21
15
|
# @return [Hash] the parameters to submit to YouTube to list annotations.
|
22
16
|
# @note YouTube does not provide an API endpoint to get annotations for
|
23
17
|
# a video, so we use an "old-style" URL that YouTube still maintains.
|
@@ -16,10 +16,6 @@ module Yt
|
|
16
16
|
|
17
17
|
private
|
18
18
|
|
19
|
-
def new_item(data)
|
20
|
-
Yt::Asset.new data: data, auth: @auth
|
21
|
-
end
|
22
|
-
|
23
19
|
# @return [Hash] the parameters to submit to YouTube to add a asset.
|
24
20
|
# @see https://developers.google.com/youtube/partner/docs/v1/assets/insert
|
25
21
|
def insert_params
|
@@ -17,10 +17,6 @@ module Yt
|
|
17
17
|
|
18
18
|
private
|
19
19
|
|
20
|
-
def new_item(data)
|
21
|
-
Yt::Claim.new data: data, auth: @auth
|
22
|
-
end
|
23
|
-
|
24
20
|
# @return [Hash] the parameters to submit to YouTube to list claims
|
25
21
|
# administered by the content owner.
|
26
22
|
# @see https://developers.google.com/youtube/partner/docs/v1/claims/list
|
@@ -45,7 +41,7 @@ module Yt
|
|
45
41
|
end
|
46
42
|
|
47
43
|
# @private
|
48
|
-
# @todo: This is
|
44
|
+
# @todo: This is one of two places outside of base.rb where @where_params
|
49
45
|
# is accessed; it should be replaced with a filter on params instead.
|
50
46
|
def claims_path
|
51
47
|
@where_params ||= {}
|
@@ -7,10 +7,8 @@ module Yt
|
|
7
7
|
|
8
8
|
private
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
def new_item(data)
|
13
|
-
Yt::ContentDetail.new data: data['contentDetails']
|
10
|
+
def attributes_for_new_item(data)
|
11
|
+
{data: data['contentDetails']}
|
14
12
|
end
|
15
13
|
|
16
14
|
# @return [Hash] the parameters to submit to YouTube to get the
|
@@ -7,11 +7,8 @@ module Yt
|
|
7
7
|
|
8
8
|
private
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
# list of them.
|
13
|
-
def new_item(data)
|
14
|
-
Yt::ContentOwnerDetail.new data: data['contentOwnerDetails']
|
10
|
+
def attributes_for_new_item(data)
|
11
|
+
{data: data['contentOwnerDetails']}
|
15
12
|
end
|
16
13
|
|
17
14
|
# @return [Hash] the parameters to submit to YouTube to get the
|
data/lib/yt/collections/ids.rb
CHANGED
@@ -7,11 +7,8 @@ module Yt
|
|
7
7
|
|
8
8
|
private
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
# list of them.
|
13
|
-
def new_item(data)
|
14
|
-
Yt::LiveStreamingDetail.new data: data['liveStreamingDetails']
|
10
|
+
def attributes_for_new_item(data)
|
11
|
+
{data: data['liveStreamingDetails']}
|
15
12
|
end
|
16
13
|
|
17
14
|
# @return [Hash] the parameters to submit to YouTube to get the
|
@@ -10,8 +10,8 @@ module Yt
|
|
10
10
|
|
11
11
|
private
|
12
12
|
|
13
|
-
def
|
14
|
-
|
13
|
+
def attributes_for_new_item(data)
|
14
|
+
{data: data, asset_id: @parent.id, auth: @auth}
|
15
15
|
end
|
16
16
|
|
17
17
|
# @return [Hash] the parameters to submit to YouTube to get ownerships.
|
@@ -10,10 +10,6 @@ module Yt
|
|
10
10
|
|
11
11
|
private
|
12
12
|
|
13
|
-
def new_item(data)
|
14
|
-
Yt::Policy.new data: data
|
15
|
-
end
|
16
|
-
|
17
13
|
# @return [Hash] the parameters to submit to YouTube to list policies
|
18
14
|
# saved by the content owner.
|
19
15
|
# @see https://developers.google.com/youtube/partner/docs/v1/policies/list
|
@@ -16,10 +16,6 @@ module Yt
|
|
16
16
|
|
17
17
|
private
|
18
18
|
|
19
|
-
def new_item(data)
|
20
|
-
Yt::Reference.new data: data, auth: @auth
|
21
|
-
end
|
22
|
-
|
23
19
|
# @return [Hash] the parameters to submit to YouTube to add a reference.
|
24
20
|
# @see https://developers.google.com/youtube/partner/docs/v1/references/insert
|
25
21
|
def insert_params
|
@@ -17,25 +17,14 @@ module Yt
|
|
17
17
|
|
18
18
|
private
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
# @see https://developers.google.com/youtube/v3/docs/playlistItems#resource
|
23
|
-
# @see https://developers.google.com/youtube/v3/docs/playlists#resource
|
24
|
-
# @see https://developers.google.com/youtube/v3/docs/channels#resource
|
25
|
-
def new_item(data)
|
26
|
-
resource_class.new id: data['id'], snippet: data['snippet'], status: data['status'], auth: @auth
|
20
|
+
def attributes_for_new_item(data)
|
21
|
+
{id: data['id'], snippet: data['snippet'], status: data['status'], auth: @auth}
|
27
22
|
end
|
28
23
|
|
29
24
|
def resources_params
|
30
25
|
{max_results: 50, part: 'snippet,status'}
|
31
26
|
end
|
32
27
|
|
33
|
-
def resource_class
|
34
|
-
resource_name = list_resources.name.demodulize.singularize
|
35
|
-
require "yt/models/#{resource_name.underscore}"
|
36
|
-
"Yt::Models::#{resource_name}".constantize
|
37
|
-
end
|
38
|
-
|
39
28
|
def build_insert_body(attributes = {})
|
40
29
|
{}.tap do |body|
|
41
30
|
insert_parts.each do |name, part|
|
@@ -59,17 +48,6 @@ module Yt
|
|
59
48
|
(part[:keys] & attributes.keys).any?
|
60
49
|
end
|
61
50
|
|
62
|
-
# @return [Hash] the original hash with angle brackets characters in its
|
63
|
-
# values replaced with similar Unicode characters accepted by Youtube.
|
64
|
-
# @see https://support.google.com/youtube/answer/57404?hl=en
|
65
|
-
def sanitize_brackets!(source)
|
66
|
-
case source
|
67
|
-
when String then source.gsub('<', '‹').gsub('>', '›')
|
68
|
-
when Array then source.map{|string| sanitize_brackets! string}
|
69
|
-
when Hash then source.each{|k,v| source[k] = sanitize_brackets! v}
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
51
|
def camelize(value)
|
74
52
|
value.to_s.camelize(:lower).to_sym
|
75
53
|
end
|
@@ -34,8 +34,8 @@ module Yt
|
|
34
34
|
|
35
35
|
private
|
36
36
|
|
37
|
-
def
|
38
|
-
|
37
|
+
def attributes_for_new_item(data)
|
38
|
+
{url: data['Location'], headers: @headers, auth: @auth}
|
39
39
|
end
|
40
40
|
|
41
41
|
def insert_params
|
@@ -7,27 +7,26 @@ module Yt
|
|
7
7
|
|
8
8
|
private
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
def new_item(data)
|
13
|
-
Yt::Snippet.new data: data['snippet'], auth: @auth
|
10
|
+
def attributes_for_new_item(data)
|
11
|
+
{data: data['snippet'], auth: @auth}
|
14
12
|
end
|
15
13
|
|
14
|
+
# # @return [Yt::Models::Snippet] a new snippet initialized with
|
15
|
+
# # one of the items returned by asking YouTube for a list of snippets.
|
16
|
+
# def new_item(data)
|
17
|
+
# Yt::Snippet.new data: data['snippet'], auth: @auth
|
18
|
+
# end
|
19
|
+
|
16
20
|
# @return [Hash] the parameters to submit to YouTube to get the
|
17
21
|
# snippet of a resource, for instance a channel.
|
18
22
|
# @see https://developers.google.com/youtube/v3/docs/channels#resource
|
19
23
|
def list_params
|
24
|
+
endpoint = @parent.class.to_s.pluralize.demodulize.camelize :lower
|
20
25
|
super.tap do |params|
|
26
|
+
params[:path] = "/youtube/v3/#{endpoint}"
|
21
27
|
params[:params] = {id: @parent.id, part: 'snippet'}
|
22
28
|
end
|
23
29
|
end
|
24
|
-
|
25
|
-
# @private
|
26
|
-
# @note Snippets overrides +list_resources+ since the endpoint is not
|
27
|
-
# '/snippets' but the endpoint related to the snippet’s resource.
|
28
|
-
def list_resources
|
29
|
-
@parent.class.to_s.pluralize
|
30
|
-
end
|
31
30
|
end
|
32
31
|
end
|
33
32
|
end
|
@@ -7,10 +7,8 @@ module Yt
|
|
7
7
|
|
8
8
|
private
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
def new_item(data)
|
13
|
-
Yt::StatisticsSet.new data: data['statistics']
|
10
|
+
def attributes_for_new_item(data)
|
11
|
+
{data: data['statistics']}
|
14
12
|
end
|
15
13
|
|
16
14
|
# @return [Hash] the parameters to submit to YouTube to get the
|
@@ -7,26 +7,19 @@ module Yt
|
|
7
7
|
|
8
8
|
private
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
# of a resource, for instance a channel.
|
13
|
-
# @see https://developers.google.com/youtube/v3/docs/playlists#resource
|
14
|
-
def new_item(data)
|
15
|
-
Yt::Status.new data: data['status']
|
10
|
+
def attributes_for_new_item(data)
|
11
|
+
{data: data['status']}
|
16
12
|
end
|
17
13
|
|
18
14
|
# @return [Hash] the parameters to submit to YouTube to get the status
|
19
15
|
# of a resource, for instance a channel.
|
20
16
|
# @see https://developers.google.com/youtube/v3/docs/channels/list
|
21
17
|
def list_params
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
# '/statuses' but the endpoint related to the snippet’s resource.
|
28
|
-
def list_resources
|
29
|
-
@parent.class.to_s.pluralize
|
18
|
+
endpoint = @parent.class.to_s.pluralize.demodulize.camelize :lower
|
19
|
+
super.tap do |params|
|
20
|
+
params[:path] = "/youtube/v3/#{endpoint}"
|
21
|
+
params[:params] = {id: @parent.id, part: 'status'}
|
22
|
+
end
|
30
23
|
end
|
31
24
|
end
|
32
25
|
end
|
@@ -21,12 +21,8 @@ module Yt
|
|
21
21
|
|
22
22
|
private
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
# subscriptions to a channel.
|
27
|
-
# @see https://developers.google.com/youtube/v3/docs/subscriptions#resource
|
28
|
-
def new_item(data)
|
29
|
-
Yt::Subscription.new id: data['id'], auth: @auth
|
24
|
+
def attributes_for_new_item(data)
|
25
|
+
{id: data['id'], auth: @auth}
|
30
26
|
end
|
31
27
|
|
32
28
|
# @note Google API must have some caching layer by which if we try to
|
@@ -7,12 +7,6 @@ module Yt
|
|
7
7
|
|
8
8
|
private
|
9
9
|
|
10
|
-
# @return [Yt::Models::UserInfo] a new user info initialized with
|
11
|
-
# one of the items returned by asking YouTube for a list of user infos.
|
12
|
-
def new_item(data)
|
13
|
-
Yt::UserInfo.new data: data
|
14
|
-
end
|
15
|
-
|
16
10
|
# @return [Hash] the parameters to submit to YouTube to get the
|
17
11
|
# user info of an account
|
18
12
|
# @see https://developers.google.com/+/api/latest/people/getOpenIdConnect
|
@@ -11,16 +11,9 @@ module Yt
|
|
11
11
|
|
12
12
|
private
|
13
13
|
|
14
|
-
|
15
|
-
# the items returned by asking YouTube for a list of videos.
|
16
|
-
# According to the documentation, tags are only visible to the video's
|
17
|
-
# uploader, and are not returned when search for all the videos of an
|
18
|
-
# account. Instead, a separate call to Videos#list is required. Setting
|
19
|
-
# +includes_tags+ to +false+ makes sure that `video.tags` will do this.
|
20
|
-
# @see https://developers.google.com/youtube/v3/docs/videos#resource
|
21
|
-
def new_item(data)
|
14
|
+
def attributes_for_new_item(data)
|
22
15
|
snippet = data.fetch('snippet', {}).merge includes_tags: false
|
23
|
-
|
16
|
+
{id: data['id']['videoId'], snippet: snippet, auth: @auth}
|
24
17
|
end
|
25
18
|
|
26
19
|
# @return [Hash] the parameters to submit to YouTube to list videos.
|
@@ -28,7 +21,7 @@ module Yt
|
|
28
21
|
def list_params
|
29
22
|
super.tap do |params|
|
30
23
|
params[:params] = videos_params
|
31
|
-
params[:path] =
|
24
|
+
params[:path] = videos_path
|
32
25
|
end
|
33
26
|
end
|
34
27
|
|
@@ -58,6 +51,19 @@ module Yt
|
|
58
51
|
apply_where_params! params
|
59
52
|
end
|
60
53
|
end
|
54
|
+
|
55
|
+
# @private
|
56
|
+
# @todo: This is one of two places outside of base.rb where @where_params
|
57
|
+
# is accessed; it should be replaced with a filter on params instead.
|
58
|
+
# @see https://developers.google.com/youtube/v3/docs/videos/list
|
59
|
+
def videos_path
|
60
|
+
@where_params ||= {}
|
61
|
+
if @parent.nil? && (@where_params.keys & [:id, :chart]).any?
|
62
|
+
'/youtube/v3/videos'
|
63
|
+
else
|
64
|
+
'/youtube/v3/search'
|
65
|
+
end
|
66
|
+
end
|
61
67
|
end
|
62
68
|
end
|
63
69
|
end
|
data/lib/yt/models/playlist.rb
CHANGED
@@ -23,15 +23,6 @@ module Yt
|
|
23
23
|
!exists?
|
24
24
|
end
|
25
25
|
|
26
|
-
def update(attributes = {})
|
27
|
-
super attributes do |data|
|
28
|
-
@id = data['id']
|
29
|
-
@snippet = Snippet.new data: data['snippet'] if data['snippet']
|
30
|
-
@status = Status.new data: data['status'] if data['status']
|
31
|
-
true
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
26
|
def exists?
|
36
27
|
!@id.nil?
|
37
28
|
end
|
data/lib/yt/models/request.rb
CHANGED
@@ -51,13 +51,21 @@ module Yt
|
|
51
51
|
private
|
52
52
|
|
53
53
|
def response
|
54
|
-
@response ||=
|
55
|
-
http.request http_request
|
56
|
-
end
|
54
|
+
@response ||= send_http_request
|
57
55
|
rescue OpenSSL::SSL::SSLError, Errno::ETIMEDOUT, Errno::ENETUNREACH, Errno::ECONNRESET => e
|
58
56
|
@response ||= e
|
59
57
|
end
|
60
58
|
|
59
|
+
def send_http_request
|
60
|
+
ActiveSupport::Notifications.instrument 'request.yt' do |payload|
|
61
|
+
payload[:method] = @method
|
62
|
+
payload[:request_uri] = uri
|
63
|
+
payload[:response] = Net::HTTP.start(*net_http_options) do |http|
|
64
|
+
http.request http_request
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
61
69
|
def http_request
|
62
70
|
@http_request ||= net_http_class.new(uri.request_uri).tap do |request|
|
63
71
|
set_headers! request
|
data/lib/yt/models/resource.rb
CHANGED
@@ -32,13 +32,19 @@ module Yt
|
|
32
32
|
@url.username if @url
|
33
33
|
end
|
34
34
|
|
35
|
-
def update(attributes = {}
|
35
|
+
def update(attributes = {})
|
36
36
|
underscore_keys! attributes
|
37
37
|
body = build_update_body attributes
|
38
38
|
params = {part: body.keys.join(',')}
|
39
|
-
do_update
|
39
|
+
do_update params: params, body: body.merge(id: @id) do |data|
|
40
|
+
@id = data['id']
|
41
|
+
@snippet = Snippet.new data: data['snippet'] if data['snippet']
|
42
|
+
@status = Status.new data: data['status'] if data['status']
|
43
|
+
true
|
44
|
+
end
|
40
45
|
end
|
41
46
|
|
47
|
+
|
42
48
|
private
|
43
49
|
|
44
50
|
# @return [Hash] the parameters to submit to YouTube to update a playlist.
|
@@ -80,17 +86,6 @@ module Yt
|
|
80
86
|
part[:required] || (part[:keys] & attributes.keys).any?
|
81
87
|
end
|
82
88
|
|
83
|
-
# @return [Hash] the original hash with angle brackets characters in its
|
84
|
-
# values replaced with similar Unicode characters accepted by Youtube.
|
85
|
-
# @see https://support.google.com/youtube/answer/57404?hl=en
|
86
|
-
def sanitize_brackets!(source)
|
87
|
-
case source
|
88
|
-
when String then source.gsub('<', '‹').gsub('>', '›')
|
89
|
-
when Array then source.map{|string| sanitize_brackets! string}
|
90
|
-
when Hash then source.each{|k,v| source[k] = sanitize_brackets! v}
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
89
|
def camelize(value)
|
95
90
|
value.to_s.camelize(:lower).to_sym
|
96
91
|
end
|
data/lib/yt/models/video.rb
CHANGED
@@ -96,16 +96,6 @@ module Yt
|
|
96
96
|
!@id.nil?
|
97
97
|
end
|
98
98
|
|
99
|
-
def update(attributes = {})
|
100
|
-
super attributes do |data|
|
101
|
-
@id = data['id']
|
102
|
-
@snippet = Snippet.new data: data['snippet'] if data['snippet']
|
103
|
-
@status = Status.new data: data['status'] if data['status']
|
104
|
-
true
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
|
109
99
|
# Returns whether the authenticated account likes the video.
|
110
100
|
#
|
111
101
|
# This method requires {Resource#auth auth} to return an
|
data/lib/yt/version.rb
CHANGED
@@ -14,7 +14,7 @@ describe Yt::Account, :device_app do
|
|
14
14
|
describe '.videos' do
|
15
15
|
let(:video) { $account.videos.where(order: 'viewCount').first }
|
16
16
|
|
17
|
-
specify 'returns the account
|
17
|
+
specify 'returns the videos uploaded by the account with their tags' do
|
18
18
|
expect(video).to be_a Yt::Video
|
19
19
|
expect(video.tags).not_to be_empty
|
20
20
|
end
|
@@ -32,6 +32,16 @@ describe Yt::Account, :device_app do
|
|
32
32
|
it { expect(count).to be_zero }
|
33
33
|
end
|
34
34
|
end
|
35
|
+
|
36
|
+
describe 'ignores filters by ID (all the videos uploaded by the account are returned)' do
|
37
|
+
let(:other_video) { $account.videos.where(order: 'viewCount', id: 'invalid').first }
|
38
|
+
it { expect(other_video.id).to eq video.id }
|
39
|
+
end
|
40
|
+
|
41
|
+
describe 'ignores filters by chart (all the videos uploaded by the account are returned)' do
|
42
|
+
let(:other_video) { $account.videos.where(order: 'viewCount', chart: 'invalid').first }
|
43
|
+
it { expect(other_video.id).to eq video.id }
|
44
|
+
end
|
35
45
|
end
|
36
46
|
|
37
47
|
describe '.upload_video' do
|
@@ -42,6 +42,14 @@ describe Yt::Channel, :device_app do
|
|
42
42
|
it { expect(channel.unsubscribe!).to be_truthy }
|
43
43
|
end
|
44
44
|
|
45
|
+
describe 'filtering by ID is ignored when listing videos' do
|
46
|
+
it { expect(channel.videos.where(id: 'invalid').first).to be_a Yt::Video }
|
47
|
+
end
|
48
|
+
|
49
|
+
describe 'filtering by chart is ignored when listing videos' do
|
50
|
+
it { expect(channel.videos.where(chart: 'invalid').first).to be_a Yt::Video }
|
51
|
+
end
|
52
|
+
|
45
53
|
# @note: these tests are slow because they go through multiple pages of
|
46
54
|
# results and do so to test that we can overcome YouTube’s limitation of
|
47
55
|
# only returning the first 500 results for each query.
|
@@ -12,4 +12,12 @@ describe Yt::Collections::Videos, :server_app do
|
|
12
12
|
specify 'with a query term, only returns some YouTube videos' do
|
13
13
|
expect(videos.where(q: 'Fullscreen CreatorPlatform', video_duration: :long).size).to be < 100_000
|
14
14
|
end
|
15
|
+
|
16
|
+
specify 'with a list of video IDs, only returns the videos matching those IDs' do
|
17
|
+
expect(videos.where(id: 'MESycYJytkU,invalid').size).to be 1
|
18
|
+
end
|
19
|
+
|
20
|
+
specify 'with a chart parameter, only returns videos of that chart', :ruby2 do
|
21
|
+
expect(videos.where(chart: 'mostPopular').size).to be 200
|
22
|
+
end
|
15
23
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.11.
|
4
|
+
version: 0.11.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Claudio Baccigalupo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-08-
|
11
|
+
date: 2014-08-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|