yt 0.14.0 → 0.14.1
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/CHANGELOG.md +9 -0
- data/Gemfile +0 -2
- data/README.md +38 -1
- data/lib/yt/collections/reports.rb +4 -1
- data/lib/yt/models/channel.rb +3 -0
- data/lib/yt/models/playlist.rb +27 -0
- data/lib/yt/models/video.rb +9 -0
- data/lib/yt/version.rb +1 -1
- data/spec/requests/as_account/channel_spec.rb +1 -0
- data/spec/requests/as_account/playlist_spec.rb +16 -0
- data/spec/requests/as_account/video_spec.rb +6 -0
- data/spec/requests/as_content_owner/channel_spec.rb +66 -0
- data/spec/requests/as_content_owner/playlist_spec.rb +213 -0
- data/spec/requests/as_content_owner/video_spec.rb +152 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: db4db84624546717fdc851f9686077c0926798ac
|
4
|
+
data.tar.gz: 69322165d6a6a13484613c7d1f3e3fda0c3c79d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fe0e64e30469c9539c4e5441e6d691bf91f6bf3f66e5d1cfbf6aa4a790a79e21aeeea6a4c2e02eb4d147817467e052409789054bd369268cba906759563fd655
|
7
|
+
data.tar.gz: c4e6b9bbab1327dcc20acbdd65260d83b6ec06723a21a098efcb0bbb6fc5ef9555a6897d1a86dd48b120e86ee58857b051c383089f1503a49c48bce8659098be
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,15 @@ For more information about changelogs, check
|
|
6
6
|
[Keep a Changelog](http://keepachangelog.com) and
|
7
7
|
[Vandamme](http://tech-angels.github.io/vandamme).
|
8
8
|
|
9
|
+
## 0.14.1 - 2015-03-30
|
10
|
+
|
11
|
+
* [FEATURE] New `monetized playbacks` report for channels.
|
12
|
+
* [FEATURE] New `estimated watched minutes` report for videos.
|
13
|
+
* [FEATURE] New video reports: `average_view_duration`, `average_view_percentage`.
|
14
|
+
* [FEATURE] New `by: :playlist` option for reports, to return views and estimated watched minutes (channels) by playlist.
|
15
|
+
* [FEATURE] New playlist reports: `views`, `playlist_starts`, `average_time_in_playlist`, `views_per_playlist_start`.
|
16
|
+
|
17
|
+
|
9
18
|
## 0.14.0 - 2015-03-25
|
10
19
|
|
11
20
|
* [FEATURE] New `by: :traffic_source` option for reports, to return views (channels/videos) and estimated watched minutes (channels) by traffic source.
|
data/Gemfile
CHANGED
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.
|
44
|
+
gem 'yt', '~> 0.14.1'
|
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*)
|
@@ -150,6 +150,8 @@ Use [Yt::Channel](http://rubydoc.info/github/Fullscreen/yt/master/Yt/Models/Chan
|
|
150
150
|
* delete playlists from a channel
|
151
151
|
* retrieve the daily earnings, views, comments, likes, dislikes, shares, subscribers gained/lost, estimated/average video watch and impressions of a channel by day
|
152
152
|
* retrieve the views and estimated minutes watched by traffic source
|
153
|
+
* retrieve the views and estimated minutes watched by video
|
154
|
+
* retrieve the views and estimated minutes watched by playlist
|
153
155
|
* retrieve the viewer percentage of a channel by gender and age group
|
154
156
|
|
155
157
|
```ruby
|
@@ -214,6 +216,12 @@ channel.viewer_percentage(gender: :male) #=> 49.12
|
|
214
216
|
|
215
217
|
channel.views since: 7.days.ago, by: :traffic_source #=> {advertising: 10.0, related_video: 20.0, promoted: 5.0, subscriber: 1.0, channel: 3.0, other: 7.0}
|
216
218
|
channel.estimated_minutes_watched since: 7.days.ago, by: :traffic_source #=> {annotation: 10.0, external_app: 20.0, external_url: 5.0, embedded: 1.0, search: 3.0}
|
219
|
+
|
220
|
+
channel.views since: 7.days.ago, by: :video #=> {#<Yt::Models::Video @id=...>: 10.0, #<Yt::Models::Video @id=...>: 20.0, …}
|
221
|
+
channel.estimated_minutes_watched since: 7.days.ago, by: :video #=> {#<Yt::Models::Video @id=...>: 10.0, #<Yt::Models::Video @id=...>: 20.0, …}
|
222
|
+
|
223
|
+
channel.views since: 7.days.ago, by: :playlist #=> {#<Yt::Models::Playlist @id=...>: 10.0, #<Yt::Models::Playlist @id=...>: 20.0, …}
|
224
|
+
channel.estimated_minutes_watched since: 7.days.ago, by: :playlist #=> {#<Yt::Models::Playlist @id=...>: 10.0, #<Yt::Models::Playlist @id=...>: 20.0, …}
|
217
225
|
```
|
218
226
|
|
219
227
|
*The methods above require to be authenticated as the channel’s account (see below).*
|
@@ -238,6 +246,11 @@ channel.viewer_percentages #=> {female: {'18-24' => 12.12, '25-34' => 16.16,…}
|
|
238
246
|
channel.viewer_percentage(gender: :female) #=> 49.12
|
239
247
|
channel.views since: 7.days.ago, by: :traffic_source #=> {advertising: 10.0, related_video: 20.0, promoted: 5.0, subscriber: 1.0, channel: 3.0, other: 7.0}
|
240
248
|
channel.estimated_minutes_watched since: 7.days.ago, by: :traffic_source #=> {annotation: 10.0, external_app: 20.0, external_url: 5.0, embedded: 1.0, search: 3.0}
|
249
|
+
channel.views since: 7.days.ago, by: :video #=> {#<Yt::Models::Video @id=...>: 10.0, #<Yt::Models::Video @id=...>: 20.0, …}
|
250
|
+
channel.estimated_minutes_watched since: 7.days.ago, by: :video #=> {#<Yt::Models::Video @id=...>: 10.0, #<Yt::Models::Video @id=...>: 20.0, …}
|
251
|
+
channel.views since: 7.days.ago, by: :playlist #=> {#<Yt::Models::Playlist @id=...>: 10.0, #<Yt::Models::Playlist @id=...>: 20.0, …}
|
252
|
+
channel.estimated_minutes_watched since: 7.days.ago, by: :playlist #=> {#<Yt::Models::Playlist @id=...>: 10.0, #<Yt::Models::Playlist @id=...>: 20.0, …}
|
253
|
+
channel.monetized_playbacks_on 5.days.ago #=> 123.0
|
241
254
|
|
242
255
|
channel.content_owner #=> 'CMSname'
|
243
256
|
channel.linked_at #=> Wed, 28 May 2014
|
@@ -350,6 +363,11 @@ video.dislikes to: 2.days.ago #=> {Tue, 27 May 2014 => 0.0, Wed, 28 May 2014 =>
|
|
350
363
|
video.shares since: 7.days.ago, until: 7.days.ago #=> {Wed, 28 May 2014 => 3.0}
|
351
364
|
video.subscribers_gained from: '2014-08-30', to: '2014-08-31' #=> {Sat, 30 Aug 2014=>1.0, Sun, 31 Aug 2014=>0.0}
|
352
365
|
video.subscribers_lost from: '2014-08-30', to: '2014-08-31' #=> {Sat, 30 Aug 2014=>0.0, Sun, 31 Aug 2014=>0.0}
|
366
|
+
video.favorites_added from: '2014-08-30', to: '2014-08-31' #=> {Sat, 30 Aug 2014=>1.0, Sun, 31 Aug 2014=>0.0}
|
367
|
+
video.favorites_removed from: '2014-08-30', to: '2014-08-31' #=> {Sat, 30 Aug 2014=>0.0, Sun, 31 Aug 2014=>0.0}
|
368
|
+
video.average_view_duration #=> {Sun, 22 Feb 2015=>329.0, Mon, 23 Feb 2015=>326.0, …}
|
369
|
+
video.average_view_percentage # {Sun, 22 Feb 2015=>38.858253094977265, Mon, 23 Feb 2015=>37.40014235438217, …}
|
370
|
+
video.estimated_minutes_watched #=> {Sun, 22 Feb 2015=>2433258.0, Mon, 23 Feb 2015=>2634360.0, …}
|
353
371
|
video.viewer_percentages #=> {female: {'18-24' => 12.12, '25-34' => 16.16,…}…}
|
354
372
|
video.viewer_percentage(gender: :female) #=> 49.12
|
355
373
|
|
@@ -372,6 +390,11 @@ video.dislikes to: 2.days.ago #=> {Tue, 27 May 2014 => 0.0, Wed, 28 May 2014 =>
|
|
372
390
|
video.shares since: 7.days.ago, until: 7.days.ago #=> {Wed, 28 May 2014 => 3.0}
|
373
391
|
video.subscribers_gained from: '2014-08-30', to: '2014-08-31' #=> {Sat, 30 Aug 2014=>1.0, Sun, 31 Aug 2014=>0.0}
|
374
392
|
video.subscribers_lost from: '2014-08-30', to: '2014-08-31' #=> {Sat, 30 Aug 2014=>0.0, Sun, 31 Aug 2014=>0.0}
|
393
|
+
video.favorites_added from: '2014-08-30', to: '2014-08-31' #=> {Sat, 30 Aug 2014=>1.0, Sun, 31 Aug 2014=>0.0}
|
394
|
+
video.favorites_removed from: '2014-08-30', to: '2014-08-31' #=> {Sat, 30 Aug 2014=>0.0, Sun, 31 Aug 2014=>0.0}
|
395
|
+
video.average_view_duration #=> {Sun, 22 Feb 2015=>329.0, Mon, 23 Feb 2015=>326.0, …}
|
396
|
+
video.average_view_percentage # {Sun, 22 Feb 2015=>38.858253094977265, Mon, 23 Feb 2015=>37.40014235438217, …}
|
397
|
+
video.estimated_minutes_watched #=> {Sun, 22 Feb 2015=>2433258.0, Mon, 23 Feb 2015=>2634360.0, …}
|
375
398
|
video.impressions_on 5.days.ago #=> 157.0
|
376
399
|
video.monetized_playbacks_on 5.days.ago #=> 123.0
|
377
400
|
|
@@ -395,6 +418,7 @@ Use [Yt::Playlist](http://rubydoc.info/github/Fullscreen/yt/master/Yt/Models/Pla
|
|
395
418
|
* access the items of a playlist
|
396
419
|
* add one or multiple videos to a playlist
|
397
420
|
* delete items from a playlist
|
421
|
+
* retrieve the views, playlist starts, average time in playlist and views per playlist start of a playlist by day
|
398
422
|
|
399
423
|
```ruby
|
400
424
|
# Playlists can be initialized with ID or URL
|
@@ -421,6 +445,19 @@ playlist.update title: 'A <title> with angle brackets', description: 'desc', tag
|
|
421
445
|
playlist.add_video 'MESycYJytkU', position: 2
|
422
446
|
playlist.add_videos ['MESycYJytkU', 'MESycYJytkU']
|
423
447
|
playlist.delete_playlist_items title: 'Fullscreen Creator Platform' #=> [true]
|
448
|
+
|
449
|
+
playlist.views_on 5.days.ago #=> 12.0
|
450
|
+
playlist.views since: 7.days.ago #=> {Wed, 28 May 2014 => 12.0, Thu, 29 May 2014 => 3.0, …}
|
451
|
+
|
452
|
+
playlist.playlist_starts_on 5.days.ago #=> 12.0
|
453
|
+
playlist.playlist_starts since: 7.days.ago #=> {Wed, 28 May 2014 => 12.0, Thu, 29 May 2014 => 3.0, …}
|
454
|
+
|
455
|
+
playlist.average_time_in_playlist_on 5.days.ago #=> 12.0
|
456
|
+
playlist.average_time_in_playlist since: 7.days.ago #=> {Wed, 28 May 2014 => 12.0, Thu, 29 May 2014 => 3.0, …}
|
457
|
+
|
458
|
+
playlist.views_per_playlist_start_on 5.days.ago #=> 12.0
|
459
|
+
playlist.views_per_playlist_start since: 7.days.ago #=> {Wed, 28 May 2014 => 12.0, Thu, 29 May 2014 => 3.0, …}
|
460
|
+
|
424
461
|
```
|
425
462
|
|
426
463
|
*The methods above require to be authenticated as the playlist’s owner (see below).*
|
@@ -6,6 +6,7 @@ module Yt
|
|
6
6
|
DIMENSIONS = Hash.new({name: 'day', parse: -> (day) {Date.iso8601 day} }).tap do |hash|
|
7
7
|
hash[:traffic_source] = {name: 'insightTrafficSourceType', parse: -> (type) {TRAFFIC_SOURCES.key type} }
|
8
8
|
hash[:video] = {name: 'video', parse: -> (video_id) { Yt::Video.new id: video_id, auth: @auth } }
|
9
|
+
hash[:playlist] = {name: 'playlist', parse: -> (playlist_id) { Yt::Playlist.new id: playlist_id, auth: @auth } }
|
9
10
|
end
|
10
11
|
|
11
12
|
# @see https://developers.google.com/youtube/analytics/v1/dimsmets/dims#Traffic_Source_Dimensions
|
@@ -64,7 +65,9 @@ module Yt
|
|
64
65
|
params['metrics'] = @metric.to_s.camelize(:lower)
|
65
66
|
params['dimensions'] = DIMENSIONS[@dimension][:name]
|
66
67
|
params['max-results'] = 10 if @dimension == :video
|
67
|
-
params['
|
68
|
+
params['max-results'] = 200 if @dimension == :playlist
|
69
|
+
params['sort'] = "-#{@metric.to_s.camelize(:lower)}" if @dimension.in? [:video, :playlist]
|
70
|
+
params[:filters] = ((params[:filters] || '').split(';') + ['isCurated==1']).compact.uniq.join(';') if @dimension == :playlist
|
68
71
|
end
|
69
72
|
end
|
70
73
|
|
data/lib/yt/models/channel.rb
CHANGED
data/lib/yt/models/playlist.rb
CHANGED
@@ -11,6 +11,18 @@ module Yt
|
|
11
11
|
# @return [Yt::Collections::PlaylistItems] the playlist’s items.
|
12
12
|
has_many :playlist_items
|
13
13
|
|
14
|
+
# @macro has_report
|
15
|
+
has_report :views
|
16
|
+
|
17
|
+
# @macro has_report
|
18
|
+
has_report :playlist_starts
|
19
|
+
|
20
|
+
# @macro has_report
|
21
|
+
has_report :average_time_in_playlist
|
22
|
+
|
23
|
+
# @macro has_report
|
24
|
+
has_report :views_per_playlist_start
|
25
|
+
|
14
26
|
# Deletes the playlist.
|
15
27
|
#
|
16
28
|
# This method requires {Resource#auth auth} to return an authenticated
|
@@ -57,6 +69,21 @@ module Yt
|
|
57
69
|
playlist_items.delete_all attrs
|
58
70
|
end
|
59
71
|
|
72
|
+
# @private
|
73
|
+
# Tells `has_reports` to retrieve the reports from YouTube Analytics API
|
74
|
+
# either as a Channel or as a Content Owner.
|
75
|
+
# @see https://developers.google.com/youtube/analytics/v1/reports
|
76
|
+
def reports_params
|
77
|
+
{}.tap do |params|
|
78
|
+
if auth.owner_name
|
79
|
+
params[:ids] = "contentOwner==#{auth.owner_name}"
|
80
|
+
else
|
81
|
+
params[:ids] = "channel==#{channel_id}"
|
82
|
+
end
|
83
|
+
params[:filters] = "playlist==#{id};isCurated==1"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
60
87
|
private
|
61
88
|
|
62
89
|
# @see https://developers.google.com/youtube/v3/docs/playlists/update
|
data/lib/yt/models/video.rb
CHANGED
@@ -74,6 +74,15 @@ module Yt
|
|
74
74
|
# @macro has_report
|
75
75
|
has_report :favorites_removed
|
76
76
|
|
77
|
+
# @macro has_report
|
78
|
+
has_report :estimated_minutes_watched
|
79
|
+
|
80
|
+
# @macro has_report
|
81
|
+
has_report :average_view_duration
|
82
|
+
|
83
|
+
# @macro has_report
|
84
|
+
has_report :average_view_percentage
|
85
|
+
|
77
86
|
# @macro has_report
|
78
87
|
has_report :impressions
|
79
88
|
|
data/lib/yt/version.rb
CHANGED
@@ -139,6 +139,7 @@ describe Yt::Channel, :device_app do
|
|
139
139
|
expect{channel.average_view_percentage}.not_to raise_error
|
140
140
|
expect{channel.earnings}.to raise_error Yt::Errors::Unauthorized
|
141
141
|
expect{channel.impressions}.to raise_error Yt::Errors::Unauthorized
|
142
|
+
expect{channel.monetized_playbacks}.to raise_error Yt::Errors::Unauthorized
|
142
143
|
|
143
144
|
expect{channel.views_on 3.days.ago}.not_to raise_error
|
144
145
|
expect{channel.comments_on 3.days.ago}.not_to raise_error
|
@@ -175,4 +175,20 @@ describe Yt::Playlist, :device_app do
|
|
175
175
|
end
|
176
176
|
end
|
177
177
|
end
|
178
|
+
|
179
|
+
context 'given one of my own playlists that I want to get reports for' do
|
180
|
+
let(:id) { $account.channel.playlists.first.id }
|
181
|
+
|
182
|
+
it 'returns valid reports for playlist-related metrics' do
|
183
|
+
expect{playlist.views}.not_to raise_error
|
184
|
+
expect{playlist.playlist_starts}.not_to raise_error
|
185
|
+
expect{playlist.average_time_in_playlist}.not_to raise_error
|
186
|
+
expect{playlist.views_per_playlist_start}.not_to raise_error
|
187
|
+
|
188
|
+
expect{playlist.views_on 3.days.ago}.not_to raise_error
|
189
|
+
expect{playlist.playlist_starts_on 3.days.ago}.not_to raise_error
|
190
|
+
expect{playlist.average_time_in_playlist_on 3.days.ago}.not_to raise_error
|
191
|
+
expect{playlist.views_per_playlist_start_on 3.days.ago}.not_to raise_error
|
192
|
+
end
|
193
|
+
end
|
178
194
|
end
|
@@ -289,6 +289,9 @@ describe Yt::Video, :device_app do
|
|
289
289
|
expect{video.subscribers_lost}.not_to raise_error
|
290
290
|
expect{video.favorites_added}.not_to raise_error
|
291
291
|
expect{video.favorites_removed}.not_to raise_error
|
292
|
+
expect{video.estimated_minutes_watched}.not_to raise_error
|
293
|
+
expect{video.average_view_duration}.not_to raise_error
|
294
|
+
expect{video.average_view_percentage}.not_to raise_error
|
292
295
|
expect{video.earnings}.to raise_error Yt::Errors::Unauthorized
|
293
296
|
expect{video.impressions}.to raise_error Yt::Errors::Unauthorized
|
294
297
|
expect{video.monetized_playbacks}.to raise_error Yt::Errors::Unauthorized
|
@@ -303,6 +306,9 @@ describe Yt::Video, :device_app do
|
|
303
306
|
expect{video.subscribers_lost_on 3.days.ago}.not_to raise_error
|
304
307
|
expect{video.favorites_added_on 3.days.ago}.not_to raise_error
|
305
308
|
expect{video.favorites_removed_on 3.days.ago}.not_to raise_error
|
309
|
+
expect{video.estimated_minutes_watched_on 3.days.ago}.not_to raise_error
|
310
|
+
expect{video.average_view_duration_on 3.days.ago}.not_to raise_error
|
311
|
+
expect{video.average_view_percentage_on 3.days.ago}.not_to raise_error
|
306
312
|
expect{video.earnings_on 3.days.ago}.to raise_error Yt::Errors::Unauthorized
|
307
313
|
expect{video.impressions_on 3.days.ago}.to raise_error Yt::Errors::Unauthorized
|
308
314
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
require 'spec_helper'
|
3
3
|
require 'yt/models/channel'
|
4
|
+
require 'yt/models/playlist'
|
4
5
|
|
5
6
|
describe Yt::Channel, :partner do
|
6
7
|
subject(:channel) { Yt::Channel.new id: id, auth: $content_owner }
|
@@ -120,6 +121,15 @@ describe Yt::Channel, :partner do
|
|
120
121
|
end
|
121
122
|
end
|
122
123
|
|
124
|
+
describe 'views can be grouped by playlist' do
|
125
|
+
let(:range) { {since: 4.days.ago, until: 3.days.ago} }
|
126
|
+
|
127
|
+
specify 'with the :by option set to :playlist' do
|
128
|
+
views = channel.views range.merge by: :playlist
|
129
|
+
expect(views.keys).to all(be_instance_of Yt::Playlist)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
123
133
|
describe 'comments can be retrieved for a specific day' do
|
124
134
|
context 'in which the channel was partnered' do
|
125
135
|
let(:comments) { channel.comments_on 5.days.ago}
|
@@ -562,6 +572,15 @@ describe Yt::Channel, :partner do
|
|
562
572
|
end
|
563
573
|
end
|
564
574
|
|
575
|
+
describe 'estimated minutes watched can be grouped by playlist' do
|
576
|
+
let(:range) { {since: 4.days.ago, until: 3.days.ago} }
|
577
|
+
|
578
|
+
specify 'with the :by option set to :playlist' do
|
579
|
+
estimated_minutes_watched = channel.estimated_minutes_watched range.merge by: :playlist
|
580
|
+
expect(estimated_minutes_watched.keys).to all(be_instance_of Yt::Playlist)
|
581
|
+
end
|
582
|
+
end
|
583
|
+
|
565
584
|
describe 'average view duration can be retrieved for a specific day' do
|
566
585
|
context 'in which the channel was partnered' do
|
567
586
|
let(:average_view_duration) { channel.average_view_duration_on 5.days.ago}
|
@@ -703,6 +722,53 @@ describe Yt::Channel, :partner do
|
|
703
722
|
end
|
704
723
|
end
|
705
724
|
|
725
|
+
describe 'monetized playbacks can be retrieved for a specific day' do
|
726
|
+
context 'in which the channel was partnered' do
|
727
|
+
let(:monetized_playbacks) { channel.monetized_playbacks_on 20.days.ago}
|
728
|
+
it { expect(monetized_playbacks).to be_a Float }
|
729
|
+
end
|
730
|
+
|
731
|
+
context 'in which the channel was not partnered' do
|
732
|
+
let(:monetized_playbacks) { channel.monetized_playbacks_on 20.years.ago}
|
733
|
+
it { expect(monetized_playbacks).to be_nil }
|
734
|
+
end
|
735
|
+
end
|
736
|
+
|
737
|
+
describe 'monetized playbacks can be retrieved for a range of days' do
|
738
|
+
let(:date) { 4.days.ago }
|
739
|
+
|
740
|
+
specify 'with a given start (:since option)' do
|
741
|
+
expect(channel.monetized_playbacks(since: date).keys.min).to eq date.to_date
|
742
|
+
end
|
743
|
+
|
744
|
+
specify 'with a given end (:until option)' do
|
745
|
+
expect(channel.monetized_playbacks(until: date).keys.max).to eq date.to_date
|
746
|
+
end
|
747
|
+
|
748
|
+
specify 'with a given start (:from option)' do
|
749
|
+
expect(channel.monetized_playbacks(from: date).keys.min).to eq date.to_date
|
750
|
+
end
|
751
|
+
|
752
|
+
specify 'with a given end (:to option)' do
|
753
|
+
expect(channel.monetized_playbacks(to: date).keys.max).to eq date.to_date
|
754
|
+
end
|
755
|
+
end
|
756
|
+
|
757
|
+
describe 'monetized_playbacks can be grouped by day' do
|
758
|
+
let(:range) { {since: 4.days.ago.to_date, until: 3.days.ago.to_date} }
|
759
|
+
let(:keys) { range.values }
|
760
|
+
|
761
|
+
specify 'without a :by option (default)' do
|
762
|
+
monetized_playbacks = channel.monetized_playbacks range
|
763
|
+
expect(monetized_playbacks.keys).to eq range.values
|
764
|
+
end
|
765
|
+
|
766
|
+
specify 'with the :by option set to :day' do
|
767
|
+
monetized_playbacks = channel.monetized_playbacks range.merge by: :day
|
768
|
+
expect(monetized_playbacks.keys).to eq range.values
|
769
|
+
end
|
770
|
+
end
|
771
|
+
|
706
772
|
specify 'viewer percentages by gender and age range can be retrieved' do
|
707
773
|
expect(channel.viewer_percentages[:female]['18-24']).to be_a Float
|
708
774
|
expect(channel.viewer_percentages[:female]['25-34']).to be_a Float
|
@@ -0,0 +1,213 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'yt/models/channel'
|
4
|
+
require 'yt/models/playlist'
|
5
|
+
|
6
|
+
describe Yt::Playlist, :partner do
|
7
|
+
subject(:playlist) { Yt::Playlist.new id: id, auth: $content_owner }
|
8
|
+
|
9
|
+
context 'given a playlist of a partnered channel', :partner do
|
10
|
+
context 'managed by the authenticated Content Owner' do
|
11
|
+
let(:id) { ENV['YT_TEST_PARTNER_PLAYLIST_ID'] }
|
12
|
+
|
13
|
+
describe 'views can be retrieved for a specific day' do
|
14
|
+
context 'in which the playlist was viewed' do
|
15
|
+
let(:views) { playlist.views_on ENV['YT_TEST_PARTNER_PLAYLIST_DATE']}
|
16
|
+
it { expect(views).to be_a Float }
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'in which the playlist was not viewed' do
|
20
|
+
let(:views) { playlist.views_on 20.years.ago}
|
21
|
+
it { expect(views).to be_nil }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe 'views can be retrieved for a range of days' do
|
26
|
+
let(:date) { 4.days.ago }
|
27
|
+
|
28
|
+
specify 'with a given start (:since option)' do
|
29
|
+
expect(playlist.views(since: date).keys.min).to eq date.to_date
|
30
|
+
end
|
31
|
+
|
32
|
+
specify 'with a given end (:until option)' do
|
33
|
+
expect(playlist.views(until: date).keys.max).to eq date.to_date
|
34
|
+
end
|
35
|
+
|
36
|
+
specify 'with a given start (:from option)' do
|
37
|
+
expect(playlist.views(from: date).keys.min).to eq date.to_date
|
38
|
+
end
|
39
|
+
|
40
|
+
specify 'with a given end (:to option)' do
|
41
|
+
expect(playlist.views(to: date).keys.max).to eq date.to_date
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe 'views can be grouped by day' do
|
46
|
+
let(:range) { {since: 4.days.ago.to_date, until: 3.days.ago.to_date} }
|
47
|
+
let(:keys) { range.values }
|
48
|
+
|
49
|
+
specify 'without a :by option (default)' do
|
50
|
+
views = playlist.views range
|
51
|
+
expect(views.keys).to eq range.values
|
52
|
+
end
|
53
|
+
|
54
|
+
specify 'with the :by option set to :day' do
|
55
|
+
views = playlist.views range.merge by: :day
|
56
|
+
expect(views.keys).to eq range.values
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe 'playlist starts can be retrieved for a specific day' do
|
61
|
+
context 'in which the playlist was viewed' do
|
62
|
+
let(:playlist_starts) { playlist.playlist_starts_on ENV['YT_TEST_PARTNER_PLAYLIST_DATE']}
|
63
|
+
it { expect(playlist_starts).to be_a Float }
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'in which the playlist was not viewed' do
|
67
|
+
let(:playlist_starts) { playlist.playlist_starts_on 20.years.ago}
|
68
|
+
it { expect(playlist_starts).to be_nil }
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe 'playlist starts can be retrieved for a range of days' do
|
73
|
+
let(:date) { 4.days.ago }
|
74
|
+
|
75
|
+
specify 'with a given start (:since option)' do
|
76
|
+
expect(playlist.playlist_starts(since: date).keys.min).to eq date.to_date
|
77
|
+
end
|
78
|
+
|
79
|
+
specify 'with a given end (:until option)' do
|
80
|
+
expect(playlist.playlist_starts(until: date).keys.max).to eq date.to_date
|
81
|
+
end
|
82
|
+
|
83
|
+
specify 'with a given start (:from option)' do
|
84
|
+
expect(playlist.playlist_starts(from: date).keys.min).to eq date.to_date
|
85
|
+
end
|
86
|
+
|
87
|
+
specify 'with a given end (:to option)' do
|
88
|
+
expect(playlist.playlist_starts(to: date).keys.max).to eq date.to_date
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe 'playlist starts can be grouped by day' do
|
93
|
+
let(:range) { {since: 4.days.ago.to_date, until: 3.days.ago.to_date} }
|
94
|
+
let(:keys) { range.values }
|
95
|
+
|
96
|
+
specify 'without a :by option (default)' do
|
97
|
+
playlist_starts = playlist.playlist_starts range
|
98
|
+
expect(playlist_starts.keys).to eq range.values
|
99
|
+
end
|
100
|
+
|
101
|
+
specify 'with the :by option set to :day' do
|
102
|
+
playlist_starts = playlist.playlist_starts range.merge by: :day
|
103
|
+
expect(playlist_starts.keys).to eq range.values
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe 'average time in playlist can be retrieved for a specific day' do
|
108
|
+
context 'in which the playlist was viewed' do
|
109
|
+
let(:average_time_in_playlist) { playlist.average_time_in_playlist_on ENV['YT_TEST_PARTNER_PLAYLIST_DATE']}
|
110
|
+
it { expect(average_time_in_playlist).to be_a Float }
|
111
|
+
end
|
112
|
+
|
113
|
+
context 'in which the playlist was not viewed' do
|
114
|
+
let(:average_time_in_playlist) { playlist.average_time_in_playlist_on 20.years.ago}
|
115
|
+
it { expect(average_time_in_playlist).to be_nil }
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe 'average time in playlist can be retrieved for a range of days' do
|
120
|
+
let(:date) { 4.days.ago }
|
121
|
+
|
122
|
+
specify 'with a given start (:since option)' do
|
123
|
+
expect(playlist.average_time_in_playlist(since: date).keys.min).to eq date.to_date
|
124
|
+
end
|
125
|
+
|
126
|
+
specify 'with a given end (:until option)' do
|
127
|
+
expect(playlist.average_time_in_playlist(until: date).keys.max).to eq date.to_date
|
128
|
+
end
|
129
|
+
|
130
|
+
specify 'with a given start (:from option)' do
|
131
|
+
expect(playlist.average_time_in_playlist(from: date).keys.min).to eq date.to_date
|
132
|
+
end
|
133
|
+
|
134
|
+
specify 'with a given end (:to option)' do
|
135
|
+
expect(playlist.average_time_in_playlist(to: date).keys.max).to eq date.to_date
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
describe 'average time in playlist can be grouped by day' do
|
140
|
+
let(:range) { {since: 4.days.ago.to_date, until: 3.days.ago.to_date} }
|
141
|
+
let(:keys) { range.values }
|
142
|
+
|
143
|
+
specify 'without a :by option (default)' do
|
144
|
+
average_time_in_playlist = playlist.average_time_in_playlist range
|
145
|
+
expect(average_time_in_playlist.keys).to eq range.values
|
146
|
+
end
|
147
|
+
|
148
|
+
specify 'with the :by option set to :day' do
|
149
|
+
average_time_in_playlist = playlist.average_time_in_playlist range.merge by: :day
|
150
|
+
expect(average_time_in_playlist.keys).to eq range.values
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
describe 'views per playlist start can be retrieved for a specific day' do
|
155
|
+
context 'in which the playlist was viewed' do
|
156
|
+
let(:views_per_playlist_start) { playlist.views_per_playlist_start_on ENV['YT_TEST_PARTNER_PLAYLIST_DATE']}
|
157
|
+
it { expect(views_per_playlist_start).to be_a Float }
|
158
|
+
end
|
159
|
+
|
160
|
+
context 'in which the playlist was not viewed' do
|
161
|
+
let(:views_per_playlist_start) { playlist.views_per_playlist_start_on 20.years.ago}
|
162
|
+
it { expect(views_per_playlist_start).to be_nil }
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
describe 'views per playlist start can be retrieved for a range of days' do
|
167
|
+
let(:date) { 4.days.ago }
|
168
|
+
|
169
|
+
specify 'with a given start (:since option)' do
|
170
|
+
expect(playlist.views_per_playlist_start(since: date).keys.min).to eq date.to_date
|
171
|
+
end
|
172
|
+
|
173
|
+
specify 'with a given end (:until option)' do
|
174
|
+
expect(playlist.views_per_playlist_start(until: date).keys.max).to eq date.to_date
|
175
|
+
end
|
176
|
+
|
177
|
+
specify 'with a given start (:from option)' do
|
178
|
+
expect(playlist.views_per_playlist_start(from: date).keys.min).to eq date.to_date
|
179
|
+
end
|
180
|
+
|
181
|
+
specify 'with a given end (:to option)' do
|
182
|
+
expect(playlist.views_per_playlist_start(to: date).keys.max).to eq date.to_date
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
describe 'views per playlist start can be grouped by day' do
|
187
|
+
let(:range) { {since: 4.days.ago.to_date, until: 3.days.ago.to_date} }
|
188
|
+
let(:keys) { range.values }
|
189
|
+
|
190
|
+
specify 'without a :by option (default)' do
|
191
|
+
views_per_playlist_start = playlist.views_per_playlist_start range
|
192
|
+
expect(views_per_playlist_start.keys).to eq range.values
|
193
|
+
end
|
194
|
+
|
195
|
+
specify 'with the :by option set to :day' do
|
196
|
+
views_per_playlist_start = playlist.views_per_playlist_start range.merge by: :day
|
197
|
+
expect(views_per_playlist_start.keys).to eq range.values
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
context 'not managed by the authenticated Content Owner' do
|
203
|
+
let(:id) { 'PLbpi6ZahtOH6J5oPGySZcmbRfT7Hyq1sZ' }
|
204
|
+
|
205
|
+
specify 'playlist starts cannot be retrieved' do
|
206
|
+
expect{playlist.views}.to raise_error Yt::Errors::Forbidden
|
207
|
+
expect{playlist.playlist_starts}.to raise_error Yt::Errors::Forbidden
|
208
|
+
expect{playlist.average_time_in_playlist}.to raise_error Yt::Errors::Forbidden
|
209
|
+
expect{playlist.views_per_playlist_start}.to raise_error Yt::Errors::Forbidden
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
@@ -7,7 +7,7 @@ describe Yt::Video, :partner do
|
|
7
7
|
|
8
8
|
context 'given a video of a partnered channel', :partner do
|
9
9
|
context 'managed by the authenticated Content Owner' do
|
10
|
-
let(:id) { ENV['
|
10
|
+
let(:id) { ENV['YT_TEST_PARTNER_VIDEO_ID'] }
|
11
11
|
|
12
12
|
describe 'advertising options can be retrieved' do
|
13
13
|
it { expect{video.advertising_options_set}.not_to raise_error }
|
@@ -478,6 +478,157 @@ describe Yt::Video, :partner do
|
|
478
478
|
end
|
479
479
|
end
|
480
480
|
|
481
|
+
describe 'estimated minutes watched can be retrieved for a specific day' do
|
482
|
+
context 'in which the video was partnered' do
|
483
|
+
let(:estimated_minutes_watched) { video.estimated_minutes_watched_on 5.days.ago}
|
484
|
+
it { expect(estimated_minutes_watched).to be_a Float }
|
485
|
+
end
|
486
|
+
|
487
|
+
context 'in which the video was not partnered' do
|
488
|
+
let(:estimated_minutes_watched) { video.estimated_minutes_watched_on 20.years.ago}
|
489
|
+
it { expect(estimated_minutes_watched).to be_nil }
|
490
|
+
end
|
491
|
+
end
|
492
|
+
|
493
|
+
describe 'estimated minutes watched can be retrieved for a range of days' do
|
494
|
+
let(:date) { 4.days.ago }
|
495
|
+
|
496
|
+
specify 'with a given start (:since option)' do
|
497
|
+
expect(video.estimated_minutes_watched(since: date).keys.min).to eq date.to_date
|
498
|
+
end
|
499
|
+
|
500
|
+
specify 'with a given end (:until option)' do
|
501
|
+
expect(video.estimated_minutes_watched(until: date).keys.max).to eq date.to_date
|
502
|
+
end
|
503
|
+
|
504
|
+
specify 'with a given start (:from option)' do
|
505
|
+
expect(video.estimated_minutes_watched(from: date).keys.min).to eq date.to_date
|
506
|
+
end
|
507
|
+
|
508
|
+
specify 'with a given end (:to option)' do
|
509
|
+
expect(video.estimated_minutes_watched(to: date).keys.max).to eq date.to_date
|
510
|
+
end
|
511
|
+
end
|
512
|
+
|
513
|
+
describe 'estimated minutes watched can be grouped by day' do
|
514
|
+
let(:range) { {since: 4.days.ago.to_date, until: 3.days.ago.to_date} }
|
515
|
+
let(:keys) { range.values }
|
516
|
+
|
517
|
+
specify 'without a :by option (default)' do
|
518
|
+
estimated_minutes_watched = video.estimated_minutes_watched range
|
519
|
+
expect(estimated_minutes_watched.keys).to eq range.values
|
520
|
+
end
|
521
|
+
|
522
|
+
specify 'with the :by option set to :day' do
|
523
|
+
estimated_minutes_watched = video.estimated_minutes_watched range.merge by: :day
|
524
|
+
expect(estimated_minutes_watched.keys).to eq range.values
|
525
|
+
end
|
526
|
+
end
|
527
|
+
|
528
|
+
describe 'estimated minutes watched can be grouped by traffic source' do
|
529
|
+
let(:range) { {since: 4.days.ago, until: 3.days.ago} }
|
530
|
+
let(:keys) { Yt::Collections::Reports::TRAFFIC_SOURCES.keys }
|
531
|
+
|
532
|
+
specify 'with the :by option set to :traffic_source' do
|
533
|
+
estimated_minutes_watched = video.estimated_minutes_watched range.merge by: :traffic_source
|
534
|
+
expect(estimated_minutes_watched.keys - keys).to be_empty
|
535
|
+
end
|
536
|
+
end
|
537
|
+
|
538
|
+
describe 'average view duration can be retrieved for a specific day' do
|
539
|
+
context 'in which the video was partnered' do
|
540
|
+
let(:average_view_duration) { video.average_view_duration_on 5.days.ago}
|
541
|
+
it { expect(average_view_duration).to be_a Float }
|
542
|
+
end
|
543
|
+
|
544
|
+
context 'in which the video was not partnered' do
|
545
|
+
let(:average_view_duration) { video.average_view_duration_on 20.years.ago}
|
546
|
+
it { expect(average_view_duration).to be_nil }
|
547
|
+
end
|
548
|
+
end
|
549
|
+
|
550
|
+
describe 'average view duration can be retrieved for a range of days' do
|
551
|
+
let(:date) { 4.days.ago }
|
552
|
+
|
553
|
+
specify 'with a given start (:since option)' do
|
554
|
+
expect(video.average_view_duration(since: date).keys.min).to eq date.to_date
|
555
|
+
end
|
556
|
+
|
557
|
+
specify 'with a given end (:until option)' do
|
558
|
+
expect(video.average_view_duration(until: date).keys.max).to eq date.to_date
|
559
|
+
end
|
560
|
+
|
561
|
+
specify 'with a given start (:from option)' do
|
562
|
+
expect(video.average_view_duration(from: date).keys.min).to eq date.to_date
|
563
|
+
end
|
564
|
+
|
565
|
+
specify 'with a given end (:to option)' do
|
566
|
+
expect(video.average_view_duration(to: date).keys.max).to eq date.to_date
|
567
|
+
end
|
568
|
+
end
|
569
|
+
|
570
|
+
describe 'average view duration can be grouped by day' do
|
571
|
+
let(:range) { {since: 4.days.ago.to_date, until: 3.days.ago.to_date} }
|
572
|
+
let(:keys) { range.values }
|
573
|
+
|
574
|
+
specify 'without a :by option (default)' do
|
575
|
+
average_view_duration = video.average_view_duration range
|
576
|
+
expect(average_view_duration.keys).to eq range.values
|
577
|
+
end
|
578
|
+
|
579
|
+
specify 'with the :by option set to :day' do
|
580
|
+
average_view_duration = video.average_view_duration range.merge by: :day
|
581
|
+
expect(average_view_duration.keys).to eq range.values
|
582
|
+
end
|
583
|
+
end
|
584
|
+
|
585
|
+
describe 'average view percentage can be retrieved for a specific day' do
|
586
|
+
context 'in which the video was partnered' do
|
587
|
+
let(:average_view_percentage) { video.average_view_percentage_on 5.days.ago}
|
588
|
+
it { expect(average_view_percentage).to be_a Float }
|
589
|
+
end
|
590
|
+
|
591
|
+
context 'in which the video was not partnered' do
|
592
|
+
let(:average_view_percentage) { video.average_view_percentage_on 20.years.ago}
|
593
|
+
it { expect(average_view_percentage).to be_nil }
|
594
|
+
end
|
595
|
+
end
|
596
|
+
|
597
|
+
describe 'average view percentage can be retrieved for a range of days' do
|
598
|
+
let(:date) { 4.days.ago }
|
599
|
+
|
600
|
+
specify 'with a given start (:since option)' do
|
601
|
+
expect(video.average_view_percentage(since: date).keys.min).to eq date.to_date
|
602
|
+
end
|
603
|
+
|
604
|
+
specify 'with a given end (:until option)' do
|
605
|
+
expect(video.average_view_percentage(until: date).keys.max).to eq date.to_date
|
606
|
+
end
|
607
|
+
|
608
|
+
specify 'with a given start (:from option)' do
|
609
|
+
expect(video.average_view_percentage(from: date).keys.min).to eq date.to_date
|
610
|
+
end
|
611
|
+
|
612
|
+
specify 'with a given end (:to option)' do
|
613
|
+
expect(video.average_view_percentage(to: date).keys.max).to eq date.to_date
|
614
|
+
end
|
615
|
+
end
|
616
|
+
|
617
|
+
describe 'average view percentage can be grouped by day' do
|
618
|
+
let(:range) { {since: 4.days.ago.to_date, until: 3.days.ago.to_date} }
|
619
|
+
let(:keys) { range.values }
|
620
|
+
|
621
|
+
specify 'without a :by option (default)' do
|
622
|
+
average_view_percentage = video.average_view_percentage range
|
623
|
+
expect(average_view_percentage.keys).to eq range.values
|
624
|
+
end
|
625
|
+
|
626
|
+
specify 'with the :by option set to :day' do
|
627
|
+
average_view_percentage = video.average_view_percentage range.merge by: :day
|
628
|
+
expect(average_view_percentage.keys).to eq range.values
|
629
|
+
end
|
630
|
+
end
|
631
|
+
|
481
632
|
describe 'impressions can be retrieved for a specific day' do
|
482
633
|
context 'in which the video was partnered' do
|
483
634
|
let(:impressions) { video.impressions_on 20.days.ago}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.14.
|
4
|
+
version: 0.14.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Claudio Baccigalupo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -267,6 +267,7 @@ files:
|
|
267
267
|
- spec/requests/as_content_owner/content_owner_spec.rb
|
268
268
|
- spec/requests/as_content_owner/match_policy_spec.rb
|
269
269
|
- spec/requests/as_content_owner/ownership_spec.rb
|
270
|
+
- spec/requests/as_content_owner/playlist_spec.rb
|
270
271
|
- spec/requests/as_content_owner/video_spec.rb
|
271
272
|
- spec/requests/as_content_owner/viewer_percentages_spec.rb
|
272
273
|
- spec/requests/as_server_app/channel_spec.rb
|
@@ -364,6 +365,7 @@ test_files:
|
|
364
365
|
- spec/requests/as_content_owner/content_owner_spec.rb
|
365
366
|
- spec/requests/as_content_owner/match_policy_spec.rb
|
366
367
|
- spec/requests/as_content_owner/ownership_spec.rb
|
368
|
+
- spec/requests/as_content_owner/playlist_spec.rb
|
367
369
|
- spec/requests/as_content_owner/video_spec.rb
|
368
370
|
- spec/requests/as_content_owner/viewer_percentages_spec.rb
|
369
371
|
- spec/requests/as_server_app/channel_spec.rb
|