yt 0.9.2 → 0.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|