yt 0.25.17 → 0.25.18

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: 4740a6f0d76647ecc9d2fc04ed46fb6386a5c31d
4
- data.tar.gz: f2b37bb5f0b81f4bd597079d75342d35d665871e
3
+ metadata.gz: 326f3adf4a4e1e7bbf64930125f77a404276d391
4
+ data.tar.gz: 26c77d99c92fc26b67b085bb1a453dc297f95a90
5
5
  SHA512:
6
- metadata.gz: eba0b93123998b7a17377f6f3353c00da95ac0c8738d5f8319ae04fa74d1a6b54ad7fcae361dc893fe2c7537a298311859105a8cc08ba8ec89e250e6010610df
7
- data.tar.gz: 87e76462320bedeee2e77d82071cad3c40ff0793963805797561e24737018f416f74b6f75fd5fe795cf8b9ebff42ad71eee1ac8851e0f58906d0b0afd988d676
6
+ metadata.gz: c07e83a315d72de93ec39e4c24b953b7aa65f96cfa7fda272d0f6bc7f18819ba065a407374aef07571b811c5baed4c4bd993c3895c19d39c3d54a0c9eb6c7291
7
+ data.tar.gz: 17cab126cf09804f07a3025f4daab542ae0a5cbb54ee6026953ec9e67e53784b972560fefd74cb66e5c629808c28114adf9080379e820bba7bf8c51cdac9ce8b
@@ -6,6 +6,14 @@ 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.18 - 2016-01-08
10
+
11
+ * [FEATURE] Add Yt::COUNTRIES and Yt::US_STATES
12
+ * [FEATURE] Add YouTube Analytics Video Groups
13
+ * [FEATURE] Add `:video_groups` to Yt::Account (list video-groups created by an account)
14
+ * [FEATURE] Add `:video_groups` to Yt::ContentOwner (list video-groups on behalf of a content owner)
15
+ * [FEATURE] Add reports by video-group
16
+
9
17
  ## 0.25.17 - 2016-01-05
10
18
 
11
19
  * [FEATURE] Add `:videos` to Yt::ContentOwner to list videos in network with a content owner
data/lib/yt.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'yt/config'
2
2
  require 'yt/version'
3
+ require 'yt/constants/geography'
3
4
  require 'yt/models/account'
4
5
  require 'yt/models/channel'
5
6
  require 'yt/models/claim'
@@ -9,6 +10,7 @@ require 'yt/models/match_policy'
9
10
  require 'yt/models/playlist'
10
11
  require 'yt/models/playlist_item'
11
12
  require 'yt/models/video'
13
+ require 'yt/models/video_group'
12
14
  require 'yt/models/ownership'
13
15
  require 'yt/models/advertising_options_set'
14
16
 
@@ -47,7 +47,7 @@ module Yt
47
47
  def find_next
48
48
  @items ||= []
49
49
  if @items[@last_index].nil? && more_pages?
50
- more_items = next_page.map{|data| new_item data}
50
+ more_items = next_page.map{|data| new_item data}.compact
51
51
  @items.concat more_items
52
52
  end
53
53
  @items[(@last_index +=1) -1]
