File Coverage

blib/lib/WebService/SEOmoz/API.pm
Criterion Covered Total %
statement 22 83 26.5
branch 0 30 0.0
condition 0 4 0.0
subroutine 8 15 53.3
pod 3 7 42.8
total 33 139 23.7


line stmt bran cond sub pod time code
1             package WebService::SEOmoz::API;
2              
3             BEGIN {
4 1     1   1051 $WebService::SEOmoz::API::VERSION = '0.02';
5             }
6              
7             # ABSTRACT: SEOmoz API
8              
9 1     1   10 use strict;
  1         2  
  1         36  
10 1     1   6 use warnings;
  1         2  
  1         41  
11 1     1   1268 use LWP::UserAgent;
  1         124781  
  1         45  
12 1     1   13 use URI::Escape qw/uri_escape/;
  1         3  
  1         106  
13 1     1   1784 use Digest::SHA;
  1         7321  
  1         67  
14 1     1   1678 use JSON::Any;
  1         41350  
  1         9  
15 1     1   8462 use vars qw/$errstr/;
  1         3  
  1         1130  
16              
17             sub new {
18 0     0 0   my $class = shift;
19 0 0         my $args = scalar @_ % 2 ? shift : {@_};
20              
21 0 0         $args->{accessID} or do { $errstr = 'accessID is required'; return; };
  0            
  0            
22 0 0         $args->{secretKey} or do { $errstr = 'secretKey is required'; return; };
  0            
  0            
23              
24 0   0       $args->{expiresInterval} ||= 300;
25              
26             # we won't have space before/after accessID/secretKey
27 0           $args->{accessID} =~ s/(^\s+|\s+$)//g;
28 0           $args->{secretKey} =~ s/(^\s+|\s+$)//g;
29              
30 0 0         unless ( $args->{ua} ) {
31 0   0       my $ua_args = delete $args->{ua_args} || { timeout => 120 };
32 0           $args->{ua} = LWP::UserAgent->new(%$ua_args);
33             }
34 0 0         unless ( $args->{json} ) {
35 0           $args->{json} = JSON::Any->new;
36             }
37              
38 0           bless $args, $class;
39             }
40              
41 0     0 0   sub errstr { $errstr }
42              
43             sub getAuthenticationStr {
44 0     0 0   my ($self) = @_;
45              
46 0           my $expires = time() + $self->{expiresInterval};
47 0           my $stringToSign = $self->{accessID} . "\n" . $expires;
48              
49             # my $binarySignature = Digest::SHA::hmac_sha1($stringToSign, $self->{secretKey});
50             # We need to base64-encode it and then url-encode that.
51             # my $urlSafeSignature = uri_escape(encode_base64($binarySignature));
52              
53             # no idea why we need append '%3D'
54 0           my $urlSafeSignature =
55             uri_escape(
56             Digest::SHA::hmac_sha1_base64( $stringToSign, $self->{secretKey} ) )
57             . '%3D';
58 0           my $authenticationStr =
59             "AccessID="
60             . $self->{accessID}
61             . "&Expires="
62             . $expires
63             . "&Signature="
64             . $urlSafeSignature;
65              
66 0           return $authenticationStr;
67             }
68              
69             sub makeRequest {
70 0     0 0   my ( $self, $url ) = @_;
71              
72             # print STDERR "# get $url\n";
73              
74 0           undef $errstr;
75              
76 0           my $resp = $self->{ua}->get($url);
77 0 0         unless ( $resp->is_success ) {
78 0           $errstr = $resp->status_line;
79 0           return;
80             }
81              
82 0           return $self->{json}->jsonToObj( $resp->content );
83             }
84              
85             sub getUrlMetrics {
86 0     0 1   my $self = shift;
87 0 0         my $args = scalar @_ % 2 ? shift : {@_};
88              
89             my $objectURL = $args->{objectURL}
90 0 0         or do { $errstr = 'objectURL is required'; return; };
  0            
  0            
91 0           my $urlToFetch =
92             "http://lsapi.seomoz.com/linkscape/url-metrics/"
93             . uri_escape($objectURL) . "?"
94             . $self->getAuthenticationStr();
95              
96 0           foreach my $k ('Cols') {
97 0 0         if ( defined $args->{$k} ) {
98 0           $urlToFetch .= "&" . "$k=" . $args->{$k};
99             }
100             }
101              
102 0           return $self->makeRequest($urlToFetch);
103             }
104              
105             sub getLinks {
106 0     0 1   my $self = shift;
107 0 0         my $args = scalar @_ % 2 ? shift : {@_};
108              
109             my $objectURL = $args->{objectURL}
110 0 0         or do { $errstr = 'objectURL is required'; return; };
  0            
  0            
111 0           my $urlToFetch =
112             "http://lsapi.seomoz.com/linkscape/links/"
113             . uri_escape($objectURL) . "?"
114             . $self->getAuthenticationStr();
115              
116 0           foreach my $k (
117             'Scope', 'Filter', 'Sort', 'SourceCols',
118             'TargetCols', 'LinkCols', 'Offset', 'Limit'
119             )
120             {
121 0 0         if ( defined $args->{$k} ) {
122 0           $urlToFetch .= "&" . "$k=" . $args->{$k};
123             }
124             }
125              
126 0           return $self->makeRequest($urlToFetch);
127             }
128              
129             sub getAnchorText {
130 0     0 1   my $self = shift;
131 0 0         my $args = scalar @_ % 2 ? shift : {@_};
132              
133             my $objectURL = $args->{objectURL}
134 0 0         or do { $errstr = 'objectURL is required'; return; };
  0            
  0            
135 0           my $urlToFetch =
136             "http://lsapi.seomoz.com/linkscape/anchor-text/"
137             . uri_escape($objectURL) . "?"
138             . $self->getAuthenticationStr();
139              
140 0           foreach my $k ( 'Scope', 'Sort', 'Cols', 'Offset', 'Limit' ) {
141 0 0         if ( defined $args->{$k} ) {
142 0           $urlToFetch .= "&" . "$k=" . $args->{$k};
143             }
144             }
145              
146 0           return $self->makeRequest($urlToFetch);
147             }
148              
149             1;
150              
151             __END__