google-api-client 0.9.pre4 → 0.9.pre5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/CHANGELOG.md +9 -0
  4. data/README.md +11 -1
  5. data/api_names.yaml +1 -0
  6. data/api_names_out.yaml +163 -98
  7. data/generated/google/apis/admin_datatransfer_v1.rb +1 -1
  8. data/generated/google/apis/analytics_v3.rb +1 -1
  9. data/generated/google/apis/analytics_v3/classes.rb +7 -0
  10. data/generated/google/apis/analytics_v3/representations.rb +1 -0
  11. data/generated/google/apis/analytics_v3/service.rb +42 -0
  12. data/generated/google/apis/appstate_v1.rb +1 -1
  13. data/generated/google/apis/bigquery_v2.rb +1 -1
  14. data/generated/google/apis/bigquery_v2/classes.rb +23 -66
  15. data/generated/google/apis/bigquery_v2/representations.rb +1 -17
  16. data/generated/google/apis/bigquery_v2/service.rb +6 -6
  17. data/generated/google/apis/cloudbilling_v1.rb +1 -1
  18. data/generated/google/apis/cloudmonitoring_v2beta2.rb +1 -1
  19. data/generated/google/apis/deploymentmanager_v2.rb +1 -1
  20. data/generated/google/apis/deploymentmanager_v2/classes.rb +5 -4
  21. data/generated/google/apis/doubleclicksearch_v2.rb +1 -1
  22. data/generated/google/apis/drive_v2.rb +1 -1
  23. data/generated/google/apis/drive_v2/service.rb +4 -3
  24. data/generated/google/apis/drive_v3.rb +1 -1
  25. data/generated/google/apis/games_configuration_v1configuration.rb +1 -1
  26. data/generated/google/apis/games_management_v1management.rb +1 -1
  27. data/generated/google/apis/games_v1.rb +1 -1
  28. data/generated/google/apis/genomics_v1.rb +1 -1
  29. data/generated/google/apis/gmail_v1.rb +1 -1
  30. data/generated/google/apis/gmail_v1/classes.rb +2 -2
  31. data/generated/google/apis/plus_domains_v1.rb +1 -1
  32. data/generated/google/apis/plus_v1.rb +1 -1
  33. data/generated/google/apis/plus_v1/classes.rb +0 -497
  34. data/generated/google/apis/plus_v1/representations.rb +0 -121
  35. data/generated/google/apis/plus_v1/service.rb +0 -101
  36. data/generated/google/apis/replicapoolupdater_v1beta1.rb +1 -1
  37. data/generated/google/apis/replicapoolupdater_v1beta1/classes.rb +4 -4
  38. data/generated/google/apis/webmasters_v3.rb +3 -3
  39. data/generated/google/apis/webmasters_v3/service.rb +2 -2
  40. data/generated/google/apis/youtube_v3.rb +1 -1
  41. data/generated/google/apis/youtube_v3/classes.rb +942 -64
  42. data/generated/google/apis/youtube_v3/representations.rb +307 -0
  43. data/generated/google/apis/youtube_v3/service.rb +443 -1
  44. data/google-api-client.gemspec +1 -0
  45. data/lib/google/apis/core/api_command.rb +2 -2
  46. data/lib/google/apis/core/base_service.rb +2 -0
  47. data/lib/google/apis/core/http_client_adapter.rb +82 -0
  48. data/lib/google/apis/core/http_command.rb +16 -1
  49. data/lib/google/apis/core/json_representation.rb +3 -2
  50. data/lib/google/apis/core/upload.rb +7 -1
  51. data/lib/google/apis/options.rb +4 -2
  52. data/lib/google/apis/version.rb +1 -1
  53. data/samples/Gemfile +7 -0
  54. data/samples/README.md +51 -0
  55. data/samples/google-api-samples +32 -0
  56. data/samples/lib/base_cli.rb +94 -0
  57. data/samples/lib/samples/analytics.rb +62 -0
  58. data/samples/lib/samples/calendar.rb +83 -0
  59. data/samples/lib/samples/drive.rb +82 -0
  60. data/samples/lib/samples/gmail.rb +50 -0
  61. data/samples/lib/samples/pubsub.rb +114 -0
  62. data/samples/lib/samples/translate.rb +44 -0
  63. data/samples/lib/samples/you_tube.rb +44 -0
  64. data/spec/google/apis/core/api_command_spec.rb +39 -0
  65. data/spec/google/apis/core/http_command_spec.rb +9 -0
  66. data/spec/google/apis/core/upload_spec.rb +14 -0
  67. data/spec/google/apis/options_spec.rb +0 -8
  68. data/spec/integration_tests/adsense_spec.rb +1 -0
  69. data/spec/integration_tests/pubsub_spec.rb +3 -3
  70. data/spec/integration_tests/url_shortener_spec.rb +14 -0
  71. data/spec/spec_helper.rb +33 -6
  72. data/{samples/translate/translate.rb → spec/spec_helper/load_path_spec.rb} +15 -6
  73. metadata +30 -6
  74. data/samples/calendar/calendar.rb +0 -43
  75. data/samples/drive/drive.rb +0 -47
  76. data/samples/pubsub/pubsub.rb +0 -51