@@ -0,0 +1,26 @@
1
+ require 'yt/collections/base'
2
+ require 'yt/models/snippet'
3
+
4
+ module Yt
5
+ module Collections
6
+ # @private
7
+ class GroupInfos < Base
8
+
9
+ private
10
+
11
+ def attributes_for_new_item(data)
12
+ {data: data, auth: @auth}
13
+ end
14
+
15
+ def list_params
16
+ super.tap do |params|
17
+ params[:path] = "/youtube/analytics/v1/groups"
18
+ params[:params] = {id: @parent.id}
19
+ if @auth.owner_name
20
+ params[:params][:on_behalf_of_content_owner] = @auth.owner_name
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,28 @@
1
+ require 'yt/collections/base'
2
+ require 'yt/models/video_group'
3
+ require 'yt/models/group_info'
4
+
5
+ module Yt
6
+ module Collections
7
+ # @private
8
+ class VideoGroups < Base
9
+
10
+ private
11
+
12
+ def attributes_for_new_item(data)
13
+ {id: data['id'], auth: @auth, group_info: Yt::GroupInfo.new(data: data)}
14
+ end
15
+
16
+ def new_item(data)
17
+ super if data['contentDetails']['itemType'] == 'youtube#video'
18
+ end
19
+
20
+ def list_params
21
+ super.tap do |params|
22
+ params[:path] = "/youtube/analytics/v1/groups"
23
+ params[:params] = @parent.video_groups_params
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,323 @@
1
+ module Yt
2
+ # The list of country codes and names used by the YouTube Analytics API.
3
+ # @see https://developers.google.com/youtube/analytics/v1/dimsmets/dims#country
4
+ COUNTRIES = {
5
+ AC: 'Ascension',
6
+ AD: 'Andorra',
7
+ AE: 'United Arab Emirates',
8
+ AF: 'Afghanistan',
9
+ AG: 'Antigua and Barbuda',
10
+ AI: 'Anguilla',
11
+ AL: 'Albania',
12
+ AM: 'Armenia',
13
+ AN: 'Netherlands Antilles',
14
+ AO: 'Angola',
15
+ AQ: 'Antarctic Territory',
16
+ AR: 'Argentina',
17
+ AS: 'American Samoa',
18
+ AT: 'Austria',
19
+ AU: 'Australia',
20
+ AW: 'Aruba',
21
+ AX: 'Aland',
22
+ AZ: 'Azerbaijan',
23
+ BA: 'Bosnia and Herzegovina',
24
+ BB: 'Barbados',
25
+ BD: 'Bangladesh',
26
+ BE: 'Belgium',
27
+ BF: 'Burkina Faso',
28
+ BG: 'Bulgaria',
29
+ BH: 'Bahrain',
30
+ BI: 'Burundi',
31
+ BJ: 'Benin',
32
+ BL: 'Saint Barthélemy',
33
+ BM: 'Bermuda',
34
+ BN: 'Brunei',
35
+ BO: 'Bolivia',
36
+ BQ: 'Bonaire, Sint Eustatius and Saba',
37
+ BR: 'Brazil',
38
+ BS: 'Bahamas',
39
+ BT: 'Bhutan',
40
+ BV: 'Bouvet Island',
41
+ BW: 'Botswana',
42
+ BY: 'Belarus',
43
+ BZ: 'Belize',
44
+ CA: 'Canada',
45
+ CC: 'Cocos (Keeling) Islands',
46
+ CD: 'Congo',
47
+ CF: 'Central African Republic',
48
+ CG: 'Congo',
49
+ CH: 'Switzerland',
50
+ CI: 'Ivory Coast',
51
+ CK: 'Cook Islands',
52
+ CL: 'Chile',
53
+ CM: 'Cameroon',
54
+ CN: 'China',
55
+ CO: 'Colombia',
56
+ CR: 'Costa Rica',
57
+ CU: 'Cuba',
58
+ CV: 'Cape Verde',
59
+ CW: 'Curaçao',
60
+ CX: 'Christmas Island',
61
+ CY: 'Cyprus',
62
+ CZ: 'Czech Republic',
63
+ DE: 'Germany',
64
+ DJ: 'Djibouti',
65
+ DK: 'Denmark',
66
+ DM: 'Dominica',
67
+ DO: 'Dominican Republic',
68
+ DZ: 'Algeria',
69
+ EC: 'Ecuador',
70
+ EE: 'Estonia',
71
+ EG: 'Egypt',
72
+ EH: 'Western Sahara',
73
+ ER: 'Eritrea',
74
+ ES: 'Spain',
75
+ ET: 'Ethiopia',
76
+ FI: 'Finland',
77
+ FJ: 'Fiji',
78
+ FK: 'Falkland Islands',
79
+ FM: 'Micronesia',
80
+ FO: 'Faroe Islands',
81
+ FR: 'France',
82
+ GA: 'Gabon',
83
+ GB: 'United Kingdom',
84
+ GD: 'Grenada',
85
+ GE: 'Georgia',
86
+ GF: 'French Guiana',
87
+ GG: 'Guernsey',
88
+ GH: 'Ghana',
89
+ GI: 'Gibraltar',
90
+ GL: 'Greenland',
91
+ GM: 'Gambia',
92
+ GN: 'Guinea',
93
+ GP: 'Guadeloupe',
94
+ GQ: 'Equatorial Guinea',
95
+ GR: 'Greece',
96
+ GS: 'South Georgia & South Sandwich Islands',
97
+ GT: 'Guatemala',
98
+ GU: 'Guam',
99
+ GW: 'Guinea-Bissau',
100
+ GY: 'Guyana',
101
+ HK: 'Hong Kong',
102
+ HM: 'Heard Island and McDonald Islands',
103
+ HN: 'Honduras',
104
+ HR: 'Croatia',
105
+ HT: 'Haiti',
106
+ HU: 'Hungary',
107
+ ID: 'Indonesia',
108
+ IE: 'Ireland',
109
+ IL: 'Israel',
110
+ IM: 'Isle of Man',
111
+ IN: 'India',
112
+ IO: 'British Indian Ocean Territory',
113
+ IQ: 'Iraq',
114
+ IR: 'Iran',
115
+ IS: 'Iceland',
116
+ IT: 'Italy',
117
+ JE: 'Jersey',
118
+ JM: 'Jamaica',
119
+ JO: 'Jordan',
120
+ JP: 'Japan',
121
+ KE: 'Kenya',
122
+ KG: 'Kyrgyzstan',
123
+ KH: 'Cambodia',
124
+ KI: 'Kiribati',
125
+ KM: 'Comoros',
126
+ KN: 'Saint Kitts and Nevis',
127
+ KP: 'North Korea',
128
+ KR: 'South Korea',
129
+ KW: 'Kuwait',
130
+ KY: 'Cayman Islands',
131
+ KZ: 'Kazakhstan',
132
+ LA: 'Laos',
133
+ LB: 'Lebanon',
134
+ LC: 'Saint Lucia',
135
+ LI: 'Liechtenstein',
136
+ LK: 'Sri Lanka',
137
+ LR: 'Liberia',
138
+ LS: 'Lesotho',
139
+ LT: 'Lithuania',
140
+ LU: 'Luxembourg',
141
+ LV: 'Latvia',
142
+ LY: 'Libya',
143
+ MA: 'Morocco',
144
+ MC: 'Monaco',
145
+ MD: 'Moldova',
146
+ ME: 'Montenegro',
147
+ MF: 'Saint Martin',
148
+ MG: 'Madagascar',
149
+ MH: 'Marshall Islands',
150
+ MK: 'Macedonia',
151
+ ML: 'Mali',
152
+ MM: 'Myanmar',
153
+ MN: 'Mongolia',
154
+ MO: 'Macau',
155
+ MP: 'Northern Mariana Islands',
156
+ MQ: 'Martinique',
157
+ MR: 'Mauritania',
158
+ MS: 'Montserrat',
159
+ MT: 'Malta',
160
+ MU: 'Mauritius',
161
+ MV: 'Maldives',
162
+ MW: 'Malawi',
163
+ MX: 'Mexico',
164
+ MY: 'Malaysia',
165
+ MZ: 'Mozambique',
166
+ NA: 'Namibia',
167
+ NC: 'New Caledonia',
168
+ NE: 'Niger',
169
+ NF: 'Norfolk Island',
170
+ NG: 'Nigeria',
171
+ NI: 'Nicaragua',
172
+ NL: 'Netherlands',
173
+ NO: 'Norway',
174
+ NP: 'Nepal',
175
+ NR: 'Nauru',
176
+ NU: 'Niue',
177
+ NZ: 'New Zealand',
178
+ OM: 'Oman',
179
+ PA: 'Panama',
180
+ PE: 'Peru',
181
+ PF: 'French Polynesia',
182
+ PG: 'Papua New Guinea',
183
+ PH: 'Philippines',
184
+ PK: 'Pakistan',
185
+ PL: 'Poland',
186
+ PM: 'Saint Pierre and Miquelon',
187
+ PN: 'Pitcairn Islands',
188
+ PR: 'Puerto Rico',
189
+ PS: 'Palestinian Territory',
190
+ PT: 'Portugal',
191
+ PW: 'Palau',
192
+ PY: 'Paraguay',
193
+ QA: 'Qatar',
194
+ RE: 'Reunion',
195
+ RO: 'Romania',
196
+ RS: 'Serbia',
197
+ RU: 'Russia',
198
+ RW: 'Rwanda',
199
+ SA: 'Saudi Arabia',
200
+ SB: 'Solomon Islands',
201
+ SC: 'Seychelles',
202
+ SD: 'Sudan',
203
+ SE: 'Sweden',
204
+ SG: 'Singapore',
205
+ SH: 'Saint Helena',
206
+ SI: 'Slovenia',
207
+ SJ: 'Svalbard',
208
+ SK: 'Slovakia',
209
+ SL: 'Sierra Leone',
210
+ SM: 'San Marino',
211
+ SN: 'Senegal',
212
+ SO: 'Somalia',
213
+ SR: 'Suriname',
214
+ SS: 'South Sudan',
215
+ ST: 'Sao Tome and Principe',
216
+ SV: 'El Salvador',
217
+ SX: 'Sint Maarten',
218
+ SY: 'Syria',
219
+ SZ: 'Swaziland',
220
+ TA: 'Tristan da Cunha',
221
+ TC: 'Turks and Caicos Islands',
222
+ TD: 'Chad',
223
+ TF: 'French Southern and Antarctic Lands',
224
+ TG: 'Togo',
225
+ TH: 'Thailand',
226
+ TJ: 'Tajikistan',
227
+ TK: 'Tokelau',
228
+ TL: 'East Timor',
229
+ TM: 'Turkmenistan',
230
+ TN: 'Tunisia',
231
+ TO: 'Tonga',
232
+ TR: 'Turkey',
233
+ TT: 'Trinidad and Tobago',
234
+ TV: 'Tuvalu',
235
+ TW: 'Taiwan',
236
+ TZ: 'Tanzania',
237
+ UA: 'Ukraine',
238
+ UG: 'Uganda',
239
+ UM: 'Midway Islands',
240
+ US: 'United States',
241
+ UY: 'Uruguay',
242
+ UZ: 'Uzbekistan',
243
+ VA: 'Vatican City',
244
+ VC: 'Saint Vincent and the Grenadines',
245
+ VE: 'Venezuela',
246
+ VG: 'British Virgin Islands',
247
+ VI: 'U.S. Virgin Islands',
248
+ VN: 'Vietnam',
249
+ VU: 'Vanuatu',
250
+ XK: 'Kosovo',
251
+ WF: 'Wallis and Futuna',
252
+ WS: 'Samoa',
253
+ YE: 'Yemen',
254
+ YT: 'Mayotte',
255
+ ZA: 'South Africa',
256
+ ZM: 'Zambia',
257
+ ZW: 'Zimbabwe',
258
+ ZZ: 'Unknown Region'
259
+ }.with_indifferent_access
260
+
261
+ # The list of U.S. state codes and names used by the YouTube Analytics API.
262
+ # @see https://developers.google.com/youtube/analytics/v1/dimsmets/dims#province
263
+ US_STATES = {
264
+ AL: 'Alabama',
265
+ AK: 'Alaska',
266
+ AZ: 'Arizona',
267
+ AR: 'Arkansas',
268
+ CA: 'California',
269
+ CO: 'Colorado',
270
+ CT: 'Connecticut',
271
+ DE: 'Delaware',
272
+ FL: 'Florida',
273
+ GA: 'Georgia',
274
+ HI: 'Hawaii',
275
+ ID: 'Idaho',
276
+ IL: 'Illinois',
277
+ IN: 'Indiana',
278
+ IA: 'Iowa',
279
+ KS: 'Kansas',
280
+ KY: 'Kentucky',
281
+ LA: 'Louisiana',
282
+ ME: 'Maine',
283
+ MD: 'Maryland',
284
+ MA: 'Massachusetts',
285
+ MI: 'Michigan',
286
+ MN: 'Minnesota',
287
+ MS: 'Mississippi',
288
+ MO: 'Missouri',
289
+ MT: 'Montana',
290
+ NE: 'Nebraska',
291
+ NV: 'Nevada',
292
+ NH: 'New Hampshire',
293
+ NJ: 'New Jersey',
294
+ NM: 'New Mexico',
295
+ NY: 'New York',
296
+ NC: 'North Carolina',
297
+ ND: 'North Dakota',
298
+ OH: 'Ohio',
299
+ OK: 'Oklahoma',
300
+ OR: 'Oregon',
301
+ PA: 'Pennsylvania',
302
+ RI: 'Rhode Island',
303
+ SC: 'South Carolina',
304
+ SD: 'South Dakota',
305
+ TN: 'Tennessee',
306
+ TX: 'Texas',
307
+ UT: 'Utah',
308
+ VT: 'Vermont',
309
+ VA: 'Virginia',
310
+ WA: 'Washington',
311
+ WV: 'West Virginia',
312
+ WI: 'Wisconsin',
313
+ WY: 'Wyoming',
314
+ DC: 'District of Columbia',
315
+ AS: 'American Samoa',
316
+ GU: 'Guam',
317
+ MP: 'Northern Mariana Islands',
318
+ PR: 'Puerto Rico',
319
+ UM: 'United States Minor Outlying Islands',
320
+ VI: 'Virgin Islands, U.S.',
321
+ ZZ: 'Unknown Region'
322
+ }.with_indifferent_access
323
+ end
@@ -160,6 +160,11 @@ module Yt
160
160
  # upload videos using the resumable upload protocol.
