pennmarc 1.1.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +5 -4
- data/lib/pennmarc/helpers/location.rb +46 -16
- data/lib/pennmarc/mappings/location_overrides.yml +1 -0
- data/lib/pennmarc/version.rb +1 -1
- data/spec/lib/pennmarc/helpers/location_spec.rb +91 -33
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9003d5a58efd2cbef83a220bd0d609edfdc2bfb883378c003d0bafa2d85e520e
|
4
|
+
data.tar.gz: d8f841dbba9e412848b31a7a11284b14e2bbb772fbb98762b827ab9e2baf6355
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a45d1e909a7a9efad1aec8047d79f3358b1ee3b523958661459c27b397f3a0f33c00deffeae2bdd30fad14156b8f348171639375677e6f600086e1b592fe2c51
|
7
|
+
data.tar.gz: ba609fef49f12f9341328fc292cc510fab6ab298174791afc99ec802ecd1c62448c9ccc009a7f01c6aefef7be2c56d794cc5f2e0bddf01c72fc4e9db11ce6961
|
data/.rubocop_todo.yml
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# This configuration was generated by
|
2
2
|
# `rubocop --auto-gen-config --auto-gen-only-exclude --exclude-limit 10000`
|
3
|
-
# on 2024-
|
3
|
+
# on 2024-08-20 20:46:53 UTC using RuboCop version 1.51.0.
|
4
4
|
# The point is for the user to remove these configuration records
|
5
5
|
# one by one as the offenses are removed from the code base.
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
@@ -14,7 +14,7 @@ Gemspec/RequireMFA:
|
|
14
14
|
Exclude:
|
15
15
|
- 'pennmarc.gemspec'
|
16
16
|
|
17
|
-
# Offense count:
|
17
|
+
# Offense count: 26
|
18
18
|
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
|
19
19
|
Metrics/AbcSize:
|
20
20
|
Exclude:
|
@@ -31,7 +31,7 @@ Metrics/AbcSize:
|
|
31
31
|
- 'lib/pennmarc/helpers/title.rb'
|
32
32
|
- 'lib/pennmarc/util.rb'
|
33
33
|
|
34
|
-
# Offense count:
|
34
|
+
# Offense count: 9
|
35
35
|
# Configuration parameters: CountComments, Max, CountAsOne.
|
36
36
|
Metrics/ClassLength:
|
37
37
|
Exclude:
|
@@ -138,9 +138,10 @@ RSpec/FilePath:
|
|
138
138
|
Exclude:
|
139
139
|
- 'spec/lib/pennmarc/parser_spec.rb'
|
140
140
|
|
141
|
-
# Offense count:
|
141
|
+
# Offense count: 26
|
142
142
|
# Configuration parameters: Max, AllowedGroups.
|
143
143
|
RSpec/NestedGroups:
|
144
144
|
Exclude:
|
145
145
|
- 'spec/lib/pennmarc/helpers/access_spec.rb'
|
146
146
|
- 'spec/lib/pennmarc/helpers/format_spec.rb'
|
147
|
+
- 'spec/lib/pennmarc/helpers/location_spec.rb'
|
@@ -37,12 +37,12 @@ module PennMARC
|
|
37
37
|
# @see https://developers.exlibrisgroup.com/alma/apis/docs/bibs/R0VUIC9hbG1hd3MvdjEvYmlicy97bW1zX2lkfQ==/
|
38
38
|
# Alma documentation for these added fields
|
39
39
|
# @param record [MARC::Record]
|
40
|
-
# @param display_value [Symbol
|
40
|
+
# @param display_value [Symbol,String] field in location hash to retrieve
|
41
41
|
# @param location_map [Hash] hash with location_code as key and location hash as value
|
42
42
|
# @return [Array<String>]
|
43
43
|
def location(record:, display_value:, location_map:)
|
44
44
|
# get enriched marc location tag and relevant subfields
|
45
|
-
enriched_location_tag_and_subfields(record) => {tag:, location_code_sf:, call_num_sf:}
|
45
|
+
enriched_location_tag_and_subfields(record) => {tag:, location_code_sf:, call_num_sf:, call_num_type_sf:}
|
46
46
|
|
47
47
|
record.fields(tag).flat_map { |field|
|
48
48
|
field.filter_map { |subfield|
|
@@ -53,8 +53,10 @@ module PennMARC
|
|
53
53
|
|
54
54
|
next if location_code_to_ignore?(location_map, location_code)
|
55
55
|
|
56
|
-
override =
|
57
|
-
|
56
|
+
override = if display_value.to_sym == :specific_location
|
57
|
+
specific_location_override(location_code: location_code, field: field,
|
58
|
+
call_num_sf: call_num_sf, call_num_type_sf: call_num_type_sf)
|
59
|
+
end
|
58
60
|
|
59
61
|
override || location_map[location_code.to_sym][display_value.to_sym]
|
60
62
|
}.flatten.compact_blank
|
@@ -70,6 +72,8 @@ module PennMARC
|
|
70
72
|
# - `:tag` (String): The enriched marc location tag
|
71
73
|
# - `:location_code_sf` (String): The subfield code where location code is stored
|
72
74
|
# - `:call_num_sf` (String): The subfield code where call number is stored
|
75
|
+
# - `:call_num_type_sf` (String, nil): The subfield code where call number type is stored. nil if unavailable in a
|
76
|
+
# MARC field and we need to look for an indicator.
|
73
77
|
def enriched_location_tag_and_subfields(record)
|
74
78
|
# in holdings records, the shelving location is always the permanent location.
|
75
79
|
# in item records, the current location takes into account
|
@@ -84,19 +88,22 @@ module PennMARC
|
|
84
88
|
tag = Enriched::Pub::ITEM_TAG
|
85
89
|
location_code_sf = Enriched::Pub::ITEM_CURRENT_LOCATION
|
86
90
|
call_num_sf = Enriched::Pub::ITEM_CALL_NUMBER
|
91
|
+
call_num_type_sf = Enriched::Pub::ITEM_CALL_NUMBER_TYPE
|
87
92
|
# if the record has API inventory tags, use them
|
88
93
|
elsif field_defined?(record, Enriched::Api::PHYS_INVENTORY_TAG)
|
89
94
|
tag = Enriched::Api::PHYS_INVENTORY_TAG
|
90
95
|
location_code_sf = Enriched::Api::PHYS_LOCATION_CODE
|
91
96
|
call_num_sf = Enriched::Api::PHYS_CALL_NUMBER
|
97
|
+
call_num_type_sf = Enriched::Api::PHYS_CALL_NUMBER_TYPE
|
92
98
|
# otherwise use Pub holding tags
|
93
99
|
else
|
94
100
|
tag = Enriched::Pub::PHYS_INVENTORY_TAG
|
95
101
|
location_code_sf = Enriched::Pub::PHYS_LOCATION_CODE
|
96
102
|
call_num_sf = Enriched::Pub::HOLDING_CLASSIFICATION_PART
|
103
|
+
call_num_type_sf = nil # for hld tags, the call num type is indicator0
|
97
104
|
end
|
98
105
|
|
99
|
-
{ tag: tag, location_code_sf: location_code_sf, call_num_sf: call_num_sf }
|
106
|
+
{ tag: tag, location_code_sf: location_code_sf, call_num_sf: call_num_sf, call_num_type_sf: call_num_type_sf }
|
100
107
|
end
|
101
108
|
|
102
109
|
# Determines whether to ignore a location code.
|
@@ -105,32 +112,55 @@ module PennMARC
|
|
105
112
|
# map, we ignore it, for faceting purposes. We also ignore the location code 'web'. We don't facet for 'web'
|
106
113
|
# which is the 'Penn Library Web' location used in Voyager. This location should eventually go away completely
|
107
114
|
# with data cleanup in Alma.
|
108
|
-
# @param location_map [
|
109
|
-
# @param location_code [
|
115
|
+
# @param location_map [Hash] hash with location_code as key and location hash as value
|
116
|
+
# @param location_code [String] retrieved from record
|
110
117
|
# @return [Boolean]
|
111
118
|
def location_code_to_ignore?(location_map, location_code)
|
112
|
-
location_map.key?(location_code.to_sym)
|
119
|
+
!location_map.key?(location_code.to_sym) || location_code == WEB_LOCATION_CODE
|
113
120
|
end
|
114
121
|
|
115
122
|
# Retrieves a specific location override based on location code and call number. Specific location overrides are
|
116
123
|
# located in `location_overrides.yml`.
|
117
|
-
# @param display_value [String | Symbol]
|
118
124
|
# @param location_code [String]
|
119
125
|
# @param field [MARC::Field]
|
120
126
|
# @param call_num_sf [String]
|
127
|
+
# @param call_num_type_sf [String, nil]
|
121
128
|
# @return [String, Nil]
|
122
|
-
def specific_location_override(
|
123
|
-
|
129
|
+
def specific_location_override(location_code:, field:, call_num_sf:, call_num_type_sf:)
|
130
|
+
callnum_type = callnum_type(field: field, call_num_type_sf: call_num_type_sf)
|
131
|
+
return unless callnum_type
|
124
132
|
|
125
|
-
|
133
|
+
override = Mappers.location_overrides.find do |_key, override_data|
|
134
|
+
override_matching?(override_data: override_data, location_code: location_code, callnum_type: callnum_type,
|
135
|
+
call_numbers: subfield_values(field, call_num_sf))
|
136
|
+
end
|
126
137
|
|
127
|
-
|
138
|
+
override&.last&.dig(:specific_location)
|
139
|
+
end
|
128
140
|
|
129
|
-
|
130
|
-
|
141
|
+
# Check override_data hash for a matching location name override
|
142
|
+
# @param override_data [Hash]
|
143
|
+
# @param location_code [String]
|
144
|
+
# @param call_numbers [Array]
|
145
|
+
# @param callnum_type [String]
|
146
|
+
# @return [Boolean]
|
147
|
+
def override_matching?(override_data:, location_code:, call_numbers:, callnum_type:)
|
148
|
+
call_numbers.any? do |call_number|
|
149
|
+
override_data[:location_code] == location_code &&
|
150
|
+
override_data[:call_num_type] == callnum_type &&
|
151
|
+
call_number.match?(override_data[:call_num_pattern])
|
131
152
|
end
|
153
|
+
end
|
132
154
|
|
133
|
-
|
155
|
+
# Return call num type value for a given field. If no call number subfield is expected (publishing holding
|
156
|
+
# inventory case), the first indicator is checked.
|
157
|
+
# @param field [MARC::Field]
|
158
|
+
# @param call_num_type_sf [String, nil]
|
159
|
+
# @return [String, nil]
|
160
|
+
def callnum_type(field:, call_num_type_sf:)
|
161
|
+
return field.indicator1 if call_num_type_sf.nil?
|
162
|
+
|
163
|
+
subfield_values(field, call_num_type_sf).first
|
134
164
|
end
|
135
165
|
end
|
136
166
|
end
|
data/lib/pennmarc/version.rb
CHANGED
@@ -4,12 +4,13 @@ describe 'PennMARC::Location' do
|
|
4
4
|
let(:helper) { PennMARC::Location }
|
5
5
|
let(:enriched_marc) { PennMARC::Enriched }
|
6
6
|
let(:mapping) { location_map }
|
7
|
+
let(:record) { marc_record(fields: fields) }
|
7
8
|
|
8
9
|
describe 'location' do
|
9
10
|
context "with only 'itm' field present" do
|
10
|
-
let(:
|
11
|
-
|
12
|
-
|
11
|
+
let(:fields) do
|
12
|
+
[marc_field(tag: enriched_marc::Pub::ITEM_TAG,
|
13
|
+
subfields: { enriched_marc::Pub::ITEM_CURRENT_LOCATION => 'stor' })]
|
13
14
|
end
|
14
15
|
|
15
16
|
it 'returns expected value' do
|
@@ -21,9 +22,9 @@ describe 'PennMARC::Location' do
|
|
21
22
|
end
|
22
23
|
|
23
24
|
context "with only 'hld' field present" do
|
24
|
-
let(:
|
25
|
-
|
26
|
-
|
25
|
+
let(:fields) do
|
26
|
+
[marc_field(tag: enriched_marc::Pub::PHYS_INVENTORY_TAG,
|
27
|
+
subfields: { enriched_marc::Pub::PHYS_LOCATION_CODE => 'stor' })]
|
27
28
|
end
|
28
29
|
|
29
30
|
it 'returns expected value' do
|
@@ -35,11 +36,11 @@ describe 'PennMARC::Location' do
|
|
35
36
|
end
|
36
37
|
|
37
38
|
context 'with both holding and item tag fields present=' do
|
38
|
-
let(:
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
39
|
+
let(:fields) do
|
40
|
+
[marc_field(tag: enriched_marc::Pub::ITEM_TAG,
|
41
|
+
subfields: { enriched_marc::Pub::ITEM_CURRENT_LOCATION => 'stor' }),
|
42
|
+
marc_field(tag: enriched_marc::Pub::PHYS_INVENTORY_TAG,
|
43
|
+
subfields: { enriched_marc::Pub::PHYS_LOCATION_CODE => 'dent' })]
|
43
44
|
end
|
44
45
|
|
45
46
|
it 'returns item location' do
|
@@ -49,7 +50,7 @@ describe 'PennMARC::Location' do
|
|
49
50
|
end
|
50
51
|
|
51
52
|
context 'with multiple library locations' do
|
52
|
-
let(:
|
53
|
+
let(:fields) { [marc_field(tag: enriched_marc::Pub::ITEM_TAG, subfields: { g: %w[dent] })] }
|
53
54
|
|
54
55
|
it 'returns expected value' do
|
55
56
|
expect(helper.location(record: record, location_map: mapping,
|
@@ -59,7 +60,7 @@ describe 'PennMARC::Location' do
|
|
59
60
|
end
|
60
61
|
|
61
62
|
context 'without enriched marc location tag' do
|
62
|
-
let(:
|
63
|
+
let(:fields) { [marc_field(tag: '852', subfields: { g: 'stor' })] }
|
63
64
|
|
64
65
|
it 'returns expected value' do
|
65
66
|
expect(helper.location(record: record, location_map: mapping, display_value: :library)).to be_empty
|
@@ -67,13 +68,11 @@ describe 'PennMARC::Location' do
|
|
67
68
|
end
|
68
69
|
|
69
70
|
context 'with AVA fields' do
|
70
|
-
let(:
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
enriched_marc::Api::PHYS_LOCATION_CODE => 'stor'
|
76
|
-
})])
|
71
|
+
let(:fields) do
|
72
|
+
[marc_field(tag: enriched_marc::Api::PHYS_INVENTORY_TAG,
|
73
|
+
subfields: { enriched_marc::Api::PHYS_LIBRARY_CODE => 'Libra',
|
74
|
+
enriched_marc::Api::PHYS_LOCATION_NAME => 'LIBRA',
|
75
|
+
enriched_marc::Api::PHYS_LOCATION_CODE => 'stor' })]
|
77
76
|
end
|
78
77
|
|
79
78
|
it 'returns expected values' do
|
@@ -84,23 +83,82 @@ describe 'PennMARC::Location' do
|
|
84
83
|
end
|
85
84
|
|
86
85
|
context 'with a specific location override' do
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
86
|
+
context 'with item fields and LC call nums' do
|
87
|
+
let(:fields) do
|
88
|
+
[marc_field(tag: enriched_marc::Pub::ITEM_TAG,
|
89
|
+
subfields: { enriched_marc::Pub::ITEM_CURRENT_LOCATION => 'vanp',
|
90
|
+
enriched_marc::Pub::ITEM_CALL_NUMBER_TYPE =>
|
91
|
+
PennMARC::Classification::LOC_CALL_NUMBER_TYPE,
|
92
|
+
enriched_marc::Pub::ITEM_CALL_NUMBER => 'ML3534 .D85 1984' }),
|
93
|
+
marc_field(tag: enriched_marc::Pub::ITEM_TAG,
|
94
|
+
subfields: { enriched_marc::Pub::ITEM_CURRENT_LOCATION => 'stor',
|
95
|
+
enriched_marc::Pub::ITEM_CALL_NUMBER_TYPE => '8',
|
96
|
+
enriched_marc::Pub::ITEM_CALL_NUMBER => 'L3534 .D85 1984' })]
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'returns expected values' do
|
100
|
+
expect(helper.location(record: record, display_value: :specific_location, location_map: mapping))
|
101
|
+
.to(contain_exactly(PennMARC::Mappers.location_overrides[:albrecht][:specific_location], 'LIBRA'))
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'returns expected values when receiving a string for display_value' do
|
105
|
+
expect(helper.location(record: record, display_value: 'specific_location', location_map: mapping))
|
106
|
+
.to(contain_exactly(PennMARC::Mappers.location_overrides[:albrecht][:specific_location], 'LIBRA'))
|
107
|
+
end
|
94
108
|
end
|
95
109
|
|
96
|
-
|
97
|
-
|
98
|
-
|
110
|
+
context 'with item fields and microfilm call nums' do
|
111
|
+
let(:fields) do
|
112
|
+
[marc_field(tag: enriched_marc::Pub::ITEM_TAG, indicator1: ' ',
|
113
|
+
subfields: { enriched_marc::Pub::ITEM_CURRENT_LOCATION => 'vanp',
|
114
|
+
enriched_marc::Pub::ITEM_CALL_NUMBER_TYPE => '8',
|
115
|
+
enriched_marc::Pub::ITEM_CALL_NUMBER => 'Microfilm 3140 item 8' })]
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'returns expected values' do
|
119
|
+
expect(helper.location(record: record, display_value: :specific_location, location_map: mapping))
|
120
|
+
.to(contain_exactly(PennMARC::Mappers.location[:vanp][:specific_location]))
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context 'with holding fields and both LC and non-LC call num type' do
|
125
|
+
let(:fields) do
|
126
|
+
[marc_field(indicator1: '8', tag: enriched_marc::Pub::PHYS_INVENTORY_TAG,
|
127
|
+
subfields: { enriched_marc::Pub::PHYS_LOCATION_CODE => 'vanp' }),
|
128
|
+
marc_field(indicator1: '0', tag: enriched_marc::Pub::PHYS_INVENTORY_TAG,
|
129
|
+
subfields: { enriched_marc::Pub::PHYS_LOCATION_CODE => 'vanp',
|
130
|
+
enriched_marc::Pub::HOLDING_CLASSIFICATION_PART => 'ML3534' })]
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'returns expected values' do
|
134
|
+
expect(helper.location(record: record, display_value: :specific_location, location_map: mapping))
|
135
|
+
.to(contain_exactly(PennMARC::Mappers.location[:vanp][:specific_location],
|
136
|
+
PennMARC::Mappers.location_overrides[:albrecht][:specific_location]))
|
137
|
+
end
|
99
138
|
end
|
100
139
|
|
101
|
-
|
102
|
-
|
103
|
-
|
140
|
+
context 'with a variety of holding fields from the Alma API enrichment' do
|
141
|
+
let(:fields) do
|
142
|
+
[marc_field(tag: enriched_marc::Api::PHYS_INVENTORY_TAG,
|
143
|
+
subfields: { enriched_marc::Api::PHYS_CALL_NUMBER => 'Locked Closet Floor',
|
144
|
+
enriched_marc::Api::PHYS_CALL_NUMBER_TYPE => '8' }),
|
145
|
+
marc_field(tag: enriched_marc::Api::PHYS_INVENTORY_TAG,
|
146
|
+
subfields: { enriched_marc::Api::PHYS_LOCATION_CODE => 'vanp',
|
147
|
+
enriched_marc::Api::PHYS_CALL_NUMBER => ['ML123 .P567 1875', 'ML123'],
|
148
|
+
enriched_marc::Api::PHYS_CALL_NUMBER_TYPE =>
|
149
|
+
PennMARC::Classification::LOC_CALL_NUMBER_TYPE }),
|
150
|
+
marc_field(tag: enriched_marc::Api::PHYS_INVENTORY_TAG,
|
151
|
+
subfields: { enriched_marc::Api::PHYS_LOCATION_CODE => 'vanp',
|
152
|
+
enriched_marc::Api::PHYS_CALL_NUMBER => 'P789 .D123 2012',
|
153
|
+
enriched_marc::Api::PHYS_CALL_NUMBER_TYPE =>
|
154
|
+
PennMARC::Classification::LOC_CALL_NUMBER_TYPE })]
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'returns expected values' do
|
158
|
+
expect(helper.location(record: record, display_value: :specific_location, location_map: mapping))
|
159
|
+
.to(contain_exactly(PennMARC::Mappers.location[:vanp][:specific_location],
|
160
|
+
PennMARC::Mappers.location_overrides[:albrecht][:specific_location]))
|
161
|
+
end
|
104
162
|
end
|
105
163
|
end
|
106
164
|
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.1.
|
4
|
+
version: 1.1.1
|
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-08-
|
15
|
+
date: 2024-08-23 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: activesupport
|