pennmarc 1.0.7 → 1.0.9

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: 11dd403cd5a0f964db340be6258d2cc510c99ccc0fc6d43a65b236853cb5b87c
4
- data.tar.gz: 85eed79f3e637121cce8be8b0f0509d26e3fa9b6283b7f5bc48b0b321259e3f3
3
+ metadata.gz: 652039b781e2ce7442f628ca722f4fda59207d1d8171bfd2fad84d2c67f3c06f
4
+ data.tar.gz: 166bbf8498f673b36373671db47031ef8a2f4d5496ed1fddeee89718bd23e09c
5
5
  SHA512:
6
- metadata.gz: 90a59eaf167d985b596663d6b8d1eab0c3263724da550babfb28fa253df326b07b72bbb5aac1cf1d4150efd2eaecce84686b2de9e99801ff178bbfabc982b765
7
- data.tar.gz: 5e0a4fdc1518af2b3a52bc137f76a30430d025f58f5cd46b9d0347a7a6a08f901e72e45917cc9a52d0352a6dbb0213725fd5a6e22650cfedb00d534fb72b44f2
6
+ metadata.gz: 68df667344adaff013da3eab5417bdd44748726a113190d20c44cc1cf4d061269619265e3de1edc9c7c767ffff5a4548a9fcb3ed2039b28a2608ec62a6e024d1
7
+ data.tar.gz: 8df6d32dbc84ff3851e4b35576e24c96c42b536330ded1f0f1678de3d1aa0729547a71b0c6ccea15e7c949ee15e068d1c0f19b18a6b414167cb736effa2b01dd
@@ -32,5 +32,16 @@ module PennMARC
32
32
  # a subfield code NOT used by the MARC 21 spec for 852 holdings records.
33
33
  # we add this subfield during preprocessing to store boundwith record IDs.
34
34
  SUB_BOUND_WITH_ID = 'y'
35
+
36
+ # MARC enrichment originating from Alma Api
37
+ # @see https://developers.exlibrisgroup.com/alma/apis/docs/bibs/R0VUIC9hbG1hd3MvdjEvYmlicy97bW1zX2lkfQ==/ Alma docs
38
+ module AlmaApi
39
+ TAG_PHYSICAL_INVENTORY = 'AVA'
40
+ TAG_DIGITAL_INVENTORY = 'AVA'
41
+ TAG_ELECTRONIC_INVENTORY = 'AVE'
42
+
43
+ SUB_PHYSICAL_CALL_NUMBER = 'd'
44
+ SUB_PHYSICAL_CALL_NUMBER_TYPE = 'k'
45
+ end
35
46
  end
36
47
  end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PennMARC
4
+ # Generates library of congress and dewey classifications using call number data.
5
+ class Classification < Helper
6
+ # Subfield value that identifies Library of Congress call number
7
+ LOC_CALL_NUMBER_TYPE = '0'
8
+
9
+ # Subfield value that identifies Dewey call number
10
+ DEWEY_CALL_NUMBER_TYPE = '1'
11
+
12
+ # Hash that maps call number type to the appropriate mapper
13
+ CLASSIFICATION_MAPS = {
14
+ LOC_CALL_NUMBER_TYPE => Mappers.loc_classification,
15
+ DEWEY_CALL_NUMBER_TYPE => Mappers.dewey_classification
16
+ }.freeze
17
+
18
+ # Enriched MARC tags that hold classification data
19
+ TAGS = [EnrichedMarc::TAG_ITEM, EnrichedMarc::AlmaApi::TAG_PHYSICAL_INVENTORY].freeze
20
+
21
+ class << self
22
+ # Parse classification values for faceting. We retrieve classification values from enriched MARC fields 'itm' or
23
+ # 'AVA' originating respectively from the Alma publishing process or from the Alma Api. We return the
24
+ # highest level LOC or Dewey classifications from each available call number, joining the class code with
25
+ # its title in a single string. See {PennMARC::EnrichedMarc} and {PennMARC::EnrichedMarc::AlmaApi} for more
26
+ # information on the enriched MARC fields.
27
+ # @see https://developers.exlibrisgroup.com/alma/apis/docs/bibs/R0VUIC9hbG1hd3MvdjEvYmlicy97bW1zX2lkfQ==/ AVA docs
28
+ # @param [MARC::Record] record
29
+ # @return [Array<String>] array of classifications
30
+ def facet(record)
31
+ record.fields(TAGS).flat_map do |field|
32
+ call_number_type = subfield_values(field, call_number_type_sf(field))&.first
33
+ call_numbers = subfield_values(field, call_number_sf(field))
34
+
35
+ call_numbers.filter_map do |call_number|
36
+ class_code = call_number[0]
37
+ title = translate_classification(class_code, call_number_type)
38
+ next if title.blank?
39
+
40
+ format_facet(class_code, call_number_type, title)
41
+ end
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ # Retrieve subfield code that stores the call number on enriched marc field
48
+ # @param [MARC::DataField] field
49
+ # @return [String]
50
+ def call_number_sf(field)
51
+ return EnrichedMarc::SUB_ITEM_CALL_NUMBER if field.tag == EnrichedMarc::TAG_ITEM
52
+
53
+ EnrichedMarc::AlmaApi::SUB_PHYSICAL_CALL_NUMBER
54
+ end
55
+
56
+ # Retrieve subfield code that stores call number type on enriched marc field
57
+ # @param [MARC::DataField] field
58
+ # @return [String]
59
+ def call_number_type_sf(field)
60
+ return EnrichedMarc::SUB_ITEM_CALL_NUMBER_TYPE if field.tag == EnrichedMarc::TAG_ITEM
61
+
62
+ EnrichedMarc::AlmaApi::SUB_PHYSICAL_CALL_NUMBER_TYPE
63
+ end
64
+
65
+ # retrieve title of classification based on single char classification code and call number type
66
+ # @param[String] class_code classification code
67
+ # @param[String] call_number_type value from call number type subfield
68
+ # @return [String, NilClass]
69
+ def translate_classification(class_code, call_number_type)
70
+ map = CLASSIFICATION_MAPS[call_number_type]
71
+
72
+ return if map.blank?
73
+
74
+ translate_relator(class_code, map)
75
+ end
76
+
77
+ # format classification facet by joining single character classification code with its corresponding title.
78
+ # Our Dewey mapping codes are single digit, so we must concatenate '00' to the class code to accurately reflect
79
+ # Dewey class codes.
80
+ # @return [String]
81
+ def format_facet(class_code, call_number_type, title)
82
+ return [class_code, title].join(' - ') if loc_call_number_type?(call_number_type)
83
+
84
+ ["#{class_code}00", title].join(' - ')
85
+ end
86
+
87
+ # Determine whether call number type is library of congress
88
+ # @param [String] call_number_type value from call number type subfield
89
+ # @return [Boolean]
90
+ def loc_call_number_type?(call_number_type)
91
+ call_number_type == '0'
92
+ end
93
+ end
94
+ end
95
+ end
@@ -13,7 +13,7 @@ module PennMARC
13
13
  # Full text links from MARC 856 fields.
