From: dbs Date: Sun, 15 Mar 2009 05:47:12 +0000 (+0000) Subject: Add performer notes tab to OPAC record detail extras (for performers and participants) X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=8afc05baaac366d0db06122c4265a6e47a639b93;p=contrib%2FConifer.git Add performer notes tab to OPAC record detail extras (for performers and participants) Hook TOC up to Table of Contents in OPAC record detail extras. Bring place of publication and publisher together Clean up the physical description (still need to apply same logic to rresult) git-svn-id: svn://svn.open-ils.org/ILS-Contrib/conifer/trunk@177 6d9bc8c9-1ec2-4278-b937-99fde70a366f --- diff --git a/conf/fm_IDL.xml b/conf/fm_IDL.xml new file mode 100644 index 0000000000..46e9426053 --- /dev/null +++ b/conf/fm_IDL.xml @@ -0,0 +1,5419 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SELECT t.* + FROM action.transit_copy t + JOIN actor.org_unit AS s ON (t.source = s.id) + JOIN actor.org_unit AS d ON (t.dest = d.id) + WHERE s.parent_ou <> d.parent_ou + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/perlmods/OpenILS/Utils/ModsParser.pm b/src/perlmods/OpenILS/Utils/ModsParser.pm new file mode 100644 index 0000000000..14e30850a3 --- /dev/null +++ b/src/perlmods/OpenILS/Utils/ModsParser.pm @@ -0,0 +1,492 @@ +package OpenILS::Utils::ModsParser; +use strict; use warnings; + +use OpenSRF::EX qw/:try/; +use XML::LibXML; +use XML::LibXSLT; +use Time::HiRes qw(time); +use OpenILS::Utils::Fieldmapper; +use OpenSRF::Utils::SettingsClient; +use OpenSRF::Utils::Logger qw/$logger/; +use Data::Dumper; + +my $parser = XML::LibXML->new(); +my $xslt = XML::LibXSLT->new(); +my $mods_sheet; + +# ---------------------------------------------------------------------------------------- +# XPATH for extracting info from a MODS doc +my $isbn_xpath = "//mods:mods/mods:identifier[\@type='isbn']"; +my $resource_xpath = "//mods:mods/mods:typeOfResource"; +my $pub_xpath = "//mods:mods/mods:originInfo//mods:dateIssued[1]|" . + "//mods:mods/mods:originInfo//mods:dateIssued[\@encoding='marc']"; +my $tcn_xpath = "//mods:mods/mods:recordInfo/mods:recordIdentifier"; +my $pub_place_xpath = "//mods:mods/mods:originInfo//mods:place//mods:placeTerm[\@type='text']"; +my $publisher_xpath = "//mods:mods/mods:originInfo//mods:publisher"; +my $edition_xpath = "//mods:mods/mods:originInfo//mods:edition[1]"; +my $abstract_xpath = "//mods:mods/mods:abstract"; +my $related_xpath = ""; +my $online_loc_xpath = "//mods:location/mods:url"; +my $physical_desc = "(//mods:physicalDescription/mods:form|//mods:physicalDescription/mods:extent|". + "//mods:physicalDescription/mods:reformattingQuality|//mods:physicalDescription/mods:internetMediaType|". + "//mods:physicalDescription/mods:digitalOrigin)"; +my $extent_xpath = "//mods:physicalDescription/mods:extent"; +my $toc_xpath = "//mods:tableOfContents"; +my $performers_xpath = "//mods:note[\@type='performers']"; + +my $xpathset = { + + title => { + abbreviated => + "//mods:mods/mods:titleInfo[mods:title and (\@type='abbreviated')]", + translated => + "//mods:mods/mods:titleInfo[mods:title and (\@type='translated')]", + uniform => + "//mods:mods/mods:titleInfo[mods:title and (\@type='uniform')]", + proper => + "//mods:mods/mods:titleInfo[mods:title and not (\@type)]", + any => + "//mods:mods/mods:titleInfo", + }, + + author => { + corporate => + "//mods:mods/mods:name[\@type='corporate']/*[local-name()='namePart']". + "[../mods:role/mods:text[text()='creator']". + " or ../mods:role/mods:roleTerm[". + " \@type='text'". + " and \@authority='marcrelator'". + " and text()='creator']". + "][1]", + personal => + "//mods:mods/mods:name[\@type='personal']/*[local-name()='namePart']". + "[../mods:role/mods:text[text()='creator']". + " or ../mods:role/mods:roleTerm[". + " \@type='text'". + " and \@authority='marcrelator'". + " and text()='creator']". + "][1]", + conference => + "//mods:mods/mods:name[\@type='conference']/*[local-name()='namePart']". + "[../mods:role/mods:text[text()='creator']". + " or ../mods:role/mods:roleTerm[". + " \@type='text'". + " and \@authority='marcrelator'". + " and text()='creator']". + "][1]", + other => + "//mods:mods/mods:name[\@type='personal']/*[local-name()='namePart']", + any => + "//mods:mods/mods:name/*[local-name()='namePart'][1]", + }, + + subject => { + + topic => + "//mods:mods/mods:subject/*[". + " local-name()='geographic'". + " or local-name()='name'". + " or local-name()='temporal'". + " or local-name()='topic'". + "]/parent::mods:subject", + +# geographic => +# "//mods:mods/*[local-name()='subject']/*[local-name()='geographic']", +# name => +# "//mods:mods/*[local-name()='subject']/*[local-name()='name']", +# temporal => +# "//mods:mods/*[local-name()='subject']/*[local-name()='temporal']", +# topic => +# "//mods:mods/*[local-name()='subject']/*[local-name()='topic']", + }, + #keyword => { keyword => "//mods:mods/*[not(local-name()='originInfo')]", }, + + series => { + series => "//mods:mods/mods:relatedItem[\@type='series']/mods:titleInfo" + } +}; +# ---------------------------------------------------------------------------------------- + + + +sub new { return bless( {}, shift() ); } + +sub get_field_value { + + my( $self, $mods, $xpath ) = @_; + + my @string; + + my $root = $mods->documentElement; + $root->setNamespace( "http://www.loc.gov/mods/v3", "mods", 1 ); + + try { + # grab the set of matching nodes + my @nodes = $root->findnodes( $xpath ); + for my $value (@nodes) { + + # grab all children of the node + my @children = $value->childNodes(); + my @child_text; + for my $child (@children) { + next unless( $child->nodeType != 3 ); + + if($child->childNodes) { + my @a; + for my $c (@{$child->childNodes}){ + push @a, $c->textContent; + } + push(@child_text, join(' ', @a)); + + } else { + push(@child_text, $child->textContent); + } + + } + if(@child_text) { + push(@string, \@child_text); + } + + if( !@child_text ) { + push(@string, $value->textContent ); + } + } + } otherwise { + $logger->info("MODS-izing failure: ".shift()); + $logger->info("Failed MODS xml: ".$root->toString); + $logger->info("Failed MODS xpath: $xpath"); + }; + return @string; +} + +=head +sub _modsdoc_to_values { + my( $self, $mods ) = @_; + my $data = {}; + for my $class (keys %$xpathset) { + $data->{$class} = {}; + for my $type(keys %{$xpathset->{$class}}) { + my @value = $self->get_field_value( $mods, $xpathset->{$class}->{$type} ); + if( $class eq "subject" ) { + push( @{$data->{$class}->{$type}}, @value ); + } else { + $data->{$class}->{$type} = $value[0]; + } + } + } + return $data; +} +=cut + +sub modsdoc_to_values { + my( $self, $mods ) = @_; + my $data = {}; + + { + my $class = "subject"; + $data->{$class} = {}; + for my $type(keys %{$xpathset->{$class}}) { + my @value = $self->get_field_value( $mods, $xpathset->{$class}->{$type} ); + for my $arr (@value) { + push( @{$data->{$class}->{$type}}, $arr); + } + } + } + + { + my $class = "title"; + $data->{$class} = {}; + for my $type(keys %{$xpathset->{$class}}) { + my @value = $self->get_field_value( $mods, $xpathset->{$class}->{$type} ); + for my $arr (@value) { + if( ref($arr) ) { + $data->{$class}->{$type} = shift @$arr; + + my $t = lc($data->{$class}->{$type}); + if($t and $t =~ /^l[eoa]s|l[ae]|el|the|un[ae]?|an?\s?$/o ) { + my $val = shift @$arr || ""; + $data->{$class}->{$type} .= " $val" if $data->{$class}->{$type}; + $data->{$class}->{$type} = " $val" unless $data->{$class}->{$type}; + } + + for my $t (@$arr) { + $data->{$class}->{$type} .= ' : ' if ($data->{$class}->{$type} =~ /\w\s*$/o); + $data->{$class}->{$type} .= " $t"; + } + } else { + $data->{$class}->{$type} = $arr; + } + } + $data->{$class}->{$type} =~ s/\s+/ /go if ($data->{$class}->{$type}); + } + } + + { + my $class = "author"; + $data->{$class} = {}; + for my $type(keys %{$xpathset->{$class}}) { + my @value = $self->get_field_value( $mods, $xpathset->{$class}->{$type} ); + $data->{$class}->{$type} = $value[0]; + } + } + + { + my $class = "series"; + $data->{$class} = {}; + for my $type(keys %{$xpathset->{$class}}) { + my @value = $self->get_field_value( $mods, $xpathset->{$class}->{$type} ); + for my $arr (@value) { + if( ref($arr) ) { + push(@{$data->{$class}->{$type}}, join(" ", @$arr)); + } else { + push( @{$data->{$class}->{$type}}, $arr ); + } + } + } + + } + + return $data; +} + + + + +# --------------------------------------------------------------------------- +# Grabs the data 'we want' from the MODS doc and returns it in hash form +# --------------------------------------------------------------------------- +sub mods_values_to_mods_slim { + my( $self, $modsperl ) = @_; + + my $title = ""; + my $author = ""; + my $subject = []; + my $series = []; + + my $tmp = $modsperl->{title}; + + + if(!$tmp) { $title = ""; } + else { + ($title = $tmp->{proper}) || + ($title = $tmp->{translated}) || + ($title = $tmp->{abbreviated}) || + ($title = $tmp->{uniform}) || + ($title = $tmp->{any}); + } + + $tmp = $modsperl->{author}; + if(!$tmp) { $author = ""; } + else { + ($author = $tmp->{personal}) || + ($author = $tmp->{corporate}) || + ($author = $tmp->{conference}) || + ($author = $tmp->{other}) || + ($author = $tmp->{any}); + } + + $tmp = $modsperl->{subject}; + if(!$tmp) { $subject = {}; } + else { + for my $key( keys %{$tmp}) { + push(@$subject, @{$tmp->{$key}}) if ($tmp->{$key}); + } + my $subh = {}; + for my $s (@$subject) { + if(defined($subh->{$s})) { $subh->{$s->[0]}++ } else { $subh->{$s->[0]} = 1;} + } + $subject = $subh + } + + $tmp = $modsperl->{'series'}; + if(!$tmp) { $series = []; } + else { $series = $tmp->{'series'}; } + + + return { series => $series, title => $title, + author => $author, subject => $subject }; +} + + + +# --------------------------------------------------------------------------- +# Initializes a MARC -> Unified MODS batch process +# --------------------------------------------------------------------------- + +sub start_mods_batch { + + my( $self, $master_doc ) = @_; + + if(!$master_doc) { + $self->{master_doc} = undef; + return; + } + + if(!$mods_sheet) { + my $xslt_doc = $parser->parse_file( + OpenSRF::Utils::SettingsClient->new->config_value(dirs => 'xsl') . "/MARC21slim2MODS33.xsl"); + $mods_sheet = $xslt->parse_stylesheet( $xslt_doc ); + } + + + my $xmldoc = $parser->parse_string($master_doc); + my $mods = $mods_sheet->transform($xmldoc); + + $self->{master_doc} = $self->modsdoc_to_values( $mods ); + $self->{master_doc} = $self->mods_values_to_mods_slim( $self->{master_doc} ); + + ($self->{master_doc}->{isbn}) = + $self->get_field_value( $mods, $isbn_xpath ); + + $self->{master_doc}->{type_of_resource} = + [ $self->get_field_value( $mods, $resource_xpath ) ]; + + ($self->{master_doc}->{tcn}) = + $self->get_field_value( $mods, $tcn_xpath ); + + ($self->{master_doc}->{pubdate}) = + $self->get_field_value( $mods, $pub_xpath ); + + my @pub_place = $self->get_field_value( $mods, $pub_place_xpath ); + my @publisher = $self->get_field_value( $mods, $publisher_xpath ); + + if (@pub_place && @publisher) { + ($self->{master_doc}->{publisher}) = $pub_place[0] . " : " . $publisher[0]; + } elsif (@pub_place) { + ($self->{master_doc}->{publisher}) = $pub_place[0]; + } elsif (@publisher) { + ($self->{master_doc}->{publisher}) = $publisher[0]; + } else { + ($self->{master_doc}->{publisher}) = undef; + } + + ($self->{master_doc}->{edition}) = + $self->get_field_value( $mods, $edition_xpath ); + + ($self->{master_doc}->{performer_notes}) = + $self->get_field_value( $mods, $performers_xpath ); + +# ------------------------------ + # holds an array of [ link, title, link, title, ... ] + $self->{master_doc}->{online_loc} = []; + for my $url ($mods->findnodes($online_loc_xpath)) { + push(@{$self->{master_doc}->{online_loc}}, $url->textContent); + push(@{$self->{master_doc}->{online_loc}}, $url->getAttribute('displayLabel') || ''); + push(@{$self->{master_doc}->{online_loc}}, $url->getAttribute('note') || ''); + } + + ($self->{master_doc}->{synopsis}) = + $self->get_field_value( $mods, $abstract_xpath ); + + $self->{master_doc}->{physical_description} = []; + push(@{$self->{master_doc}->{physical_description}}, + $self->get_field_value( $mods, $physical_desc ) ); + $self->{master_doc}->{physical_description} = + join( ' ', @{$self->{master_doc}->{physical_description}}); + + ($self->{master_doc}->{toc}) = $self->get_field_value($mods, $toc_xpath); + + ($self->{master_doc}->{extent}) = + $self->get_field_value($mods, $extent_xpath); + +} + + + +# --------------------------------------------------------------------------- +# Takes a MARCXML string and adds it to the growing MODS doc +# --------------------------------------------------------------------------- +sub push_mods_batch { + my( $self, $marcxml ) = @_; + + my $xmldoc = $parser->parse_string($marcxml); + my $mods = $mods_sheet->transform($xmldoc); + + my $xmlperl = $self->modsdoc_to_values( $mods ); + $xmlperl = $self->mods_values_to_mods_slim( $xmlperl ); + + # for backwards compatibility, remove the array part when all is decided + if(ref($xmlperl->{subject}) eq 'ARRAY' ) { + for my $subject( @{$xmlperl->{subject}} ) { + push @{$self->{master_doc}->{subject}}, $subject; + } + } else { + for my $subject ( keys %{$xmlperl->{subject}} ) { + my $s = $self->{master_doc}->{subject}; + if(defined($s->{$subject})) { $s->{$subject}++; } else { $s->{$subject} = 1; } + } + } + + push( @{$self->{master_doc}->{type_of_resource}}, + $self->get_field_value( $mods, $resource_xpath )); + + if(!($self->{master_doc}->{isbn}) ) { + ($self->{master_doc}->{isbn}) = + $self->get_field_value( $mods, $isbn_xpath ); + } +} + + +# --------------------------------------------------------------------------- +# Completes a MARC -> Unified MODS batch process and returns the perl hash +# --------------------------------------------------------------------------- +sub init_virtual_record { + my $record = Fieldmapper::metabib::virtual_record->new; + $record->subject([]); + $record->types_of_resource([]); + $record->call_numbers([]); + return $record; +} + +sub finish_mods_batch { + my $self = shift; + + return undef unless $self->{master_doc}; + + my $perl = $self->{master_doc}; + my $record = init_virtual_record(); + + # turn the hash into a fieldmapper object + #(my $title = $perl->{title}) =~ s/\[.*?\]//og; + #(my $author = $perl->{author}) =~ s/\(.*?\)//og; + my $title = $perl->{title}; + my $author = $perl->{author}; + + my @series; + for my $s (@{$perl->{series}}) { + push @series, (split( /\s*;/, $s ))[0]; + } + + # uniquify the types of resource + my $rtypes = $perl->{type_of_resource}; + my %hash = map { ($_ => 1) } @$rtypes; + $rtypes = [ keys %hash ]; + + $record->title($title); + $record->author($author); + + $record->doc_id($perl->{doc_id}); + $record->isbn($perl->{isbn}); + $record->pubdate($perl->{pubdate}); + $record->publisher($perl->{publisher}); + $record->tcn($perl->{tcn}); + + $record->edition($perl->{edition}); + + $record->subject($perl->{subject}); + $record->types_of_resource($rtypes); + $record->series(\@series); + + $record->online_loc($perl->{online_loc}); + $record->synopsis($perl->{synopsis}); + $record->physical_description($perl->{physical_description}); + $record->toc($perl->{toc}); + $record->performer_notes($perl->{performer_notes}); + $record->extent($perl->{extent}); + + $self->{master_doc} = undef; + return $record; +} + + + diff --git a/web/opac/locale/en-US/opac.dtd b/web/opac/locale/en-US/opac.dtd new file mode 100644 index 0000000000..ce1381cdbd --- /dev/null +++ b/web/opac/locale/en-US/opac.dtd @@ -0,0 +1,694 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +try again. +

