yt 0.11.1 → 0.11.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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +2 -0
  4. data/CHANGELOG.md +31 -33
  5. data/README.md +94 -3
  6. data/lib/yt.rb +1 -0
  7. data/lib/yt/actions/base.rb +19 -0
  8. data/lib/yt/actions/insert.rb +2 -0
  9. data/lib/yt/actions/list.rb +0 -7
  10. data/lib/yt/actions/modify.rb +2 -0
  11. data/lib/yt/collections/assets.rb +32 -0
  12. data/lib/yt/collections/authentications.rb +1 -0
  13. data/lib/yt/collections/claims.rb +16 -1
  14. data/lib/yt/collections/ownerships.rb +34 -0
  15. data/lib/yt/collections/references.rb +2 -12
  16. data/lib/yt/collections/resources.rb +0 -10
  17. data/lib/yt/models/account.rb +1 -1
  18. data/lib/yt/models/advertising_options_set.rb +33 -0
  19. data/lib/yt/models/asset.rb +100 -0
  20. data/lib/yt/models/channel.rb +1 -1
  21. data/lib/yt/models/claim.rb +22 -0
  22. data/lib/yt/models/content_owner.rb +16 -4
  23. data/lib/yt/models/match_policy.rb +2 -12
  24. data/lib/yt/models/ownership.rb +70 -0
  25. data/lib/yt/models/reference.rb +1 -1
  26. data/lib/yt/models/request.rb +13 -2
  27. data/lib/yt/models/resource.rb +0 -10
  28. data/lib/yt/models/resumable_session.rb +1 -0
  29. data/lib/yt/models/right_owner.rb +69 -0
  30. data/lib/yt/version.rb +1 -1
  31. data/spec/models/asset_spec.rb +20 -0
  32. data/spec/models/ownership_spec.rb +59 -0
  33. data/spec/models/right_owner_spec.rb +71 -0
  34. data/spec/requests/as_content_owner/advertising_options_set_spec.rb +15 -0
  35. data/spec/requests/as_content_owner/asset_spec.rb +12 -0
  36. data/spec/requests/as_content_owner/content_owner_spec.rb +37 -2
  37. data/spec/requests/as_content_owner/ownership_spec.rb +19 -0
  38. metadata +21 -3
  39. data/Gemfile.lock +0 -69
@@ -39,6 +39,7 @@ module Yt
39
39
  params[:path] = @uri.path
40
40
  params[:expected_response] = Net::HTTPSuccess
41
41
  params[:headers] = @headers
42
+ params[:camelize_params] = false
42
43
  params[:params] = session_params
43
44
  end
44
45
  end
@@ -0,0 +1,69 @@
1
+ require 'yt/models/description'
2
+
3
+ module Yt
4
+ module Models
5
+ # Encapsulates information about the various types of owners of an asset.
6
+ # @see https://developers.google.com/youtube/partner/docs/v1/ownership#resource
7
+ class RightOwner
8
+ def initialize(options = {})
9
+ @data = options[:data]
10
+ end
11
+
12
+ # @return [Float] the percentage of the asset that the owner controls or
13
+ # administers. For composition assets, the value can be any value
14
+ # between 0 and 100 inclusive. For all other assets, the only valid
15
+ # values are 100, which indicates that the owner completely owns the
16
+ # asset in the specified territories, and 0, which indicates that you
17
+ # are removing ownership of the asset in the specified territories.
18
+ def ratio
19
+ @ratio ||= @data['ratio'].to_f
20
+ end
21
+
22
+ # @return [String] the name of the asset’s owner or rights administrator.
23
+ def owner
24
+ @owner ||= @data['owner']
25
+ end
26
+
27
+ # @return [String] if the asset is a composition asset and the asset
28
+ # owner is not known to have a formal relationship established with
29
+ # YouTube, the name of the asset’s publisher or rights administrator.
30
+ # @return [nil] otherwise.
31
+ def publisher
32
+ @publisher ||= @data['publisher']
33
+ end
34
+
35
+ # Return the list of territories where the owner owns the asset.
36
+ # Each territory is an ISO 3166 two-letter country code.
37
+ # @return [Array<String>] if the ownership lists 'included' territories,
38
+ # the territories where the owner owns the asset.
39
+ # @return [nil] if the ownership does not list 'included' territories,
40
+ def included_territories
41
+ territories if type == 'include'
42
+ end
43
+
44
+ # Return the list of territories where the owner does not own the asset.
45
+ # Each territory is an ISO 3166 two-letter country code.
46
+ # @return [Array<String>] if the ownership lists 'excluded' territories,
47
+ # the territories where the owner does not own the asset.
48
+ # @return [nil] if the ownership does not list 'excluded' territories,
49
+ def excluded_territories
50
+ territories if type == 'exclude'
51
+ end
52
+
53
+ # @return [Boolean] whether the ownership applies to the whole world.
54
+ def everywhere?
55
+ excluded_territories == []
56
+ end
57
+
58
+ private
59
+
60
+ def type
61
+ @type ||= @data['type']
62
+ end
63
+
64
+ def territories
65
+ @territories ||= @data.fetch 'territories', []
66
+ end
67
+ end
68
+ end
69
+ end
@@ -1,3 +1,3 @@
1
1
  module Yt
