class AdwordsApi::ReportUtils
Constants
- REPORT_DEFINITION_ORDER
Definition fields have to be in particular order in the XML. Here is its specification.
- REQUIRED_FIELDS
Minimal set of required fields for report definition.
Public Class Methods
Default constructor.
Args:
-
api:
AdwordsApi
object -
version: API version to use
# File lib/adwords_api/report_utils.rb, line 37 def initialize(api, version) @api, @version = api, version end
Public Instance Methods
Downloads and returns a report.
Args:
-
report_definition: definition of the report in XML text or hash
-
cid: optional customer ID to run against
Returns:
-
report body
Raises:
-
AdwordsApi::Errors::InvalidReportDefinitionError
if the report definition is invalid -
AdwordsApi::Errors::ReportError
if server-side error occurred
# File lib/adwords_api/report_utils.rb, line 55 def download_report(report_definition, cid = nil) return get_report_response(report_definition, cid).body end
Downloads a report and saves it to a file.
Args:
-
report_definition: definition of the report in XML text or hash
-
path: path to save report to
-
cid: optional customer ID to run against
Returns:
-
nil
Raises:
-
AdwordsApi::Errors::InvalidReportDefinitionError
if the report definition is invalid -
AdwordsApi::Errors::ReportError
if server-side error occurred
# File lib/adwords_api/report_utils.rb, line 74 def download_report_as_file(report_definition, path, cid = nil) report_body = download_report(report_definition, cid) save_to_file(report_body, path) return nil end
Downloads a report with AWQL and saves it to a file.
Args:
-
report_query: query for the report as string
-
format: format for the report as string
-
path: path to save report to
-
cid: optional customer ID to run report against
Returns:
-
nil
Raises:
-
AdwordsApi::Errors::ReportError
if server-side error occurred
# File lib/adwords_api/report_utils.rb, line 150 def download_report_as_file_with_awql(report_query, format, path, cid = nil) report_body = download_report_with_awql(report_query, format, cid) save_to_file(report_body, path) return nil end
Streams a report as a string to the given block. This method will not do error checking on returned values.
Args:
-
report_definition: definition of the report in XML text or hash
-
path: path to save report to
-
cid: optional customer ID to run against
Returns:
-
nil
Raises:
-
AdwordsApi::Errors::InvalidReportDefinitionError
if the report definition is invalid
# File lib/adwords_api/report_utils.rb, line 95 def download_report_as_stream(report_definition, cid = nil, &block) return get_report_response(report_definition, cid, &block) end
Streams a report with AWQL as a string to the given block. This method will not do error checking on returned values.
Args:
-
report_query: query for the report as string
-
format: format for the report as string
-
cid: optional customer ID to run report against
Returns:
-
nil
# File lib/adwords_api/report_utils.rb, line 167 def download_report_as_stream_with_awql( report_query, format, cid = nil, &block) return get_report_response_with_awql(report_query, format, cid, &block) end
Downloads and returns a report with AWQL.
Args:
-
report_query: query for the report as string
-
format: format for the report as string
-
cid: optional customer ID to run report against
Returns:
-
report body
Raises:
-
AdwordsApi::Errors::ReportError
if a server-side error has occurred
# File lib/adwords_api/report_utils.rb, line 132 def download_report_with_awql(report_query, format, cid = nil) return get_report_response_with_awql(report_query, format, cid).body end
Returns a helper object that can manage breaking the streamed report results into individual lines.
Args:
-
report_definition: definition of the report in XML text or hash
-
path: path to save report to
-
cid: optional customer ID to run against
Returns:
-
ReportStream
object initialized to begin streaming.
Raises:
-
AdwordsApi::Errors::InvalidReportDefinitionError
if the report definition is invalid
# File lib/adwords_api/report_utils.rb, line 114 def get_stream_helper(report_definition, cid = nil) return AdwordsApi::ReportStream.set_up( self, report_definition, cid) end
Returns a helper object that can manage breaking the streamed report results into individual lines.
Args:
-
report_query: query for the report as string
-
format: format for the report as string
-
cid: optional customer ID to run report against
Returns:
-
ReportStream
object initialized to begin streaming.
# File lib/adwords_api/report_utils.rb, line 183 def get_stream_helper_with_awql(report_query, format, cid = nil) return AdwordsApi::ReportStream.set_up_with_awql( self, report_query, format, cid) end
Private Instance Methods
Adds fields order hint to generator based on specification.
# File lib/adwords_api/report_utils.rb, line 350 def add_report_definition_hash_order(node, name = :root) def_order = REPORT_DEFINITION_ORDER[name] var_order = def_order.reject { |field| !node.include?(field) } node.keys.each do |key| if REPORT_DEFINITION_ORDER.include?(key) case node[key] when Hash add_report_definition_hash_order(node[key], key) when Array node[key].each do |item| add_report_definition_hash_order(item, key) end end end end node[:order!] = var_order return nil end
Checks downloaded data for error signature. Raises ReportError if it detects an error.
# File lib/adwords_api/report_utils.rb, line 279 def check_for_errors(response) # Check for error code. if response.code != 200 # Check for error in body. report_body = response.body check_for_xml_error(report_body, response.code) # No XML error found nor raised, falling back to a default message. raise AdwordsApi::Errors::ReportError.new(response.code, 'HTTP code: %d, body: %s' % [response.code, response.body]) end return nil end
Checks for an XML error in the response body and raises an exception if it was found.
# File lib/adwords_api/report_utils.rb, line 294 def check_for_xml_error(report_body, response_code) unless report_body.nil? error_response = get_nori().parse(report_body) if error_response.include?(:report_download_error) and error_response[:report_download_error].include?(:api_error) api_error = error_response[:report_download_error][:api_error] raise AdwordsApi::Errors::ReportXmlError.new(response_code, api_error[:type], api_error[:trigger], api_error[:field_path]) end end end
Checks if the report definition looks correct.
# File lib/adwords_api/report_utils.rb, line 324 def check_report_definition_hash(report_definition) # Minimal set of fields required. REQUIRED_FIELDS.each do |field| unless report_definition.include?(field) raise AdwordsApi::Errors::InvalidReportDefinitionError, "Required field '%s' is missing in the definition" % field end end # Fields list is also required. unless report_definition[:selector].include?(:fields) raise AdwordsApi::Errors::InvalidReportDefinitionError, 'Fields list is required' end # 'Fields' must be an Array. unless report_definition[:selector][:fields].kind_of?(Array) raise AdwordsApi::Errors::InvalidReportDefinitionError, 'Fields list must be an array' end # We should request at least one field. if report_definition[:selector][:fields].empty? raise AdwordsApi::Errors::InvalidReportDefinitionError, 'At least one field needs to be requested' end end
# File lib/adwords_api/report_utils.rb, line 369 def get_nori() return @nori if @nori nori_options = { :strip_namespaces => true, :convert_tags_to => lambda { |tag| tag.snakecase.to_sym }, :advanced_typecasting => false } @nori = Nori.new(nori_options) return @nori end
Converts passed object to XML text. Currently support String (no changes) and Hash (renders XML).
# File lib/adwords_api/report_utils.rb, line 241 def get_report_definition_text(report_definition) return case report_definition when String then report_definition when Hash then report_definition_to_xml(report_definition) else raise AdwordsApi::Errors::InvalidReportDefinitionError, 'Unknown object for report definition: %s' % report_definition.class end end
Prepares headers for report request.
# File lib/adwords_api/report_utils.rb, line 253 def get_report_request_headers(url, cid) @header_handler ||= AdwordsApi::ReportHeaderHandler.new( @api.credential_handler, @api.get_auth_handler(), @api.config) return @header_handler.headers(url, cid) end
Send POST request for a report and returns Response object.
# File lib/adwords_api/report_utils.rb, line 206 def get_report_response(report_definition, cid, &block) definition_text = get_report_definition_text(report_definition) data = '__rdxml=%s' % CGI.escape(definition_text) return make_adhoc_request(data, cid, &block) end
Send POST request for a report with AWQL and returns Response object.
# File lib/adwords_api/report_utils.rb, line 213 def get_report_response_with_awql(report_query, format, cid, &block) data = '__rdquery=%s&__fmt=%s' % [CGI.escape(report_query), CGI.escape(format)] return make_adhoc_request(data, cid, &block) end
Logs HTTP headers on debug level.
# File lib/adwords_api/report_utils.rb, line 272 def log_headers(headers) @api.logger.debug('HTTP headers: [%s]' % (headers.map { |k, v| [k, v].join(': ') }.join(', '))) end
Logs the request on debug level.
# File lib/adwords_api/report_utils.rb, line 265 def log_request(url, headers, body) @api.logger.debug("Report request to: '%s'" % url) log_headers(headers) @api.logger.debug(body) end
Makes request and AdHoc service and returns response.
# File lib/adwords_api/report_utils.rb, line 220 def make_adhoc_request(data, cid, &block) @api.utils_reporter.report_utils_used() url = @api.api_config.adhoc_report_download_url(@version) headers = get_report_request_headers(url, cid) log_request(url, headers, data) # A given block indicates that we should make a stream request and yield # the results, rather than return a full response. if block_given? AdsCommon::Http.post_stream(url, data, @api.config, headers, &block) return nil else response = AdsCommon::Http.post_response( url, data, @api.config, headers) log_headers(response.headers) check_for_errors(response) return response end end
Renders a report definition hash into XML text.
# File lib/adwords_api/report_utils.rb, line 307 def report_definition_to_xml(report_definition) check_report_definition_hash(report_definition) add_report_definition_hash_order(report_definition) begin return Gyoku.xml({:report_definition => report_definition}) rescue ArgumentError => e if e.message.include?("order!") unknown_fields = e.message.slice(e.message.index('['), e.message.length) raise AdwordsApi::Errors::InvalidReportDefinitionError, "Unknown report definition field(s): %s" % unknown_fields end raise e end end
Saves raw data to a file.
# File lib/adwords_api/report_utils.rb, line 260 def save_to_file(data, path) open(path, 'wb') { |file| file.write(data) } if path end