# vim: set fileencoding=latin1 : =head1 NAME Image::ImageShack - Upload images to be hosted at imageshack.us without needing any account information. =head1 SYNOPSIS require Image::ImageShack; my $ishack = Image::ImageShack->new(); #you can access the LWP::UserAgent via the user_agent method #proxy can be specified by $ishack->user_agent->proxy(['http'], 'http://localhost:8080/'); my $image_url = 'http://www.domain.com/image.png'; #upload specifying a url my $url1 = $ishack->host($image_url); #upload with real size, just optimizes my $url2 = $ishack->host($image_url, 320); #resize to 320x240 (for websites and email) #upload a file my $url3 = $ishack->host('image.jpg'); #upload file #get the thumbnail address my $thumb_url = $ishack->thumb_url(); #will croak on error =head1 DESCRIPTION Image::ImageShack intends to make programmatically possible to upload image files to the website L. imageshack.us allows you to upload image files (jpg, jpeg, png, gif, bmp, tif, tiff, swf < 1.5 megabytes) and to optimize and or resize these files while making them available to others via imageshack.us servers (even direct linking). A thumbnail is always created. =cut package Image::ImageShack; require LWP::UserAgent; require HTTP::Response; require HTTP::Request::Common; use Carp qw(carp croak); use strict; use warnings; our $VERSION = '0.04'; $VERSION = eval $VERSION; our $url = 'http://imageshack.us'; our $uri = 'transload.php'; our $agent = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)'; #nice "fake" =head2 Method Summary =over 4 =item new(attr=>value) Constructor. Initializes the object. Attributes are: =over 4 =item agent L object to used make HTTP requests =item bar Boolean indicating whether thumbnails should have a black bar at the bottom with real image size =item login Id used to upload the files. If you have registered with imageshack.us, you should have received an email with a link similar to: http://reg.imageshack.us/setlogin.php?login=SOME_IDENTIFIER If you intend to be able to later on use the web interface to erase files, you should pass either that link as the login parameter or only the user_id (SOME_IDENTIFIER). No verification on the validity of the user_id is currently made =back =back =cut sub new{ my ($pack, %attrs) = @_; my $self = bless {}, $pack; if(ref($attrs{'lwp_ua'}) && $attrs{'lwp_ua'}->isa('LWP::UserAngent')){ $self->ua($attrs{'lwp_ua'}); }else{ my $ua = LWP::UserAgent->new( 'agent' => $agent, 'timeout' => 60*5, 'keep_alive' => 10, 'env_proxy' => 1, 'requests_redirectable' => [qw(GET POST)] ); $self->ua($ua); } if(defined($attrs{'bar'})){ $self->{'bar'} = $attrs{'bar'}; } if(defined($attrs{'login'})){ my $login = $attrs{'login'}; if($login =~/login=([0-9a-f]+)/i){ $login=$1; } $self->login($login); } return $self; } =over 4 =item user_agent Returns or sets the L object used internally so that it can the customised =cut sub user_agent{ my ($self, $ua) = @_; if(ref($ua) && $ua->isa('LWP::UserAgent')){ $self->{'_ua'}=$ua; } return $self->{'_ua'}; } #just an internal alias *ua = \*user_agent; our @optsize = (100, 150, 320, 640, 800, 1024, 1280, 1600, 'resample'); =item host($url, $size) Given an url (starts with http:// or https://) or a filename and a width in pixels uploads the image to image imageshack.us and resizes it to the desired size. Returns the url of the hosted image and croaks on error. Possible values for C<$size> are: =over 4 =item B<100> 100 x 75 (avatar) =item B<150> 150x112 (thumbnail) =item B<320> 320 x 240 ( for websites and email ) =item B<640> 640x480 (for message boards) =item B<800> 800 x 600 ( 15 -inch monitor ) =item B<1024> 1024x768 (17-inch monitor) =item B<1280> 1280 x 1024 ( 19 -inch monitor ) =item B<1600> 1600x1200 (21-inch monitor) =item B just optimizes =back =cut sub host{ my ($self, $image, $size) = @_; if(!defined($url)){ croak("No url to host"); } my %params = ( 'uploadtype' => 'on', 'brand' => '', 'refer' => '' ); my $is_external = $image=~ m{^https??://}; if($is_external){ $params{'url'} = $image; }else{ $params{'fileupload'} = [$image]; $params{'MAX_FILE_SIZE'} = 3145728; #XXX is this really necessary $params{'url'} = 'paste image url here'; } if(defined($size)){ $params{'optimage'} = 1; if($size=~/^\d+$/){ if(grep{$_ eq $size}@optsize){ $size="${size}x${size}"; }else{ croak("unknown size $size"); } } $params{'optsize'} = $size; if($self->{'bar'}){ delete($params{'rembar'}); }else{ $params{'rembar'}=1; } } my @params = ( "$url/" . ($is_external ? $uri : ''), 'Content_Type' => 'form-data', 'Content' => [%params] ); if(defined($self->login)){ push @params, 'Cookie' =>"myimages=".$self->login; } my $req = HTTP::Request::Common::POST(@params); my $rsp = $self->ua->request($req); if($rsp->is_error){ #XXX debug croak($rsp->status_line."[".$rsp->as_string."]") }else{ my $txt = $rsp->content; # Changed by "Oleg Fiksel" if($txt =~ /Direct.+?href=['"]*([^'"]+)['"]*/ism){ $self->hosted($1); if($txt =~/thumbnail for/i){ my $uri = $self->hosted(); $uri =~ s{\.([^\.]+)$}{\.th\.$1}; $self->hosted_thumb($uri); }else{ #small images have no thumbnail $self->hosted_thumb(undef); } return $self->hosted; }else{ croak("direct link not found in. Maybe an error ocurred during upload. [".$rsp->as_string."]"); } } } my $gen_method = sub{ my $field = shift; return sub{ my ($self, $val) = @_; if(defined($val)){ $self->{$field}=$val; } return $self->{$field}; }; }; *bar = $gen_method->('bar'); =item hosted Returns the url of the last uploaded image. =cut *hosted = $gen_method->('hosted'); =item hosted_thumb Returns the url of the thumbnail last uploaded image. Could be non existent for small images. =cut *hosted_thumb = $gen_method->('hosted_thumb'); =item login Returns or sets the user_id. =cut *login = $gen_method->('login'); =item logout Resets user_id. From now on images won't be associated with any user. =cut sub logout{ my $self = shift @_; $self->login(undef); return $self; } # Preloaded methods go here. 1; __END__ =back =back =head1 DISCLAIMER The author declines ANY responsibility for possible infringement of ImageShack® Terms of Service. This module doesn't use imageshack's XML API but the HTML/web interface instead. =head1 TO-DO =over 4 No guarantee that this will ever be implemented =item HTML code for forums, thumbnails, websites, etc (if you really need this, please ask the author) =item File deletin =item Implement XML API (probably never or on a different) =back =head1 SEE ALSO L http://imageshack.us http://reg.imageshack.us/content.php?page=faq http://reg.imageshack.us/content.php?page=rules =head1 AUTHOR Cláudio Valente, Eplank@cpan.orgE =head1 COPYRIGHT AND LICENSE Copyright (C) 2009 by Cláudio Valente This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.8 or, at your option, any later version of Perl 5 you may have available. =cut