yt 0.19.0 → 0.20.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.
@@ -12,32 +12,14 @@ module Yt
12
12
  @data = options[:data]
13
13
  end
14
14
 
15
- # @return [Integer] the number of times the resource has been viewed.
16
15
  has_attribute :view_count, type: Integer
17
-
18
- # @return [Integer] the number of comments for the resource.
19
16
  has_attribute :comment_count, type: Integer
20
-
21
- # @return [Integer] the number of users who liked the resource.
22
17
  has_attribute :like_count, type: Integer
23
-
24
- # @return [Integer] the number of users who disliked the resource.
25
18
  has_attribute :dislike_count, type: Integer
26
-
27
- # @return [Integer] the number of users who currently have the resource
28
- # marked as a favorite resource.
29
19
  has_attribute :favorite_count, type: Integer
30
-
31
- # @return [Integer] the number of videos updated to the resource.
32
20
  has_attribute :video_count, type: Integer
33
-
34
- # @return [Integer] the number of subscriber the resource has.
35
21
  has_attribute :subscriber_count, type: Integer
36
-
37
- # @return [Boolean] whether the number of subscribers is publicly visible.
38
- has_attribute :subscriber_count_visible?, from: :hidden_subscriber_count do |hidden|
39
- hidden == false
40
- end
22
+ has_attribute :hidden_subscriber_count
41
23
  end
42
24
  end
43
25
  end
@@ -20,8 +20,6 @@ module Yt
20
20
 
21
21
  # Privacy status
22
22
 
23
- PRIVACY_STATUSES = %q(private public unlisted)
24
-
25
23
  has_attribute :privacy_status
26
24
  has_attribute :upload_status
27
25
  has_attribute :failure_reason
@@ -6,7 +6,7 @@ module Yt
6
6
  # @see https://developers.google.com/youtube/v3/docs/videos
7
7
  class Video < Resource
8
8
 
9
- ### SNIPPET ###
9
+ ### SNIPPET ###
10
10
 
11
11
  # @!attribute [r] title
12
12
  # @return [String] the video’s title.
@@ -16,7 +16,7 @@ module Yt
16
16
  # @return [String] the video’s description.
17
17
  delegate :description, to: :snippet
18
18
 
19
- # Return the URL of the video’s thumbnail.
19
+ # Returns the URL of the video’s thumbnail.
20
20
  # @!method thumbnail_url(size = :default)
21
21
  # @param [Symbol, String] size The size of the video’s thumbnail.
22
22
  # @return [String] if +size+ is +default+, the URL of a 120x90px image.
@@ -364,7 +364,7 @@ module Yt
364
364
  # hidden the viewcount for the video or the video is not live.
365
365
  delegate :concurrent_viewers, to: :live_streaming_detail
366
366
 
367
- ### ANNOTATIONS ###
367
+ ### ASSOCIATIONS ###
368
368
 
369
369
  # @!attribute [r] annotations
370
370
  # @return [Yt::Collections::Annotations] the video’s annotations.
@@ -372,65 +372,65 @@ module Yt
372
372
 
373
373
  ### ANALYTICS ###
374
374
 
375
- # @macro views_report
375
+ # @macro report_by_video_dimensions
376
376
  has_report :views
377
377
 
378
- # @macro demographics_report
378
+ # @macro report_by_video_dimensions
379
+ has_report :estimated_minutes_watched
380
+
381
+ # @macro report_by_gender_and_age_group
379
382
  has_report :viewer_percentage
380
383
 
381
- # @macro daily_report
384
+ # @macro report_by_day
382
385
  has_report :comments
383
386
 
384
- # @macro daily_report
387
+ # @macro report_by_day
385
388
  has_report :likes
386
389
 
387
- # @macro daily_report
390
+ # @macro report_by_day
388
391
  has_report :dislikes
389
392
 
390
- # @macro daily_report
393
+ # @macro report_by_day
391
394
  has_report :shares
392
395
 
393
396
  # @note This is not the total number of subscribers gained by the video’s
394
397
  # channel, but the subscribers gained *from* the video’s page.
395
- # @macro daily_report
398
+ # @macro report_by_day
396
399
  has_report :subscribers_gained
397
400
 
398
401
  # @note This is not the total number of subscribers lost by the video’s
399
402
  # channel, but the subscribers lost *from* the video’s page.
400
- # @macro daily_report
403
+ # @macro report_by_day
401
404
  has_report :subscribers_lost
402
405
 
403
- # @macro daily_report
406
+ # @macro report_by_day
404
407
  has_report :favorites_added
405
408
 
406
- # @macro daily_report
409
+ # @macro report_by_day
407
410
  has_report :favorites_removed
408
411
 
409
- # @macro daily_report
412
+ # @macro report_by_day
410
413
  has_report :average_view_duration
411
414
 
