yt 0.19.0 → 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -42,9 +42,6 @@ module Yt
42
42
 
43
43
  # Status
44
44
 
45
- STATUSES = %q(active appealed disputed inactive pending potential
46
- takedown unknown)
47
-
48
45
  # Returns the claim’s status.
49
46
  # @return [String] the claim’s status. Possible values are: +'active'+,
50
47
  # +'appealed'+, +'disputed'+, +'inactive'+, +'pending'+, +'potential'+,
@@ -96,8 +93,6 @@ module Yt
96
93
 
97
94
  # Content Type
98
95
 
99
- CONTENT_TYPES = %q(audio video audiovisual)
100
-
101
96
  # Returns the audiovisual portion of the claimed content.
102
97
  # @return [String] the audiovisual portion of the claimed content.
103
98
  # Possible values are: +'audio'+, +'audiovisual'+, +'video'+.
@@ -10,32 +10,8 @@ module Yt
10
10
  @data = options[:data] || {}
11
11
  end
12
12
 
13
- # Returns the name of the content owner linked to the channel.
14
- #
15
- # This method requires {Resource#auth auth} to return an authenticated
16
- # instance of {Yt::ContentOwner} that can administer the channel.
17
- # @return [String] if the channel is partnered with a content owner,
18
- # the name of the content owner linked to the channel.
19
- # @return [nil] if the channel is not partnered with a content owner.
20
- # @return [nil] if {Resource#auth auth} is a content owner without
21
- # permissions to administer the channel.
22
- # @raise [Yt::Errors::Forbidden] if {Resource#auth auth} does not
23
- # return an authenticated content owner.
24
13
  has_attribute :content_owner
25
-
26
- # Returns the date and time of when the channel was linked to the content
27
- # owner.
28
- #
29
- # This method requires {Resource#auth auth} to return an authenticated
30
- # instance of {Yt::ContentOwner} that can administer the channel.
31
- # @return [Time] if the channel is partnered with a content owner,
32
- # the date and time when the channel was linked with the content owner.
33
- # @return [nil] if the channel is not partnered with a content owner.
34
- # @return [nil] if {Resource#auth auth} is a content owner without
35
- # permissions to administer the channel.
36
- # @raise [Yt::Errors::Forbidden] if {Resource#auth auth} does not
37
- # return an authenticated content owner.
38
- has_attribute :linked_at, type: Time, from: :time_linked
14
+ has_attribute :time_linked, type: Time
39
15
  end
40
16
  end
41
17
  end
@@ -1,5 +1,6 @@
1
1
  module Yt
2
2
  module Models
3
+ # @private
3
4
  # Encapsulates information about the ID that YouTube uses to uniquely
4
5
  # identify a resource.
5
6
  class Id < String
@@ -5,70 +5,151 @@ module Yt
5
5
  # Provides methods to interact with YouTube playlists.
6
6
  # @see https://developers.google.com/youtube/v3/docs/playlists
7
7
  class Playlist < Resource
8
- delegate :tags, :channel_id, :channel_title, to: :snippet
9
8
 
10
- # @!attribute [r] playlist_items
11
- # @return [Yt::Collections::PlaylistItems] the playlist’s items.
12
- has_many :playlist_items
9
+ ### SNIPPET ###
13
10
 
14
- # @macro has_report
15
- has_report :views
11
+ # @!attribute [r] title
12
+ # @return [String] the playlist’s title.
13
+ delegate :title, to: :snippet
16
14
 
17
- # @macro has_report
18
- has_report :playlist_starts
15
+ # @!attribute [r] description
16
+ # @return [String] the playlist’s description.
17
+ delegate :description, to: :snippet
19
18
 
