yt 0.11.6 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +35 -0
  3. data/README.md +13 -2
  4. data/lib/yt/actions/list.rb +11 -1
  5. data/lib/yt/associations/has_attribute.rb +51 -0
  6. data/lib/yt/associations/has_many.rb +0 -15
  7. data/lib/yt/collections/content_owners.rb +0 -4
  8. data/lib/yt/collections/playlist_items.rb +1 -1
  9. data/lib/yt/collections/resources.rb +1 -1
  10. data/lib/yt/collections/subscribed_channels.rb +46 -0
  11. data/lib/yt/collections/subscribers.rb +33 -0
  12. data/lib/yt/collections/subscriptions.rb +0 -23
  13. data/lib/yt/models/account.rb +6 -1
  14. data/lib/yt/models/annotation.rb +4 -10
  15. data/lib/yt/models/asset.rb +3 -10
  16. data/lib/yt/models/base.rb +2 -0
  17. data/lib/yt/models/channel.rb +53 -25
  18. data/lib/yt/models/claim.rb +13 -25
  19. data/lib/yt/models/content_detail.rb +9 -11
  20. data/lib/yt/models/content_owner_detail.rb +2 -8
  21. data/lib/yt/models/device_flow.rb +3 -11
  22. data/lib/yt/models/live_streaming_detail.rb +5 -25
  23. data/lib/yt/models/ownership.rb +8 -8
  24. data/lib/yt/models/playlist.rb +14 -10
  25. data/lib/yt/models/playlist_item.rb +13 -0
  26. data/lib/yt/models/policy.rb +10 -14
  27. data/lib/yt/models/policy_rule.rb +15 -21
  28. data/lib/yt/models/reference.rb +13 -37
  29. data/lib/yt/models/right_owner.rb +6 -17
  30. data/lib/yt/models/snippet.rb +19 -33
  31. data/lib/yt/models/statistics_set.rb +9 -23
  32. data/lib/yt/models/status.rb +20 -25
  33. data/lib/yt/models/subscription.rb +2 -8
  34. data/lib/yt/models/user_info.rb +11 -33
  35. data/lib/yt/version.rb +1 -1
  36. data/spec/collections/subscriptions_spec.rb +0 -7
  37. data/spec/errors/forbidden_spec.rb +10 -0
  38. data/spec/errors/server_error_spec.rb +10 -0
  39. data/spec/models/subscription_spec.rb +0 -9
  40. data/spec/requests/as_account/account_spec.rb +8 -0
  41. data/spec/requests/as_account/channel_spec.rb +40 -6
  42. data/spec/requests/as_account/playlist_item_spec.rb +26 -0
  43. data/spec/requests/as_account/playlist_spec.rb +1 -0
  44. data/spec/requests/as_server_app/channel_spec.rb +9 -0
  45. metadata +9 -2
@@ -16,6 +16,19 @@ module Yt
16
16
  def exists?
17
17
  !@id.nil?
18
18
  end
19
+
20
+ private
21
+
22
+ def resource_id
23
+ {kind: 'youtube#video', videoId: video_id}
24
+ end
25
+
26
+ # @see https://developers.google.com/youtube/v3/docs/playlistItems/update
27
+ def update_parts
28
+ keys = [:position, :playlist_id, :resource_id]
29
+ snippet = {keys: keys, required: true}
30
+ {snippet: snippet}
31
+ end
19
32
  end
20
33
  end
21
34
  end
@@ -14,31 +14,27 @@ module Yt
14
14
 
15
15
  # @return [String] the ID that YouTube assigns and uses to uniquely
16
16
  # identify the policy.
17
- def id
18
- @id ||= @data['id']
19
- end
17
+ has_attribute :id
20
18
 
21
19
  # @return [String] the policy’s name.
22
- def name
23
- @name ||= @data['name']
24
- end
20
+ has_attribute :name
25
21
 
26
22
  # @return [String] the policy’s description.
27
- def description
28
- @name ||= @data['description']
29
- end
23
+ has_attribute :description
30
24
 
31
25
  # @return [String] the time the policy was updated.
32
- def updated_at
33
- @updated_at ||= Time.parse @data['timeUpdated']
26
+ has_attribute :updated_at, type: Time, from: :time_updated
27
+
28
+ # @deprecated Use {#updated_at} instead.
29
+ def time_updated
30
+ updated_at
34
31
  end
35
- alias time_updated updated_at
36
32
 
37
33
  # @return [Array<PolicyRule>] a list of rules that specify the action
