pennmarc 1.0.24 → 1.0.25

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: 59881d630f244bc6d8b76665df84f4b22297de2d51c44f5272df4226f4e27e75
4
- data.tar.gz: 8d4e78c359dea40f482adc5b4deaa3fbb75bbe15a4fce5955ad48de054ce82c4
3
+ metadata.gz: 8b540ecd84333f097b50a3682732229854b188fcde76921eb0ec184622a690dd
4
+ data.tar.gz: 9203fadee45b9ad65ec20880a1acbc23356000b748d32d07428ec093590cd55a
5
5
  SHA512:
6
- metadata.gz: 4a3a43ff1cecadf978a8c50d59b382c2592925116cacd757f368ea0a698e9b370a94e74fd98e1a6a06a3b837ab0dbdce2efece991aaf3da4b53c74396a73ee2e
7
- data.tar.gz: 7f5468f9891c9fe15003160fb4d5a6c04cd8291ead5e803f0652368376e1fd67381195a7bdffd7ea9a7aa996c071b75240405dd956c46d879753f6811eca1b0a
6
+ metadata.gz: 6770815e8f5f828c15451fc71c04dbef6a131203e8c58d721c063b15f218d5814a71b37fd6c4f088a9c7164d5d989ff6933abc820094068921f218c937a87410
7
+ data.tar.gz: 94eee63c29ae06151816a532a5afb7db1f27490de798651c909dc07fd0f33de1b4a1ee26057b6e3a8abc5d15c54d09709df8942e6e21ad828c1296fe3191725e
@@ -12,6 +12,7 @@ module PennMARC
12
12
  PHYS_INVENTORY_TAG = 'hld'
13
13
  ELEC_INVENTORY_TAG = 'prt'
14
14
  ITEM_TAG = 'itm'
15
+ RELATED_RECORD_TAG = 'rel'
15
16
 
16
17
  # Subfields for HLD tags
17
18
  # Follow MARC 852 spec: https://www.loc.gov/marc/holdings/hd852.html, but names are translated into Alma parlance
@@ -5,14 +5,13 @@ module PennMARC
5
5
  class Access < Helper
6
6
  ONLINE = 'Online'
7
7
  AT_THE_LIBRARY = 'At the library'
8
+ RESOURCE_LINK_BASE_URL = 'hdl.library.upenn.edu'
8
9
 
9
10
  class << self
10
11
  # Based on enhanced metadata fields added by Alma publishing process or API, determine if the record has
11
12
  # electronic access or has physical holdings, and is therefore "Online" or "At the library". If a record is "At
12
13
  # the library", but has a link to a finding aid in the 856 field (matching certain criteria), also add 'Online' as
13
14
  # an access method.
14
- # @todo What if none of these criteria match? Should we include "At the library" by default? Records with no value
15
- # in this field would be lost if the user selects a facet value.
16
15
  # @param [MARC::Record] record
17
16
  # @return [Array]
18
17
  def facet(record)
@@ -24,7 +23,7 @@ module PennMARC
24
23
  return values if values.size == 2 # return early if all values are already present
25
24
 
26
25
  # only check if ONLINE isn't already there
27
- values << ONLINE if values.exclude?(ONLINE) && finding_aid_linkage?(record)
26
+ values << ONLINE if values.exclude?(ONLINE) && resource_link?(record)
28
27
  values.uniq
29
28
  end
30
29
 
@@ -44,20 +43,23 @@ module PennMARC
44
43
  field.tag.in? [Enriched::Pub::PHYS_INVENTORY_TAG, Enriched::Api::PHYS_INVENTORY_TAG]
45
44
  end
46
45
 
47
- # Check if a record contains an 856 entry for an online finding aid, meeting these criteria:
46
+ # Check if a record contains an 856 entry with a Penn Handle server link meeting these criteria:
48
47
  # 1. Indicator 1 is 4 (HTTP resource)
49
48
  # 2. Indicator 2 is NOT 2 (indicating the linkage is to a "related" thing)
50
49
  # 3. The URL specified in subfield u (URI) is a Penn Handle link
50
+ # 4. The subfield z does NOT include the string 'Finding aid'
51
51
  # See: https://www.loc.gov/marc/bibliographic/bd856.html
52
+ # @note Some electronic records do not have Portfolios in Alma, so we rely upon the Resource Link in the 856 to
53
+ # get these records included in the Online category.
52
54
  # @param [MARC::Record] record
53
55
  # @return [Boolean]
