File Coverage

lib/Google/Ads/Common/ReportUtils.pm
Criterion Covered Total %
statement 57 104 54.8
branch 0 40 0.0
condition 0 6 0.0
subroutine 19 22 86.3
pod 1 1 100.0
total 77 173 44.5


line stmt bran cond sub pod time code
1             # Copyright 2011, Google Inc. All Rights Reserved.
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             package Google::Ads::Common::ReportUtils;
16              
17 1     1   694 use strict;
  1         2  
  1         23  
18 1     1   4 use warnings;
  1         1  
  1         19  
19 1     1   5 use utf8;
  1         1  
  1         7  
20 1     1   17 use version;
  1         2  
  1         7  
21              
22 1     1   276 use Google::Ads::AdWords::Logging;
  1         3  
  1         35  
23 1     1   486 use Google::Ads::AdWords::Reports::ReportingConfiguration;
  1         3  
  1         35  
24              
25             # The following needs to be on one line because CPAN uses a particularly hacky
26             # eval() to determine module versions.
27 1     1   6 use Google::Ads::Common::Constants; our $VERSION = ${Google::Ads::Common::Constants::VERSION};
  1         2  
  1         49  
28              
29 1     1   273 use Google::Ads::Common::ReportDownloadError;
  1         2  
  1         30  
30 1     1   258 use Google::Ads::Common::ReportDownloadHandler;
  1         5  
  1         49  
31              
32 1     1   10 use File::stat;
  1         3  
  1         11  
33 1     1   75 use HTTP::Request;
  1         52  
  1         40  
34 1     1   5 use HTTP::Status qw(:constants);
  1         2  
  1         356  
35 1     1   6 use Log::Log4perl qw(:levels);
  1         1  
  1         9  
36 1     1   112 use LWP::UserAgent;
  1         2  
  1         20  
37 1     1   5 use MIME::Base64;
  1         1  
  1         39  
38 1     1   7 use POSIX;
  1         2  
  1         6  
39 1     1   1819 use Time::HiRes qw(gettimeofday tv_interval);
  1         2  
  1         11  
40 1     1   92 use URI::Escape;
  1         1  
  1         48  
41 1     1   5 use XML::Simple;
  1         1  
  1         6  