38
34
  # that YouTube should take and may optionally specify the conditions
39
35
  # under which that action is enforced.
40
- def rules
41
- @rules ||= @data['rules'].map{|rule| PolicyRule.new data: rule}
36
+ has_attribute :rules do |rules|
37
+ rules.map{|rule| PolicyRule.new data: rule}
42
38
  end
43
39
  end
44
40
  end
@@ -6,7 +6,7 @@ module Yt
6
6
  # Rules that specify the action that YouTube should take and may optionally
7
7
  # specify the conditions under which that action is enforced.
8
8
  # @see https://developers.google.com/youtube/partner/docs/v1/policies
9
- class PolicyRule
9
+ class PolicyRule < Base
10
10
  def initialize(options = {})
11
11
  @data = options[:data]
12
12
  end
@@ -18,16 +18,12 @@ module Yt
18
18
  # YouTube. Valid values for this property are: block, monetize, takedown,
19
19
  # track.
20
20
  # @return [String] the policy that YouTube should enforce.
21
- def action
22
- @action ||= @data['action']
23
- end
21
+ has_attribute :action
24
22
 
25
23
  # @return [Array] A list of additional actions that YouTube should take
26
24
  # if the conditions in the rule are met. Valid values for this property
27
25
  # are: review.
28
- def subaction
29
- @subaction ||= @data['subaction']
30
- end
26
+ has_attribute :subaction
31
27
 
32
28
  # Return the list of territories where the policy applies.
33
29
  # Each territory is an ISO 3166 two-letter country code.
@@ -58,7 +54,7 @@ module Yt
58
54
  # @example videos that match the reference for 20 to 30 seconds:
59
55
  # match_duration #= [{low: 20.0, high: 30.0}]
60
56
  def match_duration
61
- @match_duration ||= match_duration_list.map{|r| low_and_high r}
57
+ match_duration_list.map{|r| low_and_high r}
62
58
  end
63
59
 
64
60
  # @return [Array<Hash<Symbol, Float>>] the intervals of percentages the
@@ -68,7 +64,7 @@ module Yt
68
64
  # @example videos that match the reference for 40%~50% of their duration:
69
65
  # match_percent #= [{low: 40.0, high: 50.0}]
70
66
  def match_percent
71
- @match_percent ||= match_percent_list.map{|r| low_and_high r}
67
+ match_percent_list.map{|r| low_and_high r}
72
68
  end
73
69
 
74
70
  # @return [Array<Hash<Symbol, Float>>] the intervals of duration that the
@@ -78,7 +74,7 @@ module Yt
78
74
  # @example references that are between 20 and 30 seconds:
79
75
  # reference_duration #= [{low: 20.0, high: 30.0}]
80
76
  def reference_duration
81
- @reference_duration ||= reference_duration_list.map{|r| low_and_high r}
77
+ reference_duration_list.map{|r| low_and_high r}
82
78
  end
83
79
 
84
80
  # @return [Array<Hash<Symbol, Float>>] the intervals of percentages the
@@ -88,41 +84,39 @@ module Yt
88
84
  # @example videos that match either 0%~10% or 40%~50% of a reference:
89
85
  # reference_percent #= [{low: 0.0, high: 10.0}, {low: 40.0, high: 50.0}]
90
86
  def reference_percent
91
- @reference_percent ||= reference_percent_list.map{|r| low_and_high r}
87
+ reference_percent_list.map{|r| low_and_high r}
92
88
  end
93
89
 
94
90
  private
95
91
 
96
- def conditions
97
- @conditions ||= @data.fetch 'conditions', {}
98
- end
92
+ has_attribute :conditions, default: {}
99
93
 
100
94
  def territories_object
101
- @territories_object ||= conditions.fetch 'requiredTerritories', {}
95
+ conditions.fetch 'requiredTerritories', {}
102
96
  end
103
97
 
104
98
  def territories_type
105
- @territories_type ||= territories_object['type']
99
+ territories_object['type']
106
100
  end
107
101
 
108
102
  def territories
109
- @territories ||= territories_object['territories']
103
+ territories_object['territories']
110
104
  end
111
105
 
112
106
  def match_duration_list
113
- @match_duration_list ||= conditions.fetch 'matchDuration', []
107
+ conditions.fetch 'matchDuration', []
114
108
  end
115
109
 
116
110
  def match_percent_list
117
- @match_percent_list ||= conditions.fetch 'matchPercent', []
111
+ conditions.fetch 'matchPercent', []
118
112
  end
119
113
 
120
114
  def reference_duration_list