54
- def finding_aid_linkage?(record)
56
+ def resource_link?(record)
55
57
  record.fields('856').filter_map do |field|
56
58
  next if field.indicator2 == '2' || field.indicator1 != '4'
57
59
 
58
60
  subz = subfield_values(field, 'z')
59
61
  subfield_values(field, 'u').filter_map do |value|
60
- return true if subz.include?('Finding aid') && value.include?('hdl.library.upenn.edu')
62
+ return true if subz.exclude?('Finding aid') && value.include?(RESOURCE_LINK_BASE_URL)
61
63
  end
62
64
  end
63
65
  false
@@ -159,6 +159,18 @@ module PennMARC
159
159
  }.uniq
160
160
  end
161
161
 
162
+ # Gets any Host record MMS ID values from an Enriched::Pub::RELATED_RECORD_TAG field added during Alma enrichment.
163
+ # This aids in our handling of "bound with" records.
164
+ # @param [MARC::Record] record
165
+ # @return [Array<String>]
166
+ def host_record_id(record)
167
+ record.fields(Enriched::Pub::RELATED_RECORD_TAG).filter_map { |field|
168
+ next unless subfield_value?(field, 'c', /contains/i)
169
+
170
+ subfield_values field, :w
171
+ }.flatten.uniq
172
+ end
173
+
162
174
  private
163
175
 
164
176
  # Determine if subfield 'a' is an OCLC id.
@@ -18,7 +18,7 @@ module PennMARC
18
18
  # - 2: MeSH
19
19
  # - 4: Source not specified (local?)
20
20
  # - 7: Source specified in ǂ2
21
- SEARCH_SOURCE_INDICATORS = %w[0 1 2 4 7].freeze
21
+ VALID_SOURCE_INDICATORS = %w[0 1 2 4 7].freeze
22
22
 
23
23
  # Tags that serve as sources for Subject facet values
24
24
  DISPLAY_TAGS = %w[600 610 611 630 650 651].freeze
@@ -27,7 +27,7 @@ module PennMARC
27
27
  LOCAL_TAGS = %w[690 691 697].freeze
28
28
 
29
29
  # All Subjects for searching. This includes most subfield content from any field contained in {SEARCH_TAGS} or
30
- # 69X, including any linked 880 fields. Fields must have an indicator2 value in {SEARCH_SOURCE_INDICATORS}.
30
+ # 69X, including any linked 880 fields. Fields must have an indicator2 value in {VALID_SOURCE_INDICATORS}.
31
31
  # @todo this includes subfields that may not be desired like 1 (uri) and 2 (source code) but this might be OK for
32
32
  # a search (non-display) field?
33
33
  # @param [Hash] relator_map
@@ -179,12 +179,18 @@ module PennMARC
179
179
  end
180
180
  end
181
181
 
182
- # Is a field intended for display in a general subject field
182
+ # Is a field intended for display in a general subject field? To be included, the field tag is in either
183
+ # {DISPLAY_TAGS} or {LOCAL_TAGS}, and has an indicator 2 value that is in {VALID_SOURCE_INDICATORS}. If
184
+ # indicator 2 is '7' - indicating "source specified", the specified source must be in our approved source code
185
+ # list.
186
+ # @see Util.valid_subject_genre_source_code?
183
187
  # @param [MARC::DataField] field
184
188
  # @return [Boolean] whether a MARC field is intended for display under general "Subjects"
185
189
  def subject_general_display_field?(field)
186
190
  return false unless field.tag.in?(DISPLAY_TAGS + LOCAL_TAGS) && field.respond_to?(:indicator2)
187
191
 
192
+ return false if field.indicator2.present? && !field.indicator2.in?(VALID_SOURCE_INDICATORS)
193
+
188
194
  return false if field.indicator2 == '7' && !valid_subject_genre_source_code?(field)
189
195
 
190
196
  true
@@ -278,7 +284,7 @@ module PennMARC
278
284
  # @param [MARC::DataField] field
279
285
  # @return [Boolean]
280
286
  def subject_search_field?(field)
281
- return false unless field.respond_to?(:indicator2) && SEARCH_SOURCE_INDICATORS.include?(field.indicator2)
287
+ return false unless field.respond_to?(:indicator2) && VALID_SOURCE_INDICATORS.include?(field.indicator2)
282
288
 
283
289
  tag = if field.tag == '880'
284
290
  subfield_values(field, '6').first
@@ -3,33 +3,36 @@
3
3
  module PennMARC
4
4
  # This helper contains logic for parsing out Title and Title-related fields.
5
5
  class Title < Helper