Alternatively, you can use the basic HTML-only catalog +here."> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +! +Please see a librarian to renew your account."> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +not contain the following words"> +exact phrase"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +My Account for setting your email address)"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/opac/skin/default/js/rdetail.js b/web/opac/skin/default/js/rdetail.js new file mode 100644 index 0000000000..254270a5bf --- /dev/null +++ b/web/opac/skin/default/js/rdetail.js @@ -0,0 +1,924 @@ +/* */ + + +detachAllEvt('common', 'run'); +attachEvt("common", "run", rdetailDraw); +attachEvt("rdetail", "recordDrawn", rdetailBuildStatusColumns); +attachEvt("rdetail", "recordDrawn", rdetailBuildInfoRows); +attachEvt("rdetail", "recordDrawn", rdetailGetPageIds); + +var record = null; +var cp_statuses = null; +var recordsCache = []; + +var copyRowParent = null; +var copyRow = null; +var statusRow = null; +var numStatuses = null; +var defaultCN; +var callnumberCache = {}; +var rdetailLocalOnly = true; +var globalCNCache = {}; +var localTOC; +var cachedRecords; +var _statusPositions = {}; + +var rdetailShowLocal = true; +var rdetailShowCopyLocation = true; +var googleBookPreview = true; + + +var nextContainerIndex; + +function rdetailReload() { + var args = {}; + args[PARAM_LOCATION] = getNewSearchLocation(); + args[PARAM_DEPTH] = depthSelGetDepth(); + goTo(buildOPACLink(args)); +} + +var nextRecord; +var prevRecord; + +var rdetailPrev = null; +var rdetailNext = null; +var rdetailStart = null; +var rdetailEnd = null; + + + +/* looks to see if we have a next and/or previous record in the + record cache, if so, set up the nav links */ +function rdetailSetPaging(ids) { + + cachedRecords = {}; + cachedRecords.ids = ids; + + for( var i = 0; i < cachedRecords.ids.length; i++ ) { + var rec = cachedRecords.ids[i]; + if( rec == getRid() ) { + if( i > 0 ) prevRecord = cachedRecords.ids[i-1]; + if( i < cachedRecords.ids.length - 1 ) + nextRecord = cachedRecords.ids[i+1]; + break; + } + } + + $('np_offset').appendChild(text(i + 1)); + $('np_count').appendChild(text(getHitCount())); + + if(prevRecord) { + unHideMe($('np_table')); + unHideMe($('np_prev')); + unHideMe($('np_start')); + rdetailPrev = function() { _rdetailNav(prevRecord); }; + rdetailStart = function() { _rdetailNav(cachedRecords.ids[0]); }; + } + + if(nextRecord) { + unHideMe($('np_table')); + unHideMe($('np_next')); + unHideMe($('np_end')); + rdetailNext = function() { _rdetailNav(nextRecord); }; + rdetailEnd = function() { _rdetailNav(cachedRecords.ids[cachedRecords.ids.length-1]); }; + } + + runEvt('rdetail', 'nextPrevDrawn', i, cachedRecords.ids.length); +} + + +function _rdetailNav(id, offset) { + var args = {}; + args[PARAM_RID] = id; + goTo(buildOPACLink(args)); +} + +function rdetailDraw() { + + detachAllEvt('common','depthChanged'); + detachAllEvt('common','locationUpdated'); + attachEvt('common','depthChanged', rdetailReload); + attachEvt('common','locationUpdated', rdetailReload); + attachEvt('common','holdUpdated', rdetailReload); + attachEvt('common','holdUpdateCanceled', rdetailReload); + + copyRowParent = G.ui.rdetail.cp_info_row.parentNode; + copyRow = copyRowParent.removeChild(G.ui.rdetail.cp_info_row); + statusRow = G.ui.rdetail.cp_status.parentNode; + statusRow.id = '__rdsrow'; + + G.ui.rdetail.cp_info_local.onclick = rdetailShowLocalCopies; + G.ui.rdetail.cp_info_all.onclick = rdetailShowAllCopies; + + if(getLocation() == globalOrgTree.id()) + hideMe(G.ui.rdetail.cp_info_all); + + var req = new Request(FETCH_RMODS, getRid()); + req.callback(_rdetailDraw); + req.send(); + + detachAllEvt("result", "idsReceived"); + G.evt.result.hitCountReceived = []; + G.evt.result.recordReceived = []; + G.evt.result.copyCountsReceived = []; + G.evt.result.allRecordsReceived = []; +} + +function rdetailGetPageIds() { + attachEvt("result", "idsReceived", rdetailSetPaging ); + resultFetchAllRecords = true; + rresultCollectIds(true); +} + + +function buildunAPISpan (span, type, id) { + var cgi = new CGI(); + var d = new Date(); + + addCSSClass(span,'unapi-id'); + + span.setAttribute( + 'title', 'tag:' + cgi.server_name + ',' + + d.getFullYear() + ':' + type + '/' + id + ); +} + +function rdetailViewMarc(r,id) { + hideMe($('rdetail_extras_loading')); + $('rdetail_view_marc_box').innerHTML = r.getResultObject(); + + var div = elem('div', { "class" : 'hide_me' }); + var span = div.appendChild( elem('abbr') ); + + buildunAPISpan( span, 'biblio-record_entry', record.doc_id() ); + + $('rdetail_view_marc_box').insertBefore(span, $('rdetail_view_marc_box').firstChild); +} + + +function rdetailShowLocalCopies() { + rdetailShowLocal = true; + rdetailBuildInfoRows(); + hideMe(G.ui.rdetail.cp_info_local); + unHideMe(G.ui.rdetail.cp_info_all); + hideMe(G.ui.rdetail.cp_info_none); +} + +function rdetailShowAllCopies() { + + rdetailShowLocal = false; + rdetailBuildInfoRows(); + hideMe(G.ui.rdetail.cp_info_all); + unHideMe(G.ui.rdetail.cp_info_local); + hideMe(G.ui.rdetail.cp_info_none); +} + + +function _rdetailDraw(r) { + record = r.getResultObject(); + + runEvt('rdetail', 'recordRetrieved', record.doc_id()); + + G.ui.rdetail.title.appendChild(text(record.title())); + buildSearchLink(STYPE_AUTHOR, record.author(), G.ui.rdetail.author); + G.ui.rdetail.isbn.appendChild(text(cleanISBN(record.isbn()))); + G.ui.rdetail.edition.appendChild(text(record.edition())); + G.ui.rdetail.pubdate.appendChild(text(record.pubdate())); + G.ui.rdetail.publisher.appendChild(text(record.publisher())); + if (record.extent()) { + $('rdetail_physical_desc').appendChild(text(record.extent())); + } else { + $('rdetail_physical_desc').appendChild(text(record.physical_description())); + } + r = record.types_of_resource(); + if(r) { + G.ui.rdetail.tor.appendChild(text(r[0])); + setResourcePic( G.ui.rdetail.tor_pic, r[0]); + } + G.ui.rdetail.abstr.appendChild(text(record.synopsis())); + + try{ + if(record.isbn()) { + if(ENABLE_ADDED_CONTENT_ATTRIB_LINKS) { + unHideMe($('rdetail.jacket_attrib_div')); + var href = $('rdetail.jacket_attrib_link').getAttribute('href') +cleanISBN(record.isbn()); + $('rdetail.jacket_attrib_link').setAttribute('href', href); + } + rdetailCheckForGBPreview(); + + } else { + hideMe($("rdetail.jacket_attrib_div")); + hideMe($("rdetail_img_link")); + } + } catch(E) {} + + + // see if the record has any external links + var links = record.online_loc(); + for( var i = 0; links && links.length > 0 && i < links.length; i = i + 3 ) { + var href = links[i]; + // avoid matching "HTTP: The Complete Reference" + if( href.match(/https?:\/|ftps?:\/|mailto:/i) ) { + unHideMe($('rdetail_online_row')); + // MODS can contain a display label (used for the text of the link) + // as well as a note about the URL; many legacy systems conflate the + // two and generate MARC records that expect the note to be used as + // the text of the link, with no display label; here's the canonical + // format: + // + // 856 40 $uhttp://localhost$yDisplay label$zPublic note + // + // Note that the MARC21slim2MODS XSL concatenates $3 and $y together + // (as $y was defined later in MARC21's life as the display label) + var displayLabel = '' + links[i+1]; + var note = '' + links[i+2]; + if(!displayLabel || displayLabel.match(/https?:\/|ftps?:\/|mailto:/i)) { + if(!note || note.match(/https?:\/|ftps?:\/|mailto:/i)) { + displayLabel = href; + } else { + displayLabel = note; + } + } + $('rdetail_online').appendChild(elem('a', {href:href,'class':'classic_link'}, displayLabel)); + if (!note && note != displayLabel) { + $('rdetail_online').appendChild(elem('span', {'class':'url_note'}, ' - ' + note)); + } + $('rdetail_online').appendChild(elem('br')); + } + } + + // Fill in our unAPI ID, if anyone cares + var abbrs = document.getElementsByTagName('abbr'); + var span; + for (var i = 0; i < abbrs.length; i = i + 1) { + if (abbrs[i].getAttribute('name') == 'unapi') { + span = abbrs[i]; + break; + } + } + buildunAPISpan( span, 'biblio-record_entry', record.doc_id() ); + + $('rdetail_place_hold').setAttribute( + 'href','javascript:holdsDrawEditor({record:"'+record.doc_id()+'",type:"T"});'); + + $('rdetail_img_link').setAttribute('href', buildISBNSrc(cleanISBN(record.isbn()), 'large')); + G.ui.rdetail.image.setAttribute("src", buildISBNSrc(cleanISBN(record.isbn()))); + runEvt("rdetail", "recordDrawn"); + recordsCache.push(record); + + rdetailSetExtrasSelector(); + + var breq = new Request(FETCH_BRE, [getRid()]); + breq.callback( rdetailCheckDeleted ); + breq.send(); + + resultBuildCaches( [ record ] ); + resultDrawSubjects(); + resultDrawSeries(); + + // grab added content + acCollectData(cleanISBN(record.isbn()), rdetailhandleAC); +} + + + +function rdetailCheckDeleted(r) { + var br = r.getResultObject()[0]; + if( isTrue(br.deleted()) ) { + hideMe($('rdetail_place_hold')); + $('rdetail_more_actions_selector').disabled = true; + unHideMe($('rdetail_deleted_exp')); + } +} + +function rdetailSetExtrasSelector() { + if(!grabUser()) return; + unHideMe($('rdetail_more_actions')); + + var req = new Request( + FETCH_CONTAINERS, G.user.session, G.user.id(), 'biblio', 'bookbag' ); + req.callback(rdetailAddBookbags); + req.send(); +} + +function rdetailAddBookbags(r) { + + var containers = r.getResultObject(); + var selector = $('rdetail_more_actions_selector'); + var found = false; + var index = 3; + doSelectorActions(selector); + + for( var i = 0; i != containers.length; i++ ) { + found = true; + var container = containers[i]; + insertSelectorVal( selector, index++, container.name(), + "container_" + container.id(), rdetailAddToBookbag, 1 ); + } + + nextContainerIndex = index; +} + +var _actions = {}; +function rdetailNewBookbag() { + var name = prompt($('rdetail_bb_new').innerHTML,""); + if(!name) return; + + var id; + if( id = containerCreate( name ) ) { + alert($('rdetail_bb_success').innerHTML); + var selector = $('rdetail_more_actions_selector'); + insertSelectorVal( selector, nextContainerIndex++, name, + "container_" + id, rdetailAddToBookbag, 1 ); + setSelector( selector, 'start' ); + } +} + + +function rdetailAddToBookbag() { + var selector = $('rdetail_more_actions_selector'); + var id = selector.options[selector.selectedIndex].value; + setSelector( selector, 'start' ); + + if( containerCreateItem( id.substring(10), record.doc_id() )) { + alert($('rdetail_bb_item_success').innerHTML); + } +} + + +var rdetailMarcFetched = false; +function rdetailShowExtra(type, args) { + + hideMe($('rdetail_copy_info_div')); + hideMe($('rdetail_reviews_div')); + hideMe($('rdetail_toc_div')); + hideMe($('rdetail_anotes_div')); + hideMe($('rdetail_performer_notes_div')); + hideMe($('rdetail_excerpt_div')); + hideMe($('rdetail_preview_div')); + hideMe($('rdetail_marc_div')); + hideMe($('cn_browse')); + hideMe($('rdetail_cn_browse_div')); + hideMe($('rdetail_notes_div')); + + removeCSSClass($('rdetail_copy_info_link'), 'rdetail_extras_selected'); + removeCSSClass($('rdetail_viewcn_link'), 'rdetail_extras_selected'); + removeCSSClass($('rdetail_reviews_link'), 'rdetail_extras_selected'); + removeCSSClass($('rdetail_toc_link'), 'rdetail_extras_selected'); + removeCSSClass($('rdetail_excerpt_link'), 'rdetail_extras_selected'); + removeCSSClass($('rdetail_preview_link'), 'rdetail_extras_selected'); + removeCSSClass($('rdetail_anotes_link'), 'rdetail_extras_selected'); + removeCSSClass($('rdetail_performer_notes_link'), 'rdetail_extras_selected'); + removeCSSClass($('rdetail_annotation_link'), 'rdetail_extras_selected'); + removeCSSClass($('rdetail_viewmarc_link'), 'rdetail_extras_selected'); + + switch(type) { + + case "copyinfo": + unHideMe($('rdetail_copy_info_div')); + addCSSClass($('rdetail_copy_info_link'), 'rdetail_extras_selected'); + break; + + case "reviews": + addCSSClass($('rdetail_reviews_link'), 'rdetail_extras_selected'); + unHideMe($('rdetail_reviews_div')); + break; + + case "excerpt": + addCSSClass($('rdetail_excerpt_link'), 'rdetail_extras_selected'); + unHideMe($('rdetail_excerpt_div')); + break; + + case "preview": + addCSSClass($('rdetail_preview_link'), 'rdetail_extras_selected'); + unHideMe($('rdetail_preview_div')); + rdetailDisplayGBPreview(); + break; + + case "anotes": + addCSSClass($('rdetail_anotes_link'), 'rdetail_extras_selected'); + unHideMe($('rdetail_anotes_div')); + break; + + case "performer_notes": + addCSSClass($('rdetail_performer_notes_link'), 'rdetail_extras_selected'); + unHideMe($('rdetail_performer_notes_div')); + break; + + case "toc": + addCSSClass($('rdetail_toc_link'), 'rdetail_extras_selected'); + unHideMe($('rdetail_toc_div')); + break; + + case "marc": + addCSSClass($('rdetail_viewmarc_link'), 'rdetail_extras_selected'); + unHideMe($('rdetail_marc_div')); + if(rdetailMarcFetched) return; + unHideMe($('rdetail_extras_loading')); + rdetailMarcFetched = true; + var req = new Request( FETCH_MARC_HTML, record.doc_id() ); + req.callback(rdetailViewMarc); + req.send(); + break; + + case 'cn': + addCSSClass($('rdetail_viewcn_link'), 'rdetail_extras_selected'); + unHideMe($('rdetail_cn_browse_div')); + rdetailShowCNBrowse(defaultCN, getLocation(), null, true); + break; + + } +} + +function rdetailVolumeDetails(args) { + var row = $(args.rowid); + var tbody = row.parentNode; + cpdBuild( tbody, row, record, args.cn, args.org, args.depth, args.copy_location ); + return; +} + +function rdetailBuildCNList() { + + var select = $('cn_browse_selector'); + var index = 0; + var arr = []; + for( var cn in callnumberCache ) arr.push( cn ); + arr.sort(); + + if( arr.length == 0 ) { + hideMe($('rdetail_cn_browse_select_div')); + return; + } + + for( var i in arr ) { + var cn = arr[i]; + var opt = new Option(cn); + select.options[index++] = opt; + } + select.onchange = rdetailGatherCN; +} + +function rdetailGatherCN() { + var cn = getSelectorVal($('cn_browse_selector')); + rdetailShowCNBrowse( cn, getLocation(), getDepth(), true ); + setSelector( $('cn_browse_selector'), cn ); +} + + +function rdetailShowCNBrowse( cn, loc, depth, fromOnclick ) { + + if(!cn) { + unHideMe($('cn_browse_none')); + hideMe($('rdetail_cn_browse_select_div')); + return; + } + + unHideMe($('rdetail_cn_browse_select_div')); + rdetailBuildCNList(); + setSelector( $('cn_browse_selector'), cn ); + hideMe($('rdetail_copy_info_div')); + hideMe($('rdetail_reviews_div')); + hideMe($('rdetail_toc_div')); + hideMe($('rdetail_marc_div')); + unHideMe($('rdetail_cn_browse_div')); + unHideMe($('cn_browse')); + if( !rdetailLocalOnly && ! fromOnclick ) depth = findOrgDepth(globalOrgTree); + cnBrowseGo(cn, loc, depth); +} + +function rdetailhandleAC(data) { + + if( data.reviews.html ) { + $('rdetail_review_container').innerHTML = data.reviews.html; + unHideMe($('rdetail_reviews_link')); + } + + if( data.toc.html ) { + $('rdetail_toc_div').innerHTML = data.toc.html; + unHideMe($('rdetail_toc_link')); + } else if( record.toc() ) { + $('rdetail_toc_div').innerHTML = record.toc(); + unHideMe($('rdetail_toc_link')); + } + + if( data.excerpt.html ) { + $('rdetail_excerpt_div').innerHTML = data.excerpt.html; + unHideMe($('rdetail_excerpt_link')); + } + + if( data.anotes.html ) { + $('rdetail_anotes_div').innerHTML = data.anotes.html; + unHideMe($('rdetail_anotes_link')); + } + + if( record.performer_notes() ) { + $('rdetail_performer_notes_div').innerHTML = record.performer_notes(); + unHideMe($('rdetail_performer_notes_link')); + } +} + +function rdetailShowReviews(r) { + hideMe($('rdetail_extras_loading')); + var res = r.getResultObject(); + var par = $('rdetail_reviews_div'); + var template = par.removeChild($('rdetail_review_template')); + if( res && res.length > 0 ) { + unHideMe($('rdetail_reviews_link')); + for( var i = 0; i != res.length; i++ ) { + var rev = res[i]; + if( rev.text && rev.info ) { + var node = template.cloneNode(true); + $n(node, 'review_header').appendChild(text(rev.info)); + $n(node, 'review_text').appendChild(text(rev.text)); + par.appendChild(node); + } + } + } +} + + +function rdetailShowTOC(r) { + hideMe($('rdetail_extras_loading')); + var resp = r.getResultObject(); + if(resp) { + unHideMe($('rdetail_toc_link')); + $('rdetail_toc_div').innerHTML = resp; + } +} + +function rdetailBuildInfoRows() { + var req; + var method = FETCH_COPY_COUNTS_SUMMARY; + if (rdetailShowCopyLocation) + method = FETCH_COPY_LOCATION_COUNTS_SUMMARY; + + if( rdetailShowLocal ) + req = new Request(method, record.doc_id(), getLocation(), getDepth()) + else + req = new Request(method, record.doc_id()); + req.callback(_rdetailBuildInfoRows); + req.send(); +} + +function _rdetailRows(node) { + + if( rdetailShowLocal && getLocation() != globalOrgTree.id() ) { + var loc = findOrgUnit(getLocation()); + if( node ) { + if( !orgIsMine(node, loc) ) return; + } else { + for( var i = 0; i < globalOrgTree.children().length; i++ ) { + var org = findOrgUnit(globalOrgTree.children()[i]); + if( orgIsMine(org, loc) ) { + node = org; + break; + } + } + } + } + + if(!node && findOrgType(globalOrgTree.ou_type()).can_have_vols()) + node = globalOrgTree; + + + /* don't show hidden orgs */ + + if(node) { + + if(!isXUL() && !isTrue(node.opac_visible())) return; + + var row = copyRow.cloneNode(true); + row.id = "cp_info_" + node.id(); + + var libtd = findNodeByName( row, config.names.rdetail.lib_cell ); + var cntd = findNodeByName( row, config.names.rdetail.cn_cell ); + var cpctd = findNodeByName( row, config.names.rdetail.cp_count_cell ); + var actions = $n(row, 'rdetail_actions_cell'); + + var p = libtd.getElementsByTagName('a')[0]; + libtd.insertBefore(text(node.name()), p); + libtd.setAttribute("style", "padding-left: " + ((findOrgDepth(node) - 1) * 9) + "px;"); + + if(!findOrgType(node.ou_type()).can_have_vols()) { + + row.removeChild(cntd); + row.removeChild(cpctd); + row.removeChild(actions); + row.setAttribute('novols', '1'); + + libtd.setAttribute("colspan", numStatuses + 3 ); + libtd.colSpan = numStatuses + 3; + addCSSClass(row, 'copy_info_region_row'); + } + + copyRowParent.appendChild(row); + + } else { node = globalOrgTree; } + + for( var c in node.children() ) + _rdetailRows(node.children()[c]); +} + +function rdetailCNPrint(orgid, cn) { + var div = cpdBuildPrintWindow( record, orgid); + var template = div.removeChild($n(div, 'cnrow')); + var rowNode = $("cp_info_" + orgid); + cpdStylePopupWindow(div); + openWindow(div.innerHTML); +} + +var localCNFound = false; +var ctr = 0; +function _rdetailBuildInfoRows(r) { + + if (rdetailShowCopyLocation) + unHideMe( $n( $('rdetail_copy_info_table'), 'rdetail_copylocation_header' ) ); + + removeChildren(copyRowParent); + + _rdetailRows(); + + var summary = r.getResultObject(); + if(!summary) return; + + var found = false; + for( var i = 0; i < summary.length; i++ ) { + + var arr = summary[i]; + globalCNCache[arr[1]] = 1; + var thisOrg = findOrgUnit(arr[0]); + var rowNode = $("cp_info_" + thisOrg.id()); + if(!rowNode) continue; + + if(rowNode.getAttribute("used")) { + + if( rowNode.nextSibling ) { + sib = rowNode.nextSibling; + o ='cp_info_'+thisOrg.id()+'_'; + /* push the new row on as the last row for this org unit */ + while( sib && sib.id.match(o) ) { + sib = sib.nextSibling; + } + if(sib) + rowNode = copyRowParent.insertBefore(copyRow.cloneNode(true), sib); + else + rowNode = copyRowParent.appendChild(copyRow.cloneNode(true)); + } else { + rowNode = copyRowParent.appendChild(copyRow.cloneNode(true)); + } + + var n = findNodeByName( rowNode, config.names.rdetail.lib_cell ); + n.appendChild(text(thisOrg.name())); + n.setAttribute("style", "padding-left: " + ((findOrgDepth(thisOrg) - 1) * 9) + "px;"); + rowNode.id = "cp_info_" + thisOrg.id() + '_' + (++ctr); + + } else { + rowNode.setAttribute("used", "1"); + } + + var cpc_temp = rowNode.removeChild( + findNodeByName(rowNode, config.names.rdetail.cp_count_cell)); + + var statuses = arr[2]; + var cl = ''; + if (rdetailShowCopyLocation) { + cl = arr[2]; + statuses = arr[3]; + } + + + rdetailApplyStatuses(rowNode, cpc_temp, statuses); + + var isLocal = false; + if( orgIsMine( findOrgUnit(getLocation()), thisOrg ) ) { + found = true; + isLocal = true; + if(!localCNFound) { + localCNFound = true; + defaultCN = arr[1]; + } + } + + //if(isLocal) unHideMe(rowNode); + unHideMe(rowNode); + + rdetailSetPath( thisOrg, isLocal ); + rdetailBuildBrowseInfo( rowNode, arr[1], isLocal, thisOrg, cl ); + + if( i == summary.length - 1 && !defaultCN) defaultCN = arr[1]; + } + + if(!found) unHideMe(G.ui.rdetail.cp_info_none); +} + +function rdetailBuildBrowseInfo(row, cn, local, orgNode, cl) { + + if(local) { + var cache = callnumberCache[cn]; + if( cache ) cache.count++; + else callnumberCache[cn] = { count : 1 }; + } + + var depth = getDepth(); + if( !local ) depth = findOrgDepth(globalOrgTree); + + $n(row, 'rdetail_callnumber_cell').appendChild(text(cn)); + + if (rdetailShowCopyLocation) { + var cl_cell = $n(row, 'rdetail_copylocation_cell'); + cl_cell.appendChild(text(cl)); + unHideMe(cl_cell); + } + + _debug('setting action clicks for cn ' + cn); + + var dHref = 'javascript:rdetailVolumeDetails('+ + '{copy_location : "'+cl+'", rowid : "'+row.id+'", cn :"'+cn+'", depth:"'+depth+'", org:"'+orgNode.id()+'", local: '+local+'});'; + + var bHref = 'javascript:rdetailShowCNBrowse("' + cn + '", '+orgNode.id()+', "'+depth+'");'; + + unHideMe( $n(row, 'details') ) + $n(row, 'details').setAttribute('href', dHref); + unHideMe( $n(row, 'browse') ) + $n(row, 'browse').setAttribute('href', bHref); + + if(isXUL()) { + unHideMe($n(row, 'hold_div')); + $n(row, 'hold').onclick = function() { + var req = new Request(FETCH_VOLUME_BY_INFO, cn, record.doc_id(), orgNode.id()); + req.callback( + function(r) { + var vol = r.getResultObject(); + holdsDrawEditor({type: 'V', volumeObject : vol}); + } + ); + req.send(); + }; + } +} + +// sets the path to org as 'active' and displays the path if it's local +function rdetailSetPath(org, local) { + if( findOrgDepth(org) == 0 ) return; + var row = $("cp_info_" + org.id()); + row.setAttribute("hasinfo", "1"); + unHideMe(row); + rdetailSetPath(findOrgUnit(org.parent_ou()), local); +} + +//Append all the statuses for a given summary to the +//copy summary table +function rdetailApplyStatuses( row, template, statuses ) { + for( var j in _statusPositions ) { + var stat = _statusPositions[j]; + var val = statuses[stat.id()]; + var nn = template.cloneNode(true); + if(val) nn.appendChild(text(val)); + else nn.appendChild(text(0)); + row.appendChild(nn); + } +} + +//Add one td (creating a new column) to the copy summary +//table for each opac_visible copy status +function rdetailBuildStatusColumns() { + + rdetailGrabCopyStatuses(); + var parent = statusRow; + var template = parent.removeChild(G.ui.rdetail.cp_status); + + var i = 0; + for( i = 0; i < cp_statuses.length; i++ ) { + + var c = cp_statuses[i]; + if( c && isTrue(c.opac_visible()) ) { + var name = c.name(); + _statusPositions[i] = c; + var node = template.cloneNode(true); + var data = findNodeByName( node, config.names.rdetail.cp_status); + + data.appendChild(text(name)); + parent.appendChild(node); + } + } + + numStatuses = 0; + for(x in _statusPositions) numStatuses++; +} + +function rdetailGrabCopyStatuses() { + if(cp_statuses) return cp_statuses; + var req = new Request(FETCH_COPY_STATUSES); + req.send(true); + cp_statuses = req.result(); + cp_statuses = cp_statuses.sort(_rdetailSortStatuses); +} + +function _rdetailSortStatuses(a, b) { + return parseInt(a.id()) - parseInt(b.id()); +} + +/** + * XXX Need to adopt a more typical approach to showing loading status + */ +function rdetailCheckForGBPreview() { + + if (!googleBookPreview) return; + var GBPp = document.createElement('p'); + GBPp.appendChild( document.createTextNode('Loading... ' ) ); + GBPp.id = 'loading'; + $('rdetail_preview_div').appendChild(GBPp); + searchForGBPreview( cleanISBN(record.isbn()) ); + +} + +/** + * + * @param {DOM object} query The form element containing the + * input parameters "isbns" + */ +function searchForGBPreview( isbn ) { + + // Delete any previous Google Booksearch JSON queries. + var GBPJsonScript = document.getElementById("GBPJsonScript"); + if (GBPJsonScript) { + GBPJsonScript.parentNode.removeChild(GBPJsonScript); + } + + // Add a script element with the src as the user's Google Booksearch query. + // JSON output is specified by including the alt=json-in-script argument + // and the callback function is also specified as a URI argument. + var GBPScriptElement = document.createElement("script"); + + GBPScriptElement.setAttribute("id", "GBPJsonScript"); + GBPScriptElement.setAttribute("src", + "http://books.google.com/books?bibkeys=" + + isbn + "&jscmd=viewapi&callback=GBPreviewCallback"); + GBPScriptElement.setAttribute("type", "text/javascript"); + + // make the request to Google booksearch + document.documentElement.firstChild.appendChild(GBPScriptElement); +} + +/** + * This function is the call-back function for the JSON scripts which + * executes a Google book search response. + * + * XXX I18N of text needed + * + * @param {JSON} booksInfo is the JSON object pulled from the Google books service. + */ +function GBPreviewCallback(GBPBookInfo) { + // Clear any old data to prepare to display the Loading... message. + var GBPreviewDiv = document.getElementById("rdetail_preview_div"); + var GBPBook; + + for ( i in GBPBookInfo ) { + GBPBook = GBPBookInfo[i]; + } + + if ( !GBPBook ) { + return; + } + + if ( GBPBook.preview != "noview" ) { + if ( GBPBook.preview == 'full' ) { + setText( $('rdetail_preview_link'), 'Full Text' ); + $('rdetail_preview_link_a').title = 'See the full text of this book.'; + } + + // Add a button below the book cover image to load the preview. + GBPBadge = document.createElement( 'img' ); + GBPBadge.src = 'http://books.google.com/intl/en/googlebooks/images/gbs_preview_button1.gif'; + GBPBadge.title = 'Show a preview of this book from Google Book Search'; + GBPBadge.style.border = 0; + GBPBadgelink = document.createElement( 'a' ); + GBPBadgelink.href = 'javascript:rdetailShowExtra("preview");'; + GBPBadgelink.appendChild( GBPBadge ); + $('rdetail_image_cell').appendChild( GBPBadgelink ); + + unHideMe( $('rdetail_preview_link' ) ); + $('rdetail_preview_div').style.height = 600; + } +} + +/** + * This is called when the user clicks on the 'Preview' link. We assume + * a preview is available from Google if this link was made visible. + * + * XXX I18N of Google Book Preview language attribute needed + */ +function rdetailDisplayGBPreview() { + GBPreviewPane = $('rdetail_preview_div'); + if ( GBPreviewPane.getAttribute('loaded') == null || + GBPreviewPane.getAttribute('loaded') == "false" ) { + google.load("books", "0", {"callback" : rdetailGBPViewerLoadCallback, "language": "en"} ); + GBPreviewPane.setAttribute('loaded', 'true'); + } +} + +function rdetailGBPViewerLoadCallback() { + var GBPViewer = new google.books.DefaultViewer(document.getElementById('rdetail_preview_div')); + GBPViewer.load('ISBN:' + cleanISBN(record.isbn()) ); + +} diff --git a/web/opac/skin/default/xml/rdetail/rdetail_extras.xml b/web/opac/skin/default/xml/rdetail/rdetail_extras.xml new file mode 100644 index 0000000000..5fb679bc91 --- /dev/null +++ b/web/opac/skin/default/xml/rdetail/rdetail_extras.xml @@ -0,0 +1,121 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
&common.loading;
+ + +
+
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
+
+ +
+ +
+ &rdetail.extras.call.null; +
+ +
+ &rdetail.extras.call.local; + +
+ + +
+ + + +
+