File Coverage

blib/lib/WebService/Tumblr.pm
Criterion Covered Total %
statement 117 164 71.3
branch 35 64 54.6
condition 7 21 33.3
subroutine 24 36 66.6
pod 3 20 15.0
total 186 305 60.9


line stmt bran cond sub pod time code
1             package WebService::Tumblr;
2             BEGIN {
3 3     3   247852 $WebService::Tumblr::VERSION = '0.0010';
4             }
5             # ABSTRACT: A Perl interface to the Tumblr web API
6              
7              
8 3     3   27 use strict;
  3         6  
  3         70  
9 3     3   13 use warnings;
  3         6  
  3         65  
10              
11 3     3   2197 use Any::Moose;
  3         120066  
  3         21  
12 3     3   4745 use LWP::UserAgent;
  3         149316  
  3         104  
13 3     3   4815 use HTTP::Request::Common();
  3         13657  
  3         76  
14 3     3   2895 use URI::PathAbstract;
  3         238159  
  3         94  
15 3     3   3171 use JSON;
  3         40134  
  3         19  
16             our $json = JSON->new->pretty;
17 0     0 0 0 sub json { $json }
18              
19 3     3   2423 use WebService::Tumblr::Dispatch;
  3         10  
  3         117  
20 3     3   1726 use WebService::Tumblr::Result;
  3         8  
  3         115  
21              
22 3     3   21 use constant TUMBLR_URL => 'http://www.tumblr.com';
  3         6  
  3         6690  