20
- # @macro has_report
21
- has_report :average_time_in_playlist
19
+ # Returns the URL of the playlist’s thumbnail.
20
+ # @!method thumbnail_url(size = :default)
21
+ # @param [Symbol, String] size The size of the playlist’s thumbnail.
22
+ # @return [String] if +size+ is +default+, the URL of a 120x90px image.
23
+ # @return [String] if +size+ is +medium+, the URL of a 320x180px image.
24
+ # @return [String] if +size+ is +high+, the URL of a 480x360px image.
25
+ # @return [nil] if the +size+ is not +default+, +medium+ or +high+.
26
+ delegate :thumbnail_url, to: :snippet
22
27
 
23
- # @macro has_report
24
- has_report :views_per_playlist_start
28
+ # @!attribute [r] published_at
29
+ # @return [Time] the date and time that the playlist was created.
30
+ delegate :published_at, to: :snippet
31
+
32
+ # @!attribute [r] channel_id
33
+ # @return [String] the ID of the channel that the playlist belongs to.
34
+ delegate :channel_id, to: :snippet
35
+
36
+ # @!attribute [r] channel_title
37
+ # @return [String] the title of the channel that the playlist belongs to.
38
+ delegate :channel_title, to: :snippet
39
+
40
+ # @!attribute [r] tags
41
+ # @return [Array<String>] the list of tags attached to the playlist.
42
+ delegate :tags, to: :snippet
43
+
44
+ ### ACTIONS (UPLOAD, UPDATE, DELETE) ###
25
45
 
26
46
  # Deletes the playlist.
27
- #
28
- # This method requires {Resource#auth auth} to return an authenticated
29
- # instance of {Yt::Account} with permissions to delete the playlist.
30
- # @raise [Yt::Errors::Unauthorized] if {Resource#auth auth} does not
31
- # return an account with permissions to delete the playlist.
32
47
  # @return [Boolean] whether the playlist does not exist anymore.
48
+ # @raise [Yt::Errors::Unauthorized] if {Resource#auth auth} is not an
49
+ # authenticated Yt::Account with permissions to delete the playlist.
33
50
  def delete(options = {})
34
51
  do_delete {@id = nil}
35
52
  !exists?
36
53
  end
37
54
 
38
- def exists?
39
- !@id.nil?
40
- end
41
-
42
- # Adds a video to the playlist
43
- # Does not raise an error if the video cannot be added (e.g., unknown).
44
- #
45
- # This method requires {Resource#auth auth} to return an authenticated
46
- # instance of {Yt::Account} with permissions to update the playlist.
47
- # @raise [Yt::Errors::Unauthorized] if {Resource#auth auth} does not
48
- # return an account with permissions to update the playlist.
55
+ # Adds a video to the playlist.
56
+ # Unlike {#add_video!}, does not raise an error if video can’t be added.
57
+ # @param [String] video_id the video to add to the playlist.
58
+ # @param [Hash] options the options on how to add the video.
59
+ # @option options [Integer] :position where to add video in the playlist.
60
+ # @raise [Yt::Errors::Unauthorized] if {Resource#auth auth} is not an
61
+ # authenticated Yt::Account with permissions to update the playlist.
49
62
  # @return [Yt::PlaylistItem] the item added to the playlist.
50
- def add_video(video_id, attributes = {})
51
- playlist_item_params = playlist_item_params(video_id, attributes)
63
+ def add_video(video_id, options = {})
64
+ playlist_item_params = playlist_item_params(video_id, options)
52
65
  playlist_items.insert playlist_item_params, ignore_errors: true
53
66
  end
54
67
 
55
- def add_video!(video_id, attributes = {})
56
- playlist_item_params = playlist_item_params(video_id, attributes)
68
+ # Adds a video to the playlist.
69
+ # Unlike {#add_video}, raises an error if video can’t be added.
70
+ # @param [String] video_id the video ID to add to the playlist.
71
+ # @param [Hash] options the options on how to add the video.
72
+ # @option options [Integer] :position where to add video in the playlist.
73
+ # @raise [Yt::Errors::RequestError] if video can’t be added.
74
+ # @raise [Yt::Errors::Unauthorized] if {Resource#auth auth} is not an
75
+ # authenticated Yt::Account with permissions to update the playlist.
76
+ # @return [Yt::PlaylistItem] the item added to the playlist.
77
+ def add_video!(video_id, options = {})
78
+ playlist_item_params = playlist_item_params(video_id, options)
57
79
  playlist_items.insert playlist_item_params
