1 package OpenILS::WWW::SuperCat::Feed;
2 use strict; use warnings;
4 use OpenSRF::EX qw(:try);
7 use OpenSRF::Utils::SettingsClient;
14 return 1 if UNIVERSAL::can("OpenILS::WWW::SuperCat::Feed::$type" => 'new');
25 throw OpenSRF::EX::ERROR ("I need a feed type!") ;
31 return undef unless $xml;
33 $parser = new XML::LibXML if (!$parser);
35 my $self = { doc => $parser->parse_string($xml), items => [] };
37 $self = bless $self => $class;
45 $self->{type} = $type if ($type);
51 return $self->{count};
57 $self->{search} = $search if ($search);
58 return $self->{search};
64 $self->{class} = $search if ($search);
65 return $self->{class};
71 $self->{lib} = $lib if ($lib);
78 $self->{base} = $base if ($base);
85 $self->{root} = $root if ($root);
92 $self->{unapi} = $unapi if ($unapi);
93 return $self->{unapi};
98 $self->{count} += scalar(@_);
99 push @{ $self->{items} }, @_;
104 return @{ $self->{items} } if (wantarray);
105 return $self->{items};
114 for my $node ($self->{doc}->findnodes($xpath)) {
115 $node->appendChild($new);
129 for my $node ($self->{doc}->findnodes($xpath)) {
130 my $new = $self->{doc}->createElement($name) if (!$ns);
131 $new = $self->{doc}->createElementNS($ns,$name) if ($ns);
133 $new->appendChild( $self->{doc}->createTextNode( $text ) )
137 for my $key (keys %$attrs) {
138 next unless $$attrs{$key};
139 $new->setAttribute( $key => $$attrs{$key} );
143 $node->appendChild( $new );
151 my $class = ref($self) || $self;
154 my $item_xml = shift;
155 my $entry = $class->new($item_xml);
156 return undef unless $entry;
158 $entry->base($self->base);
159 $entry->unapi($self->unapi);
161 $self->push_item($entry);
167 my $holdings_xml = shift;
169 return $self unless ($holdings_xml);
171 $parser = new XML::LibXML if (!$parser);
172 my $new_doc = $parser->parse_string($holdings_xml);
174 for my $root ( $self->{doc}->findnodes($self->{holdings_xpath}) ) {
175 $root->appendChild($new_doc->documentElement);
183 for my $root ( $self->{doc}->findnodes($self->{item_xpath}) ) {
184 for my $item ( $self->items ) {
185 $root->appendChild( $item->{doc}->documentElement );
194 return $self->{doc}->toString(1);
203 #----------------------------------------------------------
205 package OpenILS::WWW::SuperCat::Feed::atom;
206 use base 'OpenILS::WWW::SuperCat::Feed';
210 my $self = $class->SUPER::build('<feed xmlns:atom="http://www.w3.org/2005/Atom"/>');
211 $self->{doc}->documentElement->setNamespace('http://www.w3.org/2005/Atom', undef);
212 $self->{type} = 'application/xml';
213 $self->{item_xpath} = '/atom:feed';
220 $self->_create_node('/atom:feed','http://www.w3.org/2005/Atom','title', $text);
226 $self->_create_node($self->{item_xpath},'http://www.w3.org/2005/Atom','updated', $text);
232 $self->_create_node('/atom:feed','http://www.w3.org/2005/Atom','author');
233 $self->_create_node('/atom:feed/atom:author', 'http://www.w3.org/2005/Atom','name', $text);
240 my $mime = shift || "application/x-$type+xml";
243 $type = 'self' if ($type eq 'atom');
247 'http://www.w3.org/2005/Atom',
262 $self->_create_node( '/atom:feed', 'http://www.w3.org/2005/Atom', 'id', $id );
265 package OpenILS::WWW::SuperCat::Feed::atom::item;
266 use base 'OpenILS::WWW::SuperCat::Feed::atom';
271 my $self = $class->SUPER::build($xml);
272 $self->{doc}->documentElement->setNamespace('http://www.w3.org/2005/Atom', 'atom');
273 $self->{item_xpath} = '/atom:entry';
274 $self->{holdings_xpath} = '/atom:entry';
275 $self->{type} = 'application/xml';
280 #----------------------------------------------------------
282 package OpenILS::WWW::SuperCat::Feed::rss2;
283 use base 'OpenILS::WWW::SuperCat::Feed';
287 my $self = $class->SUPER::build('<rss version="2.0"><channel/></rss>');
288 $self->{type} = 'application/xml';
289 $self->{item_xpath} = '/rss/channel';
296 $self->_create_node('/rss/channel',undef,'title', $text);
302 $self->_create_node($self->{item_xpath},undef,'lastBuildDate', $text);
308 $self->_create_node('/rss/channel', undef,'generator', $text);
315 my $mime = shift || "application/x-$type+xml";
317 $type = 'self' if ($type eq 'rss2');
330 package OpenILS::WWW::SuperCat::Feed::rss2::item;
331 use base 'OpenILS::WWW::SuperCat::Feed::rss2';
336 my $self = $class->SUPER::build($xml);
337 $self->{type} = 'application/xml';
338 $self->{item_xpath} = '/item';
339 $self->{holdings_xpath} = '/item';
346 $self->_create_node($self->{item_xpath},undef,'pubDate', $text);
351 #----------------------------------------------------------
353 package OpenILS::WWW::SuperCat::Feed::mods;
354 use base 'OpenILS::WWW::SuperCat::Feed';
358 my $self = $class->SUPER::build('<mods:modsCollection version="3.0" xmlns:mods="http://www.loc.gov/mods/"/>');
359 $self->{type} = 'application/xml';
360 $self->{item_xpath} = '/mods:modsCollection';
364 package OpenILS::WWW::SuperCat::Feed::mods::item;
365 use base 'OpenILS::WWW::SuperCat::Feed::mods';
370 my $self = $class->SUPER::build($xml);
371 $self->{doc}->documentElement->setNamespace('http://www.loc.gov/mods/', 'mods');
372 $self->{type} = 'application/xml';
373 $self->{holdings_xpath} = '/mods:mods';
384 if ($type eq 'unapi' || $type eq 'opac') {
387 'http://www.loc.gov/mods/',
390 { type => 'otherFormat', id => 'link-'.$linkid }
393 "mods:mods/mods:relatedItem[\@id='link-$linkid']",
394 'http://www.loc.gov/mods/',
395 'mods:recordIdentifier',
403 #----------------------------------------------------------
405 package OpenILS::WWW::SuperCat::Feed::mods3;
406 use base 'OpenILS::WWW::SuperCat::Feed::mods';
410 my $self = $class->SUPER::build('<mods:modsCollection version="3.0" xmlns:mods="http://www.loc.gov/mods/v3"/>');
411 $self->{type} = 'application/xml';
412 $self->{item_xpath} = '/mods:modsCollection';
416 package OpenILS::WWW::SuperCat::Feed::mods3::item;
417 use base 'OpenILS::WWW::SuperCat::Feed::mods::item';
422 my $self = $class->SUPER::build($xml);
423 $self->{doc}->documentElement->setNamespace('http://www.loc.gov/mods/v3', 'mods');
424 $self->{type} = 'application/xml';
425 $self->{holdings_xpath} = '/mods:mods';
434 if ($type eq 'unapi' || $type eq 'opac') {
437 'http://www.loc.gov/mods/v3',
440 { type => 'otherFormat', id => 'link-'.$linkid }
443 "mods:mods/mods:relatedItem[\@id='link-$linkid']",
444 'http://www.loc.gov/mods/v3',
445 'mods:recordIdentifier',
453 #----------------------------------------------------------
455 package OpenILS::WWW::SuperCat::Feed::marcxml;
456 use base 'OpenILS::WWW::SuperCat::Feed';
460 my $self = $class->SUPER::build('<marc:collection xmlns:marc="http://www.loc.gov/MARC21/slim"/>');
461 $self->{type} = 'application/xml';
462 $self->{item_xpath} = '/marc:collection';
470 if ($type eq 'unapi') {
473 'http://www.w3.org/1999/xhtml',
476 { rel => 'unapi-server', href => $id, title => "unapi" }
483 package OpenILS::WWW::SuperCat::Feed::marcxml::item;
484 use base 'OpenILS::WWW::SuperCat::Feed::marcxml';
489 my $self = $class->SUPER::build($xml);
490 return undef unless $self;
491 $self->{doc}->documentElement->setNamespace('http://www.loc.gov/MARC21/slim', 'marc');
492 $self->{type} = 'application/xml';
493 $self->{holdings_xpath} = '/marc:record';
502 if ($type eq 'opac') {
505 'http://www.w3.org/1999/xhtml',
508 { rel => 'otherFormat', href => $id, title => "Dynamic Details" }
511 } elsif ($type eq 'unapi-id') {
514 'http://www.w3.org/1999/xhtml',
517 { title => $id, class => "unapi-id" }
524 #----------------------------------------------------------
526 package OpenILS::WWW::SuperCat::Feed::html;
527 use base 'OpenILS::WWW::SuperCat::Feed::atom';
531 my $self = $class->SUPER::new;
532 $self->type('text/html');
536 our ($_parser, $_xslt, $xslt_file);
540 my $base = $self->base || '';
541 my $root = $self->root || '';
542 my $search = $self->search || '';
543 my $class = $self->class || '';
544 my $lib = $self->lib || '-';
548 $_parser ||= new XML::LibXML;
549 $_xslt ||= new XML::LibXSLT;
552 OpenSRF::Utils::SettingsClient
554 ->config_value( dirs => 'xsl' ).
557 # parse the MODS xslt ...
558 my $atom2html_xslt = $_xslt->parse_stylesheet( $_parser->parse_file($xslt_file) );
560 my $new_doc = $atom2html_xslt->transform(
562 base_dir => "'$root'",
564 searchTerms => "'$search'",
565 searchClass => "'$class'",
568 return $new_doc->toString(1);
572 package OpenILS::WWW::SuperCat::Feed::html::item;
573 use base 'OpenILS::WWW::SuperCat::Feed::atom::item';
575 #----------------------------------------------------------
577 package OpenILS::WWW::SuperCat::Feed::htmlcard;
578 use base 'OpenILS::WWW::SuperCat::Feed::marcxml';
582 my $self = $class->SUPER::new;
583 $self->type('text/html');
584 $self->{xsl} = "/MARC21slim2HTMLCard.xsl";
588 our ($_parser, $_xslt, $xslt_file);
592 my $base = $self->base || '';
593 my $root = $self->root || '';
594 my $search = $self->search || '';
595 my $lib = $self->lib || '-';
599 $_parser ||= new XML::LibXML;
600 $_xslt ||= new XML::LibXSLT;
603 OpenSRF::Utils::SettingsClient
605 ->config_value( dirs => 'xsl' ).$self->{xsl};
607 # parse the MODS xslt ...
608 my $atom2html_xslt = $_xslt->parse_stylesheet( $_parser->parse_file($xslt_file) );
610 my $new_doc = $atom2html_xslt->transform(
612 base_dir => "'$root'",
614 searchTerms => "'$search'",
617 return $new_doc->toString(1);
620 package OpenILS::WWW::SuperCat::Feed::htmlcard::item;
621 use base 'OpenILS::WWW::SuperCat::Feed::marcxml::item';
623 package OpenILS::WWW::SuperCat::Feed::htmlholdings;
624 use base 'OpenILS::WWW::SuperCat::Feed::htmlcard';
628 my $self = $class->SUPER::new;
629 $self->{xsl} = "/MARC21slim2HTMLCard-holdings.xsl";
633 package OpenILS::WWW::SuperCat::Feed::htmlholdings::item;
634 use base 'OpenILS::WWW::SuperCat::Feed::htmlcard::item';