121
- @reference_duration_list ||= conditions.fetch 'referenceDuration', []
115
+ conditions.fetch 'referenceDuration', []
122
116
  end
123
117
 
124
118
  def reference_percent_list
125
- @reference_percent_list ||= conditions.fetch 'referencePercent', []
119
+ conditions.fetch 'referencePercent', []
126
120
  end
127
121
 
128
122
  def low_and_high(range)
@@ -26,52 +26,38 @@ module Yt
26
26
 
27
27
  # @return [String] the ID that YouTube assigns and uses to uniquely
28
28
  # identify the reference.
29
- def id
30
- @id ||= @data['id']
31
- end
29
+ has_attribute :id
32
30
 
33
31
  # @return [String] the ID that uniquely identifies the asset that the
34
32
  # reference is associated with.
35
- def asset_id
36
- @asset_id ||= @data["assetId"]
37
- end
33
+ has_attribute :asset_id
38
34
 
39
35
  # @return [Float] The length of the reference in seconds
40
- def length
41
- @length ||= @data["length"]
42
- end
36
+ has_attribute :length
43
37
 
44
38
  # @return [String] the ID of the source video. This field is only present
45
39
  # if the reference was created by associating an asset with an existing
46
40
  # YouTube video that was uploaded to a YouTube channel linked to your
47
41
  # CMS account.
48
- def video_id
49
- @video_id ||= @data["videoId"]
50
- end
42
+ has_attribute :video_id
51
43
 
52
44
  # @return [String] the claim ID that represents the resulting association
53
45
  # between the asset and the video. This field is only present if the
54
46
  # reference was created by associating an asset with an existing
55
47
  # YouTube video that was uploaded to a YouTube channel linked to your
56
48
  # CMS account.
57
- def claim_id
58
- @claim_id ||= @data["claimId"]
59
- end
49
+ has_attribute :claim_id
60
50
 
61
51
  # @return [boolean] whether or not the reference content is included in
62
52
  # YouTube's AudioSwap program. Set this field's value to true to
63
53
  # indicate that the reference content should be included in YouTube's
64
54
  # AudioSwap program.
65
- def audioswap_enabled?
66
- @audioswap_enabled ||= @data["audioswapEnabled"]
67
- end
55
+ has_attribute :audioswap_enabled?, from: :audioswap_enabled
68
56
 
69
57
  # @return [boolean] should the reference be used to generate claims. Set
70
58
  # this value to true to indicate that the reference should not be used
71
59
  # to generate claims. This field is only used on AudioSwap references.
72
- def ignore_fp_match?
73
- @ignore_fp_match ||= @data["ignoreFpMatch"]
74
- end
60
+ has_attribute :ignore_fp_match?, from: :ignore_fp_match
75
61
 
76
62
  # @return [Boolean] the urgent status of the reference file.
77
63
  # Set this value to true to indicate that YouTube should prioritize
@@ -81,23 +67,17 @@ module Yt
81
67
  # videos that require time-sensitive processing.
82
68
  # The sooner YouTube completes Content ID processing for a video, the
83
69
  # sooner YouTube can match user-uploaded videos to that video.
84
- def urgent?
85
- @urgent ||= @data["urgent"]
86
- end
70
+ has_attribute :urgent?, from: :urgent
87
71
 
88
72
  # @return [String] An explanation of how a reference entered its current
89
73
  # state. This value is only present if the reference’s status is either
90
74
  # inactive or deleted.
91
- def status_reason
92
- @status_reason ||= @data["statusReason"]
93
- end
75
+ has_attribute :status_reason
94
76
 
95
77
  # @return [String] The ID that uniquely identifies the reference that
96
78
  # this reference duplicates. This field is only present if the
97
79
  # reference’s status is duplicate_on_hold.
98
- def duplicate_leader
99
- @duplicate_leader ||= @data["duplicateLeader"]
100
- end
80
+ has_attribute :duplicate_leader
101
81
 
102
82
  # Status
103
83
 
@@ -108,10 +88,8 @@ module Yt
108
88
  # @return [String] the reference’s status. Valid values are: activating,
109
89
  # active, checking, computing_fingerprint, deleted, duplicate_on_hold,
110
90
  # inactive, live_streaming_processing, and urgent_reference_processing.
111
- def status
112
- @status ||= @data["status"]
113
- end
114
-
91
+ has_attribute :status
92
+
115
93
  # @return [Boolean] whether the reference is pending.
116
94
  def activating?
117
95
  status == 'activating'