@@ -26,5 +26,6 @@ Gem::Specification.new do |spec|
26
26
  spec.add_runtime_dependency 'hurley', '~> 0.1'
27
27
  spec.add_runtime_dependency 'googleauth', '~> 0.5'
28
28
  spec.add_runtime_dependency 'thor', '~> 0.19'
29
+ spec.add_runtime_dependency 'httpclient', '~> 2.7'
29
30
  spec.add_runtime_dependency 'memoist', '~> 0.11'
30
31
  end
@@ -94,11 +94,11 @@ module Google
94
94
  when 400, 402...500
95
95
  error = parse_error(body)
96
96
  if error
97
- message = error['reason'] if error.has_key?('reason')
97
+ message = sprintf('%s: %s', error['reason'], error['message'])
98
98
  raise Google::Apis::RateLimitError.new(message,
99
99
  status_code: status,
100
100
  header: header,
101
- body: body) if RATE_LIMIT_ERRORS.include?(message)
101
+ body: body) if RATE_LIMIT_ERRORS.include?(error['reason'])
102
102
  end
103
103
  super(status, header, body, message)
104
104
  else
@@ -19,6 +19,7 @@ require 'google/apis/core/api_command'
19
19
  require 'google/apis/core/batch'
20
20
  require 'google/apis/core/upload'
21
21
  require 'google/apis/core/download'
22
+ require 'google/apis/core/http_client_adapter'
22
23
  require 'google/apis/options'
23
24
  require 'googleauth'
24
25
  require 'hurley'
@@ -291,6 +292,7 @@ module Google
291
292
  # @return [Hurley::Client]
292
293
  def new_client
293
294
  client = Hurley::Client.new
295
+ client.connection = Google::Apis::Core::HttpClientAdapter.new unless client_options.use_net_http
294
296
  client.request_options.timeout = request_options.timeout_sec
295
297
  client.request_options.open_timeout = request_options.open_timeout_sec
296
298
  client.request_options.proxy = client_options.proxy_url