58
80
  end
59
81
 
60
- def add_videos(video_ids = [], attributes = {})
61
- video_ids.map{|video_id| add_video video_id, attributes}
82
+ # Adds multiple videos to the playlist.
83
+ # Unlike {#add_videos!}, does not raise an error if videos can’t be added.
84
+ # @param [Array<String>] video_ids the video IDs to add to the playlist.
85
+ # @param [Hash] options the options on how to add the videos.
86
+ # @option options [Integer] :position where to add videos in the playlist.
87
+ # @raise [Yt::Errors::Unauthorized] if {Resource#auth auth} is not an
88
+ # authenticated Yt::Account with permissions to update the playlist.
89
+ # @return [Array<Yt::PlaylistItem>] the items added to the playlist.
90
+ def add_videos(video_ids = [], options = {})
91
+ video_ids.map{|video_id| add_video video_id, options}
62
92
  end
63
93
 
64
- def add_videos!(video_ids = [], attributes = {})
65
- video_ids.map{|video_id| add_video! video_id, attributes}
94
+ # Adds multiple videos to the playlist.
95
+ # Unlike {#add_videos}, raises an error if videos can’t be added.
96
+ # @param [Array<String>] video_ids the video IDs to add to the playlist.
97
+ # @param [Hash] options the options on how to add the videos.
98
+ # @option options [Integer] :position where to add videos in the playlist.
99
+ # @raise [Yt::Errors::Unauthorized] if {Resource#auth auth} is not an
100
+ # authenticated Yt::Account with permissions to update the playlist.
101
+ # @return [Array<Yt::PlaylistItem>] the items added to the playlist.
102
+ def add_videos!(video_ids = [], options = {})
103
+ video_ids.map{|video_id| add_video! video_id, options}
66
104
  end
67
105
 
68
- def delete_playlist_items(attrs = {})
69
- playlist_items.delete_all attrs
106
+ # Deletes the playlist’s items matching all the given attributes.
107
+ # @return [Array<Boolean>] whether each playlist item matching the given
108
+ # attributes was deleted.
109
+ # @raise [Yt::Errors::RequestError] if {Resource#auth auth} is not an
110
+ # authenticated Yt::Account with permissions to update the playlist.
111
+ # @param [Hash] attributes the attributes to match the items by.
112
+ # @option attributes [<String, Regexp>] :title The item’s title.
113
+ # Pass a String for perfect match or a Regexp for advanced match.
114
+ # @option attributes [<String, Regexp>] :description The item’s
115
+ # description. Pass a String (perfect match) or a Regexp (advanced).
116
+ # @option attributes [String] :privacy_status The item’s privacy status.
117
+ # @option attributes [String] :video_id The item’s video ID.
118
+ def delete_playlist_items(attributes = {})
119
+ playlist_items.delete_all attributes
70
120
  end
71
121
 
122
+ ### ASSOCIATIONS ###
123
+
124
+ # @!attribute [r] playlist_items
125
+ # @return [Yt::Collections::PlaylistItems] the playlist’s items.
126
+ has_many :playlist_items
127
+
128
+ ### ANALYTICS ###
129
+
130
+ # @macro report_by_playlist_dimensions
131
+ has_report :views
132
+
133
+ # @macro report_by_playlist_dimensions
134
+ has_report :estimated_minutes_watched
135
+
136
+ # @macro report_by_gender_and_age_group
137
+ has_report :viewer_percentage
138
+
139
+ # @macro report_by_day
140
+ has_report :average_view_duration
141
+
142
+ # @macro report_by_day
143
+ has_report :playlist_starts
144
+
145
+ # @macro report_by_day
146
+ has_report :average_time_in_playlist
147
+
148
+ # @macro report_by_day
149
+ has_report :views_per_playlist_start
150
+
151
+ ### PRIVATE API ###
152
+
72
153
  # @private