14
14
  # @param [MARC::Record] record
15
15
  # @return [Array] array of hashes
16
- def full_text(record:)
16
+ def full_text(record)
17
17
  indicator2_options = %w[0 1]
18
18
  links_from_record(record, indicator2_options)
19
19
  end
@@ -21,7 +21,7 @@ module PennMARC
21
21
  # Web text links from MARC 856 fields.
22
22
  # @param [MARC::Record] record
23
23
  # @return [Array] array of hashes
24
- def web(record:)
24
+ def web(record)
25
25
  indicator2_options = ['2', ' ', '']
26
26
  links_from_record(record, indicator2_options)
27
27
  end
@@ -23,6 +23,16 @@ module PennMARC
23
23
  @relator ||= load_map('relator.yml')
24
24
  end
25
25
 
26
+ # @return [Hash]
27
+ def loc_classification
28
+ @loc_classification ||= load_map('loc_classification.yml')
29
+ end
30
+
31
+ # @return [Hash]
32
+ def dewey_classification
33
+ @dewey_classification ||= load_map('dewey_classification.yml')
34
+ end
35
+
26
36
  # @param [String] filename of mapping file in config directory, with file extension
27
37
  # @return [Hash] mapping as hash
28
38
  def load_map(filename)
@@ -0,0 +1,11 @@
1
+ ---
2
+ '0': Computer science, information & general works
3
+ '1': Philosophy & psychology
4
+ '2': Religion
5
+ '3': Social sciences
6
+ '4': Language
7
+ '5': Science
8
+ '6': Technology
9
+ '7': Arts & recreation
10
+ '8': Literature
11
+ '9': History & geography
@@ -0,0 +1,22 @@
1
+ ---
2
+ A: General Works
3
+ B: Philosophy, Psychology, Religion
4
+ C: 'History: Auxiliary Sciences'
5
+ D: 'History: General & European'
6
+ E: 'History: United States'
7
+ F: 'History: Western Hemisphere'
8
+ G: Geography, Anthropology, Recreation
9
+ H: Social Science, Economics, Sociology
10
+ J: Political Science
11
+ K: Law
12
+ L: Education
13
+ M: Music
14
+ N: Fine Arts
15
+ P: Literature & Languages
16
+ Q: Science
17
+ R: Medicine
18
+ S: Agriculture
19
+ T: Technology
20
+ U: Military Science
21
+ V: Naval Science
22
+ Z: Bibliography & Library Science
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PennMARC
4
- VERSION = '1.0.7'
4
+ VERSION = '1.0.9'
5
5
  end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe 'PennMARC::Classification' do