@@ -0,0 +1,82 @@
1
+ require 'httpclient'
2
+ require 'hurley'
3
+ require 'hurley/client'
4
+
5
+ module Google
6
+ module Apis
7
+ module Core
8
+ # HTTPClient adapter for Hurley.
9
+ class HttpClientAdapter
10
+
11
+ def call(request)
12
+ client = ::HTTPClient.new
13
+ configure_client(client, request)
14
+
15
+ begin
16
+ ::Hurley::Response.new(request) do |res|
17
+ http_res = client.request(request.verb.to_s.upcase, request.url.to_s, nil, request.body_io, request.header.to_hash, false) do |http_res, chunk|
18
+ copy_response(http_res, res)
19
+ res.receive_body(chunk)
20
+ end
21
+ copy_response(http_res, res)
22
+ end
23
+ rescue ::HTTPClient::TimeoutError, Errno::ETIMEDOUT
24
+ raise ::Hurley::Timeout, $!
25
+ rescue ::HTTPClient::BadResponseError => err
26
+ if err.message.include?('status 407')
27
+ raise ::Hurley::ConnectionFailed, %{407 "Proxy Authentication Required "}
28
+ else
29
+ raise Hurley::ClientError, $!
30
+ end
31
+ rescue Errno::ECONNREFUSED, EOFError
32
+ raise ::Hurley::ConnectionFailed, $!
33
+ rescue => err
34
+ if defined?(OpenSSL) && OpenSSL::SSL::SSLError === err
35
+ raise Hurley::SSLError, err
36
+ else
37
+ raise
38
+ end
39
+ end
40
+ end
41
+
42
+ def copy_response(http_res, res)
43
+ unless res.status_code
44
+ res.status_code = http_res.status.to_i
45
+ http_res.header.all.each do |(k,v)|
46
+ res.header[k] = v
47
+ end
48
+ end
49
+ end
50
+
51
+ def configure_client(client, request)
52
+ client.transparent_gzip_decompression = true
53
+ if request.options.proxy
54
+ proxy = request.options.proxy
55
+ client.proxy = sprintf('%s:%d', proxy.host, proxy.port)
56
+ if proxy.user && proxy.password
57
+ client.set_proxy_auth proxy.user, proxy.password
58
+ end
59
+ end
60
+ if request.options.timeout
61
+ client.connect_timeout = request.options.timeout
62
+ client.receive_timeout = request.options.timeout
63
+ client.send_timeout = request.options.timeout
64
+ end
65
+ if request.options.open_timeout
66
+ client.connect_timeout = request.options.open_timeout
67
+ client.send_timeout = request.options.open_timeout
68
+ end
69
+ ssl_config = client.ssl_config
70
+ ssl_opts = request.ssl_options
71
+ ssl_config.verify_mode = ssl_opts.openssl_verify_mode
72
+ ssl_config.cert_store = ssl_opts.openssl_cert_store
73
+ ssl_config.add_trust_ca ssl_opts.ca_file if ssl_opts.ca_file
74
+ ssl_config.add_trust_ca ssl_opts.ca_path if ssl_opts.ca_path
75
+ ssl_config.client_cert = ssl_opts.openssl_client_cert if ssl_opts.openssl_client_cert
76
+ ssl_config.client_key = ssl_opts.openssl_client_key if ssl_opts.openssl_client_key
77
+ ssl_config.verify_depth = ssl_opts.verify_depth if ssl_opts.verify_depth
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -264,7 +264,9 @@ module Google
264
264
  # Temporary workaround for Hurley bug where the connection preference
265
265
  # is ignored and it uses nested anyway
266
266
  req.url.query_class = Hurley::Query::Flat
267
- query.each { | k, v| req.url.query[k] = v }
267
+ query.each do | k, v|
268
+ req.url.query[k] = normalize_query_value(v)
269
+ end
268
270
  # End workaround
269
271
  apply_request_options(req)
270
272
  end
@@ -291,6 +293,19 @@ module Google
291
293
  req.header.update(header)
292
294
  req.options.timeout = options.timeout_sec
293
295
  end
296
+
297
+ private
298
+
299
+ def normalize_query_value(v)
300
+ case v
301
+ when Array
302
+ v.map { |v2| normalize_query_value(v2) }
303
+ when nil
304
+ nil
305
+ else
306
+ v.to_s
307
+ end
308
+ end
294
309
  end
295
310
  end
296
311
  end