73
154
  # Tells `has_reports` to retrieve the reports from YouTube Analytics API
74
155
  # either as a Channel or as a Content Owner.
@@ -84,6 +165,11 @@ module Yt
84
165
  end
85
166
  end
86
167
 
168
+ # @private
169
+ def exists?
170
+ !@id.nil?
171
+ end
172
+
87
173
  private
88
174
 
89
175
  # @see https://developers.google.com/youtube/v3/docs/playlists/update
@@ -5,30 +5,76 @@ module Yt
5
5
  # Provides methods to interact with YouTube playlist items.
6
6
  # @see https://developers.google.com/youtube/v3/docs/playlistItems
7
7
  class PlaylistItem < Resource
8
- delegate :channel_id, :channel_title, :playlist_id, :video_id,
9
- :video, to: :snippet
10
8
 
9
+ ### SNIPPET ###
10
+
11
+ # @!attribute [r] title
12
+ # @return [String] the item’s title.
13
+ delegate :title, to: :snippet
14
+
15
+ # @!attribute [r] description
16
+ # @return [String] the item’s description.
17
+ delegate :description, to: :snippet
18
+
19
+ # Returns the URL of the item’s thumbnail.
20
+ # @!method thumbnail_url(size = :default)
21
+ # @param [Symbol, String] size The size of the item’s thumbnail.
22
+ # @return [String] if +size+ is +default+, the URL of a 120x90px image.
23
+ # @return [String] if +size+ is +medium+, the URL of a 320x180px image.
24
+ # @return [String] if +size+ is +high+, the URL of a 480x360px 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 time that the item was added to the playlist.
30
+ delegate :published_at, to: :snippet
31
+
32
+ # @!attribute [r] channel_id
33
+ # @return [String] the ID of the channel that the item belongs to.
34
+ delegate :channel_id, to: :snippet
35
+
36
+ # @!attribute [r] channel_title
37
+ # @return [String] the title of the channel that the item belongs to.
38
+ delegate :channel_title, to: :snippet
39
+
40
+ # @!attribute [r] playlist_id
41
+ # @return [String] the ID of the playlist that the item is in.
42
+ delegate :playlist_id, to: :snippet
43
+
44
+ # @return [String] the ID of the video referred by the item.
45
+ def video_id
46
+ snippet.resource_id['videoId']
47
+ end
48
+
49
+ # @return [Integer] the order in which the item appears in a playlist.
50
+ # The value is zero-based, so the first item has a position of 0.
51
+ def position
52
+ ensure_complete_snippet :position
53
+ end
54
+
55
+ ### ACTIONS (UPLOAD, UPDATE, DELETE) ###
56
+
57
+ # Deletes the playlist item.
58
+ # @return [Boolean] whether the playlist item does not exist anymore.
59
+ # @raise [Yt::Errors::Unauthorized] if {Resource#auth auth} is not an
60
+ # authenticated Yt::Account with permissions to delete the item.
11
61
  def delete(options = {})
12
62
  do_delete {@id = nil}
13
63
  !exists?
14
64
  end
15
65
 
16
- def exists?
17
- !@id.nil?
66
+ ### ASSOCIATIONS ###
67
+
68
+ # @return [Yt::Models::Video] the video referred by the item.
69
+ def video
70
+ @video ||= Video.new id: video_id, auth: @auth if video_id
18
71
  end
19
72
 
20
- # Returns the position of the item in the playlist.
21
- # Since YouTube API does not return the position on PlaylistItem#create,
22
- # the memoized @snippet is erased if the video was instantiated like that,
23
- # so that the full snippet (with position) is loaded, rather than the
24
- # partial one.
25
- # @see https://developers.google.com/youtube/v3/docs/playlistItems
26
- # @return [Integer] the order in which the item appears in a playlist.
27
- def position
28
- unless snippet.position || snippet.complete? || @auth.nil?
29
- @snippet = nil
30
- end
31
- snippet.position
73
+ ### PRIVATE API ###
74
+
75
+ # @private
76
+ def exists?
77
+ !@id.nil?
32
78
  end
