File Coverage

blib/lib/Net/MovableType.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 Net::MovableType;
2              
3             # MovableType.pm,v 1.19 2004/08/25 02:49:28 sherzodr Exp
4              
5 1     1   71187 use strict;
  1         3  
  1         37  
6 1     1   6 use vars qw($VERSION $errstr $errcode);
  1         2  
  1         61  
7 1     1   20 use Carp;
  1         3  
  1         69  
8 1     1   506 use XMLRPC::Lite;
  0            
  0            
9              
10             $VERSION = '1.75_01';
11              
12             # Preloaded methods go here.
13              
14              
15             sub _mk_boolean {
16             my $bool = shift;
17              
18             return $bool if ref( $bool );
19             return SOAP::Data->type(boolean=>$bool || 0);
20             }
21              
22              
23              
24             sub new {
25             my $class = shift;
26             $class = ref($class) || $class;
27              
28             my ($url, $username, $password) = @_;
29              
30             my $self = {
31             proxy => undef,
32             blogid => undef,
33             username => $username,
34             password => $password
35             };
36              
37             bless $self, $class;
38              
39             # if $url starts with 'http://' and ends in '.xml', we assume it was a
40             # location of rsd.xml file
41             if ( $url =~ m/^http:\/\/.+\.xml$/ ) {
42             $self->rsd_url($url) or return undef;
43              
44             # if the URL just starts with 'http://', we assume it was a url for
45             # MT's XML-RPC server
46             } elsif ( $url =~ m/^http:\/\// ) {
47             $self->{proxy} = XMLRPC::Lite->proxy($url);
48              
49             # in neither case, we assume it was a file system location of rsd.xml file
50             } elsif ( $url ) {
51             $self->rsd_file($url) or return undef;
52             }
53              
54             return $self;
55             }
56              
57              
58              
59              
60              
61             # shortcut for XMLRPC::Lite's call() method. Main difference from original call()
62             # is, it returns native Perl data, instead of XMLRPC::SOM object
63             sub call {
64             my ($self, $method, @args) = @_;
65              
66             unless ( $method ) {
67             die "call(): usage error"
68             }
69              
70             my $proxy = $self->{proxy} or die "'proxy' is missing";
71             my $som = $proxy->call($method, @args);
72             my $result= $som->result();
73              
74             unless ( defined $result ) {
75             $errstr = $som->faultstring;
76             $errcode= $som->faultcode;
77             return undef
78             }
79              
80             return $result
81             }
82              
83              
84              
85              
86             sub process_rsd {
87             my ($self, $string_or_file ) = @_;
88              
89             unless ( $string_or_file ) {
90             croak "process_rsd() usage error"
91             }
92              
93             require XML::Simple;
94             my $xml = XML::Simple::XMLin(ref($string_or_file) ? $$string_or_file : $string_or_file );
95             my $apilink = $xml->{service}->{apis}->{api}->{MetaWeblog}->{apiLink};
96             my $blogid = $xml->{service}->{apis}->{api}->{MetaWeblog}->{blogID};
97              
98             unless ( $apilink && $blogid ) {
99             croak "Couldn't retrieve 'apiLink' and 'blogID' from $xml"
100             }
101              
102             $self->blogId($blogid);
103             $self->{proxy} = XMLRPC::Lite->proxy($apilink);
104              
105             # need to return a true value indicating success
106             return 1
107             }
108              
109              
110             # fetches RSD file from a remote location,
111             # and configures Net::MovableType object properly
112             sub rsd_url {
113             my ($self, $url) = @_;
114              
115             unless ( $url ) {
116             croak "rsd_url() usage error"
117             }
118              
119             $self->{rsd_url} = $url;
120              
121             require LWP::UserAgent;
122              
123             my $ua = LWP::UserAgent->new();
124             my $req= HTTP::Request->new('GET', $url);
125             my $response = $ua->request($req);
126             if ( $response->is_error ) {
127             $errstr = $response->base . ": " . $response->message;
128             $errcode= $response->code;
129             return undef
130             }
131              
132             return $self->process_rsd($response->content_ref)
133             }
134              
135              
136              
137             sub rsd_file {
138             my ($self, $file) = @_;
139              
140             unless ( $file ) {
141             croak "rsd_file() usage error"
142             }
143              
144             $self->{rsd_file} = $file;
145              
146             return $self->process_rsd($file)
147             }
148              
149              
150              
151              
152             sub username {
153             my ($self, $username) = @_;
154              
155             if ( defined $username ) {
156             $self->{username} = $username;
157             }
158             return $self->{username}
159             }
160              
161              
162              
163             *error = \&errstr;
164             sub errstr {
165             return $errstr
166             }
167              
168              
169             sub errcode {
170             return $errcode
171             }
172              
173              
174              
175              
176             sub password {
177             my ($self, $password) = @_;
178              
179             if ( defined $password ) {
180             $self->{password} = $password
181             }
182             return $self->{password};
183             }
184              
185              
186              
187             sub proxy {
188             my ($self, $proxy) = @_;
189              
190             if ( defined $proxy ) {
191             $self->{proxy} = $proxy
192             }
193             return $self->{proxy}
194             }
195              
196              
197              
198             *blogid = \&blogId;
199             sub blogId {
200             my ($self, $blogid) = @_;
201              
202             if ( defined $blogid ) {
203             $self->{blogid} = $blogid
204             }
205             return $self->{blogid}
206             }
207              
208              
209              
210             sub resolveBlogId {
211             my ($self, $blogname) = @_;
212              
213             unless ( $self->username && $self->password ) {
214             croak "username and password are missing\n"
215             }
216              
217             my $blogs = $self->getUsersBlogs();
218             while ( my $b = shift @$blogs ) {
219             if ( $b->{blogName} eq $blogname ) {
220             return $b->{blogid}
221             }
222             }
223              
224             $errstr = "Couldn't find blog '$blogname'";
225             return undef
226             }
227              
228              
229              
230              
231             sub getBlogInfo {
232             my ($self, $blogid) = @_;
233              
234             $blogid ||= $self->blogId() or croak "no 'blogId' set";
235             my $blogs = $self->getUsersBlogs() or return undef;
236              
237             while ( my $b = shift @$blogs ) {
238             if ( $b->{blogid} == $blogid ) {
239             return $b
240             }
241             }
242              
243             $errstr = "No blog found with id '$blogid";
244             return undef
245             }
246              
247              
248              
249              
250              
251              
252              
253             *getBlogs = \&getUsersBlogs;
254             sub getUsersBlogs {
255             my ($self, $username, $password) = @_;
256              
257             $username = $self->username($username);
258             $password = $self->password($password);
259              
260             unless ( $username && $password ) {
261             croak "username and password are missing";
262             }
263              
264             return $self->call('blogger.getUsersBlogs', "", $username, $password)
265             }
266              
267              
268              
269              
270              
271              
272             sub getUserInfo {
273             my ($self, $username, $password) = @_;
274              
275             $username = $self->username($username);
276             $password = $self->password($password);
277              
278             unless ( $username && $password ) {
279             croak "username and/or password are missing"
280             }
281              
282             return $self->call('blogger.getUserInfo', "", $username, $password)
283             }
284              
285              
286              
287              
288             sub getPost {
289             my ($self, $postid, $username, $password) = @_;
290              
291             $username = $self->username($username);
292             $password = $self->password($password);
293              
294             unless ( $username && $password && $postid ) {
295             croak "getPost() usage error"
296             }
297              
298             return $self->call('metaWeblog.getPost', $postid, $username, $password)
299             }
300              
301              
302              
303              
304              
305              
306              
307             sub getRecentPosts {
308             my ($self, $numposts) = @_;
309              
310             my $blogid = $self->blogId() or croak "no 'blogId' defined";
311             my $username = $self->username() or croak "no 'username' defined";
312             my $password = $self->password() or croak "no 'password' defined";
313             $numposts ||= 1;
314              
315             return $self->call('metaWeblog.getRecentPosts', $blogid, $username, $password, $numposts)
316             }
317              
318              
319              
320             sub getRecentPostTitles {
321             my ($self, $numposts) = @_;
322              
323             my $blogid = $self->blogId() or croak "no 'blogId' defined";
324             my $username= $self->username() or croak "no 'username' defined";
325             my $password= $self->password() or croak "no 'password' defined";
326             $numposts ||= 1;
327              
328             return $self->call('mt.getRecentPostTitles', $blogid, $username, $password, $numposts)
329             }
330              
331              
332              
333              
334              
335              
336             *getCategories = \&getCategoryList;
337             sub getCategoryList {
338             my ($self, $blogid, $username, $password) = @_;
339              
340             $blogid = $self->blogId($blogid) or croak "no 'blogId' defined";
341             $username = $self->username($username) or croak "no 'username' defined";
342             $password = $self->password($password) or croak "no 'password' defined";
343              
344             return $self->call('mt.getCategoryList', $blogid, $username, $password)
345             }
346              
347              
348              
349              
350             sub getPostCategories {
351             my ($self, $postid, $username, $password) = @_;
352              
353             $username = $self->username($username) or croak "no 'username' defined";
354             $password = $self->password($password) or croak "no 'password' defined";
355              
356             unless ( $postid ) {
357             croak "getPostCategories() usage error"
358             }
359              
360             return $self->call('mt.getPostCategories', $postid, $username, $password)
361             }
362              
363              
364              
365             sub setPostCategories {
366             my ($self, $postid, $cats) = @_;
367              
368             unless ( ref $cats ) {
369             $cats = [$cats]
370             }
371              
372             unless ( @$cats && $postid ) {
373             croak "setPostCategories() usage error"
374             }
375              
376             my $blogid = $self->blogId() or croak "no 'blogId' set";
377              
378             my $category_list = $self->getCategoryList($blogid);
379             my $post_categories = [];
380             for my $cat ( @$cats ) {
381             for my $c ( @$category_list ) {
382             if ( lc $c->{categoryName} eq lc $cat ) {
383             push @$post_categories, {categoryId=>$c->{categoryId} }
384             }
385             }
386             }
387              
388             my $username = $self->username() or croak "no 'username' defined";
389             my $password = $self->password() or croak "no 'password' defined";
390             $postid or croak "setPostCategories() usage error";
391              
392             return $self->call('mt.setPostCategories', $postid, $username, $password, $post_categories)
393             }
394              
395              
396              
397              
398              
399              
400              
401              
402              
403              
404              
405             sub supportedMethods {
406             my ($self) = @_;
407              
408             return $self->call('mt.supportedMethods')
409             }
410              
411              
412              
413             sub publishPost {
414             my ($self, $postid, $username, $password) = @_;
415              
416             $username = $self->username($username) or croak "no 'username' set";
417             $password = $self->password($password) or croak "no 'password' set";
418              
419             unless ( $postid ) {
420             croak "publishPost() usage error"
421             }
422              
423             return $self->call('mt.publishPost', $postid, $username, $password)
424             }
425              
426              
427              
428              
429              
430             sub newPost {
431             my ($self, $content, $publish) = @_;
432             $publish = _mk_boolean($publish);
433              
434             my $blogid = $self->blogId() or croak "'blogId' is missing";
435             my $username = $self->username() or croak "'username' is not set";
436             my $password = $self->password() or croak "'password' is not set";
437              
438             unless ( $content && (ref($content) eq 'HASH') ) {
439             croak "newPost() usage error"
440             }
441              
442             return $self->call('metaWeblog.newPost', $blogid, $username, $password, $content, $publish)
443             }
444              
445              
446              
447              
448              
449              
450             sub editPost {
451             my ($self, $postid, $content, $publish) = @_;
452             $publish = _mk_boolean($publish);
453              
454             my $username = $self->username() or croak "'username' is not set";
455             my $password = $self->password() or croak "'password' is not set";
456              
457             unless ( $content && (ref($content) eq 'HASH') ) {
458             croak "newPost() usage error"
459             }
460             return $self->call('metaWeblog.editPost', $postid, $username, $password, $content, $publish)
461             }
462              
463              
464              
465              
466              
467              
468             sub deletePost {
469             my ($self, $postid, $publish) = @_;
470             $publish = _mk_boolean($publish);
471              
472             my $username = $self->username or croak "'username' not set";
473             my $password = $self->password or croak "'password' not set";
474             $postid or croak "deletePost() usage error";
475              
476             return $self->call('blogger.deletePost', "", $postid, $username, $password, $publish)
477             }
478              
479              
480              
481              
482             *upload = \&newMediaObject;
483             sub newMediaObject {
484             my ($self, $filename, $name, $type) = @_;
485              
486             my $blogid = $self->blogId() or croak "'blogId' is missing";
487             my $username = $self->username() or croak "'username' is not set";
488             my $password = $self->password() or croak "'password' is not set";
489              
490             unless ( $filename ) {
491             croak "newMediaObject() usage error";
492             }
493              
494             my $blob = undef;
495             if ( ref $filename ) {
496             $blob = $$filename;
497             $filename = undef;
498              
499             } else {
500             unless(open(FH, $filename)) {
501             $errstr = "couldn't open $filename: $!";
502             return undef
503             }
504             local $/ = undef;
505             $blob = ; close(FH);
506             }
507              
508             if ( $filename && !$name ) {
509             require File::Basename;
510             $name = File::Basename::basename($filename);
511             }
512              
513             unless ( $name ) {
514             croak "newMediaObject() usage error: \$name is missing"
515             }
516              
517             my %content_hash = (
518             bits => XMLRPC::Data->type(base64 => $blob),
519             name => $name,
520             type => $type || ""
521             );
522              
523             return $self->call('metaWeblog.newMediaObject', $blogid, $username, $password, \%content_hash)
524             }
525              
526              
527              
528              
529              
530              
531              
532              
533              
534              
535             sub dump {
536             my $self = shift;
537              
538             require Data::Dumper;
539             my $d = new Data::Dumper([$self], [ref $self]);
540             return $d->Dump();
541             }
542              
543              
544              
545             package MovableType;
546             @MovableType::ISA = ('Net::MovableType');
547              
548              
549             package MT;
550             @MT::ISA = ('Net::MovableType');
551              
552              
553             1;
554             __END__