]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/WWW/SuperCat/Feed.pm
6edae27ba5f04d5a1c8f09434e65ed3aad7f3327
[Evergreen.git] / Open-ILS / src / perlmods / OpenILS / WWW / SuperCat / Feed.pm
1 package OpenILS::WWW::SuperCat::Feed;
2 use strict; use warnings;
3 use vars qw/$parser/;
4 use OpenSRF::EX qw(:try);
5 use XML::LibXML;
6 use CGI;
7
8 sub new {
9         my $class = shift;
10         my $type = shift;
11         if ($type) {
12                 $class .= '::'.$type;
13                 return $class->new;
14         }
15         throw OpenSRF::EX::ERROR ("I need a feed type!") ;
16 }
17
18 sub build {
19         my $class = shift;
20         my $xml = shift;
21
22         $parser = new XML::LibXML if (!$parser);
23
24         my $self = { doc => $parser->parse_string($xml), items => [] };
25
26         return bless $self => $class;
27 }
28
29 sub base {
30         my $self = shift;
31         my $base = shift;
32         $self->{base} = $base if ($base);
33         return $self->{base};
34 }
35
36 sub unapi {
37         my $self = shift;
38         my $unapi = shift;
39         $self->{unapi} = $unapi if ($unapi);
40         return $self->{unapi};
41 }
42
43 sub push_item {
44         my $self = shift;
45         push @{ $self->{items} }, @_;
46 }
47
48 sub items {
49         my $self = shift;
50         return @{ $self->{items} } if (wantarray);
51         return $self->{items};
52 }
53
54 sub _add_node {
55         my $self = shift;
56
57         my $xpath = shift;
58         my $new = shift;
59
60         for my $node ($self->{doc}->findnodes($xpath)) {
61                 $node->appendChild($new);
62                 last;
63         }
64 }
65
66 sub _create_node {
67         my $self = shift;
68
69         my $xpath = shift;
70         my $ns = shift;
71         my $name = shift;
72         my $text = shift;
73         my $attrs = shift;
74
75         for my $node ($self->{doc}->findnodes($xpath)) {
76                 my $new = $self->{doc}->createElement($name) if (!$ns);
77                 $new = $self->{doc}->createElementNS($ns,$name) if ($ns);
78
79                 $new->appendChild( $self->{doc}->createTextNode( $text ) )
80                         if (defined $text);
81
82                 if (ref($attrs)) {
83                         for my $key (keys %$attrs) {
84                                 $new->setAttribute( $key => $$attrs{$key} );
85                         }
86                 }
87
88                 $node->appendChild( $new );
89
90                 return $new;
91         }
92 }
93
94 sub add_item {
95         my $self = shift;
96         my $class = ref($self) || $self;
97         $class .= '::item';
98
99         my $item_xml = shift;
100         my $entry = $class->new($item_xml);
101
102         $entry->base($self->base);
103         $entry->unapi($self->unapi);
104
105         $self->push_item($entry);
106         return $entry;
107 }
108
109 sub toString {
110         my $self = shift;
111         for my $root ( $self->{doc}->findnodes($self->{item_xpath}) ) {
112                 for my $item ( $self->items ) {
113                         $root->appendChild( $item->{doc}->documentElement );
114                 }
115                 last;
116         }
117
118         return $self->{doc}->toString(1);
119 }
120
121 sub id {};
122 sub link {};
123 sub title {};
124 sub update_ts {};
125 sub creator {};
126
127 #----------------------------------------------------------
128
129 package OpenILS::WWW::SuperCat::Feed::atom;
130 use base 'OpenILS::WWW::SuperCat::Feed';
131
132 sub new {
133         my $class = shift;
134         my $self = $class->SUPER::build('<atom:feed xmlns:atom="http://www.w3.org/2005/Atom"/>');
135         $self->{type} = 'atom';
136         $self->{item_xpath} = '/atom:feed';
137         return $self;
138 }
139
140 sub title {
141         my $self = shift;
142         my $text = shift;
143         $self->_create_node('/atom:feed','http://www.w3.org/2005/Atom','atom:title', $text);
144 }
145
146 sub update_ts {
147         my $self = shift;
148         my $text = shift;
149         $self->_create_node('/atom:feed','http://www.w3.org/2005/Atom','atom:updated', $text);
150 }
151
152 sub creator {
153         my $self = shift;
154         my $text = shift;
155         $self->_create_node('/atom:feed','http://www.w3.org/2005/Atom','atom:author');
156         $self->_create_node('/atom:feed/atom:author', 'http://www.w3.org/2005/Atom','atom:name', $text);
157 }
158
159 sub link {
160         my $self = shift;
161         my $type = shift;
162         my $id = shift;
163         my $mime = shift || "application/$type+xml";
164
165         $type = 'self' if ($type eq 'atom');
166
167         $self->_create_node(
168                 $self->{item_xpath},
169                 'http://www.w3.org/2005/Atom',
170                 'atom:link',
171                 undef,
172                 { rel => $type,
173                   href => $id,
174                   type => $mime,
175                 }
176         );
177 }
178
179 sub id {
180         my $self = shift;
181         my $id = shift;
182
183         $self->_create_node( '/atom:feed', 'http://www.w3.org/2005/Atom', 'atom:id', $id );
184 }
185
186 package OpenILS::WWW::SuperCat::Feed::atom::item;
187 use base 'OpenILS::WWW::SuperCat::Feed::atom';
188
189 sub new {
190         my $class = shift;
191         my $xml = shift;
192         my $self = $class->SUPER::build($xml);
193         $self->{doc}->documentElement->setNamespace('http://www.w3.org/2005/Atom', 'atom');
194         $self->{item_xpath} = '/atom:entry';
195         $self->{type} = 'atom::item';
196         return $self;
197 }
198
199
200 #----------------------------------------------------------
201
202 package OpenILS::WWW::SuperCat::Feed::rss2;
203 use base 'OpenILS::WWW::SuperCat::Feed';
204
205 sub new {
206         my $class = shift;
207         my $self = $class->SUPER::build('<rss version="2.0"><channel/></rss>');
208         $self->{type} = 'rss2';
209         $self->{item_xpath} = '/rss/channel';
210         return $self;
211 }
212
213 sub title {
214         my $self = shift;
215         my $text = shift;
216         $self->_create_node('/rss/channel',undef,'title', $text);
217 }
218
219 sub update_ts {
220         my $self = shift;
221         my $text = shift;
222         $self->_create_node('/rss/channel',undef,'lastBuildDate', $text);
223 }
224
225 sub creator {
226         my $self = shift;
227         my $text = shift;
228         $self->_create_node('/rss/channel', undef,'generator', $text);
229 }
230
231 sub link {
232         my $self = shift;
233         my $type = shift;
234         my $id = shift;
235         my $mime = shift || "application/$type+xml";
236
237         $type = 'self' if ($type eq 'rss2');
238
239         $self->_create_node(
240                 $self->{item_xpath},
241                 undef,
242                 'link',
243                 $id,
244                 { rel => $type,
245                   type => $mime,
246                 }
247         );
248 }
249
250 package OpenILS::WWW::SuperCat::Feed::rss2::item;
251 use base 'OpenILS::WWW::SuperCat::Feed::rss2';
252
253 sub new {
254         my $class = shift;
255         my $xml = shift;
256         my $self = $class->SUPER::build($xml);
257         $self->{type} = 'atom::item';
258         $self->{item_xpath} = '/item';
259         return $self;
260 }
261
262
263 #----------------------------------------------------------
264
265 package OpenILS::WWW::SuperCat::Feed::mods;
266 use base 'OpenILS::WWW::SuperCat::Feed';
267
268 sub new {
269         my $class = shift;
270         my $self = $class->SUPER::build('<mods:modsCollection version="3.0" xmlns:mods="http://www.loc.gov/mods/"/>');
271         $self->{type} = 'mods';
272         $self->{item_xpath} = '/mods:modsCollection';
273         return $self;
274 }
275
276 package OpenILS::WWW::SuperCat::Feed::mods::item;
277 use base 'OpenILS::WWW::SuperCat::Feed::mods';
278
279 sub new {
280         my $class = shift;
281         my $xml = shift;
282         my $self = $class->SUPER::build($xml);
283         $self->{doc}->documentElement->setNamespace('http://www.loc.gov/mods/', 'mods');
284         $self->{type} = 'mods::item';
285         return $self;
286 }
287
288 my $linkid = 1;
289
290 sub link {
291         my $self = shift;
292         my $type = shift;
293         my $id = shift;
294
295         if ($type eq 'unapi' || $type eq 'opac') {
296                 $self->_create_node(
297                         'mods:mods',
298                         'http://www.loc.gov/mods/',
299                         'mods:relatedItem',
300                         undef,
301                         { type => 'otherFormat', id => 'link-'.$linkid }
302                 );
303                 $self->_create_node(
304                         "mods:mods/mods:relatedItem[\@id='link-$linkid']",
305                         'http://www.loc.gov/mods/',
306                         'mods:recordIdentifier',
307                         $id
308                 );
309                 $linkid++;
310         }
311 }
312
313
314 #----------------------------------------------------------
315
316 package OpenILS::WWW::SuperCat::Feed::html;
317 use base 'OpenILS::WWW::SuperCat::Feed';
318
319 sub new {
320         my $class = shift;
321         my $self = $class->SUPER::build('<html><head/><body/></html>');
322         $self->{type} = 'html';
323         $self->{item_xpath} = '/html/body';
324         return $self;
325 }
326
327
328 1;