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

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.
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