33
79
 
34
80
  private
@@ -81,10 +81,6 @@ module Yt
81
81
 
82
82
  # Status
83
83
 
84
- STATUSES = %q(activating active checking computing_fingerprint deleted
85
- duplicate_on_hold inactive live_streaming_processing
86
- urgent_reference_processing)
87
-
88
84
  # @return [String] the reference’s status. Possible values are:
89
85
  # +'activating'+, +'active'+, +'checking'+, +'computing_fingerprint'+,
90
86
  # +'deleted'+, +'duplicate_on_hold'+, +'inactive'+,
@@ -141,8 +137,6 @@ module Yt
141
137
 
142
138
  # Content Type
143
139
 
144
- CONTENT_TYPES = %q(audio video audiovisual)
145
-
146
140
  # Returns the audiovisual portion of the referenced content.
147
141
  # @return [String] the audiovisual portion of the referenced content.
148
142
  # Possible values are: +'audio'+, +'audiovisual'+, +'video'+.
@@ -71,6 +71,17 @@ module Yt
71
71
 
72
72
  private
73
73
 
74
+ # Since YouTube API only returns tags on Videos#list, the memoized
75
+ # `@snippet` is erased if the video was instantiated through Video#search
76
+ # (e.g., by calling account.videos or channel.videos), so that the full
77
+ # snippet (with tags and category) is loaded, rather than the partial one.
78
+ def ensure_complete_snippet(attribute)
79
+ unless snippet.public_send(attribute).present? || snippet.complete?
80
+ @snippet = nil
81
+ end
82
+ snippet.public_send attribute
83
+ end
84
+
74
85
  # TODO: instead of having Video, Playlist etc override this method,
75
86
  # they should define *what* can be updated in their own *update*
76
87
  # method.
@@ -2,11 +2,7 @@ require 'yt/models/description'
2
2
 
3
3
  module Yt
4
4
  module Models
5
- # Contains basic information about the resource. The details of the snippet
6
- # are different for the different types of resources.
7
- #
8
- # Resources with a
9
- # snippet are: channels, playlists, playlist items and videos.
5
+ # Provides methods to interact with the snippet YouTube resources.
10
6
  # @see https://developers.google.com/youtube/v3/docs/channels#resource
11
7
  # @see https://developers.google.com/youtube/v3/docs/videos#resource
12
8
  # @see https://developers.google.com/youtube/v3/docs/playlists#resource
@@ -19,102 +15,21 @@ module Yt
19
15
  @auth = options[:auth]
20
16
  end
21
17
 
22
- # @return [String] if the resource is a channel, the channel’s title.
23
- # @return [String] if the resource is a playlist, the playlist’s title.
24
- # @return [String] if the resource is a playlist item, the item’s title.
25
18
  has_attribute :title, default: ''
26
-
27
- # @return [Yt::Models::Description] if the resource is a channel, the
28
- # channel’s description. Has a maximum of 1000 characters.
29
- # @return [Yt::Models::Description] if the resource is a playlist, the
30
- # playlist’s description.
31
- # @return [Yt::Models::Description] if the resource is a playlist item,
32
- # the item’s description.
33
- has_attribute :description, default: '' do |description_text|
34
- Description.new description_text
35
- end
36
-
37
- # @return [Time] if the resource is a channel, the date and time that the
38
- # channel was created.
39
- # @return [Time] if the resource is a playlist, the date and time that
40
- # the playlist was created.
41
- # @return [Time] if the resource is a playlist item, the date and time
42
- # that the item was added to the playlist.
19
+ has_attribute(:description, default: '') {|text| Description.new text}
43
20
  has_attribute :published_at, type: Time
