yt 0.7.2 → 0.7.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/HISTORY.md +1 -0
- data/README.md +89 -103
- data/lib/yt/associations/authentications.rb +2 -1
- data/lib/yt/associations/earnings.rb +9 -17
- data/lib/yt/associations/views.rb +10 -18
- data/lib/yt/collections/annotations.rb +2 -1
- data/lib/yt/collections/channels.rb +1 -0
- data/lib/yt/collections/videos.rb +3 -1
- data/lib/yt/models/annotation.rb +4 -5
- data/lib/yt/models/authentication.rb +9 -2
- data/lib/yt/models/rating.rb +1 -1
- data/lib/yt/models/snippet.rb +96 -55
- data/lib/yt/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 280089714e1281d849dcb959a4de6e8bed69b76f
|
4
|
+
data.tar.gz: 8d2482b21d1ba9827c9a8172aab4475c36348c51
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 14db211427304d5eb03b6d62f50190eb50f614e8e0c9c68d6d7ff26c19ae88378f8feb4502cfaafb2e0ee15e0be0c7aa1d7aa01ff3fc211481b59b4257261a2b
|
7
|
+
data.tar.gz: 811037e6baf6cfc47c73cb3efd4a64ed5cb1b7c0f1aa0dfffa06ec4ee73106dbb7f26fe92b1b040b3ff5a72026c2076f5d05a3b5d2b4b7143fb22d8e652385a8
|
data/Gemfile.lock
CHANGED
data/HISTORY.md
CHANGED
@@ -9,6 +9,7 @@ v0.7 - 2014/06/18
|
|
9
9
|
* More snippet methods for PlaylistItem (channel_id, channel_title, playlist_id, video_id)
|
10
10
|
* More status methods for PlaylistItem (privacy_status, public?, private?, unlisted?)
|
11
11
|
* Add video.update to update title, description, tags and categoryId of a video
|
12
|
+
* Sort channel.videos by most recent first
|
12
13
|
|
13
14
|
v0.6 - 2014/06/05
|
14
15
|
-----------------
|
data/README.md
CHANGED
@@ -19,23 +19,14 @@ channel = Yt::Channel.new id: 'UCxO1tY8h1AhOz0T4ENwmpow'
|
|
19
19
|
channel.title #=> "Fullscreen"
|
20
20
|
channel.public? #=> true
|
21
21
|
channel.comment_count #=> 773
|
22
|
-
channel.videos.count #=>
|
22
|
+
channel.videos.count #=> 12
|
23
23
|
```
|
24
24
|
|
25
25
|
```ruby
|
26
26
|
video = Yt::Video.new id: 'MESycYJytkU'
|
27
27
|
video.title #=> "Fullscreen Creator Platform"
|
28
|
-
video.public? #=> true
|
29
|
-
video.view_count #=> 55843
|
30
28
|
video.comment_count #=> 308
|
31
|
-
video.like_count #=> 556
|
32
|
-
video.dislike_count #=> 78
|
33
|
-
video.favorite_count #=> 0
|
34
|
-
video.duration #=> 86
|
35
29
|
video.hd? #=> true
|
36
|
-
video.stereoscopic? #=> false
|
37
|
-
video.captioned? #=> true
|
38
|
-
video.licensed? #=> false
|
39
30
|
video.annotations.count #=> 1
|
40
31
|
```
|
41
32
|
|
@@ -51,14 +42,18 @@ Use [Yt::Account](http://rubydoc.info/github/Fullscreen/yt/master/Yt/Models/Acco
|
|
51
42
|
|
52
43
|
* authenticate as a YouTube account
|
53
44
|
* read the attributes of the account
|
54
|
-
* access the
|
45
|
+
* access the channel managed by the account
|
46
|
+
* access the videos uploaded by the account
|
55
47
|
|
56
48
|
```ruby
|
57
|
-
#
|
49
|
+
# Accounts can be initialized with access token, refresh token or an authorization code
|
58
50
|
account = Yt::Account.new access_token: 'ya29.1.ABCDEFGHIJ'
|
59
51
|
|
60
52
|
account.email #=> .. your e-mail address..
|
61
53
|
account.channel #=> #<Yt::Models::Channel @id=...>
|
54
|
+
|
55
|
+
account.videos.count #=> 12
|
56
|
+
account.videos.first #=> #<Yt::Models::Video @id=...>
|
62
57
|
```
|
63
58
|
|
64
59
|
*All the above methods require authentication (see below).*
|
@@ -72,7 +67,7 @@ Use [Yt::ContentOwner](http://rubydoc.info/github/Fullscreen/yt/master/Yt/Models
|
|
72
67
|
* list the channels partnered with a YouTube content owner
|
73
68
|
|
74
69
|
```ruby
|
75
|
-
#
|
70
|
+
# Content owners can be initialized with access token, refresh token or an authorization code
|
76
71
|
content_owner = Yt::ContentOwner.new owner_name: 'CMSname', access_token: 'ya29.1.ABCDEFGHIJ'
|
77
72
|
|
78
73
|
content_owner.partnered_channels.count #=> 12
|
@@ -99,13 +94,13 @@ channel = Yt::Channel.new id: 'UCxO1tY8h1AhOz0T4ENwmpow'
|
|
99
94
|
channel.title #=> "Fullscreen"
|
100
95
|
channel.description #=> "The first media company for the connected generation."
|
101
96
|
channel.description.has_link_to_playlist? #=> false
|
102
|
-
channel.thumbnail_url #=> "https://yt3.ggpht.com/-KMnbKDBl60w
|
97
|
+
channel.thumbnail_url #=> "https://yt3.ggpht.com/-KMnbKDBl60w/.../photo.jpg"
|
103
98
|
channel.published_at #=> 2006-03-23 06:13:25 UTC
|
104
99
|
channel.public? #=> true
|
105
100
|
|
106
101
|
channel.view_count #=> 421619
|
107
102
|
channel.comment_count #=> 773
|
108
|
-
channel.video_count #=>
|
103
|
+
channel.video_count #=> 12
|
109
104
|
channel.subscriber_count #=> 136925
|
110
105
|
channel.subscriber_count_visible? #=> true
|
111
106
|
|
@@ -127,7 +122,6 @@ channel.subscribe #=> true
|
|
127
122
|
|
128
123
|
channel.create_playlist title: 'New playlist' #=> true
|
129
124
|
channel.delete_playlists title: 'New playlist' #=> [true]
|
130
|
-
|
131
125
|
```
|
132
126
|
|
133
127
|
*The methods above require to be authenticated as a YouTube account (see below).*
|
@@ -137,10 +131,10 @@ content_owner = Yt::ContentOwner.new owner_name: 'CMSname', access_token: 'ya29.
|
|
137
131
|
channel = Yt::Channel.new id: 'UCxO1tY8h1AhOz0T4ENwmpow', auth: content_owner
|
138
132
|
|
139
133
|
channel.earnings_on 5.days.ago #=> 12.23
|
140
|
-
channel.earnings
|
134
|
+
channel.earnings until: 2.days.ago #=> {Wed, 28 May 2014 => 1.34, Thu, 29 May 2014 => 0.47}
|
141
135
|
|
142
136
|
channel.views_on 5.days.ago #=> 44
|
143
|
-
channel.views since: 3.days.ago
|
137
|
+
channel.views since: 3.days.ago #=> {Wed, 28 May 2014 => 12, Thu, 29 May 2014 => 3}
|
144
138
|
```
|
145
139
|
|
146
140
|
*The methods above require to be authenticated as the channel’s content owner (see below).*
|
@@ -159,7 +153,7 @@ Use [Yt::Video](http://rubydoc.info/github/Fullscreen/yt/master/Yt/Models/Video)
|
|
159
153
|
video = Yt::Video.new id: 'MESycYJytkU'
|
160
154
|
|
161
155
|
video.title #=> "Fullscreen Creator Platform"
|
162
|
-
video.description #=> "The new Fullscreen Creator Platform gives creators and brands a suite
|
156
|
+
video.description #=> "The new Fullscreen Creator Platform gives creators and brands a suite..."
|
163
157
|
video.description.has_link_to_channel? #=> true
|
164
158
|
video.thumbnail_url #=> "https://i1.ytimg.com/vi/MESycYJytkU/default.jpg"
|
165
159
|
video.published_at #=> 2013-07-09 16:27:32 UTC
|
@@ -193,7 +187,7 @@ video.like #=> true
|
|
193
187
|
*The methods above require to be authenticated as a YouTube account (see below).*
|
194
188
|
|
195
189
|
```ruby
|
196
|
-
video.update title: '
|
190
|
+
video.update title: 'A title', description: 'A description', tags: ['a tag'], categoryId: '21'
|
197
191
|
```
|
198
192
|
|
199
193
|
*The methods above require to be authenticated as the video’s owner (see below).*
|
@@ -213,7 +207,7 @@ Use [Yt::Playlist](http://rubydoc.info/github/Fullscreen/yt/master/Yt/Models/Pla
|
|
213
207
|
playlist = Yt::Playlist.new id: 'PLSWYkYzOrPMRCK6j0UgryI8E0NHhoVdRc'
|
214
208
|
|
215
209
|
playlist.title #=> "Fullscreen Features"
|
216
|
-
playlist.description #=> "You send us your best videos and we feature our favorite ones
|
210
|
+
playlist.description #=> "You send us your best videos and we feature our favorite ones..."
|
217
211
|
playlist.description.has_link_to_subscribe? #=> false
|
218
212
|
playlist.thumbnail_url #=> "https://i1.ytimg.com/vi/36kL2alg7Jk/default.jpg"
|
219
213
|
playlist.published_at #=> 2012-11-27 21:23:38 UTC
|
@@ -224,14 +218,12 @@ playlist.channel_title #=> "Fullscreen"
|
|
224
218
|
|
225
219
|
playlist.playlist_items.count #=> 1
|
226
220
|
playlist.playlist_items.first #=> #<Yt::Models::PlaylistItem @id=...>
|
227
|
-
playlist.playlist_items.first.position #=> 0
|
228
|
-
playlist.playlist_items.first.video.title #=> "Fullscreen Creator Platform"
|
229
221
|
```
|
230
222
|
|
231
223
|
*The methods above do not require authentication.*
|
232
224
|
|
233
225
|
```ruby
|
234
|
-
playlist.update title: '
|
226
|
+
playlist.update title: 'title', description: 'desc', tags: ['new tag'], privacy_status: 'private'
|
235
227
|
playlist.add_video 'MESycYJytkU'
|
236
228
|
playlist.add_videos ['MESycYJytkU', 'MESycYJytkU']
|
237
229
|
playlist.delete_playlist_items title: 'Fullscreen Creator Platform' #=> [true]
|
@@ -262,7 +254,6 @@ item.playlist_id #=> "PLSWYkYzOrPMRCK6j0UgryI8E0NHhoVdRc"
|
|
262
254
|
item.position #=> 0
|
263
255
|
item.video_id #=> "W4GhTprSsOY"
|
264
256
|
item.video #=> #<Yt::Models::Video @id=...>
|
265
|
-
|
266
257
|
```
|
267
258
|
|
268
259
|
*The methods above do not require authentication.*
|
@@ -296,23 +287,34 @@ Configuring your app
|
|
296
287
|
====================
|
297
288
|
|
298
289
|
In order to use Yt you must register your app in the [Google Developers Console](https://console.developers.google.com).
|
299
|
-
|
290
|
+
|
291
|
+
If you don’t have a registered app, browse to the console and select "Create Project":
|
292
|
+
![01-create-project](https://cloud.githubusercontent.com/assets/7408595/3373043/4224c894-fbb0-11e3-9f8a-4d96bddce136.png)
|
293
|
+
|
294
|
+
When your project is ready, select APIs & Auth in the menu and enable Google+, YouTube Analytics and YouTube Data API:
|
295
|
+
![02-select-api](https://cloud.githubusercontent.com/assets/7408595/3373046/4226ea34-fbb0-11e3-9a44-872871e8b297.png)
|
296
|
+
|
297
|
+
The next step is to create an API key. Depending on the nature of your app, you should pick one of the following strategies.
|
300
298
|
|
301
299
|
Apps that do not require user interactions
|
302
300
|
------------------------------------------
|
303
301
|
|
304
302
|
If you are building a read-only app that fetches public data from YouTube, then
|
305
|
-
|
306
|
-
|
303
|
+
all you need is a **Public API access**.
|
304
|
+
|
305
|
+
Click on "Create new Key" in the Public API section and select "Server Key":
|
306
|
+
![03-create-key](https://cloud.githubusercontent.com/assets/7408595/3373045/42258fcc-fbb0-11e3-821c-699c8a3ce7bc.png)
|
307
|
+
![04-create-server-key](https://cloud.githubusercontent.com/assets/7408595/3373044/42251db2-fbb0-11e3-93f9-8f06f8390b4e.png)
|
308
|
+
|
309
|
+
Once the key for server application is created, copy the API key and add it
|
310
|
+
to your code with the following snippet of code (replacing with your own key):
|
307
311
|
|
308
312
|
```ruby
|
309
313
|
Yt.configure do |config|
|
310
|
-
config.api_key = '
|
314
|
+
config.api_key = 'AIzaSyAO8dXpvZcaP2XSDFBD91H8yQ'
|
311
315
|
end
|
312
316
|
```
|
313
317
|
|
314
|
-
replacing the value above with your own key for server application.
|
315
|
-
|
316
318
|
Remember: this kind of app is not allowed to perform any destructive operation,
|
317
319
|
so you won’t be able to like a video, subscribe to a channel or delete a
|
318
320
|
playlist from a specific account. You will only be able to retrieve read-only
|
@@ -330,14 +332,15 @@ Just pass that access token to the account initializer, such as:
|
|
330
332
|
```ruby
|
331
333
|
account = Yt::Account.new access_token: 'ya29.1.ABCDEFGHIJ'
|
332
334
|
account.email #=> (retrieves the account’s e-mail address)
|
333
|
-
account.
|
335
|
+
account.videos #=> (lists a video to an account’s playlist)
|
334
336
|
```
|
335
337
|
|
336
338
|
Scenario 2. If you don’t have the account’s access token, but you have the
|
337
339
|
**refresh token**, then it’s almost as easy.
|
338
|
-
|
339
|
-
find the
|
340
|
-
|
340
|
+
In the [Google Developers Console](https://console.developers.google.com),
|
341
|
+
find the web application that was used to obtain the refresh token, copy the
|
342
|
+
Client ID and Client secret and add them to you code with the following snippet
|
343
|
+
of code (replacing with your own keys):
|
341
344
|
|
342
345
|
```ruby
|
343
346
|
Yt.configure do |config|
|
@@ -345,38 +348,53 @@ Yt.configure do |config|
|
|
345
348
|
config.client_secret = '1234567890'
|
346
349
|
end
|
347
350
|
```
|
348
|
-
|
349
|
-
replacing the values above with the client ID and secret for web application.
|
350
351
|
Then you can manage a YouTube account by passing the refresh token to the
|
351
352
|
account initializer, such as:
|
352
353
|
|
353
354
|
```ruby
|
354
355
|
account = Yt::Account.new refresh_token: '1/1234567890'
|
355
356
|
account.email #=> (retrieves the account’s e-mail address)
|
356
|
-
account.
|
357
|
+
account.videos #=> (lists a video to an account’s playlist)
|
357
358
|
```
|
358
359
|
|
359
360
|
Scenario 3. If you don’t have any account’s token, then you can get one by
|
360
|
-
having the user authorize your app through the Google OAuth page.
|
361
|
-
|
361
|
+
having the user authorize your app through the Google OAuth page.
|
362
|
+
|
363
|
+
In the [Google Developers Console](https://console.developers.google.com),
|
364
|
+
click on "Create new Client ID" in the OAuth section and select "Web application":
|
365
|
+
![06-create-client-key](https://cloud.githubusercontent.com/assets/7408595/3373047/42379eba-fbb0-11e3-89c4-16b10e072de6.png)
|
366
|
+
|
367
|
+
Fill the "Authorized Redirect URI" textarea with the URL of your app where you
|
368
|
+
want to redirect users after they authorize their YouTube account.
|
369
|
+
|
370
|
+
Once the Client ID for web application is created, copy the Client ID and secret
|
371
|
+
and add them to your code with the following snippet of code (replacing with your own keys):
|
372
|
+
|
373
|
+
```ruby
|
374
|
+
Yt.configure do |config|
|
375
|
+
config.client_id = '49781862760-4t610gtk35462g.apps.googleusercontent.com'
|
376
|
+
config.client_secret = 'NtFHjZkJcwYZDfYVz9mp8skz9'
|
377
|
+
end
|
378
|
+
```
|
379
|
+
|
380
|
+
Finally, in your web app, add a link to the URL generated by running
|
362
381
|
|
363
382
|
```ruby
|
364
383
|
Yt::Account.new(scopes: scopes, redirect_uri: redirect_uri).authentication_url
|
365
384
|
```
|
366
385
|
|
367
|
-
where `
|
368
|
-
|
369
|
-
|
370
|
-
Sample scopes are: `youtube`, `youtube.readonly` `userinfo.email`.
|
386
|
+
where `redirect_uri` is the URL you entered in the form above, and `scopes` is
|
387
|
+
the list of YouTube scopes you want the user to authorize. Depending on the
|
388
|
+
nature of your app, you can pick one or more among `youtube`, `youtube.readonly` `userinfo.email`.
|
371
389
|
|
372
|
-
|
390
|
+
Every user who authorizes your app will be redirected to the `redirect_uri`
|
373
391
|
with an extra `code` parameter that looks something like `4/Ja60jJ7_Kw0`.
|
374
392
|
Just pass the code to the following method to authenticate and initialize the account:
|
375
393
|
|
376
394
|
```ruby
|
377
395
|
account = Yt::Account.new authorization_code: '4/Ja60jJ7_Kw0'
|
378
396
|
account.email #=> (retrieves the account’s e-mail address)
|
379
|
-
account.
|
397
|
+
account.videos #=> (lists a video to an account’s playlist)
|
380
398
|
```
|
381
399
|
|
382
400
|
Configuring with environment variables
|
@@ -386,7 +404,6 @@ As an alternative to the approach above, you can configure your app with
|
|
386
404
|
variables. Setting the following environment variables:
|
387
405
|
|
388
406
|
```bash
|
389
|
-
export YT_CLIENT_SCENARIO="device_app"
|
390
407
|
export YT_CLIENT_ID="1234567890.apps.googleusercontent.com"
|
391
408
|
export YT_CLIENT_SECRET="1234567890"
|
392
409
|
export YT_API_KEY="123456789012345678901234567890"
|
@@ -405,7 +422,6 @@ end
|
|
405
422
|
so use the approach that you prefer.
|
406
423
|
If a variable is set in both places, then `Yt.configure` takes precedence.
|
407
424
|
|
408
|
-
|
409
425
|
How to install
|
410
426
|
==============
|
411
427
|
|
@@ -415,7 +431,7 @@ To install on your system, run
|
|
415
431
|
|
416
432
|
To use inside a bundled Ruby project, add this line to the Gemfile:
|
417
433
|
|
418
|
-
gem 'yt', '~> 0.7.
|
434
|
+
gem 'yt', '~> 0.7.3'
|
419
435
|
|
420
436
|
Since the gem follows [Semantic Versioning](http://semver.org),
|
421
437
|
indicating the full version in your Gemfile (~> *major*.*minor*.*patch*)
|
@@ -442,15 +458,9 @@ How to test
|
|
442
458
|
|
443
459
|
Yt comes with two different sets of tests:
|
444
460
|
|
445
|
-
1. tests in `spec/models` and `spec/
|
461
|
+
1. tests in `spec/models`, `spec/collections` and `spec/errors` **do not hit** the YouTube API
|
446
462
|
1. tests in `spec/associations` **hit** the YouTube API and require authentication
|
447
463
|
|
448
|
-
To run all the tests, type:
|
449
|
-
|
450
|
-
```bash
|
451
|
-
rspec
|
452
|
-
```
|
453
|
-
|
454
464
|
The reason why some tests actually hit the YouTube API is because they are
|
455
465
|
meant to really integrate Yt with YouTube. YouTube API is not exactly
|
456
466
|
*the most reliable* API out there, so we need to make sure that the responses
|
@@ -460,70 +470,46 @@ You don’t have to run all the tests every time you change code.
|
|
460
470
|
Travis CI is already set up to do this for when whenever you push a branch
|
461
471
|
or create a pull request for this project.
|
462
472
|
|
463
|
-
|
464
|
-
------------------------------
|
465
|
-
|
466
|
-
To only run tests against models and collections (which do not hit the API), type:
|
473
|
+
To only run tests against models, collections and errors (which do not hit the API), type:
|
467
474
|
|
468
475
|
```bash
|
469
|
-
rspec spec/models spec/collections
|
476
|
+
rspec spec/models spec/collections spec/errors
|
470
477
|
```
|
471
478
|
|
472
|
-
|
473
|
-
--------------------
|
474
|
-
|
475
|
-
To only run tests against associations (which hit the API), type:
|
479
|
+
To also run live-tests against the YouTube API, type:
|
476
480
|
|
477
481
|
```bash
|
478
|
-
rspec
|
482
|
+
rspec
|
479
483
|
```
|
480
484
|
|
481
|
-
This
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
Browse to the Console, then create a new app that you will only use for testing.
|
485
|
+
This will fail unless you have set up a test YouTube application and some
|
486
|
+
tests YouTube accounts to hit the API. Once again, you probably don’t need
|
487
|
+
this, since Travis CI already takes care of running this kind of tests.
|
486
488
|
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
Under the "Credentials" tab of this app, create a new 'Key for server
|
491
|
-
application' and a new 'Client ID' and 'Client Secret' for **native** application.
|
492
|
-
|
493
|
-
It’s important that you pick 'native application' instead of 'web application',
|
494
|
-
otherwise running your tests will require you to open a browser and launch a
|
495
|
-
local webserver… and you don’t need to do any of that.
|
496
|
-
|
497
|
-
Finally, copy the given values and set the following environment variables:
|
498
|
-
|
499
|
-
```bash
|
500
|
-
export YT_TEST_DEVICE_CLIENT_ID="1234567890.apps.googleusercontent.com"
|
501
|
-
export YT_TEST_DEVICE_CLIENT_SECRET="1234567890"
|
502
|
-
export YT_TEST_SERVER_API_KEY="123456789012345678901234567890"
|
503
|
-
```
|
504
|
-
|
505
|
-
[ TODO:
|
506
|
-
Complete this section.
|
507
|
-
Explain how get and store the refresh token, making sure all the required scopes are authorized:
|
508
|
-
'https://www.googleapis.com/auth/youtube https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile'
|
509
|
-
]
|
489
|
+
How to contribute
|
490
|
+
=================
|
510
491
|
|
492
|
+
Yt needs your support!
|
493
|
+
The goal of Yt is to provide a Ruby interface for all the methods exposed by
|
494
|
+
the [YouTube Data API (v3)](https://developers.google.com/youtube/v3) and by
|
495
|
+
the [YouTube Analytics API](https://developers.google.com/youtube/analytics).
|
511
496
|
|
497
|
+
If you find that a method is missing, fork the project, add the missing code,
|
498
|
+
write the appropriate tests, then submit a pull request, and it will gladly
|
499
|
+
be merged!
|
512
500
|
|
513
|
-
How to
|
514
|
-
|
501
|
+
How to release new versions
|
502
|
+
===========================
|
515
503
|
|
516
|
-
|
517
|
-
|
504
|
+
If you are a manager of this project, remember to upgrade the [Yt gem](http://rubygems.org/gems/yt)
|
505
|
+
whenever a new feature is added or a bug gets fixed.
|
518
506
|
|
519
|
-
|
507
|
+
Make sure all the tests are passing on [Travis CI](https://travis-ci.org/Fullscreen/yt),
|
508
|
+
document the changes in HISTORY.md and README.md, bump the version, then run
|
520
509
|
|
521
510
|
rake release
|
522
511
|
|
523
|
-
Remember
|
524
|
-
your changes in HISTORY.md and README.md if required.
|
525
|
-
|
526
|
-
The yt gem follows [Semantic Versioning](http://semver.org).
|
512
|
+
Remember that the yt gem follows [Semantic Versioning](http://semver.org).
|
527
513
|
Any new release that is fully backward-compatible should bump the *patch* version (0.0.x).
|
528
514
|
Any new version that breaks compatibility should bump the *minor* version (0.x.0)
|
529
515
|
|
@@ -7,7 +7,8 @@ module Yt
|
|
7
7
|
module Associations
|
8
8
|
# Provides authentication methods to YouTube resources, which
|
9
9
|
# allows to access to content detail set-specific methods like `access_token`.
|
10
|
-
#
|
10
|
+
#
|
11
|
+
# YouTube resources with authentication are: {Yt::Models::Account accounts}.
|
11
12
|
module Authentications
|
12
13
|
delegate :access_token, :refresh_token, :expires_at, to: :authentication
|
13
14
|
|
@@ -2,32 +2,24 @@ require 'yt/collections/earnings'
|
|
2
2
|
|
3
3
|
module Yt
|
4
4
|
module Associations
|
5
|
-
# Provides the
|
6
|
-
#
|
7
|
-
# YouTube resources with earning are: channels.
|
5
|
+
# Provides methods which allows to access the earnings generated by a resource.
|
6
|
+
#
|
7
|
+
# YouTube resources with earning are: {Yt::Models::Channel channels}.
|
8
8
|
module Earnings
|
9
|
-
#
|
10
|
-
#
|
9
|
+
# @return [Float] the estimated earnings for one specific day in USD.
|
11
10
|
# @param [Date or Time or DateTime or String] date The date to obtain
|
12
|
-
#
|
13
|
-
#
|
14
|
-
# @return [Float] The estimated earnings in USD.
|
11
|
+
# the estimated earnings for. If +String+, must be Date-parseable.
|
15
12
|
def earnings_on(date)
|
16
13
|
earnings(from: date, to: date).values.first
|
17
14
|
end
|
18
15
|
|
19
|
-
#
|
20
|
-
#
|
16
|
+
# @return [Hash] the estimated earnings for a range of days. Each +key+ is a +Date+
|
17
|
+
# and each +value+ is a +Float+, representing estimated earnings in USD.
|
21
18
|
# @param [Hash] options the range of days to get the earnings for.
|
22
19
|
# @option options [Date or Time or DateTime or String] :since The start
|
23
|
-
#
|
24
|
-
# @note options[:since] is aliased as options[:from]
|
20
|
+
# of the days range. If +String+, must be Date-parseable. Also aliased as *:from*.
|
25
21
|
# @option options [Date or Time or DateTime or String] :until The end
|
26
|
-
#
|
27
|
-
# @note options[:until] is aliased as options[:to]
|
28
|
-
#
|
29
|
-
# @return [Hash] The estimated earnings by day. Each :key is a Date
|
30
|
-
# and each :value is a Float, representing estimated earnings in USD.
|
22
|
+
# of the days range. If +String+, must be Date-parseable. Also aliased as *:to*.
|
31
23
|
def earnings(options = {})
|
32
24
|
from = options[:since] || options[:from] || 6.days.ago
|
33
25
|
to = options[:until] || options[:to] || 2.days.ago
|
@@ -2,32 +2,24 @@ require 'yt/collections/views'
|
|
2
2
|
|
3
3
|
module Yt
|
4
4
|
module Associations
|
5
|
-
# Provides
|
6
|
-
#
|
7
|
-
# YouTube resources with
|
5
|
+
# Provides methods which allows to access the view count of a resource.
|
6
|
+
#
|
7
|
+
# YouTube resources with view counts are: {Yt::Models::Channel channels}.
|
8
8
|
module Views
|
9
|
-
#
|
10
|
-
#
|
9
|
+
# @return [Integer, nil] the view count for one specific day.
|
11
10
|
# @param [Date or Time or DateTime or String] date The date to obtain
|
12
|
-
#
|
13
|
-
#
|
14
|
-
# @return [Integer or Nil] The estimated views.
|
11
|
+
# the views for. If +String+, must be Date-parseable.
|
15
12
|
def views_on(date)
|
16
13
|
views(from: date, to: date).values.first
|
17
14
|
end
|
18
15
|
|
19
|
-
#
|
20
|
-
#
|
21
|
-
# @param [Hash] options the range of days to get the
|
16
|
+
# @return [Hash] the view counts for a range of days. Each +key+ is a +Date+
|
17
|
+
# and each +value+ is an +Integer+ or +nil+, representing the number of views.
|
18
|
+
# @param [Hash] options the range of days to get the view for.
|
22
19
|
# @option options [Date or Time or DateTime or String] :since The start
|
23
|
-
#
|
24
|
-
# @note options[:since] is aliased as options[:from]
|
20
|
+
# of the days range. If +String+, must be Date-parseable. Also aliased as *:from*.
|
25
21
|
# @option options [Date or Time or DateTime or String] :until The end
|
26
|
-
#
|
27
|
-
# @note options[:until] is aliased as options[:to]
|
28
|
-
#
|
29
|
-
# @return [Hash] The view count by day. Each :key is a Date
|
30
|
-
# and each :value is an Integer or nil, representing the number of views.
|
22
|
+
# of the days range. If +String+, must be Date-parseable. Also aliased as *:to*.
|
31
23
|
def views(options = {})
|
32
24
|
from = options[:since] || options[:from] || 5.days.ago
|
33
25
|
to = options[:until] || options[:to] || 1.day.ago
|
@@ -4,9 +4,10 @@ require 'yt/models/annotation'
|
|
4
4
|
module Yt
|
5
5
|
module Collections
|
6
6
|
# Provides methods to interact with a collection of YouTube annotations.
|
7
|
+
#
|
7
8
|
# Resources with annotations are: {Yt::Models::Video videos}.
|
8
9
|
# @note Since there is no (authenticable) API endpoint to retrieve
|
9
|
-
# annotations, only annotations of
|
10
|
+
# annotations, only annotations of public videos can be retrieved.
|
10
11
|
class Annotations < Base
|
11
12
|
|
12
13
|
private
|
@@ -4,6 +4,7 @@ require 'yt/models/video'
|
|
4
4
|
module Yt
|
5
5
|
module Collections
|
6
6
|
# Provides methods to interact with a collection of YouTube videos.
|
7
|
+
#
|
7
8
|
# Resources with videos are: {Yt::Models::Channel channels} and
|
8
9
|
# {Yt::Models::Account accounts}.
|
9
10
|
class Videos < Base
|
@@ -27,8 +28,9 @@ module Yt
|
|
27
28
|
end
|
28
29
|
|
29
30
|
def videos_params
|
31
|
+
params = {type: :video, maxResults: 50, part: 'snippet', order: 'date'}
|
30
32
|
@extra_params ||= {}
|
31
|
-
|
33
|
+
params.merge @extra_params
|
32
34
|
end
|
33
35
|
end
|
34
36
|
end
|
data/lib/yt/models/annotation.rb
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
module Yt
|
2
2
|
module Models
|
3
3
|
# Provides methods to interact with YouTube annotations.
|
4
|
+
# @note YouTube API V3 does not provide access to video annotations,
|
5
|
+
# therefore a legacy XML endpoint is used to retrieve annotations.
|
4
6
|
# @see https://www.youtube.com/yt/playbook/annotations.html
|
5
7
|
class Annotation
|
6
8
|
# @param [Hash] options the options to initialize an Annotation.
|
7
9
|
# @option options [String] :data The XML representation of an annotation
|
8
|
-
# @note YouTube API V3 does not provide access to video annotations,
|
9
|
-
# therefore the XML endpoint is used to retrieve them and its response
|
10
|
-
# is passed to the Annotation initializer.
|
11
10
|
def initialize(options = {})
|
12
11
|
@data = options[:data]
|
13
12
|
end
|
@@ -58,7 +57,7 @@ module Yt
|
|
58
57
|
# @return [Boolean] whether the annotation starts after the number of
|
59
58
|
# seconds indicated.
|
60
59
|
# @note This is broken for invideo programming, because they do not
|
61
|
-
#
|
60
|
+
# have the timestamp in the region, but in the "data" field
|
62
61
|
def starts_after?(seconds)
|
63
62
|
timestamps.first > seconds if timestamps.any?
|
64
63
|
end
|
@@ -67,7 +66,7 @@ module Yt
|
|
67
66
|
# @return [Boolean] whether the annotation starts before the number of
|
68
67
|
# seconds indicated.
|
69
68
|
# @note This is broken for invideo programming, because they do not
|
70
|
-
#
|
69
|
+
# have the timestamp in the region, but in the "data" field
|
71
70
|
def starts_before?(seconds)
|
72
71
|
timestamps.first < seconds if timestamps.any?
|
73
72
|
end
|
@@ -6,11 +6,14 @@ module Yt
|
|
6
6
|
|
7
7
|
# Before your application can access private data using a Google API,
|
8
8
|
# it must obtain an access token that grants access to that API.
|
9
|
+
#
|
9
10
|
# A single access token can grant varying degrees of access to multiple
|
10
11
|
# APIs. A variable parameter called scope controls the set of resources
|
11
12
|
# and operations that an access token permits.
|
13
|
+
#
|
12
14
|
# After an application obtains an access token, it sends the token to a
|
13
15
|
# Google API in an HTTP authorization header.
|
16
|
+
#
|
14
17
|
# Access tokens are valid only for the set of operations and resources
|
15
18
|
# described in the scope of the token request. For example, if an access
|
16
19
|
# token is issued for the Google+ API, it does not grant access to the
|
@@ -23,12 +26,14 @@ module Yt
|
|
23
26
|
# to a Google API beyond the lifetime of a single access token, it can
|
24
27
|
# obtain a refresh token. A refresh token allows your application to
|
25
28
|
# obtain new access tokens.
|
26
|
-
#
|
29
|
+
#
|
30
|
+
# Save refresh tokens in secure long-term storage and continue to
|
27
31
|
# use them as long as they remain valid. Limits apply to the number of
|
28
32
|
# refresh tokens that are issued per client-user combination, and per
|
29
33
|
# user across all clients, and these limits are different. If your
|
30
34
|
# application requests enough refresh tokens to go over one of the
|
31
35
|
# limits, older refresh tokens stop working.
|
36
|
+
#
|
32
37
|
# There is currently a 25-token limit per Google user account.
|
33
38
|
# If a user account has 25 valid tokens, the next authentication request
|
34
39
|
# succeeds, but quietly invalidates the oldest outstanding token without
|
@@ -39,7 +44,9 @@ module Yt
|
|
39
44
|
|
40
45
|
# Access tokens have limited lifetimes. If your application needs access
|
41
46
|
# to a Google API beyond the lifetime of a single access token, it can
|
42
|
-
# obtain a refresh token.
|
47
|
+
# obtain a refresh token.
|
48
|
+
#
|
49
|
+
# A refresh token allows your application to
|
43
50
|
# obtain new access tokens.
|
44
51
|
#
|
45
52
|
# @return [Time] the time when access token no longer works.
|
data/lib/yt/models/rating.rb
CHANGED
@@ -6,7 +6,7 @@ module Yt
|
|
6
6
|
# @see https://developers.google.com/youtube/v3/docs/videos/rate
|
7
7
|
# @see https://developers.google.com/youtube/v3/docs/videos/getRating
|
8
8
|
class Rating < Base
|
9
|
-
# @return [Symbol
|
9
|
+
# @return [Symbol, nil] the rating of a video (if present).
|
10
10
|
# Valid values are: :dislike, :like, :none, :unspecified
|
11
11
|
attr_reader :rating
|
12
12
|
|
data/lib/yt/models/snippet.rb
CHANGED
@@ -3,119 +3,160 @@ require 'yt/models/description'
|
|
3
3
|
module Yt
|
4
4
|
module Models
|
5
5
|
# Contains basic information about the resource. The details of the snippet
|
6
|
-
# are different for the different types of resources.
|
7
|
-
#
|
6
|
+
# are different for the different types of resources.
|
7
|
+
#
|
8
|
+
# Resources with a
|
9
|
+
# snippet are: channels, playlists, playlist items and videos.
|
8
10
|
# @see https://developers.google.com/youtube/v3/docs/channels#resource
|
9
11
|
# @see https://developers.google.com/youtube/v3/docs/videos#resource
|
12
|
+
# @see https://developers.google.com/youtube/v3/docs/playlists#resource
|
13
|
+
# @see https://developers.google.com/youtube/v3/docs/playlistItems#resource
|
10
14
|
class Snippet
|
11
15
|
def initialize(options = {})
|
12
16
|
@data = options[:data]
|
13
17
|
@auth = options[:auth]
|
14
18
|
end
|
15
19
|
|
16
|
-
# @return [String] the resource’s title.
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
20
|
+
# @return [String] if the resource is a channel, the channel’s title.
|
21
|
+
# @return [String] if the resource is a playlist, the playlist’s title.
|
22
|
+
# @return [String] if the resource is a playlist item, the item’s title.
|
23
|
+
# @return [String] if the resource is a video, the video’s title. Has a
|
24
|
+
# maximum of 100 characters and may contain all valid UTF-8 characters
|
25
|
+
# except < and >.
|
22
26
|
def title
|
23
27
|
@title ||= @data.fetch 'title', ''
|
24
28
|
end
|
25
29
|
|
26
|
-
# @return [Yt::Models::Description] the resource
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
32
|
-
#
|
30
|
+
# @return [Yt::Models::Description] if the resource is a channel, the
|
31
|
+
# channel’s description. Has a maximum of 1000 characters.
|
32
|
+
# @return [Yt::Models::Description] if the resource is a playlist, the
|
33
|
+
# playlist’s description.
|
34
|
+
# @return [Yt::Models::Description] if the resource is a playlist item,
|
35
|
+
# the item’s description.
|
36
|
+
# @return [Yt::Models::Description] if the resource is a video, the
|
37
|
+
# video’s description. Has a maximum of 5000 bytes and may contain all
|
38
|
+
# valid UTF-8 characters except < and >.
|
33
39
|
def description
|
34
40
|
@description ||= Description.new @data.fetch('description', '')
|
35
41
|
end
|
36
42
|
|
37
|
-
# @return [Time] the date and time that the
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
#
|
42
|
-
#
|
43
|
+
# @return [Time] if the resource is a channel, the date and time that the
|
44
|
+
# channel was created.
|
45
|
+
# @return [Time] if the resource is a playlist, the date and time that
|
46
|
+
# the playlist was created.
|
47
|
+
# @return [Time] if the resource is a playlist item, the date and time
|
48
|
+
# that the item was added to the playlist.
|
49
|
+
# @return [Time] if the resource is a video, the date and time that the
|
50
|
+
# video was published.
|
43
51
|
def published_at
|
44
52
|
@published_at ||= Time.parse @data['publishedAt']
|
45
53
|
end
|
46
54
|
|
47
|
-
# @param [Symbol
|
48
|
-
# @return [String
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
55
|
+
# @param [Symbol, String] size The size of the thumbnail to retrieve.
|
56
|
+
# @return [String] if the resource is a channel and +size+ is +default+,
|
57
|
+
# the URL of an 88x88px image.
|
58
|
+
# @return [String] if the resource is a playlist, a PlaylistItem or a
|
59
|
+
# Video and +size+ is +default+, the URL of an 120x90px image.
|
60
|
+
# @return [String] if the resource is a channel and +size+ is +medium+,
|
61
|
+
# the URL of an 240x240px image.
|
62
|
+
# @return [String] if the resource is a playlist, a PlaylistItem or a
|
63
|
+
# Video and +size+ is +medium+, the URL of an 320x180px image.
|
64
|
+
# @return [String] if the resource is a channel and +size+ is +high+,
|
65
|
+
# the URL of an 800x800px image.
|
66
|
+
# @return [String] if the resource is a playlist, a PlaylistItem or a
|
67
|
+
# Video and +size+ is +high+, the URL of an 480x360px image.
|
68
|
+
# @return [nil] if the +size+ is not +default+, +medium+ or +high+.
|
53
69
|
def thumbnail_url(size = :default)
|
54
70
|
@thumbnails ||= @data.fetch 'thumbnails', {}
|
55
71
|
@thumbnails.fetch(size.to_s, {})['url']
|
56
72
|
end
|
57
73
|
|
58
|
-
# @return [String
|
59
|
-
#
|
60
|
-
#
|
61
|
-
#
|
62
|
-
#
|
63
|
-
#
|
64
|
-
#
|
74
|
+
# @return [String] if the resource is a playlist, the ID that YouTube
|
75
|
+
# uses to uniquely identify the channel that the playlist belongs to.
|
76
|
+
# @return [String] if the resource is a playlist item, the ID that YouTube
|
77
|
+
# uses to uniquely identify the channel that the playlist belongs to.
|
78
|
+
# @return [String] if the resource is a video, the ID that YouTube uses
|
79
|
+
# to uniquely identify the channel that the video was uploaded to.
|
80
|
+
# @return [nil] if the resource is a channel.
|
65
81
|
def channel_id
|
66
82
|
@channel_id ||= @data['channelId']
|
67
83
|
end
|
68
84
|
|
69
|
-
# @return [String
|
70
|
-
#
|
71
|
-
#
|
72
|
-
#
|
73
|
-
#
|
85
|
+
# @return [String] if the resource is a playlist, the title of the
|
86
|
+
# channel that the playlist belongs to.
|
87
|
+
# @return [String] if the resource is a playlist item, the title of the
|
88
|
+
# channel that the playlist item belongs to.
|
89
|
+
# @return [String] if the resource is a video, the title of the channel
|
90
|
+
# that the video was uploaded to.
|
91
|
+
# @return [nil] if the resource is a channel.
|
74
92
|
def channel_title
|
75
93
|
@channel_title ||= @data['channelTitle']
|
76
94
|
end
|
77
95
|
|
78
|
-
# @return [Array<Yt::Models::Tag>]
|
79
|
-
#
|
80
|
-
#
|
96
|
+
# @return [Array<Yt::Models::Tag>] if the resource is a channel, an
|
97
|
+
# empty array.
|
98
|
+
# @return [Array<Yt::Models::Tag>] if the resource is a playlist, the
|
99
|
+
# list of keyword tags associated with the playlist.
|
100
|
+
# @return [Array<Yt::Models::Tag>] if the resource is a playlist item,
|
101
|
+
# an empty array.
|
102
|
+
# @return [Array<Yt::Models::Tag>] if the resource is a video, the list
|
103
|
+
# of keyword tags associated with the video.
|
81
104
|
def tags
|
82
105
|
@tags ||= @data.fetch 'tags', []
|
83
106
|
end
|
84
107
|
|
85
|
-
# @return [String
|
86
|
-
#
|
108
|
+
# @return [String] if the resource is a video, the YouTube video
|
109
|
+
# category associated with the video.
|
110
|
+
# @return [nil] if the resource is a channel.
|
111
|
+
# @return [nil] if the resource is a playlist.
|
112
|
+
# @return [nil] if the resource is a playlist item.
|
87
113
|
# @see https://developers.google.com/youtube/v3/docs/videoCategories/list
|
88
114
|
def category_id
|
89
115
|
@category_id ||= @data['categoryId']
|
90
116
|
end
|
91
117
|
|
92
|
-
# @return [String
|
93
|
-
# broadcast. Valid values are: live, none, upcoming
|
118
|
+
# @return [String] if the resource is a video, whether the resource is a
|
119
|
+
# live broadcast. Valid values are: live, none, upcoming.
|
120
|
+
# @return [nil] if the resource is a channel.
|
121
|
+
# @return [nil] if the resource is a playlist.
|
122
|
+
# @return [nil] if the resource is a playlist item.
|
94
123
|
def live_broadcast_content
|
95
124
|
@live_broadcast_content ||= @data['liveBroadcastContent']
|
96
125
|
end
|
97
126
|
|
98
|
-
# @return [String
|
99
|
-
# the playlist that the item is in
|
127
|
+
# @return [String] if the resource is a playlist item, the ID that
|
128
|
+
# YouTube uses to uniquely identify the playlist that the item is in.
|
129
|
+
# @return [nil] if the resource is a channel.
|
130
|
+
# @return [nil] if the resource is a playlist.
|
131
|
+
# @return [nil] if the resource is a video.
|
100
132
|
def playlist_id
|
101
133
|
@playlist_id ||= @data['playlistId']
|
102
134
|
end
|
103
135
|
|
104
|
-
# @return [Integer
|
105
|
-
# playlist. The value is zero-based, so the
|
106
|
-
# of 0, the second item of 1, and so forth
|
136
|
+
# @return [Integer] if the resource is a playlist item, the order in
|
137
|
+
# which the item appears in a playlist. The value is zero-based, so the
|
138
|
+
# first item has a position of 0, the second item of 1, and so forth.
|
139
|
+
# @return [nil] if the resource is a channel.
|
140
|
+
# @return [nil] if the resource is a playlist.
|
141
|
+
# @return [nil] if the resource is a video.
|
107
142
|
def position
|
108
143
|
@position ||= @data['position'].to_i
|
109
144
|
end
|
110
145
|
|
111
|
-
# @return [String
|
112
|
-
#
|
146
|
+
# @return [String] if the resource is a playlist item, the ID of the
|
147
|
+
# video the playlist item represents in the playlist.
|
148
|
+
# @return [nil] if the resource is a channel.
|
149
|
+
# @return [nil] if the resource is a playlist.
|
150
|
+
# @return [nil] if the resource is a video.
|
113
151
|
def video_id
|
114
152
|
@video_id ||= @data.fetch('resourceId', {})['videoId']
|
115
153
|
end
|
116
154
|
|
117
|
-
# @return [Yt::Models::Video
|
118
|
-
#
|
155
|
+
# @return [Yt::Models::Video] the video the playlist item represents in
|
156
|
+
# the playlist.
|
157
|
+
# @return [nil] if the resource is a channel.
|
158
|
+
# @return [nil] if the resource is a playlist.
|
159
|
+
# @return [nil] if the resource is a video.
|
119
160
|
def video
|
120
161
|
@video ||= Video.new id: video_id, auth: @auth if video_id
|
121
162
|
end
|
data/lib/yt/version.rb
CHANGED
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.
|
4
|
+
version: 0.7.3
|
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-06-
|
11
|
+
date: 2014-06-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|