yt 0.25.26 → 0.25.27

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 78dee68c38b98a14d9213c8f01b507425e25cca2
4
- data.tar.gz: f859f557aef4fa1a76940ddaa5488af2515cb0df
3
+ metadata.gz: c5e0f3c2d22ca139c343e25b12d546f27fab7426
4
+ data.tar.gz: ab8d1de072cd33417b2276923dcef81f40fa5063
5
5
  SHA512:
6
- metadata.gz: a98d8b324a2c866fb4ad872e22f7eda31c69dbfc4ce66e11abf5f63fa9a9e497b489a3554ba09baf1c4102b746829ca5fa29eecff3e93dea2887288e4a4ab88d
7
- data.tar.gz: 8f0da58402c694c51f1b229bf4fd9afe0f2c638893d9086311bb82734639ae523c73b28d6ae441359dc309a2883d0ddfb549bfef56c95468b3648fc4a6cea3f1
6
+ metadata.gz: c9817c82f21347ab5b0b5f2d1b866ae5de343ece03e8abfd51902a141618eb766bfa4499c2248d124a38cbd7493eb47cd743698db9eca637fdfeefb6b552573a
7
+ data.tar.gz: 9687e59b2d140f368083380fe593c18818c60f5d03c1184c6b4d604c5f7f2420b57d64138ba6b8b2427cf097527b90e493598aa64cc3899799f4ec7cf97f2c69
@@ -6,6 +6,11 @@ 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.25.27 - 2016-03-28
10
+
11
+ * [FEATURE] Add `comment_threads` association to Yt::Video.
12
+ * [FEATURE] Add `top_level_comment` and delegate its attributes (`text_display`, `author_display_name`, `like_count`, `updated_at`) to Yt::CommentThread.
13
+
9
14
  ## 0.25.26 - 2016-03-24
10
15
 
11
16
  * [FEATURE] Add Yt::Comment resource.
data/README.md CHANGED
@@ -28,6 +28,9 @@ video.title #=> "Fullscreen Creator Platform"
28
28
  video.comment_count #=> 308
29
29
  video.hd? #=> true
30
30
  video.annotations.count #=> 1
31
+ video.comment_threads #=> #<Yt::Collections::CommentThreads ...>
32
+ # Use #take to limit the number of pages need to fetch from server
33
+ video.comment_threads.take(99).map(&:author_display_name) #=> ["Paul", "Tommy", ...]
31
34
  ```
32
35
 
33
36
  The **full documentation** is available at [rubydoc.info](http://www.rubydoc.info/gems/yt/frames).
@@ -130,6 +133,12 @@ comment_thread.video_id #=> "1234"
130
133
  comment_thread.total_reply_count #=> 1
131
134
  comment_thread.can_reply? #=> true
132
135
  comment_thread.public? #=> true
136
+
137
+ comment_thread.top_level_comment #=> #<Yt::Models::Comment ...>
138
+ comment_thread.text_display #=> "funny video!"
139
+ comment_thread.like_count #=> 9
140
+ comment_thread.updated_at #=> 2016-03-22 12:56:56 UTC
141
+ comment_thread.author_display_name #=> "Joe"
133
142
  ```
134
143
 
135
144
  Yt::Comment
@@ -6,7 +6,7 @@ require 'yt/config'
6
6
  module Yt
7
7
  module Actions
8
8
  module List
9
- delegate :any?, :count, :each, :each_cons, :each_slice, :find, :first,
9
+ delegate :any?, :count, :each, :each_cons, :each_slice, :find, :first, :take,
10
10
  :flat_map, :map, :select, :size, to: :list
11
11
 
12
12
  def first!
@@ -136,4 +136,4 @@ module Yt
136
136
  end
137
137
  end
138
138
  end
