pennmarc 1.2.5 → 1.2.7
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/Gemfile +1 -0
- data/Gemfile.lock +2 -0
- data/lib/pennmarc/helpers/classification.rb +36 -7
- data/lib/pennmarc/mappings/locations.yml +10 -2
- data/lib/pennmarc/version.rb +1 -1
- data/pennmarc.gemspec +1 -0
- data/spec/lib/pennmarc/helpers/classification_spec.rb +80 -0
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 920cef15f1cac246074afedbe31a0f456ee81d9e9bcbb04c0dde024901d925db
|
4
|
+
data.tar.gz: edf42bff8a460373147e52e4cc3bf1c277655486635952ebf6604bc83fab5912
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 614f6a26980656a8030bdaf28b0c901a9d5a841e0bad65b1e0455e9f09b3071e6c1f379ea3a54c4267c66403efdef3de0e7be4862c9e05c84d3d1f228921ccd8
|
7
|
+
data.tar.gz: 6b85c2040e4b9dbb0bb95b5e5d0914ada840399338246b54ee94b338ebb7c7c58dd32a22d9ae425337b6ce7074c03124e826a7b4b117bc40cc3d05405cfe2e29
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -13,6 +13,7 @@ GEM
|
|
13
13
|
i18n (1.13.0)
|
14
14
|
concurrent-ruby (~> 1.0)
|
15
15
|
json (2.6.3)
|
16
|
+
lcsort (0.9.1)
|
16
17
|
library_stdnums (1.6.0)
|
17
18
|
marc (1.2.0)
|
18
19
|
rexml
|
@@ -111,6 +112,7 @@ PLATFORMS
|
|
111
112
|
|
112
113
|
DEPENDENCIES
|
113
114
|
activesupport (~> 7)
|
115
|
+
lcsort
|
114
116
|
library_stdnums (~> 1.6)
|
115
117
|
marc (~> 1.2)
|
116
118
|
nokogiri (~> 1.15)
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'lcsort'
|
4
|
+
|
3
5
|
module PennMARC
|
4
6
|
# Generates library of congress and dewey classifications using call number data.
|
5
7
|
class Classification < Helper
|
@@ -42,26 +44,53 @@ module PennMARC
|
|
42
44
|
}.uniq
|
43
45
|
end
|
44
46
|
|
47
|
+
# Return a normalized Call Number value for sorting purposes. This uses the Lcsort gem normalization logic, which
|
48
|
+
# returns nil for non-LC call numbers. For now, this returns only the call number values from the enrichment
|
49
|
+
# inventory fields.
|
50
|
+
# @note this could be made more efficient by just returning the first value, but in the future we may want to be
|
51
|
+
# more discerning about which call number we return (longest?)
|
52
|
+
# @param record [MARC::Record]
|
53
|
+
# @return [String, nil] a normalized call number
|
54
|
+
def sort(record)
|
55
|
+
values(record, loc_only: true).filter_map { |val| Lcsort.normalize(val) }.first
|
56
|
+
end
|
57
|
+
|
45
58
|
# Parse call number values from inventory fields, including both hld and itm fields from publishing enrichment.
|
46
59
|
# Return only unique values.
|
47
60
|
# @param record [MARC::Record]
|
48
61
|
# @return [Array<String>] array of call numbers from inventory fields
|
49
62
|
def call_number_search(record)
|
63
|
+
values(record, loc_only: false)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Return raw call number values from inventory fields
|
67
|
+
# @param record [MARC::Record]
|
68
|
+
# @param loc_only [Boolean] whether or not to explicitly return only LOC call numbers from ITM & AVA inventory
|
69
|
+
# @return [Array<String>]
|
70
|
+
def values(record, loc_only:)
|
50
71
|
call_nums = record.fields(TAGS).filter_map do |field|
|
72
|
+
next if loc_only && !loc_call_number_type?(subfield_values(field, call_number_type_sf(field))&.first)
|
73
|
+
|
51
74
|
subfield_values(field, call_number_sf(field))
|
52
75
|
end
|
53
76
|
|
54
|
-
|
55
|
-
call_nums
|
77
|
+
call_nums += hld_field_call_nums(record)
|
78
|
+
call_nums.flatten.uniq
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
# Get call nums from `hld` tags. Useful if no call nums are available from `itm` tags
|
84
|
+
# @param record [MARC::Record]
|
85
|
+
# @return [Array<String>]
|
86
|
+
def hld_field_call_nums(record)
|
87
|
+
record.fields([Enriched::Pub::PHYS_INVENTORY_TAG]).filter_map do |field|
|
56
88
|
first = subfield_values(field, Enriched::Pub::HOLDING_CLASSIFICATION_PART)&.first
|
57
89
|
last = subfield_values(field, Enriched::Pub::HOLDING_ITEM_PART)&.first
|
58
90
|
"#{first} #{last}".squish.presence
|
59
91
|
end
|
60
|
-
call_nums.flatten.uniq
|
61
92
|
end
|
62
93
|
|
63
|
-
private
|
64
|
-
|
65
94
|
# Retrieve subfield code that stores the call number on enriched marc field
|
66
95
|
# @param field [MARC::DataField]
|
67
96
|
# @return [String]
|
@@ -106,10 +135,10 @@ module PennMARC
|
|
106
135
|
end
|
107
136
|
|
108
137
|
# Determine whether call number type is library of congress
|
109
|
-
# @param call_number_type [String] value from call number type subfield
|
138
|
+
# @param call_number_type [String, nil] value from call number type subfield
|
110
139
|
# @return [Boolean]
|
111
140
|
def loc_call_number_type?(call_number_type)
|
112
|
-
call_number_type ==
|
141
|
+
call_number_type == LOC_CALL_NUMBER_TYPE
|
113
142
|
end
|
114
143
|
end
|
115
144
|
end
|
@@ -160,14 +160,14 @@ vismatl:
|
|
160
160
|
aeon: true
|
161
161
|
athstor:
|
162
162
|
specific_location: LIBRA - Athenaeum of Philadelphia
|
163
|
-
library:
|
163
|
+
library:
|
164
164
|
- LIBRA
|
165
165
|
- Athenaeum of Philadelphia
|
166
166
|
display: LIBRA - Athenaeum of Philadelphia
|
167
167
|
aeon: true
|
168
168
|
athstorcir:
|
169
169
|
specific_location: LIBRA - Athenaeum of Philadelphia Circulating
|
170
|
-
library:
|
170
|
+
library:
|
171
171
|
- LIBRA
|
172
172
|
- Athenaeum of Philadelphia
|
173
173
|
display: LIBRA - Athenaeum of Philadelphia Circulating
|
@@ -1272,6 +1272,14 @@ scinc:
|
|
1272
1272
|
- Van Pelt-Dietrich Library Center
|
1273
1273
|
display: Kislak Center for Special Collections - Incunables
|
1274
1274
|
aeon: true
|
1275
|
+
sckatzstor:
|
1276
|
+
specific_location: LIBRA Rare Library at the Katz Center
|
1277
|
+
library:
|
1278
|
+
- Special Collections
|
1279
|
+
- LIBRA
|
1280
|
+
- Library at the Katz Center for Advanced Judaic Studies
|
1281
|
+
display: LIBRA Rare Library at the Katz Center
|
1282
|
+
aeon: true
|
1275
1283
|
sclea:
|
1276
1284
|
specific_location: Kislak Center for Special Collections - Lea Collection
|
1277
1285
|
library:
|
data/lib/pennmarc/version.rb
CHANGED
data/pennmarc.gemspec
CHANGED
@@ -19,6 +19,7 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.required_ruby_version = '>= 3.2'
|
20
20
|
|
21
21
|
s.add_dependency 'activesupport', '~> 7'
|
22
|
+
s.add_dependency 'lcsort', '~> 0.9'
|
22
23
|
s.add_dependency 'library_stdnums', '~> 1.6'
|
23
24
|
s.add_dependency 'marc', '~> 1.2'
|
24
25
|
s.add_dependency 'nokogiri', '~> 1.15'
|
@@ -43,6 +43,86 @@ describe 'PennMARC::Classification' do
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
+
describe '.sort' do
|
47
|
+
context 'with enrichment via the Alma publishing process and no valid call number' do
|
48
|
+
let(:fields) do
|
49
|
+
[marc_field(tag: PennMARC::Enriched::Pub::ITEM_TAG, subfields: {
|
50
|
+
PennMARC::Enriched::Pub::ITEM_CALL_NUMBER_TYPE => helper::LOC_CALL_NUMBER_TYPE,
|
51
|
+
PennMARC::Enriched::Pub::ITEM_CALL_NUMBER => 'Secret Drawer Copy'
|
52
|
+
}),
|
53
|
+
marc_field(tag: PennMARC::Enriched::Pub::ITEM_TAG, subfields: {
|
54
|
+
PennMARC::Enriched::Pub::ITEM_CALL_NUMBER_TYPE => helper::DEWEY_CALL_NUMBER_TYPE,
|
55
|
+
PennMARC::Enriched::Pub::ITEM_CALL_NUMBER => '691.3 B2141'
|
56
|
+
})]
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'returns nil' do
|
60
|
+
expect(helper.sort(record)).to be_nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'with enrichment via the Alma publishing process and itm fields' do
|
65
|
+
let(:fields) do
|
66
|
+
[marc_field(tag: PennMARC::Enriched::Pub::ITEM_TAG, subfields: {
|
67
|
+
PennMARC::Enriched::Pub::ITEM_CALL_NUMBER_TYPE => helper::LOC_CALL_NUMBER_TYPE,
|
68
|
+
PennMARC::Enriched::Pub::ITEM_CALL_NUMBER => 'QL756 .S643'
|
69
|
+
}),
|
70
|
+
marc_field(tag: PennMARC::Enriched::Pub::ITEM_TAG, subfields: {
|
71
|
+
PennMARC::Enriched::Pub::ITEM_CALL_NUMBER_TYPE => helper::LOC_CALL_NUMBER_TYPE,
|
72
|
+
PennMARC::Enriched::Pub::ITEM_CALL_NUMBER => 'Secret Drawer Copy'
|
73
|
+
}),
|
74
|
+
marc_field(tag: PennMARC::Enriched::Pub::ITEM_TAG, subfields: {
|
75
|
+
PennMARC::Enriched::Pub::ITEM_CALL_NUMBER_TYPE => helper::DEWEY_CALL_NUMBER_TYPE,
|
76
|
+
PennMARC::Enriched::Pub::ITEM_CALL_NUMBER => '691.3 B2141'
|
77
|
+
})]
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'returns a normalized version of the first valid call number' do
|
81
|
+
expect(helper.sort(record)).to eq 'QL.0756.S643'
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'with enrichment via the Alma publishing process including both hld and itm fields' do
|
86
|
+
let(:fields) do
|
87
|
+
[marc_field(tag: PennMARC::Enriched::Pub::ITEM_TAG,
|
88
|
+
subfields: { PennMARC::Enriched::Pub::ITEM_CALL_NUMBER_TYPE => helper::LOC_CALL_NUMBER_TYPE,
|
89
|
+
PennMARC::Enriched::Pub::ITEM_CALL_NUMBER => 'QL756 .S643 1989' }),
|
90
|
+
marc_field(tag: PennMARC::Enriched::Pub::PHYS_INVENTORY_TAG,
|
91
|
+
subfields: { PennMARC::Enriched::Pub::HOLDING_CLASSIFICATION_PART => 'QL756',
|
92
|
+
PennMARC::Enriched::Pub::HOLDING_ITEM_PART => '.S643' })]
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'returns a normalized version of the first valid call number' do
|
96
|
+
expect(helper.sort(record)).to eq 'QL.0756.S643.1989'
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context 'with enrichment via the Alma publishing process and only hld fields' do
|
101
|
+
let(:fields) do
|
102
|
+
[marc_field(tag: PennMARC::Enriched::Pub::PHYS_INVENTORY_TAG,
|
103
|
+
subfields: { PennMARC::Enriched::Pub::HOLDING_CLASSIFICATION_PART => 'KF6450',
|
104
|
+
PennMARC::Enriched::Pub::HOLDING_ITEM_PART => '.C59 1989' })]
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'returns expected normalized value' do
|
108
|
+
expect(helper.sort(record)).to eq 'KF.6450.C59.1989'
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
context 'with enrichment with availability info via Alma Api' do
|
113
|
+
let(:fields) do
|
114
|
+
[marc_field(tag: PennMARC::Enriched::Api::PHYS_INVENTORY_TAG, subfields: {
|
115
|
+
PennMARC::Enriched::Api::PHYS_CALL_NUMBER_TYPE => helper::LOC_CALL_NUMBER_TYPE,
|
116
|
+
PennMARC::Enriched::Api::PHYS_CALL_NUMBER => 'QL756 .S643'
|
117
|
+
})]
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'returns expected normalized value' do
|
121
|
+
expect(helper.sort(record)).to eq 'QL.0756.S643'
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
46
126
|
describe '.call_number_search' do
|
47
127
|
let(:fields) do
|
48
128
|
[marc_field(tag: config[:tag],
|
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.2.
|
4
|
+
version: 1.2.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Kanning
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2024-12-
|
15
|
+
date: 2024-12-23 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: activesupport
|
@@ -28,6 +28,20 @@ dependencies:
|
|
28
28
|
- - "~>"
|
29
29
|
- !ruby/object:Gem::Version
|
30
30
|
version: '7'
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: lcsort
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
34
|
+
requirements:
|
35
|
+
- - "~>"
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0.9'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - "~>"
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0.9'
|
31
45
|
- !ruby/object:Gem::Dependency
|
32
46
|
name: library_stdnums
|
33
47
|
requirement: !ruby/object:Gem::Requirement
|