412
- # @macro daily_report
415
+ # @macro report_by_day
413
416
  has_report :average_view_percentage
414
417
 
415
- # @macro daily_report
416
- has_report :estimated_minutes_watched
417
-
418
- # @macro daily_report
418
+ # @macro report_by_day
419
419
  has_report :annotation_clicks
420
420
 
421
- # @macro daily_report
421
+ # @macro report_by_day
422
422
  has_report :annotation_click_through_rate
423
423
 
424
- # @macro daily_report
424
+ # @macro report_by_day
425
425
  has_report :annotation_close_rate
426
426
 
427
- # @macro daily_report
427
+ # @macro report_by_day
428
428
  has_report :earnings
429
429
 
430
- # @macro daily_report
430
+ # @macro report_by_day
431
431
  has_report :impressions
432
432
 
433
- # @macro daily_report
433
+ # @macro report_by_day
434
434
  has_report :monetized_playbacks
435
435
 
436
436
  ### STATISTICS ###
@@ -466,7 +466,6 @@ module Yt
466
466
  # player that will play the video.
467
467
  delegate :embed_html, to: :player
468
468
 
469
-
470
469
  ### ACTIONS (UPLOAD, UPDATE, DELETE) ###
471
470
 
472
471
  has_many :resumable_sessions
@@ -602,17 +601,6 @@ module Yt
602
601
 
603
602
  private
604
603
 
605
- # Since YouTube API only returns tags on Videos#list, the memoized
606
- # `@snippet` is erased if the video was instantiated through Video#search
607
- # (e.g., by calling account.videos or channel.videos), so that the full
608
- # snippet (with tags and category) is loaded, rather than the partial one.
609
- def ensure_complete_snippet(attribute)
610
- unless snippet.public_send(attribute).present? || snippet.complete?
611
- @snippet = nil
612
- end
613
- snippet.public_send attribute
614
- end
615
-
616
604
  # TODO: instead of having Video, Playlist etc override this method,
617
605
  # they should define *what* can be updated in their own *update*
618
606
  # method.
@@ -1,3 +1,3 @@
1
1
  module Yt
2
- VERSION = '0.19.0'
2
+ VERSION = '0.20.0'
3
3
  end
@@ -4,6 +4,113 @@ require 'yt/models/channel'
4
4
  describe Yt::Channel do
5
5
  subject(:channel) { Yt::Channel.new attrs }
6
6
 
7
+ describe '#title' do
8
+ context 'given a snippet with a title' do
9
+ let(:attrs) { {snippet: {"title"=>"Fullscreen"}} }
10
+ it { expect(channel.title).to eq 'Fullscreen' }
11
+ end
12
+
13
+ context 'given a snippet without a title' do
14
+ let(:attrs) { {snippet: {}} }
15
+ it { expect(channel.title).to eq '' }
16
+ end
17
+ end
18
+
19
+ describe '#description' do
20
+ context 'given a snippet with a description' do
21
+ let(:attrs) { {snippet: {"description"=>"A cool channel."}} }
22
+ it { expect(channel.description).to eq 'A cool channel.' }
23
+ end
24
+
25
+ context 'given a snippet without a description' do
26
+ let(:attrs) { {snippet: {}} }
27
+ it { expect(channel.description).to eq '' }
28
+ end
29
+ end
30
+
31
+ describe '#thumbnail_url' do
32
+ context 'given a snippet with thumbnails' do
33
+ let(:attrs) { {snippet: {"thumbnails"=>{
34
+ "default"=>{"url"=> "http://example.com/88x88.jpg"},
35
+ "medium"=>{"url"=> "http://example.com/240x240.jpg"},
36
+ }}} }
37
+ it { expect(channel.thumbnail_url).to eq 'http://example.com/88x88.jpg' }
38
+ it { expect(channel.thumbnail_url 'default').to eq 'http://example.com/88x88.jpg' }
39
+ it { expect(channel.thumbnail_url :default).to eq 'http://example.com/88x88.jpg' }
40
+ it { expect(channel.thumbnail_url :medium).to eq 'http://example.com/240x240.jpg' }
41
+ it { expect(channel.thumbnail_url :high).to be_nil }
42
+ end
43
+
44
+ context 'given a snippet without thumbnails' do
45
+ let(:attrs) { {snippet: {}} }
46
+ it { expect(channel.thumbnail_url).to be_nil }
47
+ end
48
+ end
49
+
50
+ describe '#published_at' do
51
+ context 'given a snippet with a timestamp' do
52
+ let(:attrs) { {snippet: {"publishedAt"=>"2014-04-22T19:14:49.000Z"}} }
53
+ it { expect(channel.published_at.year).to be 2014 }
54
+ end
55
+ end
56
+
57
+ describe '#comment_count' do
58
+ context 'given a video with comments' do
59
+ let(:attrs) { {statistics: {"commentCount"=>"33"}} }
60
+ it { expect(channel.comment_count).to be 33 }
61
+ end
62
+ end
63
+
64
+ describe '#video_count' do
65
+ context 'given a video with videos' do
66
+ let(:attrs) { {statistics: {"videoCount"=>"42"}} }
67
+ it { expect(channel.video_count).to be 42 }
68
+ end
69
+ end
70
+
71
+ describe '#subscriber_count' do
72
+ context 'given a video with subscribers' do
73
+ let(:attrs) { {statistics: {"subscriberCount"=>"12"}} }
74
+ it { expect(channel.subscriber_count).to be 12 }
75
+ end
76
+ end
77
+
78
+ describe '#subscriber_count_visible?' do
79
+ context 'given a video with publicly visible subscribers' do
80
+ let(:attrs) { {statistics: {"hiddenSubscriberCount"=>false}} }
81
+ it { expect(channel).to be_subscriber_count_visible }
82
+ end
83
+
84
+ context 'given a video with hidden subscribers' do
85
+ let(:attrs) { {statistics: {"hiddenSubscriberCount"=>true}} }
86
+ it { expect(channel).not_to be_subscriber_count_visible }
87
+ end
88
+ end
89
+
90
+ describe '#content_owner' do
91
+ context 'given a content_owner_detail with a content owner' do
92
+ let(:attrs) { {content_owner_details: {"contentOwner"=>"FullScreen"}} }
93
+ it { expect(channel.content_owner).to eq 'FullScreen' }
94
+ end
95
+
96
+ context 'given a content_owner_detail without a content owner' do
97
+ let(:attrs) { {content_owner_details: {}} }
98
+ it { expect(channel.content_owner).to be_nil }
99
+ end
100
+ end
101
+
102
+ describe '#linked_at' do
103
+ context 'given a content_owner_detail with a timeLinked' do
104
+ let(:attrs) { {content_owner_details: {"timeLinked"=>"2014-04-22T19:14:49.000Z"}} }
105
+ it { expect(channel.linked_at.year).to be 2014 }
106
+ end
107
+
108
+ context 'given a content_owner_detail with a timeLinked' do
109
+ let(:attrs) { {content_owner_details: {}} }
110
+ it { expect(channel.linked_at).to be_nil }
111
+ end
112
+ end
113
+
7
114
  describe '#snippet' do