@@ -76,7 +76,7 @@ module Google
76
76
  options[:render_filter] = ->(value, _doc, *_args) { value.is_a?(DateTime) ? value.rfc3339(3) : value.to_s }
77
77
  options[:parse_filter] = ->(fragment, _doc, *_args) { DateTime.parse(fragment) }
78
78
  end
79
-
79
+
80
80
  options[:render_nil] = true
81
81
  options[:getter] = getter_fn(name)
82
82
  options[:if] = if_fn(name)
@@ -107,7 +107,8 @@ module Google
107
107
  # @param [String] name
108
108
  # Property name
109
109
  # @param [Hash] options
110
- def hash(name, options)
110
+ def hash(name = nil, options = nil)
111
+ return super() unless name # Allow Object.hash
111
112
  set_default_options(name, options)
112
113
  super(name, options)
113
114
  end
@@ -82,7 +82,7 @@ module Google
82
82
  # @raise [Google::Apis::ClientError] if upload source is invalid
83
83
  def prepare!
84
84
  super
85
- if upload_source.is_a?(IO) || upload_source.is_a?(StringIO)
85
+ if streamable?(upload_source)
86
86
  self.upload_io = UploadIO.from_io(upload_source, content_type: upload_content_type)
87
87
  @close_io_on_finish = false
88
88
  elsif upload_source.is_a?(String)
@@ -97,6 +97,12 @@ module Google
97
97
  def release!
98
98
  upload_io.close if @close_io_on_finish
99
99
  end
100
+
101
+ private
102
+
103
+ def streamable?(upload_source)
104
+ upload_source.is_a?(IO) || upload_source.is_a?(StringIO) || upload_source.is_a?(Tempfile)
105
+ end
100
106
  end
101
107
 
102
108
  # Implementation of the raw upload protocol
@@ -18,7 +18,8 @@ module Google
18
18
  ClientOptions = Struct.new(
19
19
  :application_name,
20
20
  :application_version,
21
- :proxy_url)
21
+ :proxy_url,
22
+ :use_net_http)
22
23
 