42              
43             # Prepares and returns a Google::Ads::Common::ReportDownloadHandler.
44             sub get_report_handler {
45 0     0 1   my ($report_definition, $client, $server, $timeout) = @_;
46              
47 0           my $prepared_data =
48             __prepare_request($report_definition, $client, $server, $timeout);
49              
50             return Google::Ads::Common::ReportDownloadHandler->new({
51             client => $client,
52             __user_agent => $prepared_data->{lwp},
53             __http_request => $prepared_data->{request},
54             download_format => $prepared_data->{format},
55 0           });
56             }
57              
58             # Creates and properly configures an LWP::UserAgent and HTTP::Request
59             # for the specified parameters. Returns a hash with the keys: lwp,
60             # request, format.
61             sub __prepare_request {
62 0     0     my ($report_definition, $client, $server, $timeout) = @_;
63              
64             # Build report download url.
65 0 0         $server = $server ? $server : $client->get_alternate_url();
66 0 0         $server = $server =~ /\/$/ ? substr($server, 0, -1) : $server;
67 0           my $url;
68              
69 0           $url = sprintf(Google::Ads::AdWords::Constants::ADHOC_REPORT_DOWNLOAD_URL,
70             $server, $client->get_version());
71              
72 0           my $lwp = LWP::UserAgent->new();
73              
74             # Set agent timeout.
75 0 0         $lwp->timeout(
76             $timeout
77             ? $timeout
78             : Google::Ads::AdWords::Constants::LWP_DEFAULT_TIMEOUT
79             );
80              
81             # Set the authorization headers.
82 0           my @headers = ();
83              
84 0           my $auth_handler = $client->_get_auth_handler();
85              
86 0 0         if ($auth_handler->isa("Google::Ads::Common::OAuth2BaseHandler")) {
87             # In this case we use the client OAuth2
88 0           push @headers,
89             "Authorization" => "Bearer " . $auth_handler->get_access_token();
90             } else {
91 0           my $handler_warning = "The authorization handler is not supported.";
92 0 0         if ($client->get_die_on_faults()) {
93 0           die($handler_warning);
94             } else {
95 0           warn($handler_warning);
96             }
97             }
98              
99 0           my $current_version = $client->get_version();
100 0           $current_version =~ s/[^0-9]//g;
101 0 0         if ($client->get_client_id()) {
102 0           push @headers, "clientCustomerId" => $client->get_client_id();
103             }
104              
105             # Set reporting configuration headers.
106 0           my $reporting_config = $client->get_reporting_config();
107 0 0 0       if (
      0        
108             $reporting_config
109             and (defined $reporting_config->get_skip_header()
110             or defined $reporting_config->get_skip_column_header()
111             or defined $reporting_config->get_skip_summary()
112             or defined $reporting_config->get_include_zero_impressions()
113             or defined $reporting_config->get_use_raw_enum_values()))
114             {
115 0 0         if (defined $reporting_config->get_skip_header()) {
116 0 0         push @headers,
117             "skipReportHeader" => $reporting_config->get_skip_header()
118             ? "true"
119             : "false";
120             }
121 0 0         if (defined $reporting_config->get_skip_column_header()) {
122 0 0         push @headers,
123             "skipColumnHeader" => $reporting_config->get_skip_column_header()
124             ? "true"
125             : "false";
126             }
127 0 0         if (defined $reporting_config->get_skip_summary()) {
128 0 0         push @headers,
129             "skipReportSummary" => $reporting_config->get_skip_summary()
130             ? "true"
131             : "false";
132             }
133 0 0         if (defined $reporting_config->get_include_zero_impressions()) {
134 0 0         push @headers, "includeZeroImpressions" =>
135             $reporting_config->get_include_zero_impressions() ? "true" : "false";
136             }
137 0 0         if (defined $reporting_config->get_use_raw_enum_values()) {
138 0 0         push @headers,
139             "useRawEnumValues" => $reporting_config->get_use_raw_enum_values()
140             ? "true"
141             : "false";
142             }
143             }
144 0           push @headers, "developerToken" => $client->get_developer_token();
145              
146             # Read proxy configuration for the enviroment.
147 0           $lwp->env_proxy();
148              
149             # Prepare the request.
150 0           my $request;
151             my $format;
152 0 0         if (ref($report_definition) eq "HASH") {
153 0           push @headers, "Content-Type" => "application/x-www-form-urlencoded";
154             $request = HTTP::Request->new("POST", $url, \@headers,
155             "__rdquery=" . uri_escape_utf8($report_definition->{query}) . "&__fmt=" .
156 0           uri_escape_utf8($report_definition->{format}));
157 0           $format = $report_definition->{format};
158             } else {
159 0           push @headers, "Content-Type" => "application/x-www-form-urlencoded";
160 0           $request = HTTP::Request->new(
161             "POST", $url,
162             \@headers,
163             "__rdxml=" .
164             uri_escape_utf8(
165             "" . $report_definition . ""
166             ));
167 0           $format = $report_definition->get_downloadFormat() . "";
168             }
169              
170             return {
171 0           lwp => $lwp,
172             request => $request,
173             format => $format
174             };
175             }
176              
177             sub __extract_xml_error {
178 0     0     my $ref = XML::Simple->new()->XMLin(shift, ForceContent => 1);
179              
180             return Google::Ads::Common::ReportDownloadError->new({
181             type => $ref->{ApiError}->{type}->{content},
182             field_path => $ref->{ApiError}->{fieldPath}->{content}
183             ? $ref->{ApiError}->{fieldPath}->{content}
184             : "",
185             trigger => $ref->{ApiError}->{trigger}->{content}
186             ? $ref->{ApiError}->{trigger}->{content}
187 0 0         : ""
    0          
188             });
189             }
190              
191             return 1;
192              
193             =pod
194              
195             =head1 NAME
196              
197             Google::Ads::Common::ReportUtils
198              
199             =head1 SYNOPSIS
200              
201             use Google::Ads::Common::ReportUtils;
202              
203             my $response =
204             Google::Ads::Common::ReportUtils::get_report_handler($report_definition,
205             $client);
206             my $result = $response->save($outputfile);
207             if (!$result) {
208             printf("An error has occurred of type '%s', triggered by '%s'.\n",
209             $result->get_type(), $result->get_trigger());
210             }
211              
212             =head1 DESCRIPTION
213              
214             Google::Ads::Common::ReportUtils a collection of utility methods for working
215             with reports.
216              
217             =head1 SUBROUTINES
218              
219             =head2 get_report_handler
220              
221             Prepares a new instance of L using
222             the specified parameters. The actual download of report contents will not be
223             invoked by this procedure, but instead will occur when you call one of the
224             procedures on the returned handler to save the report to a file, get its
225             contents as a string, etc.
226              
227             =head3 Parameters
228              
229             =over
230              
231             =item *
232              
233             The report_definition parameter is either:
234              
235             =over
236              
237             =item *
238              
239             A C object to be defined and downloaded on the fly OR
240              
241             =item *
242              
243             A hash with an AWQL query and format. i.e.
244              
245             { query => 'query',
246             format => 'format' }
247              
248             =back
249              
250             =item *
251              
252             The client parameter is an instance of a valid L.
253              
254             =item *
255              
256             The server is an optional parameter that can be set to alter the URL from where
257             the report will be requested.
258              
259             =item *
260              
261             The timeout is an optional parameter that can be set to alter the default
262             time that the http client waits to get a response from the server. If not set,
263             the default timeout used is
264             L.
265              
266             =back
267              
268             =head3 Returns
269              
270             A new L. See the methods of
271             L that support different use
272             cases for processing the response's contents.
273              
274             =head1 LICENSE AND COPYRIGHT
275              
276             Copyright 2011 Google Inc.
277              
278             Licensed under the Apache License, Version 2.0 (the "License");
279             you may not use this file except in compliance with the License.
280             You may obtain a copy of the License at
281              
282             http://www.apache.org/licenses/LICENSE-2.0
283              
284             Unless required by applicable law or agreed to in writing, software
285             distributed under the License is distributed on an "AS IS" BASIS,
286             WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
287             See the License for the specific language governing permissions and
288             limitations under the License.
289              
290             =head1 REPOSITORY INFORMATION
291              
292             $Rev: $
293             $LastChangedBy: $
294             $Id: $
295              
296             =cut