export const HOLDINGS_XPATH =
'/holdings:holdings/holdings:counts/holdings:count';
+interface EResourceUrl {
+ href: string;
+ note: string;
+ label: string;
+}
export class BibRecordSummary {
id: number; // == record.id() for convenience
bibCallNumber: string;
net: NetService;
displayHighlights: {[name: string]: string | string[]} = {};
+ eResourceUrls: EResourceUrl[] = null;
constructor(record: IdlObject, orgId: number, orgDepth: number) {
this.id = Number(record.id());
});
}
+ // True if this record has any E-Resource URLs.
+ // this.eResourceUrls starts null so we can detect whether a
+ // retrieval attempt has been made.
+ hasEResourceUrls(): boolean {
+ return this.eResourceUrls && this.eResourceUrls.length > 0;
+ }
+
+ getEResourceUrls(): Promise<EResourceUrl[]> {
+ if (this.hasEResourceUrls()) {
+ return Promise.resolve(this.eResourceUrls);
+ }
+
+ return this.net.request(
+ 'open-ils.search',
+ 'open-ils.search.biblio.record.resource_urls.retrieve',
+ this.id
+ ).toPromise().then(urlInfo => this.eResourceUrls = urlInfo.urls);
+ }
+
// Get -> Set -> Return bib hold count
getHoldCount(): Promise<number> {
this.summary =
this.staffCat.currentDetailRecordSummary = summary;
this.bib.fleshBibUsers([summary.record]);
+ this.summary.getEResourceUrls();
});
}
<div class="flex-1">{{summary.record.edit_date() | date:'short'}}</div>
</div>
</li>
+ <ng-container *ngIf="expand && summary.hasEResourceUrls()">
+ <li class="list-group-item" *ngFor="let url of summary.eResourceUrls">
+ <div class="d-flex">
+ <div class="flex-1 font-weight-bold" i18n>
+ Electronic Resource:
+ </div>
+ <div class="flex-5">
+ <a href="{{url.href}}">{{url.label}}</a>
+ </div>
+ <div class="flex-4">{{url.note}}</div>
+ </div>
+ </li>
+ </ng-container>
</ul>
</div>
</div><!-- col -->
package OpenILS::Application::AppUtils;
use strict; use warnings;
+use MARC::Record;
+use MARC::File::XML (BinaryEncoding => 'utf8', RecordFormat => 'USMARC');
use OpenILS::Application;
use base qw/OpenILS::Application/;
use OpenSRF::Utils::Cache;
# Pile of utilty methods used accross applications.
# ---------------------------------------------------------------------------
my $cache_client = "OpenSRF::Utils::Cache";
-
+my $MARC_NAMESPACE = 'http://www.loc.gov/MARC21/slim';
# ---------------------------------------------------------------------------
# on sucess, returns the created session, on failure throws ERROR exception
}
+# generate a MARC XML document from a MARC XML string
+sub marc_xml_to_doc {
+ my ($class, $xml) = @_;
+ my $marc_doc = XML::LibXML->new->parse_string($xml);
+ $marc_doc->documentElement->setNamespace($MARC_NAMESPACE, 'marc', 1);
+ $marc_doc->documentElement->setNamespace($MARC_NAMESPACE);
+ return $marc_doc;
+}
+
+
+
1;
use OpenILS::Const qw/:const/;
use OpenILS::Event;
my $U = 'OpenILS::Application::AppUtils';
-my $MARC_NAMESPACE = 'http://www.loc.gov/MARC21/slim';
-
# generate a MARC XML document from a MARC XML string
sub marc_xml_to_doc {
my $xml = shift;
- my $marc_doc = XML::LibXML->new->parse_string($xml);
- $marc_doc->documentElement->setNamespace($MARC_NAMESPACE, 'marc', 1);
- $marc_doc->documentElement->setNamespace($MARC_NAMESPACE);
- return $marc_doc;
+ return $U->marc_xml_to_doc($xml);
}
-
__PACKAGE__->register_method(
method => 'import_authority_record',
api_name => 'open-ils.cat.authority.record.import',
return $query;
}
+__PACKAGE__->register_method(
+ method => 'record_urls',
+ api_name => 'open-ils.search.biblio.record.resource_urls.retrieve',
+ argc => 1,
+ stream => 1,
+ signature => {
+ desc => q/Returns bib record 856 URL content./,
+ params => [
+ {desc => 'Record ID or Array of Record IDs', type => 'number or array'}
+ ],
+ return => {
+ desc => 'Stream of URL objects, one collection object per record',
+ type => 'object'
+ }
+ }
+);
+
+sub record_urls {
+ my ($self, $client, $record_ids) = @_;
+
+ $record_ids = [$record_ids] unless ref $record_ids eq 'ARRAY';
+
+ my $e = new_editor();
+
+ for my $record_id (@$record_ids) {
+ my $bib = $e->retrieve_biblio_record_entry($record_id)
+ or return $e->event;
+
+ my $marc_doc = $U->marc_xml_to_doc($bib->marc);
+
+ # Logic copied from TPAC misc_utils.tts
+ my @urls;
+
+ for my $node ($marc_doc->findnodes(
+ '//*[@tag="856" and @ind1="4" and (@ind2="0" or @ind2="1")]')) {
+
+ # asset.uri's
+ next if $node->findnodes('./*[@code="9" or @code="w" or @code="n"]');
+
+ my $url = {};
+ my ($label) = $node->findnodes('./*[@code="y"]');
+ my ($notes) = $node->findnodes('./*[@code="z" or @code="3"]');
+
+ my $first = 1;
+ for my $href_node ($node->findnodes('./*[@code="u"]')) {
+ next unless $href_node;
+
+ # it's possible for multiple $u's to exist within 1 856 tag.
+ # in that case, honor the label/notes data for the first $u, but
+ # leave any subsequent $u's as unadorned href's.
+ # use href/link/note keys to be consistent with args.uri's
+
+ my $href = $href_node->textContent;
+ push(@urls, {
+ href => $href,
+ label => ($first && $label) ? $label->textContent : $href,
+ note => ($first && $notes) ? $notes->textContent : ''
+ });
+ $first = 0;
+ }
+ }
+
+ $client->respond({id => $record_id, urls => \@urls});
+ }
+
+ return undef;
+}
1;