161
161
  has_many :resumable_sessions
162
162
 
163
+ # @!attribute [r] video_groups
164
+ # @return [Yt::Collections::VideoGroups] the video-groups created by the
165
+ # account.
166
+ has_many :video_groups
167
+
163
168
  ### PRIVATE API ###
164
169
 
165
170
  has_authentication
@@ -180,6 +185,13 @@ module Yt
180
185
  {for_mine: true}
181
186
  end
182
187
 
188
+ # @private
189
+ # Tells `has_many :video_groups` that content_owner.groups should return
190
+ # all the video-groups *owned by* the account
191
+ def video_groups_params
192
+ {mine: true}
193
+ end
194
+
183
195
  # @private
184
196
  # Tells `has_many :resumable_sessions` what path to hit to upload a file.
185
197
  def upload_path
@@ -30,6 +30,11 @@ module Yt
30
30
  # @return [String] The display name of the content owner.
31
31
  attr_reader :display_name
32
32
 
33
+ # @!attribute [r] video_groups
34
+ # @return [Yt::Collections::VideoGroups] the video-groups managed by the
35
+ # content owner.
36
+ has_many :video_groups
37
+
33
38
  def initialize(options = {})
34
39
  super options
35
40
  @owner_name = options[:owner_name]
@@ -56,6 +61,13 @@ module Yt
56
61
  def videos_params
