yt 0.11.1 → 0.11.2

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -9,8 +9,8 @@ module Yt
9
9
  class References < Base
10
10
  def insert(attributes = {})
11
11
  underscore_keys! attributes
12
- body = {contentType: attributes[:content_type] }
13
- params = {claimId: attributes[:claim_id], onBehalfOfContentOwner: @auth.owner_name}
12
+ body = {content_type: attributes[:content_type] }
13
+ params = {claim_id: attributes[:claim_id], on_behalf_of_content_owner: @auth.owner_name}
14
14
  do_insert(params: params, body: body)
15
15
  end
16
16
 
@@ -41,16 +41,6 @@ module Yt
41
41
  def references_params
42
42
  apply_where_params! on_behalf_of_content_owner: @parent.owner_name
43
43
  end
44
-
45
- # If we dropped support for ActiveSupport 3, then we could simply
46
- # invoke transform_keys!{|key| key.to_s.underscore.to_sym}
47
- def underscore_keys!(hash)
48
- hash.dup.each_key{|key| hash[underscore key] = hash.delete key}
49
- end
50
-
51
- def underscore(value)
52
- value.to_s.underscore.to_sym
53
- end
54
44
  end
55
45
  end
56
46
  end
@@ -59,12 +59,6 @@ module Yt
59
59
  (part[:keys] & attributes.keys).any?
60
60
  end
61
61
 
62
- # If we dropped support for ActiveSupport 3, then we could simply
63
- # invoke transform_keys!{|key| key.to_s.underscore.to_sym}
64
- def underscore_keys!(hash)
65
- hash.dup.each_key{|key| hash[underscore key] = hash.delete key}
66
- end
67
-
68
62
  # @return [Hash] the original hash with angle brackets characters in its
69
63
  # values replaced with similar Unicode characters accepted by Youtube.
70
64
  # @see https://support.google.com/youtube/answer/57404?hl=en
@@ -79,10 +73,6 @@ module Yt
79
73
  def camelize(value)
80
74
  value.to_s.camelize(:lower).to_sym
81
75
  end
82
-
83
- def underscore(value)
84
- value.to_s.underscore.to_sym
85
- end
86
76
  end
87
77
  end
88
78
  end
@@ -56,7 +56,7 @@ module Yt
56
56
  # Tells `has_many :videos` that account.videos should return all the
57
57
  # videos *owned by* the account (public, private, unlisted).
58
58
  def videos_params
59
- {forMine: true}
59
+ {for_mine: true}
60
60
  end
61
61
  end
62
62
  end
