File Coverage

blib/lib/TextLinkAds.pm
Criterion Covered Total %
statement 24 49 48.9
branch 2 24 8.3
condition 3 12 25.0
subroutine 4 5 80.0
pod 2 2 100.0
total 35 92 38.0


line stmt bran cond sub pod time code
1             package TextLinkAds;
2              
3 2     2   34697 use strict;
  2         5  
  2         92  
4 2     2   14 use warnings;
  2         5  
  2         84  
5              
6 2     2   24 use Carp qw( carp croak );
  2         4  
  2         1548  
7              
8             our $VERSION = '0.01';
9              
10              
11             =head1 NAME
12              
13             TextLinkAds - Retrieve Text Link Ads advertiser data
14              
15              
16             =head1 SYNOPSIS
17              
18             use TextLinkAds;
19            
20             my $tla = TextLinkAds->new;
21            
22             # Fetch link information from text-link-ads.com...
23             my @links = @{ $tla->fetch( $inventory_key ) };
24            
25             # Output the data in some meaningful way...
26             print "
    \n";
27             foreach my $link ( @links ) {
28             my $before = $link->{BeforeText} || '';
29             my $after = $link->{AfterText} || '';
30              
31             print <<"END_OF_HTML";
32            
  • 33             $before $link->{Text} $after
    34            
    35             END_OF_HTML
    36             }
    37             print '';
    38              
    39              
    40             =head1 DESCRIPTION
    41              
    42             This module fetches advertiser information for a given Text Link Ads publisher
    43             account.
    44              
    45             See L.
    46              
    47              
    48             =head1 METHODS
    49              
    50             =head2 ->new( \%options )
    51              
    52             Instantiate a new TextLinkAds object.
    53              
    54             =head3 %options
    55              
    56             =over
    57              
    58             =item cache
    59              
    60             Optional. By default this module will try to use L to store
    61             data retrieved from the text-link-ads.com site for one hour. You may use the
    62             C parameter to provide an alternative object that implements the
    63             L interface. To disable caching set C to a scalar value
    64             that resolves to C.
    65              
    66             =item tmpdir
    67              
    68             Optional. A temporary directory to use when caching data. The default
    69             behaviour is to use the directory determined by
    70             Ltmpdir|File::Spec/tmpdir>.
    71              
    72             =back
    73              
    74             =cut
    75              
    76              
    77             sub new {
    78 1     1 1 613 my ( $class, $args ) = @_;
    79            
    80 1         4 my $self = bless {}, $class;
    81            
    82             # Where the tmpdir isn't defined or valid, use File::Spec to determine an
    83             # appropriate directory...
    84 1         4 my $tmpdir = $args->{tmpdir};
    85 1 0 33     6 unless ( defined $tmpdir && -d $tmpdir && -w $tmpdir ) {
          33        
    86 1         8 require File::Spec;
    87 1         121 $tmpdir = File::Spec->tmpdir;
    88             }
    89 1         8 $self->{tmpdir} = $tmpdir;
    90            
    91            
    92             # Where cache is not defined, or is a scalar with a true value, fall back
    93             # to using Cache::FileCache (providing it is installed)...
    94 1         3 my $cache = $args->{cache};
    95 1 50 0     5 if ( !defined $cache || ( !ref $cache && $cache ) ) {
          33        
    96 1         3 eval { require Cache::FileCache; };
      1         1077  
    97 1 50       95419 unless ( $@ ) {
    98 1         14 $cache = Cache::FileCache->new({
    99             cache_root => $tmpdir,
    100             default_expires_in => '1 hour',
    101             });
    102            
    103 1         350 $self->{cache} = $cache;
    104             }
    105             }
    106            
    107            
    108 1         8 return $self;
    109             }
    110              
    111              
    112             =head2 ->fetch( $inventory_key, \%options )
    113              
    114             Fetch advertiser information for the given key. It will first attempt to get
    115             the data from the cache where available, and failing that will send a request
    116             to text-link-ads.com, using the *_proxy environment variables and the
    117             If-Modified_Since request header.
    118              
    119              
    120             =head3 $inventory_key
    121              
    122             Required. The XML Key for the desired site as provided by Text Link Ads.
    123              
    124             =head3 %options
    125              
    126             =over
    127              
    128             =item user_agent
    129              
    130             Optional. In the vanilla code examples provided by Text Link Ads, both the
    131             user agent and referer CGI environment variables are included in the URI used
    132             to retrieve the XML data. While the link appears to function without them, it
    133             would probably be polite to include them where possible.
    134              
    135             =item referer
    136              
    137             See above.
    138              
    139             =back
    140              
    141              
    142             =cut
    143              
    144              
    145             sub fetch {
    146 0     0 1   my ( $self, $inventory_key, $args ) = @_;
    147            
    148             # First, attempt to retrieve the data from the cache where available...
    149 0           my $links;
    150 0 0         if ( defined $self->{cache} ) {
    151 0           $links = $self->{cache}->get( "tla_$inventory_key" );
    152            
    153 0 0         return $links if defined $links;
    154             }
    155            
    156             # Otherwise, we'll need to retrieve the data from text-link-ads.com, so
    157             # create a new user agent object...
    158 0           require LWP::UserAgent;
    159 0           my $ua = LWP::UserAgent->new(
    160             agent => "TextLinkAds.pm/$VERSION " . LWP::UserAgent->_agent,
    161             );
    162 0           $ua->env_proxy; # obey the *_proxy environment variables
    163            
    164            
    165             # Determine the URI to use when requesting the advertiser data...
    166 0           my $referer = $self->{referer};
    167 0           my $user_agent = $self->{user_agent};
    168            
    169 0 0         my $uri = 'http://www.text-link-ads.com/xml.php'
        0          
    170             . "?inventory_key=$inventory_key"
    171             . ( defined $referer ? "&referer=$referer" : '' )
    172             . ( defined $user_agent ? "&user_agent=$user_agent" : '' );
    173            
    174            
    175             # Request the advertiser data, using "If-Modified-Since" where possible...
    176 0           my $temp_file = $self->{tmpdir} . "/tla_$inventory_key";
    177 0           my $response = $ua->mirror( $uri, $temp_file );
    178            
    179 0 0         if ( !$response->is_success ) {
    180 0           croak $response->status_line;
    181             }
    182            
    183             # The resulting file was empty. This may mean there were no advertisers,
    184             # though it's also possible that an incorrect $inventory_key was given...
    185 0 0         if ( -z $temp_file ) {
    186 0           carp "No advertisers found for '$inventory_key'";
    187 0           return [];
    188             }
    189            
    190             # Parse the XML...
    191 0           require XML::Simple;
    192 0           $links = XML::Simple::XMLin($temp_file)->{Link};
    193            
    194            
    195             # Remove empty BeforeText/AfterText attributes...
    196 0           foreach my $link ( @$links ) {
    197 0 0         delete $link->{BeforeText} if ref $link->{BeforeText};
    198 0 0         delete $link->{AfterText} if ref $link->{AfterText};
    199             }
    200            
    201            
    202             # Store the new data if caching is enabled...
    203 0 0         $self->{cache}->set( "tla_$inventory_key", $links )
    204             if defined $self->{cache};
    205            
    206 0           return $links;
    207             }
    208              
    209              
    210              
    211             1; # End of the module code; everything from here is documentation...
    212             __END__