yt 0.11.6 → 0.12.0

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 (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