4
+ include MarcSpecHelpers
5
+
6
+ let(:helper) { PennMARC::Classification }
7
+ let(:record) do
8
+ marc_record fields: [marc_field(tag: tag,
9
+ subfields: { call_number_type_sf => '0', call_number_sf => 'TA683 .B3 1909b' }),
10
+ marc_field(tag: tag,
11
+ subfields: { call_number_type_sf => '0', call_number_sf => 'QL756 .S643' }),
12
+ marc_field(tag: tag,
13
+ subfields: { call_number_type_sf => '1', call_number_sf => '691.3 B2141' }),
14
+ marc_field(tag: tag,
15
+ subfields: { call_number_type_sf => '1', call_number_sf => '378.748 POS1952.29' })]
16
+ end
17
+
18
+ describe '.facet' do
19
+ context 'with enrichment via the Alma publishing process' do
20
+ let(:tag) { PennMARC::EnrichedMarc::TAG_ITEM }
21
+ let(:call_number_type_sf) { PennMARC::EnrichedMarc::SUB_ITEM_CALL_NUMBER_TYPE }
22
+ let(:call_number_sf) { PennMARC::EnrichedMarc::SUB_ITEM_CALL_NUMBER }
23
+
24
+ it 'returns expected values' do
25
+ expect(helper.facet(record)).to contain_exactly('T - Technology', '600 - Technology',
26
+ '300 - Social sciences', 'Q - Science')
27
+ end
28
+ end
29
+
30
+ context 'with enrichment with availability info via Alma Api' do
31
+ let(:tag) { PennMARC::EnrichedMarc::AlmaApi::TAG_PHYSICAL_INVENTORY }
32
+ let(:call_number_type_sf) { PennMARC::EnrichedMarc::AlmaApi::SUB_PHYSICAL_CALL_NUMBER_TYPE }
33
+ let(:call_number_sf) { PennMARC::EnrichedMarc::AlmaApi::SUB_PHYSICAL_CALL_NUMBER }
34
+
35
+ it 'returns expected values' do
36
+ expect(helper.facet(record)).to contain_exactly('T - Technology', '600 - Technology',
37
+ '300 - Social sciences', 'Q - Science')
38
+ end
39
+ end
40
+ end
41
+ end
@@ -15,8 +15,8 @@ describe 'PennMARC::Link' do
15
15
  end
16
16
 
17
17
  it 'returns full text link text and url' do
18
- expect(helper.full_text(record: record)).to contain_exactly({ link_text: 'Materials specified Public note',
19
- link_url: 'https://www.test-uri.com/' })
18
+ expect(helper.full_text(record)).to contain_exactly({ link_text: 'Materials specified Public note',
19
+ link_url: 'https://www.test-uri.com/' })
20
20
  end
21
21
  end
22
22
 
@@ -30,8 +30,8 @@ describe 'PennMARC::Link' do
30
30
  end
31
31
 
32
32
  it 'returns web link text and url' do
33
- expect(helper.web(record: record)).to contain_exactly({ link_text: 'Materials specified Public note',
34
- link_url: 'https://www.test-uri.com/' })
33
+ expect(helper.web(record)).to contain_exactly({ link_text: 'Materials specified Public note',
34
+ link_url: 'https://www.test-uri.com/' })
35
35
  end
36
36
  end
37
37
  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.7
4
+ version: 1.0.9
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: 2023-12-06 00:00:00.000000000 Z
13
+ date: 2023-12-08 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport
@@ -91,6 +91,7 @@ files:
91
91
  - lib/pennmarc/heading_control.rb
92
92
  - lib/pennmarc/helpers/access.rb
93
93
  - lib/pennmarc/helpers/citation.rb
94
+ - lib/pennmarc/helpers/classification.rb
94
95
  - lib/pennmarc/helpers/creator.rb
95
96
  - lib/pennmarc/helpers/database.rb
96
97
  - lib/pennmarc/helpers/date.rb
@@ -109,8 +110,10 @@ files:
109
110
  - lib/pennmarc/helpers/subject.rb
110
111
  - lib/pennmarc/helpers/title.rb
111
112
  - lib/pennmarc/mappers.rb
113
+ - lib/pennmarc/mappings/dewey_classification.yml
112
114
  - lib/pennmarc/mappings/iso639-2-languages.yml
113
115
  - lib/pennmarc/mappings/iso639-3-languages.yml
116
+ - lib/pennmarc/mappings/loc_classification.yml
114
117
  - lib/pennmarc/mappings/locations.yml
115
118
  - lib/pennmarc/mappings/relator.yml
116
119
  - lib/pennmarc/parser.rb
@@ -120,6 +123,7 @@ files:
120
123
  - spec/fixtures/marcxml/test.xml
121
124
  - spec/lib/pennmarc/helpers/access_spec.rb
122
125
  - spec/lib/pennmarc/helpers/citation_spec.rb
126
+ - spec/lib/pennmarc/helpers/classification_spec.rb
123
127
  - spec/lib/pennmarc/helpers/creator_spec.rb
124
128
  - spec/lib/pennmarc/helpers/database_spec.rb
125
129
  - spec/lib/pennmarc/helpers/date_spec.rb