File Coverage

blib/lib/Net/Backpack.pm
Criterion Covered Total %
statement 25 397 6.3
branch 0 124 0.0
condition 1 36 2.8
subroutine 8 49 16.3
pod 40 40 100.0
total 74 646 11.5


line stmt bran cond sub pod time code
1             # $Id$
2              
3             =head1 NAME
4            
5             Net::Backpack - Perl extension for interfacing with Backpack
6            
7             =head1 SYNOPSIS
8            
9             use Net::Backpack;
10            
11             my $bp = Net::Backpack(user => $your_backpack_username,
12             token => $your_backpack_api_token,
13             ssl => $use_ssl);
14            
15             # Fill out a Perl data structure with information about
16             # your Backspace pages.
17             my $pages = $bp->list_all_pages;
18            
19             # Alternatively get the same information in XML format
20             # my $pages = $bp->list_all_pages(xml => 1);
21            
22             # Create a new page
23             my $page = $bp->create_page(title => 'A test page',
24             description => 'Created with the Backpack API');
25            
26             # Get the id of the new page
27             my $page_id = $page->{page}{id};
28            
29             # Get details of the new page (in XML format)
30             my $page_xml = $bp->show_page(id => $page->{page}{id});
31            
32             # Rename the page
33             $bp->update_title(id => $page_id,
34             title => 'A new title');
35            
36             # Change the body
37             $bp->update_description(id => $page_id,
38             description => 'Something new');
39            
40             # Remove the page
41             $bp->destroy_page(id => $page_id);
42            
43             =head1 DESCRIPTION
44            
45             Net::Backpack provides a thin Perl wrapper around the Backpack API
46             (L<http://backpackit.com/api/>). Currently it only implements the
47             parts of the API that manipulate Backpack pages. Future releases
48             will increase the coverage.
49            
50             =head2 Getting Started
51            
52             In order to use the Backpack API, you'll need to have a Backpack
53             API token. And in order to get one of those, you'll need a Backpack
54             account. But then again, the API will be pretty useless to you if
55             you don't have a Backpack account to manipulate with it.
56            
57             You can get a Backpack account from L<http://backbackit.com/signup>.
58            
59             =head2 Backback API
60            
61             The Backpack API is based on XML over HTTP. You send an XML message
62             over HTTP to the Backpack server and the server sends a response to
63             you which is also in XML. The format of the various XML requests and
64             responses are defined at L<http://backpackit.com/api>.
65            
66             This module removes the need to deal with any XML. You create an
67             object to talk to the Backpack server and call methods on that object
68             to manipulate your Backpage pages. The values returned from Backpack
69             are converted to Perl data structures before being handed back to
70             you (although it is also possible to get back the raw XML).
71            
72             =head1 Important Note
73            
74             Net::Backpack uses XML::Simple to parse the data that is returned from
75             Backpack. From version 1.10 of Net::Backpack has changed. By default we
76             now pass the parameter C<ForceArray =E<gt> 1> to XML::Simple. This will
77             change the Perl data structure returned by most calls.
78            
79             To get the old behaviour back, you can pass the parameter C<forcearray
80             =E<gt> 0> to the C<new> function.
81            
82             =cut
83              
84             package Net::Backpack;
85              
86 2     2   131832 use 5.006;
  2         6  
  2         30  
87 2     2   6 use strict;
  2         2  
  2         26  
88 2     2   6 use warnings;
  2         1  
  2         45  
89              
90 2     2   6 use Carp;
  2         2  
  2         70  
91 2     2   596 use LWP::UserAgent;
  2         41569  
  2         35  
92 2     2   7 use HTTP::Request;
  2         3  
  2         24  
93 2     2   720 use XML::Simple;
  2         11607  
  2         12  
94              
95             our $VERSION = '1.14';
96              
97             my %data = (
98             'list_all_pages' =>
99             {
100             url => '/ws/pages/all',
101             req => '<request>
102             <token>[S:token]</token>
103             </request>'
104             },
105             'create_page' =>
106             {
107             url => '/ws/pages/new',
108             req => '<request>
109             <token>[S:token]</token>
110             <page>
111             <title>[P:title]</title>
112             <description>[P:description]</description>
113             </page>
114             </request>'
115             },
116             'show_page' =>
117             {
118             url => '/ws/page/[P:id]',
119             req => '<request>
120             <token>[S:token]</token>
121             </request>'
122             },
123             'destroy_page' =>
124             {
125             url => '/ws/page/[P:id]/destroy',
126             req => '<request>
127             <token>[S:token]</token>
128             </request>'
129             },
130             'update_title' =>
131             {
132             url => '/ws/page/[P:id]/update_title',
133             req => '<request>
134             <token>[S:token]</token>
135             <page><title>[P:title]</title></page>
136             </request>'
137             },
138             update_body =>
139             {
140             url => '/ws/page/[P:id]/update_body',
141             req => '<request>
142             <token>[S:token]</token>
143             <page><description>[P:description]</description></page>
144             </request>'
145             },
146             'duplicate_page' =>
147             {
148             url => '/ws/page/[P:id]/duplicate',
149             req => '<request>
150             <token>[S:token]</token>
151             </request>'
152             },
153             'link_page' =>
154             {
155             url => '/ws/page/[P:to_page]/link',
156             req => '<request>
157             <token>[S:token]</token>
158             <linked_page_id>[P:link_page]</linked_page_id>
159             </request>'
160             },
161             'unlink_page' =>
162             {
163             url => '/ws/page/[P:from_page]/link',
164             req => '<request>
165             <token>[S:token]</token>
166             <linked_page_id>[P:link_page]</linked_page_id>
167             </request>'
168             },
169             'share_people' =>
170             {
171             url => '/ws/page/[P:id]/share',
172             req => '<request>
173             <token>[S:token]</token>
174             <email_addresses>
175             [P:people]
176             </email_addresses>
177             </request>'
178             },
179             'make_page_public' =>
180             {
181             url => '/ws/page/[P:id]/share',
182             req => '<request>
183             <token>[S:token]</token>
184             <page>
185             <public>[P:public]</public>
186             </page>
187             </request>'
188             },
189             'unshare_friend_page' =>
190             {
191             url => '/ws/page/[P:id]/unshare_friend_page',
192             req => '<request>
193             <token>[S:token]</token>
194             </request>'
195             },
196             'email_page' =>
197             {
198             url => '/ws/page/[P:id]/email',
199             req => '<request>
200             <token>[S:token]</token>
201             </request>'
202             },
203             'list_all_items' =>
204             {
205             url => '/ws/page/[P:page_id]/items/list',
206             req => '<request>
207             <token>[S:token]</token>
208             </request>'
209             },
210             'create_item' =>
211             {
212             url => '/ws/page/[P:page_id]/items/add',
213             req => '<request>
214             <token>[S:token]</token>
215             <item>
216             <content>[P:item]</content>
217             </item>
218             </request>'
219             },
220             'update_item' =>
221             {
222             url => '/ws/page/[P:page_id]/items/update/[P:id]',
223             req => '<request>
224             <token>[S:token]</token>
225             <item>
226             <content>[P:item]</content>
227             </item>
228             </request>'
229             },
230             'toggle_item' =>
231             {
232             url => '/ws/page/[P:page_id]/items/toggle/[P:id]',
233             req => '<request>
234             <token>[S:token]</token>
235             </request>'
236             },
237             'destroy_item' =>
238             {
239             url => '/ws/page/[P:page_id]/items/destroy/[P:id]',
240             req => '<request>
241             <token>[S:token]</token>
242             </request>'
243             },
244             'move_item' =>
245             {
246             url => '/ws/page/[P:page_id]/items/move/[P:id]',
247             req => '<request>
248             <token>[S:token]</token>
249             <direction>[P:direction]</direction>
250             </request>'
251             },
252             'list_all_notes' =>
253             {
254             url => '/ws/page/[P:page_id]/notes/list',
255             req => '<request>
256             <token>[S:token]</token>
257             </request>'
258             },
259             'create_note' =>
260             {
261             url => '/ws/page/[P:page_id]/notes/create',
262             req => '<request>
263             <token>[S:token]</token>
264             <note>
265             <title>[P:title]</title>
266             <body>[P:body]</body>
267             </note>
268             </request>'
269             },
270             'update_note' =>
271             {
272             url => '/ws/page/[P:page_id]/notes/update/[P:id]',
273             req => '<request>
274             <token>[S:token]</token>
275             <note>
276             <title>[P:title]</title>
277             <body>[P:body]</body>
278             </note>
279             </request>'
280             },
281             'destroy_note' =>
282             {
283             url => '/ws/page/[P:page_id]/notes/destroy/[P:id]',
284             req => '<request>
285             <token>[S:token]</token>
286             </request>'
287             },
288             'get_tag_pages' =>
289             {
290             url => '/ws/tags/[P:page_id]',
291             req => '<request>
292             <token>[S:token]</token>
293             </request>'
294             },
295             'set_page_tags' =>
296             {
297             url => '/ws/page/[P:page_id]/tags/tag',
298             req => '<request>
299             <token>[S:token]</token>
300             <tags>[P:tags]</tags>
301             </request>'
302             },
303             'upcoming_reminders' =>
304             {
305             url => '/ws/reminders',
306             req => '<request>
307             <token>[S:token]</token>
308             </request>'
309             },
310             'create_reminder' =>
311             {
312             url => '/ws/reminders/create',
313             req => '<request>
314             <token>[S:token]</token>
315             <reminder>
316             <content>[P:content]</content>
317             <remind_at>[P:remind_at]</remind_at>
318             </reminder>
319             </request>'
320             },
321             'update_reminder' =>
322             {
323             url => '/ws/reminders/update/[P:id]',
324             req => '<request>
325             <token>[S:token]</token>
326             <reminder>
327             <content>[P:content]</content>
328             <remind_at>[P:remind_at]</remind_at>
329             </reminder>
330             </request>'
331             },
332             'destroy_reminder' =>
333             {
334             url => '/ws/reminders/destroy/[P:id]',
335             req => '<request>
336             <token>[S:token]</token>
337             </request>'
338             },
339             'list_all_emails' =>
340             {
341             url => '/ws/page/[P:page_id]/emails/list',
342             req => '<request>
343             <token>[S:token]</token>
344             </request>'
345             },
346             'show_email' =>
347             {
348             url => '/ws/page/[P:page_id]/emails/show/[P:id]',
349             req => '<request>
350             <token>[S:token]</token>
351             </request>'
352             },
353             'destroy_email' =>
354             {
355             url => '/ws/page/[P:page_id]/emails/destroy/[P:id]',
356             req => '<request>
357             <token>[S:token]</token>
358             </request>'
359             },
360             'export' =>
361             {
362             url => '/ws/account/export',
363             req => '<request>
364             <token>[S:token]</token>
365             </request>'
366             },
367             'list_all_lists' =>
368             {
369             url => '/ws/page/[P:page_id]/lists/list',
370             req => '<request>
371             <token>[S:token]</token>
372             </request>'
373             },
374             'list_this_list' =>
375             {
376             url => '/ws/page/[P:page_id]/items/list?list_id=[P:list_id]',
377             req => '<request>
378             <token>[S:token]</token>
379             </request>'
380             },
381             'create_list' =>
382             {
383             url => '/ws/page/[P:page_id]/lists/add',
384             req => '<request>
385             <token>[S:token]</token>
386             <name>[P:title]</name>
387             </request>'
388             },
389             'update_list' =>
390             {
391             url => '/ws/page/[P:page_id]/lists/update/[P:list_id]',
392             req => '<request>
393             <token>[S:token]</token>
394             <list>
395             <name>[P:title]</name>
396             </list>
397             </request>'
398             },
399             'destroy_list' =>
400             {
401             url => '/ws/page/[P:page_id]/lists/destroy/[P:list_id]',
402             req => '<request>
403             <token>[S:token]</token>
404             </request>'
405             },
406             'create_list_item' =>
407             {
408             url => '/ws/page/[P:page_id]/items/add?list_id=[P:list_id]',
409             req => '<request>
410             <token>[S:token]</token>
411             <item>
412             <content>[P:item]</content>
413             </item>
414             </request>'
415             },
416             );
417              
418             =head1 METHODS
419            
420             =head2 $bp = Net::Backpack->new(token => $token, user => $user, [forcearray => 0], ssl => 0);
421            
422             Creates a new Net::Backpack object. All communication with the
423             Backpack server is made through this object.
424            
425             Takes two mandatory arguments, your Backpack API token and your
426             Backpack username. Returns the new Net:Backpack object.
427            
428             There is also an optional parameter, forcearray. This controls the
429             value of the C<ForceArray> parameter that is used by C<XML::Simple>. The
430             default value is 1.
431            
432             If the C<ssl> parameter is provided, then communication will take
433             place over SSL. This is required for Plus and Premium accounts.
434            
435             =cut
436              
437             sub new {
438 3     3 1 119692   my $class = shift;
439 3         8   my %params = @_;
440              
441 3         3   my $self;
442 3   33     249   $self->{token} = $params{token}
443                 || croak "No Backpack API token passed Net::Backpack::new\n";
444 0   0         $self->{user} = $params{user}
445                 || croak "No Backpack API user passed Net::Backpack::new\n";
446              
447 0 0           $self->{protocol} = $params{ssl} ? 'https' : 'http';
448              
449 0   0         $self->{forcearray} = $params{forcearray} || 1;
450              
451 0             $self->{ua} = LWP::UserAgent->new;
452 0             $self->{ua}->env_proxy;
453 0             $self->{ua}->default_header('X-POST-DATA-FORMAT' => 'xml');
454              
455 0             $self->{base_url} = "$self->{protocol}://$self->{user}.backpackit.com";
456              
457 0             return bless $self, $class;
458             }
459              
460             =head2 $pages = $bp->list_all_pages([xml => 1]);
461            
462             Get a list of all of your Backpack pages. Returns a Perl data structure
463             unless the C<xml> parameter is true, in which case it returns the raw
464             XML as returned by the Backpack server.
465            
466             =cut
467              
468             sub list_all_pages {
469 0     0 1     my $self = shift;
470 0             my %params = @_;
471              
472 0             my $req_data = $data{list_all_pages};
473 0             my $url = $self->{base_url} . $req_data->{url};
474              
475 0             my $req = HTTP::Request->new('POST', $url);
476 0             $req->content($self->_expand($req_data->{req}, %params));
477              
478 0             return $self->_call(%params, req => $req);
479             }
480              
481             =head2 $page = $bp->create_page(title => $title,
482             [description => $desc, xml => 1]);
483            
484             Create a new Backpack page with the given title and (optional)
485             description. Returns a Perl data structure unless the C<xml> parameter is
486             true, in which case it returns the raw XML as returned by the Backpack server.
487            
488             =cut
489              
490             sub create_page {
491 0     0 1     my $self = shift;
492 0             my %params = @_;
493              
494 0 0           croak 'No title for new page' unless $params{title};
495 0   0         $params{description} ||= '';
496              
497 0             my $req_data = $data{create_page};
498 0             my $url = $self->{base_url} . $req_data->{url};
499              
500 0             my $req = HTTP::Request->new(POST => $url);
501 0             $req->content($self->_expand($req_data->{req}, %params));
502              
503 0             return $self->_call(%params, req => $req);
504             }
505              
506             =head2 $rc = $bp->show_page(id => $id, [xml => 1]);
507            
508             Get details of the Backpack page with the given id. Returns a Perl data
509             structure unless the C<xml> parameter is true, in which case it returns the
510             raw XML as returned by the Backpack server.
511            
512             =cut
513              
514             sub show_page {
515 0     0 1     my $self = shift;
516 0             my %params = @_;
517              
518 0 0           croak 'No id' unless $params{id};
519              
520 0             my $req_data = $data{show_page};
521 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
522              
523 0             my $req = HTTP::Request->new(POST => $url);
524              
525 0             $req->content($self->_expand($req_data->{req}, %params));
526              
527 0             return $self->_call(%params, req => $req);
528             }
529              
530             =head2 $rc = $bp->destroy_page(id => $id, [xml => 1]);
531            
532             Delete the Backpack page with the given id. Returns a Perl data structure
533             unless the C<xml> parameter is true, in which case it returns the raw XML
534             as returned by the Backpack server.
535            
536             =cut
537              
538             sub destroy_page {
539 0     0 1     my $self = shift;
540 0             my %params = @_;
541              
542 0 0           croak 'No id' unless $params{id};
543              
544 0             my $req_data = $data{destroy_page};
545 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
546              
547 0             my $req = HTTP::Request->new(POST => $url);
548              
549 0             $req->content($self->_expand($req_data->{req}, %params));
550              
551 0             return $self->_call(%params, req => $req);
552             }
553              
554             =head2 $rc = $bp->update_title(id => $id, title => $title, [xml => 1]);
555            
556             Update the title of the given Backpack page. Returns a Perl data structure
557             unless the C<xml> parameter is true, in which case it returns the raw XML
558             as returned by the Backpack server.
559            
560             =cut
561              
562             sub update_title {
563 0     0 1     my $self = shift;
564 0             my %params = @_;
565              
566 0 0           croak 'No id' unless $params{id};
567 0 0           croak 'No title' unless $params{title};
568              
569 0             my $req_data = $data{update_title};
570 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
571              
572 0             my $req = HTTP::Request->new(POST => $url);
573              
574 0             $req->content($self->_expand($req_data->{req}, %params));
575              
576 0             return $self->_call(%params, req => $req);
577             }
578              
579             =head2 $rc = $bp->update_body(id => $id, description => $desc, [xml => 1]);
580            
581             Update the description of the given Backpack page. Returns a Perl data
582             structure unless the C<xml> parameter is true, in which case it returns the
583             raw XML as returned by the Backpack server.
584            
585             =cut
586              
587             sub update_body {
588 0     0 1     my $self = shift;
589 0             my %params = @_;
590              
591 0 0           croak 'No id' unless $params{id};
592 0 0           croak 'No description' unless defined $params{description};
593              
594 0             my $req_data = $data{update_body};
595 0             my $url = $self->{base_url} .$self->_expand($req_data->{url}, %params);
596 0             my $req = HTTP::Request->new(POST => $url);
597              
598 0             $req->content($self->_expand($req_data->{req}, %params));
599              
600 0             return $self->_call(%params, req => $req);
601             }
602              
603             =head2 $page = $bp->duplicate_page(id => $id, [xml => 1]);
604            
605             Create a duplicate of the given Backpack page. Returns a Perl data
606             structure unless the C<xml> parameter is true, in which case it returns the
607             raw XML as returned by the Backpack server.
608            
609             =cut
610              
611             sub duplicate_page {
612 0     0 1     my $self = shift;
613 0             my %params = @_;
614              
615 0 0           croak 'No id' unless $params{id};
616              
617 0             my $req_data = $data{duplicate_page};
618 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
619 0             my $req = HTTP::Request->new(POST => $url);
620              
621 0             $req->content($self->_expand($req_data->{req}, %params));
622              
623 0             return $self->_call(%params, req => $req);
624             }
625              
626             =head2 $rc = $bp->link_page(link_page => $id1, to_page => $id2, [xml => 1]);
627            
628             Link one Backpack page to another. Returns a Perl data structure unless the
629             C<xml> parameter is true, in which case it returns the raw XML as returned
630             by the Backpack server.
631            
632             =cut
633              
634             sub link_page {
635 0     0 1     my $self = shift;
636 0             my %params = @_;
637              
638 0 0 0         croak 'No id' unless $params{link_page} and $params{to_page};
639              
640 0             my $req_data = $data{link_page};
641 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
642 0             my $req = HTTP::Request->new(POST => $url);
643              
644 0             $req->content($self->_expand($req_data->{req}, %params));
645              
646 0             return $self->_call(%params, req => $req);
647             }
648              
649             =head2 $rc = $bp->unlink_page(link_page => $id1, from_page => $id2,
650             [xml => 1]);
651            
652             Unlink one Backpack page from another. Returns a Perl data structure unless
653             the C<xml> parameter is true, in which case it returns the raw XML as returned
654             by the Backpack server.
655            
656             =cut
657              
658             sub unlink_page {
659 0     0 1     my $self = shift;
660 0             my %params = @_;
661              
662 0 0 0         croak 'No id' unless $params{link_page} and $params{from_page};
663              
664 0             my $req_data = $data{unlink_page};
665 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
666 0             my $req = HTTP::Request->new(POST => $url);
667              
668 0             $req->content($self->_expand($req_data->{req}, %params));
669              
670 0             return $self->_call(%params, req => $req);
671             }
672              
673             =head2 $rc = $bp->share_page(id => $id, people => \@people,
674             [ xml => 1 ]);
675            
676             Share a given Backpack page with a list of other people. The parameter
677             'people' is a list of email addresses of the people you wish to share the
678             page with.
679            
680             =cut
681              
682             sub share_page {
683 0     0 1     my $self = shift;
684 0             my %params = @_;
685              
686 0 0           croak 'No id' unless $params{id};
687 0 0           croak 'No people' unless scalar @{$params{people}};
  0            
688              
689 0             $params{people} = join "\n", @{$params{people}};
  0            
690 0             my $req_data = $data{share_people};
691 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
692 0             my $req = HTTP::Request->new(POST => $url);
693              
694 0             $req->content($self->_expand($req_data->{req}, %params));
695              
696 0             return $self->_call(%params, req => $req);
697             }
698              
699             =head2 $rc = $bp->make_page_public(id => $id, public => $public,
700             [ xml => 1 ]);
701            
702             Make a given Backpage page public or private. The parameter 'public' is
703             a boolean flag indicating whether the page should be made public or
704             private
705            
706             =cut
707              
708             sub make_page_public {
709 0     0 1     my $self = shift;
710 0             my %params = @_;
711              
712 0 0           croak 'No id' unless $params{id};
713 0 0           croak 'No public flag' unless exists $params{public};
714              
715 0             $params{public} = !!$params{public};
716 0             my $req_data = $data{make_page_public};
717 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
718 0             my $req = HTTP::Request->new(POST => $url);
719              
720 0             $req->content($self->_expand($req_data->{req}, %params));
721              
722 0             return $self->_call(%params, req => $req);
723             }
724              
725             =head2 $rc = $bp->unshare_friend_page(id => $id, [ xml => 1 ]);
726            
727             Unshare yourself from a friend's page.
728            
729             =cut
730              
731             sub unshare_friend_page {
732 0     0 1     my $self = shift;
733 0             my %params = @_;
734              
735 0 0           croak 'No id' unless $params{id};
736              
737 0             my $req_data = $data{unshare_friend_page};
738 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
739 0             my $req = HTTP::Request->new(POST => $url);
740              
741 0             $req->content($self->_expand($req_data->{req}, %params));
742              
743 0             return $self->_call(%params, req => $req);
744             }
745              
746              
747             =head2 $rc = $bp->email_page(id => $id, [ xml => 1 ]);
748            
749             Email a page to yourself.
750            
751             =cut
752              
753             sub email_page {
754 0     0 1     my $self = shift;
755 0             my %params = @_;
756              
757 0 0           croak 'No id' unless $params{id};
758              
759 0             my $req_data = $data{email_page};
760 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
761 0             my $req = HTTP::Request->new(POST => $url);
762              
763 0             $req->content($self->_expand($req_data->{req}, %params));
764              
765 0             return $self->_call(%params, req => $req);
766             }
767              
768             =head2 $items = $bp->list_all_items(page_id => $page_id, [xml => 1]);
769            
770             Get a list of all of your Backpack checklist items. Returns a Perl data structure
771             unless the C<xml> parameter is true, in which case it returns the raw
772             XML as returned by the Backpack server.
773            
774             =cut
775              
776             sub list_all_items {
777 0     0 1     my $self = shift;
778 0             my %params = @_;
779              
780 0 0           croak 'No id' unless $params{page_id};
781               
782 0             my $req_data = $data{list_all_items};
783 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
784              
785 0             my $req = HTTP::Request->new('POST', $url);
786 0             $req->content($self->_expand($req_data->{req}, %params));
787              
788 0             return $self->_call(%params, req => $req);
789             }
790              
791             =head2 $item = $bp->create_item(page_id => $page_id, item => $item, [xml => 1]);
792            
793             Create a Backpack checklist item given a page id and some item content.
794             Returns a Perl data structure unless the C<xml> parameter is true, in which case
795             it returns the raw XML as returned by the Backpack server.
796            
797             =cut
798              
799             sub create_item {
800 0     0 1     my $self = shift;
801 0             my %params = @_;
802              
803 0 0           croak 'No page id' unless $params{page_id};
804 0 0           croak 'No item content' unless $params{item};
805              
806 0             my $req_data = $data{create_item};
807 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
808              
809 0             my $req = HTTP::Request->new('POST', $url);
810 0             $req->content($self->_expand($req_data->{req}, %params));
811              
812 0             return $self->_call(%params, req => $req);
813             }
814              
815             =head2 $item = $bp->update_item(page_id => $page_id, item => $item, [xml => 1]
816             id => $item_id);
817            
818             Updates a Backpack checklist item given a page id, item id, and new content.
819             Returns a Perl data structure unless the C<xml> parameter is true, in which
820             case it returns the raw XML as returned by the Backpack server.
821            
822             =cut
823              
824             sub update_item {
825 0     0 1     my $self = shift;
826 0             my %params = @_;
827              
828 0 0           croak 'No page id' unless $params{page_id};
829 0 0           croak 'No item id' unless $params{id};
830 0 0           croak 'No item content' unless $params{item};
831              
832 0             my $req_data = $data{update_item};
833 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
834              
835 0             my $req = HTTP::Request->new('POST', $url);
836 0             $req->content($self->_expand($req_data->{req}, %params));
837              
838 0             return $self->_call(%params, req => $req);
839             }
840              
841             =head2 $response = $bp->toggle_item(page_id => $page_id, id => $item_id,
842             [xml => 1]);
843            
844             Toggles a Backpack checklist item given a page id and an item id.
845             Returns a Perl data structure unless the C<xml> parameter is true, in which
846             case it returns the raw XML as returned by the Backpack server.
847            
848             =cut
849              
850             sub toggle_item {
851 0     0 1     my $self = shift;
852 0             my %params = @_;
853              
854 0 0           croak 'No page id' unless $params{page_id};
855 0 0           croak 'No item id' unless $params{id};
856              
857 0             my $req_data = $data{toggle_item};
858 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
859              
860 0             my $req = HTTP::Request->new('POST', $url);
861 0             $req->content($self->_expand($req_data->{req}, %params));
862              
863 0             return $self->_call(%params, req => $req);
864             }
865              
866             =head2 $response = $bp->destroy_item(page_id => $page_id, id => $item_id,
867             [xml => 1]);
868            
869             Destroys a Backpack checklist item given a page id and an item id.
870             Returns a Perl data structure unless the C<xml> parameter is true, in which
871             case it returns the raw XML as returned by the Backpack server.
872            
873             =cut
874              
875             sub destroy_item {
876 0     0 1     my $self = shift;
877 0             my %params = @_;
878              
879 0 0           croak 'No page id' unless $params{page_id};
880 0 0           croak 'No item id' unless $params{id};
881              
882 0             my $req_data = $data{destroy_item};
883 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
884              
885 0             my $req = HTTP::Request->new('POST', $url);
886 0             $req->content($self->_expand($req_data->{req}, %params));
887              
888 0             return $self->_call(%params, req => $req);
889             }
890              
891             =head2 $response = $bp->move_item(page_id => $page_id, id => $item_id,
892             direction => $direction, [xml => 1]);
893            
894             Modifies the location in the list of a Backpack checklist item. Requires a
895             page id, a direction and an item id. Valid values for direction are
896             "move_lower", "move_higher", "move_to_top", and "move_to_bottom". Returns a
897             Perl data structure unless the C<xml> parameter is true, in which case it
898             returns the raw XML as returned by the Backpack server.
899            
900             =cut
901              
902             sub move_item {
903 0     0 1     my $self = shift;
904 0             my %params = @_;
905              
906 0 0           croak 'No page id' unless $params{page_id};
907 0 0           croak 'No item id' unless $params{id};
908 0 0 0         unless (exists $params{direction} &&
909                       $params{direction} =~ /move_(lower|higher|to_top|to_bottom)/) {
910 0               croak 'No direction specified';
911               }
912              
913 0             my $req_data = $data{move_item};
914 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
915             #print "url : $url\n";
916             #sleep 2;
917 0             my $req = HTTP::Request->new('POST', $url);
918 0             $req->content($self->_expand($req_data->{req}, %params));
919              
920 0             return $self->_call(%params, req => $req);
921             }
922              
923             =head2 $notes = $bp->list_all_notes(page_id => $page_id, [xml => 1]);
924            
925             Get a list of all of your Backpack notes. Returns a Perl data structure
926             unless the C<xml> parameter is true, in which case it returns the raw
927             XML as returned by the Backpack server.
928            
929             =cut
930              
931             sub list_all_notes {
932 0     0 1     my $self = shift;
933 0             my %params = @_;
934              
935 0 0           croak 'No id' unless $params{page_id};
936               
937 0             my $req_data = $data{list_all_notes};
938 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
939              
940 0             my $req = HTTP::Request->new('POST', $url);
941 0             $req->content($self->_expand($req_data->{req}, %params));
942              
943 0             return $self->_call(%params, req => $req);
944             }
945              
946             =head2 $note = $bp->create_note(page_id => $page_id, title => $title,
947             body => $body, [xml => 1]);
948            
949             Create a Backpack note given a page id and some content. Title is required,
950             body is optional. Returns a Perl data structure unless the C<xml> parameter
951             is true, in which case it returns the raw XML as returned by the Backpack
952             server.
953            
954             =cut
955              
956             sub create_note {
957 0     0 1     my $self = shift;
958 0             my %params = @_;
959              
960 0 0           croak 'No page id' unless $params{page_id};
961 0 0           croak 'No note title' unless $params{title};
962              
963 0   0         $params{body} ||= "";
964               
965 0             my $req_data = $data{create_note};
966 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
967              
968 0             print "url: $url\n";
969              
970 0             my $req = HTTP::Request->new('POST', $url);
971 0             $req->content($self->_expand($req_data->{req}, %params));
972              
973 0             return $self->_call(%params, req => $req);
974             }
975              
976             =head2 $note = $bp->update_note(page_id => $page_id, id => $note_id, [xml => 1]
977             title => $title, body => $body);
978            
979             Updates a Backpack note given a page id, note id, and new content.
980             Returns a Perl data structure unless the C<xml> parameter is true, in which
981             case it returns the raw XML as returned by the Backpack server.
982            
983             =cut
984              
985             sub update_note {
986 0     0 1     my $self = shift;
987 0             my %params = @_;
988              
989 0 0           croak 'No page id' unless $params{page_id};
990 0 0           croak 'No note id' unless $params{id};
991              
992 0   0         $params{title} ||= "";
993 0   0         $params{body} ||= "";
994                 
995 0             my $req_data = $data{update_note};
996 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
997              
998 0             my $req = HTTP::Request->new('POST', $url);
999 0             $req->content($self->_expand($req_data->{req}, %params));
1000              
1001 0             return $self->_call(%params, req => $req);
1002             }
1003              
1004             =head2 $response = $bp->destroy_note(page_id => $page_id, id => $note_id,
1005             [xml => 1]);
1006            
1007             Destroys a Backpack note given a page id and an note id.
1008             Returns a Perl data structure unless the C<xml> parameter is true, in which
1009             case it returns the raw XML as returned by the Backpack server.
1010            
1011             =cut
1012              
1013             sub destroy_note {
1014 0     0 1     my $self = shift;
1015 0             my %params = @_;
1016              
1017 0 0           croak 'No page id' unless $params{page_id};
1018 0 0           croak 'No note id' unless $params{id};
1019              
1020 0             my $req_data = $data{destroy_note};
1021 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
1022              
1023 0             my $req = HTTP::Request->new('POST', $url);
1024 0             $req->content($self->_expand($req_data->{req}, %params));
1025              
1026 0             return $self->_call(%params, req => $req);
1027             }
1028              
1029             =head2 $pages = $bp->get_tag_pages(page_id => $id, [ xml => 1 ]);
1030            
1031             Retrieve all the pages associated with a particular tag id. Returns a Perl
1032             data structure unless the C<xml> parameter is true, in which case it returns
1033             the raw XML as returned by the Backpack server.
1034            
1035             =cut
1036              
1037             sub get_tag_pages {
1038 0     0 1     my $self = shift;
1039 0             my %params = @_;
1040              
1041 0 0           croak 'No page id' unless $params{page_id};
1042              
1043 0             my $req_data = $data{get_tag_pages};
1044 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
1045 0             my $req = HTTP::Request->new(POST => $url);
1046              
1047 0             $req->content($self->_expand($req_data->{req}, %params));
1048              
1049 0             return $self->_call(%params, req => $req);
1050             }
1051              
1052             =head2 $response = $bp->set_page_tags(page_id => $id, tags => \@tags,
1053             [ xml => 1 ]);
1054            
1055             Set the tags for a given Backpack page. This method overwrites all tags for
1056             the page. An empty set of tags serves to remove all the tags for the page.
1057             Returns a Perl data structure unless the C<xml> parameter is true, in which
1058             case it returns the raw XML as returned by the Backpack server.
1059            
1060             This is currently returning true, and though it seems to create and submit a
1061             valid request, the tags are not being updated.
1062            
1063             =cut
1064              
1065             sub set_page_tags {
1066 0     0 1     my $self = shift;
1067 0             my %params = @_;
1068              
1069 0 0           croak 'No page id' unless $params{page_id};
1070              
1071 0             $params{tags} = join "\n", map { '"'.$_.'"' } @{$params{tags}};
  0            
  0            
1072 0             my $req_data = $data{set_page_tags};
1073              
1074 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
1075              
1076             # print $url.$self->_expand($req_data->{req}, %params);
1077              
1078 0             my $req = HTTP::Request->new(POST => $url);
1079              
1080 0             $req->content($self->_expand($req_data->{req}, %params));
1081              
1082 0             return $self->_call(%params, req => $req);
1083             }
1084              
1085             =head2 $reminders = $bp->upcoming_reminders([ xml => 1 ]);
1086            
1087             Gets the upcoming Backpack reminders for an account, in the time zone
1088             specified per the account's settings.
1089             Returns a Perl data structure unless the C<xml> parameter is true, in which
1090             case it returns the raw XML as returned by the Backpack server.
1091            
1092             =cut
1093              
1094             sub upcoming_reminders {
1095 0     0 1     my $self = shift;
1096 0             my %params = @_;
1097              
1098 0             my $req_data = $data{upcoming_reminders};
1099              
1100 0             my $url = $self->{base_url} . $self->_expand($req_data->{url});
1101 0             my $req = HTTP::Request->new(POST => $url);
1102              
1103 0             $req->content($self->_expand($req_data->{req}, %params));
1104              
1105 0             return $self->_call(%params, req => $req);
1106             }
1107              
1108             =head2 $reminder = $bp->create_reminder(content => $reminder, [xml => 1],
1109             [remind_at => $remind_at]);
1110            
1111             Create a Backpack reminder given some reminder content. The content
1112             takes fuzzy date/times like "+30 Do foo and bar" to set the reminder for 30
1113             minutes from now. Optionally, specify a date in a relatively parseable date
1114             format and use the remind_at parameter instead.
1115             Returns a Perl data structure unless the C<xml> parameter is true, in which
1116             case it returns the raw XML as returned by the Backpack server.
1117            
1118             =cut
1119              
1120             sub create_reminder {
1121 0     0 1     my $self = shift;
1122 0             my %params = @_;
1123              
1124 0 0           croak 'No reminder content' unless $params{content};
1125              
1126 0   0         $params{remind_at} ||= "";
1127               
1128 0             my $req_data = $data{create_reminder};
1129 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
1130              
1131 0             my $req = HTTP::Request->new('POST', $url);
1132 0             $req->content($self->_expand($req_data->{req}, %params));
1133              
1134 0             return $self->_call(%params, req => $req);
1135             }
1136              
1137             =head2 $reminder = $bp->update_reminder(id => $reminder_id,
1138             [content => $reminder], [xml => 1],
1139             [remind_at => $remind_at);
1140            
1141             Update a Backpack reminder given a reminder id. The content takes fuzzy
1142             date/times like "+30 Do foo and bar" to set the reminder for 30 minutes
1143             from now. Optionally, specify a date in a relatively parseable date format
1144             and use the remind_at parameter instead.
1145             Returns a Perl data structure unless the C<xml> parameter is true, in which
1146             case it returns the raw XML as returned by the Backpack server.
1147            
1148             =cut
1149              
1150             sub update_reminder {
1151 0     0 1     my $self = shift;
1152 0             my %params = @_;
1153              
1154 0 0           croak 'No reminder id' unless $params{id};
1155 0 0 0         unless (exists $params{content} && exists $params{remind_at}) {
1156 0               my $reminders = $self->upcoming_reminders();
1157 0   0           $params{content} ||=
1158                   $reminders->{reminders}{reminder}{$params{id}}{content};
1159 0   0           $params{remind_at} ||=
1160                   $reminders->{reminders}{reminder}{$params{id}}{remind_at};
1161               }
1162               
1163 0             my $req_data = $data{update_reminder};
1164 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
1165              
1166 0             my $req = HTTP::Request->new('POST', $url);
1167 0             $req->content($self->_expand($req_data->{req}, %params));
1168              
1169 0             return $self->_call(%params, req => $req);
1170             }
1171              
1172             =head2 $response = $bp->destroy_reminder( id => $reminder_id, [xml => 1]);
1173            
1174             Destroys a Backpack reminder given a reminder id.
1175             Returns a Perl data structure unless the C<xml> parameter is true, in which
1176             case it returns the raw XML as returned by the Backpack server.
1177            
1178             =cut
1179              
1180             sub destroy_reminder {
1181 0     0 1     my $self = shift;
1182 0             my %params = @_;
1183              
1184 0 0           croak 'No reminder id' unless $params{id};
1185              
1186 0             my $req_data = $data{destroy_reminder};
1187 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
1188              
1189 0             my $req = HTTP::Request->new('POST', $url);
1190 0             $req->content($self->_expand($req_data->{req}, %params));
1191              
1192 0             return $self->_call(%params, req => $req);
1193             }
1194              
1195             =head2 $emails = $bp->list_all_emails(page_id => $page_id, [xml => 1]);
1196            
1197             Get a list of all of your Backpack email items for a page. Returns a Perl
1198             data structure unless the C<xml> parameter is true, in which case it returns
1199             the raw XML as returned by the Backpack server.
1200            
1201             =cut
1202              
1203             sub list_all_emails {
1204 0     0 1     my $self = shift;
1205 0             my %params = @_;
1206              
1207 0 0           croak 'No id' unless $params{page_id};
1208               
1209 0             my $req_data = $data{list_all_emails};
1210 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
1211              
1212 0             my $req = HTTP::Request->new('POST', $url);
1213 0             $req->content($self->_expand($req_data->{req}, %params));
1214              
1215 0             return $self->_call(%params, req => $req);
1216             }
1217              
1218             =head2 $email = $bp->show_email(page_id => $page_id, id => $reminder_id,
1219             [xml => 1]);
1220            
1221             Returns a Backpack email item given a page id and an email id.
1222             Returns a Perl data structure unless the C<xml> parameter is true, in which
1223             case it returns the raw XML as returned by the Backpack server.
1224            
1225             =cut
1226              
1227             sub show_email {
1228 0     0 1     my $self = shift;
1229 0             my %params = @_;
1230              
1231 0 0           croak 'No page id' unless $params{page_id};
1232 0 0           croak 'No email id' unless $params{id};
1233              
1234 0             my $req_data = $data{show_email};
1235 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
1236              
1237 0             my $req = HTTP::Request->new('POST', $url);
1238 0             $req->content($self->_expand($req_data->{req}, %params));
1239              
1240 0             return $self->_call(%params, req => $req);
1241             }
1242              
1243             =head2 $response = $bp->destroy_email(page_id => $page_id, id => $reminder_id,
1244             [xml => 1]);
1245            
1246             Destroys a Backpack email item for a page given a page id and an email id.
1247             Returns a Perl data structure unless the C<xml> parameter is true, in which
1248             case it returns the raw XML as returned by the Backpack server.
1249            
1250             =cut
1251              
1252             sub destroy_email {
1253 0     0 1     my $self = shift;
1254 0             my %params = @_;
1255              
1256 0 0           croak 'No page id' unless $params{page_id};
1257 0 0           croak 'No email id' unless $params{id};
1258              
1259 0             my $req_data = $data{destroy_email};
1260 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
1261              
1262 0             my $req = HTTP::Request->new('POST', $url);
1263 0             $req->content($self->_expand($req_data->{req}, %params));
1264              
1265 0             return $self->_call(%params, req => $req);
1266             }
1267              
1268             =head2 $exported_bp = $bp->export([xml => 1]);
1269            
1270             Exports an account's entire Backpack. Returns a Perl data structure
1271             unless the C<xml> parameter is true, in which case it returns the raw
1272             XML as returned by the Backpack server.
1273            
1274             =cut
1275              
1276             sub export {
1277 0     0 1     my $self = shift;
1278 0             my %params = @_;
1279              
1280 0             my $req_data = $data{export};
1281 0             my $url = $self->{base_url} . $req_data->{url};
1282              
1283 0             my $req = HTTP::Request->new('POST', $url);
1284 0             $req->content($self->_expand($req_data->{req}, %params));
1285              
1286 0             return $self->_call(%params, req => $req);
1287             }
1288              
1289             =head2 $lists = $bp->list_all_lists(page_id => $page_id, [xml => 1]);
1290            
1291             Get a list of *all* of your Backpack checklists for a specific page.
1292             Returns a Perl data structure unless the C<xml> parameter is true,
1293             in which case it returns the raw XML as returned by the Backpack server.
1294            
1295             =cut
1296              
1297             sub list_all_lists {
1298 0     0 1     my $self = shift;
1299 0             my %params = @_;
1300              
1301 0 0           croak 'No id' unless $params{page_id};
1302              
1303 0             my $req_data = $data{list_all_lists};
1304 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
1305              
1306 0             my $req = HTTP::Request->new('POST', $url);
1307 0             $req->content($self->_expand($req_data->{req}, %params));
1308              
1309 0             return $self->_call(%params, req => $req);
1310             }
1311              
1312             =head2 $list = $bp->list_this_list(page_id => $page_id, list_id => $list_id, [xml => 1]);
1313            
1314             Get details of a specific list with the given list_id on a specific Backpack
1315             page with the given page_id. Returns a Perl data structure unless the C<xml>
1316             parameter is true, in which case it returns the raw XML as returned by the
1317             Backpack server.
1318            
1319             =cut
1320              
1321             sub list_this_list {
1322 0     0 1     my $self = shift;
1323 0             my %params = @_;
1324              
1325 0 0           croak 'No page id' unless $params{page_id};
1326 0 0           croak 'No list id' unless $params{list_id};
1327              
1328 0             my $req_data = $data{list_this_list};
1329 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
1330              
1331 0             my $req = HTTP::Request->new('POST', $url);
1332 0             $req->content($self->_expand($req_data->{req}, %params));
1333              
1334 0             return $self->_call(%params, req => $req);
1335             }
1336              
1337             =head2 $list = $bp->create_list(page_id => $page_id, title => $title, [xml => 1]);
1338            
1339             Create a new Backpack checklist given a page id and a list title.
1340             Returns a Perl data structure unless the C<xml> parameter is true, in which
1341             case it returns the raw XML as returned by the Backpack server.
1342            
1343             =cut
1344              
1345             sub create_list {
1346 0     0 1     my $self = shift;
1347 0             my %params = @_;
1348              
1349 0 0           croak 'No page id' unless $params{page_id};
1350 0 0           croak 'No list title' unless $params{title};
1351              
1352 0             my $req_data = $data{create_list};
1353 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
1354              
1355 0             my $req = HTTP::Request->new('POST', $url);
1356 0             $req->content($self->_expand($req_data->{req}, %params));
1357              
1358 0             return $self->_call(%params, req => $req);
1359             }
1360              
1361             =head2 $list = $bp->update_list(page_id => $page_id, list_id => $list_id, title => $title, [xml => 1]);
1362            
1363             Update the title of a specific list with the given list_id on a specific
1364             Backpack page with the given page_id. Returns a Perl data structure unless
1365             the C<xml> parameter is true, in which case it returns the raw XML as
1366             returned by the Backpack server.
1367            
1368             =cut
1369              
1370             sub update_list {
1371 0     0 1     my $self = shift;
1372 0             my %params = @_;
1373              
1374 0 0           croak 'No page id' unless $params{page_id};
1375 0 0           croak 'No list id' unless $params{list_id};
1376 0 0           croak 'No title' unless $params{title};
1377              
1378 0             my $req_data = $data{update_list};
1379 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
1380              
1381 0             my $req = HTTP::Request->new('POST', $url);
1382 0             $req->content($self->_expand($req_data->{req}, %params));
1383              
1384 0             return $self->_call(%params, req => $req);
1385             }
1386              
1387             =head2 $list = $bp->destroy_list(page_id => $page_id, list_id => $list_id, [xml => 1]);
1388            
1389             Destroy a specific list with the given list_id on a specific Backpack page
1390             with the given page_id. Returns a Perl data structure unless the C<xml>
1391             parameter is true, in which case it returns the raw XML as returned by the
1392             Backpack server.
1393            
1394             =cut
1395              
1396             sub destroy_list {
1397 0     0 1     my $self = shift;
1398 0             my %params = @_;
1399              
1400 0 0           croak 'No page id' unless $params{page_id};
1401 0 0           croak 'No list id' unless $params{list_id};
1402              
1403 0             my $req_data = $data{destroy_list};
1404 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
1405              
1406 0             my $req = HTTP::Request->new('POST', $url);
1407 0             $req->content($self->_expand($req_data->{req}, %params));
1408              
1409 0             return $self->_call(%params, req => $req);
1410             }
1411              
1412             =head2 $list = $bp->create_list_item(page_id => $page_id, list_id => $list_id, item = $item, [xml => 1]);
1413            
1414             Create an item on a specific list with the given list_id on a specific
1415             Backpack page with the given page_id. This differs from the usual
1416             "create_item" function in that you can specify which list on a page you want
1417             to add the item to. Returns a Perl data structure unless the C<xml> parameter
1418             is true, in which case it returns the raw XML as returned by the Backpack
1419             server.
1420            
1421             =cut
1422              
1423             sub create_list_item {
1424 0     0 1     my $self = shift;
1425 0             my %params = @_;
1426              
1427 0 0           croak 'No page id' unless $params{page_id};
1428 0 0           croak 'No list id' unless $params{list_id};
1429 0 0           croak 'No item content' unless $params{item};
1430              
1431 0             my $req_data = $data{create_list_item};
1432 0             my $url = $self->{base_url} . $self->_expand($req_data->{url}, %params);
1433              
1434 0             my $req = HTTP::Request->new('POST', $url);
1435 0             $req->content($self->_expand($req_data->{req}, %params));
1436              
1437 0             return $self->_call(%params, req => $req);
1438             }
1439              
1440              
1441             sub _call {
1442 0     0       my $self = shift;
1443 0             my %params = @_;
1444              
1445 0             my $resp = $self->{ua}->request($params{req});
1446 0             my $xml = $resp->content;
1447              
1448 0 0           if ($params{xml}) {
1449 0               return $xml;
1450               } else {
1451 0               my $data = XMLin($xml, ForceArray => $self->{forcearray});
1452 0               return $data;
1453               }
1454             }
1455              
1456             sub _expand {
1457 0     0       my $self = shift;
1458 0             my $string = shift;
1459 0             my %params = @_;
1460              
1461 0             $string =~ s/\[S:(\w+)]/$self->{$1}/g;
1462 0             $string =~ s/\[P:(\w+)]/$params{$1}/g;
1463              
1464 0             return $string;
1465             }
1466              
1467             =head1 TO DO
1468            
1469             =over 4
1470            
1471             =item *
1472            
1473             Improve documentation (I know, it's shameful)
1474