139
- end
139
+ end
@@ -0,0 +1,41 @@
1
+ require 'yt/collections/base'
2
+ require 'yt/models/video'
3
+ require 'yt/models/channel'
4
+
5
+ module Yt
6
+ module Collections
7
+ # @private
8
+ class CommentThreads < Base
9
+
10
+ private
11
+
12
+ def attributes_for_new_item(data)
13
+ {}.tap do |attributes|
14
+ attributes[:id] = data['id']
15
+ attributes[:snippet] = data['snippet']
16
+ attributes[:auth] = @auth
17
+ end
18
+ end
19
+
20
+ # @return [Hash] the parameters to submit to YouTube to get the resource.
21
+ # @see https://developers.google.com/youtube/v3/docs/commentThreads#resource
22
+ def list_params
23
+ super.tap do |params|
24
+ params[:path] = "/youtube/v3/commentThreads"
25
+ params[:params] = comments_params
26
+ end
27
+ end
28
+
29
+ def comments_params
30
+ apply_where_params!({max_results: 100, part: 'snippet'}).tap do |params|
31
+ case @parent
32
+ when Yt::Video
33
+ params[:videoId] = @parent.id
34
+ when Yt::Channel
35
+ params[:channelId] = @parent.id
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -2,21 +2,21 @@ require 'yt/models/resource'
2
2
 
3
3
  module Yt
4
4
  module Models
5
- # Provides methods to interact with YouTube channels.
5
+ # Provides methods to interact with YouTube comment thread.
6
6
  # @see https://developers.google.com/youtube/v3/docs/commentThreads
7
7
  class CommentThread < Resource
8
8
 
9
9
  ### SNIPPET ###
10
10
 
11
11
  # @!attribute [r] video_id
12
- # @return [String] the ID of the video that the comments refer to, if
13
- # any. If this property is not present or does not have a value, then
14
- # the thread applies to the channel and not to a specific video.
12
+ # @return [String] the ID of the video that the comment thread referto, if
13
+ # any. If this property is not present or does not have a value, then the
14
+ # thread applies to the channel and not to a specific video.
15
15
  delegate :video_id, to: :snippet
16
16
 
17
17
  # @!attribute [r] total_reply_count
18
18
  # @return [String] The total number of replies that have been submitted
19
- # in response to the top-level comment.
19
+ # in response to the top level comment.
20
20
  delegate :total_reply_count, to: :snippet
21
21
 
22
22
  # @return [Boolean] whether the thread, including all of its comments and
@@ -25,6 +25,26 @@ module Yt
25
25
 
26
26
  # @return [Boolean] whether the current viewer can reply to the thread.
27
27
  delegate :can_reply?, to: :snippet
28
+
29
+ # @!attribute [r] top_level_comment
30
+ # @return [Yt::TopLevelComment] the top level comment object.
31
+ delegate :top_level_comment, to: :snippet
32
+
33
+ # @!attribute [r] text_display
34
+ # @return [String] the top level comment's display text.
35
+ delegate :text_display, to: :top_level_comment
36
+
37
+ # @!attribute [r] author_display_name
38
+ # @return [String] the top level comment's author name.
39
+ delegate :author_display_name, to: :top_level_comment
40
+
41
+ # @!attribute [r] like_count
42
+ # @return [String] the top level comment's likes count.
43
+ delegate :like_count, to: :top_level_comment
44
+
45
+ # @!attribute [r] updated_at
46
+ # @return [String] the top level comment's last updated time.
47
+ delegate :updated_at, to: :top_level_comment
28
48
  end
29
49
  end
30
50
  end
@@ -1,4 +1,5 @@
1
1
  require 'yt/models/description'
2
+ require 'yt/models/comment'
2
3
 
3
4
  module Yt
4
5
  module Models
@@ -38,7 +39,6 @@ module Yt
38
39
  has_attribute :like_count, type: Integer
39
40
  has_attribute :updated_at, type: Time
40
41
 
41
-
42
42
  def thumbnail_url(size = :default)
43
43
  thumbnails.fetch(size.to_s, {})['url']
44
44
  end
@@ -51,6 +51,10 @@ module Yt
51
51
  @can_reply ||= data.fetch 'canReply', false
52
52
  end
53
53
 
54
+ def top_level_comment
55
+ @top_level_comment ||= Yt::Comment.new data['topLevelComment'].symbolize_keys
56
+ end
57
+
54
58
  # Returns whether YouTube API includes all attributes in this snippet.
55
59
  # For instance, YouTube API only returns tags and categoryId on
56
60
  # Videos#list, not on Videos#search. And returns position on
@@ -369,6 +369,9 @@ module Yt
369
369
  delegate :concurrent_viewers, to: :live_streaming_detail
370
370
 
371
371
  ### ASSOCIATIONS ###
