line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Business::SiteCatalyst; |
2
|
|
|
|
|
|
|
|
3
|
16
|
|
|
16
|
|
654347
|
use strict; |
|
16
|
|
|
|
|
41
|
|
|
16
|
|
|
|
|
597
|
|
4
|
16
|
|
|
16
|
|
89
|
use warnings; |
|
16
|
|
|
|
|
35
|
|
|
16
|
|
|
|
|
416
|
|
5
|
|
|
|
|
|
|
|
6
|
16
|
|
|
16
|
|
17160
|
use Data::Dumper; |
|
16
|
|
|
|
|
153722
|
|
|
16
|
|
|
|
|
1284
|
|
7
|
16
|
|
|
16
|
|
152
|
use Carp; |
|
16
|
|
|
|
|
30
|
|
|
16
|
|
|
|
|
1056
|
|
8
|
16
|
|
|
16
|
|
20728
|
use LWP::UserAgent qw(); |
|
16
|
|
|
|
|
921879
|
|
|
16
|
|
|
|
|
482
|
|
9
|
16
|
|
|
16
|
|
193
|
use HTTP::Request qw(); |
|
16
|
|
|
|
|
34
|
|
|
16
|
|
|
|
|
257
|
|
10
|
16
|
|
|
16
|
|
19737
|
use JSON qw(); |
|
16
|
|
|
|
|
245472
|
|
|
16
|
|
|
|
|
493
|
|
11
|
16
|
|
|
16
|
|
162
|
use Digest::MD5 qw(); |
|
16
|
|
|
|
|
35
|
|
|
16
|
|
|
|
|
310
|
|
12
|
16
|
|
|
16
|
|
15600
|
use POSIX qw(); |
|
16
|
|
|
|
|
123572
|
|
|
16
|
|
|
|
|
544
|
|
13
|
16
|
|
|
16
|
|
14764
|
use Digest::SHA1 qw(); |
|
16
|
|
|
|
|
17710
|
|
|
16
|
|
|
|
|
449
|
|
14
|
16
|
|
|
16
|
|
14632
|
use MIME::Base64 qw(); |
|
16
|
|
|
|
|
12421
|
|
|
16
|
|
|
|
|
723
|
|
15
|
|
|
|
|
|
|
|
16
|
16
|
|
|
16
|
|
10602
|
use Business::SiteCatalyst::Company; |
|
16
|
|
|
|
|
44
|
|
|
16
|
|
|
|
|
487
|
|
17
|
16
|
|
|
16
|
|
10727
|
use Business::SiteCatalyst::Report; |
|
16
|
|
|
|
|
43
|
|
|
16
|
|
|
|
|
15160
|
|
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
# Some API methods return strings or numbers rather than valid JSON. |
21
|
|
|
|
|
|
|
# This list is used to return the raw response to the caller instead of decoding output as JSON |
22
|
|
|
|
|
|
|
my %METHODS_RETURNING_INVALID_JSON = |
23
|
|
|
|
|
|
|
( |
24
|
|
|
|
|
|
|
'Company.GetEndpoint' => 1, # Returns string |
25
|
|
|
|
|
|
|
'Company.GetTokenCount' => 1, # Returns number |
26
|
|
|
|
|
|
|
'Report.CancelReport' => 1, # Returns number |
27
|
|
|
|
|
|
|
); |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
=head1 NAME |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
Business::SiteCatalyst - Interface to Adobe Omniture SiteCatalyst's REST API. |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
=head1 VERSION |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
Version 1.2.2 |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
=cut |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
our $VERSION = '1.2.2'; |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
=head1 SYNOPSIS |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
This module allows you to interact with Adobe (formerly Omniture) SiteCatalyst, |
47
|
|
|
|
|
|
|
a web analytics service. It encapsulates all the communications with the API |
48
|
|
|
|
|
|
|
provided by Adobe SiteCatalyst to offer a Perl interface for managing reports, |
49
|
|
|
|
|
|
|
pulling company-specific SiteCatalyst data (ex: token usage), uploading SAINT |
50
|
|
|
|
|
|
|
data (feature not implemented yet), etc. |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
Please note that you will need to have purchased the Adobe SiteCatalyst product, |
53
|
|
|
|
|
|
|
and have web services enabled within your account first in order to obtain a web |
54
|
|
|
|
|
|
|
services shared secret, as well as agree with the Terms and Conditions for using |
55
|
|
|
|
|
|
|
the API. |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
NOTE: the 'api_subdomain' option/config variable is utilized for the api url. |
58
|
|
|
|
|
|
|
To determine your specific API URL/Endpoint, please visit |
59
|
|
|
|
|
|
|
https://developer.omniture.com/en_US/get-started/api-explorer |
60
|
|
|
|
|
|
|
Most users won't need to set this variable unless the default causes errors. |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
API URL: 'https://' . $api_subdomain . '.omniture.com/admin/1.3/rest/?' |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
use Business::SiteCatalyst; |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
# Create an object to communicate with Adobe SiteCatalyst |
68
|
|
|
|
|
|
|
my $site_catalyst = Business::SiteCatalyst->new( |
69
|
|
|
|
|
|
|
username => 'dummyusername', |
70
|
|
|
|
|
|
|
shared_secret => 'dummysecret', |
71
|
|
|
|
|
|
|
api_subdomain => 'api|api2', #optional; default value='api' |
72
|
|
|
|
|
|
|
); |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
=head1 METHODS |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
=head2 new() |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
Create a new Adobe SiteCatalyst object that will be used as the interface with |
80
|
|
|
|
|
|
|
Adobe SiteCatalyst's API |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
use Business::SiteCatalyst; |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
# Create an object to communicate with Adobe SiteCatalyst |
85
|
|
|
|
|
|
|
my $site_catalyst = Business::SiteCatalyst->new( |
86
|
|
|
|
|
|
|
username => 'dummyusername', |
87
|
|
|
|
|
|
|
shared_secret => 'dummysecret', |
88
|
|
|
|
|
|
|
api_subdomain => 'api|api2', #optional; default value='api' |
89
|
|
|
|
|
|
|
); |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
Creates a new object to communicate with Adobe SiteCatalyst. |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
'username' and 'shared_secret' are mandatory. |
94
|
|
|
|
|
|
|
The 'verbose' parameter is optional and defaults to not verbose. |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
=cut |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
sub new |
99
|
|
|
|
|
|
|
{ |
100
|
3
|
|
|
3
|
1
|
39
|
my ( $class, %args ) = @_; |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
# Check for mandatory parameters |
103
|
3
|
|
|
|
|
10
|
foreach my $arg ( qw( username shared_secret ) ) |
104
|
|
|
|
|
|
|
{ |
105
|
6
|
50
|
33
|
|
|
49
|
croak "Argument '$arg' is needed to create the Business::SiteCatalyst object" |
106
|
|
|
|
|
|
|
if !defined( $args{$arg} ) || ( $args{$arg} eq '' ); |
107
|
|
|
|
|
|
|
} |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
#Defaults. |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
# NOTE - some users connect to api2.omniture.com, so the subdomain portion of the host is configurable |
112
|
|
|
|
|
|
|
# in the 'api_subdomain' config variable in SiteCatalystConfig.pm |
113
|
3
|
50
|
|
|
|
22
|
my $webservice_url = 'https://' . |
114
|
|
|
|
|
|
|
( defined $args{'api_subdomain'} ? $args{'api_subdomain'} : 'api' ) . |
115
|
|
|
|
|
|
|
'.omniture.com/admin/1.3/rest/?method='; |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
# Create the object |
118
|
3
|
|
|
|
|
18
|
my $self = bless( |
119
|
|
|
|
|
|
|
{ |
120
|
|
|
|
|
|
|
username => $args{'username'}, |
121
|
|
|
|
|
|
|
shared_secret => $args{'shared_secret'}, |
122
|
|
|
|
|
|
|
webservice_url => $webservice_url, |
123
|
|
|
|
|
|
|
}, |
124
|
|
|
|
|
|
|
$class, |
125
|
|
|
|
|
|
|
); |
126
|
|
|
|
|
|
|
|
127
|
3
|
|
|
|
|
16
|
$self->verbose( $args{'verbose'} ); |
128
|
|
|
|
|
|
|
|
129
|
3
|
|
|
|
|
13
|
return $self; |
130
|
|
|
|
|
|
|
} |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
=head2 instantiate_report() |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
Create a new Business::SiteCatalyst::Report object, which |
136
|
|
|
|
|
|
|
will allow retrieval of SiteCatalyst reports. |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
# Create a new report |
139
|
|
|
|
|
|
|
my $report = $site_catalyst->instantiate_report( |
140
|
|
|
|
|
|
|
type => 'report type', |
141
|
|
|
|
|
|
|
report_suite_id => 'report suite id', |
142
|
|
|
|
|
|
|
); |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
# Act on an existing report |
145
|
|
|
|
|
|
|
my $report = $site_catalyst->instantiate_report( |
146
|
|
|
|
|
|
|
report_id => 'report id', |
147
|
|
|
|
|
|
|
); |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
Parameters: |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
=over 4 |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
=item * type |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
The type of the report to instantiate. |
157
|
|
|
|
|
|
|
Acceptable values are 'Overtime', 'Ranked', and 'Trended'. |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
=item * report_suite_id |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
The Report Suite ID you want to pull data from. |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
=item * report_id |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
The id of the existing report you want to check status of, retrieve results for, |
166
|
|
|
|
|
|
|
or cancel processing. |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
=back |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
=cut |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
sub instantiate_report |
173
|
|
|
|
|
|
|
{ |
174
|
1
|
|
|
1
|
1
|
8
|
my ( $self, %args ) = @_; |
175
|
|
|
|
|
|
|
|
176
|
1
|
|
|
|
|
10
|
return Business::SiteCatalyst::Report->new( $self, %args ); |
177
|
|
|
|
|
|
|
} |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
=head2 instantiate_company() |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
Create a new Business::SiteCatalyst::Company object, which |
184
|
|
|
|
|
|
|
will allow retrieval of company-specific SiteCatalyst data. |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
my $company = $site_catalyst->instantiate_company(); |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
Parameters: none |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
=cut |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
sub instantiate_company |
194
|
|
|
|
|
|
|
{ |
195
|
1
|
|
|
1
|
1
|
7
|
my ( $self, %args ) = @_; |
196
|
|
|
|
|
|
|
|
197
|
1
|
|
|
|
|
11
|
return Business::SiteCatalyst::Company->new( $self, %args ); |
198
|
|
|
|
|
|
|
} |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
=head1 INTERNAL METHODS |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
=head2 send_request() |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
Internal, formats the JSON call with the arguments provided and checks the |
206
|
|
|
|
|
|
|
reply. |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
my ( $error, $response_data ) = $site_catalyst->send_request( |
209
|
|
|
|
|
|
|
method => $method, |
210
|
|
|
|
|
|
|
data => $data, |
211
|
|
|
|
|
|
|
); |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
=cut |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
sub send_request |
216
|
|
|
|
|
|
|
{ |
217
|
0
|
|
|
0
|
1
|
0
|
my ( $self, %args ) = @_; |
218
|
|
|
|
|
|
|
|
219
|
0
|
|
|
|
|
0
|
my $verbose = $self->verbose(); |
220
|
0
|
|
|
|
|
0
|
my $url = $self->{'webservice_url'} . $args{'method'}; |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
# Check for mandatory parameters |
223
|
0
|
|
|
|
|
0
|
foreach my $arg ( qw( method data ) ) |
224
|
|
|
|
|
|
|
{ |
225
|
0
|
0
|
0
|
|
|
0
|
croak "Argument '$arg' is needed to send a request with the Business::SiteCatalyst object" |
226
|
|
|
|
|
|
|
if !defined( $args{$arg} ) || ( $args{$arg} eq '' ); |
227
|
|
|
|
|
|
|
} |
228
|
|
|
|
|
|
|
|
229
|
0
|
|
|
|
|
0
|
my $json_in = JSON::encode_json( $args{'data'} ); |
230
|
0
|
0
|
|
|
|
0
|
carp "Sending JSON request >" . ( defined( $json_in ) ? $json_in : '' ) . "<" |
|
|
0
|
|
|
|
|
|
231
|
|
|
|
|
|
|
if $verbose; |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
# Authentication information for header. |
234
|
0
|
|
|
|
|
0
|
my $username = $self->{'username'}; |
235
|
0
|
|
|
|
|
0
|
my $nonce = Digest::MD5::md5_hex( rand() * time() ); |
236
|
0
|
|
|
|
|
0
|
chomp($nonce); |
237
|
|
|
|
|
|
|
|
238
|
0
|
|
|
|
|
0
|
my $created = POSIX::strftime("%Y-%m-%dT%H:%M:%S", gmtime()); |
239
|
0
|
|
|
|
|
0
|
my $password_digest = MIME::Base64::encode_base64( |
240
|
|
|
|
|
|
|
Digest::SHA1::sha1_hex( $nonce . $created . $self->{'shared_secret'} ) |
241
|
|
|
|
|
|
|
); |
242
|
0
|
|
|
|
|
0
|
chomp($password_digest); |
243
|
|
|
|
|
|
|
|
244
|
0
|
|
|
|
|
0
|
my $request = HTTP::Request->new(POST => $url); |
245
|
0
|
0
|
|
|
|
0
|
carp "POSTing request to URL >" . ( defined( $url ) ? $url : '' ) . "<" |
|
|
0
|
|
|
|
|
|
246
|
|
|
|
|
|
|
if $verbose; |
247
|
0
|
|
|
|
|
0
|
my $auth_header = qq|UsernameToken Username="$username", PasswordDigest="$password_digest", Nonce="$nonce", Created="$created"|; |
248
|
0
|
0
|
|
|
|
0
|
carp "Auth header: >$auth_header<" if $verbose; |
249
|
|
|
|
|
|
|
|
250
|
0
|
|
|
|
|
0
|
$request->header('X-WSSE', $auth_header); |
251
|
|
|
|
|
|
|
|
252
|
0
|
|
|
|
|
0
|
$request->content_type('application/json'); |
253
|
0
|
|
|
|
|
0
|
$request->content( $json_in ); |
254
|
|
|
|
|
|
|
|
255
|
0
|
|
|
|
|
0
|
my $user_agent = LWP::UserAgent->new(); |
256
|
0
|
|
|
|
|
0
|
my $response = $user_agent->request($request); |
257
|
|
|
|
|
|
|
|
258
|
0
|
0
|
|
|
|
0
|
croak "Request failed:" . $response->status_line() |
259
|
|
|
|
|
|
|
if !$response->is_success(); |
260
|
|
|
|
|
|
|
|
261
|
0
|
0
|
|
|
|
0
|
carp "Response >" . ( defined( $response ) ? $response->content() : '' ) . "<" |
|
|
0
|
|
|
|
|
|
262
|
|
|
|
|
|
|
if $verbose; |
263
|
|
|
|
|
|
|
|
264
|
0
|
|
|
|
|
0
|
my $json_out; |
265
|
|
|
|
|
|
|
|
266
|
0
|
0
|
|
|
|
0
|
if ( exists( $METHODS_RETURNING_INVALID_JSON{ $args{'method'} } ) ) |
267
|
|
|
|
|
|
|
{ |
268
|
0
|
|
|
|
|
0
|
$json_out = $response->content(); |
269
|
|
|
|
|
|
|
} |
270
|
|
|
|
|
|
|
else |
271
|
|
|
|
|
|
|
{ |
272
|
0
|
|
|
|
|
0
|
$json_out = JSON::decode_json( $response->content() ); |
273
|
|
|
|
|
|
|
} |
274
|
|
|
|
|
|
|
|
275
|
0
|
0
|
|
|
|
0
|
carp "JSON Response >" . ( defined( $json_out ) ? Dumper($json_out) : '' ) . "<" |
|
|
0
|
|
|
|
|
|
276
|
|
|
|
|
|
|
if $verbose; |
277
|
|
|
|
|
|
|
|
278
|
0
|
|
|
|
|
0
|
return $json_out; |
279
|
|
|
|
|
|
|
} |
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
=head2 verbose() |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
Control the verbosity of the debugging output. |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
$site_catalyst->verbose( 1 ); # turn on verbose information |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
$site_catalyst->verbose( 0 ); # quiet! |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
warn 'Verbose' if $site_catalyst->verbose(); # getter-style |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
=cut |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
sub verbose |
295
|
|
|
|
|
|
|
{ |
296
|
3
|
|
|
3
|
1
|
13
|
my ( $self, $verbose ) = @_; |
297
|
|
|
|
|
|
|
|
298
|
3
|
50
|
0
|
|
|
15
|
$self->{'verbose'} = ( $verbose || 0 ) |
299
|
|
|
|
|
|
|
if defined( $verbose ); |
300
|
|
|
|
|
|
|
|
301
|
3
|
|
|
|
|
19
|
return $self->{'verbose'}; |
302
|
|
|
|
|
|
|
} |
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
=head1 RUNNING TESTS |
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
By default, only basic tests that do not require a connection to Adobe |
308
|
|
|
|
|
|
|
SiteCatalyst's platform are run in t/. |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
To run the developer tests, you will need to do the following: |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
=over 4 |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
=item * |
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
Request access to Adobe web services from your Adobe Online Marketing Suite administrator. |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
=item * |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
In Adobe SiteCatalyst's interface, you will need to log in as an admin, then go |
321
|
|
|
|
|
|
|
to the "Admin" tab, "Admin Console > Company > Web Services". There you can find |
322
|
|
|
|
|
|
|
your "shared secret" for your username. |
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
=item * |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
Your report suite IDs can be found in Adobe SiteCatalyst's interface. Visit |
327
|
|
|
|
|
|
|
"Admin > Admin Console > Report Suites". |
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
=back |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
You can now create a file named SiteCatalystConfig.pm in your own directory, with |
332
|
|
|
|
|
|
|
the following content: |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
package Adobe SiteCatalystConfig; |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
sub new |
337
|
|
|
|
|
|
|
{ |
338
|
|
|
|
|
|
|
return |
339
|
|
|
|
|
|
|
{ |
340
|
|
|
|
|
|
|
username => 'username', |
341
|
|
|
|
|
|
|
shared_secret => 'shared_secret', |
342
|
|
|
|
|
|
|
report_suite_id => 'report_suite_id', |
343
|
|
|
|
|
|
|
api_subdomain => 'api|api2', #optional. default='api' |
344
|
|
|
|
|
|
|
verbose => 0, # Enable this for debugging output |
345
|
|
|
|
|
|
|
}; |
346
|
|
|
|
|
|
|
} |
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
1; |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
You will then be able to run all the tests included in this distribution, after |
351
|
|
|
|
|
|
|
adding the path to Adobe SiteCatalystConfig.pm to your library paths. |
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
=head1 AUTHOR |
355
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
Jennifer Pinkham, C<< >>. |
357
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
=head1 BUGS |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
Please report any bugs or feature requests to C, |
362
|
|
|
|
|
|
|
or through the web interface at L. |
363
|
|
|
|
|
|
|
I will be notified, and then you'll automatically be notified of progress on |
364
|
|
|
|
|
|
|
your bug as I make changes. |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
=head1 SUPPORT |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
You can find documentation for this module with the perldoc command. |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
perldoc Business::SiteCatalyst |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
You can also look for information at: |
375
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
=over 4 |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
=item * RT: CPAN's request tracker |
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
L |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
=item * AnnoCPAN: Annotated CPAN documentation |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
L |
385
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
=item * CPAN Ratings |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
L |
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
=item * Search CPAN |
391
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
L |
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
=back |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
=head1 ACKNOWLEDGEMENTS |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
Thanks to ThinkGeek (L) and its corporate overlords |
400
|
|
|
|
|
|
|
at Geeknet (L), for footing the bill while I write code for them! |
401
|
|
|
|
|
|
|
Special thanks for technical help from fellow ThinkGeek CPAN author Guillaume Aubert L |
402
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
|
404
|
|
|
|
|
|
|
=head1 COPYRIGHT & LICENSE |
405
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
Copyright 2013 Jennifer Pinkham. |
407
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it |
409
|
|
|
|
|
|
|
under the terms of the Artistic License. |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
See http://dev.perl.org/licenses/ for more information. |
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
=cut |
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
1; |