23
24
  RequestOptions = Struct.new(
24
25
  :authorization,
@@ -73,7 +74,8 @@ module Google
73
74
  new_options
74
75
  end
75
76
  end
76
-
77
+
78
+ ClientOptions.default.use_net_http = false
77
79
  ClientOptions.default.application_name = 'unknown'
78
80
  ClientOptions.default.application_version = '0.0.0'
79
81
 
@@ -15,7 +15,7 @@
15
15
  module Google
16
16
  module Apis
17
17
  # Client library version
18
- VERSION = '0.9.pre4'
18
+ VERSION = '0.9.pre5'
19
19
 
20
20
  # Current operating system
21
21
  # @private
data/samples/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'google-api-client', '~> 0.9.pre4'
4
+ gem 'thor', '~> 0.19'
5
+ gem 'os', '~> 0.9'
6
+ gem 'rmail', '~> 1.1'
7
+ gem 'dotenv'
data/samples/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # API Samples
2
+
3
+ This directory contains a small but growing collection of samples for various
4
+ APIs. Each sample can be run on the command line from the `google-api-samples`
5
+ script.
6
+
7
+ Contributions of new samples are welcome.
8
+
9
+ # Setup
10
+
11
+ Depending on which particular samples you want to run, different
12
+ steps may be required. Some samples, like Pub/Sub, require a service account,
13
+ others like Drive, Calendar, and YouTube require an OAuth Client ID. And in
14
+ some cases like Translate, only an API key is needed.
15
+
16
+ * Create a project at https://console.developers.google.com
17
+ * Go to the `API Manager` and enable the APIs you'd like to try
18
+ * Go to `Credentials` and create the appropriate type of credential for the sample
19
+ * For keys, use 'Server key' as the type
20
+ * For OAuth Client IDs, use 'Other' as the type
21
+ * For service accounts, use the 'JSON' key type
22
+
23
+ Additional details on how to enable APIs and create credentials can be
24
+ found in the help guide in the console.
25
+
26
+
27
+ ## Example Environment Settings
28
+
29
+ For convenience, application credentials can be read from the shell environment
30
+ or placed in a .env file.
31
+
32
+ After setup, your .env file might look something like:
33
+
34
+ ```
35
+ GOOGLE_API_KEY=AIzaSyC6GvjvPlEzJpTW2bW2t0MPHXXXXXXXXXX
36
+ GOOGLE_CLIENT_ID=479164972499-i7j6av7bp2s4on5ltb7pjXXXXXXXXXX.apps.googleusercontent.com
37
+ GOOGLE_CLIENT_SECRET=JBotCTG5biFWGzXXXXXXXXXX
38
+ GOOGLE_APPLICATION_CREDENTIALS=~/ruby-samples-cred.json
39
+ ```
40
+
41
+ # Running the samples
42
+
43
+ To list the available sample modules, run the script:
44
+ ```
45
+ google-api-samples
46
+ ```
47
+
48
+ To get help on a specific set of samples, run:
49
+ ```
50
+ google-api-samples help <module>
51
+ ```
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift(File.expand_path("../lib", __FILE__))
4
+
5
+ require 'thor'
6
+ require 'dotenv'
7
+
8
+
9
+ # Small script to allow executing samples from the command line.
10
+ # Each sample is loaded as a subcommand.
11
+ #
12
+ # Example usage:
13
+ #
14
+ # google-api-samples drive upload myfile.txt
15
+ #
16
+ #
17
+ class App < Thor
18
+
19
+ # Load all the samples and register them as subcommands
20
+ Dir.glob('./lib/samples/*.rb').each do |file|
21
+ require file
22
+ end
23
+
24
+ Samples.constants.each do |const|
25
+ desc const.downcase, "#{const} samples"
26
+ subcommand const.downcase, Samples.const_get(const)
27
+ end
28
+
29
+ end
30
+
31
+ Dotenv.load
32
+ App.start(ARGV)
@@ -0,0 +1,94 @@
1
+ # Copyright 2016 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 'googleauth'
16
+ require 'googleauth/stores/file_token_store'
17
+ require 'fileutils'
18
+ require 'thor'
19
+ require 'os'
20
+
21
+ # Base command line module for samples. Provides authorization support,
22
+ # either using application default credentials or user authorization
23
+ # depending on the use case.
24
+ class BaseCli < Thor
25
+ include Thor::Actions
26
+
27
+ OOB_URI = 'urn:ietf:wg:oauth:2.0:oob'
28
+
29
+ class_option :user, :type => :string
30
+ class_option :api_key, :type => :string
31
+
32
+ no_commands do
33
+
34
+ # Returns the path to the client_secrets.json file.
35
+ def client_secrets_path
36
+ return ENV['GOOGLE_CLIENT_SECRETS'] if ENV.has_key?('GOOGLE_CLIENT_SECRETS')
37
+ return well_known_path_for('client_secrets.json')
38
+ end
39
+
40
+ # Returns the path to the token store.
41
+ def token_store_path
42
+ return ENV['GOOGLE_CREDENTIAL_STORE'] if ENV.has_key?('GOOGLE_CREDENTIAL_STORE')
43
+ return well_known_path_for('credentials.yaml')
44
+ end
45
+
46
+ # Builds a path to a file in $HOME/.config/google (or %APPDATA%/google,
47
+ # on Windows)
48
+ def well_known_path_for(file)
49
+ if OS.windows?
50
+ File.join(ENV['APPDATA'], 'google', file)
51
+ else
52
+ File.join(ENV['HOME'], '.config', 'google', file)
53
+ end
54
+ end
55
+
56
+ # Returns application credentials for the given scope.
57
+ def application_credentials_for(scope)
58
+ Google::Auth.get_application_default(scope)
59
+ end
60
+
61
+ # Returns user credentials for the given scope. Requests authorization
62
+ # if requrired.
63
+ def user_credentials_for(scope)
64
+ FileUtils.mkdir_p(File.dirname(token_store_path))
65
+
66
+ if ENV['GOOGLE_CLIENT_ID']
67
+ client_id = Google::Auth::ClientId.new(ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET'])
68
+ else
69
+ client_id = Google::Auth::ClientId.from_file(client_secrets_path)
70
+ end
71
+ token_store = Google::Auth::Stores::FileTokenStore.new(:file => token_store_path)
72
+ authorizer = Google::Auth::UserAuthorizer.new(client_id, scope, token_store)
73
+
74
+ user_id = options[:user] || 'default'
75
+
76
+ credentials = authorizer.get_credentials(user_id)
77
+ if credentials.nil?
78
+ url = authorizer.get_authorization_url(base_url: OOB_URI)
79
+ say "Open the following URL in your browser and authorize the application."
80
+ say url
81
+ code = ask "Enter the authorization code:"
82
+ credentials = authorizer.get_and_store_credentials_from_code(
83
+ user_id: user_id, code: code, base_url: OOB_URI)
84
+ end
85
+ credentials
86
+ end
87
+
88
+ # Gets the API key of the client
89
+ def api_key
90
+ ENV['GOOGLE_API_KEY'] || options[:api_key]
91
+ end
92
+
93
+ end
94
+ end
@@ -0,0 +1,62 @@
1
+ # Copyright 2016 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 'google/apis/analytics_v3'
16
+ require 'base_cli'
17
+
18
+ module Samples
19
+ # Examples for the Google Analytics APIs
20
+ #
21
+ # Sample usage session:
22
+ #
23
+ # $ ./google-api-samples analytics show_visits 55622900 --start='2015-12-01' --end='2015-12-08'
24
+ # ga:date ga:sessions ga:users ga:newUsers ga:percentNewSessions ga:sessionDuration ga:avgSessionDuration
25
+ # 20151201 0 0 0 0.0 0.0 0.0
26
+ # 20151202 0 0 0 0.0 0.0 0.0
27
+ # 20151203 1 1 1 100.0 0.0 0.0
28
+ # 20151204 2 2 1 50.0 616.0 308.0
29
+ # 20151205 0 0 0 0.0 0.0 0.0
30
+ # 20151206 1 1 1 100.0 0.0 0.0
31
+ # 20151207 0 0 0 0.0 0.0 0.0
32
+ # 20151208 2 2 1 50.0 0.0 0.0
33
+ #
34
+ class Analytics < BaseCli
35
+ Analytics = Google::Apis::AnalyticsV3
36
+
37
+ desc 'show_visits PROFILE_ID', 'Show visists for the given analytics profile ID'
38
+ method_option :start, type: :string, required: true
39
+ method_option :end, type: :string, required: true
40
+ def show_visits(profile_id)
41
+ analytics = Analytics::AnalyticsService.new
42
+ analytics.authorization = user_credentials_for(Analytics::AUTH_ANALYTICS)
43
+
44
+ dimensions = %w(ga:date)
45
+ metrics = %w(ga:sessions ga:users ga:newUsers ga:percentNewSessions
46
+ ga:sessionDuration ga:avgSessionDuration)
47
+ sort = %w(ga:date)
48
+ result = analytics.get_ga_data("ga:#{profile_id}",
49
+ options[:start],
50
+ options[:end],
51
+ metrics.join(','),
52
+ dimensions: dimensions.join(','),
53
+ sort: sort.join(','))
54
+
55
+ data = []
56
+ data.push(result.column_headers.map { |h| h.name })
57
+ data.push(*result.rows)
58
+ print_table(data)
59
+ end
60
+
61
+ end
62
+ end