stanford-mods 2.2.0 → 2.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop_todo.yml +358 -3
- data/.travis.yml +1 -4
- data/Gemfile +3 -4
- data/Rakefile +3 -3
- data/lib/marc_countries.rb +381 -381
- data/lib/stanford-mods.rb +1 -0
- data/lib/stanford-mods/coordinate.rb +14 -36
- data/lib/stanford-mods/date_parsing.rb +7 -8
- data/lib/stanford-mods/geo_spatial.rb +32 -12
- data/lib/stanford-mods/geo_utils.rb +28 -0
- data/lib/stanford-mods/imprint.rb +1 -1
- data/lib/stanford-mods/name.rb +7 -15
- data/lib/stanford-mods/origin_info.rb +35 -37
- data/lib/stanford-mods/physical_location.rb +6 -4
- data/lib/stanford-mods/searchworks.rb +149 -182
- data/lib/stanford-mods/searchworks_languages.rb +3 -3
- data/lib/stanford-mods/searchworks_subjects.rb +16 -18
- data/lib/stanford-mods/version.rb +1 -1
- data/spec/date_parsing_spec.rb +17 -19
- data/spec/fixtures/searchworks_imprint_data.rb +1 -1
- data/spec/fixtures/searchworks_pub_date_data.rb +1 -1
- data/spec/fixtures/spotlight_pub_date_data.rb +1 -1
- data/spec/geo_spatial_spec.rb +51 -5
- data/spec/imprint_spec.rb +4 -6
- data/spec/lib/stanford-mods/coordinate_spec.rb +0 -2
- data/spec/name_spec.rb +0 -2
- data/spec/origin_info_spec.rb +26 -28
- data/spec/physical_location_spec.rb +0 -3
- data/spec/searchworks_basic_spec.rb +1 -2
- data/spec/searchworks_format_spec.rb +35 -39
- data/spec/searchworks_pub_dates_spec.rb +0 -5
- data/spec/searchworks_spec.rb +1 -7
- data/spec/searchworks_subject_raw_spec.rb +0 -5
- data/spec/searchworks_subject_spec.rb +2 -9
- data/spec/searchworks_title_spec.rb +0 -2
- data/spec/spec_helper.rb +2 -5
- data/spec/sw_publication_spec.rb +1 -2
- data/stanford-mods.gemspec +1 -2
- metadata +4 -4
@@ -1,10 +1,12 @@
|
|
1
|
-
require 'logger'
|
2
1
|
require 'mods'
|
3
2
|
|
4
|
-
# Parsing MODS //location/physicalLocation for series, box, and folder for Special Collections
|
5
|
-
# This is not used by Searchworks, otherwise it would have been in the searchworks.rb file
|
6
3
|
module Stanford
|
7
4
|
module Mods
|
5
|
+
# Parsing MODS //location/physicalLocation for series, box, and folder for Special Collections.
|
6
|
+
# This is not used by Searchworks, otherwise it would have been in the searchworks.rb file.
|
7
|
+
# Note: mods_ng_xml_location.physicalLocation should find top level and relatedItem.
|
8
|
+
# Each method here expects to find at most ONE matching element. Subsequent potential matches
|
9
|
+
# are ignored.
|
8
10
|
class Record < ::Mods::Record
|
9
11
|
# return box number (note: single valued and might be something like 35A)
|
10
12
|
# data in location/physicalLocation or in relatedItem/location/physicalLocation
|
@@ -56,7 +58,7 @@ module Stanford
|
|
56
58
|
def physical_location_str
|
57
59
|
# _location.physicalLocation should find top level and relatedItem
|
58
60
|
loc = @mods_ng_xml._location.physicalLocation.map do |node|
|
59
|
-
node.text if node.text
|
61
|
+
node.text if node.text =~ /.*(Series)|(Accession)|(Folder)|(Box).*/i
|
60
62
|
end.compact
|
61
63
|
|
62
64
|
# There should only be one location
|
@@ -7,18 +7,28 @@ require 'mods'
|
|
7
7
|
# SearchWorks specific wranglings of MODS metadata as a mixin to the Stanford::Mods::Record object
|
8
8
|
module Stanford
|
9
9
|
module Mods
|
10
|
-
|
11
10
|
class Record < ::Mods::Record
|
11
|
+
attr_writer :druid
|
12
|
+
attr_writer :logger
|
13
|
+
|
14
|
+
def druid
|
15
|
+
@druid || 'Unknown item'
|
16
|
+
end
|
17
|
+
|
18
|
+
def logger
|
19
|
+
@logger ||= Logger.new(STDOUT)
|
20
|
+
end
|
21
|
+
alias sw_logger logger
|
12
22
|
|
13
23
|
# include langagues known to SearchWorks; try to error correct when possible (e.g. when ISO-639 disagrees with MARC standard)
|
14
24
|
def sw_language_facet
|
15
25
|
result = []
|
16
|
-
|
26
|
+
mods_ng_xml.language.each { |n|
|
17
27
|
# get languageTerm codes and add their translations to the result
|
18
28
|
n.code_term.each { |ct|
|
19
|
-
if ct.authority
|
29
|
+
if ct.authority =~ /^iso639/
|
20
30
|
begin
|
21
|
-
vals = ct.text.split(/[,|\ ]/).reject {|x| x.strip.
|
31
|
+
vals = ct.text.split(/[,|\ ]/).reject { |x| x.strip.empty? }
|
22
32
|
vals.each do |v|
|
23
33
|
iso639_val = ISO_639.find(v.strip).english_name
|
24
34
|
if SEARCHWORKS_LANGUAGES.has_value?(iso639_val)
|
@@ -32,7 +42,7 @@ module Stanford
|
|
32
42
|
p "Couldn't find english name for #{ct.text}"
|
33
43
|
end
|
34
44
|
else
|
35
|
-
vals = ct.text.split(/[,|\ ]/).reject {|x| x.strip.
|
45
|
+
vals = ct.text.split(/[,|\ ]/).reject { |x| x.strip.empty? }
|
36
46
|
vals.each do |v|
|
37
47
|
result << SEARCHWORKS_LANGUAGES[v.strip]
|
38
48
|
end
|
@@ -41,18 +51,17 @@ module Stanford
|
|
41
51
|
# add languageTerm text values
|
42
52
|
n.text_term.each { |tt|
|
43
53
|
val = tt.text.strip
|
44
|
-
result << val if val.
|
54
|
+
result << val if !val.empty? && SEARCHWORKS_LANGUAGES.has_value?(val)
|
45
55
|
}
|
46
56
|
|
47
57
|
# add language values that aren't in languageTerm subelement
|
48
|
-
if n.languageTerm.
|
58
|
+
if n.languageTerm.empty?
|
49
59
|
result << n.text if SEARCHWORKS_LANGUAGES.has_value?(n.text)
|
50
60
|
end
|
51
61
|
}
|
52
62
|
result.uniq
|
53
63
|
end # language_facet
|
54
64
|
|
55
|
-
|
56
65
|
# ---- AUTHOR ----
|
57
66
|
|
58
67
|
# @return [String] value for author_1xx_search field
|
@@ -73,18 +82,17 @@ module Stanford
|
|
73
82
|
# return the display_value_w_date for all <mods><name> elements that do not have type='personal'
|
74
83
|
# @return [Array<String>] values for author_other_facet
|
75
84
|
def sw_impersonal_authors
|
76
|
-
|
85
|
+
mods_ng_xml.plain_name.select { |n| n.type_at != 'personal' }.map { |n| n.display_value_w_date }
|
77
86
|
end
|
78
87
|
|
79
88
|
# @return [Array<String>] values for author_corp_display
|
80
89
|
def sw_corporate_authors
|
81
|
-
|
82
|
-
val
|
90
|
+
mods_ng_xml.plain_name.select { |n| n.type_at == 'corporate' }.map { |n| n.display_value_w_date }
|
83
91
|
end
|
84
92
|
|
85
93
|
# @return [Array<String>] values for author_meeting_display
|
86
94
|
def sw_meeting_authors
|
87
|
-
|
95
|
+
mods_ng_xml.plain_name.select { |n| n.type_at == 'conference' }.map { |n| n.display_value_w_date }
|
88
96
|
end
|
89
97
|
|
90
98
|
# Returns a sortable version of the main_author:
|
@@ -93,17 +101,15 @@ module Stanford
|
|
93
101
|
# @return [String] value for author_sort field
|
94
102
|
def sw_sort_author
|
95
103
|
# substitute java Character.MAX_CODE_POINT for nil main_author so missing main authors sort last
|
96
|
-
val = '' + (main_author_w_date ? main_author_w_date : "\u{10FFFF} ") + (
|
104
|
+
val = '' + (main_author_w_date ? main_author_w_date : "\u{10FFFF} ") + (sort_title ? sort_title : '')
|
97
105
|
val.gsub(/[[:punct:]]*/, '').strip
|
98
106
|
end
|
99
107
|
|
100
108
|
def main_author_w_date_test
|
101
109
|
result = nil
|
102
110
|
first_wo_role = nil
|
103
|
-
|
104
|
-
if n.role.
|
105
|
-
first_wo_role ||= n
|
106
|
-
end
|
111
|
+
plain_name.each { |n|
|
112
|
+
first_wo_role ||= n if n.role.empty?
|
107
113
|
n.role.each { |r|
|
108
114
|
if r.authority.include?('marcrelator') &&
|
109
115
|
(r.value.include?('Creator') || r.value.include?('Author'))
|
@@ -111,9 +117,7 @@ module Stanford
|
|
111
117
|
end
|
112
118
|
}
|
113
119
|
}
|
114
|
-
if !result && first_wo_role
|
115
|
-
result = first_wo_role.display_value_w_date
|
116
|
-
end
|
120
|
+
result = first_wo_role.display_value_w_date if !result && first_wo_role
|
117
121
|
result
|
118
122
|
end
|
119
123
|
|
@@ -128,38 +132,35 @@ module Stanford
|
|
128
132
|
|
129
133
|
# @return [String] value for title_245_search, title_full_display
|
130
134
|
def sw_full_title
|
131
|
-
outer_nodes =
|
135
|
+
outer_nodes = mods_ng_xml.title_info
|
132
136
|
outer_node = outer_nodes ? outer_nodes.first : nil
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
end
|
153
|
-
parts.sub!(/\.$/, '') if parts
|
154
|
-
|
155
|
-
result = parts ? preParts + ". " + parts : preParts
|
156
|
-
result += "." if !result.match(/[[:punct:]]$/)
|
157
|
-
result.strip!
|
158
|
-
result = nil if result.empty?
|
159
|
-
result
|
160
|
-
else
|
161
|
-
nil
|
137
|
+
return nil unless outer_node
|
138
|
+
nonSort = outer_node.nonSort.text.strip.empty? ? nil : outer_node.nonSort.text.strip
|
139
|
+
title = outer_node.title.text.strip.empty? ? nil : outer_node.title.text.strip
|
140
|
+
preSubTitle = nonSort ? [nonSort, title].compact.join(" ") : title
|
141
|
+
preSubTitle.sub!(/:$/, '') if preSubTitle # remove trailing colon
|
142
|
+
|
143
|
+
subTitle = outer_node.subTitle.text.strip
|
144
|
+
preParts = subTitle.empty? ? preSubTitle : preSubTitle + " : " + subTitle
|
145
|
+
preParts.sub!(/\.$/, '') if preParts # remove trailing period
|
146
|
+
|
147
|
+
partName = outer_node.partName.text.strip unless outer_node.partName.text.strip.empty?
|
148
|
+
partNumber = outer_node.partNumber.text.strip unless outer_node.partNumber.text.strip.empty?
|
149
|
+
partNumber.sub!(/,$/, '') if partNumber # remove trailing comma
|
150
|
+
if partNumber && partName
|
151
|
+
parts = partNumber + ", " + partName
|
152
|
+
elsif partNumber
|
153
|
+
parts = partNumber
|
154
|
+
elsif partName
|
155
|
+
parts = partName
|
162
156
|
end
|
157
|
+
parts.sub!(/\.$/, '') if parts
|
158
|
+
|
159
|
+
result = parts ? preParts + ". " + parts : preParts
|
160
|
+
result += "." unless result =~ /[[:punct:]]$/
|
161
|
+
result.strip!
|
162
|
+
result = nil if result.empty?
|
163
|
+
result
|
163
164
|
end
|
164
165
|
|
165
166
|
# like sw_full_title without trailing \,/;:.
|
@@ -167,12 +168,9 @@ module Stanford
|
|
167
168
|
# title_display = custom, removeTrailingPunct(245abdefghijklmnopqrstuvwxyz, [\\\\,/;:], ([A-Za-z]{4}|[0-9]{3}|\\)|\\,))
|
168
169
|
# @return [String] value for title_display (like title_full_display without trailing punctuation)
|
169
170
|
def sw_title_display
|
170
|
-
result = sw_full_title
|
171
|
-
|
172
|
-
|
173
|
-
result.strip!
|
174
|
-
end
|
175
|
-
result
|
171
|
+
result = sw_full_title
|
172
|
+
return nil unless result
|
173
|
+
result.sub(/[\.,;:\/\\]+$/, '').strip
|
176
174
|
end
|
177
175
|
|
178
176
|
# this includes all titles except
|
@@ -185,22 +183,22 @@ module Stanford
|
|
185
183
|
# @return [String] value for title_sort field
|
186
184
|
def sw_sort_title
|
187
185
|
# get nonSort piece
|
188
|
-
outer_nodes =
|
186
|
+
outer_nodes = mods_ng_xml.title_info
|
189
187
|
outer_node = outer_nodes ? outer_nodes.first : nil
|
190
188
|
if outer_node
|
191
189
|
nonSort = outer_node.nonSort.text.strip.empty? ? nil : outer_node.nonSort.text.strip
|
192
190
|
end
|
193
191
|
|
194
|
-
val = '' + (
|
192
|
+
val = '' + (sw_full_title ? sw_full_title : '')
|
195
193
|
val.sub!(Regexp.new("^" + Regexp.escape(nonSort)), '') if nonSort
|
196
194
|
val.gsub!(/[[:punct:]]*/, '').strip
|
197
195
|
val.squeeze(" ").strip
|
198
196
|
end
|
199
197
|
|
200
|
-
#remove trailing commas
|
198
|
+
# remove trailing commas
|
201
199
|
# @deprecated in favor of sw_title_display
|
202
200
|
def sw_full_title_without_commas
|
203
|
-
result =
|
201
|
+
result = sw_full_title
|
204
202
|
result.sub!(/,$/, '') if result
|
205
203
|
result
|
206
204
|
end
|
@@ -215,60 +213,55 @@ module Stanford
|
|
215
213
|
# see origin_info.rb (as all this information comes from top level originInfo element)
|
216
214
|
# ---- end PUBLICATION (place, year) ----
|
217
215
|
|
218
|
-
def sw_logger
|
219
|
-
@logger ||= Logger.new(STDOUT)
|
220
|
-
end
|
221
|
-
|
222
216
|
# select one or more format values from the controlled vocabulary here:
|
223
217
|
# http://searchworks-solr-lb.stanford.edu:8983/solr/select?facet.field=format&rows=0&facet.sort=index
|
224
218
|
# @return <Array[String]> value in the SearchWorks controlled vocabulary
|
225
219
|
# @deprecated - kept for backwards compatibility but not part of SW UI redesign work Summer 2014
|
226
220
|
# @deprecated: this is no longer used in SW, Revs or Spotlight Jan 2016
|
227
221
|
def format
|
222
|
+
types = term_values(:typeOfResource)
|
223
|
+
return [] unless types
|
224
|
+
genres = term_values(:genre)
|
225
|
+
issuance = term_values([:origin_info, :issuance])
|
228
226
|
val = []
|
229
|
-
types
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
thesis = ['thesis', 'Thesis']
|
268
|
-
val << 'Thesis' if genres && !(genres & thesis).empty?
|
269
|
-
when 'three dimensional object'
|
270
|
-
val << 'Other'
|
271
|
-
end
|
227
|
+
types.each do |type|
|
228
|
+
case type
|
229
|
+
when 'cartographic'
|
230
|
+
val << 'Map/Globe'
|
231
|
+
when 'mixed material'
|
232
|
+
val << 'Manuscript/Archive'
|
233
|
+
when 'moving image'
|
234
|
+
val << 'Video'
|
235
|
+
when 'notated music'
|
236
|
+
val << 'Music - Score'
|
237
|
+
when 'software, multimedia'
|
238
|
+
val << 'Computer File'
|
239
|
+
when 'sound recording-musical'
|
240
|
+
val << 'Music - Recording'
|
241
|
+
when 'sound recording-nonmusical', 'sound recording'
|
242
|
+
val << 'Sound Recording'
|
243
|
+
when 'still image'
|
244
|
+
val << 'Image'
|
245
|
+
when 'text'
|
246
|
+
val << 'Book' if issuance && issuance.include?('monographic')
|
247
|
+
book_genres = ['book chapter', 'Book chapter', 'Book Chapter',
|
248
|
+
'issue brief', 'Issue brief', 'Issue Brief',
|
249
|
+
'librettos', 'Librettos',
|
250
|
+
'project report', 'Project report', 'Project Report',
|
251
|
+
'technical report', 'Technical report', 'Technical Report',
|
252
|
+
'working paper', 'Working paper', 'Working Paper']
|
253
|
+
val << 'Book' if genres && !(genres & book_genres).empty?
|
254
|
+
conf_pub = ['conference publication', 'Conference publication', 'Conference Publication']
|
255
|
+
val << 'Conference Proceedings' if genres && !(genres & conf_pub).empty?
|
256
|
+
val << 'Journal/Periodical' if issuance && issuance.include?('continuing')
|
257
|
+
article = ['article', 'Article']
|
258
|
+
val << 'Journal/Periodical' if genres && !(genres & article).empty?
|
259
|
+
stu_proj_rpt = ['student project report', 'Student project report', 'Student Project report', 'Student Project Report']
|
260
|
+
val << 'Other' if genres && !(genres & stu_proj_rpt).empty?
|
261
|
+
thesis = ['thesis', 'Thesis']
|
262
|
+
val << 'Thesis' if genres && !(genres & thesis).empty?
|
263
|
+
when 'three dimensional object'
|
264
|
+
val << 'Other'
|
272
265
|
end
|
273
266
|
end
|
274
267
|
val.uniq
|
@@ -280,8 +273,8 @@ module Stanford
|
|
280
273
|
# resource type should be only Map and not include Software, multimedia.
|
281
274
|
# @return <Array[String]> value in the SearchWorks controlled vocabulary
|
282
275
|
def format_main
|
283
|
-
|
284
|
-
|
276
|
+
types = term_values(:typeOfResource)
|
277
|
+
return [] unless types
|
285
278
|
article_genres = ['article', 'Article',
|
286
279
|
'book chapter', 'Book chapter', 'Book Chapter',
|
287
280
|
'issue brief', 'Issue brief', 'Issue Brief',
|
@@ -295,98 +288,72 @@ module Stanford
|
|
295
288
|
'librettos', 'Librettos',
|
296
289
|
'thesis', 'Thesis'
|
297
290
|
]
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
end
|
291
|
+
val = []
|
292
|
+
genres = term_values(:genre)
|
293
|
+
issuance = term_values([:origin_info, :issuance])
|
294
|
+
types.each do |type|
|
295
|
+
case type
|
296
|
+
when 'cartographic'
|
297
|
+
val << 'Map'
|
298
|
+
val.delete 'Software/Multimedia'
|
299
|
+
when 'mixed material'
|
300
|
+
val << 'Archive/Manuscript'
|
301
|
+
when 'moving image'
|
302
|
+
val << 'Video'
|
303
|
+
when 'notated music'
|
304
|
+
val << 'Music score'
|
305
|
+
when 'software, multimedia'
|
306
|
+
if genres && (genres.include?('dataset') || genres.include?('Dataset'))
|
307
|
+
val << 'Dataset'
|
308
|
+
elsif !val.include?('Map')
|
309
|
+
val << 'Software/Multimedia'
|
310
|
+
end
|
311
|
+
when 'sound recording-musical'
|
312
|
+
val << 'Music recording'
|
313
|
+
when 'sound recording-nonmusical', 'sound recording'
|
314
|
+
val << 'Sound recording'
|
315
|
+
when 'still image'
|
316
|
+
val << 'Image'
|
317
|
+
when 'text'
|
318
|
+
val << 'Book' if genres && !(genres & article_genres).empty?
|
319
|
+
val << 'Book' if issuance && issuance.include?('monographic')
|
320
|
+
val << 'Book' if genres && !(genres & book_genres).empty?
|
321
|
+
val << 'Journal/Periodical' if issuance && issuance.include?('continuing')
|
322
|
+
val << 'Archived website' if genres && genres.include?('archived website')
|
323
|
+
when 'three dimensional object'
|
324
|
+
val << 'Object'
|
333
325
|
end
|
334
326
|
end
|
335
327
|
val.uniq
|
336
328
|
end
|
337
329
|
|
338
|
-
# return values for the genre facet in SearchWorks
|
339
330
|
# https://github.com/sul-dlss/stanford-mods/issues/66
|
340
331
|
# Limit genre values to Government document, Conference proceedings,
|
341
332
|
# Technical report and Thesis/Dissertation
|
342
|
-
# @return <Array[String]>
|
333
|
+
# @return <Array[String]> values for the genre facet in SearchWorks
|
343
334
|
def sw_genre
|
335
|
+
genres = term_values(:genre)
|
336
|
+
return [] unless genres
|
337
|
+
types = term_values(:typeOfResource)
|
344
338
|
val = []
|
345
|
-
genres
|
346
|
-
types
|
347
|
-
if genres
|
348
|
-
if genres.include?('thesis') || genres.include?('Thesis')
|
349
|
-
val << 'Thesis/Dissertation'
|
350
|
-
end
|
339
|
+
val << 'Thesis/Dissertation' if genres.include?('thesis') || genres.include?('Thesis')
|
340
|
+
if genres && types && types.include?('text')
|
351
341
|
conf_pub = ['conference publication', 'Conference publication', 'Conference Publication']
|
352
|
-
|
353
|
-
if types && types.include?('text')
|
354
|
-
val << 'Conference proceedings'
|
355
|
-
end
|
356
|
-
end
|
357
|
-
gov_pub = ['government publication', 'Government publication', 'Government Publication']
|
358
|
-
if !(genres & gov_pub).empty?
|
359
|
-
if types && types.include?('text')
|
360
|
-
val << 'Government document'
|
361
|
-
end
|
362
|
-
end
|
342
|
+
gov_pub = ['government publication', 'Government publication', 'Government Publication']
|
363
343
|
tech_rpt = ['technical report', 'Technical report', 'Technical Report']
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
end
|
368
|
-
end
|
344
|
+
val << 'Conference proceedings' unless (genres & conf_pub).empty?
|
345
|
+
val << 'Government document' unless (genres & gov_pub).empty?
|
346
|
+
val << 'Technical report' unless (genres & tech_rpt).empty?
|
369
347
|
end
|
370
348
|
val.uniq
|
371
349
|
end
|
372
350
|
|
373
351
|
# @return [String] value with the numeric catkey in it, or nil if none exists
|
374
352
|
def catkey
|
375
|
-
catkey =
|
376
|
-
|
377
|
-
|
378
|
-
end
|
379
|
-
nil
|
380
|
-
end
|
381
|
-
|
382
|
-
def druid=(new_druid)
|
383
|
-
@druid = new_druid
|
353
|
+
catkey = term_values([:record_info, :recordIdentifier])
|
354
|
+
return nil unless catkey && !catkey.empty?
|
355
|
+
catkey.first.tr('a', '') # ensure catkey is numeric only
|
384
356
|
end
|
385
|
-
|
386
|
-
def druid
|
387
|
-
@druid ? @druid : 'Unknown item'
|
388
|
-
end
|
389
|
-
|
390
357
|
end # class Record
|
391
358
|
end # Module Mods
|
392
359
|
end # Module Stanford
|