yt-core 0.1.4 → 0.1.5
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.
- checksums.yaml +4 -4
- data/.travis.yml +8 -3
- data/CHANGELOG.md +6 -0
- data/README.md +13 -3
- data/docs/channels.html +29 -0
- data/docs/playlist_items.html +21 -0
- data/lib/yt/channel.rb +30 -2
- data/lib/yt/comment_thread.rb +1 -1
- data/lib/yt/core.rb +1 -0
- data/lib/yt/core/version.rb +1 -1
- data/lib/yt/playlist.rb +2 -2
- data/lib/yt/playlist_item.rb +22 -0
- data/lib/yt/relation.rb +3 -3
- data/lib/yt/resource.rb +4 -4
- data/lib/yt/response.rb +42 -4
- data/lib/yt/video.rb +1 -1
- data/yt-core.gemspec +2 -1
- metadata +18 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 38fe8ee547f6c51750be3b935de33654304a92bc
|
4
|
+
data.tar.gz: ca5b035d73c726d4f9f4a2428b3a4cc6cb573515
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3201de66a86b9df6caf10792426616f01ea177153983090cb32d1bd19f83f99b947b79f9012d4e33f34411930e5f3c978664d6d9c3f7b2c536ccbb4412523a52
|
7
|
+
data.tar.gz: 0f1daea896d3ea422837992e8b3f1aeefb04d0576af63e51f783ae00ac5234b45ccf7ce3d77b2fc84578968fc1e69a37befb9ac9d32b3c3cfb7ef2669c0653b1
|
data/.travis.yml
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
|
3
|
+
- 2.2.2
|
4
4
|
script:
|
5
|
-
|
6
|
-
|
5
|
+
- bundle exec rspec
|
6
|
+
- bundle exec yard stats | grep "100.00% documented"
|
7
|
+
notifications:
|
8
|
+
slack:
|
9
|
+
secure: q+C+6nmfAg0W3ZqmqCyV7cRJXoJX22WPHodEYI5WVE7PY2Y42phHOIipXeUFta3CF3VO5sk4MLXh08y0WtShi/ZGpUui0ZH8aimplUlPbbmwKukAGAwYJp7q/trU3hPZd2CkQoBBWNmJsx2aU4X39aYpUOExYrSwW4Cu17hgW1y2m3kxNJyOocuaAuMZyWYY8ktH0C5sVfL0LR7U8Ct8B9D72yyXzLrPOlTWkrln7e82tirh318XqWRM8YLLLGkwaOBqptxkNbmbNu/y+SKiqixcSUPDhLAjRXsByhDlR2f9kZsQZJ/1YnQFl/SygiL39JNMWY8aiHkN15N5iWiocalw/r+oSdZApWf7Ts69cgtoPGxNDt8L73FXs5tnhNOEkm/3kc+Vkq7mnrvX1l0Z0wqdcmZekiw31u30j/j6GU2WHC3C4taJ9TJIc7AfNUntg0l1GXh1aKi62pEdVVgJWLPU8MKXn0Z+2Me2ALrFjfGkfbGXD1lbIlQ/UfyiDyzmqN+DpT7UNcUuXKH4N/BoJtqr9upnXZsVIr0+mVD0/rpo7lZtNHsYaP1BtywKcKdXs4TNHSV51cE3ZUtAweGRsgnQsLWtszQPPG98OLFpqJP5wKRaAuIEI0134uf6V+DqWyICPY6oGX1BTbm8LuXCby7I8ErHI4V16tWuiNm6ojQ=
|
10
|
+
on_success: never
|
11
|
+
on_failure: change
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,12 @@ 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.1.5 - 2017-08-24
|
10
|
+
|
11
|
+
* [FEATURE] Add `Yt::PlaylistItem.insert` and `Yt::PlaylistItem#delete`
|
12
|
+
* [FEATURE] Add `Channel#related_playlists` and `Channel#like_playlists`
|
13
|
+
* [FEATURE] Add Channel.mine
|
14
|
+
|
9
15
|
## 0.1.4 - 2017-06-02
|
10
16
|
|
11
17
|
* [FEATURE] Add CommentThread#comments
|
data/README.md
CHANGED
@@ -57,11 +57,21 @@ To run live-tests against the YouTube API, type:
|
|
57
57
|
rspec
|
58
58
|
```
|
59
59
|
|
60
|
-
|
61
|
-
|
60
|
+
Note that some tests actually hit the YouTube API, and therefore require
|
61
|
+
either an API key or authentication credentials.
|
62
62
|
|
63
|
-
|
63
|
+
In order to run tests marked as :server you need to set up a test YouTube
|
64
|
+
application with access to the YouTube Data API v3 and an environment variable:
|
64
65
|
|
66
|
+
- `YT_SERVER_API_KEY`: API Key of a Google app with access to the YouTube Data API v3
|
67
|
+
|
68
|
+
In order to run tests marked as :account you als need to create a client ID
|
69
|
+
and secret and then generate a refresh token for the account you want to use
|
70
|
+
as test. Make sure this account has a channel with at least one playlist:
|
71
|
+
|
72
|
+
- `YT_ACCOUNT_CLIENT_ID`: Client ID of a Google app with access to the YouTube Data API v3
|
73
|
+
- `YT_ACCOUNT_CLIENT_SECRET`: Client Secret of a Google app with access to the YouTube Data API v3
|
74
|
+
- `YT_ACCOUNT_REFRESH_TOKEN`: Refresh token of a YouTube account for the app above
|
65
75
|
|
66
76
|
How to release new versions
|
67
77
|
===========================
|
data/docs/channels.html
CHANGED
@@ -32,6 +32,21 @@ channel = Yt::Channel.new id: 'UCwCnUcLcb9-eSrHa_RQGkQQ' ## use any chan
|
|
32
32
|
channel.title # => "Yt Test"
|
33
33
|
{% endhighlight %}
|
34
34
|
|
35
|
+
|
36
|
+
<p>
|
37
|
+
Other methods <strong>acts on behalf of YouTube accounts</strong> (e.g.: subscribe to a channel, delete playlists).<br />
|
38
|
+
To use these methods (marked with <span class="label label-warning"> </span> below), you need to <a href="{{ site.baseurl }}/#api_client">get an API Client ID/Secret from Google</a>, then <a href="{{ site.baseurl }}/#tokens">obtain a refresh token</a> from the account you want to act as, and finally configure the values:
|
39
|
+
</p>
|
40
|
+
|
41
|
+
{% highlight ruby %}
|
42
|
+
Yt.configuration.client_id = "<your ID>" ## replace with your client ID
|
43
|
+
Yt.configuration.client_secret = "<your secret>" ## replace with your client secret
|
44
|
+
Yt.configuration.refresh_token = "<token>" ## use the account’s refresh token
|
45
|
+
|
46
|
+
channel = Yt::Channel.mine
|
47
|
+
# => #<Yt::Channel @id=UCwCnUcLcb9-eSrHa_RQGkQQ>
|
48
|
+
{% endhighlight %}
|
49
|
+
|
35
50
|
<hr />
|
36
51
|
<h4>List of <code>Yt::Channel</code> data methods</h4>
|
37
52
|
<dl>
|
@@ -70,6 +85,12 @@ channel.title # => "Yt Test"
|
|
70
85
|
{% include doc.html instance="Channel#featured_channels_title" %}{% include example.html object='channel' method='featured_channels_title' result='"Featured channels"' %}
|
71
86
|
{% include doc.html instance="Channel#featured_channels_urls" %}{% include example.html object='channel' method='featured_channels_urls' result='["UCxO1tY8h1AhOz0T4ENwmpow"]' %}</pre>
|
72
87
|
</div></dd>
|
88
|
+
|
89
|
+
{% include dt.html title="Channel’s content details" label="warning" auth="must authenticate as the channel’s account" %}
|
90
|
+
<dd><a class="anchor" id="content_details"></a><div class="highlight"><pre>
|
91
|
+
{% include doc.html instance="Channel#related_playlists" %}{% include example.html object='channel' method='related_playlists' result='{"likes"=>"LLwCncb9-e", "watchHistory"=>"HL"}' %}
|
92
|
+
{% include doc.html instance="Channel#like_playlists" %}{% include example.html object='channel' method='like_playlists' result='#<Yt::Relation [#<Yt::Playlist @id=LLWCncb...>]>' %}</pre>
|
93
|
+
</div></dd>
|
73
94
|
</dl>
|
74
95
|
<p>
|
75
96
|
To limit the number of HTTP requests, use <code>select</code> to specify which <a href="https://developers.google.com/youtube/v3/docs/channels/list#part">parts</a> of the channel’s data to load:
|
@@ -142,3 +163,11 @@ channel.title # => "Yt Test"
|
|
142
163
|
The previous method returns existing channels that match the provided IDs, skipping any unrecognized ID.<br />
|
143
164
|
As usual, use <code>select</code> to specify which <a href="https://developers.google.com/youtube/v3/docs/channels/list#part">parts</a> of each channels’s data to load before iterating through the list.
|
144
165
|
</p>
|
166
|
+
|
167
|
+
<dl>
|
168
|
+
{% include dt.html title="Authenticated account’s channel" label="warning" auth="must authenticate as the channel’s account" %}
|
169
|
+
<dd><a class="anchor" id="mine"></a><div class="highlight"><pre>
|
170
|
+
{% include doc.html class="Channel#mine" %}{% include example.html object='<span class="no">Yt</span><span class="o">::</span><span class="no">Channel</span>' method='mine' %}
|
171
|
+
{% include example.html result='#<Yt::Channel @id=UCwCnUcLcb9-eSrHa_RQGkQQ>' %}</pre>
|
172
|
+
</div></dd>
|
173
|
+
</dl>
|
data/docs/playlist_items.html
CHANGED
@@ -27,6 +27,20 @@ item = Yt::PlaylistItem.new id: 'UEwtTGVUdXRjOUdSS0Qze' ## use any playlist item
|
|
27
27
|
item.position # => 0
|
28
28
|
{% endhighlight %}
|
29
29
|
|
30
|
+
<p>
|
31
|
+
Other methods <strong>acts on behalf of YouTube accounts</strong> (e.g.: add an item to a playlist).<br />
|
32
|
+
To use these methods (marked with <span class="label label-warning"> </span> below), you need to <a href="{{ site.baseurl }}/#api_client">get an API Client ID/Secret from Google</a>, then <a href="{{ site.baseurl }}/#tokens">obtain a refresh token</a> from the account you want to act as, and finally configure the values:
|
33
|
+
</p>
|
34
|
+
|
35
|
+
{% highlight ruby %}
|
36
|
+
Yt.configuration.client_id = "<your ID>" ## replace with your client ID
|
37
|
+
Yt.configuration.client_secret = "<your secret>" ## replace with your client secret
|
38
|
+
Yt.configuration.refresh_token = "<token>" ## use the account’s refresh token
|
39
|
+
|
40
|
+
Yt::PlaylistItem.insert playlist_id: 'PL-LeTutc9GRKD3DhnRF_y', video_id: 'gknzFj_0vvY'
|
41
|
+
# => #<Yt::PlaylistItem:0x... @id=UEwtTGVUdXRjOUdSS0Qze>
|
42
|
+
{% endhighlight %}
|
43
|
+
|
30
44
|
<hr />
|
31
45
|
<h4>List of <code>Yt::PlaylistItem</code> data methods</h4>
|
32
46
|
<dl>
|
@@ -63,3 +77,10 @@ item.position # => 0
|
|
63
77
|
{% include example.html object='fast' method='privacy_status' result='=> no extra HTTP requests' %}</pre>
|
64
78
|
</div></dd>
|
65
79
|
</dl>
|
80
|
+
<dl>
|
81
|
+
{% include dt.html title="Adding and removing a playlist item" label="warning" auth="must authenticate as the channel’s account" %}
|
82
|
+
<dd><a class="anchor" id="insert_remove"></a><div class="highlight"><pre>
|
83
|
+
{% include doc.html class="PlaylistItem#insert" %}{% include example.html object='item = <span class="no">Yt</span><span class="o">::</span><span class="no">PlaylistItem</span>' method='insert' params=' <span class="ss">playlist_id:</span> <span class="s1">"PL-..."</span>, <span class="ss">video_id:</span> <span class="s1">"gknzFj_0vvY"</span>' %}
|
84
|
+
{% include doc.html instance="PlaylistItem#delete" %}{% include example.html object='item' method='delete' result='true' %}</pre>
|
85
|
+
</div></dd>
|
86
|
+
</dl>
|
data/lib/yt/channel.rb
CHANGED
@@ -91,6 +91,11 @@ module Yt
|
|
91
91
|
# channels module.
|
92
92
|
has_attribute :featured_channels_urls, in: %i(branding_settings channel), default: []
|
93
93
|
|
94
|
+
# @!attribute [r] related_playlists
|
95
|
+
# @return [Hash] the playlists associated with the channel, such as the
|
96
|
+
# channel's uploaded videos, liked videos, and watch history.
|
97
|
+
has_attribute :related_playlists, in: :content_details
|
98
|
+
|
94
99
|
# @return [String] the canonical form of the channel’s URL.
|
95
100
|
def canonical_url
|
96
101
|
"https://www.youtube.com/channel/#{id}"
|
@@ -122,7 +127,7 @@ module Yt
|
|
122
127
|
# @see https://developers.google.com/youtube/v3/docs/search/list#channelId
|
123
128
|
def videos
|
124
129
|
@videos ||= Relation.new(Video, channel_id: id, limit: 500) do |options|
|
125
|
-
items =
|
130
|
+
items = get '/youtube/v3/search', channel_videos_params(options)
|
126
131
|
videos_for items, 'id', options
|
127
132
|
end
|
128
133
|
end
|
@@ -130,8 +135,31 @@ module Yt
|
|
130
135
|
# @return [Yt::Relation<Yt::Playlist>] the public playlists of the channel.
|
131
136
|
def playlists
|
132
137
|
@playlists ||= Relation.new(Playlist, channel_id: id) do |options|
|
133
|
-
|
138
|
+
get '/youtube/v3/playlists', channel_playlists_params(options)
|
134
139
|
end
|
135
140
|
end
|
141
|
+
|
142
|
+
# @return [Yt::Relation<Yt::Playlist>] the playlists associated with
|
143
|
+
# liked videos. Includes the deprecated favorites if still present.
|
144
|
+
def like_playlists
|
145
|
+
@like_lists ||= Relation.new(Playlist, ids: like_list_ids) do |options|
|
146
|
+
get '/youtube/v3/playlists', resource_params(options)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
# @return [Yt::Channel] the channel associated with the YouTube account
|
151
|
+
# that provided the authentication token.
|
152
|
+
def self.mine
|
153
|
+
Relation.new(self) do |options|
|
154
|
+
get '/youtube/v3/channels', mine: true, part: 'id'
|
155
|
+
end.first
|
156
|
+
end
|
157
|
+
|
158
|
+
private
|
159
|
+
|
160
|
+
def like_list_ids
|
161
|
+
names = %w(likes favorites)
|
162
|
+
related_playlists.select{|name,_| names.include? name}.values
|
163
|
+
end
|
136
164
|
end
|
137
165
|
end
|
data/lib/yt/comment_thread.rb
CHANGED
@@ -20,7 +20,7 @@ module Yt
|
|
20
20
|
def comments
|
21
21
|
@comments ||= Relation.new(Comment, parent_id: id,
|
22
22
|
initial_items: -> {[top_level_comment]}) do |options|
|
23
|
-
|
23
|
+
get '/youtube/v3/comments', thread_comments_params(options)
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
data/lib/yt/core.rb
CHANGED
data/lib/yt/core/version.rb
CHANGED
data/lib/yt/playlist.rb
CHANGED
@@ -59,7 +59,7 @@ module Yt
|
|
59
59
|
# @return [Yt::Relation<Yt::PlaylistItem>] the items of the playlist.
|
60
60
|
def items
|
61
61
|
@items ||= Relation.new(PlaylistItem, playlist_id: id) do |options|
|
62
|
-
|
62
|
+
get '/youtube/v3/playlistItems', playlist_items_params(options)
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
@@ -67,7 +67,7 @@ module Yt
|
|
67
67
|
def videos
|
68
68
|
@videos ||= Relation.new(Video, playlist_id: id) do |options|
|
69
69
|
params = playlist_items_params(options.merge parts: [:content_details])
|
70
|
-
items =
|
70
|
+
items = get '/youtube/v3/playlistItems', params
|
71
71
|
videos_for items, 'contentDetails', options
|
72
72
|
end
|
73
73
|
end
|
data/lib/yt/playlist_item.rb
CHANGED
@@ -55,5 +55,27 @@ module Yt
|
|
55
55
|
def thumbnail_url(size = :default)
|
56
56
|
thumbnails.fetch(size.to_s, {})['url']
|
57
57
|
end
|
58
|
+
|
59
|
+
# @return [Yt::PlaylistItem] the item created by appending the given
|
60
|
+
# video to the given playlist.
|
61
|
+
def self.insert(playlist_id:, video_id:)
|
62
|
+
parts = %i(id snippet)
|
63
|
+
items = -> (body) { [body] } # the response body only includes one item
|
64
|
+
resource_id = {kind: 'youtube#video', videoId: video_id}
|
65
|
+
snippet = {playlistId: playlist_id, resourceId: resource_id}
|
66
|
+
|
67
|
+
Relation.new(self, parts: parts, extract_items: items) do |options|
|
68
|
+
post '/youtube/v3/playlistItems', {part: 'snippet'}, {snippet: snippet}
|
69
|
+
end.first
|
70
|
+
end
|
71
|
+
|
72
|
+
# @return [Boolean] whether the item was removed from the playlist.
|
73
|
+
def delete
|
74
|
+
items = -> (body) { [{}] } # the response body is empty
|
75
|
+
|
76
|
+
Relation.new(PlaylistItem, id: id, extract_items: items) do |options|
|
77
|
+
delete '/youtube/v3/playlistItems', id: options[:id]
|
78
|
+
end.any?
|
79
|
+
end
|
58
80
|
end
|
59
81
|
end
|
data/lib/yt/relation.rb
CHANGED
@@ -9,7 +9,7 @@ module Yt
|
|
9
9
|
# @yield [Hash] the options to change which items to iterate through.
|
10
10
|
def initialize(item_class, options = {}, &item_block)
|
11
11
|
@options = {parts: %i(id), limit: Float::INFINITY, item_class: item_class,
|
12
|
-
initial_items: -> {[]}}
|
12
|
+
initial_items: -> {[]}, extract_items: -> (body) {body['items']}}
|
13
13
|
@options.merge! options
|
14
14
|
@item_block = item_block
|
15
15
|
end
|
@@ -27,10 +27,10 @@ module Yt
|
|
27
27
|
@items ||= initial_items.dup
|
28
28
|
if @items[@last_index].nil? && more_pages?
|
29
29
|
response = Response.new(@options, &@item_block).run
|
30
|
-
more_items = response.body
|
30
|
+
more_items = @options[:extract_items].call(response.body).map do |item|
|
31
31
|
@options[:item_class].new attributes_for_new_item(item)
|
32
32
|
end
|
33
|
-
@options.merge! offset: response.body['nextPageToken']
|
33
|
+
@options.merge! offset: response.body['nextPageToken'] if response.body
|
34
34
|
@items.concat more_items
|
35
35
|
end
|
36
36
|
@items[(@last_index +=1) -1]
|
data/lib/yt/resource.rb
CHANGED
@@ -34,7 +34,7 @@ module Yt
|
|
34
34
|
def self.where(conditions = {})
|
35
35
|
@where ||= Relation.new(self) do |options|
|
36
36
|
slicing_conditions_every(50) do |slice_options|
|
37
|
-
|
37
|
+
get resources_path, where_params(slice_options)
|
38
38
|
end
|
39
39
|
end
|
40
40
|
@where.where conditions
|
@@ -50,7 +50,7 @@ module Yt
|
|
50
50
|
define_method name do
|
51
51
|
keys = Array(options[:in]) + [name]
|
52
52
|
part = keys.shift
|
53
|
-
value = @data[part] ||
|
53
|
+
value = @data[part] || get_part(part)
|
54
54
|
keys.each{|key| value = value[camelize key]}
|
55
55
|
if value.nil? && options[:default]
|
56
56
|
value = options[:default]
|
@@ -60,9 +60,9 @@ module Yt
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
-
def
|
63
|
+
def get_part(required_part)
|
64
64
|
resources = Relation.new(self.class, ids: [id]) do |options|
|
65
|
-
|
65
|
+
get resources_path, resource_params(options)
|
66
66
|
end
|
67
67
|
|
68
68
|
parts = (@selected_data_parts + [required_part]).uniq
|
data/lib/yt/response.rb
CHANGED
@@ -12,8 +12,47 @@ module Yt
|
|
12
12
|
|
13
13
|
private
|
14
14
|
|
15
|
-
def
|
16
|
-
|
15
|
+
def get(path, params = {})
|
16
|
+
request :get, path: path, params: params
|
17
|
+
end
|
18
|
+
|
19
|
+
def post(path, params = {}, body = {})
|
20
|
+
request :post, path: path, params: params, body: body
|
21
|
+
end
|
22
|
+
|
23
|
+
def delete(path, params = {})
|
24
|
+
request :delete, path: path, params: params
|
25
|
+
end
|
26
|
+
|
27
|
+
def request(method, options = {})
|
28
|
+
HTTPRequest.new(request_options options.merge method: method).run
|
29
|
+
rescue HTTPError => error
|
30
|
+
if unauthorized?(error) && refresh_access_token
|
31
|
+
retry
|
32
|
+
else
|
33
|
+
raise
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def request_options(options)
|
38
|
+
options[:error_message] = ->(body) {JSON(body)['error']['message']}
|
39
|
+
if access_token = Yt.configuration.access_token || refresh_access_token
|
40
|
+
options[:headers] = {'Authorization' => "Bearer #{access_token}"}
|
41
|
+
else
|
42
|
+
options[:params] = options[:params].merge key: Yt.configuration.api_key
|
43
|
+
end
|
44
|
+
options
|
45
|
+
end
|
46
|
+
|
47
|
+
def unauthorized?(error)
|
48
|
+
error.response.is_a? Net::HTTPUnauthorized
|
49
|
+
end
|
50
|
+
|
51
|
+
def refresh_access_token
|
52
|
+
if Yt.configuration.refresh_token
|
53
|
+
auth = Auth.new refresh_token: Yt.configuration.refresh_token
|
54
|
+
Yt.configuration.access_token = auth.access_token
|
55
|
+
end
|
17
56
|
end
|
18
57
|
|
19
58
|
def resources_path
|
@@ -55,7 +94,6 @@ module Yt
|
|
55
94
|
def default_params(options)
|
56
95
|
{}.tap do |params|
|
57
96
|
params[:max_results] = 50
|
58
|
-
params[:key] = Yt.configuration.api_key
|
59
97
|
params[:part] = options[:parts].join ','
|
60
98
|
params[:page_token] = options[:offset]
|
61
99
|
end
|
@@ -90,7 +128,7 @@ module Yt
|
|
90
128
|
else
|
91
129
|
options[:ids] = items.body['items'].map{|item| item['id']}
|
92
130
|
options[:offset] = nil
|
93
|
-
|
131
|
+
get('/youtube/v3/videos', resource_params(options)).tap do |response|
|
94
132
|
response.body['nextPageToken'] = items.body['nextPageToken']
|
95
133
|
end
|
96
134
|
end
|
data/lib/yt/video.rb
CHANGED
@@ -183,7 +183,7 @@ module Yt
|
|
183
183
|
# @return [Yt::Relation<Yt::CommentThread>] the threads of the video.
|
184
184
|
def threads
|
185
185
|
@threads ||= Relation.new(CommentThread, video_id: id) do |options|
|
186
|
-
|
186
|
+
get '/youtube/v3/commentThreads', video_threads_params(options)
|
187
187
|
end
|
188
188
|
end
|
189
189
|
|
data/yt-core.gemspec
CHANGED
@@ -23,7 +23,8 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
24
24
|
spec.require_paths = ['lib']
|
25
25
|
|
26
|
-
spec.add_dependency 'yt-
|
26
|
+
spec.add_dependency 'yt-auth', '>= 0.2.3'
|
27
|
+
spec.add_dependency 'yt-support', '>= 0.1.3'
|
27
28
|
|
28
29
|
spec.add_development_dependency 'bundler', '~> 1.14'
|
29
30
|
spec.add_development_dependency 'rspec', '~> 3.5'
|
metadata
CHANGED
@@ -1,29 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yt-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Claudio Baccigalupo
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-08-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: yt-auth
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.2.3
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.2.3
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: yt-support
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
16
30
|
requirements:
|
17
31
|
- - ">="
|
18
32
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.1.
|
33
|
+
version: 0.1.3
|
20
34
|
type: :runtime
|
21
35
|
prerelease: false
|
22
36
|
version_requirements: !ruby/object:Gem::Requirement
|
23
37
|
requirements:
|
24
38
|
- - ">="
|
25
39
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.1.
|
40
|
+
version: 0.1.3
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: bundler
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|