yt 0.4.7 → 0.4.8
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 +4 -4
- data/.travis.yml +5 -5
- data/Gemfile.lock +1 -1
- data/HISTORY.md +1 -0
- data/README.md +94 -5
- data/lib/yt/actions/request.rb +32 -2
- data/lib/yt/models/configuration.rb +12 -1
- data/lib/yt/version.rb +1 -1
- data/spec/models/configuration_spec.rb +57 -0
- data/spec/support/device_app.rb +2 -3
- data/spec/support/server_app.rb +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d001dddb418e4e74f6de7356d350befaaec179d1
|
|
4
|
+
data.tar.gz: 2356e2a5fa9861028411c6f8b0ca99b94d79f735
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4de11d3034cba5ec8702c2c747c8689142f915bb4e8d17d6dc21e65e583359ff5b6bba94f9f2f855229227cc7a6c8ec76a325a2af8ac49edf24e145954850352
|
|
7
|
+
data.tar.gz: bfcd0d23ea29ed718595bf6e71a9bc6552cc1fa748aa1d1f76dafd73e76c37708b126b83f5539cd716c9740e013f4e67c7f6109c34c0f1f56f151c16402160f2
|
data/.travis.yml
CHANGED
|
@@ -6,13 +6,13 @@ matrix:
|
|
|
6
6
|
- rvm: 1.9.3
|
|
7
7
|
gemfile: gemfiles/Gemfile.activesupport-3.x
|
|
8
8
|
env:
|
|
9
|
-
- secure:
|
|
9
|
+
- secure: MRWnEbchfgv+FLXLDzkc5rqqiZ/fE/9zQVYRUlTtwHYWKRacl45RDzv0ns7avz/tGGyL/3CMQabOvRiErhN5FWoaRdQV3kBl+gAgSvV910dC+gb/dEpTxU8KGRFLBOFG5oT2WF9eTDjUOxNRiR0jEw/+wD/FltxHEuoc5EixdSI=
|
|
10
10
|
- rvm: 2.0.0
|
|
11
11
|
gemfile: gemfiles/Gemfile.activesupport-4.x
|
|
12
12
|
env:
|
|
13
|
-
- secure:
|
|
13
|
+
- secure: fxPlgZJcWnJZcsQYfLm5EQI4kt9Ohikwi5YugcU+daT43ZacrK0MWAnPhYBXnwNbfsot1udSFnN8DADxbL6/0DxVGVVuQUB4hT59kh8im58Rfim6uCDbgsPLeCzMrWuE2Mj+SBcwVlJ2i0zWqFv6nz4TCi007E/4BOLjjmTsOSo=
|
|
14
14
|
env:
|
|
15
15
|
global:
|
|
16
|
-
- secure:
|
|
17
|
-
- secure:
|
|
18
|
-
- secure:
|
|
16
|
+
- secure: QEKPYkbA9ejUZTYz4p8xWMKqZ+2KpiKa2c6eu79ISQcGsp3gRvnvAzEVByVxrr+K7Igtj/jeRUE8xXMDh6d6wCcguNkTy9BVNevlo12qESpM8oP0iEmnQJL0TtYWEvqivJMg/FSXOaRj4kifB1sfTQjJLdTKVMM52r5qR9K60bs=
|
|
17
|
+
- secure: DznIfIfJN5c0lad7FPf8TVqbMDFFajcDyWPDA55KtlDgpMrjgmLh7z1ZEhQMLvu+HAdvnxx7jEiroeMCT724hXS3ex4MsQnn9fohuM4bsjeqxgxCtdL3urFGBwGx3wMmisY3Jn+5WEQkeqrfMgnUGIyXMp8K1VvjJ6r4GrW6yEk=
|
|
18
|
+
- secure: NeI3iyIAY3ZKAQ+AGo8+uFxdaMmf9zYkVDJMbHsXZLkHxsF1UAMnFic8EEsktfx+zobykQFarwBFeN7LtEvMjpIHeL0caKas0NiUmvnXjCh7CfK9lqY1rjZSYuNSA8uSR1Bl7GOxBjQD8xtRoUdaYAF8MLPVtEs76l0tSVwHQ6Q=
|
data/Gemfile.lock
CHANGED
data/HISTORY.md
CHANGED
|
@@ -7,6 +7,7 @@ v0.4 - 2014/05/09
|
|
|
7
7
|
* Fix parsing annotation and timestamps longer than 1 hour
|
|
8
8
|
* Fix delegating tags from resources to snippets
|
|
9
9
|
* Two options to add videos to a playlist: fail or not if a video is missing
|
|
10
|
+
* Allow to configure Yt credentials through environment variables
|
|
10
11
|
|
|
11
12
|
v0.3.0 - 2014/04/16
|
|
12
13
|
--------------------
|
data/README.md
CHANGED
|
@@ -154,7 +154,7 @@ annotation.has_link_to_playlist? #=> true
|
|
|
154
154
|
|
|
155
155
|
*Annotations do not require authentication.*
|
|
156
156
|
|
|
157
|
-
|
|
157
|
+
Configuring your app
|
|
158
158
|
====================
|
|
159
159
|
|
|
160
160
|
In order to use Yt you must register your app in the [Google Developers Console](https://console.developers.google.com).
|
|
@@ -164,8 +164,8 @@ Apps that do not require user interactions
|
|
|
164
164
|
------------------------------------------
|
|
165
165
|
|
|
166
166
|
If you are building a read-only app that fetches public data from YouTube, then
|
|
167
|
-
generate a **Public API access** key in the Google Console
|
|
168
|
-
snippet of code to the initializer of your app:
|
|
167
|
+
generate a **Public API access** key in the Google Console.
|
|
168
|
+
Next, add the following snippet of code to the initializer of your app:
|
|
169
169
|
|
|
170
170
|
```ruby
|
|
171
171
|
Yt.configure do |config|
|
|
@@ -265,6 +265,32 @@ account.playlists.first.add_video 'MESycYJytkU' #=> (adds a video to an account
|
|
|
265
265
|
Scenario 3. If you don’t have the account’s refresh token, then [..TODO..]
|
|
266
266
|
|
|
267
267
|
|
|
268
|
+
Configuring your app through environment variables
|
|
269
|
+
==================================================
|
|
270
|
+
|
|
271
|
+
As an alternative to the approach above, you can configure Yt using environment
|
|
272
|
+
variables. Setting the following environment variables:
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
export YT_CLIENT_SCENARIO="device_app"
|
|
276
|
+
export YT_CLIENT_ID="1234567890.apps.googleusercontent.com"
|
|
277
|
+
export YT_CLIENT_SECRET="1234567890"
|
|
278
|
+
export YT_API_KEY="123456789012345678901234567890"
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
is equivalent to configuration your app with the initializer:
|
|
282
|
+
|
|
283
|
+
```ruby
|
|
284
|
+
Yt.configure do |config|
|
|
285
|
+
config.scenario = :device_app
|
|
286
|
+
config.client_id = '1234567890.apps.googleusercontent.com'
|
|
287
|
+
config.client_secret = '1234567890'
|
|
288
|
+
config.api_key = '123456789012345678901234567890'
|
|
289
|
+
end
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
so use the approach that you prefer.
|
|
293
|
+
If a variable is set in both places, then `Yt.configure` takes precedence.
|
|
268
294
|
|
|
269
295
|
|
|
270
296
|
How to install
|
|
@@ -276,7 +302,7 @@ To install on your system, run
|
|
|
276
302
|
|
|
277
303
|
To use inside a bundled Ruby project, add this line to the Gemfile:
|
|
278
304
|
|
|
279
|
-
gem 'yt', '~> 0.4.
|
|
305
|
+
gem 'yt', '~> 0.4.8'
|
|
280
306
|
|
|
281
307
|
Since the gem follows [Semantic Versioning](http://semver.org),
|
|
282
308
|
indicating the full version in your Gemfile (~> *major*.*minor*.*patch*)
|
|
@@ -301,7 +327,70 @@ Google API!
|
|
|
301
327
|
How to test
|
|
302
328
|
===========
|
|
303
329
|
|
|
304
|
-
|
|
330
|
+
Yt comes with two different sets of tests:
|
|
331
|
+
|
|
332
|
+
1. tests in `spec/models` and `spec/collections` **do not hit** the YouTube API
|
|
333
|
+
1. tests in `spec/associations` **hit** the YouTube API and require authentication
|
|
334
|
+
|
|
335
|
+
To run all the tests, type:
|
|
336
|
+
|
|
337
|
+
```bash
|
|
338
|
+
rspec
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
The reason why some tests actually hit the YouTube API is because they are
|
|
342
|
+
meant to really integrate Yt with YouTube. YouTube API is not exactly
|
|
343
|
+
*the most reliable* API out there, so we need to make sure that the responses
|
|
344
|
+
match the documentation.
|
|
345
|
+
|
|
346
|
+
You don’t have to run all the tests every time you change code.
|
|
347
|
+
Travis CI is already set up to do this for when whenever you push a branch
|
|
348
|
+
or create a pull request for this project.
|
|
349
|
+
|
|
350
|
+
Testing models and collections
|
|
351
|
+
------------------------------
|
|
352
|
+
|
|
353
|
+
To only run tests against models and collections (which do not hit the API), type:
|
|
354
|
+
|
|
355
|
+
```bash
|
|
356
|
+
rspec spec/models spec/collections
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
Testing associations
|
|
360
|
+
--------------------
|
|
361
|
+
|
|
362
|
+
To only run tests against associations (which hit the API), type:
|
|
363
|
+
|
|
364
|
+
```bash
|
|
365
|
+
rspec spec/associations
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
This test will fail at first. As documented by the error message, you will need
|
|
369
|
+
an app registered in the [Google Developers Console](https://console.developers.google.com)
|
|
370
|
+
to proceed.
|
|
371
|
+
|
|
372
|
+
Browse to the Console, then create a new app that you will only use for testing.
|
|
373
|
+
|
|
374
|
+
Under the "APIs" tab of this app, enable 'Google+ API', 'Youtube Analytics
|
|
375
|
+
API' and 'YouTube Data API v3'.
|
|
376
|
+
|
|
377
|
+
Under the "Credentials" tab of this app, create a new 'Key for server
|
|
378
|
+
application' and a new 'Client ID' and 'Client Secret' for **native** application.
|
|
379
|
+
|
|
380
|
+
It’s important that you pick 'native application' instead of 'web application',
|
|
381
|
+
otherwise running your tests will require you to open a browser and launch a
|
|
382
|
+
local webserver… and you don’t need to do any of that.
|
|
383
|
+
|
|
384
|
+
Finally, copy the given values and set the following environment variables:
|
|
385
|
+
|
|
386
|
+
```bash
|
|
387
|
+
export YT_TEST_DEVICE_CLIENT_ID="1234567890.apps.googleusercontent.com"
|
|
388
|
+
export YT_TEST_DEVICE_CLIENT_SECRET="1234567890"
|
|
389
|
+
export YT_TEST_SERVER_API_KEY="123456789012345678901234567890"
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
[ TODO: Complete this section. Explain how get and store the refresh token,
|
|
393
|
+
making sure all the required scopes are authorized. ]
|
|
305
394
|
|
|
306
395
|
|
|
307
396
|
How to contribute
|
data/lib/yt/actions/request.rb
CHANGED
|
@@ -21,7 +21,7 @@ module Yt
|
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def run
|
|
24
|
-
add_authorization_to_request!
|
|
24
|
+
add_authorization_to_request! if requires_authorization?
|
|
25
25
|
fetch_response.tap do |response|
|
|
26
26
|
response.body = parse_format response.body if response.body
|
|
27
27
|
# puts "You can try again running #{to_curl}"
|
|
@@ -43,13 +43,19 @@ module Yt
|
|
|
43
43
|
def add_authorization_to_request!
|
|
44
44
|
if @auth.respond_to? :access_token_for
|
|
45
45
|
@headers['Authorization'] = "Bearer #{@auth.access_token_for @scope}"
|
|
46
|
-
|
|
46
|
+
elsif Yt.configuration.api_key
|
|
47
47
|
params = URI.decode_www_form @uri.query || ''
|
|
48
48
|
params << [:key, Yt.configuration.api_key]
|
|
49
49
|
@uri.query = URI.encode_www_form params
|
|
50
|
+
else
|
|
51
|
+
raise RequestError, missing_credentials
|
|
50
52
|
end
|
|
51
53
|
end
|
|
52
54
|
|
|
55
|
+
def requires_authorization?
|
|
56
|
+
@uri.host == Request.default_params[:host]
|
|
57
|
+
end
|
|
58
|
+
|
|
53
59
|
def fetch_response
|
|
54
60
|
Net::HTTP.start(@uri.host, @uri.port, use_ssl: true) do |http|
|
|
55
61
|
klass = "Net::HTTP::#{@method.capitalize}".constantize
|
|
@@ -75,6 +81,30 @@ module Yt
|
|
|
75
81
|
end
|
|
76
82
|
end
|
|
77
83
|
|
|
84
|
+
def missing_credentials
|
|
85
|
+
<<-MSG
|
|
86
|
+
In order to perform this request, you need to register your app with the
|
|
87
|
+
Google Developers Console (https://console.developers.google.com).
|
|
88
|
+
|
|
89
|
+
Make sure your app has access to the Google+ and YouTube APIs.
|
|
90
|
+
Generate a client ID, client secret and server API key, then pass their
|
|
91
|
+
values to Yt. One way of doing this is through an initializer:
|
|
92
|
+
|
|
93
|
+
Yt.configure do |config|
|
|
94
|
+
config.client_id = '1234567890.apps.googleusercontent.com'
|
|
95
|
+
config.client_secret = '1234567890'
|
|
96
|
+
config.api_key = '123456789012345678901234567890'
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
An alternative (but equivalent) way is throught environment variables:
|
|
100
|
+
|
|
101
|
+
export YT_CLIENT_ID="1234567890.apps.googleusercontent.com"
|
|
102
|
+
export YT_CLIENT_SECRET="1234567890"
|
|
103
|
+
export YT_API_KEY="123456789012345678901234567890"
|
|
104
|
+
|
|
105
|
+
MSG
|
|
106
|
+
end
|
|
107
|
+
|
|
78
108
|
# def to_curl
|
|
79
109
|
# %Q{curl -X #{@method.upcase} "#{@uri}"}
|
|
80
110
|
# end
|
|
@@ -23,7 +23,18 @@ module Yt
|
|
|
23
23
|
attr_accessor :scenario, :api_key, :client_id, :client_secret, :account
|
|
24
24
|
|
|
25
25
|
def initialize
|
|
26
|
-
@scenario =
|
|
26
|
+
@scenario = set_scenario ENV['YT_CLIENT_SCENARIO']
|
|
27
|
+
@client_id = ENV['YT_CLIENT_ID']
|
|
28
|
+
@client_secret = ENV['YT_CLIENT_SECRET']
|
|
29
|
+
@api_key = ENV['YT_API_KEY']
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def set_scenario(value)
|
|
35
|
+
valid_scenarios = [:web_app, :device_app, :server_app]
|
|
36
|
+
scenario = valid_scenarios.find{|scenario| scenario.to_s == value}
|
|
37
|
+
scenario || :web_app
|
|
27
38
|
end
|
|
28
39
|
end
|
|
29
40
|
end
|
data/lib/yt/version.rb
CHANGED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Yt::Configuration do
|
|
4
|
+
subject(:config) { Yt::Configuration.new }
|
|
5
|
+
|
|
6
|
+
describe '#scenario' do
|
|
7
|
+
context 'by default' do
|
|
8
|
+
it {expect(config.scenario).to be :web_app }
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
context 'given an invalid environment variable YT_CLIENT_SCENARIO' do
|
|
12
|
+
before { ENV['YT_CLIENT_SCENARIO'] = 'not-a-scenario'}
|
|
13
|
+
it {expect(config.scenario).to be :web_app }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
context 'given a valid environment variable YT_CLIENT_SCENARIO' do
|
|
17
|
+
before { ENV['YT_CLIENT_SCENARIO'] = 'device_app'}
|
|
18
|
+
it {expect(config.scenario).to be :device_app }
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe '#client_id' do
|
|
23
|
+
context 'by default' do
|
|
24
|
+
it {expect(config.client_id).to be_nil }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
context 'given an environment variable YT_CLIENT_ID' do
|
|
28
|
+
let(:client_id) { '1234567890.apps.googleusercontent.com' }
|
|
29
|
+
before { ENV['YT_CLIENT_ID'] = client_id}
|
|
30
|
+
it {expect(config.client_id).to eq client_id }
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
describe '#client_secret' do
|
|
35
|
+
context 'by default' do
|
|
36
|
+
it {expect(config.client_secret).to be_nil }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
context 'given an environment variable YT_CLIENT_SECRET' do
|
|
40
|
+
let(:client_secret) { '1234567890' }
|
|
41
|
+
before { ENV['YT_CLIENT_SECRET'] = client_secret}
|
|
42
|
+
it {expect(config.client_secret).to eq client_secret }
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
describe '#api_key' do
|
|
47
|
+
context 'by default' do
|
|
48
|
+
it {expect(config.api_key).to be_nil }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
context 'given an environment variable YT_API_KEY' do
|
|
52
|
+
let(:api_key) { '123456789012345678901234567890' }
|
|
53
|
+
before { ENV['YT_API_KEY'] = api_key}
|
|
54
|
+
it {expect(config.api_key).to eq api_key }
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
data/spec/support/device_app.rb
CHANGED
|
@@ -6,9 +6,8 @@ RSpec.configure do |config|
|
|
|
6
6
|
unless Yt.configuration.scenario == :device_app
|
|
7
7
|
Yt.configure do |config|
|
|
8
8
|
config.scenario = :device_app
|
|
9
|
-
config.client_id = ENV['
|
|
10
|
-
config.client_secret = ENV['
|
|
11
|
-
# Note: makes sure ALL the scopes are authorized in YT_TEST_DEVICE_REFRESH_TOKEN
|
|
9
|
+
config.client_id = ENV['YT_TEST_DEVICE_CLIENT_ID']
|
|
10
|
+
config.client_secret = ENV['YT_TEST_DEVICE_CLIENT_SECRET']
|
|
12
11
|
config.account = Yt::Account.new refresh_token: ENV['YT_TEST_DEVICE_REFRESH_TOKEN']
|
|
13
12
|
end
|
|
14
13
|
end
|
data/spec/support/server_app.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: yt
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Claudio Baccigalupo
|
|
@@ -197,6 +197,7 @@ files:
|
|
|
197
197
|
- spec/collections/videos_spec.rb
|
|
198
198
|
- spec/models/annotation_spec.rb
|
|
199
199
|
- spec/models/channel_spec.rb
|
|
200
|
+
- spec/models/configuration_spec.rb
|
|
200
201
|
- spec/models/description_spec.rb
|
|
201
202
|
- spec/models/details_set_spec.rb
|
|
202
203
|
- spec/models/playlist_item_spec.rb
|
|
@@ -268,6 +269,7 @@ test_files:
|
|
|
268
269
|
- spec/collections/videos_spec.rb
|
|
269
270
|
- spec/models/annotation_spec.rb
|
|
270
271
|
- spec/models/channel_spec.rb
|
|
272
|
+
- spec/models/configuration_spec.rb
|
|
271
273
|
- spec/models/description_spec.rb
|
|
272
274
|
- spec/models/details_set_spec.rb
|
|
273
275
|
- spec/models/playlist_item_spec.rb
|