google-adwords-api 1.5.0 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (132) hide show
  1. checksums.yaml +4 -4
  2. data/COPYING +0 -0
  3. data/ChangeLog +4 -0
  4. data/README.md +9 -236
  5. data/lib/adwords_api.rb +2 -234
  6. metadata +8 -134
  7. data/adwords_api.yml +0 -53
  8. data/lib/adwords_api/api_config.rb +0 -221
  9. data/lib/adwords_api/batch_job_utils.rb +0 -334
  10. data/lib/adwords_api/credential_handler.rb +0 -96
  11. data/lib/adwords_api/errors.rb +0 -110
  12. data/lib/adwords_api/incremental_upload_helper.rb +0 -75
  13. data/lib/adwords_api/query_utils/query_builder.rb +0 -41
  14. data/lib/adwords_api/query_utils/report_query.rb +0 -30
  15. data/lib/adwords_api/query_utils/report_query_builder.rb +0 -82
  16. data/lib/adwords_api/query_utils/service_query.rb +0 -62
  17. data/lib/adwords_api/query_utils/service_query_builder.rb +0 -83
  18. data/lib/adwords_api/query_utils/where_builder.rb +0 -97
  19. data/lib/adwords_api/report_header_handler.rb +0 -80
  20. data/lib/adwords_api/report_stream.rb +0 -70
  21. data/lib/adwords_api/report_utils.rb +0 -383
  22. data/lib/adwords_api/utils.rb +0 -56
  23. data/lib/adwords_api/utils_reporter.rb +0 -58
  24. data/lib/adwords_api/v201809/account_label_service.rb +0 -46
  25. data/lib/adwords_api/v201809/account_label_service_registry.rb +0 -46
  26. data/lib/adwords_api/v201809/ad_customizer_feed_service.rb +0 -46
  27. data/lib/adwords_api/v201809/ad_customizer_feed_service_registry.rb +0 -46
  28. data/lib/adwords_api/v201809/ad_group_ad_service.rb +0 -62
  29. data/lib/adwords_api/v201809/ad_group_ad_service_registry.rb +0 -46
  30. data/lib/adwords_api/v201809/ad_group_bid_modifier_service.rb +0 -54
  31. data/lib/adwords_api/v201809/ad_group_bid_modifier_service_registry.rb +0 -46
  32. data/lib/adwords_api/v201809/ad_group_criterion_service.rb +0 -62
  33. data/lib/adwords_api/v201809/ad_group_criterion_service_registry.rb +0 -46
  34. data/lib/adwords_api/v201809/ad_group_extension_setting_service.rb +0 -54
  35. data/lib/adwords_api/v201809/ad_group_extension_setting_service_registry.rb +0 -46
  36. data/lib/adwords_api/v201809/ad_group_feed_service.rb +0 -54
  37. data/lib/adwords_api/v201809/ad_group_feed_service_registry.rb +0 -46
  38. data/lib/adwords_api/v201809/ad_group_service.rb +0 -62
  39. data/lib/adwords_api/v201809/ad_group_service_registry.rb +0 -46
  40. data/lib/adwords_api/v201809/ad_param_service.rb +0 -46
  41. data/lib/adwords_api/v201809/ad_param_service_registry.rb +0 -46
  42. data/lib/adwords_api/v201809/ad_service.rb +0 -46
  43. data/lib/adwords_api/v201809/ad_service_registry.rb +0 -46
  44. data/lib/adwords_api/v201809/adwords_user_list_service.rb +0 -62
  45. data/lib/adwords_api/v201809/adwords_user_list_service_registry.rb +0 -46
  46. data/lib/adwords_api/v201809/asset_service.rb +0 -46
  47. data/lib/adwords_api/v201809/asset_service_registry.rb +0 -46
  48. data/lib/adwords_api/v201809/batch_job_service.rb +0 -54
  49. data/lib/adwords_api/v201809/batch_job_service_registry.rb +0 -46
  50. data/lib/adwords_api/v201809/bidding_strategy_service.rb +0 -54
  51. data/lib/adwords_api/v201809/bidding_strategy_service_registry.rb +0 -46
  52. data/lib/adwords_api/v201809/budget_order_service.rb +0 -54
  53. data/lib/adwords_api/v201809/budget_order_service_registry.rb +0 -46
  54. data/lib/adwords_api/v201809/budget_service.rb +0 -54
  55. data/lib/adwords_api/v201809/budget_service_registry.rb +0 -46
  56. data/lib/adwords_api/v201809/campaign_bid_modifier_service.rb +0 -54
  57. data/lib/adwords_api/v201809/campaign_bid_modifier_service_registry.rb +0 -46
  58. data/lib/adwords_api/v201809/campaign_criterion_service.rb +0 -54
  59. data/lib/adwords_api/v201809/campaign_criterion_service_registry.rb +0 -46
  60. data/lib/adwords_api/v201809/campaign_extension_setting_service.rb +0 -54
  61. data/lib/adwords_api/v201809/campaign_extension_setting_service_registry.rb +0 -46
  62. data/lib/adwords_api/v201809/campaign_feed_service.rb +0 -54
  63. data/lib/adwords_api/v201809/campaign_feed_service_registry.rb +0 -46
  64. data/lib/adwords_api/v201809/campaign_group_performance_target_service.rb +0 -46
  65. data/lib/adwords_api/v201809/campaign_group_performance_target_service_registry.rb +0 -46
  66. data/lib/adwords_api/v201809/campaign_group_service.rb +0 -46
  67. data/lib/adwords_api/v201809/campaign_group_service_registry.rb +0 -46
  68. data/lib/adwords_api/v201809/campaign_service.rb +0 -62
  69. data/lib/adwords_api/v201809/campaign_service_registry.rb +0 -46
  70. data/lib/adwords_api/v201809/campaign_shared_set_service.rb +0 -54
  71. data/lib/adwords_api/v201809/campaign_shared_set_service_registry.rb +0 -46
  72. data/lib/adwords_api/v201809/constant_data_service.rb +0 -110
  73. data/lib/adwords_api/v201809/constant_data_service_registry.rb +0 -46
  74. data/lib/adwords_api/v201809/conversion_tracker_service.rb +0 -54
  75. data/lib/adwords_api/v201809/conversion_tracker_service_registry.rb +0 -46
  76. data/lib/adwords_api/v201809/custom_affinity_service.rb +0 -62
  77. data/lib/adwords_api/v201809/custom_affinity_service_registry.rb +0 -46
  78. data/lib/adwords_api/v201809/customer_extension_setting_service.rb +0 -54
  79. data/lib/adwords_api/v201809/customer_extension_setting_service_registry.rb +0 -46
  80. data/lib/adwords_api/v201809/customer_feed_service.rb +0 -54
  81. data/lib/adwords_api/v201809/customer_feed_service_registry.rb +0 -46
  82. data/lib/adwords_api/v201809/customer_negative_criterion_service.rb +0 -54
  83. data/lib/adwords_api/v201809/customer_negative_criterion_service_registry.rb +0 -46
  84. data/lib/adwords_api/v201809/customer_service.rb +0 -62
  85. data/lib/adwords_api/v201809/customer_service_registry.rb +0 -46
  86. data/lib/adwords_api/v201809/customer_sync_service.rb +0 -38
  87. data/lib/adwords_api/v201809/customer_sync_service_registry.rb +0 -47
  88. data/lib/adwords_api/v201809/data_service.rb +0 -94
  89. data/lib/adwords_api/v201809/data_service_registry.rb +0 -46
  90. data/lib/adwords_api/v201809/draft_async_error_service.rb +0 -46
  91. data/lib/adwords_api/v201809/draft_async_error_service_registry.rb +0 -46
  92. data/lib/adwords_api/v201809/draft_service.rb +0 -54
  93. data/lib/adwords_api/v201809/draft_service_registry.rb +0 -46
  94. data/lib/adwords_api/v201809/feed_item_service.rb +0 -54
  95. data/lib/adwords_api/v201809/feed_item_service_registry.rb +0 -46
  96. data/lib/adwords_api/v201809/feed_item_target_service.rb +0 -54
  97. data/lib/adwords_api/v201809/feed_item_target_service_registry.rb +0 -46
  98. data/lib/adwords_api/v201809/feed_mapping_service.rb +0 -54
  99. data/lib/adwords_api/v201809/feed_mapping_service_registry.rb +0 -46
  100. data/lib/adwords_api/v201809/feed_service.rb +0 -54
  101. data/lib/adwords_api/v201809/feed_service_registry.rb +0 -46
  102. data/lib/adwords_api/v201809/label_service.rb +0 -54
  103. data/lib/adwords_api/v201809/label_service_registry.rb +0 -46
  104. data/lib/adwords_api/v201809/location_criterion_service.rb +0 -46
  105. data/lib/adwords_api/v201809/location_criterion_service_registry.rb +0 -46
  106. data/lib/adwords_api/v201809/managed_customer_service.rb +0 -78
  107. data/lib/adwords_api/v201809/managed_customer_service_registry.rb +0 -46
  108. data/lib/adwords_api/v201809/media_service.rb +0 -54
  109. data/lib/adwords_api/v201809/media_service_registry.rb +0 -46
  110. data/lib/adwords_api/v201809/offline_call_conversion_feed_service.rb +0 -38
  111. data/lib/adwords_api/v201809/offline_call_conversion_feed_service_registry.rb +0 -46
  112. data/lib/adwords_api/v201809/offline_conversion_adjustment_feed_service.rb +0 -38
  113. data/lib/adwords_api/v201809/offline_conversion_adjustment_feed_service_registry.rb +0 -46
  114. data/lib/adwords_api/v201809/offline_conversion_feed_service.rb +0 -38
  115. data/lib/adwords_api/v201809/offline_conversion_feed_service_registry.rb +0 -46
  116. data/lib/adwords_api/v201809/offline_data_upload_service.rb +0 -46
  117. data/lib/adwords_api/v201809/offline_data_upload_service_registry.rb +0 -46
  118. data/lib/adwords_api/v201809/report_definition_service.rb +0 -38
  119. data/lib/adwords_api/v201809/report_definition_service_registry.rb +0 -46
  120. data/lib/adwords_api/v201809/shared_criterion_service.rb +0 -54
  121. data/lib/adwords_api/v201809/shared_criterion_service_registry.rb +0 -46
  122. data/lib/adwords_api/v201809/shared_set_service.rb +0 -54
  123. data/lib/adwords_api/v201809/shared_set_service_registry.rb +0 -46
  124. data/lib/adwords_api/v201809/targeting_idea_service.rb +0 -38
  125. data/lib/adwords_api/v201809/targeting_idea_service_registry.rb +0 -46
  126. data/lib/adwords_api/v201809/traffic_estimator_service.rb +0 -38
  127. data/lib/adwords_api/v201809/traffic_estimator_service_registry.rb +0 -46
  128. data/lib/adwords_api/v201809/trial_async_error_service.rb +0 -46
  129. data/lib/adwords_api/v201809/trial_async_error_service_registry.rb +0 -46
  130. data/lib/adwords_api/v201809/trial_service.rb +0 -54
  131. data/lib/adwords_api/v201809/trial_service_registry.rb +0 -46
  132. data/lib/adwords_api/version.rb +0 -24