@@ -0,0 +1,33 @@
1
+ require 'yt/models/base'
2
+
3
+ module Yt
4
+ module Models
5
+ # Encapsulates advertising options of a video, such as the types of ads
6
+ # that can run during the video as well as the times when ads are allowed
7
+ # to run during the video.
8
+ # @see https://developers.google.com/youtube/partner/docs/v1/videoAdvertisingOptions#resource
9
+ class AdvertisingOptionsSet < Base
10
+ def initialize(options = {})
11
+ @auth = options[:auth]
12
+ @video_id = options[:video_id]
13
+ end
14
+
15
+ def update(attributes = {})
16
+ underscore_keys! attributes
17
+ do_patch body: attributes
18
+ true
19
+ end
20
+
21
+ private
22
+
23
+ # @see https://developers.google.com/youtube/partner/docs/v1/videoAdvertisingOptions/patch
24
+ def patch_params
25
+ super.tap do |params|
26
+ params[:expected_response] = Net::HTTPOK
27
+ params[:path] = "/youtube/partner/v1/videoAdvertisingOptions/#{@video_id}"
28
+ params[:params] = {on_behalf_of_content_owner: @auth.owner_name}
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,100 @@
1
+ require 'yt/models/base'
2
+
3
+ module Yt
4
+ module Models
5
+ # Provides methods to interact with YouTube ContentID assets.
6
+ # @see https://developers.google.com/youtube/partner/docs/v1/assets
7
+ class Asset < Base
8
+ attr_reader :auth
9
+
10
+ def initialize(options = {})
11
+ @data = options[:data]
12
+ @id = options[:id]
13
+ @auth = options[:auth]
14
+ end
15
+
16
+ # @!attribute [r] ownership
17
+ # @return [Yt::Models::Ownership] the asset’s ownership.
18
+ has_one :ownership
19
+ delegate :general_owners, :performance_owners, :synchronization_owners,
20
+ :mechanical_owners, to: :ownership
21
+
22
+ # Soft-deletes the asset.
23
+ # @note YouTube API does not provide a +delete+ method for the Asset
24
+ # resource, but only an +update+ method. Updating the +status+ of a
25
+ # Asset to "inactive" can be considered a soft-deletion.
26
+ # @note Despite what the documentation says, YouTube API never returns
27
+ # the status of an asset, so it’s impossible to update, although the
28
+ # documentation says this should be the case. If YouTube ever fixes
29
+ # the API, then the following code can be uncommented.
30
+ # @return [Boolean] whether the asset is inactive.
31
+ # def delete
32
+ # body = {id: id, status: :inactive}
33
+ # do_update(body: body) {|data| @data = data}
34
+ # inactive?
35
+ # end
36
+
37
+ # @return [String] the ID that YouTube assigns and uses to uniquely
38
+ # identify the asset.
39
+ def id
40
+ @id ||= @data['id']
41
+ end
42
+
43
+ # @return [String] the asset’s type. This value determines the metadata
44
+ # fields that you can set for the asset. In addition, certain API
45
+ # functions may only be supported for specific types of assets. For
46
+ # example, composition assets may have more complex ownership data than
47
+ # other types of assets.
48
+ # Valid values for this property are: art_track_video, composition,
49
+ # episode, general, movie, music_video, season, show, sound_recording,
50
+ # video_game, and web.
51
+ def type
52
+ @type ||= @data['type']
53
+ end
54
+
55
+ # Status
56
+
57
+ STATUSES = %q(active inactive pending)
58
+
59
+ # @return [String] the asset’s status. Valid values are: active,
60
+ # inactive, and pending.
61
+ # @note Despite what the documentation says, YouTube API never returns
62
+ # the status of an asset, so it’s impossible to update, although the
63
+ # documentation says this should be the case. If YouTube ever fixes
64
+ # the API, then the following code can be uncommented.
65
+ # def status
66
+ # @status ||= @data["status"]
67
+ # end
68
+ #
69
+ # # @return [Boolean] whether the asset is active.
70
+ # def active?
71
+ # status == 'active'
72
+ # end
73
+ #
74
+ # # @return [Boolean] whether the asset is inactive.
75
+ # def inactive?
76
+ # status == 'inactive'
77
+ # end
78
+ #
79
+ # # @return [Boolean] whether the asset is pending.
80
+ # def pending?
81
+ # status == 'pending'
82
+ # end
83
+
84
+ private
85
+
86
+ # @see https://developers.google.com/youtube/partner/docs/v1/assets/update
87
+ # @note Despite what the documentation says, YouTube API never returns
88
+ # the status of an asset, so it’s impossible to update, although the
89
+ # documentation says this should be the case. If YouTube ever fixes
90
+ # the API, then the following code can be uncommented.
91
+ # def update_params
92
+ # super.tap do |params|
93
+ # params[:expected_response] = Net::HTTPOK
94
+ # params[:path] = "/youtube/partner/v1/assets/#{id}"
95
+ # params[:params] = {on_behalf_of_content_owner: @auth.owner_name}
96
+ # end
97
+ # end
98
+ end
99
+ end
100
+ end
@@ -124,7 +124,7 @@ module Yt
124
124
  # Tells `has_many :videos` that channel.videos should return all the
125
125
  # videos publicly available on the channel.
126
126
  def videos_params
127
- {channelId: id}
127
+ {channel_id: id}
128
128
  end
129
129
 
130
130
  # @private
@@ -7,6 +7,19 @@ module Yt
7
7
  class Claim < Base
8
8
  def initialize(options = {})
9
9
  @data = options[:data]
10
+ @id = options[:id]
11
+ @auth = options[:auth]
12
+ end
13
+
14
+ # Soft-deletes the claim.
15
+ # @note YouTube API does not provide a +delete+ method for the Asset
16
+ # resource, but only an +update+ method. Updating the +status+ of a
17
+ # Asset to "inactive" can be considered a soft-deletion.
18
+ # @return [Boolean] whether the claim is inactive.
19
+ def delete
20
+ body = {status: :inactive}
21
+ do_patch(body: body) {|data| @data = data}
22
+ inactive?
10
23
  end
11
24
 
12
25
  # @return [String] the ID that YouTube assigns and uses to uniquely
@@ -137,6 +150,15 @@ module Yt
137
150
  def match_reference_id
138
151
  @match_reference_id ||= @data.fetch('matchInfo', {})['referenceId']
139
152
  end
