yt 0.19.0 → 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 17691684dae81110d7d3ff39e8952823deedc5ac
4
- data.tar.gz: a2438b53994ef551b3525a310db27990695a7f1d
3
+ metadata.gz: 5fe27d147e90b10dde52f153efedf061043b9788
4
+ data.tar.gz: fb07f986240215dba34f01d78762503471cf61a5
5
5
  SHA512:
6
- metadata.gz: 9994436e29b6ef5b5bc3533db28e5f40e2839948076f30cac3794769b4e962cd0dee3dc88e4f1f52641420cd401b62070d8cc8bcf9aae4eabf349b397bfa6408
7
- data.tar.gz: 98f99214f24da915e60247d4192579b93b5579e5e16e83cde009bd017f21c46c5a9a6c22a7451b291c1e4afd69fc130570b29fd419b37b1d96d9148a0469e6fb
6
+ metadata.gz: 0c20df4b1ad2ac9420d3bd183e04892f9cffaaefb3989330794ce8004de7f06c8ce6b52260980582f2cc22e5239871c24aa868156d27bd488465184dd8940da3
7
+ data.tar.gz: b4ec8a79ced4d3e5535a68daa4ae56f593d70e8bd86d20c0c3ef041ca85c88266b77f2f787a7fe1bf08fd04b61b4738ffc02ab3b93d5cce8699ba60c3c7d701b
@@ -6,6 +6,23 @@ For more information about changelogs, check
6
6
  [Keep a Changelog](http://keepachangelog.com) and
7
7
  [Vandamme](http://tech-angels.github.io/vandamme).
8
8
 
9
+ ## 0.20.0 - 2015-04-29
10
+
11
+ **How to upgrade**
12
+
13
+ If your code doesn’t use any of the following constants that were public but
14
+ undocumented, then you are good to go.
15
+
16
+ If it does, then you should redefine those constants in your own app, since
17
+ it’s not Yt’s goal to validate the values posted to YouTube API.
18
+
19
+ * [REMOVAL] Remove `Asset#STATUSES` (was `%q(active inactive pending)`).
20
+ * [REMOVAL] Remove `Claim#STATUSES` (was `%q(active appealed disputed inactive pending potential takedown unknown)`).
21
+ * [REMOVAL] Remove `Claim#CONTENT_TYPES` (was `%q(audio video audiovisual)`).
22
+ * [REMOVAL] Remove `Reference#STATUSES` (was `%q(activating active checking computing_fingerprint deleted duplicate_on_hold inactive live_streaming_processing urgent_reference_processing)`).
23
+ * [REMOVAL] Remove `Reference#CONTENT_TYPES` (was `%q(audio video audiovisual)`).
24
+ * [REMOVAL] Remove `Status#PRIVACY_STATUSES` (was `%q(private public unlisted)`).
25
+
9
26
  ## 0.19.0 - 2015-04-28
10
27
 
11
28
  **How to upgrade**
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.19.0'
44
+ gem 'yt', '~> 0.20.0'
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*)
@@ -1,12 +1,10 @@
1
1
  module Yt
2
2
  module Associations
3
+ # @private
3
4
  # Provides methods to access the analytics reports of a resource.
4
- #
5
- # YouTube resources with reports are: {Yt::Models::Channel channels} and
6
- # {Yt::Models::Channel videos}.
7
5
  module HasReports
8
6
  # @!macro [new] report
9
- # Returns the $1 of the video grouped by the given dimension.
7
+ # Returns the $1 grouped by the given dimension.
10
8
  # @!method $1(options = {})
11
9
  # @param [Hash] options the time-range and dimensions for the $1.
12
10
  # @option options [#to_date] :since The first day of the time-range.
@@ -14,65 +12,103 @@ module Yt
14
12
  # @option options [#to_date] :until The last day of the time-range.
15
13
  # Also aliased as +:to+.
16
14
 
17
- # @!macro [new] daily_report
18
- # @option options [Symbol] :by (:day) The dimension to collect $1 by.
19
- # Accepted values are: +:day+.
20
- # @return [Hash<Date, Float>] if grouped by day, the $1 of the video
15
+ # @!macro [new] report_with_day
16
+ # @return [Hash<Date, Float>] if grouped by day, the $1
21
17
  # for each day in the time-range.
22
- # @example Get the video’s $1 for each day of last week:
23
- # video.$1 since: 2.weeks.ago, until: 1.week.ago, by: :day
18
+ # @example Get the $1 for each day of last week:
19
+ # resource.$1 since: 2.weeks.ago, until: 1.week.ago, by: :day
24
20
  # # => {Wed, 8 May 2014 => 12.0, Thu, 9 May 2014 => 34.2, …}
25
21
  # @macro report
26
22
 
27
- # @!macro [new] views_report
23
+ # @!macro [new] report_by_day
28
24
  # @option options [Symbol] :by (:day) The dimension to collect $1 by.
29
- # Accepted values are: +:day+, +:traffic_source+,
30
- # +:playback_location+,+:embedded_player_location+, +:related_video+.
31
- # @return [Hash<Date, Float>] if grouped by day, the $1 of the video
32
- # for each day in the time-range.
33
- # @example Get the video’s $1 for each day of last week:
34
- # video.$1 since: 2.weeks.ago, until: 1.week.ago, by: :day
35
- # # => {Wed, 8 May 2014 => 12.0, Thu, 9 May 2014 => 34.2, …}
36
- # @return [Hash<Symbol, Float>] if grouped by traffic source, the
37
- # $1 of the video for each traffic source.
38
- # @example Get yesterday’s video’s $1 grouped by traffic source:
39
- # video.$1 from: 1.day.ago, to: 1.day.ago, by: :traffic_source
40
- # # => {advertising: 53.0, channel: 7.0, …}
25
+ # Accepted values are: +:day+.
26
+ # @macro report_with_day
27
+
28
+ # @!macro [new] report_with_video_dimensions
41
29
  # @return [Hash<Symbol, Float>] if grouped by playback location, the
42
- # $1 of the video for each traffic playback location.
43
- # @example Get yesterday’s video’s $1 grouped by playback location:
44
- # video.$1 from: 1.day.ago, to: 1.day.ago, by: :playback_location
30
+ # $1 for each traffic playback location.
31
+ # @example Get yesterday’s $1 grouped by playback location:
32
+ # resource.$1 from: 1.day.ago, to: 1.day.ago, by: :playback_location
45
33
  # # => {embedded: 53.0, watch: 467.0, …}
34
+ # @return [Hash<Yt::Video, Float>] if grouped by related video, the
35
+ # $1 for each related video.
36
+ # @example Get yesterday’s $1 by related video:
37
+ # resource.$1 from: 1.day.ago, to: 1.day.ago, by: :related_video
38
+ # # => {#<Yt::Video @id=…> => 33.0, #<Yt::Video @id=…> => 12.0, …}
39
+ # @return [Hash<Yt::Video, Float>] if grouped by device type, the
40
+ # $1 for each device type.
41
+ # @example Get yesterday’s $1 by device type:
42
+ # resource.$1 from: 1.day.ago, to: 1.day.ago, by: :device_type
43
+ # # => {mobile: 133.0, tv: 412.0, …}
44
+ # @return [Hash<Yt::Video, Float>] if grouped by traffic source, the
45
+ # $1 for each traffic source.
46
+ # @example Get yesterday’s $1 by traffic source:
47
+ # resource.$1 from: 1.day.ago, to: 1.day.ago, by: :traffic_source
48
+ # # => {advertising: 543.0, playlist: 92.0, …}
49
+ # @macro report_with_day
50
+
51
+ # @!macro [new] report_by_video_dimensions
52
+ # @option options [Symbol] :by (:day) The dimension to collect $1 by.
53
+ # Accepted values are: +:day+, +:traffic_source+,
54
+ # +:playback_location+, +:related_video+, +:embedded_player_location+.
46
55
  # @return [Hash<Symbol, Float>] if grouped by embedded player location,
47
- # the $1 of the video for each embedded player location.
48
- # @example Get yesterday’s video’s $1 by embedded player location:
49
- # video.$1 from: 1.day.ago, to: 1.day.ago, by: :embedded_player_location
56
+ # the $1 for each embedded player location.
57
+ # @example Get yesterday’s $1 by embedded player location:
58
+ # resource.$1 from: 1.day.ago, to: 1.day.ago, by: :embedded_player_location
50
59
  # # => {"fullscreen.net" => 92.0, "yahoo.com" => 14.0, …}
51
- # @return [Hash<Yt::Video, Float>] if grouped by related video, the
52
- # $1 of the video for each related video.
53
- # @example Get yesterday’s video’s $1 by related video:
54
- # video.$1 from: 1.day.ago, to: 1.day.ago, by: :related_video
60
+ # @macro report_with_video_dimensions
61
+
62
+ # @!macro [new] report_with_channel_dimensions
63
+ # @return [Hash<Yt::Video, Float>] if grouped by video, the
64
+ # $1 for each video.
65
+ # @example Get yesterday’s $1 by video:
66
+ # resource.$1 from: 1.day.ago, to: 1.day.ago, by: :video
55
67
  # # => {#<Yt::Video @id=…> => 33.0, #<Yt::Video @id=…> => 12.0, …}
56
- # @macro report
68
+ # @return [Hash<Yt::Video, Float>] if grouped by playlist, the
69
+ # $1 for each playlist.
70
+ # @example Get yesterday’s $1 by playlist:
71
+ # resource.$1 from: 1.day.ago, to: 1.day.ago, by: :playlist
72
+ # # => {#<Yt::Video @id=…> => 33.0, #<Yt::Video @id=…> => 12.0, …}
73
+ # @macro report_with_video_dimensions
74
+
75
+ # @!macro [new] report_by_channel_dimensions
76
+ # @option options [Symbol] :by (:day) The dimension to collect $1 by.
77
+ # Accepted values are: +:day+, +:traffic_source+,
78
+ # +:playback_location+, +:related_video+, +:video+,
79
+ # +:playlist+, +:embedded_player_location+.
80
+ # @return [Hash<Symbol, Float>] if grouped by embedded player location,
81
+ # the $1 for each embedded player location.
82
+ # @example Get yesterday’s $1 by embedded player location:
83
+ # resource.$1 from: 1.day.ago, to: 1.day.ago, by: :embedded_player_location
84
+ # # => {"fullscreen.net" => 92.0, "yahoo.com" => 14.0, …}
85
+ # @macro report_with_channel_dimensions
86
+
87
+ # @!macro [new] report_by_playlist_dimensions
88
+ # @option options [Symbol] :by (:day) The dimension to collect $1 by.
89
+ # Accepted values are: +:day+, +:traffic_source+,
90
+ # +:playback_location+, +:related_video+, +:video+,
91
+ # +:playlist+.
92
+ # @macro report_with_channel_dimensions
57
93
 
58
- # @!macro [new] demographics_report
94
+ # @!macro [new] report_by_gender_and_age_group
59
95
  # @option options [Symbol] :by (:gender_age_group) The dimension to
60
96
  # show viewer percentage by.
61
97
  # Accepted values are: +:gender+, +:age_group+, +:gender_age_group+.
62
- # @return [Hash<Symbol, Float>] if grouped by gender, the video’s
98
+ # @return [Hash<Symbol, Float>] if grouped by gender, the
63
99
  # viewer percentage by gender.
64
- # @example Get yesterday’s video’s viewer percentage by gender:
65
- # video.$1 from: 1.day.ago, to: 1.day.ago, by: :gender
100
+ # @example Get yesterday’s viewer percentage by gender:
101
+ # resource.$1 from: 1.day.ago, to: 1.day.ago, by: :gender
66
102
  # # => {female: 53.0, male: 47.0}
67
- # @return [Hash<String, Float>] if grouped by age group, the video’s
103
+ # @return [Hash<String, Float>] if grouped by age group, the
68
104
  # viewer percentage by age group.
69
- # @example Get yesterday’s video’s $1 grouped by age group:
70
- # video.$1 from: 1.day.ago, to: 1.day.ago, by: :age_group
105
+ # @example Get yesterday’s $1 grouped by age group:
106
+ # resource.$1 from: 1.day.ago, to: 1.day.ago, by: :age_group
71
107
  # # => {"18-24" => 4.54, "35-24" => 12.31, "45-34" => 8.92, …}
72
108
  # @return [Hash<Symbol, [Hash<String, Float>]>] if grouped by gender
73
- # and age group, the video’s viewer percentage by gender/age group.
74
- # @example Get yesterday’s video’s $1 by gender and age group:
75
- # video.$1 from: 1.day.ago, to: 1.day.ago
109
+ # and age group, the viewer percentage by gender/age group.
110
+ # @example Get yesterday’s $1 by gender and age group:
111
+ # resource.$1 from: 1.day.ago, to: 1.day.ago
76
112
  # # => {female: {"18-24" => 12.12, "25-34" => 16.16, …}, male:…}
77
113
  # @macro report
78
114
 
@@ -71,6 +71,7 @@ module Yt
71
71
  timestamps.first < seconds if timestamps.any?
72
72
  end
73
73
 
74
+ # @return [String] the textual content of the annotation.
74
75
  def text
75
76
  @text ||= @data['TEXT'] || ''
76
77
  end
@@ -72,8 +72,6 @@ module Yt
72
72
 
73
73
  # Status
74
74
 
75
- STATUSES = %q(active inactive pending)
76
-
77
75
  # Returns the asset’s status.
78
76
  # @return [String] the asset’s status. Possible values are: +'active'+,
79
77
  # +'inactive'+, +'pending'+.
@@ -2,9 +2,90 @@ require 'yt/models/resource'
2
2
 
3
3
  module Yt
4
4
  module Models
5
- # A channel resource contains information about a YouTube channel.
5
+ # Provides methods to interact with YouTube channels.
6
6
  # @see https://developers.google.com/youtube/v3/docs/channels
7
7
  class Channel < Resource
8
+
9
+ ### SNIPPET ###
10
+
11
+ # @!attribute [r] title
12
+ # @return [String] the channel’s title.
13
+ delegate :title, to: :snippet
14
+
15
+ # @!attribute [r] description
16
+ # @return [String] the channel’s description.
17
+ delegate :description, to: :snippet
18
+
19
+ # Returns the URL of the channel’s thumbnail.
20
+ # @!method thumbnail_url(size = :default)
21
+ # @param [Symbol, String] size The size of the channel’s thumbnail.
22
+ # @return [String] if +size+ is +default+, the URL of a 88x88px image.
23
+ # @return [String] if +size+ is +medium+, the URL of a 240x240px image.
24
+ # @return [String] if +size+ is +high+, the URL of a 800x800px image.
25
+ # @return [nil] if the +size+ is not +default+, +medium+ or +high+.
26
+ delegate :thumbnail_url, to: :snippet
27
+
28
+ # @!attribute [r] published_at
29
+ # @return [Time] the date and time that the channel was created.
30
+ delegate :published_at, to: :snippet
31
+
32
+ ### SUBSCRIPTION ###
33
+
34
+ has_one :subscription
35
+
36
+ # @return [Boolean] whether the account is subscribed to the channel.
37
+ # @raise [Yt::Errors::Unauthorized] if {Resource#auth auth} is not an
38
+ # authenticated Yt::Account.
39
+ def subscribed?
40
+ sleep [(@subscriptions_updated_at || Time.now) - Time.now, 0].max
41
+ subscription.exists?
42
+ rescue Errors::NoItems
43
+ false
44
+ end
45
+
46
+ # Subscribes the authenticated account to the channel.
47
+ # Unlike {#subscribe!}, does not raise an error if already subscribed.
48
+ # @raise [Yt::Errors::Unauthorized] if {Resource#auth auth} is not an
49
+ # authenticated Yt::Account.
50
+ def subscribe
51
+ subscriptions.insert(ignore_errors: true).tap do |subscription|
52
+ throttle_subscriptions
53
+ @subscription = subscription
54
+ end
55
+ end
56
+
57
+ # Subscribes the authenticated account to the channel.
58
+ # Unlike {#subscribe}, raises an error if already subscribed.
59
+ # @raise [Yt::Errors::RequestError] if already subscribed.
60
+ # @raise [Yt::Errors::Unauthorized] if {Resource#auth auth} is not an
61
+ # authenticated Yt::Account.
62
+ def subscribe!
63
+ subscriptions.insert.tap do |subscription|
64
+ throttle_subscriptions
65
+ @subscription = subscription
66
+ end
67
+ end
68
+
69
+ # Unsubscribes the authenticated account from the channel.
70
+ # Unlike {#unsubscribe!}, does not raise an error if already unsubscribed.
71
+ # @raise [Yt::Errors::Unauthorized] if {Resource#auth auth} is not an
72
+ # authenticated Yt::Account.
73
+ def unsubscribe
74
+ unsubscribe! if subscribed?
75
+ end
76
+
77
+ # Unsubscribes the authenticated account from the channel.
78
+ # Unlike {#unsubscribe}, raises an error if already unsubscribed.
79
+ #
80
+ # @raise [Yt::Errors::RequestError] if already unsubscribed.
81
+ # @raise [Yt::Errors::Unauthorized] if {Resource#auth auth} is not an
82
+ # authenticated Yt::Account.
83
+ def unsubscribe!
84
+ subscription.delete.tap{ throttle_subscriptions }
85
+ end
86
+
87
+ ### ASSOCIATIONS ###
88
+
8
89
  # @!attribute [r] videos
9
90
  # @return [Yt::Collections::Videos] the channel’s videos.
10
91
  has_many :videos
@@ -13,168 +94,154 @@ module Yt
13
94
  # @return [Yt::Collections::Playlists] the channel’s playlists.
14
95
  has_many :playlists
15
96
 
16
- # @macro has_report
17
- has_report :earnings
97
+ # @!attribute [r] subscribed_channels
98
+ # @return [Yt::Collections::SubscribedChannels] the channels that this
99
+ # channel is subscribed to.
100
+ # @raise [Yt::Errors::Forbidden] if the owner of the channel has
101
+ # explicitly select the option to keep all subscriptions private.
102
+ has_many :subscribed_channels
103
+
104
+ ### ANALYTICS ###
18
105
 
19
- # @macro has_report
106
+ # @macro report_by_channel_dimensions
20
107
  has_report :views
21
108
 
22
- # @macro has_report
109
+ # @macro report_by_channel_dimensions
110
+ has_report :estimated_minutes_watched
111
+
112
+ # @macro report_by_gender_and_age_group
113
+ has_report :viewer_percentage
114
+
115
+ # @macro report_by_day
23
116
  has_report :comments
24
117
 
25
- # @macro has_report
118
+ # @macro report_by_day
26
119
  has_report :likes
27
120
 
28
- # @macro has_report
121
+ # @macro report_by_day
29
122
  has_report :dislikes
30
123
 
31
- # @macro has_report
124
+ # @macro report_by_day
32
125
  has_report :shares
33
126
 
34
- # @macro has_report
127
+ # @macro report_by_day
35
128
  has_report :subscribers_gained
36
129
 
37
- # @macro has_report
130
+ # @macro report_by_day
38
131
  has_report :subscribers_lost
39
132
 
40
- # @macro has_report
133
+ # @macro report_by_day
41
134
  has_report :favorites_added
42
135
 
43
- # @macro has_report
136
+ # @macro report_by_day
44
137
  has_report :favorites_removed
45
138
 
46
- # @macro has_report
47
- has_report :estimated_minutes_watched
48
-
49
- # @macro has_report
139
+ # @macro report_by_day
50
140
  has_report :average_view_duration
51
141
 
52
- # @macro has_report
142
+ # @macro report_by_day
53
143
  has_report :average_view_percentage
54
144
 
55
- # @macro has_report
56
- has_report :impressions
57
-
58
- # @macro has_report
59
- has_report :monetized_playbacks
60
-
61
- # @macro has_report
145
+ # @macro report_by_day
62
146
  has_report :annotation_clicks
63
147
 
64
- # @macro has_report
148
+ # @macro report_by_day
65
149
  has_report :annotation_click_through_rate
66
150
 
67
- # @macro has_report
151
+ # @macro report_by_day
68
152
  has_report :annotation_close_rate
69
153
 
70
- # @macro has_report
71
- has_report :viewer_percentage
154
+ # @macro report_by_day
155
+ has_report :earnings
156
+
157
+ # @macro report_by_day
158
+ has_report :impressions
159
+
160
+ # @macro report_by_day
161
+ has_report :monetized_playbacks
162
+
163
+ ### STATISTICS ###
72
164
 
73
- # @!attribute [r] statistics_set
74
- # @return [Yt::Models::StatisticsSet] the statistics for the video.
75
165
  has_one :statistics_set
76
- delegate :view_count, :comment_count, :video_count, :subscriber_count,
77
- :subscriber_count_visible?, to: :statistics_set
78
166
 
79
- # @!attribute [r] content_owner_detail
80
- # @return [Yt::Models::ContentOwnerDetail] the video’s content owner
81
- # details.
82
- has_one :content_owner_detail
83
- delegate :content_owner, :linked_at, to: :content_owner_detail
167
+ # @!attribute [r] view_count
168
+ # @return [Integer] the number of times the channel has been viewed.
169
+ delegate :view_count, to: :statistics_set
84
170
 
85
- # @!attribute [r] subscribed_channels
86
- # @return [Yt::Collections::SubscribedChannels] the channels that the channel is subscribed to.
87
- # @raise [Yt::Errors::Forbidden] if the owner of the channel has
88
- # explicitly select the option to keep all subscriptions private.
89
- has_many :subscribed_channels
171
+ # @!attribute [r] comment_count
172
+ # @return [Integer] the number of comments for the channel.
173
+ delegate :comment_count, to: :statistics_set
90
174
 
91
- # @!attribute [r] subscription
92
- # @return [Yt::Models::Subscription] the channel’s subscription by auth.
93
- # @raise [Yt::Errors::NoItems] if {Resource#auth auth} is not
94
- # subscribed to the channel.
95
- # @raise [Yt::Errors::Unauthorized] if {Resource#auth auth} does not
96
- # return an authenticated account.
97
- has_one :subscription
175
+ # @!attribute [r] video_count
176
+ # @return [Integer] the number of videos uploaded to the channel.
177
+ delegate :video_count, to: :statistics_set
98
178
 
99
- # Override Resource's new to set statistics as well
100
- # if the response includes them
101
- def initialize(options = {})
102
- super options
103
- if options[:statistics]
104
- @statistics_set = StatisticsSet.new data: options[:statistics]
105
- end
106
- end
179
+ # @!attribute [r] subscriber_count
180
+ # @return [Integer] the number of subscriber the channel has.
181
+ delegate :subscriber_count, to: :statistics_set
107
182
 
108
- # Returns whether the authenticated account is subscribed to the channel.
109
- #
110
- # This method requires {Resource#auth auth} to return an
111
- # authenticated instance of {Yt::Account}.
112
- # @return [Boolean] whether the account is subscribed to the channel.
113
- # @raise [Yt::Errors::Unauthorized] if {Resource#auth auth} does not
114
- # return an authenticated account.
115
- def subscribed?
116
- sleep [(@subscriptions_updated_at || Time.now) - Time.now, 0].max
117
- subscription.exists?
118
- rescue Errors::NoItems
119
- false
183
+ # @return [Boolean] whether the number of subscribers is publicly visible.
184
+ def subscriber_count_visible?
185
+ statistics_set.hidden_subscriber_count == false
120
186
  end
121
187
 
122
- # Unsubscribes the authenticated account from the channel.
123
- # Raises an error if the account was not subscribed.
124
- #
125
- # This method requires {Resource#auth auth} to return an
126
- # authenticated instance of {Yt::Account}.
127
- # @raise [Yt::Errors::RequestError] if {Resource#auth auth} was not
128
- # subscribed to the channel.
129
- # @raise [Yt::Errors::Unauthorized] if {Resource#auth auth} does not
130
- # return an authenticated account.
131
- def unsubscribe!
132
- subscription.delete.tap{ throttle_subscriptions }
133
- end
188
+ ### CONTENT OWNER DETAILS ###
134
189
 
135
- # Unsubscribes the authenticated account from the channel.
136
- # Does not raise an error if the account was not subscribed.
137
- #
138
- # This method requires {Resource#auth auth} to return an
139
- # authenticated instance of {Yt::Account}.
140
- # @raise [Yt::Errors::Unauthorized] if {Resource#auth auth} does not
141
- # return an authenticated account.
142
- def unsubscribe
143
- unsubscribe! if subscribed?
144
- end
190
+ has_one :content_owner_detail
145
191
 
146
- # Subscribes the authenticated account to the channel.
147
- # Raises an error if the account was already subscribed.
148
- #
149
- # This method requires {Resource#auth auth} to return an
150
- # authenticated instance of {Yt::Account}.
151
- # @raise [Yt::Errors::RequestError] if {Resource#auth auth} was already
152
- # subscribed to the channel.
153
- # @raise [Yt::Errors::Unauthorized] if {Resource#auth auth} does not
154
- # return an authenticated account.
155
- def subscribe!
156
- subscriptions.insert.tap do |subscription|
157
- throttle_subscriptions
158
- @subscription = subscription
159
- end
192
+ # The name of the content owner linked to the channel.
193
+ # @!attribute [r] content_owner
194
+ # @return [String] if the channel is partnered, its content owner’s name.
195
+ # @return [nil] if the channel is not partnered or if {Resource#auth auth}
196
+ # is a content owner without permissions to administer the channel.
197
+ # @raise [Yt::Errors::Forbidden] if {Resource#auth auth} does not
198
+ # return an authenticated content owner.
199
+ delegate :content_owner, to: :content_owner_detail
200
+
201
+ # Returns the time the channel was partnered to a content owner.
202
+ # @return [Time] if the channel is partnered, the time when it was linked
203
+ # to its content owner.
204
+ # @return [nil] if the channel is not partnered or if {Resource#auth auth}
205
+ # is a content owner without permissions to administer the channel.
206
+ # @raise [Yt::Errors::Forbidden] if {Resource#auth auth} does not
207
+ # return an authenticated content owner.
208
+ def linked_at
209
+ content_owner_detail.time_linked
160
210
  end
161
211
 
162
- # Subscribes the authenticated account to the channel.
163
- # Does not raise an error if the account was already subscribed.
164
- #
165
- # This method requires {Resource#auth auth} to return an
166
- # authenticated instance of {Yt::Account}.
167
- # @raise [Yt::Errors::Unauthorized] if {Resource#auth auth} does not
168
- # return an authenticated account.
169
- def subscribe
170
- subscriptions.insert(ignore_errors: true).tap do |subscription|
171
- throttle_subscriptions
172
- @subscription = subscription
173
- end
212
+ ### ACTIONS (UPLOAD, UPDATE, DELETE) ###
213
+
214
+ # Deletes the channel’s playlists matching all the given attributes.
215
+ # @return [Array<Boolean>] whether each playlist matching the given
216
+ # attributes was deleted.
217
+ # @raise [Yt::Errors::RequestError] if {Resource#auth auth} is not an
218
+ # authenticated Yt::Account with permissions to update the channel.
219
+ # @param [Hash] attributes the attributes to match the playlists by.
220
+ # @option attributes [<String, Regexp>] :title The playlist’s title.
221
+ # Pass a String for perfect match or a Regexp for advanced match.
222
+ # @option attributes [<String, Regexp>] :description The playlist’s
223
+ # description. Pass a String (perfect match) or a Regexp (advanced).
224
+ # @option attributes [Array<String>] :tags The playlist’s tags.
225
+ # All tags must match exactly.
226
+ # @option attributes [String] :privacy_status The playlist’s privacy
227
+ # status.
228
+ def delete_playlists(attributes = {})
229
+ playlists.delete_all attributes
174
230
  end
175
231
 
176
- def delete_playlists(attrs = {})
177
- playlists.delete_all attrs
232
+ ### PRIVATE API ###
233
+
234
+ # @private
235
+ # Override Resource's new to set statistics as well
236
+ # if the response includes them
237
+ def initialize(options = {})
238
+ super options
239
+ if options[:statistics]
240
+ @statistics_set = StatisticsSet.new data: options[:statistics]
241
+ end
242
+ if options[:content_owner_details]
243
+ @content_owner_detail = ContentOwnerDetail.new data: options[:content_owner_details]
244
+ end
178
245
  end
179
246
 
180
247
  # @private