6
- class << self
7
- # We use these fields when retrieving auxiliary titles in the *search_aux methods:
8
- # {https://www.loc.gov/marc/bibliographic/bd130.html 130},
9
- # {https://www.loc.gov/marc/bibliographic/bd210.html 210},
10
- # {https://www.loc.gov/marc/bibliographic/bd245.html 245},
11
- # {https://www.loc.gov/marc/bibliographic/bd246.html 246},
12
- # {https://www.loc.gov/marc/bibliographic/bd247.html 247},
13
- # {https://www.loc.gov/marc/bibliographic/bd440.html 440},
14
- # {https://www.loc.gov/marc/bibliographic/bd490.html 490},
15
- # {https://www.loc.gov/marc/bibliographic/bd730.html 730},
16
- # {https://www.loc.gov/marc/bibliographic/bd740.html 740},
17
- # {https://www.loc.gov/marc/bibliographic/bd830.html 830},
18
- # {https://www.loc.gov/marc/bibliographic/bd773.html 773},
19
- # {https://www.loc.gov/marc/bibliographic/bd774.html 774},
20
- # {https://www.loc.gov/marc/bibliographic/bd780.html 780},
21
- # {https://www.loc.gov/marc/bibliographic/bd785.html 785},
22
- # {https://www.loc.gov/marc/bibliographic/bd700.html 700},
23
- # {https://www.loc.gov/marc/bibliographic/bd710.html 710},
24
- # {https://www.loc.gov/marc/bibliographic/bd711.html 711},
25
- # {https://www.loc.gov/marc/bibliographic/bd505.html 505}
26
- AUX_TITLE_TAGS = {
27
- main: %w[130 210 240 245 246 247 440 490 730 740 830],
28
- related: %w[773 774 780 785],
29
- entity: %w[700 710 711],
30
- note: %w[505]
31
- }.freeze
6
+ # We use these fields when retrieving auxiliary titles in the *search_aux methods:
7
+ # {https://www.loc.gov/marc/bibliographic/bd130.html 130},
8
+ # {https://www.loc.gov/marc/bibliographic/bd210.html 210},
9
+ # {https://www.loc.gov/marc/bibliographic/bd245.html 245},
10
+ # {https://www.loc.gov/marc/bibliographic/bd246.html 246},
11
+ # {https://www.loc.gov/marc/bibliographic/bd247.html 247},
12
+ # {https://www.loc.gov/marc/bibliographic/bd440.html 440},
13
+ # {https://www.loc.gov/marc/bibliographic/bd490.html 490},
14
+ # {https://www.loc.gov/marc/bibliographic/bd730.html 730},
15
+ # {https://www.loc.gov/marc/bibliographic/bd740.html 740},
16
+ # {https://www.loc.gov/marc/bibliographic/bd830.html 830},
17
+ # {https://www.loc.gov/marc/bibliographic/bd773.html 773},
18
+ # {https://www.loc.gov/marc/bibliographic/bd774.html 774},
19
+ # {https://www.loc.gov/marc/bibliographic/bd780.html 780},
20
+ # {https://www.loc.gov/marc/bibliographic/bd785.html 785},
21
+ # {https://www.loc.gov/marc/bibliographic/bd700.html 700},
22
+ # {https://www.loc.gov/marc/bibliographic/bd710.html 710},
23
+ # {https://www.loc.gov/marc/bibliographic/bd711.html 711},
24
+ # {https://www.loc.gov/marc/bibliographic/bd505.html 505}
25
+ AUX_TITLE_TAGS = {
26
+ main: %w[130 210 240 245 246 247 440 490 730 740 830],
27
+ related: %w[773 774 780 785],
28
+ entity: %w[700 710 711],
29
+ note: %w[505]
30
+ }.freeze
31
+
32
+ # This text is used in Alma to indicate a Bib record is a "Host" record for other bibs (bound-withs)
33
+ HOST_BIB_TITLE = 'Host bibliographic record for boundwith'
32
34
 
35
+ class << self
33
36
  # Main Title Search field. Takes from {https://www.loc.gov/marc/bibliographic/bd245.html 245} and linked 880.
34
37
  # @note Ported from get_title_1_search_values.
35
38
  # @param [MARC::Record] record
@@ -217,6 +220,16 @@ module PennMARC
217
220
  }.uniq
218
221
  end
219
222
 