@@ -1,334 +0,0 @@
1
- # Encoding: utf-8
2
- #
3
- # Copyright:: Copyright 2015, Google Inc. All Rights Reserved.
4
- #
5
- # License:: Licensed under the Apache License, Version 2.0 (the "License");
6
- # you may not use this file except in compliance with the License.
7
- # You may obtain a copy of the License at
8
- #
9
- # http://www.apache.org/licenses/LICENSE-2.0
10
- #
11
- # Unless required by applicable law or agreed to in writing, software
12
- # distributed under the License is distributed on an "AS IS" BASIS,
13
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14
- # implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- #
18
- # Contains utility methods specific to using the BatchJobService.
19
-
20
- require 'nokogiri'
21
- require 'nori'
22
-
23
- require 'ads_common/http'
24
- require 'ads_common/savon_service'
25
- require 'adwords_api/errors'
26
- require 'adwords_api/incremental_upload_helper'
27
-
28
- module AdwordsApi
29
- class BatchJobUtils
30
- # Default constructor.
31
- #
32
- # Args:
33
- # - api: AdwordsApi object
34
- # - version: API version to use
35
- #
36
- def initialize(api, version)
37
- @api, @version = api, version
38
- end
39
-
40
- # Uploads the given operations for a batch job to the provided URL.
41
- #
42
- # Args:
43
- # - hash_operations: An array of ruby has operations to execute by
44
- # posting them to the provided URL
45
- # - service_name: The name of the AdwordsApi service as a symbol that would
46
- # normally make this request
47
- # - batch_job_url: The UploadURL provided by BatchJobService
48
- #
49
- # Raises:
50
- # - InvalidBatchJobOperationError: If there is a problem converting the
51
- # given operations to SOAP.
52
- #
53
- def upload_operations(operations, batch_job_url)
54
- helper = start_incremental_upload(batch_job_url)
55
- helper.upload(operations, true)
56
- end
57
-
58
- # Provides a helper to manage incremental uploads.
59
- #
60
- # Args:
61
- # - batch_job_url: The UploadURL provided by BatchJobService for new jobs,
62
- # or the upload_url from IncrementalUploadHelper for continued jobs.
63
- # - uploaded_bytes: The number of bytes already uploaded for this
64
- # incremental batch job. Can be retrieved from the IncrementalUploadHelper
65
- # using uploaded_bytes.
66
- #
67
- # Returns:
68
- # - an IncrementalUploadHelper that will accept operations and put them,
69
- # keeping track of uploaded bytes automatically.
70
- #
71
- def start_incremental_upload(batch_job_url, uploaded_bytes = 0)
72
- return AdwordsApi::IncrementalUploadHelper.new(
73
- self, uploaded_bytes, batch_job_url)
74
- end
75
-
76
- # Initializes an upload URL to get the actual URL to which to upload
77
- # operations.
78
- #
79
- # Args:
80
- # - batch_job_url: The UploadURL provided by BatchJobService
81
- #
82
- # Returns:
83
- # - The URL that should actually be used to upload operations.
84
- #
85
- def initialize_url(batch_job_url)
86
- headers = DEFAULT_HEADERS
87
- headers['Content-Length'] = 0
88
- headers['x-goog-resumable'] = 'start'
89
-
90
- response = AdsCommon::Http.post_response(
91
- batch_job_url, '', @api.config, headers)
92
-
93
- return response.headers['Location']
94
- end
95
-
96
- # Puts the provided operations to the provided URL, allowing
97
- # for incremental followup puts.
98
- #
99
- # Args:
100
- # - soap_operations: An array including SOAP operations provided by
101
- # generate_soap_operations
102
- # - batch_job_url: The UploadURL provided by BatchJobService
103
- # - total_content_length: The total number of bytes already uploaded
104
- # incrementally. Set this to 0 the first time you call the method.
105
- # - is_last_request: Whether or not this set of uploads will conclude the
106
- # full request.
107
- #
108
- # Returns:
109
- # - total content length, including what was just uploaded. Pass this back
110
- # into this method on subsequent calls.
111
- def put_incremental_operations(
112
- operations, batch_job_url, total_content_length = 0,
113
- is_last_request = false)
114
- @api.utils_reporter.batch_job_utils_used()
115
- headers = DEFAULT_HEADERS
116
- soap_operations = generate_soap_operations(operations)
117
- request_body = soap_operations.join
118
- is_first_request = (total_content_length == 0)
119
-
120
- if is_first_request
121
- request_body = (UPLOAD_XML_PREFIX % [@version]) + request_body
122
- end
123
- if is_last_request
124
- request_body += UPLOAD_XML_SUFFIX
125
- end
126
-
127
- request_body = add_padding(request_body)
128
- content_length = request_body.bytesize
129
-
130
- headers['Content-Length'] = content_length
131
-
132
- lower_bound = total_content_length
133
- upper_bound = total_content_length + content_length - 1
134
- total_bytes = is_last_request ? upper_bound + 1 : '*'
135
- content_range =
136
- "bytes %d-%d/%s" % [lower_bound, upper_bound, total_bytes]
137
-
138
- headers['Content-Range'] = content_range
139
-
140
- log_request(batch_job_url, headers, request_body)
141
-
142
- # The HTTPI library fails to handle the response when uploading
143
- # incremental requests. We're not interested in the response, so just
144
- # ignore the error.
145
- begin
146
- AdsCommon::Http.put_response(
147
- batch_job_url, request_body, @api.config, headers)
148
- rescue ArgumentError
149
- end
150
-
151
- total_content_length += content_length
152
- return total_content_length
153
- end
154
-
155
- # Downloads the results of a batch job from the specified URL.
156
- #
157
- # Args:
158
- # - batch_job_url: The URL provided by BatchJobService to fetch the results
159
- # from
160
- #
161
- # Returns:
162
- # - the results of the batch job, as a ruby hash, or nil if none yet exist
163
- #
164
- def get_job_results(batch_job_url)
165
- @api.utils_reporter.batch_job_utils_used()
166
- xml_response = AdsCommon::Http.get_response(batch_job_url, @api.config)
167
- begin
168
- return sanitize_result(
169
- get_nori().parse(xml_response.body)[:mutate_response][:rval])
170
- rescue
171
- return nil
172
- end
173
- end
174
-
175
- private
176
-
177
- # For incremental uploads, the size (in bytes) of the body of the request
178
- # must be in multiples of 256k.
179
- REQUIRED_CONTENT_LENGTH_INCREMENT = 256 * 1024
180
-
181
- UPLOAD_XML_PREFIX = '<?xml version="1.0" encoding="UTF-8"?><ns1:mutate ' +
182
- 'xmlns:ns1="https://adwords.google.com/api/adwords/cm/%s">'
183
- UPLOAD_XML_SUFFIX = '</ns1:mutate>'
184
- DEFAULT_HEADERS = {"Content-Type" => "application/xml"}
185
-
186
- SERVICES_BY_OPERATION_TYPE = {
187
- 'AdGroupAdOperation' => :AdGroupAdService,
188
- 'AdGroupAdLabelOperation' => :AdGroupAdService,
189
- 'AdGroupBidModifierOperation' => :AdGroupBidModifierService,
190
- 'AdGroupCriterionOperation' => :AdGroupCriterionService,
191
- 'AdGroupCriterionLabelOperation' => :AdGroupCriterionService,
192
- 'AdGroupExtensionSettingOperation' => :AdGroupExtensionSettingService,
193
- 'AdGroupOperation' => :AdGroupService,
194
- 'AdGroupLabelOperation' => :AdGroupService,
195
- 'BudgetOperation' => :BudgetService,
196
- 'CampaignCriterionOperation' => :CampaignCriterionService,
197
- 'CampaignExtensionSettingOperation' => :CampaignExtensionSettingService,
198
- 'CampaignLabelOperation' => :CampaignService,
199
- 'CampaignOperation' => :CampaignService,
200
- 'CampaignSharedSetOperation' => :CampaignSharedSetService,
201
- 'CustomerExtensionSettingOperation' => :CustomerExtensionSettingService,
202
- 'FeedItemOperation' => :FeedItemService,
203
- 'FeedItemTargetOperation' => :FeedItemTargetService,
204
- 'SharedCriterionOperation' => :SharedCriterionService,
205
- 'SharedSetOperation' => :SharedSetService
206
- }
207
-
208
- METHODS_BY_OPERATION_TYPE = {
209
- 'AdGroupAdOperation' => 'mutate_to_xml',
210
- 'AdGroupAdLabelOperation' => 'mutate_label_to_xml',
211
- 'AdGroupBidModifierOperation' => 'mutate_to_xml',
212
- 'AdGroupCriterionOperation' => 'mutate_to_xml',
213
- 'AdGroupCriterionLabelOperation' => 'mutate_label_to_xml',
214
- 'AdGroupExtensionSettingOperation' => 'mutate_to_xml',
215
- 'AdGroupOperation' => 'mutate_to_xml',
216
- 'AdGroupLabelOperation' => 'mutate_label_to_xml',
217
- 'BudgetOperation' => 'mutate_to_xml',
218
- 'CampaignCriterionOperation' => 'mutate_to_xml',
219
- 'CampaignExtensionSettingOperation' => 'mutate_to_xml',
220
- 'CampaignLabelOperation' => 'mutate_label_to_xml',
221
- 'CampaignOperation' => 'mutate_to_xml',
222
- 'CampaignSharedSetOperation' => 'mutate_to_xml',
223
- 'CustomerExtensionSettingOperation' => 'mutate_to_xml',
224
- 'FeedItemOperation' => 'mutate_to_xml',
225
- 'FeedItemTargetOperation' => 'mutate_to_xml',
226
- 'SharedCriterionOperation' => 'mutate_to_xml',
227
- 'SharedSetOperation' => 'mutate_to_xml'
228
- }
229
-
230
- def generate_soap_operations(hash_operations)
231
- unless hash_operations.is_a?(Array)
232
- raise AdwordsApi::Errors::InvalidBatchJobOperationError,
233
- 'Operations must be in an array.'
234
- end
235
- return hash_operations.map do |operation|
236
- operation_type = operation[:xsi_type]
237
- if operation_type.nil?
238
- raise AdwordsApi::Errors::InvalidBatchJobOperationError,
239
- ':xsi_type for operations must be defined ' +
240
- 'explicitly for batch jobs.'
241
- end
242
- service_name = SERVICES_BY_OPERATION_TYPE[operation_type]
243
- if service_name.nil?
244
- raise AdwordsApi::Errors::InvalidBatchJobOperationError,
245
- 'Unknown operation type: %s' % operation_type
246
- end
247
- method_name = METHODS_BY_OPERATION_TYPE[operation_type]
248
- service = @api.service(service_name, @version)
249
- full_soap_xml = service.send(method_name, [operation])
250
- operation_xml = extract_soap_operations(full_soap_xml)
251
- operation_xml
252
- end
253
- end
254
-
255
- # Given a full SOAP xml string, extract just the operations element
256
- # from the SOAP body as a string.
257
- def extract_soap_operations(full_soap_xml)
258
- doc = Nokogiri::XML(full_soap_xml)
259
- operations = doc.css('wsdl|operations')
260
- operations.attr('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance')
261
- operations.each do |element|
262
- check_xsi_type(element)
263
- end
264
- return operations.to_s
265
- end
266
-
267
- def check_xsi_type(xml_node)
268
- xsi_type = xml_node['xsi:type']
269
- unless xsi_type.nil? or xsi_type.start_with?('ns1:')
270
- xml_node['xsi:type'] = 'ns1:' + xsi_type
271
- end
272
- children = xml_node.children
273
- unless children.empty?
274
- children.each do |element|
275
- check_xsi_type(element)
276
- end
277
- end
278
- end
279
-
280
- # Logs the request on debug level.
281
- def log_request(url, headers, body)
282
- logger = @api.logger
283
- logger.debug("Report request to: '%s'" % url)
284
- logger.debug('HTTP headers: [%s]' %
285
- (headers.map { |k, v| [k, v].join(': ') }.join(', ')))
286
- logger.debug(body)
287
- end
288
-
289
- # Removes extraneous XML information from return hash.
290
- def sanitize_result(results)
291
- if results.is_a?(Array)
292
- ret = []
293
- results.each do |result|
294
- ret << sanitize_result(result)
295
- end
296
- return ret
297
- end
298
-
299
- if results.is_a?(Hash)
300
- ret = {}
301
- results.each do |k, v|
302
- v = sanitize_result(v) if v.is_a?(Hash)
303
- ret[k] = v unless k.to_s.start_with?('@')
304
- end
305
- return ret
306
- end
307
-
308
- return results
309
- end
310
-
311
- def add_padding(xml)
312
- remainder = xml.bytesize % REQUIRED_CONTENT_LENGTH_INCREMENT
313
- return xml if remainder == 0
314
- bytes_to_add = REQUIRED_CONTENT_LENGTH_INCREMENT - remainder
315
- padded_xml = xml + (' ' * bytes_to_add)
316
- return padded_xml
317
- end
318
-
319
- def get_nori()
320
- return @nori if @nori
321
-
322
- nori_options = {
323
- :strip_namespaces => true,
324
- :convert_tags_to => lambda { |tag| tag.snakecase.to_sym },
325
- :empty_tag_value => "",
326
- :advanced_typecasting => false
327
- }
328
-
329
- @nori = Nori.new(nori_options)
330
-
331
- return @nori
332
- end
333
- end
334
- end
@@ -1,96 +0,0 @@
1
- # Encoding: utf-8
2
- #
3
- # Copyright:: Copyright 2010, Google Inc. All Rights Reserved.
4
- #
5
- # License:: Licensed under the Apache License, Version 2.0 (the "License");
6
- # you may not use this file except in compliance with the License.
7
- # You may obtain a copy of the License at
8
- #
9
- # http://www.apache.org/licenses/LICENSE-2.0
10
- #
11
- # Unless required by applicable law or agreed to in writing, software
12
- # distributed under the License is distributed on an "AS IS" BASIS,
13
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14
- # implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- #
18
- # AdWords-specific credential handler.
19
-
20
- require 'ads_common/credential_handler'
21
- require 'adwords_api/api_config'
22
-
23
- module AdwordsApi
24
- class CredentialHandler < AdsCommon::CredentialHandler
25
- # Whether we're making validate-only requests.
26
- attr_accessor :validate_only
27
- # Whether we're making partial failure requests.
28
- attr_accessor :partial_failure
29
-
30
- def initialize(config)
31
- super(config)
32
- @validate_only = false
33
- @partial_failure = false
34
- end
35
-
36
- # Create the list of credentials to be used by the auth handler for header
37
- # generation.
38
- def credentials(credentials_override = nil)
39
- result = super(credentials_override)
40
- validate_headers_for_server(result)
41
-
42
- extra_headers = {
43
- 'userAgent' => generate_user_agent(),
44
- 'developerToken' => result[:developer_token]
45
- }
46
- extra_headers['clientCustomerId'] = result[:client_customer_id] if
47
- result[:client_customer_id]
48
- extra_headers['validateOnly'] = 'true' if @validate_only
49
- extra_headers['partialFailure'] = 'true' if @partial_failure
50
- result[:extra_headers] = extra_headers
51
- return result
52
- end
53
-
54
- # Generates string to use as user agent in headers.
55
- def generate_user_agent(extra_ids = [])
56
- agent_app = @config.read('authentication.user_agent')
57
- if !agent_app.nil? && !agent_app.ascii_only?
58
- raise AdwordsApi::Errors::InvalidUserAgentError.new(
59
- 'User agent contains non-ASCII characters.', agent_app)
60
- end
61
- extra_ids << ['AwApi-Ruby/%s' % AdwordsApi::ApiConfig::CLIENT_LIB_VERSION]
62
- super(extra_ids, agent_app)
63
- end
64
-
65
- # Returns the client customer ID specified in the current credentials.
66
- def identifier()
67
- return credentials[:extra_headers]['clientCustomerId']
68
- end
69
-
70
- private
71
-
72
- # Validates that the right credentials are being used for the chosen
73
- # environment.
74
- #
75
- # Raises:
76
- # - AdwordsApi::Errors:BadCredentialsError if supplied credentials are not
77
- # valid.
78
- #
79
- def validate_headers_for_server(credentials)
80
- client_customer_id = credentials[:client_customer_id]
81
-
82
- if client_customer_id and (!(client_customer_id.is_a?(Integer) or
83
- (client_customer_id =~ /^\d+(-\d+-\d+)?$/)))
84
- raise AdwordsApi::Errors::BadCredentialsError,
85
- 'Invalid client customer ID: %s' % client_customer_id.to_s
86
- end
87
-
88
- token = credentials[:developer_token]
89
- if token.nil? || token.empty?
90
- raise AdwordsApi::Errors::BadCredentialsError,
91
- 'Developer token is missing, check credentials.'
92
- end
93
- return nil
94
- end
95
- end
96
- end
@@ -1,110 +0,0 @@
1
- # Encoding: utf-8
2
- #
3
- # Copyright:: Copyright 2010, Google Inc. All Rights Reserved.
4
- #
5
- # License:: Licensed under the Apache License, Version 2.0 (the "License");
6
- # you may not use this file except in compliance with the License.
7
- # You may obtain a copy of the License at
8
- #
9
- # http://www.apache.org/licenses/LICENSE-2.0
10
- #
11
- # Unless required by applicable law or agreed to in writing, software
12
- # distributed under the License is distributed on an "AS IS" BASIS,
13
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14
- # implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- #
18
- # Specific error handling for the AdWords API.
19
-
20
- require 'ads_common/errors'
21
- require 'ads_common/results_extractor'
22
-
23
- module AdwordsApi
24
- module Errors
25
-
26
- # This class encapsulates base class for API exceptions. More specific
27
- # exceptions are generated based on Service WSDL.
28
- class ApiException < AdsCommon::Errors::ApiException
29
- attr_reader :array_fields
30
-
31
- def initialize(exception_fault, registry)
32
- @array_fields ||= []
33
- extractor = AdsCommon::ResultsExtractor.new(registry)
34
- exception_type = exception_fault[:application_exception_type]
35
- exception_data = (exception_type.nil?) ? exception_fault :
36
- extractor.extract_exception_data(exception_fault, exception_type)
37
- exception_data.each { |key, value| set_field(key, value) }
38
- super(exception_data[:message])
39
- end
40
-
41
- private
42
-
43
- # Sets instance's property to a value if it is defined
44
- def set_field(field, value)
45
- if respond_to?(field)
46
- value = arrayize(value) if is_array_field(field)
47
- instance_variable_set("@#{field}", value)
48
- end
49
- end
50
-
51
- # Makes sure object is an array
52
- def arrayize(object)
53
- return [] if object.nil?
54
- return object.is_a?(Array) ? object : [object]
55
- end
56
-
57
- # Should a field be forced to be an array
58
- def is_array_field(field)
59
- return @array_fields.include?(field.to_s)
60
- end
61
- end
62
-
63
- # Error for invalid credentials sush as malformed ID.
64
- class BadCredentialsError < AdsCommon::Errors::ApiException
65
- end
66
-
67
- # Error for malformed report definition.
68
- class InvalidReportDefinitionError < AdsCommon::Errors::ApiException
69
- end
70
-
71
- # Error for server-side report error.
72
- class ReportError < AdsCommon::Errors::ApiException
73
- attr_reader :http_code
74
-
75
- def initialize(http_code, message)
76
- super(message)
77
- @http_code = http_code
78
- end
79
- end
80
-
81
- # Error for server-side report XML error.
82
- class ReportXmlError < ReportError
83
- attr_reader :type, :trigger, :field_path
84
-
85
- def initialize(http_code, error_type, error_trigger, error_field_path)
86
- message =
87
- "HTTP code: %d, error type: '%s', trigger: '%s', field path: '%s'" %
88
- [http_code, error_type, error_trigger, error_field_path]
89
- super(http_code, message)
90
- @type = error_type
91
- @trigger = error_trigger
92
- @field_path = error_field_path
93
- end
94
- end
95
-
96
- # Error for use an unsupported operation in a batch job.
97
- class InvalidBatchJobOperationError < AdsCommon::Errors::ApiException
98
- end
99
-
100
- # Error for using an invalid user agent string.
101
- class InvalidUserAgentError < AdsCommon::Errors::Error
102
- attr_reader :user_agent
103
-
104
- def initialize(message, user_agent)
105
- super(message)
106
- @user_agent = user_agent
107
- end
108
- end
109
- end
110
- end
@@ -1,75 +0,0 @@
1
- # Encoding: utf-8
2
- #
3
- # Copyright:: Copyright 2015, Google Inc. All Rights Reserved.
4
- #
5
- # License:: Licensed under the Apache License, Version 2.0 (the "License");
6
- # you may not use this file except in compliance with the License.
7
- # You may obtain a copy of the License at
8
- #
9
- # http://www.apache.org/licenses/LICENSE-2.0
10
- #
11
- # Unless required by applicable law or agreed to in writing, software
12
- # distributed under the License is distributed on an "AS IS" BASIS,
13
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14
- # implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- #
18
- # Contains helper methods to allow incremental uploads with the
19
- # BatchJobService.
20
-
21
- module AdwordsApi
22
- class IncrementalUploadHelper
23
- attr_reader :upload_url, :uploaded_bytes
24
-
25
- # Default constructor.
26
- #
27
- # Args:
28
- # - batch_job_service: The instance of BatchJobService that is providing
29
- # this helper
30
- # - uploaded_bytes: The number of bytes that have already been uploaded
31
- # as part of this incremental process.
32
- # - upload_url: The URL that should be used to upload incremental
33
- # operations for this job.
34
- #
35
- def initialize(batch_job_utils, uploaded_bytes, upload_url)
36
- @batch_job_utils = batch_job_utils
37
- @uploaded_bytes = uploaded_bytes
38
- if @uploaded_bytes == 0
39
- @upload_url = @batch_job_utils.initialize_url(upload_url)
40
- else
41
- @upload_url = upload_url
42
- end
43
- @finished = false
44
- end
45
-
46
- # Takes an array of operations and puts it to the batch job incrementally.
47
- #
48
- # Args:
49
- # - hash_operations: An array of operations to put, represented in hashes
50
- # like you would normally pass to services.
51
- # - is_last_request: Whether this request is the last request of the
52
- # incremental job.
53
- #
54
- # Raises:
55
- # - InvalidBatchJobOperationError: If this incremental upload is already
56
- # finished or if there is an error converting the hash operations to
57
- # soap operations.
58
- #
59
- def upload(operations, is_last_request = false)
60
- check_status()
61
- @uploaded_bytes = @batch_job_utils.put_incremental_operations(
62
- operations, @upload_url, @uploaded_bytes, is_last_request)
63
- @finished = true if is_last_request
64
- end
65
-
66
- private
67
-
68
- def check_status()
69
- if @finished
70
- raise AdwordsApi::Errors::InvalidBatchJobOperationError,
71
- 'Cannot put new operations to completed incremental upload.'
72
- end
73
- end
74
- end
75
- end
@@ -1,41 +0,0 @@
1
- # Encoding: utf-8
2
- #
3
- # Copyright:: Copyright 2018, Google Inc. All Rights Reserved.
4
- #
5
- # License:: Licensed under the Apache License, Version 2.0 (the "License");
6
- # you may not use this file except in compliance with the License.
7
- # You may obtain a copy of the License at
8
- #
9
- # http://www.apache.org/licenses/LICENSE-2.0
10
- #
11
- # Unless required by applicable law or agreed to in writing, software
12
- # distributed under the License is distributed on an "AS IS" BASIS,
13
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14
- # implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- #
18
- # Base class with common methods used across both report and service queries.
19
-
20
- require 'adwords_api/query_utils/where_builder'
21
-
22
- module AdwordsApi
23
- class QueryBuilder
24
- def initialize(api)
25
- @api = api
26
- @where = []
27
- end
28
-
29
- def where(field)
30
- clause = WhereBuilder.new(field)
31
- @where << clause
32
- return clause
33
- end
34
-
35
- def build_where()
36
- return '' if @where.empty?
37
- wheres = @where.map {|w| w.awql}
38
- return sprintf(' WHERE %s', wheres.join(' AND '))
39
- end
40
- end
41
- end
@@ -1,30 +0,0 @@
1
- # Encoding: utf-8
2
- #
3
- # Copyright:: Copyright 2018, Google Inc. All Rights Reserved.
4
- #
5
- # License:: Licensed under the Apache License, Version 2.0 (the "License");
6
- # you may not use this file except in compliance with the License.
7
- # You may obtain a copy of the License at
8
- #
9
- # http://www.apache.org/licenses/LICENSE-2.0
10
- #
11
- # Unless required by applicable law or agreed to in writing, software
12
- # distributed under the License is distributed on an "AS IS" BASIS,
13
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14
- # implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- #
18
- # Class to hold a generated AWQL query for reports.
19
-
20
- module AdwordsApi
21
- class ReportQuery
22
- def initialize(query)
23
- @query = query
24
- end
25
-
26
- def to_s()
27
- return @query
28
- end
29
- end
30
- end