class BingAdsApi::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:
BingAdsApi
object -
version: API version to use
# File lib/bing_ads_api/report_utils.rb, line 17 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:
-
BingAdsApi::Errors::InvalidReportDefinitionError
if the report definition is invalid -
BingAdsApi::Errors::ReportError
if server-side error occurred
# File lib/bing_ads_api/report_utils.rb, line 35 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:
-
BingAdsApi::Errors::InvalidReportDefinitionError
if the report definition is invalid -
BingAdsApi::Errors::ReportError
if server-side error occurred
# File lib/bing_ads_api/report_utils.rb, line 54 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
Private Instance Methods
Adds fields order hint to generator based on specification.
# File lib/bing_ads_api/report_utils.rb, line 183 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/bing_ads_api/report_utils.rb, line 126 def check_for_errors(response) # Check for error in body. report_body = response.body if report_body and ((RUBY_VERSION < '1.9.1') or report_body.valid_encoding?) error_message_regex = '^!!!(-?\d+)\|\|\|(-?\d+)\|\|\|(.*)\?\?\?' data = report_body.slice(0, 1024) matches = data.match(error_message_regex) if matches message = (matches[3].nil?) ? data : matches[3] raise BingAdsApi::Errors::ReportError.new(response.code, 'Report download error occured: %s' % message) end end # Check for error code. unless response.code == 200 raise BingAdsApi::Errors::ReportError.new(response.code, 'Report download error occured, http code: %d, body: %s' % [response.code, response.body]) end return nil end
Checks if the report definition looks correct.
# File lib/bing_ads_api/report_utils.rb, line 157 def check_report_definition_hash(report_definition) # Minimal set of fields required. REQUIRED_FIELDS.each do |field| unless report_definition.include?(field) raise BingAdsApi::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 BingAdsApi::Errors::InvalidReportDefinitionError, 'Fields list is required' end # 'Fields' must be an Array. unless report_definition[:selector][:fields].kind_of?(Array) raise BingAdsApi::Errors::InvalidReportDefinitionError, 'Fields list must be an array' end # We should request at least one field. if report_definition[:selector][:fields].empty? raise BingAdsApi::Errors::InvalidReportDefinitionError, 'At least one field needs to be requested' end end
Converts passed object to XML text. Currently support String (no changes) and Hash (renders XML).
# File lib/bing_ads_api/report_utils.rb, line 92 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 BingAdsApi::Errors::InvalidReportDefinitionError, 'Unknown object for report definition: %s' % report_definition.class end end
Prepares headers for report request.
# File lib/bing_ads_api/report_utils.rb, line 104 def get_report_request_headers(url, cid) @header_handler ||= BingAdsApi::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/bing_ads_api/report_utils.rb, line 78 def get_report_response(report_definition, cid) definition_text = get_report_definition_text(report_definition) data = '__rdxml=%s' % CGI.escape(definition_text) url = @api.api_config.adhoc_report_download_url( @api.config.read('service.environment'), @version) headers = get_report_request_headers(url, cid) log_request(url, headers, definition_text) response = AdsCommonForBingAds::Http.post_response(url, data, @api.config, headers) check_for_errors(response) return response end
Logs the request on debug level.
# File lib/bing_ads_api/report_utils.rb, line 116 def log_request(url, headers, body) logger = @api.logger logger.debug("Report request to: '%s'" % url) logger.debug('HTTP headers: [%s]' % (headers.map { |k, v| [k, v].join(': ') }.join(', '))) logger.debug(body) end
Renders a report definition hash into XML text.
# File lib/bing_ads_api/report_utils.rb, line 150 def report_definition_to_xml(report_definition) check_report_definition_hash(report_definition) add_report_definition_hash_order(report_definition) return Gyoku.xml({:report_definition => report_definition}) end
Saves raw data to a file.
# File lib/bing_ads_api/report_utils.rb, line 111 def save_to_file(data, path) open(path, 'wb') { |file| file.write(data) } if path end