57
62
  {for_content_owner: true, on_behalf_of_content_owner: @owner_name}
58
63
  end
64
+
65
+ # @private
66
+ # Tells `has_many :video_groups` that content_owner.video_groups should
67
+ # return all the video-groups *on behalf of* the content owner
68
+ def video_groups_params
69
+ {on_behalf_of_content_owner: @owner_name}
70
+ end
59
71
  end
60
72
  end
61
73
  end
@@ -0,0 +1,16 @@
1
+ module Yt
2
+ module Models
3
+ class GroupInfo < Base
4
+ attr_reader :data
5
+
6
+ def initialize(options = {})
7
+ @data = options[:data]['snippet'].merge options[:data]['contentDetails']
8
+ @auth = options[:auth]
9
+ end
10
+
11
+ has_attribute :title, default: ''
12
+ has_attribute :item_count, type: Integer
13
+ has_attribute :published_at, type: Time
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,127 @@
1
+ require 'yt/models/base'
2
+
3
+ module Yt
4
+ module Models
5
+ # Provides methods to interact with YouTube Analytics video-groups.
6
+ # @see https://developers.google.com/youtube/analytics/v1/reference/groups
7
+ class VideoGroup < Base
8
+ # @private
9
+ attr_reader :id, :auth
10
+
11
+ ### GROUP INFO ###
12
+
13
+ has_one :group_info
14
+
15
+ # @!attribute [r] title
16
+ # @return [String] the title of the group.
17
+ delegate :title, to: :group_info
18
+
19
+ # @!attribute [r] item_count
20
+ # @return [Integer] the number of resources in the group.
21
+ delegate :item_count, to: :group_info
22
+
23
+ # @!attribute [r] published_at
24
+ # @return [Time] the date and time when the group was created.
25
+ delegate :published_at, to: :group_info
26
+
27
+ ### ANALYTICS ###
28
+
29
+ # @macro reports
30
+
31
+ # @macro report_by_video_dimensions
32
+ has_report :views, Integer
33
+
34
+ # @macro report_by_day
35
+ has_report :uniques, Integer
36
+
37
+ # @macro report_by_video_dimensions
38
+ has_report :estimated_minutes_watched, Integer
39
+
40
+ # @macro report_by_gender_and_age_group
41
+ has_report :viewer_percentage, Float
42
+
43
+ # @macro report_by_day_and_country
44
+ has_report :comments, Integer
45
+
46
+ # @macro report_by_day_and_country
47
+ has_report :likes, Integer
48
+
49
+ # @macro report_by_day_and_country
50
+ has_report :dislikes, Integer
51
+
52
+ # @macro report_by_day_and_country
53
+ has_report :shares, Integer
54
+
55
+ # @note This is not the total number of subscribers gained by the video’s
56
+ # channel, but the subscribers gained *from* the video’s page.
57
+ # @macro report_by_day_and_country
58
+ has_report :subscribers_gained, Integer
59
+
60
+ # @note This is not the total number of subscribers lost by the video’s
61
+ # channel, but the subscribers lost *from* the video’s page.
62
+ # @macro report_by_day_and_country
63
+ has_report :subscribers_lost, Integer
64
+
65
+ # @macro report_by_day_and_country
66
+ has_report :favorites_added, Integer
67
+
68
+ # @macro report_by_day_and_country
69
+ has_report :favorites_removed, Integer
70
+
71
+ # @macro report_by_day_and_country
72
+ has_report :videos_added_to_playlists, Integer
73
+
74
+ # @macro report_by_day_and_country
75
+ has_report :videos_removed_from_playlists, Integer
76
+
77
+ # @macro report_by_day_and_state
78
+ has_report :average_view_duration, Integer
79
+
80
+ # @macro report_by_day_and_state
81
+ has_report :average_view_percentage, Float
82
+
83
+ # @macro report_by_day_and_state
84
+ has_report :annotation_clicks, Integer
85
+
86
+ # @macro report_by_day_and_state
87
+ has_report :annotation_click_through_rate, Float
88
+
89
+ # @macro report_by_day_and_state
90
+ has_report :annotation_close_rate, Float
91
+
92
+ # @macro report_by_day_and_country
93
+ has_report :earnings, Float
94
+
95
+ # @macro report_by_day_and_country
96
+ has_report :impressions, Integer
97
+
98
+ # @macro report_by_day_and_country
99
+ has_report :monetized_playbacks, Integer
100
+
101
+ # @macro report_by_day_and_country
102
+ has_report :playback_based_cpm, Float
103
+
104
+ ### PRIVATE API ###
105
+
106
+ # @private
107
+ def initialize(options = {})
108
+ @id = options[:id]
109
+ @auth = options[:auth]
110
+ @group_info = options[:group_info] if options[:group_info]
111
+ end
112
+
113
+ # @private
114
+ # Tells `has_reports` to retrieve group reports from the Analytics API.
115
+ def reports_params
116
+ {}.tap do |params|
117
+ if auth.owner_name
118
+ params[:ids] = "contentOwner==#{auth.owner_name}"
119
+ else
120
+ params[:ids] = "channel==mine"
121
+ end
122
+ params[:filters] = "group==#{id}"
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
@@ -210,6 +210,7 @@ module Yt
210
210
  Errno::ENETUNREACH,
