pennmarc 1.0.8 → 1.0.9

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: 2dbb99dde790dda81ab9af2e7fdcc003a6ebc06a5ff447816705ef0836594a30
4
- data.tar.gz: 75ab2803be0bc910f62ecb177490ab4de09c13cadabbf5b55921197f7e713ef9
3
+ metadata.gz: 652039b781e2ce7442f628ca722f4fda59207d1d8171bfd2fad84d2c67f3c06f
4
+ data.tar.gz: 166bbf8498f673b36373671db47031ef8a2f4d5496ed1fddeee89718bd23e09c
5
5
  SHA512:
6
- metadata.gz: 755bce4545eedf08220d746d7a01a0d2e2d5a0abfc777cd94aff4a2e33d7f34a457f7bd181031bc934c8c2435a5c8e8fe5a20a301ba363974ce2dcafa6d81783
7
- data.tar.gz: 8613afeaf7fbe166fc1ce62acd792bcc85f89537ad0f515da140b811b17c2a62e3136fbeb8335758068ae672fb3a579f847cc6c12fcd2a696fa3358f85a10524
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
@@ -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.8'
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
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.8
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-07 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