44
-
45
- # @param [Symbol, String] size The size of the thumbnail to retrieve.
46
- # @return [String] if the resource is a channel and +size+ is +default+,
47
- # the URL of an 88x88px image.
48
- # @return [String] if the resource is a playlist or a playlist item and
49
- # +size+ is +default+, the URL of an 120x90px image.
50
- # @return [String] if the resource is a channel and +size+ is +medium+,
51
- # the URL of an 240x240px image.
52
- # @return [String] if the resource is a playlist or a playlist item and
53
- # +size+ is +medium+, the URL of an 320x180px image.
54
- # @return [String] if the resource is a channel and +size+ is +high+,
55
- # the URL of an 800x800px image.
56
- # @return [String] if the resource is a playlist or a playlist item and
57
- # +size+ is +high+, the URL of an 480x360px image.
58
- # @return [nil] if the +size+ is not +default+, +medium+ or +high+.
59
- def thumbnail_url(size = :default)
60
- thumbnails.fetch(size.to_s, {})['url']
61
- end
62
-
63
- # @return [String] if the resource is a playlist, the ID that YouTube
64
- # uses to uniquely identify the channel that the playlist belongs to.
65
- # @return [String] if the resource is a playlist item, the ID that YouTube
66
- # uses to uniquely identify the channel that the playlist belongs to.
67
- # @return [nil] if the resource is a channel.
68
21
  has_attribute :channel_id
69
-
70
- # @return [String] if the resource is a playlist, the title of the
71
- # channel that the playlist belongs to.
72
- # @return [String] if the resource is a playlist item, the title of the
73
- # channel that the playlist item belongs to.
74
- # @return [nil] if the resource is a channel.
75
22
  has_attribute :channel_title
76
-
77
- # @return [Array<Yt::Models::Tag>] if the resource is a channel, an
78
- # empty array.
79
- # @return [Array<Yt::Models::Tag>] if the resource is a playlist, the
80
- # list of keyword tags associated with the playlist.
81
- # @return [Array<Yt::Models::Tag>] if the resource is a playlist item,
82
- # an empty array.
83
23
  has_attribute :tags, default: []
84
-
85
24
  has_attribute :category_id
86
-
87
- BROADCAST_TYPES = %q(live none upcoming)
88
-
89
25
  has_attribute :live_broadcast_content
90
-
91
- # @return [String] if the resource is a playlist item, the ID that
92
- # YouTube uses to uniquely identify the playlist that the item is in.
93
- # @return [nil] if the resource is a channel.
94
- # @return [nil] if the resource is a playlist.
95
26
  has_attribute :playlist_id
96
-
97
- # @return [Integer] if the resource is a playlist item, the order in
98
- # which the item appears in a playlist. The value is zero-based, so the
99
- # first item has a position of 0, the second item of 1, and so forth.
100
- # @return [nil] if the resource is a channel.
101
- # @return [nil] if the resource is a playlist.
102
27
  has_attribute :position, type: Integer
28
+ has_attribute :resource_id, default: {}
29
+ has_attribute :thumbnails, default: {}
103
30
 
104
- # @return [String] if the resource is a playlist item, the ID of the
105
- # video the playlist item represents in the playlist.
106
- # @return [nil] if the resource is a channel.
107
- # @return [nil] if the resource is a playlist.
108
- def video_id
109
- resource_id['videoId']
110
- end
111
-
112
- # @return [Yt::Models::Video] the video the playlist item represents in
113
- # the playlist.
114
- # @return [nil] if the resource is a channel.
115
- # @return [nil] if the resource is a playlist.
116
- def video
117
- @video ||= Video.new id: video_id, auth: @auth if video_id
31
+ def thumbnail_url(size = :default)
32
+ thumbnails.fetch(size.to_s, {})['url']
118
33
  end
119
34
 
120
35
  # Returns whether YouTube API includes all attributes in this snippet.
@@ -129,11 +44,6 @@ module Yt
129
44
  def complete?
130
45
  @complete ||= data.fetch :complete, true
131
46
  end
132
-
133
- private
134
-
135
- has_attribute :thumbnails, default: {}
136
- has_attribute :resource_id, default: {}
137
47
  end
138
48
  end
139
49
  end