8
115
  context 'given fetching a channel returns a snippet' do
9
116
  let(:attrs) { {snippet: {"title"=>"Fullscreen"}} }
@@ -3,28 +3,4 @@ require 'yt/models/content_owner_detail'
3
3
 
4
4
  describe Yt::ContentOwnerDetail do
5
5
  subject(:content_owner_detail) { Yt::ContentOwnerDetail.new data: data }
6
-
7
- describe '#content_owner' do
8
- context 'given a content_owner_detail with a content owner' do
9
- let(:data) { {"contentOwner"=>"FullScreen"} }
10
- it { expect(content_owner_detail.content_owner).to eq 'FullScreen' }
11
- end
12
-
13
- context 'given a content_owner_detail without a content owner' do
14
- let(:data) { {} }
15
- it { expect(content_owner_detail.content_owner).to be_nil }
16
- end
17
- end
18
-
19
- describe '#linked_at' do
20
- context 'given a content_owner_detail with a timeLinked' do
21
- let(:data) { {"timeLinked"=>"2014-04-22T19:14:49.000Z"} }
22
- it { expect(content_owner_detail.linked_at.year).to be 2014 }
23
- end
24
-
25
- context 'given a content_owner_detail with a timeLinked' do
26
- let(:data) { {} }
27
- it { expect(content_owner_detail.linked_at).to be_nil }
28
- end
29
- end
30
6
  end
@@ -2,19 +2,108 @@ require 'spec_helper'
2
2
  require 'yt/models/playlist_item'
3
3
 
4
4
  describe Yt::PlaylistItem do