223
+ # Determine if the record is a "Host" bibliographic record for other bib records ("bound-withs")
224
+ # @param [MARC::Record] record
225
+ # @return [Boolean]
226
+ def host_bib_record?(record)
227
+ record.fields('245').any? do |f|
228
+ title = join_subfields(f, &subfield_in?(%w[a]))
229
+ title.include?(HOST_BIB_TITLE)
230
+ end
231
+ end
232
+
220
233
  private
221
234
 
222
235
  # Create prefix/filing hash for representing a title value with filing characters removed, with special
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PennMARC
4
- VERSION = '1.0.24'
4
+ VERSION = '1.0.25'
5
5
  end
@@ -69,6 +69,17 @@ describe 'PennMARC::Access' do
69
69
  { z: 'Finding aid', u: 'http://hdl.library.upenn.edu/1017/d/pacscl/UPENN_RBML_MsColl200' }
70
70
  end
71
71
 
72
+ it 'does not include online access' do
73
+ expect(helper.facet(record)).to contain_exactly(PennMARC::Access::AT_THE_LIBRARY)
74
+ end
75
+ end
76
+
77
+ context 'with an 856 describing a resource link' do
78
+ let(:indicators) { { indicator1: '4', indicator2: '1' } }
79
+ let(:location_and_access_subfields) do
80
+ { z: 'Connect to resource', u: 'http://hdl.library.upenn.edu/1234' }
81
+ end
82
+
72
83
  it 'includes online access' do
73
84
  expect(helper.facet(record)).to contain_exactly(PennMARC::Access::ONLINE, PennMARC::Access::AT_THE_LIBRARY)
74
85
  end
@@ -161,4 +161,18 @@ describe 'PennMARC::Identifier' do
161
161
  '10.1038/sdata.2016.18', '10.18574/9781479842865')
162
162
  end
163
163
  end
164
+
165
+ describe '.host_record_id' do
166
+ let(:record) do
167
+ marc_record fields: [
168
+ marc_field(tag: PennMARC::Enriched::Pub::RELATED_RECORD_TAG, subfields: { w: '123456789', c: 'Contains',
169
+ a: 'Title' }),
170
+ marc_field(tag: PennMARC::Enriched::Pub::RELATED_RECORD_TAG, subfields: { w: '666666666', c: 'Contained In' })
171
+ ]
172
+ end
173
+
174
+ it 'returns only the desired host record MMS ID values' do
175
+ expect(helper.host_record_id(record)).to contain_exactly '123456789'
176
+ end
177
+ end
164
178
  end
@@ -288,6 +288,22 @@ describe 'PennMARC::Subject' do
288
288
  'Early works to 1950.')
289
289
  end
290
290
  end
291
+
292
+ context 'with a mix of allowed and disallowed heading sources' do
293
+ let(:fields) do
294
+ [marc_field(tag: '650', indicator2: '7', subfields: {
295
+ '2': 'fast',
296
+ a: 'Philosophy in motion pictures.',
297
+ '0': 'http://id.loc.gov/authorities/subjects/sh92003501'
298
+ }),
299
+ marc_field(tag: '650', indicator2: '7', subfields: { '2': 'gnd', a: 'Filmästhetik.' }),
300
+ marc_field(tag: '650', indicator2: '6', subfields: { a: 'Cinéma et arts.' })]
301
+ end
302
+
303
+ it 'includes only permitted headings from approved ontologies' do
304
+ expect(values).to contain_exactly 'Philosophy in motion pictures.'
305
+ end
306
+ end
291
307
  end
292
308
 
293
309
  describe '.childrens_show' do
@@ -249,4 +249,24 @@ describe 'PennMARC::Title' do
249
249
  expect(values).not_to include 'Linkage', '247'
250
250
  end
251
251
  end
252
+
253
+ describe '.host_bib_record?' do
254
+ let(:record) { marc_record fields: [marc_field(tag: '245', subfields: subfields)] }
255
+
256
+ context 'with a host record' do
257
+ let(:subfields) { { a: "#{PennMARC::Title::HOST_BIB_TITLE} for 123456789" } }
258
+
259
+ it 'returns true' do
260
+ expect(helper.host_bib_record?(record)).to be true
261
+ end
262
+ end
263
+
264
+ context 'with a non-host record' do
265
+ let(:subfields) { { a: 'Regular record' } }
266
+
267
+ it 'returns false' do
268
+ expect(helper.host_bib_record?(record)).to be false
269
+ end
270
+ end
271
+ end
252
272
  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.0.24
4
+ version: 1.0.25
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Kanning
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2024-06-18 00:00:00.000000000 Z
13
+ date: 2024-06-26 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport