File Coverage

blib/lib/Pikeo/API.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package Pikeo::API;
2              
3 4     4   207043 use warnings;
  4         10  
  4         152  
4 4     4   23 use strict;
  4         8  
  4         387  
5              
6 4     4   4676 use Data::Dumper;
  4         41998  
  4         287  
7 4     4   2065 use DateTime::Format::RSS;
  0            
  0            
8             use LWP::UserAgent;
9             use Digest::SHA1 qw(sha1_base64 sha1);
10             use Digest::MD5 qw(md5_hex);
11             use MIME::Base64;
12             use DateTime::Format::ISO8601;
13             use DateTime;
14             use Carp;
15              
16             use XML::LibXML;
17             use XML::LibXML::XPathContext;
18              
19             use Pikeo::API::User::Logged;
20              
21             =head1 NAME
22              
23             Pikeo::API - High-level OO interface to pikeo.com API!
24              
25             =head1 VERSION
26              
27             Version 1.01
28              
29             =cut
30              
31             our $VERSION = '1.01';
32              
33             =head1 SYNOPSIS
34              
35             use Pikeo::API;
36             use Pikeo::API::Photos;
37              
38             # create an API object to maintain you session
39             # trough out the diferent calls
40             my $api = Pikeo::API->new({api_secret=>'asd', api_key=>'asdas'});
41            
42             # Create the Photos facade
43             my $photos = Pikeo::API::Photos->new({ api => $api });
44             # Search for photos
45             $photos_searched = $photos->search({text=>'shozu'});
46              
47             =head1 DESCRIPTION
48              
49             This package provides a OO interface to the pikeo.com API.
50              
51             Using the pikeo REST API, this distribution provides an high-level
52             interface to traverse the pikeo objects.
53              
54             To use this module you need to have a valid API key.
55              
56             This module, Pikeo::API, provides the object that olds the
57             api request definitions such as api_key, user agent configuration
58             and credentials for de authenticaded calls.
59              
60             You must instantiate a Pikeo::API object in order to use the facade
61             module that abstract the photos, albums, etc.
62              
63             All the facade modules receive an Pikeo::API object as a mandatory argument
64             for their constructors.
65              
66             =head2 FACADE MODULES
67              
68             =over 4
69              
70             =item Pikeo::API::Photos
71              
72             Search and retrieve photos.
73              
74             =item Pikeo::API::User
75              
76             Search and retrieve users/profiles.
77              
78             =item Pikeo::API::User::Logged
79              
80             Provides access to the private methods for your user.
81             You must be logged in.
82              
83             =back
84              
85             =head1 FUNCTIONS
86              
87             =head2 CONSTRUCTORS
88              
89             =head3 new( \%args )
90              
91             Returns a Pikeo::API object.
92              
93             Required args are:
94              
95             =over 4
96              
97             =item * api_key
98              
99             Your api key
100              
101             =item * api_secret
102              
103             Optional args are:
104              
105             =item * username
106              
107             Username to login
108              
109             =item * password
110              
111             Password for the logged user
112              
113             =back
114              
115             =cut
116              
117             sub new {
118             my $class = shift;
119             my $params= shift;
120              
121             croak "I need an API key" unless $params->{'api_key'};
122             croak "I need an API shared secret" unless $params->{'api_secret'};
123              
124             my $self = {
125             _api_key => $params->{'api_key'},
126             _api_secret => $params->{'api_secret'},
127             };
128              
129             $self = bless $self, $class;
130              
131             if ( $params->{'username'} ) {
132             $self->login({$params->{'username'}, $params->{'password'}});
133             }
134             return $self;
135             }
136              
137             =head2 INSTANCE METHODS
138              
139             =head3 login(\%args)
140              
141             Authenticate and logs in a user.
142              
143             Required args are:
144              
145             =over 4
146              
147             =item * username
148              
149             Username to login
150              
151             =item * password
152              
153             =back
154              
155             =cut
156              
157             sub login {
158             my $self = shift;
159             my $params = shift;
160              
161             croak "need a username and password"
162             unless $params->{'username'} and $params->{'password'};
163              
164             $self->{_auth_user} = $params->{'username'};
165             $self->{_auth_pass} = $params->{'password'};
166              
167             #TODO make a test call to login to validate user and password
168              
169             return 1;
170             }
171              
172             =head3 is_logged_in()
173              
174             Returns 1 if there is a logged access, 0 otherwise
175              
176             =cut
177            
178             sub is_logged_in {
179             my $self = shift;
180             return $self->{_auth_user} ? 1 : 0;
181             }
182              
183             =head3 request_parsed($api_method, \%args)
184              
185             Make a request to the give API method and returns a XML::LibXML object with the result.
186              
187             \%args should contain all the arguments to be passed as parameters to the remote API.
188              
189             =cut
190              
191             sub request_parsed {
192             my $self = shift;
193             my $api = shift;
194             my $params = shift;
195              
196             my $resp = $self->request( $api, $params );
197             croak "request failed ".$resp->status_line unless $resp->is_success;
198              
199             my $parser = XML::LibXML->new();
200             my $doc = XML::LibXML::XPathContext->new($parser->parse_string($resp->content));
201              
202             if ( $doc->findvalue("/response/fault/fault_code") ) {
203             croak "API error code ".$doc->findvalue("/response/fault/fault_code").
204             " ( ".$doc->findvalue("/response/fault/fault_message")." )";
205             }
206              
207             return $doc;
208             }
209              
210             sub request {
211             my $self = shift;
212             my $api = shift;
213             my $params = shift;
214              
215             my $iso8601 = DateTime::Format::ISO8601->new;
216             my $a = LWP::UserAgent->new(timeout=>20);
217             my $timestamp = DateTime->now()."Z";
218             my $nonce = encode_base64($timestamp.rand(10).rand(10));
219             chomp($nonce);
220              
221             my $api_sig_raw = $nonce.$timestamp.$self->{_api_secret};
222             if ( $self->{_auth_user} ) {
223             $api_sig_raw .= uc(md5_hex($self->{_auth_pass}));
224             $params->{login} = $self->{_auth_user};
225             }
226             my $api_sig = encode_base64(sha1($api_sig_raw));
227             chomp($api_sig);
228              
229             my $r = $a->post( 'http://api.pikeo.com/services/pikeo/v2/rest',
230             {
231             nonce => $nonce,
232             api_key => $self->{_api_key},
233             api_sig => $api_sig,
234             timestamp => $timestamp,
235             method => $api,
236             %$params,
237             }
238             );
239              
240             return $r;
241             }
242              
243             =head1 AUTHOR
244              
245             Bruno Tavares, C<< >>
246              
247             =head1 BUGS
248              
249             Please report any bugs or feature requests to
250             C, or through the web interface at
251             L.
252             I will be notified, and then you'll automatically be notified of progress on
253             your bug as I make changes.
254              
255             =head1 SUPPORT
256              
257             You can find documentation for this module with the perldoc command.
258              
259             perldoc Pikeo::API
260              
261             You can also look for information at:
262              
263             =over 4
264              
265             =item * AnnoCPAN: Annotated CPAN documentation
266              
267             L
268              
269             =item * CPAN Ratings
270              
271             L
272              
273             =item * RT: CPAN's request tracker
274              
275             L
276              
277             =item * Search CPAN
278              
279             L
280              
281             =back
282              
283             =head1 ACKNOWLEDGEMENTS
284              
285             =head1 COPYRIGHT & LICENSE
286              
287             Copyright 2008 Bruno Tavares, all rights reserved.
288              
289             This program is free software; you can redistribute it and/or modify it
290             under the same terms as Perl itself.
291              
292             =cut
293              
294             1; # End of Pikeo::API