@@ -167,9 +145,7 @@ module Yt
167
145
  # @return [String] whether the reference covers the audio, video, or
168
146
  # audiovisual portion of the claimed content. Valid values are: audio,
169
147
  # audiovisual, video.
170
- def content_type
171
- @content_type ||= @data["contentType"]
172
- end
148
+ has_attribute :content_type
173
149
 
174
150
  # @return [Boolean] whether the reference covers the audio of the
175
151
  # content.
@@ -4,7 +4,7 @@ module Yt
4
4
  module Models
5
5
  # Encapsulates information about the various types of owners of an asset.
6
6
  # @see https://developers.google.com/youtube/partner/docs/v1/ownership#resource
7
- class RightOwner
7
+ class RightOwner < Base
8
8
  def initialize(options = {})
9
9
  @data = options[:data]
10
10
  end
@@ -15,22 +15,16 @@ module Yt
15
15
  # values are 100, which indicates that the owner completely owns the
16
16
  # asset in the specified territories, and 0, which indicates that you
17
17
  # are removing ownership of the asset in the specified territories.
18
- def ratio
19
- @ratio ||= @data['ratio'].to_f
20
- end
18
+ has_attribute :ratio, type: Float
21
19
 
22
20
  # @return [String] the name of the asset’s owner or rights administrator.
23
- def owner
24
- @owner ||= @data['owner']
25
- end
21
+ has_attribute :owner
26
22
 
27
23
  # @return [String] if the asset is a composition asset and the asset
28
24
  # owner is not known to have a formal relationship established with
29
25
  # YouTube, the name of the asset’s publisher or rights administrator.
30
26
  # @return [nil] otherwise.
31
- def publisher
32
- @publisher ||= @data['publisher']
33
- end
27
+ has_attribute :publisher
34
28
 
35
29
  # Return the list of territories where the owner owns the asset.
36
30
  # Each territory is an ISO 3166 two-letter country code.
@@ -57,13 +51,8 @@ module Yt
57
51
 
58
52
  private
59
53
 
60
- def type
61
- @type ||= @data['type']
62
- end
63
-
64
- def territories
65
- @territories ||= @data.fetch 'territories', []
66
- end
54
+ has_attribute :type
55
+ has_attribute :territories, default: []
67
56
  end
68
57
  end
69
58
  end
@@ -11,7 +11,7 @@ module Yt
11
11
  # @see https://developers.google.com/youtube/v3/docs/videos#resource
12
12
  # @see https://developers.google.com/youtube/v3/docs/playlists#resource
13
13
  # @see https://developers.google.com/youtube/v3/docs/playlistItems#resource
14
- class Snippet
14
+ class Snippet < Base
15
15
  def initialize(options = {})
16
16
  @data = options[:data]
17
17
  @auth = options[:auth]
@@ -23,9 +23,7 @@ module Yt
23
23
  # @return [String] if the resource is a video, the video’s title. Has a
24
24
  # maximum of 100 characters and may contain all valid UTF-8 characters
25
25
  # except < and >.
26
- def title
27
- @title ||= @data.fetch 'title', ''
28
- end
26
+ has_attribute :title, default: ''
29
27
 
30
28
  # @return [Yt::Models::Description] if the resource is a channel, the
31
29
  # channel’s description. Has a maximum of 1000 characters.
@@ -36,8 +34,8 @@ module Yt
36
34
  # @return [Yt::Models::Description] if the resource is a video, the
37
35
  # video’s description. Has a maximum of 5000 bytes and may contain all
38
36
  # valid UTF-8 characters except < and >.
39
- def description
40
- @description ||= Description.new @data.fetch('description', '')
37
+ has_attribute :description, default: '' do |description_text|
38
+ Description.new description_text
41
39
  end
42
40
 
43
41
  # @return [Time] if the resource is a channel, the date and time that the
@@ -48,9 +46,7 @@ module Yt
48
46
  # that the item was added to the playlist.
49
47
  # @return [Time] if the resource is a video, the date and time that the
50
48
  # video was published.
51
- def published_at
52
- @published_at ||= Time.parse @data['publishedAt']
53
- end
49
+ has_attribute :published_at, type: Time
54
50
 
55
51
  # @param [Symbol, String] size The size of the thumbnail to retrieve.
56
52
  # @return [String] if the resource is a channel and +size+ is +default+,
@@ -67,8 +63,7 @@ module Yt
67
63
  # Video and +size+ is +high+, the URL of an 480x360px image.
68
64
  # @return [nil] if the +size+ is not +default+, +medium+ or +high+.