23              
24             sub empty ($) {
25 14   66 14 0 105 return not defined $_[0] && length $_[0];
26             }
27              
28             sub hash_refactor {
29 3     3 0 30 my %arguments = @_;
30 3         13 my ( $hash, $key0, $else, $delete, $exclusive, $exists ) = @arguments{qw/ hash key else delete exclusive exists /};
31              
32             # FIXME Return value of key0
33 3 50       12 return unless defined $else;
34 3 50       12 $else = [ $else ] unless ref $else eq 'ARRAY';
35              
36 3         5 my @found;
37 3         8 for my $key ( $key0, @$else ) {
38 11 50       20 if ( $exists ) {
39 0 0       0 if ( $exists eq 'empty' ) { push @found, $key if ! empty $hash->{ $key } }
  0 0       0  
40 0 0       0 else { push @found, $key if exists $hash->{ $key } }
41             }
42 11 100       30 else { push @found, $key if $hash->{ $key } }
43             }
44              
45 3 50       11 return unless @found;
46              
47 3         5 my $has;
48 3 100 66     26 if ( @found and $found[ 0 ] eq $key0 ) {
49 2         2 $has = 1;
50 2         2 shift @found;
51             }
52              
53 3         6 my $value;
54 3 50       8 if ( $exclusive ) {
55 0 0 0     0 if ( $has && @found ) {
56 0         0 die "Exclusivity violated: $key0 @found";
57             }
58              
59 0 0       0 if ( @found > 1 ) {
60 0         0 die "Exclusivity violated: @found";
61             }
62             }
63              
64 3 100       7 if ( $has ) {
65 2 100       5 if ( $delete ) {
66 1         6 delete $hash->{ $_ } for @found;
67             }
68 2         17 return $hash->{ $key0 };
69             }
70             else {
71 1         3 my $value = $hash->{ $found[0] };
72 1 50       7 if ( $delete ) {
73 0         0 delete $hash->{ $_ } for @found;
74             }
75 1         11 return $hash->{ $key0 } = $value;
76             }
77             }
78              
79             sub _urlify ($) {
80 4     4   7 my $given = shift;
81              
82 4 50       11 return if empty $given;
83              
84 4 100       32 if ( $given !~ m/\./ ) {
85 2         5 $given = "$given.tumblr.com";
86             }
87 4 100       16 if ( $given !~ m/^[A-Za-z0-9]+:\/\// ) {
88 3         8 $given = "http://$given";
89             }
90              
91 4         13 return $given;
92             }
93              
94             sub _url_from ($) {
95 1     1   3 my $self = shift;
96 1         3 my $given = shift;
97              
98 1         4 my ( $url, $blog ) = delete @$given{qw/ url blog /};
99              
100 1 50       5 return _urlify $url unless empty $url;
101 1 50       3 return _urlify $blog unless empty $blog;
102 1         4 return;
103             }
104              
105             sub _extract ($@) {
106 2     2   3 my $self = shift;
107 2         4 my $given = shift;
108              
109 2         3 my %return;
110 2         6 for ( @_ ) {
111 44 50       78 $return{ $_ } = delete $given->{ $_ } if exists $given->{ $_ };
112             }
113              
114 2         7 return \%return;
115             }
116              
117             sub BUILD {
118 1     1 1 2 my $self = shift;
119 1         3 my $given = shift;
120              
121 1 50       3 die "*** Two or more of: name, blog, url" if 1 < grep { ! empty $given->{ $_ } } qw/ name blog url /;
  3         13  
122 1   33     6 ! empty $given->{ $_ } and $self->url( $given->{ $_ } ) for qw/ name blog /;
123             }
124              
125             has secure => qw/ is rw default 1 /;
126              
127             has agent => qw/ is ro lazy_build 1 /;
128             sub _build_agent {
129 0     0   0 my $agent = LWP::UserAgent->new;
130 0         0 return $agent;
131             }
132              
133             has [qw/ email password /] => qw/ is rw /;
134              
135             has _name => qw/ is rw /;
136             has url => qw/ is rw /, trigger => sub {
137             my ( $self, $value ) = @_;
138             my $url = _urlify $value;
139             if ( empty $url ) {
140             $self->_name( undef );
141             return undef;
142             }
143             my $uri = URI->new( $url );
144             my $host = $uri->host;
145             if ( $host =~ m/^([^\.]+)\.tumblr.com$/ ) { $self->_name( $1 ) }
146             else { $self->_name( $host ) }
147             $self->{ url } = $url; # FIXME This is a hack, do this better
148             };
149              
150             sub name {
151 4     4 1 1585 my $self = shift;
152 4 100       29 return $self->_name unless @_;
153 1         8 $self->url( @_ );
154             }
155              
156 0     0 0 0 sub blog { return shift->name( @_ ) }
157              
158             sub _url {
159 1     1   2 my $self = shift;
160 1         5 my $url = $self->url;
161 1 50       5 die "*** Missing url" unless $self->url;
162 1         8 return _urlify $url;
163             }
164              
165             sub identity {
166 2     2 0 12 my $self = shift;
167 2 100       6 if ( @_ ) {
168 1         3 my ( $email, $password ) = @_;
169 1         5 $self->email( $email );
170 1         6 $self->password( $password );
171             }
172             else {
173 1         9 return ( $self->email, $self->password );
174             }
175             }
176              
177             sub new_dispatch {
178 2     2 0 5 my $self = shift;
179 2         42 return WebService::Tumblr::Dispatch->new( tumblr => $self, @_ );
180             }
181              
182             sub dispatch {
183 2     2 0 5 my $self = shift;
184 2         2 my $arguments = shift;
185 2         9 my %options = @_;
186              
187 2         4 my $base = TUMBLR_URL;
188 2         8 $base = URI->new( $base );
189 2 50       123 $base->scheme( 'https' ) if $self->secure;
190              
191 2 100       6279 if ( $options{ url } ) {
192 1         6 $base = $self->_url_from( $arguments );
193 1   33     8 $base ||= $self->_url;
194             }
195 2         18 my $url = URI::PathAbstract->new( $base, path => $options{ path } );
196 2 50       586 my $query = $self->_extract( $arguments, @{ $options{ passthrough } || [] } );
  2         14  
197 2         8 my $dispatch = $self->new_dispatch( method => 'GET', url => $url, query => $query );
198 2 100       154 $dispatch->authenticate if $options{ authenticate };
199              
200 2         8 return $dispatch;
201             }
202              
203             sub write {
204 1     1 1 750 my $self = shift;
205 1         3 my %arguments = @_;
206              
207 1         10 my $dispatch = $self->dispatch( \%arguments,
208             path => 'api/write',
209             passthrough => [qw/
210             email password type generator date private tags format group slug state send-to-twitter
211             post-id
212             title body
213             source data caption click-through-url
214             quote source
215             name url description
216             title conversation
217             embed data title caption
218             data externally-hosted-url caption
219             /],
220             authenticate => 1,
221             );
222              
223 1         5 return $dispatch;
224             }
225              
226             sub edit {
227 0     0 0 0 my $self = shift;
228 0         0 my %arguments = @_;
229              
230 0 0       0 die "*** Missing post-id" unless $arguments{ 'post-id' };
231              
232 0         0 return $self->write( @_ );
233             }
234              
235             sub delete {
236 0     0 0 0 my $self = shift;
237 0         0 my %arguments = @_;
238              
239 0         0 my $dispatch = $self->dispatch( \%arguments,
240             path => 'api/delete',
241             passthrough => [qw/ email password post-id /],
242             authenticate => 1,
243             );
244              
245 0         0 return $dispatch;
246             }
247              
248             sub reblog {
249 0     0 0 0 my $self = shift;
250 0         0 my %arguments = @_;
251              
252 0         0 my $dispatch = $self->dispatch( \%arguments,
253             path => 'api/delete',
254             passthrough => [qw/ email password post-id reblog-key comment as /],
255             authenticate => 1,
256             );
257              
258 0         0 return $dispatch;
259             }
260              
261             sub pages {
262 0     0 0 0 my $self = shift;
263 0         0 my %arguments = @_;
264              
265 0         0 my $dispatch = $self->dispatch( \%arguments,
266             url => 1,
267             path => 'api/pages',
268             passthrough => [qw/ email password /],
269             );
270 0 0 0     0 $dispatch->authenticate if $arguments{ all } || $dispatch->query->{ state };
271              
272 0         0 return $dispatch;
273             }
274              
275             sub posts {
276 1     1 0 2 my $self = shift;
277 1         2 my %arguments = @_;
278              
279 1         8 my $dispatch = $self->dispatch( \%arguments,
280             url => 1,
281             path => 'api/read',
282             passthrough => [qw/ email password start num type id filter tagged chrono search state /],
283             );
284 1 50 33     13 $dispatch->authenticate if $arguments{ all } || $dispatch->query->{ state };
285              
286 1         4 return $dispatch;
287             }
288              
289             sub read {
290 0     0 0   my $self = shift;
291              
292 0           return $self->posts( @_ );
293             }
294              
295             sub dashboard {
296 0     0 0   my $self = shift;
297 0           my %arguments = @_;
298              
299 0           my $dispatch = $self->dispatch( \%arguments,
300             path => 'api/dashboard',
301             passthrough => [qw/ email password start num filter likes /],
302             authenticate => 1,
303             );
304              
305 0           return $dispatch;
306             }
307              
308             sub likes {
309 0     0 0   my $self = shift;
310 0           my %arguments = @_;
311              
312 0           my $dispatch = $self->dispatch( \%arguments,
313             path => 'api/dashboard',
314             passthrough => [qw/ email password start num filter /],
315             authenticate => 1,
316             );
317              
318 0           return $dispatch;
319             }
320              
321             sub like {
322 0     0 0   my $self = shift;
323 0           my %arguments = @_;
324              
325 0           my $dispatch = $self->dispatch( \%arguments,
326             path => 'api/like',
327             passthrough => [qw/ email password post-id reblog-key /],
328             authenticate => 1,
329             );
330              
331 0           return $dispatch;
332             }
333              
334             sub authenticate {
335 0     0 0   my $self = shift;
336 0           my %arguments = @_;
337              
338 0           my $dispatch = $self->dispatch( \%arguments,
339             path => 'api/authenticate',
340             passthrough => [qw/ email password include-theme /],
341             authenticate => 1,
342             );
343              
344 0           return $dispatch;
345             }
346              
347             1;
348              
349             __END__