pennmarc 1.0.4 → 1.0.5

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: 50fd0383f0e78807f62f8abe784f75d8dace6e5b0ecf64877f79ad90b6d40354
4
- data.tar.gz: 3df19d10534fc787c55814e30bd1b066a8c5ea10e7da15f9b320c4500891e0be
3
+ metadata.gz: 9aa7e5cf7ade86fc51db4d35791eed5e3e38784e35d33bd9b82379a91ab3786e
4
+ data.tar.gz: 8b2668fbfd1fc645b203e23f12cfe5681014a870fa504f45c7c0b034682be325
5
5
  SHA512:
6
- metadata.gz: 277bb7c15e224c8134b8cea8b28de474d27022a1537904844af8c5542ff3f0080c37f13db38a5a9463a07453bcc403ccf346c2b5538c2fe26012df6a67dec24f
7
- data.tar.gz: 1ca8e643758f86aeabdfbeb1576f513c866ba5ef1a40b6edaa279f687af7644baf6b953db6f078548fc72ca99b75b6377db7d80d98a19059c797b6ad41b5f648
6
+ metadata.gz: aff6902488cb0d85bee32f3a3c5f4b613c8c5867ab3b594af40dad4c54e501b735b79fbed1ba8656c1144b87b58a9edc6e0ed961cc62603c7ccefb0c244b3117
7
+ data.tar.gz: e262a56ed0512de8c93c4ef0f94f87c322904d44ed845a64b9eb8dc58c8c3cc9c62675d52e314c5cd15eba0d7f4daea4725675af0c3e96ac7cb501a55074edf7
data/.rubocop_todo.yml CHANGED
@@ -1,36 +1,12 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config --auto-gen-only-exclude --exclude-limit 10000`
3
- # on 2023-08-25 13:55:25 UTC using RuboCop version 1.51.0.
3
+ # on 2023-11-08 20:19:45 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
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
- # Offense count: 2
10
- # This cop supports safe autocorrection (--autocorrect).
11
- # Configuration parameters: EnforcedStyle, IndentationWidth.
12
- # SupportedStyles: with_first_argument, with_fixed_indentation
13
- Layout/ArgumentAlignment:
14
- Exclude:
15
- - 'spec/lib/pennmarc/helpers/series_spec.rb'
16
-
17
- # Offense count: 1
18
- # This cop supports safe autocorrection (--autocorrect).
19
- # Configuration parameters: EnforcedStyle.
20
- # SupportedStyles: empty_lines, no_empty_lines
21
- Layout/EmptyLinesAroundBlockBody:
22
- Exclude:
23
- - 'spec/lib/pennmarc/helpers/identifer_spec.rb'
24
-
25
- # Offense count: 1
26
- # This cop supports safe autocorrection (--autocorrect).
27
- # Configuration parameters: EnforcedStyle.
28
- # SupportedStyles: final_newline, final_blank_line
29
- Layout/TrailingEmptyLines:
30
- Exclude:
31
- - 'spec/lib/pennmarc/helpers/identifer_spec.rb'
32
-
33
- # Offense count: 22
9
+ # Offense count: 23
34
10
  # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
35
11
  Metrics/AbcSize:
36
12
  Exclude:
@@ -38,6 +14,7 @@ Metrics/AbcSize:
38
14
  - 'lib/pennmarc/helpers/edition.rb'
39
15
  - 'lib/pennmarc/helpers/format.rb'
40
16
  - 'lib/pennmarc/helpers/genre.rb'
17
+ - 'lib/pennmarc/helpers/language.rb'
41
18
  - 'lib/pennmarc/helpers/location.rb'
42
19
  - 'lib/pennmarc/helpers/note.rb'
43
20
  - 'lib/pennmarc/helpers/production.rb'
@@ -66,6 +43,7 @@ Metrics/CyclomaticComplexity:
66
43
  - 'lib/pennmarc/helpers/edition.rb'
67
44
  - 'lib/pennmarc/helpers/format.rb'
68
45
  - 'lib/pennmarc/helpers/genre.rb'
46
+ - 'lib/pennmarc/helpers/language.rb'
69
47
  - 'lib/pennmarc/helpers/note.rb'
70
48
  - 'lib/pennmarc/helpers/production.rb'
71
49
  - 'lib/pennmarc/helpers/relation.rb'
@@ -104,6 +82,7 @@ Metrics/PerceivedComplexity:
104
82
  - 'lib/pennmarc/helpers/edition.rb'
105
83
  - 'lib/pennmarc/helpers/format.rb'
106
84
  - 'lib/pennmarc/helpers/genre.rb'
85
+ - 'lib/pennmarc/helpers/language.rb'
107
86
  - 'lib/pennmarc/helpers/note.rb'
108
87
  - 'lib/pennmarc/helpers/production.rb'
109
88
  - 'lib/pennmarc/helpers/series.rb'
@@ -152,16 +131,9 @@ RSpec/FilePath:
152
131
  Exclude:
153
132
  - 'spec/lib/pennmarc/parser_spec.rb'
154
133
 
155
- # Offense count: 4
134
+ # Offense count: 6
156
135
  # Configuration parameters: Max, AllowedGroups.
157
136
  RSpec/NestedGroups:
158
137
  Exclude:
138
+ - 'spec/lib/pennmarc/helpers/access_spec.rb'
159
139
  - 'spec/lib/pennmarc/helpers/format_spec.rb'
160
-
161
- # Offense count: 2
162
- # This cop supports safe autocorrection (--autocorrect).
163
- # Configuration parameters: Max, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns.
164
- # URISchemes: http, https
165
- Layout/LineLength:
166
- Exclude:
167
- - 'spec/lib/pennmarc/helpers/creator_spec.rb'
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PennMARC
4
+ # Methods for extracting how a record can be accessed
5
+ class Access < Helper
6
+ ONLINE = 'Online'
7
+ AT_THE_LIBRARY = 'At the library'
8
+
9
+ class << self
10
+ # Based primarily on the "enhanced MARC" fields added by Alma, determine if the record has
11
+ # electronic access or has physical holding, and is therefore "Online" or "At the library". If a record is "At the
12
+ # library", but has a link to a finding aid in the 856 field (matching certain criteria), also add 'Online' as an
13
+ # 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
+ # @param [MARC::Record] record
17
+ # @return [Array]
18
+ def facet(record)
19
+ acc = record.filter_map do |field|
20
+ next AT_THE_LIBRARY if field.tag == EnrichedMarc::TAG_HOLDING
21
+ next ONLINE if field.tag == EnrichedMarc::TAG_ELECTRONIC_INVENTORY
22
+ end
23
+
24
+ return acc if acc.size == 2 # return early if all values are already present
25
+
26
+ acc << ONLINE if acc.exclude?(ONLINE) && finding_aid_linkage?(record) # only check if ONLINE isn't already there
27
+ acc
28
+ end
29
+
30
+ private
31
+
32
+ # Check if a record contains an 856 entry for an online finding aid, meeting these criteria:
33
+ # 1. Indicator 1 is 4 (HTTP resource)
34
+ # 2. Indicator 2 is NOT 2 (indicating the linkage is to a "related" thing)
35
+ # 3. The URL specified in subfield u (URI) is a Penn Handle link
36
+ # See: https://www.loc.gov/marc/bibliographic/bd856.html
37
+ # @param [MARC::Record] record
38
+ # @return [Boolean]
39
+ def finding_aid_linkage?(record)
40
+ record.fields('856').filter_map do |field|
41
+ next if field.indicator2 == '2' || field.indicator1 != '4'
42
+
43
+ subz = subfield_values(field, 'z')
44
+ subfield_values(field, 'u').filter_map do |value|
45
+ return true if subz.include?('Finding aid') && value.include?('hdl.library.upenn.edu')
46
+ end
47
+ end
48
+ false
49
+ end
50
+ end
51
+ end
52
+ end
data/lib/pennmarc/util.rb CHANGED
@@ -5,6 +5,14 @@ require_relative 'heading_control'
5
5
  module PennMARC
6
6
  # class to hold "utility" methods used in MARC parsing methods
7
7
  module Util
8
+ # Check if a given record has a field present by tag (e.g., '041')
9
+ # @param [MARC::Record] record
10
+ # @param [String] marc_field
11
+ # @return [Boolean]
12
+ def field_defined?(record, marc_field)
13
+ record.select { |field| field.tag == marc_field }.any?
14
+ end
15
+
8
16
  # Join subfields from a field selected based on a provided proc
9
17
  # @param [MARC::DataField] field
10
18
  # @param [Proc] selector
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PennMARC
4
- VERSION = '1.0.4'
4
+ VERSION = '1.0.5'
5
5
  end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe 'PennMARC::Access' do
4
+ include MarcSpecHelpers
5
+
6
+ let(:helper) { PennMARC::Access }
7
+
8
+ describe '.facet' do
9
+ context 'with an electronic record' do
10
+ let(:record) do
11
+ marc_record fields: [marc_field(tag: 'prt')]
12
+ end
13
+
14
+ it 'returns expected access value' do
15
+ expect(helper.facet(record)).to contain_exactly(PennMARC::Access::ONLINE)
16
+ end
17
+ end
18
+
19
+ context 'with a print record' do
20
+ let(:record) do
21
+ marc_record fields: [marc_field(tag: 'hld')]
22
+ end
23
+
24
+ it 'returns expected access value' do
25
+ expect(helper.facet(record)).to contain_exactly(PennMARC::Access::AT_THE_LIBRARY)
26
+ end
27
+ end
28
+
29
+ context 'with a record containing a link to a finding aid (as a handle link)' do
30
+ let(:record) do
31
+ marc_record fields: [marc_field(tag: 'hld'),
32
+ marc_field(tag: '856', subfields: location_and_access_subfields, **indicators)]
33
+ end
34
+
35
+ context 'with an 856 describing a related record, not the record itself' do
36
+ let(:indicators) { { indicator1: '4', indicator2: '2' } }
37
+ let(:location_and_access_subfields) do
38
+ { z: 'Finding Aid', u: 'http://hdl.library.upenn.edu/1017/d/pacscl/UPENN_RBML_MsColl200' }
39
+ end
40
+
41
+ it 'does not include online access' do
42
+ expect(helper.facet(record)).not_to include PennMARC::Access::ONLINE
43
+ end
44
+ end
45
+
46
+ context 'with an 865 describing a link to a finding aid' do
47
+ let(:indicators) { { indicator1: '4', indicator2: '1' } }
48
+ let(:location_and_access_subfields) do
49
+ { z: 'Finding aid', u: 'http://hdl.library.upenn.edu/1017/d/pacscl/UPENN_RBML_MsColl200' }
50
+ end
51
+
52
+ it 'includes online access' do
53
+ expect(helper.facet(record)).to contain_exactly(PennMARC::Access::ONLINE, PennMARC::Access::AT_THE_LIBRARY)
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -17,9 +17,11 @@ describe 'PennMARC::Creator' do
17
17
  end
18
18
 
19
19
  it 'contains the expected search field values for a single author work' do
20
- expect(helper.search(record, relator_map: mapping)).to eq ['Name Surname http://cool.uri/12345 author 1900-2000.',
21
- 'Surname, Name http://cool.uri/12345 author 1900-2000.',
22
- 'Alternative Surname']
20
+ expect(helper.search(record, relator_map: mapping)).to eq [
21
+ 'Name Surname http://cool.uri/12345 author 1900-2000.',
22
+ 'Surname, Name http://cool.uri/12345 author 1900-2000.',
23
+ 'Alternative Surname'
24
+ ]
23
25
  end
24
26
  end
25
27
 
@@ -58,7 +60,9 @@ describe 'PennMARC::Creator' do
58
60
  end
59
61
 
60
62
  it 'returns values for the corporate author, including mapped relator code from ǂ4' do
61
- expect(helper.values(record, relator_map: mapping)).to contain_exactly 'Annual Report Leader author, Author.'
63
+ expect(helper.values(record, relator_map: mapping)).to contain_exactly(
64
+ 'Annual Report Leader author, Author.'
65
+ )
62
66
  end
63
67
  end
64
68
  end
@@ -146,7 +150,8 @@ describe 'PennMARC::Creator' do
146
150
  end
147
151
 
148
152
  it 'includes corporate author and creator values from allowed subfields' do
149
- expect(values).to contain_exactly 'Conference on Things Earth', 'Series of Things Earth', 'Thing Institute'
153
+ expect(values).to contain_exactly 'Conference on Things Earth', 'Series of Things Earth',
154
+ 'Thing Institute'
150
155
  end
151
156
  end
152
157
  end
@@ -39,7 +39,7 @@ describe 'PennMARC::Date' do
39
39
  it 'does not output any warning to STDOUT' do
40
40
  expect {
41
41
  helper.added(record)
42
- }.to_not output(a_string_including('Error parsing date in date added subfield')).to_stdout
42
+ }.not_to output(a_string_including('Error parsing date in date added subfield')).to_stdout
43
43
  end
44
44
  end
45
45
 
@@ -113,7 +113,6 @@ describe 'PennMARC::Identifier' do
113
113
  it 'does not return DOI values' do
114
114
  expect(helper.publisher_number_show(record)).not_to include('10.18574/9781479842865')
115
115
  expect(helper.publisher_number_show(record)).not_to include('doi')
116
-
117
116
  end
118
117
  end
119
118
 
@@ -19,9 +19,11 @@ describe 'PennMARC::Series' do
19
19
 
20
20
  describe '.show' do
21
21
  it 'returns the series' do
22
- expect(helper.show(record, relator_map: mapping)).to contain_exactly('Bean Bagatolvski 1997- bk. 1',
23
- 'Teachings of the feathered pillow',
24
- 'Учения пернатой подушки', 'Evil Giant Megacorp')
22
+ expect(helper.show(record, relator_map: mapping)).to contain_exactly(
23
+ 'Bean Bagatolvski 1997- bk. 1',
24
+ 'Teachings of the feathered pillow',
25
+ 'Учения пернатой подушки', 'Evil Giant Megacorp'
26
+ )
25
27
  end
26
28
  end
27
29
 
@@ -7,6 +7,18 @@ describe 'PennMARC::Util' do
7
7
  Class.new { extend PennMARC::Util }
8
8
  end
9
9
 
10
+ describe '.field_defined?' do
11
+ let(:record) { marc_record fields: [marc_field(tag: '100')] }
12
+
13
+ it 'returns true if the field is present in the record' do
14
+ expect(util.field_defined?(record, '100')).to be true
15
+ end
16
+
17
+ it 'returns false if the field is not present in the record' do
18
+ expect(util.field_defined?(record, '101')).to be false
19
+ end
20
+ end
21
+
10
22
  describe '.join_subfields' do
11
23
  let(:field) { marc_field subfields: { a: 'bad', '1': 'join', '3': '', '9': 'subfields' } }
12
24
 
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.4
4
+ version: 1.0.5
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-10-19 00:00:00.000000000 Z
13
+ date: 2023-11-09 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport
@@ -89,6 +89,7 @@ files:
89
89
  - lib/pennmarc/encoding_level.rb
90
90
  - lib/pennmarc/enriched_marc.rb
91
91
  - lib/pennmarc/heading_control.rb
92
+ - lib/pennmarc/helpers/access.rb
92
93
  - lib/pennmarc/helpers/citation.rb
93
94
  - lib/pennmarc/helpers/creator.rb
94
95
  - lib/pennmarc/helpers/database.rb
@@ -117,6 +118,7 @@ files:
117
118
  - lib/pennmarc/version.rb
118
119
  - pennmarc.gemspec
119
120
  - spec/fixtures/marcxml/test.xml
121
+ - spec/lib/pennmarc/helpers/access_spec.rb
120
122
  - spec/lib/pennmarc/helpers/citation_spec.rb
121
123
  - spec/lib/pennmarc/helpers/creator_spec.rb
122
124
  - spec/lib/pennmarc/helpers/database_spec.rb