1 package OpenILS::WWW::SuperCat::Feed;
2 use strict; use warnings;
4 use OpenSRF::EX qw(:try);
7 use OpenSRF::Utils::SettingsClient;
8 use OpenSRF::Utils::Logger qw/$logger/;
11 my $log = 'OpenSRF::Utils::Logger';
17 return 1 if UNIVERSAL::can("OpenILS::WWW::SuperCat::Feed::$type" => 'new');
28 throw OpenSRF::EX::ERROR ("I need a feed type!") ;
34 return undef unless $xml;
36 $parser = new XML::LibXML if (!$parser);
38 my $self = { doc => $parser->parse_string($xml), items => [] };
40 $self = bless $self => $class;
48 $self->{type} = $type if ($type);
54 return $self->{count};
60 $self->{search} = $search if ($search);
61 return $self->{search};
67 $self->{class} = $search if ($search);
68 return $self->{class};
74 $self->{sort} = $search if ($search);
81 $self->{sort_dir} = $search if ($search);
82 return $self->{sort_dir};
88 $self->{lang} = $search if ($search);
95 $self->{lib} = $lib if ($lib);
102 $self->{base} = $base if ($base);
103 return $self->{base};
109 $self->{root} = $root if ($root);
110 return $self->{root};
116 $self->{unapi} = $unapi if ($unapi);
117 return $self->{unapi};
122 $self->{count} += scalar(@_);
123 push @{ $self->{items} }, @_;
128 return @{ $self->{items} } if (wantarray);
129 return $self->{items};
138 for my $node ($self->{doc}->findnodes($xpath)) {
139 $node->appendChild($new);
153 for my $node ($self->{doc}->findnodes($xpath)) {
154 my $new = $self->{doc}->createElement($name) if (!$ns);
155 $new = $self->{doc}->createElementNS($ns,$name) if ($ns);
157 $new->appendChild( $self->{doc}->createTextNode( $text ) )
161 for my $key (keys %$attrs) {
162 next unless $$attrs{$key};
163 $new->setAttribute( $key => $$attrs{$key} );
167 $node->appendChild( $new );
175 my $class = ref($self) || $self;
178 my $item_xml = shift;
179 my $entry = $class->new($item_xml);
180 return undef unless $entry;
182 $entry->base($self->base);
183 $entry->unapi($self->unapi);
185 $self->push_item($entry);
191 my $holdings_xml = shift;
193 return $self unless ($holdings_xml);
195 $parser = new XML::LibXML if (!$parser);
196 my $new_doc = $parser->parse_string($holdings_xml);
198 for my $root ( $self->{doc}->findnodes($self->{holdings_xpath}) ) {
199 $root->appendChild($new_doc->documentElement);
207 for my $root ( $self->{doc}->findnodes($self->{item_xpath}) ) {
208 for my $item ( $self->items ) {
209 $root->appendChild( $item->{doc}->documentElement );
218 $log->debug("Document composed");
219 return $self->{doc}->toString(1);
228 #----------------------------------------------------------
230 package OpenILS::WWW::SuperCat::Feed::atom;
231 use base 'OpenILS::WWW::SuperCat::Feed';
235 my $self = $class->SUPER::build('<feed xmlns:atom="http://www.w3.org/2005/Atom"/>');
236 $self->{doc}->documentElement->setNamespace('http://www.w3.org/2005/Atom', undef);
237 $self->{doc}->documentElement->setNamespace('http://www.w3.org/2005/Atom', 'atom');
238 $self->{type} = 'application/xml';
239 $self->{item_xpath} = '/atom:feed';
246 $self->_create_node('/atom:feed','http://www.w3.org/2005/Atom','title', $text);
252 $self->_create_node($self->{item_xpath},'http://www.w3.org/2005/Atom','updated', $text);
258 $self->_create_node('/atom:feed','http://www.w3.org/2005/Atom','author');
259 $self->_create_node('/atom:feed/atom:author', 'http://www.w3.org/2005/Atom','name', $text);
266 my $mime = shift || "application/x-$type+xml";
269 $type = 'self' if ($type eq 'atom');
273 'http://www.w3.org/2005/Atom',
288 $self->_create_node( '/atom:feed', 'http://www.w3.org/2005/Atom', 'id', $id );
291 package OpenILS::WWW::SuperCat::Feed::atom::item;
292 use base 'OpenILS::WWW::SuperCat::Feed::atom';
297 my $self = $class->SUPER::build($xml);
298 $self->{doc}->documentElement->setNamespace('http://www.w3.org/2005/Atom', undef);
299 $self->{doc}->documentElement->setNamespace('http://www.w3.org/2005/Atom', 'atom');
300 $self->{item_xpath} = '/atom:entry';
301 $self->{holdings_xpath} = '/atom:entry';
302 $self->{type} = 'application/xml';
307 #----------------------------------------------------------
309 package OpenILS::WWW::SuperCat::Feed::rss2;
310 use base 'OpenILS::WWW::SuperCat::Feed';
314 my $self = $class->SUPER::build('<rss version="2.0"><channel/></rss>');
315 $self->{type} = 'application/xml';
316 $self->{item_xpath} = '/rss/channel';
323 $self->_create_node('/rss/channel',undef,'title', $text);
329 $self->_create_node($self->{item_xpath},undef,'lastBuildDate', $text);
335 $self->_create_node('/rss/channel', undef,'generator', $text);
342 my $mime = shift || "application/x-$type+xml";
344 $type = 'self' if ($type eq 'rss2');
357 package OpenILS::WWW::SuperCat::Feed::rss2::item;
358 use base 'OpenILS::WWW::SuperCat::Feed::rss2';
363 my $self = $class->SUPER::build($xml);
364 $self->{type} = 'application/xml';
365 $self->{item_xpath} = '/item';
366 $self->{holdings_xpath} = '/item';
373 $self->_create_node($self->{item_xpath},undef,'pubDate', $text);
378 #----------------------------------------------------------
380 package OpenILS::WWW::SuperCat::Feed::mods;
381 use base 'OpenILS::WWW::SuperCat::Feed';
385 my $self = $class->SUPER::build('<mods:modsCollection version="3.0" xmlns:mods="http://www.loc.gov/mods/"/>');
386 $self->{type} = 'application/xml';
387 $self->{item_xpath} = '/mods:modsCollection';
391 package OpenILS::WWW::SuperCat::Feed::mods::item;
392 use base 'OpenILS::WWW::SuperCat::Feed::mods';
397 my $self = $class->SUPER::build($xml);
398 $self->{doc}->documentElement->setNamespace('http://www.loc.gov/mods/', undef);
399 $self->{doc}->documentElement->setNamespace('http://www.loc.gov/mods/', 'mods');
400 $self->{type} = 'application/xml';
401 $self->{holdings_xpath} = '/mods:mods';
412 if ($type eq 'unapi' || $type eq 'opac') {
415 'http://www.loc.gov/mods/',
418 { type => 'otherFormat', id => 'link-'.$linkid }
421 "mods:mods/mods:relatedItem[\@id='link-$linkid']",
422 'http://www.loc.gov/mods/',
423 'mods:recordIdentifier',
431 #----------------------------------------------------------
433 package OpenILS::WWW::SuperCat::Feed::mods3;
434 use base 'OpenILS::WWW::SuperCat::Feed::mods';
438 my $self = $class->SUPER::build('<mods:modsCollection version="3.0" xmlns:mods="http://www.loc.gov/mods/v3"/>');
439 $self->{type} = 'application/xml';
440 $self->{item_xpath} = '/mods:modsCollection';
444 package OpenILS::WWW::SuperCat::Feed::mods3::item;
445 use base 'OpenILS::WWW::SuperCat::Feed::mods::item';
450 my $self = $class->SUPER::build($xml);
451 $self->{doc}->documentElement->setNamespace('http://www.loc.gov/mods/v3', undef);
452 $self->{doc}->documentElement->setNamespace('http://www.loc.gov/mods/v3', 'mods');
453 $self->{type} = 'application/xml';
454 $self->{holdings_xpath} = '/mods:mods';
463 if ($type eq 'unapi' || $type eq 'opac') {
466 'http://www.loc.gov/mods/v3',
469 { type => 'otherFormat', id => 'link-'.$linkid }
472 "mods:mods/mods:relatedItem[\@id='link-$linkid']",
473 'http://www.loc.gov/mods/v3',
474 'mods:recordIdentifier',
482 #----------------------------------------------------------
484 package OpenILS::WWW::SuperCat::Feed::marcxml;
485 use base 'OpenILS::WWW::SuperCat::Feed';
489 my $self = $class->SUPER::build('<marc:collection xmlns:marc="http://www.loc.gov/MARC21/slim"/>');
490 $self->{type} = 'application/xml';
491 $self->{item_xpath} = '/marc:collection';
499 if ($type eq 'unapi') {
502 'http://www.w3.org/1999/xhtml',
505 { rel => 'unapi-server', href => $id, title => "unapi" }
512 package OpenILS::WWW::SuperCat::Feed::marcxml::item;
513 use base 'OpenILS::WWW::SuperCat::Feed::marcxml';
518 my $self = $class->SUPER::build($xml);
519 return undef unless $self;
520 $self->{doc}->documentElement->setNamespace('http://www.loc.gov/MARC21/slim', undef);
521 $self->{doc}->documentElement->setNamespace('http://www.loc.gov/MARC21/slim', 'marc');
522 $self->{type} = 'application/xml';
523 $self->{holdings_xpath} = '/marc:record';
532 if ($type eq 'opac') {
535 'http://www.w3.org/1999/xhtml',
538 { rel => 'otherFormat', href => $id, title => "Dynamic Details" }
541 } elsif ($type eq 'unapi-id') {
544 'http://www.w3.org/1999/xhtml',
547 { title => $id, class => "unapi-id" }
554 #----------------------------------------------------------
556 package OpenILS::WWW::SuperCat::Feed::html;
557 use base 'OpenILS::WWW::SuperCat::Feed::atom';
561 my $self = $class->SUPER::new;
562 $self->type('text/html');
566 our ($_parser, $_xslt, $xslt_file);
570 my $base = $self->base || '';
571 my $root = $self->root || '';
572 my $search = $self->search || '';
573 my $class = $self->class || '';
574 my $lib = $self->lib || '-';
578 $_parser ||= new XML::LibXML;
579 $_xslt ||= new XML::LibXSLT;
582 OpenSRF::Utils::SettingsClient
584 ->config_value( dirs => 'xsl' ).
587 # parse the MODS xslt ...
588 my $atom2html_xslt = $_xslt->parse_stylesheet( $_parser->parse_file($xslt_file) );
590 my $new_doc = $atom2html_xslt->transform(
592 base_dir => "'$root'",
594 searchTerms => "'$search'",
595 searchClass => "'$class'",
598 return $new_doc->toString(1);
602 package OpenILS::WWW::SuperCat::Feed::html::item;
603 use base 'OpenILS::WWW::SuperCat::Feed::atom::item';
605 #----------------------------------------------------------
607 package OpenILS::WWW::SuperCat::Feed::htmlcard;
608 use base 'OpenILS::WWW::SuperCat::Feed::marcxml';
612 my $self = $class->SUPER::new;
613 $self->type('text/html');
614 $self->{xsl} = "/MARC21slim2HTMLCard.xsl";
618 our ($_parser, $_xslt, $xslt_file);
622 my $base = $self->base || '';
623 my $root = $self->root || '';
624 my $search = $self->search || '';
625 my $sort = $self->Sort || '';
626 my $sort_dir = $self->SortDir || '';
627 my $lang = $self->lang || '';
628 my $lib = $self->lib || '-';
632 $_parser ||= new XML::LibXML;
633 $_xslt ||= new XML::LibXSLT;
636 OpenSRF::Utils::SettingsClient
638 ->config_value( dirs => 'xsl' ).$self->{xsl};
640 # parse the MODS xslt ...
641 my $atom2html_xslt = $_xslt->parse_stylesheet( $_parser->parse_file($xslt_file) );
643 my $new_doc = $atom2html_xslt->transform(
645 base_dir => "'$root'",
647 searchTerms => "'$search'",
648 searchSort => "'$sort'",
649 searchSortDir => "'$sort_dir'",
650 searchLang => "'$lang'",
653 return $new_doc->toString(1);
656 package OpenILS::WWW::SuperCat::Feed::htmlcard::item;
657 use base 'OpenILS::WWW::SuperCat::Feed::marcxml::item';
659 package OpenILS::WWW::SuperCat::Feed::htmlholdings;
660 use base 'OpenILS::WWW::SuperCat::Feed::htmlcard';
664 my $self = $class->SUPER::new;
665 $self->{xsl} = "/MARC21slim2HTMLCard-holdings.xsl";
669 package OpenILS::WWW::SuperCat::Feed::htmlholdings::item;
670 use base 'OpenILS::WWW::SuperCat::Feed::htmlcard::item';