yt 0.9.2 → 0.9.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/Gemfile.lock +1 -1
- data/HISTORY.md +2 -0
- data/README.md +1 -1
- data/lib/yt/actions/list.rb +9 -1
- data/lib/yt/collections/annotations.rb +1 -0
- data/lib/yt/collections/authentications.rb +1 -1
- data/lib/yt/collections/base.rb +10 -3
- data/lib/yt/collections/channels.rb +5 -1
- data/lib/yt/collections/claims.rb +7 -8
- data/lib/yt/collections/content_details.rb +5 -1
- data/lib/yt/collections/content_owners.rb +1 -1
- data/lib/yt/collections/ids.rb +5 -1
- data/lib/yt/collections/partnered_channels.rb +7 -6
- data/lib/yt/collections/playlist_items.rb +7 -3
- data/lib/yt/collections/playlists.rb +7 -3
- data/lib/yt/collections/policies.rb +1 -6
- data/lib/yt/collections/references.rb +1 -5
- data/lib/yt/collections/reports.rb +3 -2
- data/lib/yt/collections/resources.rb +2 -7
- data/lib/yt/collections/statistics_sets.rb +6 -2
- data/lib/yt/collections/statuses.rb +2 -4
- data/lib/yt/collections/subscriptions.rb +10 -1
- data/lib/yt/collections/videos.rb +10 -6
- data/lib/yt/collections/viewer_percentages.rb +3 -2
- data/lib/yt/models/claim.rb +14 -0
- data/lib/yt/models/playlist.rb +1 -28
- data/lib/yt/models/resource.rb +35 -0
- data/lib/yt/models/video.rb +12 -9
- data/lib/yt/version.rb +1 -1
- data/spec/collections/claims_spec.rb +30 -0
- data/spec/collections/playlist_items_spec.rb +1 -0
- data/spec/collections/policies_spec.rb +30 -0
- data/spec/collections/references_spec.rb +30 -0
- data/spec/collections/videos_spec.rb +25 -1
- data/spec/models/claim_spec.rb +12 -0
- data/spec/requests/as_account/account_spec.rb +1 -1
- data/spec/requests/as_account/video_spec.rb +58 -12
- data/spec/requests/as_content_owner/content_owner_spec.rb +14 -1
- metadata +27 -33
- data/spec/collections/annotations_spec.rb +0 -6
- data/spec/collections/channels_spec.rb +0 -6
- data/spec/collections/content_details_spec.rb +0 -6
- data/spec/collections/ratings_spec.rb +0 -6
- data/spec/collections/snippets_spec.rb +0 -6
- data/spec/collections/user_infos_spec.rb +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ab23bb89da9f80619391db9f6d8a490609631147
|
4
|
+
data.tar.gz: 4e2cc2d536a284e70f43f6c94fd80cd44dc63b4f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 24ecc8fe727d82e972d568310e9d463f1a51f1028184ca99bf122b63e647857ec62174a214882eb1b81e681eec36127cf9b3dadb1c23544235d11ec9acfc1312
|
7
|
+
data.tar.gz: c118aa416a094bee9ecd3027756045720d3409c1a9c0d99479f9fe1b0e6d2544b855d4b63c299bdbbe47cfa7d55fbfa786ff1c07497b92d72a98656fcfab0cc5
|
data/.travis.yml
CHANGED
data/Gemfile.lock
CHANGED
data/HISTORY.md
CHANGED
@@ -4,6 +4,8 @@ v0.9 - 2014/07/28
|
|
4
4
|
* [breaking change] Rename rating.update to rating.set
|
5
5
|
* Add content_owner.references to retrieve ContentID references
|
6
6
|
* Add content_owner.policies to list ContentID policies
|
7
|
+
* Let 'update' methods understand both under_score and camelCased parameters
|
8
|
+
* Add claim.third_party?
|
7
9
|
|
8
10
|
|
9
11
|
v0.8 - 2014/07/18
|
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.9.
|
44
|
+
gem 'yt', '~> 0.9.3'
|
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*)
|
data/lib/yt/actions/list.rb
CHANGED
@@ -19,6 +19,7 @@ module Yt
|
|
19
19
|
while next_item = find_next
|
20
20
|
items << next_item
|
21
21
|
end
|
22
|
+
@where_params = {}
|
22
23
|
end
|
23
24
|
end
|
24
25
|
|
@@ -41,7 +42,7 @@ module Yt
|
|
41
42
|
|
42
43
|
def next_page
|
43
44
|
params = list_params.dup
|
44
|
-
params[:params][:
|
45
|
+
params[:params][:page_token] = @page_token if @page_token
|
45
46
|
next_page = fetch_page params
|
46
47
|
@page_token = next_page[:token]
|
47
48
|
next_page[:items]
|
@@ -55,6 +56,7 @@ module Yt
|
|
55
56
|
end
|
56
57
|
|
57
58
|
def request(params = {})
|
59
|
+
camelize_keys! params[:params] if params.fetch(:camelize_params, true)
|
58
60
|
@last_request = Yt::Request.new params
|
59
61
|
end
|
60
62
|
|
@@ -80,6 +82,12 @@ module Yt
|
|
80
82
|
def list_resources
|
81
83
|
self.class
|
82
84
|
end
|
85
|
+
|
86
|
+
def camelize_keys!(hash = {})
|
87
|
+
hash.dup.each_key do |key|
|
88
|
+
hash[key.to_s.camelize(:lower).to_sym] = hash.delete key
|
89
|
+
end
|
90
|
+
end
|
83
91
|
end
|
84
92
|
end
|
85
93
|
end
|
data/lib/yt/collections/base.rb
CHANGED
@@ -20,9 +20,16 @@ module Yt
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def where(conditions = {})
|
23
|
-
|
24
|
-
|
25
|
-
|
23
|
+
self.tap do
|
24
|
+
@items = []
|
25
|
+
@where_params = conditions
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def apply_where_params!(params = {})
|
32
|
+
params.merge!(@where_params ||= {})
|
26
33
|
end
|
27
34
|
end
|
28
35
|
end
|
@@ -12,7 +12,11 @@ module Yt
|
|
12
12
|
# @return [Hash] the parameters to submit to YouTube to list channels.
|
13
13
|
# @see https://developers.google.com/youtube/v3/docs/channels/list
|
14
14
|
def list_params
|
15
|
-
super.tap{|params| params[:params]
|
15
|
+
super.tap{|params| params[:params] = channels_params}
|
16
|
+
end
|
17
|
+
|
18
|
+
def channels_params
|
19
|
+
resources_params.merge mine: true
|
16
20
|
end
|
17
21
|
end
|
18
22
|
end
|
@@ -19,23 +19,22 @@ module Yt
|
|
19
19
|
# @see https://developers.google.com/youtube/partner/docs/v1/claims/list
|
20
20
|
# @see https://developers.google.com/youtube/partner/docs/v1/claimSearch/list
|
21
21
|
def list_params
|
22
|
-
|
23
22
|
super.tap do |params|
|
24
|
-
params[:params] = claims_params
|
25
23
|
params[:path] = claims_path
|
24
|
+
params[:params] = claims_params
|
26
25
|
end
|
27
26
|
end
|
28
27
|
|
29
28
|
def claims_params
|
30
|
-
|
31
|
-
(@extra_params ||= {}).each do |key, value|
|
32
|
-
params[key.to_s.camelize :lower] = value
|
33
|
-
end
|
34
|
-
end
|
29
|
+
apply_where_params! on_behalf_of_content_owner: @parent.owner_name
|
35
30
|
end
|
36
31
|
|
32
|
+
# @private
|
33
|
+
# @todo: This is the only place outside of base.rb where @where_params
|
34
|
+
# is accessed; it should be replaced with a filter on params instead.
|
37
35
|
def claims_path
|
38
|
-
|
36
|
+
@where_params ||= {}
|
37
|
+
if @where_params.empty? || @where_params.key?(:id)
|
39
38
|
'/youtube/partner/v1/claims'
|
40
39
|
else
|
41
40
|
'/youtube/partner/v1/claimSearch'
|
@@ -18,10 +18,14 @@ module Yt
|
|
18
18
|
# @see https://developers.google.com/youtube/v3/docs/videos#resource
|
19
19
|
def list_params
|
20
20
|
super.tap do |params|
|
21
|
-
params[:params] =
|
21
|
+
params[:params] = content_details_params
|
22
22
|
params[:path] = '/youtube/v3/videos'
|
23
23
|
end
|
24
24
|
end
|
25
|
+
|
26
|
+
def content_details_params
|
27
|
+
{max_results: 50, part: 'contentDetails', id: @parent.id}
|
28
|
+
end
|
25
29
|
end
|
26
30
|
end
|
27
31
|
end
|
data/lib/yt/collections/ids.rb
CHANGED
@@ -13,10 +13,14 @@ module Yt
|
|
13
13
|
|
14
14
|
def list_params
|
15
15
|
super.tap do |params|
|
16
|
-
params[:params] =
|
16
|
+
params[:params] = ids_params
|
17
17
|
params[:path] = "/youtube/v3/#{@parent.kind.pluralize}"
|
18
18
|
end
|
19
19
|
end
|
20
|
+
|
21
|
+
def ids_params
|
22
|
+
{for_username: @parent.username, part: 'id'}
|
23
|
+
end
|
20
24
|
end
|
21
25
|
end
|
22
26
|
end
|
@@ -6,13 +6,14 @@ module Yt
|
|
6
6
|
|
7
7
|
private
|
8
8
|
|
9
|
-
# @
|
10
|
-
# @
|
11
|
-
|
9
|
+
# @private
|
10
|
+
# @note Partnered Channels overwrites +channel_params+ since the query
|
11
|
+
# is slightly different.
|
12
|
+
def channels_params
|
12
13
|
super.tap do |params|
|
13
|
-
params
|
14
|
-
params[:
|
15
|
-
params[:
|
14
|
+
params.delete :mine
|
15
|
+
params[:managed_by_me] = true
|
16
|
+
params[:on_behalf_of_content_owner] = @parent.owner_name
|
16
17
|
end
|
17
18
|
end
|
18
19
|
|
@@ -17,10 +17,14 @@ module Yt
|
|
17
17
|
|
18
18
|
private
|
19
19
|
|
20
|
-
# @return [Hash] the parameters to submit to YouTube to list
|
21
|
-
# @see https://developers.google.com/youtube/v3/docs/
|
20
|
+
# @return [Hash] the parameters to submit to YouTube to list channels.
|
21
|
+
# @see https://developers.google.com/youtube/v3/docs/channels/list
|
22
22
|
def list_params
|
23
|
-
super.tap{|params| params[:params]
|
23
|
+
super.tap{|params| params[:params] = playlist_items_params}
|
24
|
+
end
|
25
|
+
|
26
|
+
def playlist_items_params
|
27
|
+
resources_params.merge playlist_id: @parent.id
|
24
28
|
end
|
25
29
|
end
|
26
30
|
end
|
@@ -20,10 +20,14 @@ module Yt
|
|
20
20
|
|
21
21
|
private
|
22
22
|
|
23
|
-
# @return [Hash] the parameters to submit to YouTube to list
|
24
|
-
# @see https://developers.google.com/youtube/v3/docs/
|
23
|
+
# @return [Hash] the parameters to submit to YouTube to list channels.
|
24
|
+
# @see https://developers.google.com/youtube/v3/docs/channels/list
|
25
25
|
def list_params
|
26
|
-
super.tap{|params| params[:params]
|
26
|
+
super.tap{|params| params[:params] = playlists_params}
|
27
|
+
end
|
28
|
+
|
29
|
+
def playlists_params
|
30
|
+
resources_params.merge channel_id: @parent.id
|
27
31
|
end
|
28
32
|
end
|
29
33
|
end
|
@@ -18,7 +18,6 @@ module Yt
|
|
18
18
|
# saved by the content owner.
|
19
19
|
# @see https://developers.google.com/youtube/partner/docs/v1/policies/list
|
20
20
|
def list_params
|
21
|
-
|
22
21
|
super.tap do |params|
|
23
22
|
params[:params] = policies_params
|
24
23
|
params[:path] = '/youtube/partner/v1/policies'
|
@@ -26,11 +25,7 @@ module Yt
|
|
26
25
|
end
|
27
26
|
|
28
27
|
def policies_params
|
29
|
-
|
30
|
-
(@extra_params ||= {}).each do |key, value|
|
31
|
-
params[key.to_s.camelize :lower] = value
|
32
|
-
end
|
33
|
-
end
|
28
|
+
apply_where_params! on_behalf_of_content_owner: @parent.owner_name
|
34
29
|
end
|
35
30
|
end
|
36
31
|
end
|
@@ -25,11 +25,7 @@ module Yt
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def references_params
|
28
|
-
|
29
|
-
(@extra_params ||= {}).each do |key, value|
|
30
|
-
params[key.to_s.camelize :lower] = value
|
31
|
-
end
|
32
|
-
end
|
28
|
+
apply_where_params! on_behalf_of_content_owner: @parent.owner_name
|
33
29
|
end
|
34
30
|
end
|
35
31
|
end
|
@@ -20,12 +20,13 @@ module Yt
|
|
20
20
|
def list_params
|
21
21
|
super.tap do |params|
|
22
22
|
params[:path] = '/youtube/analytics/v1/reports'
|
23
|
-
params[:params] =
|
23
|
+
params[:params] = reports_params
|
24
|
+
params[:camelize_params] = false
|
24
25
|
end
|
25
26
|
end
|
26
27
|
|
27
28
|
def reports_params
|
28
|
-
|
29
|
+
@parent.reports_params.tap do |params|
|
29
30
|
params['start-date'] = @days_range.begin
|
30
31
|
params['end-date'] = @days_range.end
|
31
32
|
params['metrics'] = @metric
|
@@ -18,13 +18,8 @@ module Yt
|
|
18
18
|
resource_class.new id: data['id'], snippet: data['snippet'], status: data['status'], auth: @auth
|
19
19
|
end
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
# @see https://developers.google.com/youtube/v3/docs/playlists/list
|
24
|
-
def list_params
|
25
|
-
super.tap do |params|
|
26
|
-
params[:params] = {maxResults: 50, part: 'snippet,status'}
|
27
|
-
end
|
21
|
+
def resources_params
|
22
|
+
{max_results: 50, part: 'snippet,status'}
|
28
23
|
end
|
29
24
|
|
30
25
|
def resource_class
|
@@ -7,7 +7,7 @@ module Yt
|
|
7
7
|
|
8
8
|
private
|
9
9
|
|
10
|
-
# @return [Yt::Models::StatisticsSet] a new statistics set initialized
|
10
|
+
# @return [Yt::Models::StatisticsSet] a new statistics set initialized
|
11
11
|
# with one of the items returned by asking YouTube for a list of them.
|
12
12
|
def new_item(data)
|
13
13
|
Yt::StatisticsSet.new data: data['statistics']
|
@@ -18,10 +18,14 @@ module Yt
|
|
18
18
|
# @see https://developers.google.com/youtube/v3/docs/videos#resource
|
19
19
|
def list_params
|
20
20
|
super.tap do |params|
|
21
|
-
params[:params] = {maxResults: 50, part: 'statistics', id: @parent.id}
|
22
21
|
params[:path] = "/youtube/v3/#{@parent.kind.pluralize}"
|
22
|
+
params[:params] = statistics_sets_params
|
23
23
|
end
|
24
24
|
end
|
25
|
+
|
26
|
+
def statistics_sets_params
|
27
|
+
{max_results: 50, part: 'statistics', id: @parent.id}
|
28
|
+
end
|
25
29
|
end
|
26
30
|
end
|
27
31
|
end
|
@@ -19,13 +19,11 @@ module Yt
|
|
19
19
|
# of a resource, for instance a channel.
|
20
20
|
# @see https://developers.google.com/youtube/v3/docs/channels/list
|
21
21
|
def list_params
|
22
|
-
super.tap
|
23
|
-
params[:params] = {id: @parent.id, part: 'status'}
|
24
|
-
end
|
22
|
+
super.tap{|params| params[:params] = {id: @parent.id, part: 'status'}}
|
25
23
|
end
|
26
24
|
|
27
25
|
# @private
|
28
|
-
# @note Statuses overrides +list_resources+ since the endpoint is not
|
26
|
+
# @note Statuses overrides +list_resources+ since the endpoint is not
|
29
27
|
# '/statuses' but the endpoint related to the snippet’s resource.
|
30
28
|
def list_resources
|
31
29
|
@parent.class.to_s.pluralize
|
@@ -50,7 +50,16 @@ module Yt
|
|
50
50
|
# @see https://developers.google.com/youtube/v3/docs/subscriptions/list
|
51
51
|
def list_params
|
52
52
|
super.tap do |params|
|
53
|
-
params[:params] =
|
53
|
+
params[:params] = subscriptions_params
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def subscriptions_params
|
58
|
+
{}.tap do |params|
|
59
|
+
params[:max_results] = 50
|
60
|
+
params[:for_channel_id] = @parent.id
|
61
|
+
params[:mine] = true
|
62
|
+
params[:part] = 'snippet'
|
54
63
|
end
|
55
64
|
end
|
56
65
|
|
@@ -22,7 +22,7 @@ module Yt
|
|
22
22
|
# @see https://developers.google.com/youtube/v3/docs/search/list
|
23
23
|
def list_params
|
24
24
|
super.tap do |params|
|
25
|
-
params[:params] =
|
25
|
+
params[:params] = videos_params
|
26
26
|
params[:path] = '/youtube/v3/search'
|
27
27
|
end
|
28
28
|
end
|
@@ -36,17 +36,21 @@ module Yt
|
|
36
36
|
# that limit, the query is restarted with a publishedBefore filter in
|
37
37
|
# case there are more videos to be listed for a channel
|
38
38
|
def add_offset_to(items)
|
39
|
-
if items.count == videos_params[:
|
39
|
+
if items.count == videos_params[:max_results]
|
40
40
|
last_published = items.last['snippet']['publishedAt']
|
41
41
|
@page_token, @published_before = '', last_published
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
45
|
def videos_params
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
46
|
+
@parent.videos_params.tap do |params|
|
47
|
+
params[:type] = :video
|
48
|
+
params[:max_results] = 50
|
49
|
+
params[:part] = 'snippet'
|
50
|
+
params[:order] = 'date'
|
51
|
+
params[:published_before] = @published_before if @published_before
|
52
|
+
apply_where_params! params
|
53
|
+
end
|
50
54
|
end
|
51
55
|
end
|
52
56
|
end
|
@@ -24,12 +24,13 @@ module Yt
|
|
24
24
|
def list_params
|
25
25
|
super.tap do |params|
|
26
26
|
params[:path] = '/youtube/analytics/v1/reports'
|
27
|
-
params[:params] =
|
27
|
+
params[:params] = reports_params
|
28
|
+
params[:capitalize_params] = false
|
28
29
|
end
|
29
30
|
end
|
30
31
|
|
31
32
|
def reports_params
|
32
|
-
|
33
|
+
@parent.reports_params.tap do |params|
|
33
34
|
params['start-date'] = 3.months.ago.to_date
|
34
35
|
params['end-date'] = Date.today.to_date
|
35
36
|
params['metrics'] = :viewerPercentage
|
data/lib/yt/models/claim.rb
CHANGED
@@ -27,6 +27,11 @@ module Yt
|
|
27
27
|
@video_id ||= @data["videoId"]
|
28
28
|
end
|
29
29
|
|
30
|
+
# Status
|
31
|
+
|
32
|
+
STATUSES = %q(active appealed disputed inactive pending potential
|
33
|
+
takedown unknown)
|
34
|
+
|
30
35
|
# @return [String] the claim’s status. Valid values are: active,
|
31
36
|
# appealed, disputed, inactive, pending, potential, takedown, unknown.
|
32
37
|
# @note When updating a claim, you can update its status from active to
|
@@ -76,6 +81,10 @@ module Yt
|
|
76
81
|
status == 'unknown'
|
77
82
|
end
|
78
83
|
|
84
|
+
# Content Type
|
85
|
+
|
86
|
+
CONTENT_TYPES = %q(audio video audiovisual)
|
87
|
+
|
79
88
|
# @return [String] whether the claim covers the audio, video, or
|
80
89
|
# audiovisual portion of the claimed content. Valid values are: audio,
|
81
90
|
# audiovisual, video.
|
@@ -103,6 +112,11 @@ module Yt
|
|
103
112
|
@created_at ||= Time.parse @data["timeCreated"]
|
104
113
|
end
|
105
114
|
|
115
|
+
# @return [Boolean] whether a third party created the claim.
|
116
|
+
def third_party?
|
117
|
+
@third_party_claim ||= @data['thirdPartyClaim'] == true
|
118
|
+
end
|
119
|
+
|
106
120
|
# Return whether the video should be blocked where not explicitly owned.
|
107
121
|
# @return [Boolean] whether the claimed video should be blocked anywhere
|
108
122
|
# it is not explicitly owned. For example, if you upload a video for an
|
data/lib/yt/models/playlist.rb
CHANGED
@@ -24,22 +24,7 @@ module Yt
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def update(attributes = {})
|
27
|
-
|
28
|
-
|
29
|
-
body = {id: @id}.tap do |body|
|
30
|
-
update_parts.each do |part, options|
|
31
|
-
if (options[:keys] & attributes.keys).any? || options[:required]
|
32
|
-
body[part] = {}.tap do |hash|
|
33
|
-
options[:keys].map do |key|
|
34
|
-
hash[camelize key] = attributes[key] || send(key)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
part = body.except(:id).keys.join(',')
|
42
|
-
do_update(params: {part: part}, body: body) do |data|
|
27
|
+
super attributes do |data|
|
43
28
|
@id = data['id']
|
44
29
|
@snippet = Snippet.new data: data['snippet'] if data['snippet']
|
45
30
|
@status = Status.new data: data['status'] if data['status']
|
@@ -88,18 +73,6 @@ module Yt
|
|
88
73
|
{snippet: snippet, status: status}
|
89
74
|
end
|
90
75
|
|
91
|
-
# @note If we dropped support for ActiveSupport 3, then we could simply
|
92
|
-
# invoke transform_keys!{|key| key.to_s.underscore.to_sym}
|
93
|
-
def underscore_keys!(hash)
|
94
|
-
hash.dup.each_key do |key|
|
95
|
-
hash[key.to_s.underscore.to_sym] = hash.delete key
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
def camelize(value)
|
100
|
-
value.to_s.camelize(:lower).to_sym
|
101
|
-
end
|
102
|
-
|
103
76
|
def video_params(video_id)
|
104
77
|
{id: video_id, kind: :video}
|
105
78
|
end
|
data/lib/yt/models/resource.rb
CHANGED
@@ -30,6 +30,13 @@ module Yt
|
|
30
30
|
@url.username if @url
|
31
31
|
end
|
32
32
|
|
33
|
+
def update(attributes = {}, &block)
|
34
|
+
underscore_keys! attributes
|
35
|
+
body = build_update_body attributes
|
36
|
+
params = {part: body.keys.join(',')}
|
37
|
+
do_update(params: params, body: body.merge(id: @id), &block)
|
38
|
+
end
|
39
|
+
|
33
40
|
private
|
34
41
|
|
35
42
|
# @return [Hash] the parameters to submit to YouTube to update a playlist.
|
@@ -47,6 +54,34 @@ module Yt
|
|
47
54
|
def delete_params
|
48
55
|
super.tap{|params| params[:params] = {id: @id}}
|
49
56
|
end
|
57
|
+
|
58
|
+
def build_update_body(attributes = {})
|
59
|
+
body = {}
|
60
|
+
update_parts.each do |name, part|
|
61
|
+
body[name] = {}.tap do |hash|
|
62
|
+
part[:keys].map{|k| hash[camelize k] = attributes.fetch k, send(k)}
|
63
|
+
end if should_include_part_in_update?(part, attributes)
|
64
|
+
end
|
65
|
+
body
|
66
|
+
end
|
67
|
+
|
68
|
+
def should_include_part_in_update?(part, attributes = {})
|
69
|
+
part[:required] || (part[:keys] & attributes.keys).any?
|
70
|
+
end
|
71
|
+
|
72
|
+
# If we dropped support for ActiveSupport 3, then we could simply
|
73
|
+
# invoke transform_keys!{|key| key.to_s.underscore.to_sym}
|
74
|
+
def underscore_keys!(hash)
|
75
|
+
hash.dup.each_key{|key| hash[underscore key] = hash.delete key}
|
76
|
+
end
|
77
|
+
|
78
|
+
def camelize(value)
|
79
|
+
value.to_s.camelize(:lower).to_sym
|
80
|
+
end
|
81
|
+
|
82
|
+
def underscore(value)
|
83
|
+
value.to_s.underscore.to_sym
|
84
|
+
end
|
50
85
|
end
|
51
86
|
end
|
52
87
|
end
|
data/lib/yt/models/video.rb
CHANGED
@@ -81,21 +81,15 @@ module Yt
|
|
81
81
|
# caution, as the whole status object needs to be updated, not just
|
82
82
|
# privacyStatus, but also embeddable, license, publicStatsViewable,
|
83
83
|
# and publishAt
|
84
|
-
def update(
|
85
|
-
|
86
|
-
options[:description] ||= description
|
87
|
-
options[:tags] ||= tags
|
88
|
-
options[:categoryId] ||= category_id
|
89
|
-
snippet = options.slice :title, :description, :tags, :categoryId
|
90
|
-
body = {id: @id, snippet: snippet}
|
91
|
-
|
92
|
-
do_update(params: {part: 'snippet'}, body: body) do |data|
|
84
|
+
def update(attributes = {})
|
85
|
+
super attributes do |data|
|
93
86
|
@id = data['id']
|
94
87
|
@snippet = Snippet.new data: data['snippet'] if data['snippet']
|
95
88
|
true
|
96
89
|
end
|
97
90
|
end
|
98
91
|
|
92
|
+
|
99
93
|
# Returns whether the authenticated account likes the video.
|
100
94
|
#
|
101
95
|
# This method requires {Resource#auth auth} to return an
|
@@ -157,6 +151,15 @@ module Yt
|
|
157
151
|
params['filters'] = "video==#{id}"
|
158
152
|
end
|
159
153
|
end
|
154
|
+
|
155
|
+
private
|
156
|
+
|
157
|
+
# @see https://developers.google.com/youtube/v3/docs/videos/update
|
158
|
+
# @todo: Add status, recording details keys
|
159
|
+
def update_parts
|
160
|
+
snippet_keys = [:title, :description, :tags, :category_id]
|
161
|
+
{snippet: {keys: snippet_keys}}
|
162
|
+
end
|
160
163
|
end
|
161
164
|
end
|
162
165
|
end
|
data/lib/yt/version.rb
CHANGED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'yt/collections/claims'
|
3
|
+
require 'yt/models/content_owner'
|
4
|
+
|
5
|
+
describe Yt::Collections::Claims do
|
6
|
+
subject(:collection) { Yt::Collections::Claims.new parent: content_owner }
|
7
|
+
let(:content_owner) { Yt::ContentOwner.new owner_name: 'any-name' }
|
8
|
+
let(:page) { {items: [], token: 'any-token'} }
|
9
|
+
let(:query) { {q: 'search string'} }
|
10
|
+
|
11
|
+
describe '#count' do
|
12
|
+
context 'called once with .where(query) and once without' do
|
13
|
+
after do
|
14
|
+
collection.where(query).count
|
15
|
+
collection.count
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'only applies the query on the first call' do
|
19
|
+
expect(collection).to receive(:fetch_page) do |options|
|
20
|
+
expect(options[:params]).to include query
|
21
|
+
page
|
22
|
+
end
|
23
|
+
expect(collection).to receive(:fetch_page) do |options|
|
24
|
+
expect(options[:params]).not_to include query
|
25
|
+
page
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'yt/collections/policies'
|
3
|
+
require 'yt/models/content_owner'
|
4
|
+
|
5
|
+
describe Yt::Collections::Policies do
|
6
|
+
subject(:collection) { Yt::Collections::Policies.new parent: content_owner }
|
7
|
+
let(:content_owner) { Yt::ContentOwner.new owner_name: 'any-name' }
|
8
|
+
let(:page) { {items: [], token: 'any-token'} }
|
9
|
+
let(:query) { {id: 'any-id'} }
|
10
|
+
|
11
|
+
describe '#count' do
|
12
|
+
context 'called once with .where(query) and once without' do
|
13
|
+
after do
|
14
|
+
collection.where(query).count
|
15
|
+
collection.count
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'only applies the query on the first call' do
|
19
|
+
expect(collection).to receive(:fetch_page) do |options|
|
20
|
+
expect(options[:params]).to include query
|
21
|
+
page
|
22
|
+
end
|
23
|
+
expect(collection).to receive(:fetch_page) do |options|
|
24
|
+
expect(options[:params]).not_to include query
|
25
|
+
page
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'yt/collections/references'
|
3
|
+
require 'yt/models/content_owner'
|
4
|
+
|
5
|
+
describe Yt::Collections::References do
|
6
|
+
subject(:collection) { Yt::Collections::References.new parent: content_owner }
|
7
|
+
let(:content_owner) { Yt::ContentOwner.new id: 'any-id' }
|
8
|
+
let(:page) { {items: [], token: 'any-token'} }
|
9
|
+
let(:query) { {id: 'reference-id'} }
|
10
|
+
|
11
|
+
describe '#count' do
|
12
|
+
context 'called once with .where(query) and once without' do
|
13
|
+
after do
|
14
|
+
collection.where(query).count
|
15
|
+
collection.count
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'only applies the query on the first call' do
|
19
|
+
expect(collection).to receive(:fetch_page) do |options|
|
20
|
+
expect(options[:params]).to include query
|
21
|
+
page
|
22
|
+
end
|
23
|
+
expect(collection).to receive(:fetch_page) do |options|
|
24
|
+
expect(options[:params]).not_to include query
|
25
|
+
page
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,6 +1,30 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'yt/collections/videos'
|
3
|
+
require 'yt/models/channel'
|
3
4
|
|
4
5
|
describe Yt::Collections::Videos do
|
5
|
-
|
6
|
+
subject(:collection) { Yt::Collections::Videos.new parent: channel }
|
7
|
+
let(:channel) { Yt::Channel.new id: 'any-id' }
|
8
|
+
let(:page) { {items: [], token: 'any-token'} }
|
9
|
+
let(:query) { {q: 'search string'} }
|
10
|
+
|
11
|
+
describe '#count' do
|
12
|
+
context 'called once with .where(query) and once without' do
|
13
|
+
after do
|
14
|
+
collection.where(query).count
|
15
|
+
collection.count
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'only applies the query on the first call' do
|
19
|
+
expect(collection).to receive(:fetch_page) do |options|
|
20
|
+
expect(options[:params]).to include query
|
21
|
+
page
|
22
|
+
end
|
23
|
+
expect(collection).to receive(:fetch_page) do |options|
|
24
|
+
expect(options[:params]).not_to include query
|
25
|
+
page
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
6
30
|
end
|
data/spec/models/claim_spec.rb
CHANGED
@@ -189,4 +189,16 @@ describe Yt::Claim do
|
|
189
189
|
it { expect(claim.block_outside_ownership?).to be false }
|
190
190
|
end
|
191
191
|
end
|
192
|
+
|
193
|
+
describe '#third_party?' do
|
194
|
+
context 'given fetching a claim returns thirdPartyClaim true' do
|
195
|
+
let(:data) { {"thirdPartyClaim"=>true} }
|
196
|
+
it { expect(claim.third_party?).to be true }
|
197
|
+
end
|
198
|
+
|
199
|
+
context 'given fetching a claim returns thirdPartyClaim true' do
|
200
|
+
let(:data) { {"thirdPartyClaim"=>false} }
|
201
|
+
it { expect(claim.third_party?).to be false }
|
202
|
+
end
|
203
|
+
end
|
192
204
|
end
|
@@ -12,7 +12,7 @@ describe Yt::Account, :device_app do
|
|
12
12
|
|
13
13
|
describe '.videos' do
|
14
14
|
it { expect($account.videos).to be_a Yt::Collections::Videos }
|
15
|
-
it { expect($account.videos.first).to be_a Yt::Video }
|
15
|
+
it { expect($account.videos.where(order: 'viewCount').first).to be_a Yt::Video }
|
16
16
|
|
17
17
|
describe '.where(q: query_string)' do
|
18
18
|
let(:count) { $account.videos.where(q: query).count }
|
@@ -100,24 +100,70 @@ describe Yt::Video, :device_app do
|
|
100
100
|
end
|
101
101
|
|
102
102
|
context 'given one of my own videos that I want to update' do
|
103
|
-
let(:id) { $account.videos.first.id }
|
103
|
+
let(:id) { $account.videos.where(order: 'viewCount').first.id }
|
104
|
+
let!(:old_title) { video.title }
|
105
|
+
let!(:old_privacy_status) { video.privacy_status }
|
106
|
+
let(:update) { video.update attrs }
|
104
107
|
|
105
|
-
|
108
|
+
context 'given I update the title' do
|
106
109
|
# NOTE: The use of UTF-8 characters is to test that we can pass up to
|
107
110
|
# 50 characters, independently of their representation
|
108
111
|
let(:attrs) { {title: "Yt Example Update Video #{rand} - ®•♡❥❦❧☙"} }
|
109
|
-
|
110
|
-
|
112
|
+
|
113
|
+
specify 'only updates the title' do
|
114
|
+
expect(update).to be true
|
115
|
+
expect(video.title).not_to eq old_title
|
116
|
+
expect(video.privacy_status).to eq old_privacy_status
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context 'given I update the description' do
|
121
|
+
let!(:old_description) { video.description }
|
122
|
+
let(:attrs) { {description: "Yt Example Description #{rand} - ®•♡❥❦❧☙"} }
|
123
|
+
|
124
|
+
specify 'only updates the description' do
|
125
|
+
expect(update).to be true
|
126
|
+
expect(video.description).not_to eq old_description
|
127
|
+
expect(video.title).to eq old_title
|
128
|
+
expect(video.privacy_status).to eq old_privacy_status
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
context 'given I update the tags' do
|
133
|
+
let!(:old_tags) { video.tags }
|
134
|
+
let(:attrs) { {tags: ["Yt Test Tag #{rand}"]} }
|
135
|
+
|
136
|
+
specify 'only updates the tag' do
|
137
|
+
expect(update).to be true
|
138
|
+
expect(video.tags).not_to eq old_tags
|
139
|
+
expect(video.title).to eq old_title
|
140
|
+
expect(video.privacy_status).to eq old_privacy_status
|
141
|
+
end
|
111
142
|
end
|
112
143
|
|
113
|
-
|
114
|
-
let(:
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
144
|
+
context 'given I update the category ID' do
|
145
|
+
let!(:old_category_id) { video.category_id }
|
146
|
+
let!(:new_category_id) { old_category_id == '22' ? '21' : '22' }
|
147
|
+
|
148
|
+
context 'passing the parameter in underscore syntax' do
|
149
|
+
let(:attrs) { {category_id: new_category_id} }
|
150
|
+
|
151
|
+
specify 'only updates the category ID' do
|
152
|
+
expect(update).to be true
|
153
|
+
expect(video.category_id).not_to eq old_category_id
|
154
|
+
expect(video.title).to eq old_title
|
155
|
+
expect(video.privacy_status).to eq old_privacy_status
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
context 'passing the parameter in camel-case syntax' do
|
160
|
+
let(:attrs) { {categoryId: new_category_id} }
|
161
|
+
|
162
|
+
specify 'only updates the category ID' do
|
163
|
+
expect(update).to be true
|
164
|
+
expect(video.category_id).not_to eq old_category_id
|
165
|
+
end
|
166
|
+
end
|
121
167
|
end
|
122
168
|
|
123
169
|
it 'returns valid reports for video-related metrics' do
|
@@ -9,7 +9,20 @@ describe Yt::ContentOwner, :partner do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
describe '.claims' do
|
12
|
-
|
12
|
+
describe 'given the content owner has policies' do
|
13
|
+
let(:claim) { $content_owner.claims.first }
|
14
|
+
|
15
|
+
it 'returns valid metadata' do
|
16
|
+
expect(claim.id).to be_a String
|
17
|
+
expect(claim.asset_id).to be_a String
|
18
|
+
expect(claim.video_id).to be_a String
|
19
|
+
expect(claim.status).to be_in Yt::Claim::STATUSES
|
20
|
+
expect(claim.content_type).to be_in Yt::Claim::CONTENT_TYPES
|
21
|
+
expect(claim.created_at).to be_a Time
|
22
|
+
expect(claim).not_to be_third_party
|
23
|
+
expect(claim.block_outside_ownership?).to be_in [true, false]
|
24
|
+
end
|
25
|
+
end
|
13
26
|
|
14
27
|
describe '.where(id: claim_id)' do
|
15
28
|
let(:count) { $content_owner.claims.where(id: claim_id).count }
|
metadata
CHANGED
@@ -1,97 +1,97 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.3
|
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-07-
|
11
|
+
date: 2014-07-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - '>='
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - '>='
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - '>='
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - '>='
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - '>='
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: yard
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - '>='
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - '>='
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: coveralls
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - '>='
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - '>='
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
description: Youtube V3 API client.
|
@@ -102,10 +102,10 @@ executables:
|
|
102
102
|
extensions: []
|
103
103
|
extra_rdoc_files: []
|
104
104
|
files:
|
105
|
-
-
|
106
|
-
-
|
107
|
-
-
|
108
|
-
-
|
105
|
+
- .gitignore
|
106
|
+
- .rspec
|
107
|
+
- .travis.yml
|
108
|
+
- .yardopts
|
109
109
|
- Gemfile
|
110
110
|
- Gemfile.lock
|
111
111
|
- HISTORY.md
|
@@ -189,15 +189,12 @@ files:
|
|
189
189
|
- lib/yt/models/user_info.rb
|
190
190
|
- lib/yt/models/video.rb
|
191
191
|
- lib/yt/version.rb
|
192
|
-
- spec/collections/
|
193
|
-
- spec/collections/channels_spec.rb
|
194
|
-
- spec/collections/content_details_spec.rb
|
192
|
+
- spec/collections/claims_spec.rb
|
195
193
|
- spec/collections/playlist_items_spec.rb
|
196
194
|
- spec/collections/playlists_spec.rb
|
197
|
-
- spec/collections/
|
198
|
-
- spec/collections/
|
195
|
+
- spec/collections/policies_spec.rb
|
196
|
+
- spec/collections/references_spec.rb
|
199
197
|
- spec/collections/subscriptions_spec.rb
|
200
|
-
- spec/collections/user_infos_spec.rb
|
201
198
|
- spec/collections/videos_spec.rb
|
202
199
|
- spec/errors/missing_auth_spec.rb
|
203
200
|
- spec/errors/no_items_spec.rb
|
@@ -257,31 +254,28 @@ require_paths:
|
|
257
254
|
- lib
|
258
255
|
required_ruby_version: !ruby/object:Gem::Requirement
|
259
256
|
requirements:
|
260
|
-
- -
|
257
|
+
- - '>='
|
261
258
|
- !ruby/object:Gem::Version
|
262
259
|
version: 1.9.3
|
263
260
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
264
261
|
requirements:
|
265
|
-
- -
|
262
|
+
- - '>='
|
266
263
|
- !ruby/object:Gem::Version
|
267
264
|
version: '0'
|
268
265
|
requirements: []
|
269
266
|
rubyforge_project:
|
270
|
-
rubygems_version: 2.2.
|
267
|
+
rubygems_version: 2.2.1
|
271
268
|
signing_key:
|
272
269
|
specification_version: 4
|
273
270
|
summary: Yt makes it easy to interact with Youtube V3 API by providing a modular,
|
274
271
|
intuitive and tested Ruby-style API.
|
275
272
|
test_files:
|
276
|
-
- spec/collections/
|
277
|
-
- spec/collections/channels_spec.rb
|
278
|
-
- spec/collections/content_details_spec.rb
|
273
|
+
- spec/collections/claims_spec.rb
|
279
274
|
- spec/collections/playlist_items_spec.rb
|
280
275
|
- spec/collections/playlists_spec.rb
|
281
|
-
- spec/collections/
|
282
|
-
- spec/collections/
|
276
|
+
- spec/collections/policies_spec.rb
|
277
|
+
- spec/collections/references_spec.rb
|
283
278
|
- spec/collections/subscriptions_spec.rb
|
284
|
-
- spec/collections/user_infos_spec.rb
|
285
279
|
- spec/collections/videos_spec.rb
|
286
280
|
- spec/errors/missing_auth_spec.rb
|
287
281
|
- spec/errors/no_items_spec.rb
|