yt 0.9.1 → 0.9.2
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/Gemfile.lock +1 -1
- data/HISTORY.md +1 -0
- data/README.md +2 -1
- data/lib/yt/collections/policies.rb +37 -0
- data/lib/yt/models/content_owner.rb +4 -0
- data/lib/yt/models/policy.rb +44 -0
- data/lib/yt/models/policy_rule.rb +133 -0
- data/lib/yt/version.rb +1 -1
- data/spec/models/policy_rule_spec.rb +63 -0
- data/spec/models/policy_spec.rb +41 -0
- data/spec/requests/as_content_owner/content_owner_spec.rb +26 -0
- metadata +8 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5fe9ccf19b87eba1932a8381ec62e4c7e18bb997
|
4
|
+
data.tar.gz: bcc2aefb8c393bac857f94157267d66ab96301ae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f3f0ddfe5fcf4c20b72a77478efba519a33db0bf9565b52a47daaa6f768fe68015d3436d4535fdd759443462903c5ec788750ef5595317672c7492d903c25db2
|
7
|
+
data.tar.gz: 0dcc83e353408a679b723516e3801eafd2b1710ee25584040a9d9c359fa8dadac24b44949779b6b4f042a09e3ebd633b737b3c64815bf826ed571bdb0f0169e2
|
data/Gemfile.lock
CHANGED
data/HISTORY.md
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.9.
|
44
|
+
gem 'yt', '~> 0.9.2'
|
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*)
|
@@ -107,6 +107,7 @@ content_owner.claims.where(q: 'Fullscreen').count #=> 24
|
|
107
107
|
content_owner.claims.first #=> #<Yt::Models::Claim @id=...>
|
108
108
|
|
109
109
|
content_owner.references.where(asset_id: "ABCDEFG").first => #<Yt::Models::Reference @id=...>
|
110
|
+
content_owner.policies.first => #<Yt::Models::Policy @id=...>
|
110
111
|
```
|
111
112
|
|
112
113
|
*All the above methods require authentication (see below).*
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'yt/collections/base'
|
2
|
+
require 'yt/models/policy'
|
3
|
+
|
4
|
+
module Yt
|
5
|
+
module Collections
|
6
|
+
# Provides methods to interact with a collection of Content ID policies.
|
7
|
+
#
|
8
|
+
# Resources with policies are: {Yt::Models::ContentOwner content owners}.
|
9
|
+
class Policies < Base
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def new_item(data)
|
14
|
+
Yt::Policy.new data: data
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [Hash] the parameters to submit to YouTube to list policies
|
18
|
+
# saved by the content owner.
|
19
|
+
# @see https://developers.google.com/youtube/partner/docs/v1/policies/list
|
20
|
+
def list_params
|
21
|
+
|
22
|
+
super.tap do |params|
|
23
|
+
params[:params] = policies_params
|
24
|
+
params[:path] = '/youtube/partner/v1/policies'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def policies_params
|
29
|
+
{onBehalfOfContentOwner: @parent.owner_name}.tap do |params|
|
30
|
+
(@extra_params ||= {}).each do |key, value|
|
31
|
+
params[key.to_s.camelize :lower] = value
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -19,6 +19,10 @@ module Yt
|
|
19
19
|
# @return [Yt::Collection::References] the references administered by the content owner.
|
20
20
|
has_many :references
|
21
21
|
|
22
|
+
# @!attribute [r] policies
|
23
|
+
# @return [Yt::Collection::Policies] the policies saved by the content owner.
|
24
|
+
has_many :policies
|
25
|
+
|
22
26
|
def initialize(options = {})
|
23
27
|
super options
|
24
28
|
@owner_name = options[:owner_name]
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'yt/models/base'
|
2
|
+
require 'yt/models/policy_rule'
|
3
|
+
|
4
|
+
module Yt
|
5
|
+
module Models
|
6
|
+
# Provides methods to interact with YouTube ContentID policies.
|
7
|
+
# A policy resource specifies rules that define a particular usage or
|
8
|
+
# match policy that a partner can associate with an asset or claim.
|
9
|
+
# @see https://developers.google.com/youtube/partner/docs/v1/policies
|
10
|
+
class Policy < Base
|
11
|
+
def initialize(options = {})
|
12
|
+
@data = options[:data]
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [String] the ID that YouTube assigns and uses to uniquely
|
16
|
+
# identify the policy.
|
17
|
+
def id
|
18
|
+
@id ||= @data['id']
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [String] the policy’s name.
|
22
|
+
def name
|
23
|
+
@name ||= @data['name']
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [String] the policy’s description.
|
27
|
+
def description
|
28
|
+
@name ||= @data['description']
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [String] the time the policy was updated.
|
32
|
+
def time_updated
|
33
|
+
@time_updated ||= Time.parse @data['timeUpdated']
|
34
|
+
end
|
35
|
+
|
36
|
+
# @return [Array<PolicyRule>] a list of rules that specify the action
|
37
|
+
# that YouTube should take and may optionally specify the conditions
|
38
|
+
# under which that action is enforced.
|
39
|
+
def rules
|
40
|
+
@rules ||= @data['rules'].map{|rule| PolicyRule.new data: rule}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'yt/models/base'
|
2
|
+
|
3
|
+
module Yt
|
4
|
+
module Models
|
5
|
+
# Provides methods to interact with YouTube ContentID policy rules.
|
6
|
+
# Rules that specify the action that YouTube should take and may optionally
|
7
|
+
# specify the conditions under which that action is enforced.
|
8
|
+
# @see https://developers.google.com/youtube/partner/docs/v1/policies
|
9
|
+
class PolicyRule
|
10
|
+
def initialize(options = {})
|
11
|
+
@data = options[:data]
|
12
|
+
end
|
13
|
+
|
14
|
+
ACTIONS = %q(block monetize takedown track)
|
15
|
+
|
16
|
+
# Return the policy that YouTube should enforce if the rule’s conditions
|
17
|
+
# are all valid for an asset or for an attempt to view that asset on
|
18
|
+
# YouTube. Valid values for this property are: block, monetize, takedown,
|
19
|
+
# track.
|
20
|
+
# @return [String] the policy that YouTube should enforce.
|
21
|
+
def action
|
22
|
+
@action ||= @data['action']
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [Array] A list of additional actions that YouTube should take
|
26
|
+
# if the conditions in the rule are met. Valid values for this property
|
27
|
+
# are: review.
|
28
|
+
def subaction
|
29
|
+
@subaction ||= @data['subaction']
|
30
|
+
end
|
31
|
+
|
32
|
+
# Return the list of territories where the policy applies.
|
33
|
+
# Each territory is an ISO 3166 two-letter country code.
|
34
|
+
# YouTube determines whether the condition is satisfied based on the
|
35
|
+
# user’s location.
|
36
|
+
# @return [Array<String>] the territories where the policy applies.
|
37
|
+
# @example (with 'block' action) only block a video for U.S. users:
|
38
|
+
# included_territories #=> ['us']
|
39
|
+
def included_territories
|
40
|
+
territories_type == 'include' ? territories : []
|
41
|
+
end
|
42
|
+
|
43
|
+
# Return the list of territories where the policy does not apply.
|
44
|
+
# Each territory is an ISO 3166 two-letter country code.
|
45
|
+
# YouTube determines whether the condition is satisfied based on the
|
46
|
+
# user’s location.
|
47
|
+
# @return [Array<String>] the territories where the policy does not apply.
|
48
|
+
# @example (with 'block' action) only allow U.S. users to view a video:
|
49
|
+
# excluded_territories #=> ['us']
|
50
|
+
def excluded_territories
|
51
|
+
territories_type == 'exclude' ? territories : []
|
52
|
+
end
|
53
|
+
|
54
|
+
# @return [Array<Hash<Symbol, Float>>] the intervals of time the user-
|
55
|
+
# or partner-uploaded content needs to match a reference file for the
|
56
|
+
# rule to apply. :low is the minimum (inclusive) allowed value and
|
57
|
+
# :high is the maximum (inclusive) allowed value for the rule to apply.
|
58
|
+
# @example videos that match the reference for 20 to 30 seconds:
|
59
|
+
# match_duration #= [{low: 20.0, high: 30.0}]
|
60
|
+
def match_duration
|
61
|
+
@match_duration ||= match_duration_list.map{|r| low_and_high r}
|
62
|
+
end
|
63
|
+
|
64
|
+
# @return [Array<Hash<Symbol, Float>>] the intervals of percentages the
|
65
|
+
# user- or partner-uploaded content needs to match a reference file for
|
66
|
+
# the rule to apply. :low is the minimum (inclusive) allowed value and
|
67
|
+
# :high is the maximum (inclusive) allowed value for the rule to apply.
|
68
|
+
# @example videos that match the reference for 40%~50% of their duration:
|
69
|
+
# match_percent #= [{low: 40.0, high: 50.0}]
|
70
|
+
def match_percent
|
71
|
+
@match_percent ||= match_percent_list.map{|r| low_and_high r}
|
72
|
+
end
|
73
|
+
|
74
|
+
# @return [Array<Hash<Symbol, Float>>] the intervals of duration that the
|
75
|
+
# reference must have for the rule to apply. :low is the minimum
|
76
|
+
# (inclusive) allowed value, :high is the maximum (inclusive) allowed
|
77
|
+
# value for the rule to apply.
|
78
|
+
# @example references that are between 20 and 30 seconds:
|
79
|
+
# reference_duration #= [{low: 20.0, high: 30.0}]
|
80
|
+
def reference_duration
|
81
|
+
@reference_duration ||= reference_duration_list.map{|r| low_and_high r}
|
82
|
+
end
|
83
|
+
|
84
|
+
# @return [Array<Hash<Symbol, Float>>] the intervals of percentages the
|
85
|
+
# reference file needs to match the user- or partner-uploaded content
|
86
|
+
# for the rule to apply. :low is the minimum (inclusive) allowed value,
|
87
|
+
# :high is the maximum (inclusive) allowed value for the rule to apply.
|
88
|
+
# @example videos that match either 0%~10% or 40%~50% of a reference:
|
89
|
+
# reference_percent #= [{low: 0.0, high: 10.0}, {low: 40.0, high: 50.0}]
|
90
|
+
def reference_percent
|
91
|
+
@reference_percent ||= reference_percent_list.map{|r| low_and_high r}
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def conditions
|
97
|
+
@conditions ||= @data.fetch 'conditions', {}
|
98
|
+
end
|
99
|
+
|
100
|
+
def territories_object
|
101
|
+
@territories_object ||= conditions.fetch 'requiredTerritories', {}
|
102
|
+
end
|
103
|
+
|
104
|
+
def territories_type
|
105
|
+
@territories_type ||= territories_object['type']
|
106
|
+
end
|
107
|
+
|
108
|
+
def territories
|
109
|
+
@territories ||= territories_object['territories']
|
110
|
+
end
|
111
|
+
|
112
|
+
def match_duration_list
|
113
|
+
@match_duration_list ||= conditions.fetch 'matchDuration', []
|
114
|
+
end
|
115
|
+
|
116
|
+
def match_percent_list
|
117
|
+
@match_percent_list ||= conditions.fetch 'matchPercent', []
|
118
|
+
end
|
119
|
+
|
120
|
+
def reference_duration_list
|
121
|
+
@reference_duration_list ||= conditions.fetch 'referenceDuration', []
|
122
|
+
end
|
123
|
+
|
124
|
+
def reference_percent_list
|
125
|
+
@reference_percent_list ||= conditions.fetch 'referencePercent', []
|
126
|
+
end
|
127
|
+
|
128
|
+
def low_and_high(range)
|
129
|
+
{low: range['low'], high: range['high']}
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
data/lib/yt/version.rb
CHANGED
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'yt/models/policy_rule'
|
3
|
+
|
4
|
+
describe Yt::PolicyRule do
|
5
|
+
subject(:policy_rule) { Yt::PolicyRule.new data: data }
|
6
|
+
|
7
|
+
describe '#action' do
|
8
|
+
context 'given fetching a policy rule returns an action' do
|
9
|
+
let(:data) { {"action"=>"takedown"} }
|
10
|
+
it { expect(policy_rule.action).to eq 'takedown' }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#subaction' do
|
15
|
+
context 'given fetching a policy rule returns a subaction' do
|
16
|
+
let(:data) { {"subaction"=>"review"} }
|
17
|
+
it { expect(policy_rule.subaction).to eq 'review' }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#included_territories' do
|
22
|
+
context 'given fetching a policy rule returns included territories' do
|
23
|
+
let(:data) { {"conditions"=>{"requiredTerritories"=>{"type"=>"include", "territories"=>["US", "CA"]}}} }
|
24
|
+
let(:data) { {"conditions"=>{"requiredTerritories"=>{"type"=>"include", "territories"=>["US", "CA"]}}} }
|
25
|
+
it { expect(policy_rule.included_territories).to eq %w(US CA) }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#excluded_territories' do
|
30
|
+
context 'given fetching a policy rule returns excluded territories' do
|
31
|
+
let(:data) { {"conditions"=>{"requiredTerritories"=>{"type"=>"exclude", "territories"=>["US", "CA"]}}} }
|
32
|
+
it { expect(policy_rule.excluded_territories).to eq %w(US CA) }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#match_duration' do
|
37
|
+
context 'given fetching a policy rule returns a match duration list' do
|
38
|
+
let(:data) { {"conditions"=>{"matchDuration"=>[{"high"=>60.0}]}} }
|
39
|
+
it { expect(policy_rule.match_duration).to match_array [{low: nil, high: 60.0}] }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '#match_percent' do
|
44
|
+
context 'given fetching a policy rule returns a match percent list' do
|
45
|
+
let(:data) { {"conditions"=>{"matchPercent"=>[{"high"=>60.0}]}} }
|
46
|
+
it { expect(policy_rule.match_percent).to match_array [{low: nil, high: 60.0}] }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '#reference_duration' do
|
51
|
+
context 'given fetching a policy rule returns a reference duration list' do
|
52
|
+
let(:data) { {"conditions"=>{"referenceDuration"=>[{"low"=>60.0, "high"=>600.0}, {"low"=>20.0, "high"=>30.0}]}} }
|
53
|
+
it { expect(policy_rule.reference_duration).to match_array [{low: 60.0, high: 600.0}, {low: 20.0, high: 30.0}] }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '#reference_percent' do
|
58
|
+
context 'given fetching a policy rule returns a reference percent list' do
|
59
|
+
let(:data) { {"conditions"=>{"referencePercent"=>[{"low"=>60.0, "high"=>600.0}, {"low"=>20.0, "high"=>30.0}]}} }
|
60
|
+
it { expect(policy_rule.reference_percent).to match_array [{low: 60.0, high: 600.0}, {low: 20.0, high: 30.0}] }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'yt/models/policy'
|
3
|
+
|
4
|
+
describe Yt::Policy do
|
5
|
+
subject(:policy) { Yt::Policy.new data: data }
|
6
|
+
|
7
|
+
describe '#id' do
|
8
|
+
context 'given fetching a policy returns an id' do
|
9
|
+
let(:data) { {"id"=>"S123456789"} }
|
10
|
+
it { expect(policy.id).to eq 'S123456789' }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#name' do
|
15
|
+
context 'given fetching a policy returns a name' do
|
16
|
+
let(:data) { {"name"=>"Block in all countries"} }
|
17
|
+
it { expect(policy.name).to eq 'Block in all countries' }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#description' do
|
22
|
+
context 'given fetching a policy returns a description' do
|
23
|
+
let(:data) { {"description"=>"Block videos in every country"} }
|
24
|
+
it { expect(policy.description).to eq 'Block videos in every country' }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#time_updated' do
|
29
|
+
context 'given fetching a policy returns a timeUpdated' do
|
30
|
+
let(:data) { {"timeUpdated"=>"1970-01-16T20:33:03.675Z"} }
|
31
|
+
it { expect(policy.time_updated.year).to be 1970 }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#rules' do
|
36
|
+
context 'given fetching a policy returns rules' do
|
37
|
+
let(:data) { {"rules"=>[{"action"=>"track"},{"action"=>"track"}]} }
|
38
|
+
it { expect(policy.rules.size).to be 2 }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -113,4 +113,30 @@ describe Yt::ContentOwner, :partner do
|
|
113
113
|
end
|
114
114
|
end
|
115
115
|
end
|
116
|
+
|
117
|
+
describe '.policies' do
|
118
|
+
describe 'given the content owner has policies' do
|
119
|
+
let(:policy) { $content_owner.policies.first }
|
120
|
+
let(:rule) { policy.rules.first }
|
121
|
+
|
122
|
+
it 'returns valid metadata' do
|
123
|
+
expect(policy.id).to be_a String
|
124
|
+
expect(policy.name).to be_a String
|
125
|
+
expect(policy.time_updated).to be_a Time
|
126
|
+
expect(rule.action).to be_in Yt::PolicyRule::ACTIONS
|
127
|
+
expect(rule.included_territories).to be_an Array
|
128
|
+
expect(rule.excluded_territories).to be_an Array
|
129
|
+
expect(rule.match_duration).to be_an Array
|
130
|
+
expect(rule.match_percent).to be_an Array
|
131
|
+
expect(rule.reference_duration).to be_an Array
|
132
|
+
expect(rule.reference_percent).to be_an Array
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe '.where(id: policy_id) given an unknown policy ID' do
|
137
|
+
let(:policy) { $content_owner.policies.where(id: policy_id).first }
|
138
|
+
let(:policy_id) { '--not-a-matching-reference-id--' }
|
139
|
+
it { expect(policy).not_to be }
|
140
|
+
end
|
141
|
+
end
|
116
142
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Claudio Baccigalupo
|
@@ -140,6 +140,7 @@ files:
|
|
140
140
|
- lib/yt/collections/partnered_channels.rb
|
141
141
|
- lib/yt/collections/playlist_items.rb
|
142
142
|
- lib/yt/collections/playlists.rb
|
143
|
+
- lib/yt/collections/policies.rb
|
143
144
|
- lib/yt/collections/ratings.rb
|
144
145
|
- lib/yt/collections/references.rb
|
145
146
|
- lib/yt/collections/reports.rb
|
@@ -173,6 +174,8 @@ files:
|
|
173
174
|
- lib/yt/models/id.rb
|
174
175
|
- lib/yt/models/playlist.rb
|
175
176
|
- lib/yt/models/playlist_item.rb
|
177
|
+
- lib/yt/models/policy.rb
|
178
|
+
- lib/yt/models/policy_rule.rb
|
176
179
|
- lib/yt/models/rating.rb
|
177
180
|
- lib/yt/models/reference.rb
|
178
181
|
- lib/yt/models/request.rb
|
@@ -209,6 +212,8 @@ files:
|
|
209
212
|
- spec/models/description_spec.rb
|
210
213
|
- spec/models/playlist_item_spec.rb
|
211
214
|
- spec/models/playlist_spec.rb
|
215
|
+
- spec/models/policy_rule_spec.rb
|
216
|
+
- spec/models/policy_spec.rb
|
212
217
|
- spec/models/rating_spec.rb
|
213
218
|
- spec/models/reference_spec.rb
|
214
219
|
- spec/models/request_spec.rb
|
@@ -291,6 +296,8 @@ test_files:
|
|
291
296
|
- spec/models/description_spec.rb
|
292
297
|
- spec/models/playlist_item_spec.rb
|
293
298
|
- spec/models/playlist_spec.rb
|
299
|
+
- spec/models/policy_rule_spec.rb
|
300
|
+
- spec/models/policy_spec.rb
|
294
301
|
- spec/models/rating_spec.rb
|
295
302
|
- spec/models/reference_spec.rb
|
296
303
|
- spec/models/request_spec.rb
|