Update tests
[catagits/XML-Feed.git] / lib / XML / Feed / Format / Atom.pm
CommitLineData
c4d4c98e 1# $Id: Atom.pm 1958 2006-08-14 05:31:27Z btrott $
0d5e38d1 2
729cd7a8 3package XML::Feed::Format::Atom;
0d5e38d1 4use strict;
5
6use base qw( XML::Feed );
7use XML::Atom::Feed;
8use XML::Atom::Util qw( iso2dt );
9use List::Util qw( first );
ecac864a 10use DateTime::Format::W3CDTF;
0d5e38d1 11
9a36f82c 12use XML::Atom::Entry;
13XML::Atom::Entry->mk_elem_accessors(qw( lat long ), ['http://www.w3.org/2003/01/geo/wgs84_pos#']);
14
5383a560 15use XML::Atom::Content;
16
948f9350 17sub identify {
18 my $class = shift;
19 my $xml = shift;
20 my $tag = $class->_get_first_tag($xml);
21 return ($tag eq 'feed');
22}
23
973e1f9e 24sub init_empty {
4e9c4625 25 my ($feed, %args) = @_;
26 $args{'Version'} ||= '1.0';
27
28 $feed->{atom} = XML::Atom::Feed->new(%args);
973e1f9e 29 $feed;
30}
31
5383a560 32# monkey patch
33{
34 my $sub = sub {
35 my $item = shift;
36 if (XML::Atom::LIBXML) {
37 my $elem = $item->elem;
38 if (@_) {
39 $elem->setAttributeNS('http://www.w3.org/XML/1998/namespace',
40 'base', $_[0]);
41 }
42 return $elem->getAttributeNS('http://www.w3.org/XML/1998/namespace', 'base');
43 } else {
44 if (@_) {
45 $item->elem->setAttribute('xml:base', $_[0]);
46 }
47 return $item->elem->getAttribute('xml:base');
48 }
49
50 };
51 no strict 'refs';
52 *XML::Atom::Feed::base = $sub unless XML::Atom::Feed->can('base');
53 *XML::Atom::Entry::base = $sub unless XML::Atom::Entry->can('base');
54 *XML::Atom::Content::base = $sub unless XML::Atom::Content->can('base');
55}
56
0d5e38d1 57sub init_string {
58 my $feed = shift;
59 my($str) = @_;
fe71566d 60 if ($str) {
61 $feed->{atom} = XML::Atom::Feed->new(Stream => $str)
62 or return $feed->error(XML::Atom::Feed->errstr);
63 }
0d5e38d1 64 $feed;
65}
66
67sub format { 'Atom' }
68
973e1f9e 69sub title { shift->{atom}->title(@_) }
0d5e38d1 70sub link {
973e1f9e 71 my $feed = shift;
72 if (@_) {
73 $feed->{atom}->add_link({ rel => 'alternate', href => $_[0],
74 type => 'text/html', });
75 } else {
4679cf3f 76 my $l = first { !defined $_->rel || $_->rel eq 'alternate' } $feed->{atom}->link;
973e1f9e 77 $l ? $l->href : undef;
78 }
79}
9a36f82c 80
81sub self_link {
82 my $feed = shift;
83 if (@_) {
84 my $uri = shift;
85 $feed->{atom}->add_link({type => "application/atom+xml", rel => "self", href => $uri});
86 return $uri;
87 }
88 else
89 {
90 my $l =
91 first
92 { !defined $_->rel || $_->rel eq 'self' }
93 $feed->{atom}->link;
94 ;
95
96 return $l ? $l->href : undef;
97 }
98}
99
973e1f9e 100sub description { shift->{atom}->tagline(@_) }
101sub copyright { shift->{atom}->copyright(@_) }
102sub language { shift->{atom}->language(@_) }
103sub generator { shift->{atom}->generator(@_) }
e8fcbc5b 104sub id { shift->{atom}->id(@_) }
105sub updated { shift->{atom}->updated(@_) }
106sub add_link { shift->{atom}->add_link(@_) }
5383a560 107sub base { shift->{atom}->base(@_) }
973e1f9e 108
109sub author {
110 my $feed = shift;
111 if (@_ && $_[0]) {
c4d4c98e 112 my $person = XML::Atom::Person->new(Version => 1.0);
973e1f9e 113 $person->name($_[0]);
114 $feed->{atom}->author($person);
115 } else {
116 $feed->{atom}->author ? $feed->{atom}->author->name : undef;
117 }
118}
119
5383a560 120
121
122
973e1f9e 123sub modified {
124 my $feed = shift;
125 if (@_) {
ecac864a 126 $feed->{atom}->modified(DateTime::Format::W3CDTF->format_datetime($_[0]));
973e1f9e 127 } else {
1ee56ab5 128 return iso2dt($feed->{atom}->modified) if $feed->{atom}->modified;
129 return iso2dt($feed->{atom}->updated) if $feed->{atom}->updated;
130 return undef;
973e1f9e 131 }
0d5e38d1 132}
0d5e38d1 133
c4d4c98e 134sub entries {
0d5e38d1 135 my @entries;
136 for my $entry ($_[0]->{atom}->entries) {
729cd7a8 137 push @entries, XML::Feed::Entry::Format::Atom->wrap($entry);
0d5e38d1 138 }
c4d4c98e 139
0d5e38d1 140 @entries;
141}
142
973e1f9e 143sub add_entry {
33d4cb3f 144 my $feed = shift;
145 my $entry = shift || return;
146 $entry = $feed->_convert_entry($entry);
973e1f9e 147 $feed->{atom}->add_entry($entry->unwrap);
148}
149
150sub as_xml { $_[0]->{atom}->as_xml }
151
729cd7a8 152package XML::Feed::Entry::Format::Atom;
0d5e38d1 153use strict;
154
155use base qw( XML::Feed::Entry );
156use XML::Atom::Util qw( iso2dt );
a749d9b9 157use XML::Feed::Content;
973e1f9e 158use XML::Atom::Entry;
0d5e38d1 159use List::Util qw( first );
160
973e1f9e 161sub init_empty {
162 my $entry = shift;
c4d4c98e 163 $entry->{entry} = XML::Atom::Entry->new(Version => 1.0);
973e1f9e 164 1;
165}
166
167sub title { shift->{entry}->title(@_) }
e8fcbc5b 168sub source { shift->{entry}->source(@_) }
169sub updated { shift->{entry}->updated(@_) }
5383a560 170sub base { shift->{entry}->base(@_) }
e8fcbc5b 171
0d5e38d1 172sub link {
973e1f9e 173 my $entry = shift;
174 if (@_) {
175 $entry->{entry}->add_link({ rel => 'alternate', href => $_[0],
176 type => 'text/html', });
177 } else {
4679cf3f 178 my $l = first { !defined $_->rel || $_->rel eq 'alternate' } $entry->{entry}->link;
973e1f9e 179 $l ? $l->href : undef;
180 }
0d5e38d1 181}
a749d9b9 182
183sub summary {
973e1f9e 184 my $entry = shift;
185 if (@_) {
ac9492d2 186 my %param;
187 if (ref($_[0]) eq 'XML::Feed::Content') {
188 %param = (Body => $_[0]->body);
189 } else {
190 %param = (Body => $_[0]);
191 }
192 $entry->{entry}->summary(XML::Atom::Content->new(%param, Version => 1.0));
973e1f9e 193 } else {
ac9492d2 194 my $s = $entry->{entry}->summary;
195 # map Atom types to MIME types
196 my $type = ($s && ref($s) eq 'XML::Feed::Content') ? $s->type : undef;
197 if ($type) {
198 $type = 'text/html' if $type eq 'xhtml' || $type eq 'html';
199 $type = 'text/plain' if $type eq 'text';
200 }
201 my $body = $s;
202 if (defined $s && ref($s) eq 'XML::Feed::Content') {
203 $body = $s->body;
204 }
205 XML::Feed::Content->wrap({ type => $type,
206 body => $body });
973e1f9e 207 }
a749d9b9 208}
209
4f413435 210my %types = (
211 'text/xhtml' => 'xhtml',
212 'text/html' => 'html',
213 'text/plain' => 'text',
214);
215
a749d9b9 216sub content {
973e1f9e 217 my $entry = shift;
218 if (@_) {
219 my %param;
5383a560 220 my $base;
973e1f9e 221 if (ref($_[0]) eq 'XML::Feed::Content') {
4f413435 222 if (defined $_[0]->type && defined $types{$_[0]->type}) {
223 %param = (Body => $_[0]->body, Type => $types{$_[0]->type});
224 } else {
225 %param = (Body => $_[0]->body);
226 }
5383a560 227 $base = $_[0]->base if defined $_[0]->base;
973e1f9e 228 } else {
c4d4c98e 229 %param = (Body => $_[0]);
973e1f9e 230 }
c4d4c98e 231 $entry->{entry}->content(XML::Atom::Content->new(%param, Version => 1.0));
5383a560 232 $entry->{entry}->content->base($base) if defined $base;
973e1f9e 233 } else {
234 my $c = $entry->{entry}->content;
c4d4c98e 235
236 # map Atom types to MIME types
237 my $type = $c ? $c->type : undef;
238 if ($type) {
239 $type = 'text/html' if $type eq 'xhtml' || $type eq 'html';
240 $type = 'text/plain' if $type eq 'text';
241 }
242
243 XML::Feed::Content->wrap({ type => $type,
5383a560 244 base => $c ? $c->base : undef,
973e1f9e 245 body => $c ? $c->body : undef });
246 }
a749d9b9 247}
0d5e38d1 248
249sub category {
973e1f9e 250 my $entry = shift;
0d5e38d1 251 my $ns = XML::Atom::Namespace->new(dc => 'http://purl.org/dc/elements/1.1/');
973e1f9e 252 if (@_) {
c4d4c98e 253 $entry->{entry}->add_category({ term => $_[0] });
973e1f9e 254 } else {
c4d4c98e 255 my $category = $entry->{entry}->category;
bf34c07e 256 my @return = $category ? ($category->label || $category->term) : $entry->{entry}->getlist($ns, 'subject');
257 return wantarray? @return : $return[0];
973e1f9e 258 }
259}
260
261sub author {
262 my $entry = shift;
263 if (@_ && $_[0]) {
c4d4c98e 264 my $person = XML::Atom::Person->new(Version => 1.0);
973e1f9e 265 $person->name($_[0]);
266 $entry->{entry}->author($person);
267 } else {
268 $entry->{entry}->author ? $entry->{entry}->author->name : undef;
269 }
270}
271
272sub id { shift->{entry}->id(@_) }
273
274sub issued {
275 my $entry = shift;
276 if (@_) {
ecac864a 277 $entry->{entry}->issued(DateTime::Format::W3CDTF->format_datetime($_[0])) if $_[0];
973e1f9e 278 } else {
279 $entry->{entry}->issued ? iso2dt($entry->{entry}->issued) : undef;
280 }
0d5e38d1 281}
282
973e1f9e 283sub modified {
284 my $entry = shift;
285 if (@_) {
ecac864a 286 $entry->{entry}->modified(DateTime::Format::W3CDTF->format_datetime($_[0])) if $_[0];
973e1f9e 287 } else {
1ee56ab5 288 return iso2dt($entry->{entry}->modified) if $entry->{entry}->modified;
289 return iso2dt($entry->{entry}->updated) if $entry->{entry}->updated;
290 return undef;
973e1f9e 291 }
292}
0d5e38d1 293
9a36f82c 294sub lat {
295 my $entry = shift;
296 if (@_) {
297 $entry->{entry}->lat($_[0]) if $_[0];
298 } else {
299 $entry->{entry}->lat;
300 }
301}
302
303sub long {
304 my $entry = shift;
305 if (@_) {
306 $entry->{entry}->long($_[0]) if $_[0];
307 } else {
308 $entry->{entry}->long;
309 }
310}
311
0d5e38d1 3121;