2
- VERSION = '0.11.1'
2
+ VERSION = '0.11.2'
3
3
  end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+ require 'yt/models/asset'
3
+
4
+ describe Yt::Asset do
5
+ subject(:asset) { Yt::Asset.new data: data }
6
+
7
+ describe '#id' do
8
+ context 'given fetching a asset returns an id' do
9
+ let(:data) { {"id"=>"A123456789012345"} }
10
+ it { expect(asset.id).to eq 'A123456789012345' }
11
+ end
12
+ end
13
+
14
+ describe '#type' do
15
+ context 'given fetching a asset returns an type' do
16
+ let(:data) { {"type"=>"web"} }
17
+ it { expect(asset.type).to eq 'web' }
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+ require 'yt/models/ownership'
3
+
4
+ describe Yt::Ownership do
5
+ subject(:ownership) { Yt::Ownership.new data: data }
6
+ let(:data) { {} }
7
+
8
+ describe '#general_owners' do
9
+ context 'given fetching an ownership returns a general owner' do
10
+ let(:general) { '{"ratio":100.0,"owner":"FullScreen","type":"exclude"}' }
11
+ let(:data) { {"general"=>[general]} }
12
+ it { expect(ownership.general_owners.size).to be 1 }
13
+ it { expect(ownership.general_owners.first).to be_a Yt::RightOwner }
14
+ end
15
+
16
+ context 'given fetching an ownership does not return general owners' do
17
+ it { expect(ownership.general_owners).to be_empty }
18
+ end
19
+ end
20
+
21
+ describe '#performance_owners' do
22
+ context 'given fetching an ownership returns a performance owner' do
23
+ let(:performance) { '{"ratio":100.0,"owner":"FullScreen","type":"exclude"}' }
24
+ let(:data) { {"performance"=>[performance]} }
25
+ it { expect(ownership.performance_owners.size).to be 1 }
26
+ it { expect(ownership.performance_owners.first).to be_a Yt::RightOwner }
27
+ end
28
+
29
+ context 'given fetching an ownership does not return performance owners' do
30
+ it { expect(ownership.performance_owners).to be_empty }
31
+ end
32
+ end
33
+
34
+ describe '#synchronization_owners' do
35
+ context 'given fetching an ownership returns a synchronization owner' do
36
+ let(:synchronization) { '{"ratio":100.0,"owner":"FullScreen","type":"exclude"}' }
37
+ let(:data) { {"synchronization"=>[synchronization]} }
38
+ it { expect(ownership.synchronization_owners.size).to be 1 }
39
+ it { expect(ownership.synchronization_owners.first).to be_a Yt::RightOwner }
40
+ end
41
+
42
+ context 'given fetching an ownership does not return synchronization owners' do
43
+ it { expect(ownership.synchronization_owners).to be_empty }
44
+ end
45
+ end
46
+
47
+ describe '#mechanical_owners' do
48
+ context 'given fetching an ownership returns a mechanical owner' do
49
+ let(:mechanical) { '{"ratio":100.0,"owner":"FullScreen","type":"exclude"}' }
50
+ let(:data) { {"mechanical"=>[mechanical]} }
51
+ it { expect(ownership.mechanical_owners.size).to be 1 }
52
+ it { expect(ownership.mechanical_owners.first).to be_a Yt::RightOwner }
53
+ end
54
+
55
+ context 'given fetching an ownership does not return mechanical owners' do
56
+ it { expect(ownership.mechanical_owners).to be_empty }
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,71 @@
1
+ require 'spec_helper'
2
+ require 'yt/models/right_owner'
3
+
4
+ describe Yt::RightOwner do
5
+ subject(:right_owner) { Yt::RightOwner.new data: data }
6
+ let(:data) { {} }
7
+
8
+ describe '#ratio' do
9
+ context 'given fetching an owner returns a ratio' do
10
+ let(:data) { {"ratio"=>"20.0"} }
11
+ it { expect(right_owner.ratio).to eq 20 }
12
+ end
13
+ end
14
+
15
+ describe '#owner' do
16
+ context 'given fetching an owner returns an owner name' do
17
+ let(:data) { {"owner"=>"FullScreen"} }
18
+ it { expect(right_owner.owner).to eq 'FullScreen' }
19
+ end
20
+ end
21
+
22
+ describe '#owner' do
23
+ context 'given fetching an owner returns a publisher name' do
24
+ let(:data) { {"publisher"=>"Third Party"} }
25
+ it { expect(right_owner.publisher).to eq 'Third Party' }
26
+ end
27
+
28
+ context 'given fetching an owner does not return a publisher name' do
29
+ it { expect(right_owner.publisher).to be_nil }
30
+ end
31
+ end
32
+
33
+ describe '#included_territories' do
34
+ context 'given fetching an owner returns included territories' do
35
+ let(:data) { {"type"=>"include", "territories"=>["US", "CA"]} }
36
+ it { expect(right_owner.included_territories).to eq %w(US CA) }
37
+ end
38
+
39
+ context 'given fetching an owner does not return included territories' do
40
+ it { expect(right_owner.included_territories).to be_nil }
41
+ end
42
+ end
43
+
44
+ describe '#excluded_territories' do
45
+ context 'given fetching an owner returns excluded territories' do
46
+ let(:data) { {"type"=>"exclude", "territories"=>["US", "CA"]} }
47
+ it { expect(right_owner.excluded_territories).to eq %w(US CA) }
48
+ end
49
+
50
+ context 'given fetching an owner does not return excluded territories' do
51
+ it { expect(right_owner.excluded_territories).to be_nil }
52
+ end
53
+ end
54
+
55
+ describe '#everywhere?' do
56
+ context 'given fetching an owner returns zero excluded territories' do
57
+ let(:data) { {"type"=>"exclude", "territories"=>[]} }
58
+ it { expect(right_owner).to be_everywhere }
59
+ end
60
+
61
+ context 'given fetching an owner returns no excluded territories' do
62
+ let(:data) { {"type"=>"exclude"} }
63
+ it { expect(right_owner).to be_everywhere }
64
+ end
65
+
66
+ context 'given fetching an owner returns included territories' do
67
+ let(:data) { {"type"=>"include", "territories"=>[]} }
68
+ it { expect(right_owner).not_to be_everywhere }
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+ require 'yt/models/advertising_options_set'
3
+
4
+ describe Yt::AdvertisingOptionsSet, :partner do
5
+ subject(:advertising_options_set) { Yt::AdvertisingOptionsSet.new video_id: video_id, auth: $content_owner }
6
+
7
+ context 'given a video managed by the authenticated Content Owner' do
8
+ let(:video_id) { ENV['YT_TEST_PARTNER_CLAIMABLE_VIDEO_ID'] }
9
+
10
+ describe 'the advertising options can be updated' do
11
+ let(:params) { {ad_formats: %w(standard_instream long)} }
12
+ it { expect(advertising_options_set.update params).to be true }
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+ require 'yt/models/content_owner'
3
+
4
+ describe Yt::Asset, :partner do
5
+ describe '.ownership' do
6
+ let(:asset) { Yt::Asset.new id: asset_id, auth: $content_owner }
7
+ describe 'given an asset administered by the content owner' do
8
+ let(:asset_id) { ENV['YT_TEST_PARTNER_ASSET_ID'] }
9
+ it { expect(asset.ownership).to be_a Yt::Ownership }
10
+ end
11
+ end
12
+ end
@@ -10,8 +10,31 @@ describe Yt::ContentOwner, :partner do
10
10
  it { expect($content_owner.partnered_channels.size).to be > 0 }
