yt 0.25.13 → 0.32.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +305 -1
- data/MIT-LICENSE +1 -1
- data/README.md +86 -5
- data/YOUTUBE_IT.md +3 -3
- data/lib/yt.rb +5 -2
- data/lib/yt/actions/list.rb +3 -3
- data/lib/yt/associations/has_authentication.rb +33 -1
- data/lib/yt/associations/has_reports.rb +13 -18
- data/lib/yt/collections/assets.rb +2 -2
- data/lib/yt/collections/authentications.rb +9 -2
- data/lib/yt/collections/base.rb +3 -3
- data/lib/yt/collections/bulk_report_jobs.rb +28 -0
- data/lib/yt/collections/bulk_reports.rb +24 -0
- data/lib/yt/collections/claims.rb +22 -1
- data/lib/yt/collections/comment_threads.rb +41 -0
- data/lib/yt/collections/content_owners.rb +1 -1
- data/lib/yt/collections/group_infos.rb +27 -0
- data/lib/yt/collections/group_items.rb +45 -0
- data/lib/yt/collections/reports.rb +75 -13
- data/lib/yt/collections/revocations.rb +30 -0
- data/lib/yt/collections/video_groups.rb +29 -0
- data/lib/yt/collections/videos.rb +34 -9
- data/lib/yt/constants/geography.rb +326 -0
- data/lib/yt/errors/forbidden.rb +1 -3
- data/lib/yt/errors/no_items.rb +1 -3
- data/lib/yt/errors/request_error.rb +10 -7
- data/lib/yt/errors/server_error.rb +1 -3
- data/lib/yt/errors/unauthorized.rb +3 -3
- data/lib/yt/models/account.rb +12 -0
- data/lib/yt/models/advertising_options_set.rb +4 -4
- data/lib/yt/models/bulk_report.rb +23 -0
- data/lib/yt/models/bulk_report_job.rb +23 -0
- data/lib/yt/models/channel.rb +21 -12
- data/lib/yt/models/claim.rb +13 -2
- data/lib/yt/models/comment.rb +37 -0
- data/lib/yt/models/comment_thread.rb +50 -0
- data/lib/yt/models/content_detail.rb +6 -0
- data/lib/yt/models/content_owner.rb +31 -1
- data/lib/yt/models/group_info.rb +16 -0
- data/lib/yt/models/group_item.rb +15 -0
- data/lib/yt/models/resource.rb +3 -10
- data/lib/yt/models/revocation.rb +12 -0
- data/lib/yt/models/right_owner.rb +0 -2
- data/lib/yt/models/snippet.rb +24 -3
- data/lib/yt/models/video.rb +42 -11
- data/lib/yt/models/video_group.rb +186 -0
- data/lib/yt/request.rb +5 -3
- data/lib/yt/version.rb +2 -2
- data/spec/collections/comment_threads_spec.rb +46 -0
- data/spec/collections/playlist_items_spec.rb +1 -1
- data/spec/collections/reports_spec.rb +2 -2
- data/spec/constants/geography_spec.rb +16 -0
- data/spec/models/annotation_spec.rb +1 -1
- data/spec/models/claim_spec.rb +15 -3
- data/spec/models/comment_spec.rb +40 -0
- data/spec/models/comment_thread_spec.rb +93 -0
- data/spec/models/content_detail_spec.rb +7 -0
- data/spec/models/reference_spec.rb +2 -2
- data/spec/models/request_spec.rb +21 -0
- data/spec/models/resource_spec.rb +0 -15
- data/spec/models/video_spec.rb +1 -1
- data/spec/requests/as_account/account_spec.rb +16 -4
- data/spec/requests/as_account/authentications_spec.rb +1 -13
- data/spec/requests/as_account/channel_spec.rb +15 -45
- data/spec/requests/as_account/playlist_item_spec.rb +3 -3
- data/spec/requests/as_account/playlist_spec.rb +5 -32
- data/spec/requests/as_account/video_spec.rb +2022 -21
- data/spec/requests/as_content_owner/account_spec.rb +4 -0
- data/spec/requests/as_content_owner/bulk_report_job_spec.rb +19 -0
- data/spec/requests/as_content_owner/channel_spec.rb +59 -270
- data/spec/requests/as_content_owner/content_owner_spec.rb +89 -1
- data/spec/requests/as_content_owner/playlist_spec.rb +0 -15
- data/spec/requests/as_content_owner/video_group_spec.rb +112 -0
- data/spec/requests/as_content_owner/video_spec.rb +72 -146
- data/spec/requests/as_server_app/channel_spec.rb +1 -21
- data/spec/requests/as_server_app/comment_spec.rb +22 -0
- data/spec/requests/as_server_app/comment_thread_spec.rb +27 -0
- data/spec/requests/as_server_app/comment_threads_spec.rb +41 -0
- data/spec/requests/as_server_app/playlist_item_spec.rb +2 -2
- data/spec/requests/as_server_app/playlist_spec.rb +1 -22
- data/spec/requests/as_server_app/video_spec.rb +21 -19
- data/spec/requests/as_server_app/videos_spec.rb +5 -5
- data/spec/requests/unauthenticated/video_spec.rb +1 -9
- data/spec/spec_helper.rb +1 -1
- data/yt.gemspec +2 -1
- metadata +51 -17
- data/lib/yt/collections/ids.rb +0 -27
- data/lib/yt/config.rb +0 -54
- data/lib/yt/models/configuration.rb +0 -70
- data/lib/yt/models/description.rb +0 -58
- data/lib/yt/models/url.rb +0 -91
- data/spec/models/configuration_spec.rb +0 -44
- data/spec/models/description_spec.rb +0 -94
- data/spec/models/url_spec.rb +0 -84
- data/spec/requests/as_account/resource_spec.rb +0 -18
data/YOUTUBE_IT.md
CHANGED
@@ -141,7 +141,7 @@ client = YouTubeIt::Client.new
|
|
141
141
|
client.videos_by(:query => "penguin", :author => "liz")
|
142
142
|
# with yt: the 'author' filter was removed from YouTube API V3, so the
|
143
143
|
# request must be done using the channel of the requested author
|
144
|
-
channel = Yt::Channel.new
|
144
|
+
channel = Yt::Channel.new id: 'UCxxxxxxxxx'
|
145
145
|
channel.videos.where(q: 'penguin')
|
146
146
|
```
|
147
147
|
|
@@ -176,7 +176,7 @@ client = YouTubeIt::Client.new
|
|
176
176
|
client.videos_by(:user => 'liz')
|
177
177
|
# with yt: the 'author' filter was removed from YouTube API V3, so the
|
178
178
|
# request must be done using the channel of the requested author
|
179
|
-
channel = Yt::Channel.new
|
179
|
+
channel = Yt::Channel.new id: 'UCxxxxxxxxx'
|
180
180
|
channel.videos.where(q: 'penguin')
|
181
181
|
```
|
182
182
|
|
@@ -188,7 +188,7 @@ client = YouTubeIt::Client.new
|
|
188
188
|
client.videos_by(:favorites, :user => 'liz')
|
189
189
|
# with yt: note that only *old* channels have a "Favorites" playlist, since
|
190
190
|
# "Favorites" has been deprecated by YouTube in favor of "Liked Videos".
|
191
|
-
channel = Yt::Channel.new
|
191
|
+
channel = Yt::Channel.new id: 'UCxxxxxxxxx'
|
192
192
|
channel.related_playlists.find{|p| p.title == 'Favorites'}
|
193
193
|
```
|
194
194
|
|
data/lib/yt.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'yt/config'
|
2
2
|
require 'yt/version'
|
3
|
+
require 'yt/constants/geography'
|
3
4
|
require 'yt/models/account'
|
4
5
|
require 'yt/models/channel'
|
5
6
|
require 'yt/models/claim'
|
@@ -9,13 +10,15 @@ require 'yt/models/match_policy'
|
|
9
10
|
require 'yt/models/playlist'
|
10
11
|
require 'yt/models/playlist_item'
|
11
12
|
require 'yt/models/video'
|
13
|
+
require 'yt/models/video_group'
|
14
|
+
require 'yt/models/comment_thread'
|
12
15
|
require 'yt/models/ownership'
|
13
16
|
require 'yt/models/advertising_options_set'
|
14
17
|
|
15
18
|
# An object-oriented Ruby client for YouTube.
|
16
19
|
# Helps creating applications that need to interact with YouTube objects.
|
17
20
|
# Inclused methods to access YouTube Data API V3 resources (channels, videos,
|
18
|
-
# ...), YouTube Analytics API V2 resources (metrics,
|
21
|
+
# ...), YouTube Analytics API V2 resources (metrics, estimated_revenue, ...), and
|
19
22
|
# objects not available through the API (annotations).
|
20
23
|
module Yt
|
21
|
-
end
|
24
|
+
end
|
data/lib/yt/actions/list.rb
CHANGED
@@ -6,7 +6,7 @@ require 'yt/config'
|
|
6
6
|
module Yt
|
7
7
|
module Actions
|
8
8
|
module List
|
9
|
-
delegate :any?, :count, :each, :each_cons, :each_slice, :find, :first,
|
9
|
+
delegate :any?, :count, :each, :each_cons, :each_slice, :find, :first, :take,
|
10
10
|
:flat_map, :map, :select, :size, to: :list
|
11
11
|
|
12
12
|
def first!
|
@@ -47,7 +47,7 @@ module Yt
|
|
47
47
|
def find_next
|
48
48
|
@items ||= []
|
49
49
|
if @items[@last_index].nil? && more_pages?
|
50
|
-
more_items = next_page.map{|data| new_item data}
|
50
|
+
more_items = next_page.map{|data| new_item data}.compact
|
51
51
|
@items.concat more_items
|
52
52
|
end
|
53
53
|
@items[(@last_index +=1) -1]
|
@@ -136,4 +136,4 @@ module Yt
|
|
136
136
|
end
|
137
137
|
end
|
138
138
|
end
|
139
|
-
end
|
139
|
+
end
|
@@ -9,6 +9,7 @@ module Yt
|
|
9
9
|
def has_authentication
|
10
10
|
require 'yt/collections/authentications'
|
11
11
|
require 'yt/collections/device_flows'
|
12
|
+
require 'yt/collections/revocations'
|
12
13
|
require 'yt/errors/missing_auth'
|
13
14
|
require 'yt/errors/no_items'
|
14
15
|
require 'yt/errors/unauthorized'
|
@@ -57,7 +58,31 @@ module Yt
|
|
57
58
|
def refreshed_access_token?
|
58
59
|
old_access_token = authentication.access_token
|
59
60
|
@authentication = @access_token = @refreshed_authentications = nil
|
60
|
-
|
61
|
+
|
62
|
+
if old_access_token != authentication.access_token
|
63
|
+
access_token_was_refreshed
|
64
|
+
true
|
65
|
+
else
|
66
|
+
false
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Revoke access given to the application.
|
71
|
+
# Returns true if the access was correctly revoked.
|
72
|
+
# @see https://developers.google.com/identity/protocols/OAuth2WebServer#tokenrevoke
|
73
|
+
def revoke_access
|
74
|
+
revocations.first!
|
75
|
+
@authentication = @access_token = @refreshed_authentications = nil
|
76
|
+
true
|
77
|
+
rescue Errors::RequestError => e
|
78
|
+
raise unless e.reasons.include? 'invalid_token'
|
79
|
+
false
|
80
|
+
end
|
81
|
+
|
82
|
+
# Invoked when the access token is refreshed.
|
83
|
+
def access_token_was_refreshed
|
84
|
+
# Apps using Yt can override this method to handle this event, for
|
85
|
+
# instance to store the newly generated access token in the database.
|
61
86
|
end
|
62
87
|
|
63
88
|
private
|
@@ -103,6 +128,7 @@ module Yt
|
|
103
128
|
error_message = case
|
104
129
|
when @redirect_uri && @scopes then missing_authorization_code_message
|
105
130
|
when @scopes then pending_device_code_message
|
131
|
+
else {}
|
106
132
|
end
|
107
133
|
raise Errors::MissingAuth, error_message
|
108
134
|
end
|
@@ -149,6 +175,12 @@ module Yt
|
|
149
175
|
end
|
150
176
|
end
|
151
177
|
|
178
|
+
def revocations
|
179
|
+
@revocations ||= Collections::Revocations.of(self).tap do |auth|
|
180
|
+
auth.auth_params = {token: @refresh_token || @access_token}
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
152
184
|
def authentication_url_params
|
153
185
|
{}.tap do |params|
|
154
186
|
params[:client_id] = client_id
|
@@ -206,18 +206,17 @@ module Yt
|
|
206
206
|
# @macro report
|
207
207
|
# @macro report_with_country_and_state
|
208
208
|
|
209
|
-
# Defines
|
209
|
+
# Defines a public instance methods to access the reports of a
|
210
210
|
# resource for a specific metric.
|
211
211
|
# @param [Symbol] metric the metric to access the reports of.
|
212
212
|
# @param [Class] type The class to cast the returned values to.
|
213
|
-
# @example Adds +comments+
|
213
|
+
# @example Adds +comments+ on a Channel resource.
|
214
214
|
# class Channel < Resource
|
215
215
|
# has_report :comments, Integer
|
216
216
|
# end
|
217
217
|
def has_report(metric, type)
|
218
218
|
require 'yt/collections/reports'
|
219
219
|
|
220
|
-
define_metric_on_method metric
|
221
220
|
define_metric_method metric
|
222
221
|
define_reports_method metric, type
|
223
222
|
define_range_metric_method metric
|
@@ -226,12 +225,6 @@ module Yt
|
|
226
225
|
|
227
226
|
private
|
228
227
|
|
229
|
-
def define_metric_on_method(metric)
|
230
|
-
define_method "#{metric}_on" do |date|
|
231
|
-
send(metric, from: date, to: date, by: :day).values.first
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
228
|
def define_reports_method(metric, type)
|
236
229
|
(@metrics ||= {})[metric] = type
|
237
230
|
define_method :reports do |options = {}|
|
@@ -242,6 +235,7 @@ module Yt
|
|
242
235
|
state = location[:state] if location.is_a?(Hash)
|
243
236
|
dimension = options[:by] || (metric == :viewer_percentage ? :gender_age_group : :range)
|
244
237
|
videos = options[:videos]
|
238
|
+
historical = options[:historical].to_s if [true, false].include?(options[:historical])
|
245
239
|
if dimension == :month
|
246
240
|
from = from.to_date.beginning_of_month
|
247
241
|
to = to.to_date.beginning_of_month
|
@@ -250,9 +244,9 @@ module Yt
|
|
250
244
|
|
251
245
|
only = options.fetch :only, []
|
252
246
|
reports = Collections::Reports.of(self).tap do |reports|
|
253
|
-
reports.metrics =
|
247
|
+
reports.metrics = self.class.instance_variable_get(:@metrics).select{|k, v| k.in? only}
|
254
248
|
end
|
255
|
-
reports.within date_range, country, state, dimension, videos
|
249
|
+
reports.within date_range, country, state, dimension, videos, historical
|
256
250
|
end unless defined?(reports)
|
257
251
|
end
|
258
252
|
|
@@ -265,6 +259,7 @@ module Yt
|
|
265
259
|
state = location[:state] if location.is_a?(Hash)
|
266
260
|
dimension = options[:by] || (metric == :viewer_percentage ? :gender_age_group : :range)
|
267
261
|
videos = options[:videos]
|
262
|
+
historical = options[:historical].to_s if [true, false].include?(options[:historical])
|
268
263
|
if dimension == :month
|
269
264
|
from = from.to_date.beginning_of_month
|
270
265
|
to = to.to_date.beginning_of_month
|
@@ -276,10 +271,10 @@ module Yt
|
|
276
271
|
results = case dimension
|
277
272
|
when :day
|
278
273
|
Hash[*range.flat_map do |date|
|
279
|
-
[date, instance_variable_get("@#{metric}_#{dimension}_#{country}_#{state}")[date] ||= send("range_#{metric}", range, dimension, country, state, videos)[date]]
|
274
|
+
[date, instance_variable_get("@#{metric}_#{dimension}_#{country}_#{state}")[date] ||= send("range_#{metric}", range, dimension, country, state, videos, historical)[date]]
|
280
275
|
end]
|
281
276
|
else
|
282
|
-
instance_variable_get("@#{metric}_#{dimension}_#{country}_#{state}")[range] ||= send("range_#{metric}", range, dimension, country, state, videos)
|
277
|
+
instance_variable_get("@#{metric}_#{dimension}_#{country}_#{state}")[range] ||= send("range_#{metric}", range, dimension, country, state, videos, historical)
|
283
278
|
end
|
284
279
|
lookup_class = case options[:by]
|
285
280
|
when :video, :related_video then Yt::Collections::Videos
|
@@ -296,25 +291,25 @@ module Yt
|
|
296
291
|
end
|
297
292
|
|
298
293
|
def define_range_metric_method(metric)
|
299
|
-
define_method "range_#{metric}" do |date_range, dimension, country, state, videos|
|
294
|
+
define_method "range_#{metric}" do |date_range, dimension, country, state, videos, historical|
|
300
295
|
ivar = instance_variable_get "@range_#{metric}_#{dimension}_#{country}_#{state}"
|
301
296
|
instance_variable_set "@range_#{metric}_#{dimension}_#{country}_#{state}", ivar || {}
|
302
|
-
instance_variable_get("@range_#{metric}_#{dimension}_#{country}_#{state}")[date_range] ||= send("all_#{metric}").within date_range, country, state, dimension, videos
|
297
|
+
instance_variable_get("@range_#{metric}_#{dimension}_#{country}_#{state}")[date_range] ||= send("all_#{metric}").within date_range, country, state, dimension, videos, historical
|
303
298
|
end
|
304
299
|
private "range_#{metric}"
|
305
300
|
end
|
306
301
|
|
307
302
|
def define_all_metric_method(metric, type)
|
308
303
|
define_method "all_#{metric}" do
|
309
|
-
# @note Asking for the "
|
304
|
+
# @note Asking for the "estimated_revenue" metric of a day in which a channel
|
310
305
|
# made 0 USD returns the wrong "nil". But adding to the request the
|
311
306
|
# "estimatedMinutesWatched" metric returns the correct value 0.
|
312
307
|
metrics = {metric => type}
|
313
|
-
metrics[:estimated_minutes_watched] = Integer if metric == :
|
308
|
+
metrics[:estimated_minutes_watched] = Integer if metric == :estimated_revenue
|
314
309
|
Collections::Reports.of(self).tap{|reports| reports.metrics = metrics}
|
315
310
|
end
|
316
311
|
private "all_#{metric}"
|
317
312
|
end
|
318
313
|
end
|
319
314
|
end
|
320
|
-
end
|
315
|
+
end
|
@@ -39,7 +39,7 @@ module Yt
|
|
39
39
|
# is accessed; it should be replaced with a filter on params instead.
|
40
40
|
def assets_path
|
41
41
|
@where_params ||= {}
|
42
|
-
if @where_params.
|
42
|
+
if @where_params.key?(:id)
|
43
43
|
'/youtube/partner/v1/assets'
|
44
44
|
else
|
45
45
|
'/youtube/partner/v1/assetSearch'
|
@@ -55,4 +55,4 @@ module Yt
|
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
58
|
-
end
|
58
|
+
end
|
@@ -40,8 +40,15 @@ module Yt
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def expected?(error)
|
43
|
-
error.kind == 'invalid_grant'
|
43
|
+
error.kind == 'invalid_grant' &&
|
44
|
+
invalid_code_errors.exclude?(error.description)
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def invalid_code_errors
|
50
|
+
["Code was already redeemed.", "Invalid code."]
|
44
51
|
end
|
45
52
|
end
|
46
53
|
end
|
47
|
-
end
|
54
|
+
end
|
data/lib/yt/collections/base.rb
CHANGED
@@ -31,9 +31,9 @@ module Yt
|
|
31
31
|
# are at https://developers.google.com/youtube/v3/docs/search/list
|
32
32
|
#
|
33
33
|
# @example Return the first video of a channel (no requirements):
|
34
|
-
#
|
34
|
+
# channel.videos.first
|
35
35
|
# @example Return the first long video of a channel by video count:
|
36
|
-
#
|
36
|
+
# channel.videos.where(order: 'viewCount', video_duration: 'long').first
|
37
37
|
def where(requirements = {})
|
38
38
|
self.tap do
|
39
39
|
@items = []
|
@@ -59,4 +59,4 @@ module Yt
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
end
|
62
|
-
end
|
62
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'yt/collections/base'
|
2
|
+
require 'yt/models/bulk_report_job'
|
3
|
+
|
4
|
+
module Yt
|
5
|
+
module Collections
|
6
|
+
# @private
|
7
|
+
class BulkReportJobs < Base
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def attributes_for_new_item(data)
|
12
|
+
{id: data['id'], auth: @auth, report_type_id: data['reportTypeId']}
|
13
|
+
end
|
14
|
+
|
15
|
+
def list_params
|
16
|
+
super.tap do |params|
|
17
|
+
params[:host] = 'youtubereporting.googleapis.com'
|
18
|
+
params[:path] = "/v1/jobs"
|
19
|
+
params[:params] = {on_behalf_of_content_owner: @parent.owner_name}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def items_key
|
24
|
+
'jobs'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'yt/collections/base'
|
2
|
+
require 'yt/models/bulk_report'
|
3
|
+
|
4
|
+
module Yt
|
5
|
+
module Collections
|
6
|
+
# @private
|
7
|
+
class BulkReports < Base
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def list_params
|
12
|
+
super.tap do |params|
|
13
|
+
params[:host] = 'youtubereporting.googleapis.com'
|
14
|
+
params[:path] = "/v1/jobs/#{@parent.id}/reports"
|
15
|
+
params[:params] = {on_behalf_of_content_owner: @parent.auth.owner_name}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def items_key
|
20
|
+
'reports'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -17,6 +17,27 @@ module Yt
|
|
17
17
|
|
18
18
|
private
|
19
19
|
|
20
|
+
def attributes_for_new_item(data)
|
21
|
+
{}.tap do |attributes|
|
22
|
+
attributes[:id] = data['id']
|
23
|
+
attributes[:auth] = @auth
|
24
|
+
attributes[:data] = data
|
25
|
+
attributes[:asset] = data['asset']
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def eager_load_items_from(items)
|
30
|
+
if included_relationships.include? :asset
|
31
|
+
asset_ids = items.map{|a| a.values_at 'videoId', 'assetId'}.to_h.values
|
32
|
+
conditions = { id: asset_ids.join(','), fetch_metadata: 'effective' }
|
33
|
+
assets = @parent.assets.where conditions
|
34
|
+
items.each do |item|
|
35
|
+
item['asset'] = assets.find { |a| a.id == item['assetId'] }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
super
|
39
|
+
end
|
40
|
+
|
20
41
|
# @return [Hash] the parameters to submit to YouTube to list claims
|
21
42
|
# administered by the content owner.
|
22
43
|
# @see https://developers.google.com/youtube/partner/docs/v1/claims/list
|
@@ -53,4 +74,4 @@ module Yt
|
|
53
74
|
end
|
54
75
|
end
|
55
76
|
end
|
56
|
-
end
|
77
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'yt/collections/base'
|
2
|
+
require 'yt/models/video'
|
3
|
+
require 'yt/models/channel'
|
4
|
+
|
5
|
+
module Yt
|
6
|
+
module Collections
|
7
|
+
# @private
|
8
|
+
class CommentThreads < Base
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def attributes_for_new_item(data)
|
13
|
+
{}.tap do |attributes|
|
14
|
+
attributes[:id] = data['id']
|
15
|
+
attributes[:snippet] = data['snippet']
|
16
|
+
attributes[:auth] = @auth
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [Hash] the parameters to submit to YouTube to get the resource.
|
21
|
+
# @see https://developers.google.com/youtube/v3/docs/commentThreads#resource
|
22
|
+
def list_params
|
23
|
+
super.tap do |params|
|
24
|
+
params[:path] = "/youtube/v3/commentThreads"
|
25
|
+
params[:params] = comments_params
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def comments_params
|
30
|
+
apply_where_params!({max_results: 100, part: 'snippet'}).tap do |params|
|
31
|
+
case @parent
|
32
|
+
when Yt::Video
|
33
|
+
params[:videoId] = @parent.id
|
34
|
+
when Yt::Channel
|
35
|
+
params[:channelId] = @parent.id
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -11,7 +11,7 @@ module Yt
|
|
11
11
|
private
|
12
12
|
|
13
13
|
def attributes_for_new_item(data)
|
14
|
-
{owner_name: data['id'], authentication: @auth.authentication}
|
14
|
+
{owner_name: data['id'], display_name: data['displayName'], authentication: @auth.authentication}
|
15
15
|
end
|
16
16
|
|
17
17
|
# @return [Hash] the parameters to submit to YouTube to list content
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'yt/collections/base'
|
2
|
+
require 'yt/models/snippet'
|
3
|
+
|
4
|
+
module Yt
|
5
|
+
module Collections
|
6
|
+
# @private
|
7
|
+
class GroupInfos < Base
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def attributes_for_new_item(data)
|
12
|
+
{data: data, auth: @auth}
|
13
|
+
end
|
14
|
+
|
15
|
+
def list_params
|
16
|
+
super.tap do |params|
|
17
|
+
params[:host] = 'youtubeanalytics.googleapis.com'
|
18
|
+
params[:path] = "/v2/groups"
|
19
|
+
params[:params] = {id: @parent.id}
|
20
|
+
if @auth.owner_name
|
21
|
+
params[:params][:on_behalf_of_content_owner] = @auth.owner_name
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|