yt 0.7.9 → 0.7.10

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: cfcbde361ff972549cb68415dd88749f21c517e0
4
- data.tar.gz: 1c1f419d4bb67484a0d00e2cb0b710cfdcc63c18
3
+ metadata.gz: d59d615fd8bb939c84404f9cda73c12135b8ca68
4
+ data.tar.gz: dc7a6b4c8421c86f2b568263c408876957f7907d
5
5
  SHA512:
6
- metadata.gz: 6b02f9e1d4354bc4a5fb3cb5b66b5f212a7cecc2284f7f472dcf56006bccc257466d20008250a062473b529f36f4f00575a7af28adfa2bd2b53ddd77c3c15c38
7
- data.tar.gz: b684f9e3660801b5452e8629a76a308321f02ee75fe54ea80ddc4a0cf0734dfa39bca1a485d82077a171591840abb700b6b93501005217ec035c77e49a52495b
6
+ metadata.gz: d08d0ca9a0bb9beeb223f1f26739dbdff3226a969a6d7a1060b6038c8c9a79ae1c969535555994166cd23c367816e399a53a31830868e443fc834f203623df5d
7
+ data.tar.gz: 2d30fd95cc78bc93b838bf165c2546298de4f192944ead0330d1a20be923e0c470f41a3edce61624565f407d562125917f32eac98e44bba109fd240351ab3977
data/.yardopts CHANGED
@@ -1,3 +1,4 @@
1
1
  --no-private
2
2
  lib/yt/associations/has_reports.rb
3
+ lib/yt/associations/has_viewer_percentages.rb
3
4
  lib/**/*.rb
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- yt (0.7.9)
4
+ yt (0.7.10)
5
5
  activesupport
6
6
 
7
7
  GEM
data/HISTORY.md CHANGED
@@ -16,6 +16,7 @@ v0.7 - 2014/06/18
16
16
  * Make reports available also on Video (not just Channel)
17
17
  * New account.upload_video to upload a video (either local or remote).
18
18
  * Make channel.videos access more than 500 videos per channel
19
+ * Add viewer percentage (age group, gender) to Channel and Video reports
19
20
 
20
21
  v0.6 - 2014/06/05