153
+
154
+ # @see https://developers.google.com/youtube/partner/docs/v1/claims/update
155
+ def patch_params
156
+ super.tap do |params|
157
+ params[:expected_response] = Net::HTTPOK
158
+ params[:path] = "/youtube/partner/v1/claims/#{id}"
159
+ params[:params] = {on_behalf_of_content_owner: @auth.owner_name}
160
+ end
161
+ end
140
162
  end
141
163
  end
142
164
  end
@@ -8,19 +8,23 @@ module Yt
8
8
  class ContentOwner < Account
9
9
 
10
10
  # @!attribute [r] partnered_channels
11
- # @return [Yt::Collection::PartneredChannels] the channels managed by the CMS account.
11
+ # @return [Yt::Collections::PartneredChannels] the channels managed by the CMS account.
12
12
  has_many :partnered_channels
13
13
 
14
14
  # @!attribute [r] claims
15
- # @return [Yt::Collection::Claims] the claims administered by the content owner.
15
+ # @return [Yt::Collections::Claims] the claims administered by the content owner.
16
16
  has_many :claims
17
17
 
18
+ # @!attribute [r] assets
19
+ # @return [Yt::Collection::Assets] the assets administered by the content owner.
20
+ has_many :assets
21
+
18
22
  # @!attribute [r] references
19
- # @return [Yt::Collection::References] the references administered by the content owner.
23
+ # @return [Yt::Collections::References] the references administered by the content owner.
20
24
  has_many :references
21
25
 
22
26
  # @!attribute [r] policies
23
- # @return [Yt::Collection::Policies] the policies saved by the content owner.
27
+ # @return [Yt::Collections::Policies] the policies saved by the content owner.
24
28
  has_many :policies
25
29
 
26
30
  def initialize(options = {})
@@ -31,6 +35,14 @@ module Yt
31
35
  def create_reference(params = {})
32
36
  references.insert params
33
37
  end
38
+
39
+ def create_asset(params = {})
40
+ assets.insert params
41
+ end
42
+
43
+ def create_claim(params = {})
44
+ claims.insert params
45
+ end
34
46
  end
35
47
  end
36
48
  end
@@ -13,7 +13,7 @@ module Yt
13
13
 
14
14
  def update(attributes = {})
15
15
  underscore_keys! attributes
16
- do_patch body: {policyId: attributes[:policy_id]}
16
+ do_patch body: attributes.slice(:policy_id)
17
17
  true
18
18
  end
19
19
 
@@ -25,20 +25,10 @@ module Yt
25
25
  def patch_params
26
26
  super.tap do |params|
27
27
  params[:path] = "/youtube/partner/v1/assets/#{@asset_id}/matchPolicy"
28
- params[:params] = {onBehalfOfContentOwner: @auth.owner_name}
28
+ params[:params] = {on_behalf_of_content_owner: @auth.owner_name}
29
29
  params[:expected_response] = Net::HTTPOK
30
30
  end
31
31
  end
32
-
33
- # If we dropped support for ActiveSupport 3, then we could simply
34
- # invoke transform_keys!{|key| key.to_s.underscore.to_sym}
35
- def underscore_keys!(hash)
36
- hash.dup.each_key{|key| hash[underscore key] = hash.delete key}
37
- end
38
-
39
- def underscore(value)
40
- value.to_s.underscore.to_sym
41
- end
42
32
  end
43
33
  end
44
34
  end
