pennmarc 1.0.7 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/pennmarc/enriched_marc.rb +11 -0
- data/lib/pennmarc/helpers/classification.rb +95 -0
- data/lib/pennmarc/helpers/link.rb +2 -2
- data/lib/pennmarc/mappers.rb +10 -0
- data/lib/pennmarc/mappings/dewey_classification.yml +11 -0
- data/lib/pennmarc/mappings/loc_classification.yml +22 -0
- data/lib/pennmarc/version.rb +1 -1
- data/spec/lib/pennmarc/helpers/classification_spec.rb +41 -0
- data/spec/lib/pennmarc/helpers/link_spec.rb +4 -4
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 652039b781e2ce7442f628ca722f4fda59207d1d8171bfd2fad84d2c67f3c06f
|
4
|
+
data.tar.gz: 166bbf8498f673b36373671db47031ef8a2f4d5496ed1fddeee89718bd23e09c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 68df667344adaff013da3eab5417bdd44748726a113190d20c44cc1cf4d061269619265e3de1edc9c7c767ffff5a4548a9fcb3ed2039b28a2608ec62a6e024d1
|
7
|
+
data.tar.gz: 8df6d32dbc84ff3851e4b35576e24c96c42b536330ded1f0f1678de3d1aa0729547a71b0c6ccea15e7c949ee15e068d1c0f19b18a6b414167cb736effa2b01dd
|
@@ -32,5 +32,16 @@ module PennMARC
|
|
32
32
|
# a subfield code NOT used by the MARC 21 spec for 852 holdings records.
|
33
33
|
# we add this subfield during preprocessing to store boundwith record IDs.
|
34
34
|
SUB_BOUND_WITH_ID = 'y'
|
35
|
+
|
36
|
+
# MARC enrichment originating from Alma Api
|
37
|
+
# @see https://developers.exlibrisgroup.com/alma/apis/docs/bibs/R0VUIC9hbG1hd3MvdjEvYmlicy97bW1zX2lkfQ==/ Alma docs
|
38
|
+
module AlmaApi
|
39
|
+
TAG_PHYSICAL_INVENTORY = 'AVA'
|
40
|
+
TAG_DIGITAL_INVENTORY = 'AVA'
|
41
|
+
TAG_ELECTRONIC_INVENTORY = 'AVE'
|
42
|
+
|
43
|
+
SUB_PHYSICAL_CALL_NUMBER = 'd'
|
44
|
+
SUB_PHYSICAL_CALL_NUMBER_TYPE = 'k'
|
45
|
+
end
|
35
46
|
end
|
36
47
|
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PennMARC
|
4
|
+
# Generates library of congress and dewey classifications using call number data.
|
5
|
+
class Classification < Helper
|
6
|
+
# Subfield value that identifies Library of Congress call number
|
7
|
+
LOC_CALL_NUMBER_TYPE = '0'
|
8
|
+
|
9
|
+
# Subfield value that identifies Dewey call number
|
10
|
+
DEWEY_CALL_NUMBER_TYPE = '1'
|
11
|
+
|
12
|
+
# Hash that maps call number type to the appropriate mapper
|
13
|
+
CLASSIFICATION_MAPS = {
|
14
|
+
LOC_CALL_NUMBER_TYPE => Mappers.loc_classification,
|
15
|
+
DEWEY_CALL_NUMBER_TYPE => Mappers.dewey_classification
|
16
|
+
}.freeze
|
17
|
+
|
18
|
+
# Enriched MARC tags that hold classification data
|
19
|
+
TAGS = [EnrichedMarc::TAG_ITEM, EnrichedMarc::AlmaApi::TAG_PHYSICAL_INVENTORY].freeze
|
20
|
+
|
21
|
+
class << self
|
22
|
+
# Parse classification values for faceting. We retrieve classification values from enriched MARC fields 'itm' or
|
23
|
+
# 'AVA' originating respectively from the Alma publishing process or from the Alma Api. We return the
|
24
|
+
# highest level LOC or Dewey classifications from each available call number, joining the class code with
|
25
|
+
# its title in a single string. See {PennMARC::EnrichedMarc} and {PennMARC::EnrichedMarc::AlmaApi} for more
|
26
|
+
# information on the enriched MARC fields.
|
27
|
+
# @see https://developers.exlibrisgroup.com/alma/apis/docs/bibs/R0VUIC9hbG1hd3MvdjEvYmlicy97bW1zX2lkfQ==/ AVA docs
|
28
|
+
# @param [MARC::Record] record
|
29
|
+
# @return [Array<String>] array of classifications
|
30
|
+
def facet(record)
|
31
|
+
record.fields(TAGS).flat_map do |field|
|
32
|
+
call_number_type = subfield_values(field, call_number_type_sf(field))&.first
|
33
|
+
call_numbers = subfield_values(field, call_number_sf(field))
|
34
|
+
|
35
|
+
call_numbers.filter_map do |call_number|
|
36
|
+
class_code = call_number[0]
|
37
|
+
title = translate_classification(class_code, call_number_type)
|
38
|
+
next if title.blank?
|
39
|
+
|
40
|
+
format_facet(class_code, call_number_type, title)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
# Retrieve subfield code that stores the call number on enriched marc field
|
48
|
+
# @param [MARC::DataField] field
|
49
|
+
# @return [String]
|
50
|
+
def call_number_sf(field)
|
51
|
+
return EnrichedMarc::SUB_ITEM_CALL_NUMBER if field.tag == EnrichedMarc::TAG_ITEM
|
52
|
+
|
53
|
+
EnrichedMarc::AlmaApi::SUB_PHYSICAL_CALL_NUMBER
|
54
|
+
end
|
55
|
+
|
56
|
+
# Retrieve subfield code that stores call number type on enriched marc field
|
57
|
+
# @param [MARC::DataField] field
|
58
|
+
# @return [String]
|
59
|
+
def call_number_type_sf(field)
|
60
|
+
return EnrichedMarc::SUB_ITEM_CALL_NUMBER_TYPE if field.tag == EnrichedMarc::TAG_ITEM
|
61
|
+
|
62
|
+
EnrichedMarc::AlmaApi::SUB_PHYSICAL_CALL_NUMBER_TYPE
|
63
|
+
end
|
64
|
+
|
65
|
+
# retrieve title of classification based on single char classification code and call number type
|
66
|
+
# @param[String] class_code classification code
|
67
|
+
# @param[String] call_number_type value from call number type subfield
|
68
|
+
# @return [String, NilClass]
|
69
|
+
def translate_classification(class_code, call_number_type)
|
70
|
+
map = CLASSIFICATION_MAPS[call_number_type]
|
71
|
+
|
72
|
+
return if map.blank?
|
73
|
+
|
74
|
+
translate_relator(class_code, map)
|
75
|
+
end
|
76
|
+
|
77
|
+
# format classification facet by joining single character classification code with its corresponding title.
|
78
|
+
# Our Dewey mapping codes are single digit, so we must concatenate '00' to the class code to accurately reflect
|
79
|
+
# Dewey class codes.
|
80
|
+
# @return [String]
|
81
|
+
def format_facet(class_code, call_number_type, title)
|
82
|
+
return [class_code, title].join(' - ') if loc_call_number_type?(call_number_type)
|
83
|
+
|
84
|
+
["#{class_code}00", title].join(' - ')
|
85
|
+
end
|
86
|
+
|
87
|
+
# Determine whether call number type is library of congress
|
88
|
+
# @param [String] call_number_type value from call number type subfield
|
89
|
+
# @return [Boolean]
|
90
|
+
def loc_call_number_type?(call_number_type)
|
91
|
+
call_number_type == '0'
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -13,7 +13,7 @@ module PennMARC
|
|
13
13
|
# Full text links from MARC 856 fields.
|
14
14
|
# @param [MARC::Record] record
|
15
15
|
# @return [Array] array of hashes
|
16
|
-
def full_text(record
|
16
|
+
def full_text(record)
|
17
17
|
indicator2_options = %w[0 1]
|
18
18
|
links_from_record(record, indicator2_options)
|
19
19
|
end
|
@@ -21,7 +21,7 @@ module PennMARC
|
|
21
21
|
# Web text links from MARC 856 fields.
|
22
22
|
# @param [MARC::Record] record
|
23
23
|
# @return [Array] array of hashes
|
24
|
-
def web(record
|
24
|
+
def web(record)
|
25
25
|
indicator2_options = ['2', ' ', '']
|
26
26
|
links_from_record(record, indicator2_options)
|
27
27
|
end
|
data/lib/pennmarc/mappers.rb
CHANGED
@@ -23,6 +23,16 @@ module PennMARC
|
|
23
23
|
@relator ||= load_map('relator.yml')
|
24
24
|
end
|
25
25
|
|
26
|
+
# @return [Hash]
|
27
|
+
def loc_classification
|
28
|
+
@loc_classification ||= load_map('loc_classification.yml')
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [Hash]
|
32
|
+
def dewey_classification
|
33
|
+
@dewey_classification ||= load_map('dewey_classification.yml')
|
34
|
+
end
|
35
|
+
|
26
36
|
# @param [String] filename of mapping file in config directory, with file extension
|
27
37
|
# @return [Hash] mapping as hash
|
28
38
|
def load_map(filename)
|
@@ -0,0 +1,22 @@
|
|
1
|
+
---
|
2
|
+
A: General Works
|
3
|
+
B: Philosophy, Psychology, Religion
|
4
|
+
C: 'History: Auxiliary Sciences'
|
5
|
+
D: 'History: General & European'
|
6
|
+
E: 'History: United States'
|
7
|
+
F: 'History: Western Hemisphere'
|
8
|
+
G: Geography, Anthropology, Recreation
|
9
|
+
H: Social Science, Economics, Sociology
|
10
|
+
J: Political Science
|
11
|
+
K: Law
|
12
|
+
L: Education
|
13
|
+
M: Music
|
14
|
+
N: Fine Arts
|
15
|
+
P: Literature & Languages
|
16
|
+
Q: Science
|
17
|
+
R: Medicine
|
18
|
+
S: Agriculture
|
19
|
+
T: Technology
|
20
|
+
U: Military Science
|
21
|
+
V: Naval Science
|
22
|
+
Z: Bibliography & Library Science
|
data/lib/pennmarc/version.rb
CHANGED
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
describe 'PennMARC::Classification' do
|
4
|
+
include MarcSpecHelpers
|
5
|
+
|
6
|
+
let(:helper) { PennMARC::Classification }
|
7
|
+
let(:record) do
|
8
|
+
marc_record fields: [marc_field(tag: tag,
|
9
|
+
subfields: { call_number_type_sf => '0', call_number_sf => 'TA683 .B3 1909b' }),
|
10
|
+
marc_field(tag: tag,
|
11
|
+
subfields: { call_number_type_sf => '0', call_number_sf => 'QL756 .S643' }),
|
12
|
+
marc_field(tag: tag,
|
13
|
+
subfields: { call_number_type_sf => '1', call_number_sf => '691.3 B2141' }),
|
14
|
+
marc_field(tag: tag,
|
15
|
+
subfields: { call_number_type_sf => '1', call_number_sf => '378.748 POS1952.29' })]
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '.facet' do
|
19
|
+
context 'with enrichment via the Alma publishing process' do
|
20
|
+
let(:tag) { PennMARC::EnrichedMarc::TAG_ITEM }
|
21
|
+
let(:call_number_type_sf) { PennMARC::EnrichedMarc::SUB_ITEM_CALL_NUMBER_TYPE }
|
22
|
+
let(:call_number_sf) { PennMARC::EnrichedMarc::SUB_ITEM_CALL_NUMBER }
|
23
|
+
|
24
|
+
it 'returns expected values' do
|
25
|
+
expect(helper.facet(record)).to contain_exactly('T - Technology', '600 - Technology',
|
26
|
+
'300 - Social sciences', 'Q - Science')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'with enrichment with availability info via Alma Api' do
|
31
|
+
let(:tag) { PennMARC::EnrichedMarc::AlmaApi::TAG_PHYSICAL_INVENTORY }
|
32
|
+
let(:call_number_type_sf) { PennMARC::EnrichedMarc::AlmaApi::SUB_PHYSICAL_CALL_NUMBER_TYPE }
|
33
|
+
let(:call_number_sf) { PennMARC::EnrichedMarc::AlmaApi::SUB_PHYSICAL_CALL_NUMBER }
|
34
|
+
|
35
|
+
it 'returns expected values' do
|
36
|
+
expect(helper.facet(record)).to contain_exactly('T - Technology', '600 - Technology',
|
37
|
+
'300 - Social sciences', 'Q - Science')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -15,8 +15,8 @@ describe 'PennMARC::Link' do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
it 'returns full text link text and url' do
|
18
|
-
expect(helper.full_text(record
|
19
|
-
|
18
|
+
expect(helper.full_text(record)).to contain_exactly({ link_text: 'Materials specified Public note',
|
19
|
+
link_url: 'https://www.test-uri.com/' })
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -30,8 +30,8 @@ describe 'PennMARC::Link' do
|
|
30
30
|
end
|
31
31
|
|
32
32
|
it 'returns web link text and url' do
|
33
|
-
expect(helper.web(record
|
34
|
-
|
33
|
+
expect(helper.web(record)).to contain_exactly({ link_text: 'Materials specified Public note',
|
34
|
+
link_url: 'https://www.test-uri.com/' })
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pennmarc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Kanning
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2023-12-
|
13
|
+
date: 2023-12-08 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activesupport
|
@@ -91,6 +91,7 @@ files:
|
|
91
91
|
- lib/pennmarc/heading_control.rb
|
92
92
|
- lib/pennmarc/helpers/access.rb
|
93
93
|
- lib/pennmarc/helpers/citation.rb
|
94
|
+
- lib/pennmarc/helpers/classification.rb
|
94
95
|
- lib/pennmarc/helpers/creator.rb
|
95
96
|
- lib/pennmarc/helpers/database.rb
|
96
97
|
- lib/pennmarc/helpers/date.rb
|
@@ -109,8 +110,10 @@ files:
|
|
109
110
|
- lib/pennmarc/helpers/subject.rb
|
110
111
|
- lib/pennmarc/helpers/title.rb
|
111
112
|
- lib/pennmarc/mappers.rb
|
113
|
+
- lib/pennmarc/mappings/dewey_classification.yml
|
112
114
|
- lib/pennmarc/mappings/iso639-2-languages.yml
|
113
115
|
- lib/pennmarc/mappings/iso639-3-languages.yml
|
116
|
+
- lib/pennmarc/mappings/loc_classification.yml
|
114
117
|
- lib/pennmarc/mappings/locations.yml
|
115
118
|
- lib/pennmarc/mappings/relator.yml
|
116
119
|
- lib/pennmarc/parser.rb
|
@@ -120,6 +123,7 @@ files:
|
|
120
123
|
- spec/fixtures/marcxml/test.xml
|
121
124
|
- spec/lib/pennmarc/helpers/access_spec.rb
|
122
125
|
- spec/lib/pennmarc/helpers/citation_spec.rb
|
126
|
+
- spec/lib/pennmarc/helpers/classification_spec.rb
|
123
127
|
- spec/lib/pennmarc/helpers/creator_spec.rb
|
124
128
|
- spec/lib/pennmarc/helpers/database_spec.rb
|
125
129
|
- spec/lib/pennmarc/helpers/date_spec.rb
|