21
22
  -----------------
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.7.9'
44
+ gem 'yt', '~> 0.7.10'
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*)
@@ -107,6 +107,7 @@ Use [Yt::Channel](http://rubydoc.info/github/Fullscreen/yt/master/Yt/Models/Chan
107
107
  * subscribe to and unsubscribe from a channel
108
108
  * create and delete playlists from a channel
109
109
  * retrieve the daily earnings, views, comments, likes, dislikes, shares and impressions of a channel
110
+ * retrieve the viewer percentage of a channel by gender and age group
110
111
 
111
112
  ```ruby
112
113
  channel = Yt::Channel.new id: 'UCxO1tY8h1AhOz0T4ENwmpow'
@@ -155,6 +156,8 @@ channel.comments until: 2.days.ago #=> {Wed, 28 May 2014 => 9.0, Thu, 29 May 201
155
156
  channel.likes from: 8.days.ago #=> {Tue, 27 May 2014 => 7.0, Wed, 28 May 2014 => 0.0, …}
156
157
  channel.dislikes to: 2.days.ago #=> {Tue, 27 May 2014 => 0.0, Wed, 28 May 2014 => 1.0, …}
157
158
  channel.shares since: 7.days.ago, until: 7.days.ago #=> {Wed, 28 May 2014 => 3.0}
159
+
160
+ channel.viewer_percentages #=> {female: {'18-24' => 12.12, '25-34' => 16.16,…}…}
158
161
  ```
159
162
 
160
163
  *The methods above require to be authenticated as the channel’s account (see below).*
@@ -170,6 +173,8 @@ channel.likes from: 8.days.ago #=> {Tue, 27 May 2014 => 7.0, Wed, 28 May 2014 =>
170
173
  channel.dislikes to: 2.days.ago #=> {Tue, 27 May 2014 => 0.0, Wed, 28 May 2014 => 1.0, …}
171
174
  channel.shares since: 7.days.ago, until: 7.days.ago #=> {Wed, 28 May 2014 => 3.0}
172
175
  channel.impressions_on 5.days.ago #=> 157.0
176
+
177
+ channel.viewer_percentages #=> {female: {'18-24' => 12.12, '25-34' => 16.16,…}…}
173
178
  ```
174
179
 
175
180
  *The methods above require to be authenticated as the channel’s content owner (see below).*
@@ -183,7 +188,8 @@ Use [Yt::Video](http://rubydoc.info/github/Fullscreen/yt/master/Yt/Models/Video)
183
188
  * update the attributes of a video
184
189
  * access the annotations of a video
185
190
  * like and dislike a video
186
- * retrieve the daily earnings, views, comments, likes, dislikes, shares and impressions of a channel
191
+ * retrieve the daily earnings, views, comments, likes, dislikes, shares and impressions of a video
192
+ * retrieve the viewer percentage of a video by gender and age group
187
193
 
188
194
  ```ruby
189
195
  video = Yt::Video.new id: 'MESycYJytkU'
@@ -233,6 +239,8 @@ video.comments until: 2.days.ago #=> {Wed, 28 May 2014 => 9.0, Thu, 29 May 2014
233
239
  video.likes from: 8.days.ago #=> {Tue, 27 May 2014 => 7.0, Wed, 28 May 2014 => 0.0, …}
234
240
  video.dislikes to: 2.days.ago #=> {Tue, 27 May 2014 => 0.0, Wed, 28 May 2014 => 1.0, …}
235
241
  video.shares since: 7.days.ago, until: 7.days.ago #=> {Wed, 28 May 2014 => 3.0}
242
+
243
+ video.viewer_percentages #=> {female: {'18-24' => 12.12, '25-34' => 16.16,…}…}
236
244
  ```
237
245
 
238
246
  *The methods above require to be authenticated as the video’s owner (see below).*
@@ -248,6 +256,8 @@ video.likes from: 8.days.ago #=> {Tue, 27 May 2014 => 7.0, Wed, 28 May 2014 => 0
248
256
  video.dislikes to: 2.days.ago #=> {Tue, 27 May 2014 => 0.0, Wed, 28 May 2014 => 1.0, …}
249
257
  video.shares since: 7.days.ago, until: 7.days.ago #=> {Wed, 28 May 2014 => 3.0}
250
258
  video.impressions_on 5.days.ago #=> 157.0
259
+
260
+ video.viewer_percentages #=> {female: {'18-24' => 12.12, '25-34' => 16.16,…}…}
251
261
  ```
252
262
 
253
263
  *The methods above require to be authenticated as the video’s content owner (see below).*
data/bin/yt CHANGED
@@ -53,6 +53,7 @@ puts " Subscribers are visible? #{channel.subscriber_count_visible?}"
53
53
  # puts " Likes: #{channel.likes}"
54
54
  # puts " Dislikes: #{channel.dislikes}"
55
55
  # puts " Shares: #{channel.shares}"
56
+ # puts " Viewers: #{channel.viewer_percentages}"
56
57
 
57
58
  account.videos.first(5).each.with_index do |video, i|
58
59
  puts "\nVIDEO #{i+1}:\n"
@@ -82,6 +83,7 @@ account.videos.first(5).each.with_index do |video, i|
82
83
  # puts " Likes: #{video.likes}"
83
84
  # puts " Dislikes: #{video.dislikes}"
84
85
  # puts " Shares: #{video.shares}"
86
+ # puts " Viewers: #{video.viewer_percentages}"
85
87
  puts " Annotations: #{video.annotations.count}"
86
88
  end
87
89
 
@@ -1,9 +1,9 @@
1
1
  module Yt
2
2
  module Associations
3
- # Provides methods to to access the analytics reports of a resource.
3
+ # Provides methods to access the analytics reports of a resource.
4
4
  #
5
5
  # YouTube resources with reports are: {Yt::Models::Channel channels} and
6
- # {Yt::Models::Channel videos}.
6
+ # {Yt::Models::Channel videos}.
7
7
  module HasReports
8
8
  # @!macro has_report
9
9
  # @!method $1_on(date)
@@ -0,0 +1,39 @@
1
+ module Yt
2
+ module Associations
3
+ # Provides methods to access the viewer percentage reports of a resource.
4
+ #
5
+ # YouTube resources with viewer percentage reports are:
6
+ # {Yt::Models::Channel channels} and {Yt::Models::Channel videos}.
7
+ module HasViewerPercentages
8
+ # @!macro has_viewer_percentages
9
+ # @!method viewer_percentages
10
+ # @return [Hash<Symbol,Hash<String,Float>>] the viewer percentages.
11
+ # The first-level hash identifies the genres (:female, :male).
12
+ # The second-level hash identifies the age ranges ('18-24',
13
+ # '25-34', '35-44', '45-54', '55-64', '65-')
14
+ # @example Return the % of male viewers of a channel older than 64
15
+ # channel.viewer_percentages[:male]['65-'] #=> 12.02
16
+
17
+ # Defines a public instance methods to access the viewer percentages of
18
+ # a resource for a specific metric.
19
+ # @example Adds +viewer_percentages+ on a Channel resource.
20
+ # class Channel < Resource
21
+ # has_viewer_percentages
22
+ # end
23
+ def has_viewer_percentages
24
+ require 'yt/collections/viewer_percentages'
25
+
26
+ define_viewer_percentages_method
27
+ end
28
+
29
+ private
30
+
31
+ def define_viewer_percentages_method
32
+ # @todo: add options like start and end date
33
+ define_method :viewer_percentages do
34
+ @viewer_percentages ||= Collections::ViewerPercentages.of(self).all
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -14,11 +14,11 @@ module Yt
14
14
  # video to upload. If the request succeeds, YouTube returns a unique
15
15
  # URL to upload the video file (and eventually resume the upload).
16
16
  # @param [Integer] content_length the size (bytes) of the video to upload.
17
- # @param [Hash] params the metadata to add to the uploaded video.
18
- # @option params [String] :title The video’s title.
19
- # @option params [String] :description The video’s description.
20
- # @option params [Array<String>] :title The video’s tags.
21
- # @option params [String] :privacy_status The video’s privacy status.
17
+ # @param [Hash] options the metadata to add to the uploaded video.
18
+ # @option options [String] :title The video’s title.
19
+ # @option options [String] :description The video’s description.
20
+ # @option options [Array<String>] :title The video’s tags.
21
+ # @option options [String] :privacy_status The video’s privacy status.
22
22
  def insert(content_length, options = {})
23
23
  @headers = headers_for content_length
24
24
  body = {}
@@ -0,0 +1,46 @@
1
+ require 'yt/collections/base'
2
+
3
+ module Yt
4
+ module Collections
5
+ class ViewerPercentages < Base
6
+
7
+ def all
8
+ Hash.new{|h,k| h[k] = Hash.new(0.0)}.tap do |hash|
9
+ each{|item| hash[item.gender][item.age_range] = item.value}
10
+ end
11
+ end
12
+
13
+ private
14
+
15
+ # @note could use column headers to be more precise
16
+ def new_item(data)
17
+ Struct.new(:gender, :age_range, :value).new.tap do |item|
18
+ item.gender = data.first.to_sym
19
+ item.age_range = data.second.gsub /^age/, ''
20
+ item.value = data.last
21
+ end
22
+ end
23
+
24
+ def list_params
25
+ super.tap do |params|
26
+ params[:path] = '/youtube/analytics/v1/reports'
27
+ params[:params] = @parent.reports_params.merge reports_params
28
+ end
29
+ end
30
+
31
+ def reports_params
32
+ {}.tap do |params|
33
+ params['start-date'] = 3.months.ago.to_date
34
+ params['end-date'] = Date.today.to_date
35
+ params['metrics'] = :viewerPercentage
36
+ params['dimensions'] = 'gender,ageGroup'
37
+ params['sort'] = 'gender,ageGroup'
38
+ end
39
+ end
40
+
41
+ def items_key
42
+ 'rows'
43
+ end
44
+ end
45
+ end
46
+ end
@@ -5,6 +5,7 @@ require 'yt/associations/has_authentication'
5
5
  require 'yt/associations/has_many'
6
6
  require 'yt/associations/has_one'
7
7
  require 'yt/associations/has_reports'
8
+ require 'yt/associations/has_viewer_percentages'
8
9
 
9
10
  require 'yt/errors/request_error'
10
11
 
@@ -15,6 +16,7 @@ module Yt
15
16
  include Actions::Update
16
17
 
17
18
  extend Associations::HasReports
19
+ extend Associations::HasViewerPercentages
18
20
  extend Associations::HasOne
19
21
  extend Associations::HasMany
20
22
  extend Associations::HasAuthentication
@@ -38,6 +38,9 @@ module Yt
38
38
  # @macro has_report
39
39
  has_report :impressions
40
40
 
41
+ # @macro has_viewer_percentages
42
+ has_viewer_percentages
43
+
41
44
  # @!attribute [r] statistics_set
42
45
  # @return [Yt::Models::StatisticsSet] the statistics for the video.
43
46
  has_one :statistics_set
@@ -60,9 +60,13 @@ module Yt
60
60
  end
61
61
 
62
62
  def set_headers!(request)
63
- if @body_type == :json
63
+ case @body_type
64
+ when :json
64
65
  request.initialize_http_header 'Content-Type' => 'application/json'
65
66
  request.initialize_http_header 'Content-length' => '0' unless @body
67
+ when :file
68
+ request.initialize_http_header 'Content-Length' => @body.size.to_s
69
+ request.initialize_http_header 'Transfer-Encoding' => 'chunked'
66
70
  end
67
71
  @headers.each{|name, value| request.add_field name, value}
68
72
  end
@@ -84,7 +88,7 @@ module Yt
84
88
  case @body_type
85
89
  when :json then request.body = @body.to_json
86
90
  when :form then request.set_form_data @body
87
- when :file then request.body = @body.read
91
+ when :file then request.body_stream = @body
88
92
  end if @body
89
93
  end
90
94
 
@@ -43,6 +43,9 @@ module Yt
43
43
  # @macro has_report
44
44
  has_report :impressions
45
45
 
46
+ # @macro has_viewer_percentages
47
+ has_viewer_percentages
48
+
46
49
  # @!attribute [r] statistics_set
47
50
  # @return [Yt::Models::StatisticsSet] the statistics for the video.
48
51
  has_one :statistics_set
@@ -1,3 +1,3 @@
1
1
  module Yt
2
- VERSION = '0.7.9'
2
+ VERSION = '0.7.10'
3
3
  end
@@ -99,6 +99,10 @@ describe Yt::Channel, :device_app do
99
99
  expect{channel.earnings_on 3.days.ago}.to raise_error Yt::Errors::Unauthorized
100
100
  expect{channel.impressions_on 3.days.ago}.to raise_error Yt::Errors::Unauthorized
101
101
  end
102
+
103
+ it 'returns valid reports for channel-related demographics' do
104
+ expect{channel.viewer_percentages}.not_to raise_error
105
+ end
102
106
  end
103
107
 
104
108
  context 'given an unknown channel' do
@@ -79,8 +79,7 @@ describe Yt::Video, :device_app do
79
79
  it { expect{video.update attrs}.not_to change{video.privacy_status} }
80
80
  end
81
81
 
82
-
83
- it 'returns valid reports for channel-related metrics' do
82
+ it 'returns valid reports for video-related metrics' do
84
83
  # Some reports are only available to Content Owners.
85
84
  # See content ownere test for more details about what the methods return.
86
85
  expect{video.views}.not_to raise_error
@@ -99,5 +98,9 @@ describe Yt::Video, :device_app do
99
98
  expect{video.earnings_on 3.days.ago}.to raise_error Yt::Errors::Unauthorized
100
99
  expect{video.impressions_on 3.days.ago}.to raise_error Yt::Errors::Unauthorized
101
100
  end
101
+
102
+ it 'returns valid reports for video-related demographics' do
103
+ expect{video.viewer_percentages}.not_to raise_error
104
+ end
102
105
  end
103
106
  end
@@ -245,6 +245,21 @@ describe Yt::Channel, :partner do
245
245
  expect(channel.impressions(to: date).keys.max).to eq date.to_date
246
246
  end
247
247
  end
248
+
249
+ specify 'viewer percentages by gender and age range can be retrieved' do
250
+ expect(channel.viewer_percentages[:female]['18-24']).to be_a Float
251
+ expect(channel.viewer_percentages[:female]['25-34']).to be_a Float
252
+ expect(channel.viewer_percentages[:female]['35-44']).to be_a Float
253
+ expect(channel.viewer_percentages[:female]['45-54']).to be_a Float
254
+ expect(channel.viewer_percentages[:female]['55-64']).to be_a Float
255
+ expect(channel.viewer_percentages[:female]['65-']).to be_a Float
256
+ expect(channel.viewer_percentages[:male]['18-24']).to be_a Float
257
+ expect(channel.viewer_percentages[:male]['25-34']).to be_a Float
258
+ expect(channel.viewer_percentages[:male]['35-44']).to be_a Float
259
+ expect(channel.viewer_percentages[:male]['45-54']).to be_a Float
260
+ expect(channel.viewer_percentages[:male]['55-64']).to be_a Float
261
+ expect(channel.viewer_percentages[:male]['65-']).to be_a Float
262
+ end
248
263
  end
249
264
 
250
265
  context 'not managed by the authenticated Content Owner' do
@@ -232,6 +232,21 @@ describe Yt::Video, :partner do
232
232
  expect(video.impressions(to: date).keys.max).to eq date.to_date
233
233
  end
234
234
  end
235
+
236
+ specify 'viewer percentages by gender and age range can be retrieved' do
237
+ expect(video.viewer_percentages[:female]['18-24']).to be_a Float
238
+ expect(video.viewer_percentages[:female]['25-34']).to be_a Float
239
+ expect(video.viewer_percentages[:female]['35-44']).to be_a Float
240
+ expect(video.viewer_percentages[:female]['45-54']).to be_a Float
241
+ expect(video.viewer_percentages[:female]['55-64']).to be_a Float
242
+ expect(video.viewer_percentages[:female]['65-']).to be_a Float
243
+ expect(video.viewer_percentages[:male]['18-24']).to be_a Float
244
+ expect(video.viewer_percentages[:male]['25-34']).to be_a Float
245
+ expect(video.viewer_percentages[:male]['35-44']).to be_a Float
246
+ expect(video.viewer_percentages[:male]['45-54']).to be_a Float
247
+ expect(video.viewer_percentages[:male]['55-64']).to be_a Float
248
+ expect(video.viewer_percentages[:male]['65-']).to be_a Float
249
+ end
235
250
  end
236
251
  end
237
252
  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.7.9
4
+ version: 0.7.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Claudio Baccigalupo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-16 00:00:00.000000000 Z
11
+ date: 2014-07-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -127,6 +127,7 @@ files:
127
127
  - lib/yt/associations/has_many.rb
128
128
  - lib/yt/associations/has_one.rb
129
129
  - lib/yt/associations/has_reports.rb
130
+ - lib/yt/associations/has_viewer_percentages.rb
130
131
  - lib/yt/collections/annotations.rb
131
132
  - lib/yt/collections/authentications.rb
132
133
  - lib/yt/collections/base.rb
@@ -147,6 +148,7 @@ files:
147
148
  - lib/yt/collections/subscriptions.rb
148
149
  - lib/yt/collections/user_infos.rb
149
150
  - lib/yt/collections/videos.rb
151
+ - lib/yt/collections/viewer_percentages.rb
150
152
  - lib/yt/config.rb
151
153
  - lib/yt/errors/forbidden.rb
152
154
  - lib/yt/errors/missing_auth.rb