@@ -0,0 +1,70 @@
1
+ require 'yt/models/base'
2
+ require 'yt/models/right_owner'
3
+
4
+ module Yt
5
+ module Models
6
+ # Provides methods to interact with YouTube ContentID asset ownership,
7
+ # which provide ownership information for the specified asset.
8
+ # @see https://developers.google.com/youtube/partner/docs/v1/ownership
9
+ class Ownership < Base
10
+ def initialize(options = {})
11
+ @data = options[:data] || {}
12
+ @auth = options[:auth]
13
+ @asset_id = options[:asset_id]
14
+ end
15
+
16
+ def update(attributes = {})
17
+ underscore_keys! attributes
18
+ do_update body: attributes
19
+ true
20
+ end
21
+
22
+ # Assigns 100% of the general ownership of the asset to @auth.
23
+ def obtain!
24
+ update general: [{ratio: 100, owner: @auth.owner_name, type: :exclude}]
25
+ end
26
+
27
+ # @return [Array<RightOwner>] a list that identifies the owners of an
28
+ # asset and the territories where each owner has ownership.
29
+ # General asset ownership is used for all types of assets and is the
30
+ # only type of ownership data that can be provided for assets that are
31
+ # not compositions.
32
+ def general_owners
33
+ @general_owners ||= as_owners @data['general']
34
+ end
35
+
36
+ # @return [Array<RightOwner>] a list that identifies owners of the
37
+ # performance rights for a composition asset.
38
+ def performance_owners
39
+ @performance_owners ||= as_owners @data['performance']
40
+ end
41
+
42
+ # @return [Array<RightOwner>] a list that identifies owners of the
43
+ # synchronization rights for a composition asset.
44
+ def synchronization_owners
45
+ @synchronization_owners ||= as_owners @data['synchronization']
46
+ end
47
+
48
+ # @return [Array<RightOwner>] a list that identifies owners of the
49
+ # mechanical rights for a composition asset.
50
+ def mechanical_owners
51
+ @mechanical_owners ||= as_owners @data['mechanical']
52
+ end
53
+
54
+ private
55
+
56
+ # @see https://developers.google.com/youtube/partner/docs/v1/ownership/update
57
+ def update_params
58
+ super.tap do |params|
59
+ params[:expected_response] = Net::HTTPOK
60
+ params[:path] = "/youtube/partner/v1/assets/#{@asset_id}/ownership"
61
+ params[:params] = {on_behalf_of_content_owner: @auth.owner_name}
62
+ end
63
+ end
64
+
65
+ def as_owners(data)
66
+ (data || []).map{|owner_data| Yt::RightOwner.new data: owner_data}
67
+ end
68
+ end
69
+ end
70
+ end
@@ -196,7 +196,7 @@ module Yt
196
196
  super.tap do |params|
197
197
  params[:expected_response] = Net::HTTPOK
198
198
  params[:path] = "/youtube/partner/v1/references/#{id}"
199
- params[:params] = {onBehalfOfContentOwner: @auth.owner_name}
199
+ params[:params] = {on_behalf_of_content_owner: @auth.owner_name}
200
200
  end
201
201
  end
202
202
  end
@@ -15,7 +15,6 @@ module Yt
15
15
  class Request
16
16
  def initialize(options = {})
17
17
  @auth = options[:auth]
18
- @body = options[:body]
19
18
  @file = options[:file]
20
19
  @body_type = options.fetch :body_type, :json
21
20
  @expected_response = options.fetch :expected_response, Net::HTTPSuccess
@@ -24,9 +23,14 @@ module Yt
24
23
  @host = options.fetch :host, google_api_host
25
24
  @method = options.fetch :method, :get
26
25
  @path = options[:path]
27
- @query = options.fetch(:params, {}).to_param
26
+ @body = options[:body]
27
+ camelize_keys! @body if options.fetch(:camelize_body, true)
28
+ params = options.fetch :params, {}
29
+ camelize_keys! params if options.fetch(:camelize_params, true)
30
+ @query = params.to_param
28
31
  end
29
32
 
33
+
30
34
  def run
31
35
  p as_curl if Yt.configuration.developing?
32
36
 
@@ -132,6 +136,13 @@ module Yt
132
136
  end if body
133
137
  end
134
138
 
139
+ def camelize_keys!(object)
140
+ return object unless object.is_a?(Hash)
141
+ object.dup.each_key do |key|
142
+ object[key.to_s.camelize(:lower).to_sym] = object.delete key
143
+ end
144
+ end
145
+
135
146
  # There are two cases to run a request again: YouTube responds with a
136
147
  # random error that can be fixed by waiting for some seconds and running
137
148
  # the exact same query, or the access token needs to be refreshed.
@@ -80,12 +80,6 @@ module Yt
80
80
  part[:required] || (part[:keys] & attributes.keys).any?
81
81
  end
82
82
 
83
- # If we dropped support for ActiveSupport 3, then we could simply
84
- # invoke transform_keys!{|key| key.to_s.underscore.to_sym}
85
- def underscore_keys!(hash)
86
- hash.dup.each_key{|key| hash[underscore key] = hash.delete key}
87
- end
88
-
89
83
  # @return [Hash] the original hash with angle brackets characters in its
90
84
  # values replaced with similar Unicode characters accepted by Youtube.
91
85
  # @see https://support.google.com/youtube/answer/57404?hl=en
@@ -100,10 +94,6 @@ module Yt
100
94
  def camelize(value)
101
95
  value.to_s.camelize(:lower).to_sym
102
96
  end
103
-
104
- def underscore(value)
105
- value.to_s.underscore.to_sym
106
- end
107
97
  end
108
98
  end
109
99
  end