11
11
  end
12
12
 
13
+ describe 'claims' do
14
+ let(:asset_id) { ENV['YT_TEST_PARTNER_ASSET_ID'] }
15
+ let(:policy_id) { ENV['YT_TEST_PARTNER_POLICY_ID'] }
16
+ let(:video_id) { ENV['YT_TEST_PARTNER_CLAIMABLE_VIDEO_ID'] }
17
+ let(:params) { {asset_id: asset_id, video_id: video_id, policy_id: policy_id, content_type: 'audiovisual'} }
18
+
19
+ specify 'can be added' do
20
+ begin
21
+ expect($content_owner.create_claim params).to be_a Yt::Claim
22
+ rescue Yt::Errors::RequestError => e
23
+ # @note: Every time this test runs, a claim is inserted for the same
24
+ # video and asset, but YouTube does not allow this, and responds with
25
+ # an error message like "Video is already claimed. Existing claims
26
+ # on this video: AbCdEFg1234".
27
+ # For the sake of testing, we delete the duplicate and try again.
28
+ raise unless e.reasons.include? 'alreadyClaimed'
29
+ id = e.kind['message'].match(/this video: (.*?)$/) {|re| re[1]}
30
+ Yt::Claim.new(id: id, auth: $content_owner).delete
31
+ expect($content_owner.create_claim params).to be_a Yt::Claim
32
+ end
33
+ end
34
+ end
35
+
13
36
  describe '.claims' do
