File Coverage

blib/lib/Net/Google/Blogger/Blog/Entry.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::Google::Blogger::Blog::Entry;
2              
3 1     1   1452 use warnings;
  1         2  
  1         29  
4 1     1   5 use strict;
  1         3  
  1         42  
5              
6 1     1   5 use Any::Moose;
  1         1  
  1         5  
7 1     1   926 use XML::Simple ();
  0            
  0            
8              
9              
10             our $VERSION = '0.09';
11              
12             has id => ( is => 'rw', isa => 'Str' );
13             has title => ( is => 'rw', isa => 'Str' );
14             has content => ( is => 'rw', isa => 'Str' );
15             has author => ( is => 'rw', isa => 'Str' );
16             has published => ( is => 'rw', isa => 'Str' );
17             has updated => ( is => 'rw', isa => 'Str' );
18             has edit_url => ( is => 'rw', isa => 'Str' );
19             has id_url => ( is => 'rw', isa => 'Str' );
20             has public_url => ( is => 'rw', isa => 'Str' );
21             has source_xml_tree => ( is => 'rw', isa => 'HashRef', default => sub { {} }, required => 1 );
22             has categories => ( is => 'rw', isa => 'ArrayRef[Str]', auto_deref => 1 );
23             has blog => ( is => 'rw', isa => 'Net::Google::Blogger::Blog', required => 1 );
24              
25             __PACKAGE__->meta->make_immutable;
26              
27              
28             sub BUILDARGS {
29             ## Populates object attributes from parsed XML source.
30             my $class = shift;
31             my %params = @_;
32              
33             my $attrs = $class->source_xml_tree_to_attrs($params{source_xml_tree})
34             if $params{source_xml_tree};
35              
36             $attrs->{$_} = $params{$_} foreach keys %params;
37             return $attrs;
38             }
39              
40              
41             sub source_xml_tree_to_attrs {
42             ## Returns hash of attributes extracted from XML tree.
43             my $class = shift;
44             my ($tree) = @_;
45              
46             my $get_link_by_rel = sub {
47             ## Returns value for 'href' attribute for link with given 'ref' attribute, if it's present.
48             my ($rel_value) = @_;
49              
50             my ($link) = grep $_->{rel} eq $rel_value, @{ $tree->{link} };
51             return $link->{href} if $link;
52             };
53              
54             return {
55             id => $tree->{id}[0],
56             author => $tree->{author}[0]{name}[0],
57             published => $tree->{published}[0],
58             updated => $tree->{updated}[0],
59             title => $tree->{title}[0]{content},
60             content => $tree->{content}{content},
61             public_url => $get_link_by_rel->('alternate'),
62             id_url => $get_link_by_rel->('self'),
63             edit_url => $get_link_by_rel->('edit'),
64             categories => [ map $_->{term}, @{ $tree->{category} || [] } ],
65             };
66             }
67              
68              
69             sub update_from_http_response {
70             ## Updates entry internal structures from given HTTP
71             ## response. Used to update entry after it's been created on the
72             ## server.
73             my $self = shift;
74             my ($response) = @_;
75              
76             my $xml_tree = XML::Simple::XMLin($response->content, ForceArray => 1);
77             $self->source_xml_tree($xml_tree);
78              
79             my $new_attrs = $self->source_xml_tree_to_attrs($xml_tree);
80             $self->$_($new_attrs->{$_}) foreach keys %$new_attrs;
81             }
82              
83              
84             sub as_xml {
85             ## Returns XML string representing the entry.
86             my $self = shift;
87              
88             # Add namespace specifiers to the root element, which appears to be undocumented requirement.
89             $self->source_xml_tree->{xmlns} = 'http://www.w3.org/2005/Atom';
90             $self->source_xml_tree->{'xmlns:thr'} = 'http://purl.org/rss/1.0/modules/threading/' if $self->id;
91              
92             # Place attribute values into original data tree. Don't generate an Atom entry anew as
93             # Blogger wants us to preserve all original data when updating posts.
94             $self->source_xml_tree->{title}[0] = {
95             content => $self->title,
96             type => 'text',
97             };
98             $self->source_xml_tree->{content} = {
99             content => $self->content,
100             type => 'html',
101             };
102             $self->source_xml_tree->{category} = [
103             map {
104             scheme => 'http://www.blogger.com/atom/ns#',
105             term => $_,
106             },
107             $self->categories
108             ];
109              
110             # Convert data tree to XML.
111             return XML::Simple::XMLout($self->source_xml_tree, RootName => 'entry');
112             }
113              
114              
115             sub save {
116             ## Saves the entry to blogger.
117             my $self = shift;
118              
119             if ($self->id) {
120             # Update the entry.
121             my $response = $self->blog->blogger->http_put($self->edit_url => $self->as_xml);
122             die 'Unable to save entry: ' . $response->status_line unless $response->is_success;
123             }
124             else {
125             # Create new entry.
126             $self->blog->add_entry($self);
127             }
128             }
129              
130              
131             sub delete {
132             ## Deletes the entry from server.
133             my $self = shift;
134              
135             $self->blog->delete_entry($self);
136             }
137              
138              
139             1;
140              
141             __END__