pennmarc 1.2.5 → 1.2.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|