14
- describe 'given the content owner has policies' do
37
+ describe 'given the content owner has claims' do
15
38
  let(:claim) { $content_owner.claims.first }
16
39
 
17
40
  it 'returns valid metadata' do
@@ -43,7 +66,7 @@ describe Yt::ContentOwner, :partner do
43
66
  let(:count) { $content_owner.claims.where(asset_id: asset_id).count }
44
67
 
45
68
  context 'given the asset ID of a claim administered by the content owner' do
46
- let(:asset_id) { ENV['YT_TEST_PARTNER_ASSET_ID'] }
69
+ let(:asset_id) { ENV['YT_TEST_PARTNER_ASSET_WITH_CLAIM_ID'] }
47
70
  it { expect(count).to be > 0 }
48
71
  end
49
72
 
@@ -175,4 +198,16 @@ describe Yt::ContentOwner, :partner do
175
198
  it { expect(policy).not_to be }
176
199
  end
177
200
  end
201
+
202
+ # @note: The following test works, but YouTube API endpoint to mark
203
+ # an asset as 'invalid' (soft-delete) does not work, and apparently
204
+ # there is no way to update the status of a asset.
205
+ # Therefore, the test is commented out, otherwise a new asset would
206
+ # be created every time the test is run.
207
+ # describe 'assets can be added' do
208
+ # let(:params) { {type: 'web'} }
209
+ # before { @asset = $content_owner.create_asset params }
210
+ # after { @asset.delete } # This does not seem to work
211
+ # it { expect(@asset).to be_a Yt::Asset }
212
+ # end
178
213
  end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+ require 'yt/models/ownership'
