yt 0.13.5 → 0.13.6
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 +6 -0
- data/Gemfile +1 -1
- data/README.md +4 -1
- data/lib/yt/actions/list.rb +7 -3
- data/lib/yt/associations/has_viewer_percentages.rb +1 -1
- data/lib/yt/collections/channels.rb +9 -1
- data/lib/yt/collections/partnered_channels.rb +28 -1
- data/lib/yt/collections/viewer_percentages.rb +15 -7
- data/lib/yt/models/channel.rb +15 -3
- data/lib/yt/models/video.rb +3 -3
- data/lib/yt/version.rb +1 -1
- data/spec/requests/as_account/channels_spec.rb +18 -0
- data/spec/requests/as_content_owner/content_owner_spec.rb +17 -5
- data/spec/requests/as_content_owner/viewer_percentages_spec.rb +18 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 30c38777c96e3983801b273d1ca29efd2e107cd9
|
4
|
+
data.tar.gz: 4de8292876f8d7193a0d5e32355b65a0fdd5444b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 35e20ccb37d0a7a9a8faa9045735025488a896b21313a47189556f7031dd0581f8f485e775dbf8cbbfb791a5805a2e4b07e4856334da6827c1394959911ee243
|
7
|
+
data.tar.gz: af3f518907140a82bb4a22baa82d1b07a4fb47ae62b016c91f138a6c8b3cab733fb26a0b4f8c7af73dff9651907fd83a56561edf30ec3ec5126b76060f24dfda
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,12 @@ 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.13.6 - 2014-10-08
|
10
|
+
|
11
|
+
* [ENHANCEMENT] Accept `includes(:viewer_percentages)` in `.partnered_channels` to eager-load multiple viewer percentages at once.
|
12
|
+
* [ENHANCEMENT] Accept `where` in ViewerPercentages to collect data for multiple channels at once.
|
13
|
+
* [ENHANCEMENT] Accept `part` in the `where` clause of Channels, so statistics can be loaded at once.
|
14
|
+
|
9
15
|
## 0.13.5 - 2014-10-06
|
10
16
|
|
11
17
|
* [ENHANCEMENT] Add `advertising_options_set` and `ad_formats` to video
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -113,7 +113,10 @@ Use [Yt::ContentOwner](http://rubydoc.info/github/Fullscreen/yt/master/Yt/Models
|
|
113
113
|
content_owner = Yt::ContentOwner.new owner_name: 'CMSname', access_token: 'ya29.1.ABCDEFGHIJ'
|
114
114
|
|
115
115
|
content_owner.partnered_channels.count #=> 12
|
116
|
-
content_owner.partnered_channels.
|
116
|
+
content_owner.partnered_channels.map &:title #=> ["Fullscreen", "Best of Fullscreen", ...]
|
117
|
+
content_owner.partnered_channels.where(part: 'statistics').map &:subscriber_count #=> [136925, 56945, ...]
|
118
|
+
content_owner.partnered_channels.includes(:viewer_percentages).map &:viewer_percentages #=> [{female: {'18-24' => 12.12,…}…}, {female: {'18-24' => 40.12,…}…}, …]
|
119
|
+
|
117
120
|
|
118
121
|
content_owner.claims.where(q: 'Fullscreen').count #=> 24
|
119
122
|
content_owner.claims.first #=> #<Yt::Models::Claim @id=...>
|
data/lib/yt/actions/list.rb
CHANGED
@@ -6,8 +6,8 @@ require 'yt/config'
|
|
6
6
|
module Yt
|
7
7
|
module Actions
|
8
8
|
module List
|
9
|
-
delegate :
|
10
|
-
:size, to: :list
|
9
|
+
delegate :any?, :count, :each, :each_cons, :each_slice, :find, :first,
|
10
|
+
:flat_map, :map, :size, to: :list
|
11
11
|
|
12
12
|
def first!
|
13
13
|
first.tap{|item| raise Errors::NoItems, error_message unless item}
|
@@ -84,7 +84,11 @@ module Yt
|
|
84
84
|
params[:params][:page_token] = @page_token if @page_token
|
85
85
|
next_page = fetch_page params
|
86
86
|
@page_token = next_page[:token]
|
87
|
-
next_page[:items]
|
87
|
+
eager_load_items_from next_page[:items]
|
88
|
+
end
|
89
|
+
|
90
|
+
def eager_load_items_from(items)
|
91
|
+
items
|
88
92
|
end
|
89
93
|
|
90
94
|
def fetch_page(params = {})
|
@@ -38,7 +38,7 @@ module Yt
|
|
38
38
|
def define_viewer_percentages_method
|
39
39
|
# @todo: add options like start and end date
|
40
40
|
define_method :viewer_percentages do
|
41
|
-
@viewer_percentages ||= Collections::ViewerPercentages.of(self)
|
41
|
+
@viewer_percentages ||= Collections::ViewerPercentages.of(self)[id]
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
@@ -9,6 +9,12 @@ module Yt
|
|
9
9
|
|
10
10
|
private
|
11
11
|
|
12
|
+
def attributes_for_new_item(data)
|
13
|
+
super(data).tap do |attributes|
|
14
|
+
attributes[:statistics] = data['statistics']
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
12
18
|
# @return [Hash] the parameters to submit to YouTube to list channels.
|
13
19
|
# @see https://developers.google.com/youtube/v3/docs/channels/list
|
14
20
|
def list_params
|
@@ -16,7 +22,9 @@ module Yt
|
|
16
22
|
end
|
17
23
|
|
18
24
|
def channels_params
|
19
|
-
|
25
|
+
params = resources_params
|
26
|
+
params.merge! mine: true if @parent
|
27
|
+
apply_where_params! params
|
20
28
|
end
|
21
29
|
end
|
22
30
|
end
|
@@ -4,8 +4,35 @@ module Yt
|
|
4
4
|
module Collections
|
5
5
|
class PartneredChannels < Channels
|
6
6
|
|
7
|
+
def includes(relationship)
|
8
|
+
self.tap do
|
9
|
+
@items = []
|
10
|
+
@includes_relationship = relationship
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
7
14
|
private
|
8
15
|
|
16
|
+
def attributes_for_new_item(data)
|
17
|
+
super(data).tap do |attributes|
|
18
|
+
attributes[:viewer_percentages] = data['viewerPercentages']
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def eager_load_items_from(items)
|
23
|
+
if @includes_relationship == :viewer_percentages
|
24
|
+
filters = "channel==#{items.map{|item| item['id']}.join(',')}"
|
25
|
+
ids = "contentOwner==#{@auth.owner_name}"
|
26
|
+
conditions = {ids: ids, filters: filters}
|
27
|
+
viewer_percentages = Collections::ViewerPercentages.new auth: @auth
|
28
|
+
viewer_percentages = viewer_percentages.where conditions
|
29
|
+
items.each do |item|
|
30
|
+
item['viewerPercentages'] = viewer_percentages[item['id']]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
items
|
34
|
+
end
|
35
|
+
|
9
36
|
# @private
|
10
37
|
# @note Partnered Channels overwrites +channel_params+ since the query
|
11
38
|
# is slightly different.
|
@@ -13,7 +40,7 @@ module Yt
|
|
13
40
|
super.tap do |params|
|
14
41
|
params.delete :mine
|
15
42
|
params[:managed_by_me] = true
|
16
|
-
params[:on_behalf_of_content_owner] = @
|
43
|
+
params[:on_behalf_of_content_owner] = @auth.owner_name
|
17
44
|
end
|
18
45
|
end
|
19
46
|
|
@@ -3,10 +3,13 @@ require 'yt/collections/base'
|
|
3
3
|
module Yt
|
4
4
|
module Collections
|
5
5
|
class ViewerPercentages < Base
|
6
|
+
delegate :[], to: :all
|
6
7
|
|
7
8
|
def all
|
8
|
-
Hash.new{|h,k| h[k] = Hash.new
|
9
|
-
each
|
9
|
+
Hash.new{|h,k| h[k] = Hash.new{|h,k| h[k] = Hash.new 0.0}}.tap do |hash|
|
10
|
+
each do |item|
|
11
|
+
hash[item.id][item.gender][item.age_range] = item.value
|
12
|
+
end
|
10
13
|
end
|
11
14
|
end
|
12
15
|
|
@@ -14,9 +17,10 @@ module Yt
|
|
14
17
|
|
15
18
|
# @note could use column headers to be more precise
|
16
19
|
def new_item(data)
|
17
|
-
Struct.new(:gender, :age_range, :value).new.tap do |item|
|
18
|
-
item.
|
19
|
-
item.
|
20
|
+
Struct.new(:id, :gender, :age_range, :value).new.tap do |item|
|
21
|
+
item.id = data.first
|
22
|
+
item.gender = data.second.to_sym
|
23
|
+
item.age_range = data.third.gsub /^age/, ''
|
20
24
|
item.value = data.last
|
21
25
|
end
|
22
26
|
end
|
@@ -30,12 +34,16 @@ module Yt
|
|
30
34
|
end
|
31
35
|
|
32
36
|
def reports_params
|
33
|
-
|
37
|
+
{}.tap do |params|
|
34
38
|
params['start-date'] = 3.months.ago.to_date
|
35
39
|
params['end-date'] = Date.today.to_date
|
36
40
|
params['metrics'] = :viewerPercentage
|
37
|
-
params['dimensions'] = 'gender,ageGroup'
|
38
41
|
params['sort'] = 'gender,ageGroup'
|
42
|
+
params.merge! @parent.reports_params if @parent
|
43
|
+
apply_where_params! params
|
44
|
+
main_dimension = params.fetch(:filters, '').split('==').first
|
45
|
+
main_dimension ||= params.fetch(:ids, '').split('==').first
|
46
|
+
params['dimensions'] = "#{main_dimension},#{params['sort']}"
|
39
47
|
end
|
40
48
|
end
|
41
49
|
|
data/lib/yt/models/channel.rb
CHANGED
@@ -63,6 +63,18 @@ module Yt
|
|
63
63
|
# return an authenticated account.
|
64
64
|
has_one :subscription
|
65
65
|
|
66
|
+
# Override Resource's new to set statistics as well
|
67
|
+
# if the response includes them
|
68
|
+
def initialize(options = {})
|
69
|
+
super options
|
70
|
+
if options[:statistics]
|
71
|
+
@statistics_set = StatisticsSet.new data: options[:statistics]
|
72
|
+
end
|
73
|
+
if options[:viewer_percentages]
|
74
|
+
@viewer_percentages = options[:viewer_percentages]
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
66
78
|
# Returns whether the authenticated account is subscribed to the channel.
|
67
79
|
#
|
68
80
|
# This method requires {Resource#auth auth} to return an
|
@@ -149,10 +161,10 @@ module Yt
|
|
149
161
|
def reports_params
|
150
162
|
{}.tap do |params|
|
151
163
|
if auth.owner_name
|
152
|
-
params[
|
153
|
-
params[
|
164
|
+
params[:ids] = "contentOwner==#{auth.owner_name}"
|
165
|
+
params[:filters] = "channel==#{id}"
|
154
166
|
else
|
155
|
-
params[
|
167
|
+
params[:ids] = "channel==#{id}"
|
156
168
|
end
|
157
169
|
end
|
158
170
|
end
|
data/lib/yt/models/video.rb
CHANGED
@@ -167,11 +167,11 @@ module Yt
|
|
167
167
|
def reports_params
|
168
168
|
{}.tap do |params|
|
169
169
|
if auth.owner_name
|
170
|
-
params[
|
170
|
+
params[:ids] = "contentOwner==#{auth.owner_name}"
|
171
171
|
else
|
172
|
-
params[
|
172
|
+
params[:ids] = "channel==#{channel_id}"
|
173
173
|
end
|
174
|
-
params[
|
174
|
+
params[:filters] = "video==#{id}"
|
175
175
|
end
|
176
176
|
end
|
177
177
|
|
data/lib/yt/version.rb
CHANGED
@@ -0,0 +1,18 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'yt/collections/channels'
|
4
|
+
|
5
|
+
describe Yt::Collections::Channels, :device_app do
|
6
|
+
subject(:channels) { Yt::Collections::Channels.new auth: $account }
|
7
|
+
|
8
|
+
context 'with a list of parts' do
|
9
|
+
let(:part) { 'statistics' }
|
10
|
+
let(:channel) { channels.where(part: part, id: 'UCxO1tY8h1AhOz0T4ENwmpow').first }
|
11
|
+
|
12
|
+
specify 'load ONLY the specified parts of the channels' do
|
13
|
+
expect(channel.instance_variable_defined? :@snippet).to be false
|
14
|
+
expect(channel.instance_variable_defined? :@status).to be false
|
15
|
+
expect(channel.instance_variable_defined? :@statistics_set).to be true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -2,12 +2,24 @@ require 'spec_helper'
|
|
2
2
|
require 'yt/models/content_owner'
|
3
3
|
|
4
4
|
describe Yt::ContentOwner, :partner do
|
5
|
-
describe '.partnered_channels
|
6
|
-
|
7
|
-
|
5
|
+
describe '.partnered_channels' do
|
6
|
+
let(:partnered_channels) { $content_owner.partnered_channels }
|
7
|
+
|
8
|
+
specify '.first' do
|
9
|
+
expect(partnered_channels.first).to be_a Yt::Channel
|
10
|
+
end
|
11
|
+
|
12
|
+
specify '.size', :ruby2 do
|
13
|
+
expect(partnered_channels.size).to be > 0
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'with includes(:viewer_percentages)' do
|
17
|
+
let(:channel) { partnered_channels.includes(:viewer_percentages).first }
|
8
18
|
|
9
|
-
|
10
|
-
|
19
|
+
specify 'eager-loads the viewer percentages of each channel' do
|
20
|
+
expect(channel.instance_variable_defined? :@viewer_percentages).to be true
|
21
|
+
end
|
22
|
+
end
|
11
23
|
end
|
12
24
|
|
13
25
|
describe 'claims' do
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'yt/collections/viewer_percentages'
|
4
|
+
|
5
|
+
describe Yt::Collections::ViewerPercentages, :partner do
|
6
|
+
subject(:viewer_percentages) { Yt::Collections::ViewerPercentages.new auth: $content_owner }
|
7
|
+
|
8
|
+
context 'for two channels at once' do
|
9
|
+
let(:filters) { 'channel==UCxO1tY8h1AhOz0T4ENwmpow,UCsmvakQZlvGsyjyOhmhvOsw' }
|
10
|
+
let(:ids) { "contentOwner==#{$content_owner.owner_name}" }
|
11
|
+
let(:result) { viewer_percentages.where filters: filters, ids: ids }
|
12
|
+
|
13
|
+
it 'returns the viewer percentages of both' do
|
14
|
+
expect(result['UCggO99g88eUDPcqkTShOPvw'][:female]['18-24']).to be_a Float
|
15
|
+
expect(result['UC8oJ8Sdgkpcy4gylGjTHtBw'][:male]['18-24']).to be_a Float
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
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.13.
|
4
|
+
version: 0.13.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Claudio Baccigalupo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-10-
|
11
|
+
date: 2014-10-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -251,6 +251,7 @@ files:
|
|
251
251
|
- spec/requests/as_account/account_spec.rb
|
252
252
|
- spec/requests/as_account/authentications_spec.rb
|
253
253
|
- spec/requests/as_account/channel_spec.rb
|
254
|
+
- spec/requests/as_account/channels_spec.rb
|
254
255
|
- spec/requests/as_account/playlist_item_spec.rb
|
255
256
|
- spec/requests/as_account/playlist_spec.rb
|
256
257
|
- spec/requests/as_account/resource_spec.rb
|
@@ -264,6 +265,7 @@ files:
|
|
264
265
|
- spec/requests/as_content_owner/match_policy_spec.rb
|
265
266
|
- spec/requests/as_content_owner/ownership_spec.rb
|
266
267
|
- spec/requests/as_content_owner/video_spec.rb
|
268
|
+
- spec/requests/as_content_owner/viewer_percentages_spec.rb
|
267
269
|
- spec/requests/as_server_app/channel_spec.rb
|
268
270
|
- spec/requests/as_server_app/playlist_item_spec.rb
|
269
271
|
- spec/requests/as_server_app/playlist_spec.rb
|
@@ -345,6 +347,7 @@ test_files:
|
|
345
347
|
- spec/requests/as_account/account_spec.rb
|
346
348
|
- spec/requests/as_account/authentications_spec.rb
|
347
349
|
- spec/requests/as_account/channel_spec.rb
|
350
|
+
- spec/requests/as_account/channels_spec.rb
|
348
351
|
- spec/requests/as_account/playlist_item_spec.rb
|
349
352
|
- spec/requests/as_account/playlist_spec.rb
|
350
353
|
- spec/requests/as_account/resource_spec.rb
|
@@ -358,6 +361,7 @@ test_files:
|
|
358
361
|
- spec/requests/as_content_owner/match_policy_spec.rb
|
359
362
|
- spec/requests/as_content_owner/ownership_spec.rb
|
360
363
|
- spec/requests/as_content_owner/video_spec.rb
|
364
|
+
- spec/requests/as_content_owner/viewer_percentages_spec.rb
|
361
365
|
- spec/requests/as_server_app/channel_spec.rb
|
362
366
|
- spec/requests/as_server_app/playlist_item_spec.rb
|
363
367
|
- spec/requests/as_server_app/playlist_spec.rb
|