google-api-client 0.7.1 → 0.8.0
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 +13 -5
- data/CHANGELOG.md +14 -0
- data/Gemfile +0 -36
- data/README.md +12 -1
- data/Rakefile +1 -8
- data/google-api-client.gemspec +40 -0
- data/lib/google/api_client.rb +98 -30
- data/lib/google/api_client/auth/compute_service_account.rb +1 -1
- data/lib/google/api_client/auth/file_storage.rb +19 -44
- data/lib/google/api_client/auth/installed_app.rb +11 -7
- data/lib/google/api_client/auth/storage.rb +101 -0
- data/lib/google/api_client/auth/storages/file_store.rb +58 -0
- data/lib/google/api_client/auth/storages/redis_store.rb +54 -0
- data/lib/google/api_client/batch.rb +13 -11
- data/lib/google/api_client/charset.rb +33 -0
- data/lib/google/api_client/client_secrets.rb +9 -6
- data/lib/google/api_client/discovery/api.rb +3 -3
- data/lib/google/api_client/discovery/resource.rb +3 -3
- data/lib/google/api_client/discovery/schema.rb +3 -5
- data/lib/google/api_client/errors.rb +5 -0
- data/lib/google/api_client/railtie.rb +2 -1
- data/lib/google/api_client/request.rb +1 -2
- data/lib/google/api_client/result.rb +4 -2
- data/lib/google/api_client/service.rb +2 -2
- data/lib/google/api_client/service/batch.rb +7 -0
- data/lib/google/api_client/service/stub_generator.rb +4 -2
- data/lib/google/api_client/service_account.rb +3 -0
- data/lib/google/api_client/version.rb +8 -13
- data/spec/google/api_client/auth/storage_spec.rb +122 -0
- data/spec/google/api_client/auth/storages/file_store_spec.rb +40 -0
- data/spec/google/api_client/auth/storages/redis_store_spec.rb +70 -0
- data/spec/google/api_client/batch_spec.rb +29 -30
- data/spec/google/api_client/client_secrets_spec.rb +53 -0
- data/spec/google/api_client/discovery_spec.rb +101 -91
- data/spec/google/api_client/gzip_spec.rb +21 -9
- data/spec/google/api_client/media_spec.rb +31 -32
- data/spec/google/api_client/request_spec.rb +3 -4
- data/spec/google/api_client/result_spec.rb +51 -47
- data/spec/google/api_client/service_account_spec.rb +40 -35
- data/spec/google/api_client/service_spec.rb +144 -112
- data/spec/google/api_client/simple_file_store_spec.rb +30 -34
- data/spec/google/api_client_spec.rb +139 -40
- data/spec/spec_helper.rb +9 -1
- metadata +111 -88
- data/CONTRIBUTING.md +0 -32
- data/lib/cacerts.pem +0 -2183
- data/lib/google/inflection.rb +0 -28
- data/spec/fixtures/files/privatekey.p12 +0 -0
- data/spec/fixtures/files/sample.txt +0 -33
- data/spec/fixtures/files/secret.pem +0 -19
- data/tasks/gem.rake +0 -97
- data/tasks/git.rake +0 -45
- data/tasks/metrics.rake +0 -22
- data/tasks/spec.rake +0 -57
- data/tasks/wiki.rake +0 -82
- data/tasks/yard.rake +0 -29
@@ -26,7 +26,7 @@ module Google
|
|
26
26
|
# client = Google::APIClient.new
|
27
27
|
# flow = Google::APIClient::InstalledAppFlow.new(
|
28
28
|
# :client_id => '691380668085.apps.googleusercontent.com',
|
29
|
-
# :client_secret => '
|
29
|
+
# :client_secret => '...',
|
30
30
|
# :scope => 'https://www.googleapis.com/auth/drive'
|
31
31
|
# )
|
32
32
|
# client.authorization = flow.authorize
|
@@ -92,9 +92,10 @@ module Google
|
|
92
92
|
:Logger => WEBrick::Log.new(STDOUT, 0),
|
93
93
|
:AccessLog => []
|
94
94
|
)
|
95
|
-
|
96
|
-
|
97
|
-
|
95
|
+
begin
|
96
|
+
trap("INT") { server.shutdown }
|
97
|
+
|
98
|
+
server.mount_proc '/' do |req, res|
|
98
99
|
auth.code = req.query['code']
|
99
100
|
if auth.code
|
100
101
|
auth.fetch_access_token!
|
@@ -102,10 +103,13 @@ module Google
|
|
102
103
|
res.status = WEBrick::HTTPStatus::RC_ACCEPTED
|
103
104
|
res.body = RESPONSE_BODY
|
104
105
|
server.stop
|
105
|
-
|
106
|
+
end
|
106
107
|
|
107
|
-
|
108
|
-
|
108
|
+
Launchy.open(auth.authorization_uri.to_s)
|
109
|
+
server.start
|
110
|
+
ensure
|
111
|
+
server.shutdown
|
112
|
+
end
|
109
113
|
if @authorization.access_token
|
110
114
|
if storage.respond_to?(:write_credentials)
|
111
115
|
storage.write_credentials(@authorization)
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# Copyright 2013 Google Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'signet/oauth_2/client'
|
16
|
+
|
17
|
+
module Google
|
18
|
+
class APIClient
|
19
|
+
##
|
20
|
+
# Represents cached OAuth 2 tokens stored on local disk in a
|
21
|
+
# JSON serialized file. Meant to resemble the serialized format
|
22
|
+
# http://google-api-python-client.googlecode.com/hg/docs/epy/oauth2client.file.Storage-class.html
|
23
|
+
#
|
24
|
+
class Storage
|
25
|
+
|
26
|
+
AUTHORIZATION_URI = 'https://accounts.google.com/o/oauth2/auth'
|
27
|
+
TOKEN_CREDENTIAL_URI = 'https://accounts.google.com/o/oauth2/token'
|
28
|
+
|
29
|
+
# @return [Object] Storage object.
|
30
|
+
attr_accessor :store
|
31
|
+
|
32
|
+
# @return [Signet::OAuth2::Client]
|
33
|
+
attr_reader :authorization
|
34
|
+
|
35
|
+
##
|
36
|
+
# Initializes the Storage object.
|
37
|
+
#
|
38
|
+
# @params [Object] Storage object
|
39
|
+
def initialize(store)
|
40
|
+
@store= store
|
41
|
+
end
|
42
|
+
|
43
|
+
##
|
44
|
+
# Write the credentials to the specified store.
|
45
|
+
#
|
46
|
+
# @params [Signet::OAuth2::Client] authorization
|
47
|
+
# Optional authorization instance. If not provided, the authorization
|
48
|
+
# already associated with this instance will be written.
|
49
|
+
def write_credentials(authorization=nil)
|
50
|
+
@authorization = authorization if authorization
|
51
|
+
if @authorization.respond_to?(:refresh_token) && @authorization.refresh_token
|
52
|
+
store.write_credentials(credentials_hash)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
##
|
57
|
+
# Loads credentials and authorizes an client.
|
58
|
+
# @return [Object] Signet::OAuth2::Client or NIL
|
59
|
+
def authorize
|
60
|
+
@authorization = nil
|
61
|
+
cached_credentials = load_credentials
|
62
|
+
if cached_credentials && cached_credentials.size > 0
|
63
|
+
@authorization = Signet::OAuth2::Client.new(cached_credentials)
|
64
|
+
@authorization.issued_at = Time.at(cached_credentials['issued_at'].to_i)
|
65
|
+
self.refresh_authorization if @authorization.expired?
|
66
|
+
end
|
67
|
+
return @authorization
|
68
|
+
end
|
69
|
+
|
70
|
+
##
|
71
|
+
# refresh credentials and save them to store
|
72
|
+
def refresh_authorization
|
73
|
+
authorization.refresh!
|
74
|
+
self.write_credentials
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
##
|
80
|
+
# Attempt to read in credentials from the specified store.
|
81
|
+
def load_credentials
|
82
|
+
store.load_credentials
|
83
|
+
end
|
84
|
+
|
85
|
+
##
|
86
|
+
# @return [Hash] with credentials
|
87
|
+
def credentials_hash
|
88
|
+
{
|
89
|
+
:access_token => authorization.access_token,
|
90
|
+
:authorization_uri => AUTHORIZATION_URI,
|
91
|
+
:client_id => authorization.client_id,
|
92
|
+
:client_secret => authorization.client_secret,
|
93
|
+
:expires_in => authorization.expires_in,
|
94
|
+
:refresh_token => authorization.refresh_token,
|
95
|
+
:token_credential_uri => TOKEN_CREDENTIAL_URI,
|
96
|
+
:issued_at => authorization.issued_at.to_i
|
97
|
+
}
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# Copyright 2013 Google Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'json'
|
16
|
+
|
17
|
+
module Google
|
18
|
+
class APIClient
|
19
|
+
##
|
20
|
+
# Represents cached OAuth 2 tokens stored on local disk in a
|
21
|
+
# JSON serialized file. Meant to resemble the serialized format
|
22
|
+
# http://google-api-python-client.googlecode.com/hg/docs/epy/oauth2client.file.Storage-class.html
|
23
|
+
#
|
24
|
+
class FileStore
|
25
|
+
|
26
|
+
attr_accessor :path
|
27
|
+
|
28
|
+
##
|
29
|
+
# Initializes the FileStorage object.
|
30
|
+
#
|
31
|
+
# @param [String] path
|
32
|
+
# Path to the credentials file.
|
33
|
+
def initialize(path)
|
34
|
+
@path= path
|
35
|
+
end
|
36
|
+
|
37
|
+
##
|
38
|
+
# Attempt to read in credentials from the specified file.
|
39
|
+
def load_credentials
|
40
|
+
open(path, 'r') { |f| JSON.parse(f.read) }
|
41
|
+
rescue
|
42
|
+
nil
|
43
|
+
end
|
44
|
+
|
45
|
+
##
|
46
|
+
# Write the credentials to the specified file.
|
47
|
+
#
|
48
|
+
# @param [Signet::OAuth2::Client] authorization
|
49
|
+
# Optional authorization instance. If not provided, the authorization
|
50
|
+
# already associated with this instance will be written.
|
51
|
+
def write_credentials(credentials_hash)
|
52
|
+
open(self.path, 'w+') do |f|
|
53
|
+
f.write(credentials_hash.to_json)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# Copyright 2013 Google Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'json'
|
16
|
+
|
17
|
+
module Google
|
18
|
+
class APIClient
|
19
|
+
class RedisStore
|
20
|
+
|
21
|
+
DEFAULT_REDIS_CREDENTIALS_KEY = "google_api_credentials"
|
22
|
+
|
23
|
+
attr_accessor :redis
|
24
|
+
|
25
|
+
##
|
26
|
+
# Initializes the RedisStore object.
|
27
|
+
#
|
28
|
+
# @params [Object] Redis instance
|
29
|
+
def initialize(redis, key = nil)
|
30
|
+
@redis= redis
|
31
|
+
@redis_credentials_key = key
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Attempt to read in credentials from redis.
|
36
|
+
def load_credentials
|
37
|
+
credentials = redis.get redis_credentials_key
|
38
|
+
JSON.parse(credentials) if credentials
|
39
|
+
end
|
40
|
+
|
41
|
+
def redis_credentials_key
|
42
|
+
@redis_credentials_key || DEFAULT_REDIS_CREDENTIALS_KEY
|
43
|
+
end
|
44
|
+
|
45
|
+
##
|
46
|
+
# Write the credentials to redis.
|
47
|
+
#
|
48
|
+
# @params [Hash] credentials
|
49
|
+
def write_credentials(credentials_hash)
|
50
|
+
redis.set(redis_credentials_key, credentials_hash.to_json)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -14,7 +14,7 @@
|
|
14
14
|
|
15
15
|
require 'addressable/uri'
|
16
16
|
require 'google/api_client/reference'
|
17
|
-
require '
|
17
|
+
require 'securerandom'
|
18
18
|
|
19
19
|
module Google
|
20
20
|
class APIClient
|
@@ -90,8 +90,7 @@ module Google
|
|
90
90
|
@global_callback = block if block_given?
|
91
91
|
@last_auto_id = 0
|
92
92
|
|
93
|
-
|
94
|
-
@base_id = UUIDTools::UUID.random_create.to_s
|
93
|
+
@base_id = SecureRandom.uuid
|
95
94
|
|
96
95
|
options[:uri] ||= 'https://www.googleapis.com/batch'
|
97
96
|
options[:http_method] ||= 'POST'
|
@@ -140,14 +139,17 @@ module Google
|
|
140
139
|
# the HTTP response.
|
141
140
|
def process_http_response(response)
|
142
141
|
content_type = find_header('Content-Type', response.headers)
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
142
|
+
m = /.*boundary=(.+)/.match(content_type)
|
143
|
+
if m
|
144
|
+
boundary = m[1]
|
145
|
+
parts = response.body.split(/--#{Regexp.escape(boundary)}/)
|
146
|
+
parts = parts[1...-1]
|
147
|
+
parts.each do |part|
|
148
|
+
call_response = deserialize_call_response(part)
|
149
|
+
_, call, callback = @calls.assoc(call_response.call_id)
|
150
|
+
result = Google::APIClient::Result.new(call, call_response)
|
151
|
+
callback.call(result) if callback
|
152
|
+
end
|
151
153
|
end
|
152
154
|
Google::APIClient::Result.new(self, response)
|
153
155
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'zlib'
|
3
|
+
|
4
|
+
module Google
|
5
|
+
class APIClient
|
6
|
+
class Charset < Faraday::Response::Middleware
|
7
|
+
include Google::APIClient::Logging
|
8
|
+
|
9
|
+
def charset_for_content_type(type)
|
10
|
+
if type
|
11
|
+
m = type.match(/(?:charset|encoding)="?([a-z0-9-]+)"?/i)
|
12
|
+
if m
|
13
|
+
return Encoding.find(m[1])
|
14
|
+
end
|
15
|
+
end
|
16
|
+
nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def adjust_encoding(env)
|
20
|
+
charset = charset_for_content_type(env[:response_headers]['content-type'])
|
21
|
+
if charset && env[:body].encoding != charset
|
22
|
+
env[:body].force_encoding(charset)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def on_complete(env)
|
27
|
+
adjust_encoding(env)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
Faraday::Response.register_middleware :charset => Google::APIClient::Charset
|
@@ -13,7 +13,6 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
15
|
|
16
|
-
require 'multi_json'
|
17
16
|
require 'compat/multi_json'
|
18
17
|
|
19
18
|
|
@@ -63,7 +62,7 @@ module Google
|
|
63
62
|
end
|
64
63
|
while filename == nil
|
65
64
|
search_path ||= File.expand_path('.')
|
66
|
-
if File.
|
65
|
+
if File.exists?(File.join(search_path, 'client_secrets.json'))
|
67
66
|
filename = File.join(search_path, 'client_secrets.json')
|
68
67
|
elsif search_path == '/' || search_path =~ /[a-zA-Z]:[\/\\]/
|
69
68
|
raise ArgumentError,
|
@@ -89,12 +88,12 @@ module Google
|
|
89
88
|
@client_id = fdata[:client_id] || fdata["client_id"]
|
90
89
|
@client_secret = fdata[:client_secret] || fdata["client_secret"]
|
91
90
|
@redirect_uris = fdata[:redirect_uris] || fdata["redirect_uris"]
|
92
|
-
@redirect_uris ||= [fdata[:redirect_uri]]
|
91
|
+
@redirect_uris ||= [fdata[:redirect_uri] || fdata["redirect_uri"]].compact
|
93
92
|
@javascript_origins = (
|
94
93
|
fdata[:javascript_origins] ||
|
95
94
|
fdata["javascript_origins"]
|
96
95
|
)
|
97
|
-
@javascript_origins ||= [fdata[:javascript_origin]]
|
96
|
+
@javascript_origins ||= [fdata[:javascript_origin] || fdata["javascript_origin"]].compact
|
98
97
|
@authorization_uri = fdata[:auth_uri] || fdata["auth_uri"]
|
99
98
|
@authorization_uri ||= fdata[:authorization_uri]
|
100
99
|
@token_credential_uri = fdata[:token_uri] || fdata["token_uri"]
|
@@ -121,7 +120,11 @@ module Google
|
|
121
120
|
# @return [String]
|
122
121
|
# JSON
|
123
122
|
def to_json
|
124
|
-
return MultiJson.dump(
|
123
|
+
return MultiJson.dump(to_hash)
|
124
|
+
end
|
125
|
+
|
126
|
+
def to_hash
|
127
|
+
{
|
125
128
|
self.flow => ({
|
126
129
|
'client_id' => self.client_id,
|
127
130
|
'client_secret' => self.client_secret,
|
@@ -142,7 +145,7 @@ module Google
|
|
142
145
|
end
|
143
146
|
accu
|
144
147
|
end
|
145
|
-
}
|
148
|
+
}
|
146
149
|
end
|
147
150
|
|
148
151
|
def to_authorization
|
@@ -15,7 +15,7 @@
|
|
15
15
|
|
16
16
|
require 'addressable/uri'
|
17
17
|
require 'multi_json'
|
18
|
-
require '
|
18
|
+
require 'active_support/inflector'
|
19
19
|
require 'google/api_client/discovery/resource'
|
20
20
|
require 'google/api_client/discovery/method'
|
21
21
|
require 'google/api_client/discovery/media'
|
@@ -41,13 +41,13 @@ module Google
|
|
41
41
|
@discovery_document = discovery_document
|
42
42
|
metaclass = (class << self; self; end)
|
43
43
|
self.discovered_resources.each do |resource|
|
44
|
-
method_name =
|
44
|
+
method_name = ActiveSupport::Inflector.underscore(resource.name).to_sym
|
45
45
|
if !self.respond_to?(method_name)
|
46
46
|
metaclass.send(:define_method, method_name) { resource }
|
47
47
|
end
|
48
48
|
end
|
49
49
|
self.discovered_methods.each do |method|
|
50
|
-
method_name =
|
50
|
+
method_name = ActiveSupport::Inflector.underscore(method.name).to_sym
|
51
51
|
if !self.respond_to?(method_name)
|
52
52
|
metaclass.send(:define_method, method_name) { method }
|
53
53
|
end
|
@@ -15,7 +15,7 @@
|
|
15
15
|
|
16
16
|
require 'addressable/uri'
|
17
17
|
|
18
|
-
require '
|
18
|
+
require 'active_support/inflector'
|
19
19
|
require 'google/api_client/discovery/method'
|
20
20
|
|
21
21
|
|
@@ -45,13 +45,13 @@ module Google
|
|
45
45
|
@discovery_document = discovery_document
|
46
46
|
metaclass = (class <<self; self; end)
|
47
47
|
self.discovered_resources.each do |resource|
|
48
|
-
method_name =
|
48
|
+
method_name = ActiveSupport::Inflector.underscore(resource.name).to_sym
|
49
49
|
if !self.respond_to?(method_name)
|
50
50
|
metaclass.send(:define_method, method_name) { resource }
|
51
51
|
end
|
52
52
|
end
|
53
53
|
self.discovered_methods.each do |method|
|
54
|
-
method_name =
|
54
|
+
method_name = ActiveSupport::Inflector.underscore(method.name).to_sym
|
55
55
|
if !self.respond_to?(method_name)
|
56
56
|
metaclass.send(:define_method, method_name) { method }
|
57
57
|
end
|
@@ -21,7 +21,7 @@ require 'autoparse'
|
|
21
21
|
require 'addressable/uri'
|
22
22
|
require 'addressable/template'
|
23
23
|
|
24
|
-
require '
|
24
|
+
require 'active_support/inflector'
|
25
25
|
require 'google/api_client/errors'
|
26
26
|
|
27
27
|
|
@@ -78,10 +78,8 @@ module Google
|
|
78
78
|
# puts schema_data.inspect
|
79
79
|
|
80
80
|
if schema_name
|
81
|
-
api_name_string =
|
82
|
-
|
83
|
-
api_version_string =
|
84
|
-
Google::INFLECTOR.camelize(api.version).gsub('.', '_')
|
81
|
+
api_name_string = ActiveSupport::Inflector.camelize(api.name)
|
82
|
+
api_version_string = ActiveSupport::Inflector.camelize(api.version).gsub('.', '_')
|
85
83
|
# This is for compatibility with Ruby 1.8.7.
|
86
84
|
# TODO(bobaman) Remove this when we eventually stop supporting 1.8.7.
|
87
85
|
args = []
|