File Coverage

lib/WWW/VenusEnvy.pm
Criterion Covered Total %
statement 65 80 81.2
branch 20 46 43.4
condition 7 13 53.8
subroutine 11 11 100.0
pod 3 3 100.0
total 106 153 69.2


line stmt bran cond sub pod time code
1             ############################################################
2             #
3             # $Id: VenusEnvy.pm,v 1.10 2006/01/28 13:17:40 nicolaw Exp $
4             # WWW::VenusEnvy - Retrieve VenusEnvy comic strip images
5             #
6             # Copyright 2005,2006 Nicola Worthington
7             #
8             # Licensed under the Apache License, Version 2.0 (the "License");
9             # you may not use this file except in compliance with the License.
10             # You may obtain a copy of the License at
11             #
12             # http://www.apache.org/licenses/LICENSE-2.0
13             #
14             # Unless required by applicable law or agreed to in writing, software
15             # distributed under the License is distributed on an "AS IS" BASIS,
16             # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17             # See the License for the specific language governing permissions and
18             # limitations under the License.
19             #
20             ############################################################
21              
22             package WWW::VenusEnvy;
23             # vim:ts=4:sw=4:tw=78
24              
25 3     3   40628 use strict;
  3         8  
  3         121  
26 3     3   15 use Exporter;
  3         13  
  3         133  
27 3     3   3369 use LWP::UserAgent qw();
  3         169788  
  3         83  
28 3     3   35 use HTTP::Request qw();
  3         6  
  3         63  
29 3     3   16 use Carp qw(carp croak);
  3         30  
  3         254  
30 3     3   15 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
  3         8  
  3         3925  