3
+
4
+ describe Yt::Ownership, :partner do
5
+ subject(:ownership) { Yt::Ownership.new asset_id: asset_id, auth: $content_owner }
6
+
7
+ context 'given an asset managed by the authenticated Content Owner' do
8
+ let(:asset_id) { ENV['YT_TEST_PARTNER_ASSET_ID'] }
9
+
10
+ describe 'the ownership can be updated' do
11
+ let(:general_owner) { {ratio: 100, owner: 'FullScreen', type: 'include', territories: ['US', 'CA']} }
12
+ it { expect(ownership.update general: [general_owner]).to be true }
13
+ end
14
+
15
+ describe 'the complete ownership can be obtained' do
16
+ it { expect(ownership.obtain!).to be true }
17
+ end
18
+ end
19
+ 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.11.1
4
+ version: 0.11.2
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-08-17 00:00:00.000000000 Z
11
+ date: 2014-08-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -108,7 +108,6 @@ files:
108
108
  - ".yardopts"
109
109
  - CHANGELOG.md
110
110
  - Gemfile
111
- - Gemfile.lock
112
111
  - MIT-LICENSE
113
112
  - README.md
114
113
  - Rakefile
@@ -117,6 +116,7 @@ files:
117
116
  - gemfiles/Gemfile.activesupport-3.x
118
117
  - gemfiles/Gemfile.activesupport-4.x
119
118
  - lib/yt.rb
119
+ - lib/yt/actions/base.rb
120
120
  - lib/yt/actions/delete.rb
121
121
  - lib/yt/actions/delete_all.rb
122
122
  - lib/yt/actions/insert.rb
@@ -130,6 +130,7 @@ files:
130
130
  - lib/yt/associations/has_reports.rb
131
131
  - lib/yt/associations/has_viewer_percentages.rb
132
132
  - lib/yt/collections/annotations.rb
133
+ - lib/yt/collections/assets.rb
133
134
  - lib/yt/collections/authentications.rb
134
135
  - lib/yt/collections/base.rb
135
136
  - lib/yt/collections/channels.rb
@@ -140,6 +141,7 @@ files:
140
141
  - lib/yt/collections/device_flows.rb
141
142
  - lib/yt/collections/ids.rb
142
143
  - lib/yt/collections/live_streaming_details.rb
144
+ - lib/yt/collections/ownerships.rb
143
145
  - lib/yt/collections/partnered_channels.rb
144
146
  - lib/yt/collections/playlist_items.rb
145
147
  - lib/yt/collections/playlists.rb
@@ -164,7 +166,9 @@ files:
164
166
  - lib/yt/errors/server_error.rb
165
167
  - lib/yt/errors/unauthorized.rb
166
168
  - lib/yt/models/account.rb
169
+ - lib/yt/models/advertising_options_set.rb
167
170
  - lib/yt/models/annotation.rb
171
+ - lib/yt/models/asset.rb
168
172
  - lib/yt/models/authentication.rb
169
173
  - lib/yt/models/base.rb
170
174
  - lib/yt/models/channel.rb
@@ -179,6 +183,7 @@ files:
179
183
  - lib/yt/models/iterator.rb
180
184
  - lib/yt/models/live_streaming_detail.rb
181
185
  - lib/yt/models/match_policy.rb
186
+ - lib/yt/models/ownership.rb
182
187
  - lib/yt/models/playlist.rb
183
188
  - lib/yt/models/playlist_item.rb
184
189
  - lib/yt/models/policy.rb
@@ -188,6 +193,7 @@ files:
188
193
  - lib/yt/models/request.rb
189
194
  - lib/yt/models/resource.rb
190
195
  - lib/yt/models/resumable_session.rb
196
+ - lib/yt/models/right_owner.rb
191
197
  - lib/yt/models/snippet.rb
192
198
  - lib/yt/models/statistics_set.rb
193
199
  - lib/yt/models/status.rb
@@ -210,6 +216,7 @@ files:
210
216
  - spec/errors/unauthorized_spec.rb
211
217
  - spec/models/account_spec.rb
212
218
  - spec/models/annotation_spec.rb
219
+ - spec/models/asset_spec.rb
213
220
  - spec/models/channel_spec.rb