372
+ # @!attribute [r] comments
373
+ # @return [Yt::Collections::Comments] the video’s comments.
374
+ has_many :comment_threads
372
375
 
373
376
  # @!attribute [r] annotations
374
377
  # @return [Yt::Collections::Annotations] the video’s annotations.
@@ -1,3 +1,3 @@
1
1
  module Yt
2
- VERSION = '0.25.26'
2
+ VERSION = '0.25.27'
3
3
  end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+ require 'yt/collections/comment_threads'
3
+ require 'yt/models/video'
4
+ require 'yt/models/channel'
5
+
6
+ describe Yt::Collections::CommentThreads do
7
+ subject(:collection) { Yt::Collections::CommentThreads.new parent: parent}
8
+
9
+ describe '#size', :ruby2 do
10
+ describe 'sends only one request and return the total results' do
11
+ let(:total_results) { 1234 }
12
+ let(:parent) { Yt::Video.new id: 'any-id' }
13
+
14
+ before do
15
+ expect_any_instance_of(Yt::Request).to receive(:run).once do
16
+ double(body: {'pageInfo'=>{'totalResults'=>total_results}})
17
+ end
18
+ end
19
+ it { expect(collection.size).to be total_results }
20
+ end
21
+ end
22
+
23
+ describe '#count' do
24
+ let(:query) { {q: 'search string'} }
25
+ let(:parent) { Yt::Video.new id: 'any-id' }
26
+ let(:page) { {items: [], token: 'any-token'} }
27
+
28
+ context 'called once with .where(query) and once without' do
29
+ after do
30
+ collection.where(query).count
31
+ collection.count
32
+ end
33
+
34
+ it 'only applies the query on the first call' do
35
+ expect(collection).to receive(:fetch_page) do |options|
36
+ expect(options[:params]).to include query
37
+ page
38
+ end
39
+ expect(collection).to receive(:fetch_page) do |options|
40
+ expect(options[:params]).not_to include query
41
+ page
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -23,6 +23,38 @@ describe Yt::CommentThread do
23
23
  end
24
24
  end
25
25
 
26
+ describe '#top_level_comment' do
27
+ context 'given a snippet with a top level comment' do
28
+ let(:attrs) { {snippet: {"topLevelComment"=> {}}} }
29
+ it { expect(comment_thread.top_level_comment).to be_a Yt::Comment }
30
+ end
31
+ end
32
+
33
+ describe 'attributes from #top_level_comment delegations' do
34
+ context 'with values' do
35
+ let(:attrs) { {snippet: {"topLevelComment"=> {"id" => "xyz123", "snippet" => {
36
+ "textDisplay" => "funny video!",
37
+ "authorDisplayName" => "fullscreen",
38
+ "likeCount" => 99,
39
+ "updatedAt" => "2016-03-22T12:56:56.3Z"}}}} }
40
+
41
+ it { expect(comment_thread.top_level_comment.id).to eq 'xyz123' }
42
+ it { expect(comment_thread.text_display).to eq 'funny video!' }
43
+ it { expect(comment_thread.author_display_name).to eq 'fullscreen' }
44
+ it { expect(comment_thread.like_count).to eq 99 }
45
+ it { expect(comment_thread.updated_at).to eq Time.parse('2016-03-22T12:56:56.3Z') }
46
+ end
47
+
48
+ context 'without values' do
49
+ let(:attrs) { {snippet: {"topLevelComment"=> {"snippet" => {}}}} }
50
+
51
+ it { expect(comment_thread.text_display).to be_nil }
52
+ it { expect(comment_thread.author_display_name).to be_nil }
53
+ it { expect(comment_thread.like_count).to be_nil }
54
+ it { expect(comment_thread.updated_at).to be_nil }
55
+ end
56
+ end
57
+
26
58
  describe '#total_reply_count' do
27
59
  context 'given a snippet with a total reply count' do
28
60
  let(:attrs) { {snippet: {"totalReplyCount"=>1}} }
@@ -1,5 +1,6 @@
1
1
  require 'spec_helper'
2
2
  require 'yt/models/comment_thread'
3
+ require 'yt/models/comment'
3
4
 
4
5
  describe Yt::CommentThread, :server_app do
5
6
  subject(:comment_thread) { Yt::CommentThread.new attrs }
