yt 0.24.7 → 0.24.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +1 -1
- data/lib/yt/associations/has_reports.rb +19 -14
- data/lib/yt/collections/reports.rb +6 -0
- data/lib/yt/models/content_detail.rb +6 -1
- data/lib/yt/models/video.rb +6 -0
- data/lib/yt/version.rb +1 -1
- data/spec/models/video_spec.rb +18 -1
- data/spec/requests/as_content_owner/channel_spec.rb +34 -1
- data/spec/requests/as_content_owner/playlist_spec.rb +24 -0
- data/spec/requests/as_content_owner/video_spec.rb +24 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 393804430300ba24dfed2e8d04a72005eec8bd74
|
4
|
+
data.tar.gz: 36a59293e808300580f0f0500e7aac5891204572
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ab215a61d381055c52fafbe91b0a38acb05b8f262164375713724557d7148774d281539e74b3eca471f3ac5bd17491bc4ecbb90b25f071ba56bdf0dd1fc7879a
|
7
|
+
data.tar.gz: 5af865f608ffae8c1526ed46283932e13f2be206f759382b1f877bdd001693fdcbc1f820f7924667f3c538666a6673af05270fa68b757f93ec2a6aefb704e127
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,11 @@ For more information about changelogs, check
|
|
6
6
|
[Keep a Changelog](http://keepachangelog.com) and
|
7
7
|
[Vandamme](http://tech-angels.github.io/vandamme).
|
8
8
|
|
9
|
+
## 0.24.8 - 2015-06-18
|
10
|
+
|
11
|
+
* [FEATURE] New `by: :week` option for reports.
|
12
|
+
* [FEATURE] New Video#age_restricted? method
|
13
|
+
|
9
14
|
## 0.24.7 - 2015-06-08
|
10
15
|
|
11
16
|
* [ENHANCEMENT] Add `:videos` option to limit channel reports to subset of videos
|
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.24.
|
44
|
+
gem 'yt', '~> 0.24.8'
|
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*)
|
@@ -10,7 +10,7 @@ module Yt
|
|
10
10
|
# @option options [Array<Symbol>] :only The metrics to generate reports
|
11
11
|
# for.
|
12
12
|
# @option options [Symbol] :by (:day) The dimension to collect metrics
|
13
|
-
# by. Accepted values are: +:day+, +:month+.
|
13
|
+
# by. Accepted values are: +:day+, +:week+, +:month+.
|
14
14
|
# @option options [#to_date] :since The first day of the time-range.
|
15
15
|
# Also aliased as +:from+.
|
16
16
|
# @option options [#to_date] :until The last day of the time-range.
|
@@ -40,6 +40,11 @@ module Yt
|
|
40
40
|
# @example Get the $1 for this and last month:
|
41
41
|
# resource.$1 since: 1.month.ago, by: :month
|
42
42
|
# # => {Wed, 01 Apr 2014..Thu, 30 Apr 2014 => 12.0, Fri, 01 May 2014..Sun, 31 May 2014 => 34.0, …}
|
43
|
+
# @return [Hash<Range<Date, Date>, $2>] if grouped by week, the $1
|
44
|
+
# for each week in the time-range.
|
45
|
+
# @example Get the $1 for this and last week:
|
46
|
+
# resource.$1 since: 1.week.ago, by: :week
|
47
|
+
# # => {Wed, 01 Apr 2014..Tue, 07 Apr 2014 => 20.0, Wed, 08 Apr 2014..Tue, 14 Apr 2014 => 13.0, …}
|
43
48
|
# @macro report
|
44
49
|
|
45
50
|
# @!macro [new] report_with_range
|
@@ -70,19 +75,19 @@ module Yt
|
|
70
75
|
|
71
76
|
# @!macro [new] report_by_day
|
72
77
|
# @option options [Symbol] :by (:day) The dimension to collect $1 by.
|
73
|
-
# Accepted values are: +:day+, +:month+.
|
78
|
+
# Accepted values are: +:day+, +:week+, +:month+.
|
74
79
|
# @macro report_with_day
|
75
80
|
|
76
81
|
# @!macro [new] report_by_day_and_country
|
77
82
|
# @option options [Symbol] :by (:day) The dimension to collect $1 by.
|
78
|
-
# Accepted values are: +:day+, +:month+, :+range+.
|
83
|
+
# Accepted values are: +:day+, +:week+, +:month+, :+range+.
|
79
84
|
# @macro report_with_day
|
80
85
|
# @macro report_with_range
|
81
86
|
# @macro report_with_country
|
82
87
|
|
83
88
|
# @!macro [new] report_by_day_and_state
|
84
89
|
# @option options [Symbol] :by (:day) The dimension to collect $1 by.
|
85
|
-
# Accepted values are: +:day+, +:month+, :+range+.
|
90
|
+
# Accepted values are: +:day+, +:week+, +:month+, :+range+.
|
86
91
|
# @macro report_with_day
|
87
92
|
# @macro report_with_range
|
88
93
|
# @macro report_with_country_and_state
|
@@ -123,9 +128,9 @@ module Yt
|
|
123
128
|
|
124
129
|
# @!macro [new] report_by_video_dimensions
|
125
130
|
# @option options [Symbol] :by (:day) The dimension to collect $1 by.
|
126
|
-
# Accepted values are: +:day+, +:
|
127
|
-
# +:search_term+, +:playback_location+,
|
128
|
-
# +:embedded_player_location+.
|
131
|
+
# Accepted values are: +:day+, +:week+, +:month+, +:range+,
|
132
|
+
# +:traffic_source+,+:search_term+, +:playback_location+,
|
133
|
+
# +:related_video+, +:embedded_player_location+.
|
129
134
|
# @option options [Array<Symbol>] :includes ([:id]) if grouped by
|
130
135
|
# related video, the parts of each video to eager-load. Accepted
|
131
136
|
# values are: +:id+, +:snippet+, +:status+, +:statistics+,
|
@@ -157,9 +162,9 @@ module Yt
|
|
157
162
|
|
158
163
|
# @!macro [new] report_by_channel_dimensions
|
159
164
|
# @option options [Symbol] :by (:day) The dimension to collect $1 by.
|
160
|
-
# Accepted values are: +:day+, +:
|
161
|
-
# +:
|
162
|
-
# +:playlist+, +:embedded_player_location+.
|
165
|
+
# Accepted values are: +:day+, +:week+, +:month+, +:range+,
|
166
|
+
# +:traffic_source+, +:search_term+, +:playback_location+, +:video+,
|
167
|
+
# +:related_video+, +:playlist+, +:embedded_player_location+.
|
163
168
|
# @return [Hash<Symbol, $2>] if grouped by embedded player location,
|
164
169
|
# the $1 for each embedded player location.
|
165
170
|
# @example Get yesterday’s $1 by embedded player location:
|
@@ -170,8 +175,8 @@ module Yt
|
|
170
175
|
|
171
176
|
# @!macro [new] report_by_playlist_dimensions
|
172
177
|
# @option options [Symbol] :by (:day) The dimension to collect $1 by.
|
173
|
-
# Accepted values are: +:day+, +:
|
174
|
-
# +:playback_location+, +:related_video+, +:video+,
|
178
|
+
# Accepted values are: +:day+, +:week+, +:month+, +:range+,
|
179
|
+
# +:traffic_source+, +:playback_location+, +:related_video+, +:video+,
|
175
180
|
# +:playlist+.
|
176
181
|
# @macro report_with_channel_dimensions
|
177
182
|
# @macro report_with_country_and_state
|
@@ -230,7 +235,7 @@ module Yt
|
|
230
235
|
def define_reports_method(metric, type)
|
231
236
|
(@metrics ||= {})[metric] = type
|
232
237
|
define_method :reports do |options = {}|
|
233
|
-
from = options[:since] || options[:from] || (options[:by].in?([:day, :month]) ? 5.days.ago : '2005-02-01')
|
238
|
+
from = options[:since] || options[:from] || (options[:by].in?([:day, :week, :month]) ? 5.days.ago : '2005-02-01')
|
234
239
|
to = options[:until] || options[:to] || Date.today
|
235
240
|
location = options[:in]
|
236
241
|
country = location.is_a?(Hash) ? location[:country] : location
|
@@ -253,7 +258,7 @@ module Yt
|
|
253
258
|
|
254
259
|
def define_metric_method(metric)
|
255
260
|
define_method metric do |options = {}|
|
256
|
-
from = options[:since] || options[:from] || (options[:by].in?([:day, :month]) ? 5.days.ago : '2005-02-01')
|
261
|
+
from = options[:since] || options[:from] || (options[:by].in?([:day, :week, :month]) ? 5.days.ago : '2005-02-01')
|
257
262
|
to = options[:until] || options[:to] || Date.today
|
258
263
|
location = options[:in]
|
259
264
|
country = location.is_a?(Hash) ? location[:country] : location
|
@@ -6,6 +6,7 @@ module Yt
|
|
6
6
|
class Reports < Base
|
7
7
|
DIMENSIONS = Hash.new({name: 'day', parse: ->(day, *values) { @metrics.keys.zip(values.map{|v| {Date.iso8601(day) => v}}).to_h} }).tap do |hash|
|
8
8
|
hash[:month] = {name: 'month', parse: ->(month, *values) { @metrics.keys.zip(values.map{|v| {Range.new(Date.strptime(month, '%Y-%m').beginning_of_month, Date.strptime(month, '%Y-%m').end_of_month) => v} }).to_h} }
|
9
|
+
hash[:week] = {name: '7DayTotals', parse: ->(last_day_of_week, *values) { @metrics.keys.zip(values.map{|v| {Range.new(Date.strptime(last_day_of_week) - 6, Date.strptime(last_day_of_week)) => v} }).to_h} }
|
9
10
|
hash[:range] = {parse: ->(*values) { @metrics.keys.zip(values.map{|v| {total: v}}).to_h } }
|
10
11
|
hash[:traffic_source] = {name: 'insightTrafficSourceType', parse: ->(source, *values) { @metrics.keys.zip(values.map{|v| {TRAFFIC_SOURCES.key(source) => v}}).to_h} }
|
11
12
|
hash[:playback_location] = {name: 'insightPlaybackLocationType', parse: ->(location, *values) { @metrics.keys.zip(values.map{|v| {PLAYBACK_LOCATIONS.key(location) => v}}).to_h} }
|
@@ -77,6 +78,11 @@ module Yt
|
|
77
78
|
end
|
78
79
|
if dimension == :month
|
79
80
|
hash = hash.transform_values{|h| h.sort_by{|range, v| range.first}.to_h}
|
81
|
+
elsif dimension == :week
|
82
|
+
hash = hash.transform_values do |h|
|
83
|
+
h.select{|range, v| range.last.wday == days_range.last.wday}.
|
84
|
+
sort_by{|range, v| range.first}.to_h
|
85
|
+
end
|
80
86
|
elsif dimension == :day
|
81
87
|
hash = hash.transform_values{|h| h.sort_by{|day, v| day}.to_h}
|
82
88
|
elsif dimension.in? [:traffic_source, :country, :state, :playback_location, :device_type]
|
@@ -22,6 +22,11 @@ module Yt
|
|
22
22
|
has_attribute :definition
|
23
23
|
has_attribute :caption
|
24
24
|
has_attribute :licensed_content
|
25
|
+
has_attribute :content_rating, default: {}
|
26
|
+
|
27
|
+
def youtube_rating
|
28
|
+
content_rating['ytRating']
|
29
|
+
end
|
25
30
|
|
26
31
|
private
|
27
32
|
|
@@ -57,4 +62,4 @@ module Yt
|
|
57
62
|
end
|
58
63
|
end
|
59
64
|
end
|
60
|
-
end
|
65
|
+
end
|
data/lib/yt/models/video.rb
CHANGED
@@ -247,6 +247,12 @@ module Yt
|
|
247
247
|
content_detail.licensed_content || false
|
248
248
|
end
|
249
249
|
|
250
|
+
# @return [Boolean] whether the video is identified by YouTube as
|
251
|
+
# age-restricted content.
|
252
|
+
def age_restricted?
|
253
|
+
content_detail.youtube_rating == 'ytAgeRestricted'
|
254
|
+
end
|
255
|
+
|
250
256
|
### FILE DETAILS ###
|
251
257
|
|
252
258
|
has_one :file_detail
|
data/lib/yt/version.rb
CHANGED
data/spec/models/video_spec.rb
CHANGED
@@ -473,6 +473,23 @@ describe Yt::Video do
|
|
473
473
|
end
|
474
474
|
end
|
475
475
|
|
476
|
+
describe '#age_restricted?' do
|
477
|
+
context 'given a video with age restricted content' do
|
478
|
+
let(:attrs) { {content_details: {"contentRating"=>{"ytRating"=>"ytAgeRestricted"}}} }
|
479
|
+
it { expect(video).to be_age_restricted }
|
480
|
+
end
|
481
|
+
|
482
|
+
context 'given a video without age restricted content' do
|
483
|
+
let(:attrs) { {content_details: {}} }
|
484
|
+
it { expect(video).not_to be_age_restricted }
|
485
|
+
end
|
486
|
+
|
487
|
+
context 'given a video with a content rating but not ytRating' do
|
488
|
+
let(:attrs) { {content_details: {"contentRating"=>{"acbRating": "PG"}}} }
|
489
|
+
it { expect(video).not_to be_age_restricted }
|
490
|
+
end
|
491
|
+
end
|
492
|
+
|
476
493
|
describe '#file_size' do
|
477
494
|
context 'given a video with fileSize' do
|
478
495
|
let(:attrs) { {file_details: {"fileSize"=>"8000000"}} }
|
@@ -649,4 +666,4 @@ describe Yt::Video do
|
|
649
666
|
it { expect{video.delete}.to change{video.exists?} }
|
650
667
|
end
|
651
668
|
end
|
652
|
-
end
|
669
|
+
end
|
@@ -42,6 +42,18 @@ describe Yt::Channel, :partner do
|
|
42
42
|
expect(result[metric].values).to all(be_a type)
|
43
43
|
end
|
44
44
|
end
|
45
|
+
|
46
|
+
specify 'by week' do
|
47
|
+
range = {since: ENV['YT_TEST_PARTNER_VIDEO_DATE'], until: Date.parse(ENV['YT_TEST_PARTNER_VIDEO_DATE']) + 9}
|
48
|
+
result = channel.reports range.merge(only: metrics, by: :week)
|
49
|
+
metrics.each do |metric, type|
|
50
|
+
expect(result[metric].size).to be <= 2
|
51
|
+
expect(result[metric].keys).to all(be_a Range)
|
52
|
+
expect(result[metric].keys.map{|range| range.first.wday}.uniq).to be_one
|
53
|
+
expect(result[metric].keys.map{|range| range.last.wday}.uniq).to be_one
|
54
|
+
expect(result[metric].values).to all(be_a type)
|
55
|
+
end
|
56
|
+
end
|
45
57
|
end
|
46
58
|
|
47
59
|
[:views, :uniques, :comments, :likes, :dislikes, :shares,
|
@@ -86,6 +98,18 @@ describe Yt::Channel, :partner do
|
|
86
98
|
expect(result.keys.map &:last).to eq result.keys.map(&:last).map(&:end_of_month)
|
87
99
|
end
|
88
100
|
end
|
101
|
+
|
102
|
+
describe "#{metric} can be grouped by week and returns non-overlapping periods" do
|
103
|
+
let(:metric) { metric }
|
104
|
+
let(:range) { {since: ENV['YT_TEST_PARTNER_VIDEO_DATE'], until: Date.parse(ENV['YT_TEST_PARTNER_VIDEO_DATE']) + 9} }
|
105
|
+
let(:result) { channel.public_send metric, range.merge(by: :week)}
|
106
|
+
specify do
|
107
|
+
expect(result.size).to be <= 2
|
108
|
+
expect(result.keys).to all(be_a Range)
|
109
|
+
expect(result.keys.map{|range| range.first.wday}.uniq).to be_one
|
110
|
+
expect(result.keys.map{|range| range.last.wday}.uniq).to be_one
|
111
|
+
end
|
112
|
+
end
|
89
113
|
end
|
90
114
|
|
91
115
|
{views: Integer, comments: Integer, likes: Integer, dislikes: Integer,
|
@@ -452,12 +476,21 @@ describe Yt::Channel, :partner do
|
|
452
476
|
describe 'views can be limited to a subset of videos' do
|
453
477
|
let(:range) { {since: ENV['YT_TEST_PARTNER_VIDEO_DATE']} }
|
454
478
|
let(:videos) { channel.videos.first(2) }
|
479
|
+
let(:video_views) { videos.inject(0){|total, video| total + video.views(range)[:total]} }
|
455
480
|
|
456
481
|
specify 'with the :videos option listing the video IDs' do
|
457
|
-
video_views = videos.inject(0){|total, video| total + video.views(range)[:total]}
|
458
482
|
views = channel.views range.merge videos: videos.map(&:id)
|
459
483
|
expect(views[:total]).to eq video_views
|
460
484
|
end
|
485
|
+
|
486
|
+
specify 'with a maximum of 200 video IDs' do
|
487
|
+
views = channel.views range.merge videos: (videos*100).map(&:id)
|
488
|
+
expect(views[:total]).to eq video_views
|
489
|
+
end
|
490
|
+
|
491
|
+
specify 'but fails with more than 200 video IDs' do
|
492
|
+
expect{channel.views range.merge videos: (videos*101).map(&:id)}.to raise_error Yt::Errors::RequestError
|
493
|
+
end
|
461
494
|
end
|
462
495
|
|
463
496
|
describe 'uniques can be retrieved for a single country' do
|
@@ -35,6 +35,18 @@ describe Yt::Playlist, :partner do
|
|
35
35
|
expect(result[metric].values).to all(be_a type)
|
36
36
|
end
|
37
37
|
end
|
38
|
+
|
39
|
+
specify 'by week' do
|
40
|
+
range = {since: ENV['YT_TEST_PARTNER_VIDEO_DATE'], until: Date.parse(ENV['YT_TEST_PARTNER_VIDEO_DATE']) + 9}
|
41
|
+
result = playlist.reports range.merge(only: metrics, by: :week)
|
42
|
+
metrics.each do |metric, type|
|
43
|
+
expect(result[metric].size).to be <= 2
|
44
|
+
expect(result[metric].keys).to all(be_a Range)
|
45
|
+
expect(result[metric].keys.map{|range| range.first.wday}.uniq).to be_one
|
46
|
+
expect(result[metric].keys.map{|range| range.last.wday}.uniq).to be_one
|
47
|
+
expect(result[metric].values).to all(be_a type)
|
48
|
+
end
|
49
|
+
end
|
38
50
|
end
|
39
51
|
|
40
52
|
{views: Integer, estimated_minutes_watched: Integer,
|
@@ -76,6 +88,18 @@ describe Yt::Playlist, :partner do
|
|
76
88
|
end
|
77
89
|
end
|
78
90
|
|
91
|
+
describe "#{metric} can be grouped by week and returns non-overlapping periods" do
|
92
|
+
let(:metric) { metric }
|
93
|
+
let(:range) { {since: ENV['YT_TEST_PARTNER_VIDEO_DATE'], until: Date.parse(ENV['YT_TEST_PARTNER_VIDEO_DATE']) + 9} }
|
94
|
+
let(:result) { playlist.public_send metric, range.merge(by: :week)}
|
95
|
+
specify do
|
96
|
+
expect(result.size).to be <= 2
|
97
|
+
expect(result.keys).to all(be_a Range)
|
98
|
+
expect(result.keys.map{|range| range.first.wday}.uniq).to be_one
|
99
|
+
expect(result.keys.map{|range| range.last.wday}.uniq).to be_one
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
79
103
|
describe "#{metric} can be retrieved for a specific day" do
|
80
104
|
let(:metric) { metric }
|
81
105
|
let(:result) { playlist.public_send "#{metric}_on", date }
|
@@ -55,6 +55,18 @@ describe Yt::Video, :partner do
|
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
|
+
describe "#{metric} can be grouped by week and returns non-overlapping periods" do
|
59
|
+
let(:metric) { metric }
|
60
|
+
let(:range) { {since: ENV['YT_TEST_PARTNER_VIDEO_DATE'], until: Date.parse(ENV['YT_TEST_PARTNER_VIDEO_DATE']) + 9} }
|
61
|
+
let(:result) { video.public_send metric, range.merge(by: :week)}
|
62
|
+
specify do
|
63
|
+
expect(result.size).to be <= 2
|
64
|
+
expect(result.keys).to all(be_a Range)
|
65
|
+
expect(result.keys.map{|range| range.first.wday}.uniq).to be_one
|
66
|
+
expect(result.keys.map{|range| range.last.wday}.uniq).to be_one
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
58
70
|
describe "#{metric} can be retrieved for a single country" do
|
59
71
|
let(:result) { video.public_send metric, options }
|
60
72
|
|
@@ -225,6 +237,18 @@ describe Yt::Video, :partner do
|
|
225
237
|
expect(result[metric].values).to all(be_a type)
|
226
238
|
end
|
227
239
|
end
|
240
|
+
|
241
|
+
specify 'by week' do
|
242
|
+
range = {since: ENV['YT_TEST_PARTNER_VIDEO_DATE'], until: Date.parse(ENV['YT_TEST_PARTNER_VIDEO_DATE']) + 9}
|
243
|
+
result = video.reports range.merge(only: metrics, by: :week)
|
244
|
+
metrics.each do |metric, type|
|
245
|
+
expect(result[metric].size).to be <= 2
|
246
|
+
expect(result[metric].keys).to all(be_a Range)
|
247
|
+
expect(result[metric].keys.map{|range| range.first.wday}.uniq).to be_one
|
248
|
+
expect(result[metric].keys.map{|range| range.last.wday}.uniq).to be_one
|
249
|
+
expect(result[metric].values).to all(be_a type)
|
250
|
+
end
|
251
|
+
end
|
228
252
|
end
|
229
253
|
|
230
254
|
describe 'earnings can be grouped by day' do
|
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.24.
|
4
|
+
version: 0.24.8
|
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-06-
|
11
|
+
date: 2015-06-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|