File Coverage

blib/lib/Catmandu/Importer/Atom.pm
Criterion Covered Total %
statement 15 53 28.3
branch 0 12 0.0
condition 0 15 0.0
subroutine 5 7 71.4
pod 0 1 0.0
total 20 88 22.7


line stmt bran cond sub pod time code
1             package Catmandu::Importer::Atom;
2              
3 1     1   104312 use namespace::clean;
  1         13200  
  1         6  
4 1     1   529 use Catmandu::Sane;
  1         143983  
  1         7  
5 1     1   264 use Catmandu::Util qw(trim);
  1         2  
  1         45  
6 1     1   480 use XML::Atom::Client;
  1         487931  
  1         32  
7 1     1   8 use Moo;
  1         2  
  1         9  
8              
9             with 'Catmandu::Importer';
10              
11             my $ENTRY_ATTRS = [qw(id title published updated summary rights)];
12             my $CONTENT_ATTRS = [qw(mode type body)];
13             my $PERSON_ATTRS = [qw(name email uri homepage)];
14             my $LINK_ATTRS = [qw(rel href hreflang title type length)];
15             my $CATEGORY_ATTRS = [qw(term label scheme)];
16              
17             has url => (is => 'ro', required => 1);
18             has entries => (is => 'ro', init_arg => undef, lazy => 1, builder => '_build_entries');
19              
20             sub _build_entries {
21 0     0     my $self = $_[0];
22 0           my $feed = XML::Atom::Client->new->getFeed($self->url);
23             [map {
24 0           my $entry = $_;
  0            
25 0           my $entry_data = {};
26 0           for my $key (@$ENTRY_ATTRS) {
27 0   0       $entry_data->{$key} = trim($entry->$key || next) || next;
28             }
29 0 0         if (my $content = $entry->content) {
30 0           for my $key (@$CONTENT_ATTRS) {
31 0   0       $entry_data->{content}{$key} = trim($content->$key || next) || next;
32             }
33             }
34 0 0         if (my $author = $entry->author) {
35 0           for my $key (@$PERSON_ATTRS) {
36 0   0       $entry_data->{author}{$key} = trim($author->$key || next) || next;
37             }
38             }
39 0 0         if (my $contributor = $entry->contributor) {
40 0           for my $key (@$PERSON_ATTRS) {
41 0   0       $entry_data->{contributor}{$key} = trim($contributor->$key || next) || next;
42             }
43             }
44 0 0         if (my @category = $entry->category) {
45             $entry_data->{category} = [map {
46 0           my $category = $_;
  0            
47 0           my $category_data = {};
48 0           for my $key (@$CATEGORY_ATTRS) {
49 0   0       $category_data->{$key} = trim($category->$key || next) || next;
50             }
51 0           $category_data;
52             } @category];
53             }
54 0 0         if (my @links = $entry->link) {
55             $entry_data->{link} = [map {
56 0           my $link = $_;
  0            
57 0           my $link_data = {};
58 0           for my $key (@$LINK_ATTRS) {
59 0   0       $link_data->{$key} = trim($link->$key || next) || next;
60             }
61 0           $link_data;
62             } @links];
63             }
64 0           for my $node ($entry->elem->childNodes) {
65 0           my $uri = $node->namespaceURI;
66 0 0 0       next if (! $uri || $uri eq 'http://purl.org/atom/ns#');
67 0           my $name = $node->nodeName;
68 0           my $value = $node->textContent;
69 0           $entry_data->{$name} = $value;
70             }
71 0           $entry_data;
72             } $feed->entries];
73             }
74              
75 0     0 0   sub to_array { goto &entries }
76              
77             sub generator {
78             my ($self) = @_;
79             my $n = 0;
80             sub {
81             $self->entries->[$n++];
82             };
83             }
84              
85             =head1 NAME
86              
87             Catmandu::Importer::Atom - Package that imports Atom feeds
88              
89             =head1 SYNOPSIS
90              
91             use Catmandu::Importer::Atom;
92              
93             my $importer = Catmandu::Importer::Atom->new(url => "...");
94              
95             my $n = $importer->each(sub {
96             my $hashref = $_[0];
97             # ...
98             });
99              
100             =head1 DATA MODEL
101              
102             Each parsed Atom entry is transformed into a hash ref:
103              
104             {
105             id => '...' ,
106             title => '...' ,
107             published => '...' ,
108             updated => '...' ,
109             summary => '...' ,
110             rights => '...' ,
111             content => {
112             mode => '...' ,
113             type => '...' ,
114             body => '...' ,
115             } ,
116             author => {
117             name => '...' ,
118             email => '...' ,
119             uri => '...' ,
120             homepage => '...' ,
121             } ,
122             contributor => {
123             name => '...' ,
124             email => '...' ,
125             uri => '...' ,
126             homepage => '...' ,
127             } ,
128             category => [
129             { term => '...' , label => '...' , scheme => '....' } ,
130             ],
131             link => [
132             { rel => '...' , href => '...' , hreflang => '...' ,
133             title => '...' , type => '...' , length => '...'} ,
134             ],
135             <<all other elements are added as name-value pairs>>
136             }
137              
138             =head1 METHODS
139              
140             =head2 new(url => URL,[entries => [qw(...)])
141              
142             Create a new Atom importer for the URL. Optionally provide a entries parameter with the
143             feed items you want to import.
144              
145             =head2 count
146              
147             =head2 each(&callback)
148              
149             =head2 ...
150              
151             Every Catmandu::Importer is a Catmandu::Iterable all its methods are inherited. The
152             Catmandu::Importer::Atom methods are not idempotent: Atom feeds can only be read once.
153              
154             =head1 SEE ALSO
155              
156             L<Catmandu::Iterable>
157              
158             =cut
159              
160             1;