@@ -11,6 +12,12 @@ describe Yt::CommentThread, :server_app do
11
12
  it { expect(comment_thread.total_reply_count).to be_an Integer }
12
13
  it { expect(comment_thread.can_reply?).to be false }
13
14
  it { expect(comment_thread).to be_public }
15
+
16
+ it { expect(comment_thread.top_level_comment).to be_a Yt::Comment }
17
+ it { expect(comment_thread.text_display).not_to be_empty }
18
+ it { expect(comment_thread.author_display_name).not_to be_empty }
19
+ it { expect(comment_thread.updated_at).to be_a Time }
20
+ it { expect(comment_thread.like_count).to be_a Integer }
14
21
  end
15
22
 
16
23
  context 'given an comment thread ID about a video' do
@@ -0,0 +1,41 @@
1
+ # encoding: UTF-8
2
+ require 'spec_helper'
3
+ require 'yt/collections/comment_threads'
4
+ require 'yt/models/video'
5
+ require 'yt/models/channel'
6
+
7
+ describe Yt::Collections::CommentThreads, :server_app do
8
+ context "without parent association", :ruby2 do
9
+ subject(:comment_threads) { Yt::Collections::CommentThreads.new }
10
+
11
+ specify 'without given any of id, videoId, channelId or allThreadsRelatedToChannelId param, raise request error', :ruby2 do
12
+ expect{ comment_threads.size }.to raise_error(Yt::Errors::RequestError)
13
+ end
14
+
15
+ specify 'with a id param, only return one comment thread' do
16
+ expect(comment_threads.where(id: 'z13zytsilxbexh30e233gdyyttngfjfz104').size).to eq 1
17
+ end
18
+
19
+ specify 'with a videoId param, returns comment threads for the video', focus: true do
20
+ expect(comment_threads.where(videoId: 'MsplPPW7tFo').size).to be > 0
21
+ end
22
+
23
+ specify 'with a channelId param, returns comment threads for the channel' do
24
+ expect(comment_threads.where(channelId: 'UC-lHJZR3Gqxm24_Vd_AJ5Yw').size).to be > 0
25
+ end
26
+ end
27
+
28
+ context "with parent association", :ruby2 do
29
+ subject(:comment_threads) { Yt::Collections::CommentThreads.new parent: parent}
30
+
31
+ context "parent as video" do
32
+ let(:parent) { Yt::Models::Video.new id: 'MsplPPW7tFo' }
33
+ it { expect(comment_threads.size).to be > 0 }
34
+ end
35
+
36
+ context "parent as channel" do
37
+ let(:parent) { Yt::Models::Channel.new id: 'UC-lHJZR3Gqxm24_Vd_AJ5Yw' }
38
+ it { expect(comment_threads.size).to be > 0 }
39
+ end
40
+ end
41
+ end
@@ -1,11 +1,12 @@
1
1
  require 'spec_helper'
2
2
  require 'yt/models/video'
3
+ require 'yt/collections/comment_threads'
3
4
 
4
5
  describe Yt::Video, :server_app do
5
6
  subject(:video) { Yt::Video.new attrs }
6
7
 
7
8
  context 'given an existing video ID' do
8
- let(:attrs) { {id: 'MESycYJytkU'} }
9
+ let(:attrs) { {id: 'L3JDXvz7G6c'} }
9
10
 
10
11
  it { expect(video.content_detail).to be_a Yt::ContentDetail }
11
12
 
@@ -27,11 +28,11 @@ describe Yt::Video, :server_app do
27
28
  end
28
29
 
29
30
  context 'given an existing video URL' do
30
- let(:attrs) { {url: 'https://www.youtube.com/watch?v=MESycYJytkU&list=LLxO1tY8h1AhOz0T4ENwmpow'} }
31
+ let(:attrs) { {url: 'https://www.youtube.com/watch?v=L3JDXvz7G6c'} }
31
32
 
32
33
  specify 'provides access to its data' do
33
- expect(video.id).to eq 'MESycYJytkU'
34
- expect(video.title).to eq 'Fullscreen Creator Platform'
34
+ expect(video.id).to eq 'L3JDXvz7G6c'
35
+ expect(video.title).to eq "you’re in fullscreen"
35
36
  expect(video.privacy_status).to eq 'public'
