| Net-Pavatar documentation | Contained in the Net-Pavatar distribution. |
Net::Pavatar - Pavatar client
Version 1.01
use Net::Pavatar;
my ($hash, $file_type) = Net::Pavatar->fetch( 'http://someblog.com/', { size => [32, 48] } );
if ($file_type) {
open FILE, ">avatar.$file_type";
print FILE $hash->{'48'};
close FILE;
}
Fetches a pavatar image from a given URL and gives it to you in the sizes you specify. Uses LWPx::ParanoidAgent to protect your servers from attacks.
This module fully conforms to Pavatar spec 0.3.0 (http://pavatar.com/spec/pavatar-0.3.0), which is the latest one on Apr 25th, 2007.
Returns a hashref and a string, as a 2-list. The hash contains the image sizes as keys, and the image data for each size as values. The string contains the image type and can either be 'jpeg', 'png' or 'gif'. If a pavatar does not exist, or is not valid for any reason, returns null.
The \%opts hashref is optional, and accepts the following keys:
size : the sizes that you want the pavatar image returned in - defaults to 80
timeout : the total time that UserAgent is allowed to retrieve each page or image - defaults to 15
e.g. Net::Pavatar->fetch( $url, { size => [32, 48], timeout => 25 } )
Alexander Karelas, <karjala at karjala.org>
Please report any bugs or feature requests to
bug-net-pavatar at rt.cpan.org, or through the web interface at
http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Net-Pavatar.
I will be notified, and then you'll automatically be notified of progress on
your bug as I make changes.
You can find documentation for this module with the perldoc command.
perldoc Net::Pavatar
You can also look for information at:
Copyright 2007 Alexander Karelas, all rights reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
| Net-Pavatar documentation | Contained in the Net-Pavatar distribution. |
package Net::Pavatar; use warnings; use strict; use LWPx::ParanoidAgent; use Carp; use URI; use GD; use Regexp::Common qw /URI/;
our $VERSION = '1.01';
sub _browser_get { my $url = shift; my $browser = shift; my ($i, $resp) = (0, undef); do { if ($i++) { sleep(1); } $resp = $browser->get($url); } until ($i >= 3 or $resp->code <= 499); return wantarray ? ($resp, $resp->is_success) : $resp; }
sub _discover { my $class = shift; my $url = shift; my $params = shift || {}; my $ua = $params->{'ua'} || LWPx::ParanoidAgent->new( timeout => 15, parse_head => 0 ); my ($resp, $ok) = &_browser_get($url, $ua); if (! $ok) { return } my $base = $resp->base(); # STEP 3.a of spec my ($answer) = $resp->header('X-Pavatar'); if (defined $answer) { if ($answer eq 'none' or $answer !~ /$RE{'URI'}{'HTTP'}/) { return } return $answer; } # STEP 3.b of spec my $page = $resp->content; if ($resp->content_type =~ /\b(x?html|xml)\b/) { ($answer) = $page =~ /<link rel="pavatar" href="([^"]+)" ?\/?>/gi; if (defined $answer) { if ($answer eq 'none' or $answer !~ /$RE{'URI'}{'HTTP'}/) { return } return $answer; } } # STEP 3.c of spec my $uri = URI->new($url); #my $uri = $resp->request->uri; if ($uri->scheme ne 'http') { return; } $uri = 'http://'.$uri->host_port.($uri->path || '/'); my $pavuri = URI->new_abs('pavatar.png', $uri); my $max_size = $ua->max_size; $ua->max_size(51200); ($resp, $ok) = &_browser_get( $pavuri->as_string, $ua ); if ($ok) { $ua->max_size($max_size); return wantarray ? ($pavuri, $resp) : $pavuri; } my $did_pavuri = $pavuri->as_string; $pavuri->path('/pavatar.png'); if ($pavuri->as_string ne $did_pavuri) { ($resp, $ok) = &_browser_get( $pavuri, $ua ); if ($ok) { $ua->max_size($max_size); return wantarray ? ($pavuri, $resp) : $pavuri; } } $ua->max_size($max_size); return; }
sub fetch { my $class = shift; my $url = shift; my $params = shift || {}; my $ua = $params->{'ua'} || LWPx::ParanoidAgent->new( timeout => 15, parse_head => 0 ); ($url, my $resp) = $class->_discover($url, { ua => $ua }); if (! $url) { return; } my $max_size = $ua->max_size; $ua->max_size(51200); my $ok; if (! $resp) { ($resp, $ok) = &_browser_get($url, $ua); } else { $ok = 1; } $ua->max_size($max_size); if (! $ok) { return; } my $type = $resp->content_type; ($type) = $type =~ /^image\/(.+)$/g; my $img; if ($type eq 'jpeg') { $img = GD::Image->newFromJpegData($resp->content, 1); } elsif ($type eq 'gif') { $img = GD::Image->newFromGifData($resp->content, 1); } elsif ($type eq 'png') { $img = GD::Image->newFromPngData($resp->content, 1); } else { return; } if (! $img) { return; } my ($width, $height) = $img->getBounds(); if ($width != 80 or $height != 80) { return; } my @sizes; my $size = $params->{'size'}; if (! defined $size) { @sizes = (80); } elsif (ref $size eq 'ARRAY') { @sizes = grep { /^\d+$/ } @$size; } elsif (! ref $size) { @sizes = int($size); } else { confess "Error: sizes parameter needs to be a number or an arrayref"; } my $return = { }; foreach my $size (@sizes) { if ($size == 80) { $return->{'80'} = $resp->content(); } elsif ($size > 0 and $size < 80) { my $newimage = GD::Image->new($size, $size, 1); $newimage->copyResampled($img, 0, 0, 0, 0, $size, $size, 80, 80); my $data = $newimage->$type(); $return->{$size} = $data; } else { confess "Error: problem with size = '$size' (needs to be an integer between 1 and 80 inclusive)"; } } if (! keys %$return) { return; } return ($return, $type); }
1; # End of Net::Pavatar