yt 0.24.7 → 0.24.8
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 +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
|