69
65
  def thumbnail_url(size = :default)
70
- @thumbnails ||= @data.fetch 'thumbnails', {}
71
- @thumbnails.fetch(size.to_s, {})['url']
66
+ thumbnails.fetch(size.to_s, {})['url']
72
67
  end
73
68
 
74
69
  # @return [String] if the resource is a playlist, the ID that YouTube
@@ -78,9 +73,7 @@ module Yt
78
73
  # @return [String] if the resource is a video, the ID that YouTube uses
79
74
  # to uniquely identify the channel that the video was uploaded to.
80
75
  # @return [nil] if the resource is a channel.
81
- def channel_id
82
- @channel_id ||= @data['channelId']
83
- end
76
+ has_attribute :channel_id
84
77
 
85
78
  # @return [String] if the resource is a playlist, the title of the
86
79
  # channel that the playlist belongs to.
@@ -89,9 +82,7 @@ module Yt
89
82
  # @return [String] if the resource is a video, the title of the channel
90
83
  # that the video was uploaded to.
91
84
  # @return [nil] if the resource is a channel.
92
- def channel_title
93
- @channel_title ||= @data['channelTitle']
94
- end
85
+ has_attribute :channel_title
95
86
 
96
87
  # @return [Array<Yt::Models::Tag>] if the resource is a channel, an
97
88
  # empty array.
@@ -101,9 +92,7 @@ module Yt
101
92
  # an empty array.
102
93
  # @return [Array<Yt::Models::Tag>] if the resource is a video, the list
103
94
  # of keyword tags associated with the video.
104
- def tags
105
- @tags ||= @data.fetch 'tags', []
106
- end
95
+ has_attribute :tags, default: []
107
96
 
108
97
  # @return [String] if the resource is a video, the YouTube video
109
98
  # category associated with the video.
@@ -111,9 +100,7 @@ module Yt
111
100
  # @return [nil] if the resource is a playlist.
112
101
  # @return [nil] if the resource is a playlist item.
113
102
  # @see https://developers.google.com/youtube/v3/docs/videoCategories/list
114
- def category_id
115
- @category_id ||= @data['categoryId']
116
- end
103
+ has_attribute :category_id
117
104
 
118
105
  BROADCAST_TYPES = %q(live none upcoming)
119
106
 
@@ -122,18 +109,14 @@ module Yt
122
109
  # @return [nil] if the resource is a channel.
123
110
  # @return [nil] if the resource is a playlist.
124
111
  # @return [nil] if the resource is a playlist item.
125
- def live_broadcast_content
126
- @live_broadcast_content ||= @data['liveBroadcastContent']
127
- end
112
+ has_attribute :live_broadcast_content
128
113
 
129
114
  # @return [String] if the resource is a playlist item, the ID that
130
115
  # YouTube uses to uniquely identify the playlist that the item is in.
131
116
  # @return [nil] if the resource is a channel.
132
117
  # @return [nil] if the resource is a playlist.
133
118
  # @return [nil] if the resource is a video.
134
- def playlist_id
135
- @playlist_id ||= @data['playlistId']
136
- end
119
+ has_attribute :playlist_id
137
120
 
138
121
  # @return [Integer] if the resource is a playlist item, the order in
139
122
  # which the item appears in a playlist. The value is zero-based, so the
@@ -141,9 +124,7 @@ module Yt
141
124
  # @return [nil] if the resource is a channel.
142
125
  # @return [nil] if the resource is a playlist.
143
126
  # @return [nil] if the resource is a video.
144
- def position
145
- @position ||= @data['position'].to_i
146
- end
127
+ has_attribute :position, type: Integer
147
128
 
148
129
  # @return [String] if the resource is a playlist item, the ID of the
149
130
  # video the playlist item represents in the playlist.
@@ -151,7 +132,7 @@ module Yt
151
132
  # @return [nil] if the resource is a playlist.
152
133
  # @return [nil] if the resource is a video.
153
134
  def video_id
154
- @video_id ||= @data.fetch('resourceId', {})['videoId']
135
+ resource_id['videoId']
155
136
  end
156
137
 
157
138
  # @return [Yt::Models::Video] the video the playlist item represents in
@@ -174,6 +155,11 @@ module Yt
174
155
  def includes_tags
175
156
  @includes_tags ||= @data.fetch :includes_tags, true
176
157
  end
158
+
159
+ private
160
+
161
+ has_attribute :thumbnails, default: {}
162
+ has_attribute :resource_id, default: {}
177
163
  end
178
164
  end
179
165
  end