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->{sort} = $search if ($search);
78 $self->{sort_dir} = $search if ($search);
79 return $self->{sort_dir};
85 $self->{lang} = $search if ($search);
92 $self->{lib} = $lib if ($lib);
99 $self->{base} = $base if ($base);
100 return $self->{base};
106 $self->{root} = $root if ($root);
107 return $self->{root};
113 $self->{unapi} = $unapi if ($unapi);
114 return $self->{unapi};
119 $self->{count} += scalar(@_);
120 push @{ $self->{items} }, @_;
125 return @{ $self->{items} } if (wantarray);
126 return $self->{items};
135 for my $node ($self->{doc}->findnodes($xpath)) {
136 $node->appendChild($new);
150 for my $node ($self->{doc}->findnodes($xpath)) {
151 my $new = $self->{doc}->createElement($name) if (!$ns);
152 $new = $self->{doc}->createElementNS($ns,$name) if ($ns);
154 $new->appendChild( $self->{doc}->createTextNode( $text ) )
158 for my $key (keys %$attrs) {
159 next unless $$attrs{$key};
160 $new->setAttribute( $key => $$attrs{$key} );
164 $node->appendChild( $new );
172 my $class = ref($self) || $self;
175 my $item_xml = shift;
176 my $entry = $class->new($item_xml);
177 return undef unless $entry;
179 $entry->base($self->base);
180 $entry->unapi($self->unapi);
182 $self->push_item($entry);
188 my $holdings_xml = shift;
190 return $self unless ($holdings_xml);
192 $parser = new XML::LibXML if (!$parser);
193 my $new_doc = $parser->parse_string($holdings_xml);
195 for my $root ( $self->{doc}->findnodes($self->{holdings_xpath}) ) {
196 $root->appendChild($new_doc->documentElement);
204 for my $root ( $self->{doc}->findnodes($self->{item_xpath}) ) {
205 for my $item ( $self->items ) {
206 $root->appendChild( $item->{doc}->documentElement );
215 return $self->{doc}->toString(1);
224 #----------------------------------------------------------
226 package OpenILS::WWW::SuperCat::Feed::atom;
227 use base 'OpenILS::WWW::SuperCat::Feed';
231 my $self = $class->SUPER::build('<feed xmlns:atom="http://www.w3.org/2005/Atom"/>');
232 $self->{doc}->documentElement->setNamespace('http://www.w3.org/2005/Atom', undef);
233 $self->{doc}->documentElement->setNamespace('http://www.w3.org/2005/Atom', 'atom');
234 $self->{type} = 'application/atom+xml';
235 $self->{item_xpath} = '/atom:feed';
242 $self->_create_node('/atom:feed','http://www.w3.org/2005/Atom','title', $text);
248 $self->_create_node($self->{item_xpath},'http://www.w3.org/2005/Atom','updated', $text);
254 $self->_create_node('/atom:feed','http://www.w3.org/2005/Atom','author');
255 $self->_create_node('/atom:feed/atom:author', 'http://www.w3.org/2005/Atom','name', $text);
262 my $mime = shift || "application/x-$type+xml";
265 $type = 'self' if ($type eq 'atom');
269 'http://www.w3.org/2005/Atom',
284 $self->_create_node( $self->{item_xpath}, 'http://www.w3.org/2005/Atom', 'id', $id );
287 package OpenILS::WWW::SuperCat::Feed::atom::item;
288 use base 'OpenILS::WWW::SuperCat::Feed::atom';
293 my $self = $class->SUPER::build($xml);
294 $self->{doc}->documentElement->setNamespace('http://www.w3.org/2005/Atom', undef);
295 $self->{doc}->documentElement->setNamespace('http://www.w3.org/2005/Atom', 'atom');
296 $self->{item_xpath} = '/atom:entry';
297 $self->{holdings_xpath} = '/atom:entry';
298 $self->{type} = 'application/atom+xml';
303 #----------------------------------------------------------
305 package OpenILS::WWW::SuperCat::Feed::rss2;
306 use base 'OpenILS::WWW::SuperCat::Feed';
310 my $self = $class->SUPER::build('<rss version="2.0"><channel/></rss>');
311 $self->{type} = 'application/rss+xml';
312 $self->{item_xpath} = '/rss/channel';
319 $self->_create_node('/rss/channel',undef,'title', $text);
325 $self->_create_node($self->{item_xpath},undef,'lastBuildDate', $text);
331 $self->_create_node('/rss/channel', undef,'generator', $text);
338 my $mime = shift || "application/x-$type+xml";
340 $type = 'self' if ($type eq 'rss2');
357 $self->_create_node($self->{item_xpath}, undef,'guid', $id);
360 package OpenILS::WWW::SuperCat::Feed::rss2::item;
361 use base 'OpenILS::WWW::SuperCat::Feed::rss2';
366 my $self = $class->SUPER::build($xml);
367 $self->{type} = 'application/rss+xml';
368 $self->{item_xpath} = '/item';
369 $self->{holdings_xpath} = '/item';
376 $self->_create_node($self->{item_xpath},undef,'pubDate', $text);
381 #----------------------------------------------------------
383 package OpenILS::WWW::SuperCat::Feed::mods;
384 use base 'OpenILS::WWW::SuperCat::Feed';
388 my $self = $class->SUPER::build('<mods:modsCollection version="3.0" xmlns:mods="http://www.loc.gov/mods/"/>');
389 $self->{type} = 'application/xml';
390 $self->{item_xpath} = '/mods:modsCollection';
394 package OpenILS::WWW::SuperCat::Feed::mods::item;
395 use base 'OpenILS::WWW::SuperCat::Feed::mods';
400 my $self = $class->SUPER::build($xml);
401 $self->{doc}->documentElement->setNamespace('http://www.loc.gov/mods/', undef);
402 $self->{doc}->documentElement->setNamespace('http://www.loc.gov/mods/', 'mods');
403 $self->{type} = 'application/xml';
404 $self->{holdings_xpath} = '/mods:mods';
415 if ($type eq 'unapi' || $type eq 'opac') {
418 'http://www.loc.gov/mods/',
421 { type => 'otherFormat', id => 'link-'.$linkid }
424 "mods:mods/mods:relatedItem[\@id='link-$linkid']",
425 'http://www.loc.gov/mods/',
426 'mods:recordIdentifier',
434 #----------------------------------------------------------
436 package OpenILS::WWW::SuperCat::Feed::mods3;
437 use base 'OpenILS::WWW::SuperCat::Feed::mods';
441 my $self = $class->SUPER::build('<mods:modsCollection version="3.0" xmlns:mods="http://www.loc.gov/mods/v3"/>');
442 $self->{type} = 'application/xml';
443 $self->{item_xpath} = '/mods:modsCollection';
447 package OpenILS::WWW::SuperCat::Feed::mods3::item;
448 use base 'OpenILS::WWW::SuperCat::Feed::mods::item';
453 my $self = $class->SUPER::build($xml);
454 $self->{doc}->documentElement->setNamespace('http://www.loc.gov/mods/v3', undef);
455 $self->{doc}->documentElement->setNamespace('http://www.loc.gov/mods/v3', 'mods');
456 $self->{type} = 'application/xml';
457 $self->{holdings_xpath} = '/mods:mods';
466 if ($type eq 'unapi' || $type eq 'opac') {
469 'http://www.loc.gov/mods/v3',
472 { type => 'otherFormat', id => 'link-'.$linkid }
475 "mods:mods/mods:relatedItem[\@id='link-$linkid']",
476 'http://www.loc.gov/mods/v3',
477 'mods:recordIdentifier',
485 #----------------------------------------------------------
487 package OpenILS::WWW::SuperCat::Feed::marcxml;
488 use base 'OpenILS::WWW::SuperCat::Feed';
492 my $self = $class->SUPER::build('<marc:collection xmlns:marc="http://www.loc.gov/MARC21/slim"/>');
493 $self->{type} = 'application/xml';
494 $self->{item_xpath} = '/marc:collection';
502 if ($type eq 'unapi') {
505 'http://www.w3.org/1999/xhtml',
508 { rel => 'unapi-server', href => $id, title => "unapi" }
515 package OpenILS::WWW::SuperCat::Feed::marcxml::item;
516 use base 'OpenILS::WWW::SuperCat::Feed::marcxml';
521 my $self = $class->SUPER::build($xml);
522 return undef unless $self;
523 $self->{doc}->documentElement->setNamespace('http://www.loc.gov/MARC21/slim', undef);
524 $self->{type} = 'application/xml';
525 $self->{holdings_xpath} = '/*[local-name()="record"]';
534 if ($type eq 'opac') {
536 '*[local-name()="record"]',
537 'http://www.w3.org/1999/xhtml',
540 { rel => 'otherFormat', href => $id, title => "Dynamic Details" }
543 } elsif ($type eq 'unapi-id') {
545 '*[local-name()="record"]',
546 'http://www.w3.org/1999/xhtml',
549 { title => $id, class => "unapi-id" }
556 #----------------------------------------------------------
558 package OpenILS::WWW::SuperCat::Feed::html;
559 use base 'OpenILS::WWW::SuperCat::Feed::atom';
563 my $self = $class->SUPER::new;
564 $self->type('text/html');
568 our ($_parser, $_xslt, $xslt_file);
572 my $base = $self->base || '';
573 my $root = $self->root || '';
574 my $search = $self->search || '';
575 my $class = $self->class || '';
576 my $lib = $self->lib || '-';
580 $_parser ||= new XML::LibXML;
581 $_xslt ||= new XML::LibXSLT;
584 OpenSRF::Utils::SettingsClient
586 ->config_value( dirs => 'xsl' ).
589 # parse the MODS xslt ...
590 my $atom2html_xslt = $_xslt->parse_stylesheet( $_parser->parse_file($xslt_file) );
592 my $new_doc = $atom2html_xslt->transform(
594 base_dir => "'$root'",
596 searchTerms => "'$search'",
597 searchClass => "'$class'",
600 return $new_doc->toString(1);
604 package OpenILS::WWW::SuperCat::Feed::html::item;
605 use base 'OpenILS::WWW::SuperCat::Feed::atom::item';
607 #----------------------------------------------------------
609 package OpenILS::WWW::SuperCat::Feed::htmlcard;
610 use base 'OpenILS::WWW::SuperCat::Feed::marcxml';
614 my $self = $class->SUPER::new;
615 $self->type('text/html');
616 $self->{xsl} = "/MARC21slim2HTMLCard.xsl";
620 our ($_parser, $_xslt, $xslt_file);
624 my $base = $self->base || '';
625 my $root = $self->root || '';
626 my $search = $self->search || '';
627 my $sort = $self->Sort || '';
628 my $sort_dir = $self->SortDir || '';
629 my $lang = $self->lang || '';
630 my $lib = $self->lib || '-';
634 $_parser ||= new XML::LibXML;
635 $_xslt ||= new XML::LibXSLT;
638 OpenSRF::Utils::SettingsClient
640 ->config_value( dirs => 'xsl' ).$self->{xsl};
642 # parse the MODS xslt ...
643 my $atom2html_xslt = $_xslt->parse_stylesheet( $_parser->parse_file($xslt_file) );
645 my $new_doc = $atom2html_xslt->transform(
647 base_dir => "'$root'",
649 searchTerms => "'$search'",
650 searchSort => "'$sort'",
651 searchSortDir => "'$sort_dir'",
652 searchLang => "'$lang'",
655 return $new_doc->toString(1);
658 package OpenILS::WWW::SuperCat::Feed::htmlcard::item;
659 use base 'OpenILS::WWW::SuperCat::Feed::marcxml::item';
661 package OpenILS::WWW::SuperCat::Feed::htmlholdings;
662 use base 'OpenILS::WWW::SuperCat::Feed::htmlcard';
666 my $self = $class->SUPER::new;
667 $self->{xsl} = "/MARC21slim2HTMLCard-holdings.xsl";
671 package OpenILS::WWW::SuperCat::Feed::htmlholdings::item;
672 use base 'OpenILS::WWW::SuperCat::Feed::htmlcard::item';