211
211
  Errno::ECONNRESET,
212
212
  Net::OpenTimeout,
213
+ SocketError,
213
214
  Net::HTTPServerError
214
215
  ] + extra_server_errors
215
216
  end
@@ -233,7 +234,7 @@ module Yt
233
234
  @retries_so_far += 1
234
235
  if (@retries_so_far < max_retries)
235
236
  @response = @http_request = @uri = nil
236
- sleep 3
237
+ sleep 3 + (10 * @retries_so_far)
237
238
  end
238
239
  end
239
240
 
@@ -1,3 +1,3 @@
1
1
  module Yt
2
- VERSION = '0.25.17'
2
+ VERSION = '0.25.18'
3
3
  end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+ require 'yt/constants/geography'
3
+
4
+ describe 'Yt::COUNTRIES' do
5
+ it 'returns all country codes and names' do
6
+ expect(Yt::COUNTRIES[:US]).to eq 'United States'
7
+ expect(Yt::COUNTRIES['IT']).to eq 'Italy'
8
+ end
9
+ end
10
+
11
+ describe 'Yt::US_STATES' do
12
+ it 'returns all U.S. state codes and names' do
13
+ expect(Yt::US_STATES[:CA]).to eq 'California'
14
+ expect(Yt::US_STATES['CO']).to eq 'Colorado'
15
+ end
16
+ end
@@ -178,6 +178,27 @@ describe Yt::Request do
178
178
  it { expect{request.run}.not_to fail }
