1{
2
3=head1 NAME
4
5Net::Blogger::API::Core - Blogger API methods
6
7=head1 SYNOPSIS
8
9 It's very dark in here because this is a black box.
10
11=head1 DESCRIPTION
12
13Net::Blogger::API::Core defined methods that correspond to the
14Blogger API.
15
16It is inherited by I<Net::Blogger::Engine::Base.pm>
17
18=cut
19
20package Net::Blogger::API::Core;
21use strict;
22
23$Net::Blogger::API::Core::VERSION   = '1.01';
24@Net::Blogger::API::Core::ISA       = qw ( Exporter );
25@Net::Blogger::API::Core::EXPORT    = qw ();
26@Net::Blogger::API::Core::EXPORT_OK = qw ();
27
28use Exporter;
29
30=head1 Blogger API METHODS
31
32=head2 $pkg->getUsersBlogs()
33
34Fetch the I<blogid>, I<url> and I<blogName> for each of the Blogger blogs
35the current user is registered to.
36
37Returns an array ref of hashes.
38
39=cut
40
41sub getUsersBlogs {
42    my $self  = shift;
43    my $blogs = [];
44
45    my $call = $self->_Client->call(
46				    "blogger.getUsersBlogs",
47				    $self->_Type(string=>$self->AppKey()),
48				    $self->_Type(string=>$self->Username()),
49				    $self->_Type(string=>$self->Password()),
50				    );
51
52    ($call) ? return $call->result() : return [];
53}
54
55=head2 $pkg->newPost(\%args)
56
57Add a new post to the Blogger server.
58
59Valid arguments are :
60
61=over 4
62
63=item *
64
65B<postbody> (required)
66
67Scalar ref.
68
69=item *
70
71B<publish>
72
73Boolean.
74
75=back
76
77If the length of I<postbody> exceeds maximum length allowed by the Blogger servers
78-- 65,536 characters -- currently  the text will be chunked into smaller pieces are
79each piece will be posted separately.
80
81Releases prior to Net::Blogger 0.85 accepted a list of arguments
82rather than a reference. Version 0.85+ are backwards compatible.
83
84Returns an array containing one, or more, post ids.
85
86=cut
87
88sub newPost {
89    my $self = shift;
90    my $args = (ref($_[0]) eq "HASH") ? shift : { @_ };
91
92    if (! $self->check_newPost($args)) {
93      return 0;
94    }
95
96    if ($self->check_exceedsMaxLength($args)) {
97      return $self->_PostInChunks(%$args);
98    }
99
100    my $postbody = $args->{'postbody'};
101    my $publish  = ($args->{'publish'}) ? 1 : 0;
102
103    my $call = $self->_Client->call(
104				    "blogger.newPost",
105				    $self->_Type(string=>$self->AppKey()),
106				    $self->_Type(string=>$self->BlogId()),
107				    $self->_Type(string=>$self->Username()),
108				    $self->_Type(string=>$self->Password()),
109				    $self->_Type(string=>$$postbody),
110				    $self->_Type(boolean=>$publish),
111				    );
112
113    return ($call) ? $call->result() : return 0;
114}
115
116=head2 $pkg->getPost($postid)
117
118Returns a hash ref, containing the following keys : userid, postid,
119content and dateCreated.
120
121=cut
122
123sub getPost {
124    my $self   = shift;
125    my $postid = shift;
126
127    if (! $self->check_getPost($postid)) {
128      return 0;
129    }
130
131    my $call = $self->_Client->call(
132				    "blogger.getPost",
133				    $self->_Type(string=>$self->AppKey()),
134				    $self->_Type(string=>$postid),
135				    $self->_Type(string=>$self->Username()),
136				    $self->_Type(string=>$self->Password()),
137				    );
138
139    if (! $call) { return 0; }
140
141    my $post = $call->result();
142
143    # See KNOWN ISSUES
144
145    if ($post eq "0") {
146	$self->LastError("Unable to locate post.");
147	return 0;
148    }
149
150    return $post;
151}
152
153=head2 $pkg->getRecentPosts(\%args)
154
155Fetch the latest (n) number of posts for a given blog. The most recent posts
156are returned first.
157
158Valid arguments are
159
160=over 4
161
162=item *
163
164B<numposts>
165
166Int. If no argument is passed to the method, default is 1.
167
168"NumberOfPosts is limited to 20 at this time. Let me know if this
169gets annoying. Letting this number get too high could result in some
170expensive db access, so I want to be careful with it." --Ev
171
172=back
173
174Releases prior to Net::Blogger 0.85 accepted a list of arguments
175rather than a reference. Version 0.85+ are backwards compatible.
176
177Returns true or false, followed by an array of hash refs. Each hash ref
178contains the following keys : postid,content,userid,dateCreated
179
180=cut
181
182sub getRecentPosts {
183    my $self = shift;
184    my $args = (ref($_[0]) eq "HASH") ? shift : { @_ };
185
186    if (! $self->check_getRecentPosts($args)) {
187      return (0);
188    }
189
190    my $call = $self->_Client->call(
191				    "blogger.getRecentPosts",
192				    $self->_Type(string=>$self->AppKey()),
193				    $self->_Type(string=>$self->BlogId()),
194				    $self->_Type(string=>$self->Username()),
195				    $self->_Type(string=>$self->Password()),
196				    $self->_Type(int=>$args->{'numposts'}),
197				  );
198
199    my @posts = ($call) ? (1,@{$call->result()}) : (0,undef);
200    return @posts;
201}
202
203=head2 $pkg->editPost(\%args)
204
205Update the Blogger database. Set the body of entry $postid to $body.
206
207Valid arguments are :
208
209=over 4
210
211=item *
212
213B<postbody> (required)
214
215Scalar ref or a valid filehandle.
216
217=item *
218
219B<postid>
220
221String. I<required>
222
223=item *
224
225B<publish>
226
227Boolean.
228
229=back
230
231If the length of I<postbody> exceeds maximum length allowed by the Blogger servers
232-- 65,536 characters -- currently  the text will be chunked into smaller pieces are
233each piece will be posted separately.
234
235Releases prior to Net::Blogger 0.85 accepted a list of arguments
236rather than a reference. Version 0.85+ are backwards compatible.
237
238Returns an array containing one, or more, post ids.
239
240=cut
241
242sub editPost {
243    my $self = shift;
244    my $args = (ref($_[0]) eq "HASH") ? shift : { @_ };
245
246    if (! $self->check_editPost($args)) {
247      return 0;
248    }
249
250    if ($self->check_exceedsMaxLength($args)) {
251      return $self->_PostInChunks(%$args);
252    }
253
254    my $postbody = $args->{'postbody'};
255    my $postid   = $args->{'postid'};
256
257    if (($self->MaxPostLength()) && (length($$postbody) > $self->MaxPostLength())) {
258	return $self->_PostInChunks(%$args);
259    }
260
261    my $publish = ($args->{'publish'}) ? 1 : 0;
262
263    my $ok = undef;
264
265    my $call= $self->_Client->call(
266				   "blogger.editPost",
267				   $self->_Type(string=>$self->AppKey()),
268				   $self->_Type(string=>$postid),
269				   $self->_Type(string=>$self->Username()),
270				   $self->_Type(string=>$self->Password()),
271				   $self->_Type(string=>$$postbody),
272				   $self->_Type(boolean=>$publish),
273				   );
274
275    ($call) ? return $call->result() : return 0;
276}
277
278=head2 $pkg->deletePost(\%args)
279
280Delete a post from the Blogger server.
281
282Valid arguments are
283
284=over 4
285
286=item *
287
288B<postid>
289
290String. I<required>
291
292=item *
293
294B<publish>
295
296Boolean.
297
298=back
299
300Releases prior to Net::Blogger 0.85 accepted a list of arguments
301rather than a reference. Version 0.85+ are backwards compatible.
302
303Returns true or false.
304
305=cut
306
307sub deletePost {
308    my $self = shift;
309    my $args = (ref($_[0]) eq "HASH") ? shift : { @_ };
310
311    if (! $self->check_deletePost($args)) {
312      return 0;
313    }
314
315    my $postid  = $args->{'postid'};
316    my $publish = ($args->{'publish'}) ? 1 : 0;
317
318    my $call = $self->_Client->call(
319				    "blogger.deletePost",
320				    $self->_Type(string=>$self->AppKey()),
321				    $self->_Type(string=>$postid),
322				    $self->_Type(string=>$self->Username()),
323				    $self->_Type(string=>$self->Password()),
324				    $self->_Type(boolean=>$publish),
325				    );
326
327    ($call) ? return $call->result() : return 0;
328}
329
330=head2 $pkg->setTemplate(\%args)
331
332Set the body of the template matching type I<$type>.
333
334 <quote src = "ev">
335  template is the HTML (XML, whatever -- Blogger can output any sort
336  of text). Must contain opening and closing <Blogger> tags to be
337  valid and accepted.
338 </quote>
339
340Valid arguments are
341
342=over 4
343
344=item *
345
346B<template>
347
348Scalar ref. I<required>
349
350=item *
351
352B<type>
353
354String. I<required>
355
356Valid types are "main" and "archiveIndex"
357
358=back
359
360Releases prior to Net::Blogger 0.85 accepted a list of arguments
361rather than a reference. Version 0.85+ are backwards compatible.
362
363Returns true or false.
364
365=cut
366
367sub setTemplate {
368    my $self = shift;
369    my $args = (ref($_[0]) eq "HASH") ? shift : { @_ };
370
371    if (! $self->check_setTemplate($args)) {
372      return 0;
373    }
374
375    my $call = $self->_Client->call(
376				    "blogger.setTemplate",
377				    $self->_Type(string=>$self->AppKey()),
378				    $self->_Type(string=>$self->BlogId()),
379				    $self->_Type(string=>$self->Username()),
380				    $self->_Type(string=>$self->Password()),
381				    $self->_Type(string=>${$args->{'template'}}),
382				    $self->_Type(string=>$args->{'type'}),
383				    );
384
385    ($call) ? return $call->result() : return 0;
386}
387
388=head2 $pkg->getTemplate(\%args)
389
390Fetch the body of the template matching type I<$type>.
391
392Valid types are
393
394=over 4
395
396=item *
397
398B<type>
399
400String. I<required>
401
402Valid types are "main" and "archiveIndex"
403
404=back
405
406Releases prior to Net::Blogger 0.85 accepted a list of arguments
407rather than a reference. Version 0.85+ are backwards compatible.
408
409Returns a string.
410
411=cut
412
413sub getTemplate {
414    my $self = shift;
415    my $args = (ref($_[0]) eq "HASH") ? shift : { @_ };
416
417    if (! $self->check_getTemplate($args)) {
418      return 0;
419    }
420
421    my $call = $self->_Client->call(
422				    "blogger.getTemplate",
423				    $self->_Type(string=>$self->AppKey()),
424				    $self->_Type(string=>$self->BlogId()),
425				    $self->_Type(string=>$self->Username()),
426				    $self->_Type(string=>$self->Password()),
427				    $self->_Type(string=>$args->{'type'}),
428				    );
429
430    ($call) ? return $call->result() : return 0;
431}
432
433sub check_exceedsMaxLength {
434  my $self = shift;
435  my $args = shift;
436
437  if (! $self->MaxPostLength()) {
438    return 0;
439  }
440
441  if (length(${$args->{'postbody'}}) < $self->MaxPostLength()) {
442    return 0;
443  }
444
445  return 1;
446}
447
448sub check_newPost {
449  my $self = shift;
450  my $args = shift;
451
452  if (ref($args->{'postbody'}) ne "SCALAR") {
453    $self->LastError("You must pass postbody as a scalar reference.");
454    return 0;
455  }
456
457  return 1;
458}
459
460sub check_getPost {
461  my $self   = shift;
462  my $postid = shift;
463
464  if (! $postid) {
465    $self->LastError("You must specify a postid.");
466    return 0;
467  }
468
469  return 1;
470}
471
472sub check_getRecentPosts {
473  my $self = shift;
474  my $args = shift;
475
476  my $num   = (defined $args->{'numposts'}) ? $args->{'numposts'} : 1;
477
478  unless ($num =~ /^(\d+)$/) {
479    $self->LastError("Argument $args->{'numposts'} isn't numeric.");
480    return 0;
481  }
482
483  unless (($num >= 1) && ($num <= 20)) {
484    $self->LastError("You must specify 'numposts' as an integer between 1 and 20.");
485    return (0);
486  }
487
488  return 1;
489}
490
491sub check_editPost {
492  my $self = shift;
493  my $args = shift;
494
495  if (! $args->{'postid'}) {
496    $self->LastError("You must specify a postid.");
497    return 0;
498  }
499
500  if (ref($args->{'postbody'}) ne "SCALAR") {
501    $self->LastError("You must pass postbody as a scalar reference.");
502    return 0;
503  }
504
505    return 1;
506}
507
508sub check_deletePost {
509  my $self = shift;
510  my $args = shift;
511
512  if (! $args->{'postid'}) {
513    $self->LastError("No post id.");
514    return 0;
515  }
516
517  return 1;
518}
519
520sub check_setTemplate {
521  my $self = shift;
522  my $args = shift;
523
524  if (ref($args->{'template'}) ne "SCALAR") {
525    $self->LastError("You must pass template as a scalar reference.");
526    return 0;
527  }
528
529  unless ($args->{'type'} =~ /^(main|archiveIndex)$/) {
530    $self->LastError("Valid template types are 'main' and 'archiveIndex'.");
531    return 0;
532  }
533
534  # see also : The Perl Cookbook, chapter 6.15
535  unless (${$args->{'template'}} =~ /(<Blogger>)[^<]*(?:(?! <\/?Blogger>)<[^<]*)*(<\/Blogger>)/m) {
536    $self->LastError("Your template must contain opening and closing <Blogger> tags.");
537    return 0;
538  }
539
540  return 1;
541}
542
543sub check_getTemplate {
544  my $self = shift;
545  my $args = shift;
546
547  unless ($args->{'type'} =~ /^(main|archiveIndex)$/) {
548    $self->LastError("Valid template types are 'main' and 'archiveIndex'.");
549    return 0;
550  }
551
552  return 1;
553}
554
555=head1 VERSION
556
5571.0
558
559=head1 DATE
560
561$Date: 2005/03/26 19:29:08 $
562
563=head1 AUTHOR
564
565Aaron Straup Cope
566
567=head1 SEE ALSO
568
569L<Net::Blogger::Engine::Base>
570
571L<Net::Blogger::API::Extended>
572
573=head1 LICENSE
574
575Copyright (c) 2001-2005 Aaron Straup Cope.
576
577This is free software, you may use it and distribute it under the same terms as Perl itself.
578
579=cut
580
581return 1;
582
583}
584