yt 0.7.9 → 0.7.10

Sign up to get free protection for your applications and to get access to all the features.
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