179
179
  end
180
180
  end
181
+
182
+ # NOTE: This test is just a reflection of YouTube irrational behavior of
183
+ # being unavailable once in a while, and therefore causing Net::HTTP to
184
+ # fail, although retrying after some seconds works.
185
+ context 'a SocketError', ruby21: true do
186
+ let(:http_error) { SocketError.new }
187
+
188
+ context 'every time' do
189
+ before { expect(Net::HTTP).to receive(:start).at_least(:once).and_raise http_error }
190
+
191
+ it { expect{request.run}.to fail }
192
+ end
193
+
194
+ context 'but works the second time' do
195
+ before { expect(Net::HTTP).to receive(:start).at_least(:once).and_return retry_response }
196
+ before { allow(retry_response).to receive(:body) }
197
+ let(:retry_response) { Net::HTTPOK.new nil, nil, nil }
198
+
199
+ it { expect{request.run}.not_to fail }
200
+ end
201
+ end
181
202
  end
182
203
  end
183
204
  end
@@ -97,6 +97,21 @@ describe Yt::Account, :device_app do
97
97
  end
98
98
  end
99
99
 
100
+ describe '.video_groups' do
101
+ let(:video_group) { $account.video_groups.first }
102
+
103
+ specify 'returns the first video-group created by the account' do
104
+ expect(video_group).to be_a Yt::VideoGroup
105
+ expect(video_group.title).to be_a String
106
+ expect(video_group.item_count).to be_an Integer
107
+ expect(video_group.published_at).to be_a Time
108
+ end
109
+
110
+ specify 'allows to run reports against each video-group' do
111
+ expect(video_group.views).to be
112
+ end
113
+ end
114
+
100
115
  describe '.upload_video' do