31              
32             $VERSION = '1.10' || sprintf('%d.%02d', q$Revision$ =~ /(\d+)/g);
33             @ISA = qw(Exporter);
34             @EXPORT = ();
35             @EXPORT_OK = qw(&get_strip &strip_url &mirror_strip);
36             %EXPORT_TAGS = ( all => \@EXPORT_OK );
37              
38             sub mirror_strip {
39 3     3 1 1549 my $filename = shift;
40 3   66     29 my $url = shift || strip_url();
41              
42 3         12 my $blob = get_strip($url);
43 3 100       149 return undef if !defined($blob);
44              
45 1 50 33     12 if ((!defined($filename) || !length($filename)) && defined($url)) {
      33        
46 0         0 ($filename = $url) =~ s#.*/##;
47             }
48 1         4 my $ext = _image_format($blob);
49 1         18 $filename =~ s/(\.(jpe?g|gif|png))?$/.$ext/i;
50              
51 1 50       168 open(FH,">$filename") ||
52             croak "Unable to open file handle FH for file '$filename': $!";
53 1         7 binmode FH;
54 1         633 print FH $blob;
55 1 50       52 close(FH) ||
56             carp "Unable to close file handle FH for file '$filename': $!";
57 1         10162 return $filename;
58             }
59              
60             sub get_strip {
61 8   100 8 1 67 my $url = shift || strip_url() || '';
62              
63 8 100       51 if ($url =~ /^(\d{8}\d*(\.(jpg|gif|png))?)$/i) {
64 2         8 $url = "http://venusenvy.keenspace.com/comics/$1";
65 2 50       16 $url .= '.jpg' unless $url =~ /\.(jpg|gif|png)$/i;
66             }
67              
68 8         32 my $ua = _new_agent();
69 8         60 my $req = HTTP::Request->new(GET => $url);
70             #$req->referer('http://venusenvy.keenspace.com/');
71 8         946 $req->referer('http://venusenvy.comicgenesis.com/');
72 8         439 my $response = $ua->request($req);
73              
74 8         4071188 my $status;
75 8 100       36 unless ($response->is_success) {
76 6         70 $status = $response->status_line;
77 6 50       76 unless ($url =~ s/\.gif$/.jpg/i) { $url =~ s/\.jpg$/.gif/i; }
  6         12  
78 6         26 $req = HTTP::Request->new(GET => $url);
79             #$req->referer('http://venusenvy.keenspace.com/');
80 6         583 $req->referer('http://venusenvy.comicgenesis.com/');
81 6         492 $response = $ua->request($req);
82             }
83              
84 8 100       2201 if ($response->is_success) {
    50          
85 2 50       21 unless (_image_format($response->content)) {
86 0 0       0 carp('Unrecognised image format') if $^W;
87 0         0 return undef;
88             }
89 2 50       12 if (length($response->content) < 1300) {
90 0 0       0 if ($response->content =~ /(anti\-?)?hotlinking/i) {
91 0 0       0 carp('Image has been blocked by anti-hotlinking server') if $^W;
92 0         0 return undef;
93             }
94 0 0       0 carp('Image data is too') if $^W;
95 0         0 return undef;
96             }
97 2         1841 return $response->content;
98             } elsif ($^W) {
99 0         0 carp($status);
100             }
101 6         215 return undef;
102             }
103              
104             sub strip_url {
105 9     9 1 90 my $ua = _new_agent();
106              
107 9         46 my $response = $ua->get('http://venusenvy.keenspace.com');
108 9 50       5704843 if ($response->is_success) {
    0          
109 9         293 my $html = $response->content;
110 9 50       259 if ($html =~ m#
111             /comics/\d{8}\d*\.(gif|jpg|png))".*?>#imsx) {
112 0         0 my $url = $1;
113 0 0       0 $url = "http://venusenvy.keenspace.com$1" unless $url =~ /^https?:\/\//i;
114 0         0 return $url;
115             }
116              
117             } elsif ($^W) {
118 0         0 carp($response->status_line);
119             }
120              
121 9         1459 return undef;
122             }
123              
124             sub _image_format {
125 3   50 3   882 local $_ = shift || '';
126 3 50       17 return 'gif' if /^GIF8[79]a/;
127 3 50       86 return 'jpg' if /^\xFF\xD8/;
128 0 0       0 return 'png' if /^\x89PNG\x0d\x0a\x1a\x0a/;
129 0         0 return undef;
130             }
131              
132             sub _new_agent {
133 17     17   115 my @agents = (
134             'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1).',
135             'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.8) '.
136             'Gecko/20050718 Firefox/1.0.4 (Debian package 1.0.4-2sarge1)',
137             'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.7.5) '.
138             'Gecko/20041110 Firefox/1.0',
139             'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) '.
140             'AppleWebKit/125.5.5 (KHTML, like Gecko) Safari/125.12',
141             'Mozilla/4.0 (compatible; MSIE 6.0; Windows 98)',
142             );
143              
144 17         521 my $ua = LWP::UserAgent->new(
145             agent => $agents[int(rand(@agents))],
146             timeout => 20
147             );
148 17         8386 $ua->env_proxy;
149 17         26917 $ua->max_size(1024*500);
150 17         403 return $ua;
151             }
152              
153              
154             1;
155              
156             =pod
157              
158             =head1 NAME
159              
160             WWW::VenusEnvy - Retrieve VenusEnvy comic strip images
161              
162             =head1 SYNOPSIS
163              
164             use WWW::VenusEnvy qw(get_strip mirror_strip strip_url);
165            
166             # Get the URL for todays strip
167             my $image_url = strip_url();
168            
169             # Get todays strip
170             my $image_blob = get_strip();
171            
172             # Get a specific strip by specifying the ID
173             my $christmas_kiss = get_strip("20051229");
174            
175             # Write todays strip to local_filename.gif on disk
176             my $filename_written = mirror_strip("local_filename.gif");
177            
178             # Write a specific strip to mystrip.gif on disk
179             my $filename_written = mirror_strip("mystrip.gif","20051229");
180              
181             =head1 DESCRIPTION
182              
183             This module will download the latest VenusEnvy comic strip from
184             the Keenspace website and return a binary blob of the image, or
185             write it to disk.
186              
187             =head1 EXPORTS
188              
189             The following functions can be exported with the C<:all> export
190             tag, or individually as is show in the above example.
191              
192             =head2 strip_url
193              
194             # Return todays strip URL
195             my $url = strip_url();
196            
197             # Return the strip URL for 19th August 2005
198             $url = strip_url("20050819");
199              
200             Accepts an optional argument specifying the date of the comic
201             strip in ISO format C.
202              
203             =head2 get_strip
204              
205             # Get todays comic strip image
206             my $image_blob = get_strip();
207              
208             Accepts an optional argument specifying the date of the comic
209             strip in ISO format C.
210              
211             =head2 mirror_strip
212              
213             # Write todays comic strip to "mystrip.gif" on disk
214             my $filename_written = mirror_strip("mystrip.gif");
215              
216             Accepts two optional arguments. The first is the filename that
217             the comic strip should be written to on disk. The second specifies
218             the date of the comic strip in ISO format C.
219              
220             Returns the name of the file that was written to disk.
221              
222             =head1 VERSION
223              
224             $Id: VenusEnvy.pm,v 1.10 2006/01/28 13:17:40 nicolaw Exp $
225              
226             =head1 AUTHOR
227              
228             Nicola Worthington
229              
230             L
231              
232             =head1 COPYRIGHT
233              
234             Copyright 2005,2006 Nicola Worthington.
235              
236             This software is licensed under The Apache Software License, Version 2.0.
237              
238             L
239              
240             =cut
241              
242              
243