line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package WebService::Thumbalizr; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
68126
|
use 5.016003; |
|
1
|
|
|
|
|
4
|
|
4
|
1
|
|
|
1
|
|
6
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
19
|
|
5
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
23
|
|
6
|
|
|
|
|
|
|
|
7
|
1
|
|
|
1
|
|
692
|
use LWP::UserAgent; |
|
1
|
|
|
|
|
48724
|
|
|
1
|
|
|
|
|
38
|
|
8
|
1
|
|
|
1
|
|
9
|
use URI::Escape qw(uri_escape); |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
52
|
|
9
|
1
|
|
|
1
|
|
447
|
use Text::Trim; |
|
1
|
|
|
|
|
580
|
|
|
1
|
|
|
|
|
60
|
|
10
|
1
|
|
|
1
|
|
6
|
use Digest::MD5 qw(md5_hex); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
66
|
|
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0; |
13
|
1
|
|
|
1
|
|
805
|
use IO::Socket::SSL; |
|
1
|
|
|
|
|
84471
|
|
|
1
|
|
|
|
|
8
|
|
14
|
|
|
|
|
|
|
IO::Socket::SSL::set_ctx_defaults( |
15
|
|
|
|
|
|
|
SSL_verifycn_scheme => 'www', |
16
|
|
|
|
|
|
|
SSL_verify_mode => 0, |
17
|
|
|
|
|
|
|
verify_mode => 0, |
18
|
|
|
|
|
|
|
); |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
our $VERSION = '1.0.0'; |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
=head1 NAME |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
WebService::Thumbalizr - Perl extension for Thumbalizr (L), a web service to create screenshots of web pages. |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
=head1 SYNOPSIS |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
use WebService::Thumbalizr; |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
my $thumbalizr = WebService::Thumbalizr->new(key => 'my_key', secret => 'my_secret'); |
31
|
|
|
|
|
|
|
my $url = $thumbalizr->url('http://www.google.com/'); |
32
|
|
|
|
|
|
|
my ($status, $image) = $thumbalizr->download($url); |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
=head1 DESCRIPTION |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
Thumbalizr (L) is a web service to easily embed live screenshots of any URL in your website. Thumbalizr has full support for Flash, JavaScript, CSS, & HTML5. |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
The latest API version is detailed at L. |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
The source code is available on github at L. |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
=head1 METHODS |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
=over 4 |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
=head2 new() |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
my $thumbalizr = WebService::Thumbalizr->new((secret => 'my_secret', key => 'my_embed_key', debug => 1]); |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
Create a new WebService::Thumbalizr object. You must pass your API secret (login to your Thumbalizr account to display your secret). |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
Arguments: |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
=over 4 |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
=item key |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
Required. Embed API key. |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
=item secret |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
Required. Thumbalizr secret. |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
=item base |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
Optional. Base URL for all API requests. You should use the default base provided by the library. Be careful if you decide to use HTTP instead of HTTPS as your API key could be sniffed and your account could be used without your consent. |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
=item debug |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
Optional. Set to 1 to print debug output to the standard output. 0 (disabled) by default. |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
=item timeout |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
Optional. Set the request timeout - in seconds - against the API. Defaults to 90s. |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
=back |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
C contains the last error message, it is NEVER reset, i.e last_error may not be empty after a successful API call if an earlier call failed. |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
=cut |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
sub new { |
84
|
1
|
|
|
1
|
1
|
704
|
my ($self, %args) = @_; |
85
|
|
|
|
|
|
|
|
86
|
1
|
|
|
|
|
11
|
my $ua = LWP::UserAgent->new(); |
87
|
1
|
|
50
|
|
|
3267
|
$ua->timeout($args{'timeout'} || 90); |
88
|
1
|
|
|
|
|
24
|
$ua->env_proxy; |
89
|
1
|
|
|
|
|
14084
|
$ua->agent("WebService::Thumbalizr $VERSION"); |
90
|
1
|
|
|
|
|
101
|
$ua->ssl_opts( verify_hostnames => 0 ); |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
my $thumbalizr = { |
93
|
|
|
|
|
|
|
_key => trim $args{key} || '', |
94
|
|
|
|
|
|
|
_secret => trim $args{secret} || '', |
95
|
|
|
|
|
|
|
_base => $args{base} || 'https://api.thumbalizr.com/api/v1/', |
96
|
1
|
|
50
|
|
|
52
|
_debug => $args{debug} || 0, |
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
_retry => 2, |
99
|
|
|
|
|
|
|
last_error => '', |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
_ua => $ua, |
102
|
|
|
|
|
|
|
}; |
103
|
|
|
|
|
|
|
|
104
|
1
|
|
|
|
|
126
|
return bless($thumbalizr, $self); |
105
|
|
|
|
|
|
|
} |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
=head2 url() |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
my $thumbalizr = WebService::Thumbalizr->url($url, size => 'page, bwidth => 1280, bheight => 1024); |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
Return the Thumbalizr URL to retrieve the screenshot. See L for the full list of options |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
Arguments: |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
=over 4 |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
=item url |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
Required. URL of the website to create a screenshot of. |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
=back |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
=cut |
125
|
|
|
|
|
|
|
sub url { |
126
|
0
|
|
|
0
|
1
|
|
my ($self, $url, %args) = @_; |
127
|
|
|
|
|
|
|
|
128
|
0
|
|
|
|
|
|
my $api_key = uri_escape($self->{_key}, 1); |
129
|
|
|
|
|
|
|
|
130
|
0
|
|
|
|
|
|
my $query = 'url=' . uri_escape($url); |
131
|
|
|
|
|
|
|
|
132
|
0
|
|
|
|
|
|
foreach my $option (keys %args) { |
133
|
0
|
|
|
|
|
|
$query .= '&' . uri_escape(trim($option)) . '=' . uri_escape(trim $args{$option}); |
134
|
|
|
|
|
|
|
} |
135
|
|
|
|
|
|
|
|
136
|
0
|
|
|
|
|
|
my $token = md5_hex($query . $self->{_secret}); |
137
|
|
|
|
|
|
|
|
138
|
0
|
|
|
|
|
|
return $self->{_base} . "embed/$api_key/$token/?$query"; |
139
|
|
|
|
|
|
|
} |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
=head2 download() |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
my ($status, $image) = $thumbalizr->download($url); |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
Download a screenshot. Optionally, you can save the image directly to a file. |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
Return the status of the screenshot (OK, FAILED or QUEUED), and the image data or image file name. In case the screenshto is not finished, the image data will be empty. |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
Arguments: |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
=over 4 |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
=item |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
Required. Thumbalizr Embed URL generated by $tumbalizr->url |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
=item |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
Optional A local file name to save the image to. |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
=back |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
=cut |
164
|
|
|
|
|
|
|
sub download { |
165
|
0
|
|
|
0
|
1
|
|
my ($self, $url, $file) = @_; |
166
|
|
|
|
|
|
|
|
167
|
0
|
|
|
|
|
|
my $res; |
168
|
0
|
|
|
|
|
|
my $try = 0; |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
do { |
171
|
0
|
|
|
|
|
|
$self->info("Try $try"); |
172
|
0
|
|
|
|
|
|
eval { |
173
|
0
|
|
|
|
|
|
$res = $self->{_ua}->get($url); |
174
|
|
|
|
|
|
|
}; |
175
|
0
|
0
|
|
|
|
|
$self->error($@) if ($@); |
176
|
0
|
|
|
|
|
|
$try++; |
177
|
|
|
|
|
|
|
} |
178
|
0
|
|
0
|
|
|
|
until($try < $self->{_retry} && defined $@); |
179
|
|
|
|
|
|
|
|
180
|
0
|
0
|
|
|
|
|
if (! $res->is_success) { |
181
|
0
|
|
|
|
|
|
$self->error("Server sent back an error: " . $res->code); |
182
|
0
|
|
|
|
|
|
return ('FAILED', ''); |
183
|
|
|
|
|
|
|
} |
184
|
|
|
|
|
|
|
|
185
|
0
|
|
0
|
|
|
|
my $status = $res->header('X-Thumbalizr-Status') || 'FAILED'; |
186
|
0
|
0
|
|
|
|
|
if ($status eq 'FAILED') { |
187
|
0
|
|
|
|
|
|
$self->error($res->header('X-Thumbalizr-Error')); |
188
|
|
|
|
|
|
|
} |
189
|
|
|
|
|
|
|
|
190
|
0
|
0
|
0
|
|
|
|
if (defined($file) && $file ne '') { |
191
|
0
|
0
|
|
|
|
|
if ($status ne 'OK') { |
192
|
0
|
|
|
|
|
|
return ($status, ''); |
193
|
|
|
|
|
|
|
} |
194
|
|
|
|
|
|
|
|
195
|
0
|
0
|
|
|
|
|
open TARGET, "> $file" or $self->error("Cannot open $file for writing: $!"); |
196
|
0
|
|
|
|
|
|
binmode TARGET; |
197
|
0
|
|
|
|
|
|
print TARGET $res->decoded_content; |
198
|
0
|
|
|
|
|
|
close TARGET; |
199
|
|
|
|
|
|
|
|
200
|
0
|
|
|
|
|
|
return ($status, $file); |
201
|
|
|
|
|
|
|
} |
202
|
|
|
|
|
|
|
|
203
|
0
|
|
|
|
|
|
return ($status, $res->decoded_content); |
204
|
|
|
|
|
|
|
} |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
=head2 download_wait() |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
my ($status, $image) = $thumbalizr->download_wait($url); |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
Download a screenshot. Optionally, you can save the image directly to a file. Unlike the C function, C will attempt to retrieve the screenshot until it is either finished (OK) or failed |
213
|
|
|
|
|
|
|
(FAILED). |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
Return the status of the screenshot (OK, FAILED ), and the image data or image file name. In case the screenshot is not finished, the image data will be empty. |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
Arguments: |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
=over 4 |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
=item |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
Required. Thumbalizr Embed URL generated by $tumbalizr->url |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
=item |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
Optional A local file name to save the image to. |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
=item |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
Optional The number of seconds to wait between 2 tries. 10 by default. |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
=back |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
=cut |
237
|
|
|
|
|
|
|
sub download_wait { |
238
|
0
|
|
|
0
|
1
|
|
my ($self, $url, $file, $wait) = @_; |
239
|
0
|
|
0
|
|
|
|
$wait ||= 10; |
240
|
|
|
|
|
|
|
|
241
|
0
|
|
|
|
|
|
$self->info("Wait $wait s"); |
242
|
|
|
|
|
|
|
|
243
|
0
|
|
|
|
|
|
my ($status, $result) = $self->download($url, $file); |
244
|
0
|
|
|
|
|
|
while ($status eq 'QUEUED') { |
245
|
0
|
|
|
|
|
|
$self->info("Status: $status"); |
246
|
0
|
|
|
|
|
|
sleep $wait; |
247
|
0
|
|
|
|
|
|
($status, $result) = $self->download($url, $file); |
248
|
|
|
|
|
|
|
} |
249
|
|
|
|
|
|
|
|
250
|
0
|
|
|
|
|
|
return ($status, $result); |
251
|
|
|
|
|
|
|
} |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
sub info { |
255
|
0
|
|
|
0
|
0
|
|
my ($self, $message) = @_; |
256
|
|
|
|
|
|
|
|
257
|
0
|
0
|
|
|
|
|
if ($self->{_debug}) { |
258
|
0
|
|
|
|
|
|
print "Error: $message\n"; |
259
|
|
|
|
|
|
|
} |
260
|
|
|
|
|
|
|
|
261
|
0
|
|
|
|
|
|
return ''; |
262
|
|
|
|
|
|
|
} |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
sub error { |
265
|
0
|
|
|
0
|
0
|
|
my ($self, $message) = @_; |
266
|
|
|
|
|
|
|
|
267
|
0
|
|
|
|
|
|
$self->{last_error} = $message; |
268
|
|
|
|
|
|
|
|
269
|
0
|
0
|
|
|
|
|
if ($self->{_debug}) { |
270
|
0
|
|
|
|
|
|
print $message, "\n"; |
271
|
|
|
|
|
|
|
} |
272
|
|
|
|
|
|
|
|
273
|
0
|
|
|
|
|
|
return ''; |
274
|
|
|
|
|
|
|
} |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
1; |
277
|
|
|
|
|
|
|
__END__ |