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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 21463a3d231e3ba853929bc03241d8e3c109c6191d3a5747c1a397aad40e454d
4
- data.tar.gz: e747a26ee6ed508b13a3079acd2291d194d4a9a9bc4a984dcefd8145d5f76084
3
+ metadata.gz: 920cef15f1cac246074afedbe31a0f456ee81d9e9bcbb04c0dde024901d925db
4
+ data.tar.gz: edf42bff8a460373147e52e4cc3bf1c277655486635952ebf6604bc83fab5912
5
5
  SHA512:
6
- metadata.gz: ee0a42b85b4862caca7417176947497d63253d07818341e3ef483789554dfcf06eff4f658a89d44d865e7354f4dcae3e88e060cdd41c941e016de5d86e8ad365
7
- data.tar.gz: ca200369654cb607e14ea1225ce785a90ca05da9f5fe9a3a7390748b997b4b5e423f26a1c832bfab14c339a493af39f2422171b647542f92a926e5c2a7405993
6
+ metadata.gz: 614f6a26980656a8030bdaf28b0c901a9d5a841e0bad65b1e0455e9f09b3071e6c1f379ea3a54c4267c66403efdef3de0e7be4862c9e05c84d3d1f228921ccd8
7
+ data.tar.gz: 6b85c2040e4b9dbb0bb95b5e5d0914ada840399338246b54ee94b338ebb7c7c58dd32a22d9ae425337b6ce7074c03124e826a7b4b117bc40cc3d05405cfe2e29
data/Gemfile CHANGED
@@ -3,6 +3,7 @@
3
3
  source 'https://rubygems.org'
4
4
 
5
5
  gem 'activesupport', '~> 7'
6
+ gem 'lcsort'
6
7
  gem 'library_stdnums', '~> 1.6'
7
8
  gem 'marc', '~> 1.2'
8
9
  gem 'nokogiri', '~> 1.15'
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
- # Ensure we get call numbers for records with no `itm` tags by also checking `hld` and de-duping
55
- call_nums += record.fields([Enriched::Pub::PHYS_INVENTORY_TAG]).filter_map do |field|
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 == '0'
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:
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PennMARC
4
- VERSION = '1.2.5'
4
+ VERSION = '1.2.7'
5
5
  end
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.5
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-17 00:00:00.000000000 Z
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