214
221
  - spec/models/claim_spec.rb
215
222
  - spec/models/configuration_spec.rb
@@ -217,6 +224,7 @@ files:
217
224
  - spec/models/content_owner_detail_spec.rb
218
225
  - spec/models/description_spec.rb
219
226
  - spec/models/live_streaming_detail_spec.rb
227
+ - spec/models/ownership_spec.rb
220
228
  - spec/models/playlist_item_spec.rb
221
229
  - spec/models/playlist_spec.rb
222
230
  - spec/models/policy_rule_spec.rb
@@ -225,6 +233,7 @@ files:
225
233
  - spec/models/reference_spec.rb
226
234
  - spec/models/request_spec.rb
227
235
  - spec/models/resource_spec.rb
236
+ - spec/models/right_owner_spec.rb
228
237
  - spec/models/snippet_spec.rb
229
238
  - spec/models/statistics_set_spec.rb
230
239
  - spec/models/status_spec.rb
@@ -241,9 +250,12 @@ files:
241
250
  - spec/requests/as_account/video.mp4
242
251
  - spec/requests/as_account/video_spec.rb
243
252
  - spec/requests/as_content_owner/account_spec.rb
253
+ - spec/requests/as_content_owner/advertising_options_set_spec.rb
254
+ - spec/requests/as_content_owner/asset_spec.rb
244
255
  - spec/requests/as_content_owner/channel_spec.rb
245
256
  - spec/requests/as_content_owner/content_owner_spec.rb
246
257
  - spec/requests/as_content_owner/match_policy_spec.rb
258
+ - spec/requests/as_content_owner/ownership_spec.rb
247
259
  - spec/requests/as_content_owner/video_spec.rb
248
260
  - spec/requests/as_server_app/channel_spec.rb
249
261
  - spec/requests/as_server_app/playlist_item_spec.rb
@@ -295,6 +307,7 @@ test_files:
295
307
  - spec/errors/unauthorized_spec.rb
296
308
  - spec/models/account_spec.rb
297
309
  - spec/models/annotation_spec.rb
310
+ - spec/models/asset_spec.rb
298
311
  - spec/models/channel_spec.rb
299
312
  - spec/models/claim_spec.rb
300
313
  - spec/models/configuration_spec.rb
@@ -302,6 +315,7 @@ test_files:
302
315
  - spec/models/content_owner_detail_spec.rb
303
316
  - spec/models/description_spec.rb
304
317
  - spec/models/live_streaming_detail_spec.rb
318
+ - spec/models/ownership_spec.rb
305
319
  - spec/models/playlist_item_spec.rb
306
320
  - spec/models/playlist_spec.rb
307
321
  - spec/models/policy_rule_spec.rb
@@ -310,6 +324,7 @@ test_files:
310
324
  - spec/models/reference_spec.rb
311
325
  - spec/models/request_spec.rb
312
326
  - spec/models/resource_spec.rb
327
+ - spec/models/right_owner_spec.rb
313
328
  - spec/models/snippet_spec.rb
314
329
  - spec/models/statistics_set_spec.rb
315
330
  - spec/models/status_spec.rb
@@ -326,9 +341,12 @@ test_files:
326
341
  - spec/requests/as_account/video.mp4
327
342
  - spec/requests/as_account/video_spec.rb
328
343
  - spec/requests/as_content_owner/account_spec.rb
344
+ - spec/requests/as_content_owner/advertising_options_set_spec.rb
345
+ - spec/requests/as_content_owner/asset_spec.rb
329
346
  - spec/requests/as_content_owner/channel_spec.rb
330
347
  - spec/requests/as_content_owner/content_owner_spec.rb
331
348
  - spec/requests/as_content_owner/match_policy_spec.rb
349
+ - spec/requests/as_content_owner/ownership_spec.rb
332
350
  - spec/requests/as_content_owner/video_spec.rb
333
351
  - spec/requests/as_server_app/channel_spec.rb
334
352
  - spec/requests/as_server_app/playlist_item_spec.rb