5
- subject(:playlist_item) { Yt::PlaylistItem.new attrs }
5
+ subject(:item) { Yt::PlaylistItem.new attrs }
6
+
7
+ describe '#title' do
8
+ context 'given a snippet with a title' do
9
+ let(:attrs) { {snippet: {"title"=>"Fullscreen"}} }
10
+ it { expect(item.title).to eq 'Fullscreen' }
11
+ end
12
+
13
+ context 'given a snippet without a title' do
14
+ let(:attrs) { {snippet: {}} }
15
+ it { expect(item.title).to eq '' }
16
+ end
17
+ end
18
+
19
+ describe '#published_at' do
20
+ context 'given a snippet with a timestamp' do
21
+ let(:attrs) { {snippet: {"publishedAt"=>"2014-04-22T19:14:49.000Z"}} }
22
+ it { expect(item.published_at.year).to be 2014 }
23
+ end
24
+ end
25
+
26
+ describe '#description' do
27
+ context 'given a snippet with a description' do
28
+ let(:attrs) { {snippet: {"description"=>"A video."}} }
29
+ it { expect(item.description).to eq 'A video.' }
30
+ end
31
+
32
+ context 'given a snippet without a description' do
33
+ let(:attrs) { {snippet: {}} }
34
+ it { expect(item.description).to eq '' }
35
+ end
36
+ end
37
+
38
+ describe '#thumbnail_url' do
39
+ context 'given a snippet with thumbnails' do
40
+ let(:attrs) { {snippet: {"thumbnails"=>{
41
+ "default"=>{"url"=> "http://example.com/120x90.jpg"},
42
+ "medium"=>{"url"=> "http://example.com/320x180.jpg"},
43
+ }}} }
44
+ it { expect(item.thumbnail_url).to eq 'http://example.com/120x90.jpg' }
45
+ it { expect(item.thumbnail_url 'default').to eq 'http://example.com/120x90.jpg' }
46
+ it { expect(item.thumbnail_url :default).to eq 'http://example.com/120x90.jpg' }
47
+ it { expect(item.thumbnail_url :medium).to eq 'http://example.com/320x180.jpg' }
48
+ it { expect(item.thumbnail_url :large).to be_nil }
49
+ end
50
+
51
+ context 'given a snippet without thumbnails' do
52
+ let(:attrs) { {snippet: {}} }
53
+ it { expect(item.thumbnail_url).to be_nil }
54
+ end
55
+ end
56
+
57
+ describe '#channel_id' do
58
+ context 'given a snippet with a channel ID' do
59
+ let(:attrs) { {snippet: {"channelId"=>"UCxO1tY8h1AhOz0T4ENwmpow"}} }
60
+ it { expect(item.channel_id).to eq 'UCxO1tY8h1AhOz0T4ENwmpow' }
61
+ end
62
+
63
+ context 'given a snippet without a channel ID' do
64
+ let(:attrs) { {snippet: {}} }
65
+ it { expect(item.channel_id).to be_nil }
66
+ end
67
+ end
68
+
69
+ describe '#channel_title' do
70
+ context 'given a snippet with a channel title' do
71
+ let(:attrs) { {snippet: {"channelTitle"=>"Fullscreen"}} }
72
+ it { expect(item.channel_title).to eq 'Fullscreen' }
73
+ end
74
+
75
+ context 'given a snippet without a channel title' do
76
+ let(:attrs) { {snippet: {}} }
77
+ it { expect(item.channel_title).to be_nil }
78
+ end
79
+ end
80
+
81
+ describe '#video_id and #video' do
82
+ context 'given a snippet with a video resource' do
83
+ let(:attrs) { {snippet: {"resourceId"=>{"kind"=>"youtube#video","videoId"=>"W4GhTprSsOY"}}} }
84
+ it { expect(item.video_id).to eq 'W4GhTprSsOY' }
85
+ it { expect(item.video).to be_a Yt::Models::Video }
86
+ it { expect(item.video.id).to eq 'W4GhTprSsOY' }
87
+ end
88
+
89
+ context 'given a snippet without a video resource' do
90
+ let(:attrs) { {snippet: {}} }
91
+ it { expect(item.video_id).to be_nil }
92
+ it { expect(item.video).to be_nil }
93
+ end
94
+ end
6
95
 
7
96
  describe '#snippet' do
8
97
  context 'given fetching a playlist item returns a snippet' do
9
98
  let(:attrs) { {snippet: {"position"=>0}} }
10
- it { expect(playlist_item.snippet).to be_a Yt::Snippet }
99
+ it { expect(item.snippet).to be_a Yt::Snippet }
11
100
  end
12
101
  end
13
102
 
14
103
  describe '#status' do
15
104
  context 'given fetching a playlist item returns a status' do
16
105
  let(:attrs) { {status: {"privacyStatus"=>"public"}} }
17
- it { expect(playlist_item.status).to be_a Yt::Status }
106
+ it { expect(item.status).to be_a Yt::Status }
18
107
  end
19
108
  end
20
109
 
@@ -22,10 +111,10 @@ describe Yt::PlaylistItem do
22
111
  let(:attrs) { {id: 'playlist-item-id'} }
23
112
 
24
113
  context 'given an existing playlist item' do
25
- before { expect(playlist_item).to receive(:do_delete).and_yield }
114
+ before { expect(item).to receive(:do_delete).and_yield }
26
115
 
27
- it { expect(playlist_item.delete).to be true }
28
- it { expect{playlist_item.delete}.to change{playlist_item.exists?} }
116
+ it { expect(item.delete).to be true }
117
+ it { expect{item.delete}.to change{item.exists?} }
29
118
  end
30
119
  end
31
120
  end