36
37
  end
37
38
  end
@@ -55,4 +56,24 @@ describe Yt::Video, :server_app do
55
56
  end
56
57
  end
57
58
 
58
- end
59
+ describe 'associations' do
60
+ let(:attrs) { {id: 'MsplPPW7tFo'} }
61
+
62
+ describe '#comment_threads' do
63
+ it { expect(video.comment_threads).to be_a Yt::Collections::CommentThreads }
64
+ it { expect(video.comment_threads.first.top_level_comment).to be_a Yt::Models::Comment }
65
+ end
66
+
67
+ describe '#comment_threads.each_cons' do
68
+ it {
69
+ comment_threads = []
70
+ video.comment_threads.each_cons(2).take_while do |items|
71
+ comment_threads += items
72
+ comment_threads.size < 6
73
+ end
74
+ expect(comment_threads.size).to be 6
75
+ }
76
+ end
77
+ end
78
+ end
79
+
@@ -22,7 +22,7 @@ describe Yt::Collections::Videos, :server_app do
22
22
  end
23
23
 
24
24
  specify 'with a chart parameter, only returns videos of that chart', :ruby2 do
25
- expect(videos.where(chart: 'mostPopular').size).to be 30
25
+ expect(videos.where(chart: 'mostPopular').size).to be 200
26
26
  end
27
27
 
28
28
  context 'with a list of parts' do
@@ -37,4 +37,4 @@ describe Yt::Collections::Videos, :server_app do
37
37
  expect(video.instance_variable_defined? :@content_detail).to be true
38
38
  end
39
39
  end
40
- end
40
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.25.26
4
+ version: 0.25.27
5
5
  platform: ruby
6
6
  authors:
7
7
  - Claudio Baccigalupo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-24 00:00:00.000000000 Z
11
+ date: 2016-04-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -137,6 +137,7 @@ files:
137
137
  - lib/yt/collections/channels.rb
138
138
  - lib/yt/collections/claim_histories.rb
139
139
  - lib/yt/collections/claims.rb
140
+ - lib/yt/collections/comment_threads.rb
140
141
  - lib/yt/collections/content_details.rb
141
142
  - lib/yt/collections/content_owner_details.rb
142
143
  - lib/yt/collections/content_owners.rb
@@ -229,6 +230,7 @@ files:
229
230
  - lib/yt/request.rb
230
231
  - lib/yt/version.rb
231
232
  - spec/collections/claims_spec.rb
233
+ - spec/collections/comment_threads_spec.rb
232
234
  - spec/collections/playlist_items_spec.rb
233
235
  - spec/collections/playlists_spec.rb
234
236
  - spec/collections/policies_spec.rb
@@ -300,6 +302,7 @@ files:
300
302
  - spec/requests/as_server_app/channel_spec.rb
301
303
  - spec/requests/as_server_app/comment_spec.rb
302
304
  - spec/requests/as_server_app/comment_thread_spec.rb
305
+ - spec/requests/as_server_app/comment_threads_spec.rb
303
306
  - spec/requests/as_server_app/playlist_item_spec.rb
304
307
  - spec/requests/as_server_app/playlist_spec.rb
305
308
  - spec/requests/as_server_app/video_spec.rb
@@ -336,6 +339,7 @@ summary: Yt makes it easy to interact with Youtube V3 API by providing a modular
336
339
  intuitive and tested Ruby-style API.
337
340
  test_files:
338
341
  - spec/collections/claims_spec.rb
342
+ - spec/collections/comment_threads_spec.rb
339
343
  - spec/collections/playlist_items_spec.rb
340
344
  - spec/collections/playlists_spec.rb
341
345
  - spec/collections/policies_spec.rb
@@ -407,6 +411,7 @@ test_files:
407
411
  - spec/requests/as_server_app/channel_spec.rb
408
412
  - spec/requests/as_server_app/comment_spec.rb
409
413
  - spec/requests/as_server_app/comment_thread_spec.rb
414
+ - spec/requests/as_server_app/comment_threads_spec.rb
410
415
  - spec/requests/as_server_app/playlist_item_spec.rb
411
416
  - spec/requests/as_server_app/playlist_spec.rb
412
417
  - spec/requests/as_server_app/video_spec.rb