101
116
  let(:video_params) { {title: 'Test Yt upload', privacy_status: 'private', category_id: 17} }
102
117
  let(:video) { $account.upload_video path_or_url, video_params }
@@ -51,6 +51,20 @@ describe Yt::ContentOwner, :partner do
51
51
  end
52
52
  end
53
53
 
54
+ describe '.video_groups' do
55
+ let(:video_group) { $content_owner.video_groups.first }
56
+
57
+ specify 'returns the first video-group created by the account' do
58
+ expect(video_group).to be_a Yt::VideoGroup
59
+ expect(video_group.title).to be_a String
60
+ expect(video_group.item_count).to be_an Integer
61
+ expect(video_group.published_at).to be_a Time
62
+ end
63
+
64
+ specify 'allows to run reports against each video-group' do
65
+ expect(video_group.views).to be
66
+ end
67
+ end
54
68
 
55
69
  describe 'claims' do
56
70
  let(:asset_id) { ENV['YT_TEST_PARTNER_ASSET_ID'] }
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+ require 'yt/models/video_group'
3
+
4
+ describe Yt::VideoGroup, :partner do
5
+ subject(:video_group) { Yt::VideoGroup.new id: id, auth: $content_owner }
6
+
7
+ context 'given a video-group', :partner do
8
+ context 'managed by the authenticated Content Owner' do
9
+ let(:id) { ENV['YT_TEST_PARTNER_VIDEO_GROUP_ID'] }
10
+
11
+ specify 'the title can be retrieved' do
12
+ expect(video_group.title).to be_a(String)
13
+ expect(video_group.title).not_to be_empty
14
+ end
15
+
16
+ specify 'the number of videos in the group can be retrieved' do
17
+ expect(video_group.item_count).to be_an(Integer)
18
+ expect(video_group.item_count).not_to be_zero
19
+ end
20
+
21
+ describe 'multiple reports can be retrieved at once' do
22
+ metrics = {views: Integer, uniques: Integer,
23
+ estimated_minutes_watched: Integer, comments: Integer, likes: Integer,
24
+ dislikes: Integer, shares: Integer, subscribers_gained: Integer,
25
+ subscribers_lost: Integer, favorites_added: Integer,
26
+ videos_added_to_playlists: Integer, videos_removed_from_playlists: Integer,
27
+ favorites_removed: Integer, average_view_duration: Integer,
28
+ average_view_percentage: Float, annotation_clicks: Integer,
29
+ annotation_click_through_rate: Float,
30
+ annotation_close_rate: Float, earnings: Float, impressions: Integer,
31
+ monetized_playbacks: Integer}
32
+
33
+ specify 'by day, and are chronologically sorted' do
34
+ range = {since: 5.days.ago.to_date, until: 3.days.ago.to_date}
35
+ result = video_group.reports range.merge(only: metrics, by: :day)
36
+ metrics.each do |metric, type|
37
+ expect(result[metric].keys).to all(be_a Date)
38
+ expect(result[metric].values).to all(be_a type)
39
+ expect(result[metric].keys.sort).to eq result[metric].keys
40
+ end
41
+ end
42
+
43
+ # NOTE: all the other filters also apply, not tested for brevity
44
+ end
45
+
46
+ describe 'viewer_percentage can be grouped by age group' do
47
+ let(:range) { {since: 1.year.ago.to_date, until: 1.week.ago.to_date} }
48
+ let(:keys) { range.values }
49
+
50
+ specify 'with the :by option set to :age_group' do
51
+ viewer_percentage = video_group.viewer_percentage range.merge by: :age_group
52
+ expect(viewer_percentage.keys - %w(65- 35-44 45-54 13-17 25-34 55-64 18-24)).to be_empty
53
+ expect(viewer_percentage.values).to all(be_instance_of Float)
54
+ end
55
+ end
56
+ end
57
+
58
+ context 'not managed by the authenticated Content Owner' do
59
+ let(:id) { 'ABExJp9gAAA' }
60
+
61
+ specify 'views cannot be retrieved' do
62
+ expect{video_group.views}.to raise_error Yt::Error
63
+ end
64
+ end
65
+ end
66
+ end
@@ -1,7 +1,7 @@
1
1
  require 'simplecov'
