File Coverage

blib/lib/WWW/Tumblr/Blog.pm
Criterion Covered Total %
statement 32 49 65.3
branch 7 20 35.0
condition 4 6 66.6
subroutine 7 10 70.0
pod 0 4 0.0
total 50 89 56.1


line stmt bran cond sub pod time code
1             package WWW::Tumblr::Blog;
2 16     16   120 use Moose;
  16         34  
  16         149  
3 16     16   143299 use Carp;
  16         33  
  16         1546  
4 16     16   132 use Data::Dumper;
  16         32  
  16         869  
5 16     16   106 use JSON;
  16         32  
  16         166  
6              
7 16     16   2892 use WWW::Tumblr::API;
  16         103  
  16         135  
8             extends 'WWW::Tumblr';
9              
10             has 'base_hostname', is => 'rw', isa => 'Str', required => 1;
11              
12             tumblr_api_method info => [ 'GET', 'apikey' ];
13             tumblr_api_method avatar => [ 'GET', 'none', undef, 'size' ];
14             tumblr_api_method likes => [ 'GET', 'apikey'];
15             tumblr_api_method followers => [ 'GET', 'oauth' ];
16              
17             tumblr_api_method posts => [ 'GET', 'apikey', undef, 'type' ];
18             tumblr_api_method posts_queue => [ 'GET', 'oauth' ];
19             tumblr_api_method posts_draft => [ 'GET', 'oauth' ];
20             tumblr_api_method posts_submission => [ 'GET', 'oauth' ];
21              
22             tumblr_api_method post_delete => [ 'POST', 'oauth' ];
23              
24             # posting methods!
25              
26             my %post_required_params = (
27             text => 'body',
28             photo => { any => [qw(source data)] },
29             quote => 'quote',
30             link => 'url',
31             chat => 'conversation',
32             audio => { any => [qw(external_url data)] },
33             video => { any => [qw(embed data)] },
34             );
35              
36             sub post {
37 7     7 0 5639 my $self = shift;
38 7         46 my %args = @_;
39              
40 7         43 $self->_post( %args );
41             }
42              
43             sub _post {
44 7     7   69 my $self = shift;
45 7         38 my %args = @_;
46              
47 7         224 my $subr = join('/', split( /_/, [ split '::', [ caller( 1 ) ]->[3] ]->[-1] ) );
48              
49             Carp::croak "no type specified when trying to post"
50 7 50       60 unless $args{ type };
51              
52             # check for required params per type:
53              
54 7 50       62 if ( $post_required_params{ $args{ type } } ) {
55 7         22 my $req = $post_required_params{ $args{ type } };
56 7 100 66     86 if ( ref $req && ref $req eq 'HASH' && defined $req->{any} ) {
      66        
57             Carp::croak "Trying to post type ".$args{type}." without any of: " .
58 0         0 join( ' ', @{ $req->{any} } )
59 3 50       7 if scalar( grep { $args{ $_ } } @{ $req->{any} } ) == 0;
  6         72  
  3         13  
60             } else {
61             Carp::croak "Trying to post type ".$args{type}." without: $req"
62 4 50       18 unless defined $args{ $req };
63             }
64             }
65              
66 7         504 my $response = $self->_tumblr_api_request({
67             auth => 'oauth',
68             http_method => 'POST',
69             url_path => 'blog/' . $self->base_hostname . '/' . $subr,
70             extra_args => \%args,
71             });
72              
73 7 50       71 if ( $response->is_success ) {
74 7         163 return decode_json( $response->decoded_content)->{response};
75             } else {
76 0           $self->error( WWW::Tumblr::ResponseError->new(
77             response => $response
78             ));
79             return
80 0           }
81             }
82              
83             sub post_edit {
84 0     0 0   my $self = shift;
85 0           my %args = @_;
86             Carp::croak "no id specified when trying to edit a post!"
87 0 0         unless $args{ id };
88              
89 0           $self->_post( %args );
90             }
91              
92             sub post_reblog {
93 0     0 0   my $self = shift;
94 0           my %args = @_;
95              
96             Carp::croak "no id specified when trying to reblog a post!"
97 0 0         unless $args{ id };
98             Carp::croak "no reblog_key specified when trying to reblog a post!"
99 0 0         unless $args{ reblog_key };
100              
101             # Reblog doesn't go through _post() as it doesn't need a type
102 0           my $response = $self->_tumblr_api_request({
103             auth => 'oauth',
104             http_method => 'POST',
105             url_path => 'blog/' . $self->base_hostname . '/post/reblog',
106             extra_args => \%args,
107             });
108              
109 0 0         if ( $response->is_success ) {
110 0           return decode_json( $response->decoded_content)->{response};
111             } else {
112 0           $self->error( WWW::Tumblr::ResponseError->new(
113             response => $response
114             ));
115 0           return;
116             }
117             }
118              
119 0     0 0   sub blog { Carp::croak "Unsupported" }
120              
121             1;
122              
123             =pod
124              
125             =head1 NAME
126              
127             WWW::Tumblr::Blog
128              
129             =head1 SYNOPSIS
130              
131             my $blog = $t->blog('stuff.tumblr.com');
132             # or the domain name:
133             # my $blog = $t->blog('myblogontumblrandstuff.com');
134              
135             # as per http://www.tumblr.com/docs/en/api/v2#blog-info
136             my $info = $blog->info;
137              
138             # as per http://www.tumblr.com/docs/en/api/v2#blog-likes
139             my $likes = $blog->likes;
140             my $likes = $blog->likes(
141             limit => 5,
142             offset => 10,
143             );
144              
145             # as per http://www.tumblr.com/docs/en/api/v2#photo-posts
146             my $posts = $blog->posts(
147             type => 'photo',
148             ... # etc
149             );
150              
151             # Posting to the blog:
152              
153             # using the source param:
154             my $post = $blog->post(
155             type => 'photo',
156             source => 'http://someserver.com/photo.jpg',
157             );
158              
159             # using local files with the data param
160             # which needs to be an array reference
161             my $post = $blog->post(
162             type => 'photo',
163             data => [ '/home/david/larry.jpg' ],
164             );
165              
166             # you can post multiple files, as per the Tumblr API:
167             my $post = $blog->post(
168             type => 'photo',
169             data => [ '/file1.jpg', 'file2.jpg', ... ],
170             );
171              
172             # if the result was false (empty list), then do something with the
173             # error:
174             do_something_with_the_error( $tumblr->error ) unless $post;
175             # or $likes
176             # or $info
177             # or anything else
178              
179             # Reblogging a post (photosets, text, anything):
180             # First get the post you want to reblog to obtain its reblog_key
181             my $source = $t->blog('someblog.tumblr.com');
182             my $posts = $source->posts(limit => 1);
183             my $original = $posts->{posts}[0];
184              
185             # Then reblog it to your blog:
186             my $reblog = $blog->post_reblog(
187             id => $original->{id},
188             reblog_key => $original->{reblog_key},
189             comment => 'Nice post!', # optional
190             );
191              
192             =head1 CAVEATS
193              
194             =over
195              
196             =item *
197              
198             I never really tried posting audios or videos.
199              
200             =item *
201              
202             B<Image format limitations:> This module uses Tumblr's legacy posting API which
203             only supports B<JPEG, PNG, and GIF> images. Formats like B<WebP are not supported>
204             by the legacy API. If you try to upload a webp file, you'll get:
205              
206             Error 400: Mime type "image/webp" not supported from file
207              
208             This is a Tumblr API limitation, not a bug in this module. Tumblr's web interface
209             uses their newer NPF (Neue Post Format) which supports more formats. NPF support
210             would require significant changes to this module and is tracked as a future
211             enhancement. See L<https://www.tumblr.com/docs/npf> for NPF documentation.
212              
213             =item *
214              
215             B<Video uploads:> Direct video file uploads have similar limitations. The legacy
216             API primarily supports video via embed URLs (YouTube, Vimeo, etc.) rather than
217             direct file uploads.
218              
219             =back
220              
221             =head1 BUGS
222              
223             Please refer to L<WWW::Tumblr>.
224              
225             =head1 AUTHOR(S)
226              
227             The same folks as L<WWW::Tumblr>.
228              
229             =head1 SEE ALSO
230              
231             L<WWW::Tumblr>, L<WWW::Tumblr::ResponseError>.
232              
233             =head1 COPYRIGHT and LICENSE
234              
235             Same as L<WWW::Tumblr>.
236              
237             =cut