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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cb0bf4c30ad40bcee865ed6596fbfc6d6d16a5d3924d62947d270a3d5fa3aac5
4
- data.tar.gz: 33ca607af919156ac45a73067605b6ac298fef9c17ef983060e6a871c54ca26f
3
+ metadata.gz: 9003d5a58efd2cbef83a220bd0d609edfdc2bfb883378c003d0bafa2d85e520e
4
+ data.tar.gz: d8f841dbba9e412848b31a7a11284b14e2bbb772fbb98762b827ab9e2baf6355
5
5
  SHA512:
6
- metadata.gz: 5e5d316a7e1340aaf7438297e17198339d02ab797842b47ec2cece1daf75f96a387565b4fdc6ca273ef1a64630e1f486bc713ea75793ed3d783998234a83c517
7
- data.tar.gz: 6f6d6824e1aa5fecbcd2dc13bbc94ea575531e96ea5f822b992719f3b28189cce4c26febc2f31848f24008a57f6a839f787383752cfd2c915695b1f1e66fe5ca
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-07-02 15:41:46 UTC using RuboCop version 1.51.0.
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: 25
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: 8
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: 23
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 | String] field in location hash to retrieve
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 = specific_location_override(display_value: display_value, location_code: location_code,
57
- field: field, call_num_sf: call_num_sf)
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 [location_map] hash with location_code as key and location hash as value
109
- # @param location_code [location_code] retrieved from record
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) == false || location_code == WEB_LOCATION_CODE
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(display_value:, location_code:, field:, call_num_sf:)
123
- return unless display_value.to_sym == :specific_location
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
- locations_overrides = Mappers.location_overrides
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
- call_numbers = subfield_values(field, call_num_sf)
138
+ override&.last&.dig(:specific_location)
139
+ end
128
140
 
129
- override = locations_overrides.find do |_key, value|
130
- value[:location_code] == location_code && call_numbers.any? { |num| num.match?(value[:call_num_pattern]) }
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
- override&.last&.dig(:specific_location)
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
@@ -1,5 +1,6 @@
1
1
  albrecht:
2
2
  location_code: 'vanp'
3
3
  call_num_pattern: '^M.*'
4
+ call_num_type: '0'
4
5
  specific_location: 'Van Pelt - Albrecht Music Library'
5
6
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PennMARC
4
- VERSION = '1.1.0'
4
+ VERSION = '1.1.1'
5
5
  end
@@ -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(:record) do
11
- marc_record(fields: [marc_field(tag: enriched_marc::Pub::ITEM_TAG,
12
- subfields: { enriched_marc::Pub::ITEM_CURRENT_LOCATION => 'stor' })])
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(:record) do
25
- marc_record(fields: [marc_field(tag: enriched_marc::Pub::PHYS_INVENTORY_TAG,
26
- subfields: { enriched_marc::Pub::PHYS_LOCATION_CODE => 'stor' })])
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(:record) do
39
- marc_record(fields: [marc_field(tag: enriched_marc::Pub::ITEM_TAG,
40
- subfields: { enriched_marc::Pub::ITEM_CURRENT_LOCATION => 'stor' }),
41
- marc_field(tag: enriched_marc::Pub::PHYS_INVENTORY_TAG,
42
- subfields: { enriched_marc::Pub::PHYS_LOCATION_CODE => 'dent' })])
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(:record) { marc_record(fields: [marc_field(tag: enriched_marc::Pub::ITEM_TAG, subfields: { g: %w[dent] })]) }
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(:record) { marc_record(fields: [marc_field(tag: '852', subfields: { g: 'stor' })]) }
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(:record) do
71
- marc_record(fields: [marc_field(tag: enriched_marc::Api::PHYS_INVENTORY_TAG,
72
- subfields: {
73
- enriched_marc::Api::PHYS_LIBRARY_CODE => 'Libra',
74
- enriched_marc::Api::PHYS_LOCATION_NAME => 'LIBRA',
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
- let(:record) do
88
- marc_record(fields: [marc_field(tag: enriched_marc::Pub::ITEM_TAG,
89
- subfields: { enriched_marc::Pub::ITEM_CURRENT_LOCATION => 'vanp',
90
- enriched_marc::Pub::ITEM_CALL_NUMBER => 'ML3534 .D85 1984' }),
91
- marc_field(tag: enriched_marc::Pub::ITEM_TAG,
92
- subfields: { enriched_marc::Pub::ITEM_CURRENT_LOCATION => 'stor',
93
- enriched_marc::Pub::ITEM_CALL_NUMBER => 'L3534 .D85 1984' })])
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
- it 'returns expected values' do
97
- expect(helper.location(record: record, display_value: :specific_location, location_map: mapping))
98
- .to(contain_exactly(PennMARC::Mappers.location_overrides[:albrecht][:specific_location], 'LIBRA'))
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
- it 'returns expected values when receiving a string for display_value' do
102
- expect(helper.location(record: record, display_value: 'specific_location', location_map: mapping))
103
- .to(contain_exactly(PennMARC::Mappers.location_overrides[:albrecht][:specific_location], 'LIBRA'))
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.0
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-20 00:00:00.000000000 Z
15
+ date: 2024-08-23 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: activesupport