2
2
  require 'coveralls'
3
3
 
4
- SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
4
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new [
5
5
  SimpleCov::Formatter::HTMLFormatter,
6
6
  Coveralls::SimpleCov::Formatter
7
7
  ]
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.17
4
+ version: 0.25.18
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-01-05 00:00:00.000000000 Z
11
+ date: 2016-01-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -142,6 +142,7 @@ files:
142
142
  - lib/yt/collections/content_owners.rb
143
143
  - lib/yt/collections/device_flows.rb
144
144
  - lib/yt/collections/file_details.rb
145
+ - lib/yt/collections/group_infos.rb
145
146
  - lib/yt/collections/ids.rb
146
147
  - lib/yt/collections/live_streaming_details.rb
147
148
  - lib/yt/collections/ownerships.rb
@@ -165,8 +166,10 @@ files:
165
166
  - lib/yt/collections/subscriptions.rb
166
167
  - lib/yt/collections/user_infos.rb
167
168
  - lib/yt/collections/video_categories.rb
169
+ - lib/yt/collections/video_groups.rb
168
170
  - lib/yt/collections/videos.rb
169
171
  - lib/yt/config.rb
172
+ - lib/yt/constants/geography.rb
170
173
  - lib/yt/errors/forbidden.rb
171
174
  - lib/yt/errors/missing_auth.rb
172
175
  - lib/yt/errors/no_items.rb
@@ -192,6 +195,7 @@ files:
192
195
  - lib/yt/models/description.rb
193
196
  - lib/yt/models/device_flow.rb
194
197
  - lib/yt/models/file_detail.rb
198
+ - lib/yt/models/group_info.rb
195
199
  - lib/yt/models/id.rb
196
200
  - lib/yt/models/iterator.rb
197
201
  - lib/yt/models/live_streaming_detail.rb
@@ -217,6 +221,7 @@ files:
217
221
  - lib/yt/models/user_info.rb
218
222
  - lib/yt/models/video.rb
219
223
  - lib/yt/models/video_category.rb
224
+ - lib/yt/models/video_group.rb
220
225
  - lib/yt/request.rb
221
226
  - lib/yt/version.rb
222
227
  - spec/collections/claims_spec.rb
@@ -227,6 +232,7 @@ files:
227
232
  - spec/collections/reports_spec.rb
228
233
  - spec/collections/subscriptions_spec.rb
229
234
  - spec/collections/videos_spec.rb
235
+ - spec/constants/geography_spec.rb
230
236
  - spec/errors/forbidden_spec.rb
231
237
  - spec/errors/missing_auth_spec.rb
232
238
  - spec/errors/no_items_spec.rb
@@ -283,6 +289,7 @@ files:
283
289
  - spec/requests/as_content_owner/match_policy_spec.rb
284
290
  - spec/requests/as_content_owner/ownership_spec.rb
285
291
  - spec/requests/as_content_owner/playlist_spec.rb
292
+ - spec/requests/as_content_owner/video_group_spec.rb
286
293
  - spec/requests/as_content_owner/video_spec.rb
287
294
  - spec/requests/as_server_app/channel_spec.rb
288
295
  - spec/requests/as_server_app/playlist_item_spec.rb
@@ -328,6 +335,7 @@ test_files:
328
335
  - spec/collections/reports_spec.rb
329
336
  - spec/collections/subscriptions_spec.rb
330
337
  - spec/collections/videos_spec.rb
338
+ - spec/constants/geography_spec.rb
331
339
  - spec/errors/forbidden_spec.rb
332
340
  - spec/errors/missing_auth_spec.rb
333
341
  - spec/errors/no_items_spec.rb
@@ -384,6 +392,7 @@ test_files:
384
392
  - spec/requests/as_content_owner/match_policy_spec.rb
385
393
  - spec/requests/as_content_owner/ownership_spec.rb
386
394
  - spec/requests/as_content_owner/playlist_spec.rb
395
+ - spec/requests/as_content_owner/video_group_spec.rb
387
396
  - spec/requests/as_content_owner/video_spec.rb
388
397
  - spec/requests/as_server_app/channel_spec.rb
389
398
  - spec/requests/as_server_app/playlist_item_spec.rb