uw_catalog 0.0.3 → 0.0.4
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.
- data/lib/uw_catalog.rb +2 -0
- data/lib/uw_catalog/model/holding.rb +26 -4
- data/lib/uw_catalog/model/holding_marc.rb +599 -0
- data/lib/uw_catalog/version.rb +1 -1
- data/uw_catalog.gemspec +8 -7
- metadata +24 -23
data/lib/uw_catalog.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'data_mapper'
|
3
3
|
require 'yaml'
|
4
|
+
require 'marc'
|
4
5
|
|
5
6
|
require 'uw_catalog/model/bib_data'
|
6
7
|
require 'uw_catalog/model/location'
|
7
8
|
require 'uw_catalog/model/holding'
|
9
|
+
require 'uw_catalog/model/holding_marc'
|
8
10
|
require 'uw_catalog/model/item'
|
9
11
|
require 'uw_catalog/model/items_listing'
|
10
12
|
require 'uw_catalog/voyager_sql'
|
@@ -47,18 +47,42 @@ module UwCatalog
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
+
def library_has
|
51
|
+
ret = Hash.new
|
52
|
+
marc = HoldingMarc.new(@id)
|
53
|
+
val = marc.bound_copies
|
54
|
+
ret[:bound_copies] = val unless (val.nil? or val.empty?)
|
55
|
+
val = marc.indexes
|
56
|
+
ret[:indexes] = val unless (val.nil? or val.empty?)
|
57
|
+
val = marc.supplements
|
58
|
+
ret[:supplements] = val unless (val.nil? or val.empty?)
|
59
|
+
ret
|
60
|
+
end
|
61
|
+
|
50
62
|
def get_items_display(concise = false)
|
51
63
|
ret = Hash.new
|
52
64
|
return ret unless items.size > 0
|
53
65
|
|
54
|
-
|
66
|
+
ret.merge!(library_has)
|
67
|
+
|
68
|
+
status_list = item_statuses(concise)
|
69
|
+
ret[:status] = status_list
|
70
|
+
|
71
|
+
ret
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
def item_statuses(concise)
|
76
|
+
status_list = Array.new
|
77
|
+
return status_list unless items.size > 0
|
55
78
|
|
56
79
|
items.each do |item|
|
57
80
|
status_available, status_text = get_status(item)
|
58
81
|
status_list << {:item_id => item.id, :status_text => status_text,
|
59
|
-
:available => status_available, :copy_number=> item.copy_number,
|
82
|
+
:available => status_available, :copy_number=> item.copy_number,
|
60
83
|
:item_enum => item.item_enum}
|
61
84
|
end
|
85
|
+
|
62
86
|
if (concise)
|
63
87
|
total_count = status_list.size
|
64
88
|
status_list.keep_if{|i| i[:available] == false}.compact
|
@@ -68,8 +92,6 @@ module UwCatalog
|
|
68
92
|
end
|
69
93
|
|
70
94
|
status_list.sort! {|a,b| a[:item_enum].to_s <=> b[:item_enum].to_s} unless status_list.size < 1
|
71
|
-
ret[:status] = status_list
|
72
|
-
ret
|
73
95
|
end
|
74
96
|
|
75
97
|
def get_status(item)
|
@@ -0,0 +1,599 @@
|
|
1
|
+
module UwCatalog
|
2
|
+
class HoldingMarc
|
3
|
+
|
4
|
+
@@year_captions = ['(year)', '(Year)', 'year', '(year covered)']
|
5
|
+
@@month_captions = ['(month)', 'mo']
|
6
|
+
@@day_captions = ['(day)']
|
7
|
+
@@season_captions = ['(season)']
|
8
|
+
|
9
|
+
attr_reader :holding_id, :record
|
10
|
+
|
11
|
+
def initialize(holding_id)
|
12
|
+
@holding_id = holding_id
|
13
|
+
to_marc
|
14
|
+
end
|
15
|
+
|
16
|
+
def marc_record
|
17
|
+
@record
|
18
|
+
end
|
19
|
+
|
20
|
+
def bound_copies
|
21
|
+
bound_copies_internal
|
22
|
+
end
|
23
|
+
|
24
|
+
def indexes
|
25
|
+
indexes_internal
|
26
|
+
end
|
27
|
+
|
28
|
+
def indexes
|
29
|
+
indexes_internal
|
30
|
+
end
|
31
|
+
|
32
|
+
def supplements
|
33
|
+
supplements_internal
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
|
38
|
+
def new_issues
|
39
|
+
issues_received(0)
|
40
|
+
end
|
41
|
+
|
42
|
+
def issues_received(category)
|
43
|
+
sql = "select serial_issues.enumchron " +
|
44
|
+
"from line_item_copy_status " +
|
45
|
+
"inner join subscription on line_item_copy_status.line_item_id = subscription.line_item_id " +
|
46
|
+
"inner join component on subscription.subscription_id = component.subscription_id " +
|
47
|
+
"inner join serial_issues on component.component_id = serial_issues.component_id " +
|
48
|
+
"inner join issues_received on issues_received.issue_id = serial_issues.issue_id and component.component_id = issues_received.component_id " +
|
49
|
+
"where line_item_copy_status.mfhd_id = ? " +
|
50
|
+
"and component.category = ? " +
|
51
|
+
"and serial_issues.received = 1 " +
|
52
|
+
"and issues_received.opac_suppressed = 1"
|
53
|
+
repository(:UW).adapter.select(sql, @holding_id, category)
|
54
|
+
end
|
55
|
+
|
56
|
+
def to_marc
|
57
|
+
if @record.nil?
|
58
|
+
@record = MARC::Record.new_from_marc(marc_stream)
|
59
|
+
end
|
60
|
+
@record
|
61
|
+
end
|
62
|
+
|
63
|
+
def marc_stream
|
64
|
+
marc_stream = ''
|
65
|
+
sql = "select mfhd_data.record_segment from mfhd_master, mfhd_data where mfhd_master.mfhd_id=? and " +
|
66
|
+
" mfhd_master.mfhd_id = mfhd_data.mfhd_id"
|
67
|
+
mfhd_data_segments = repository(:UW).adapter.select(sql, @holding_id)
|
68
|
+
mfhd_data_segments.each do |segment|
|
69
|
+
marc_stream << segment
|
70
|
+
end
|
71
|
+
marc_stream
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
def classification_part
|
76
|
+
@record = to_marc
|
77
|
+
if @record['852'] and @record['852']['h']
|
78
|
+
@record['852']['h']
|
79
|
+
else
|
80
|
+
nil
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def location_code
|
85
|
+
@record['852']['b']
|
86
|
+
end
|
87
|
+
|
88
|
+
def indexes_internal
|
89
|
+
indexes_key_ordered_hash = Hash.new
|
90
|
+
indexes = Array.new
|
91
|
+
|
92
|
+
caption_and_pattern = get_caption_and_pattern_hash(@record, '855')
|
93
|
+
@record.find_all {|field| field.tag == '865' or field.tag == '868'}.each do |field|
|
94
|
+
|
95
|
+
if field.tag == '868'
|
96
|
+
|
97
|
+
# I don't trust that the data in subfield $8 will always be numeric floats.
|
98
|
+
begin
|
99
|
+
key = "%04d" % field['8'].to_i
|
100
|
+
str = field['a']
|
101
|
+
str += " " + field['z'] if field['z']
|
102
|
+
indexes_key_ordered_hash[key] = str
|
103
|
+
rescue
|
104
|
+
# Move on and don't include the data if it is improperly coded.
|
105
|
+
end
|
106
|
+
|
107
|
+
# Full blown MARC Format Holdings Data. Oy!
|
108
|
+
elsif field.tag == '865'
|
109
|
+
|
110
|
+
link_and_sequence = field['8']
|
111
|
+
|
112
|
+
if link_and_sequence
|
113
|
+
link = link_and_sequence.split('.')[0]
|
114
|
+
sequence = link_and_sequence.split('.')[1]
|
115
|
+
|
116
|
+
# Make sure that we know which caption/pattern to link to before processing the 865 field
|
117
|
+
if caption_and_pattern[link]
|
118
|
+
|
119
|
+
# Parse the data
|
120
|
+
enum_chron_hash = Hash.new
|
121
|
+
add_field_chronology_data_to_enum_chron_hash(caption_and_pattern, link, enum_chron_hash, field)
|
122
|
+
add_field_enumeration_data_to_enum_chron_hash(caption_and_pattern, link, enum_chron_hash, field)
|
123
|
+
|
124
|
+
# Format it
|
125
|
+
str = get_enum_chron_type_of_unit_and_notes(enum_chron_hash, field)
|
126
|
+
|
127
|
+
# I don't trust that the data in subfield $8 will always be numeric floats.
|
128
|
+
begin
|
129
|
+
key = ("%04d" % link.to_i) + "-" + ("%04d" % sequence.to_i)
|
130
|
+
indexes_key_ordered_hash[key] = str.strip
|
131
|
+
rescue
|
132
|
+
# Move on and don't include the data if it is improperly coded.
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
indexes_key_ordered_hash.keys.sort.each {|key| indexes << indexes_key_ordered_hash[key] }
|
140
|
+
|
141
|
+
issues_received(2).each { |new_index| indexes << new_index }
|
142
|
+
|
143
|
+
indexes
|
144
|
+
end
|
145
|
+
|
146
|
+
def supplements_internal
|
147
|
+
supplements_key_ordered_hash = Hash.new
|
148
|
+
supplements = Array.new
|
149
|
+
|
150
|
+
caption_and_pattern = get_caption_and_pattern_hash(@record, '854')
|
151
|
+
@record.find_all {|field| field.tag == '864' or field.tag == '867'}.each do |field|
|
152
|
+
|
153
|
+
if field.tag == '867'
|
154
|
+
|
155
|
+
# I don't trust that the data in subfield $8 will always be numeric floats.
|
156
|
+
begin
|
157
|
+
key = "%04d" % field['8'].to_i
|
158
|
+
str = field['a']
|
159
|
+
str += " " + field['z'] if field['z']
|
160
|
+
supplements_key_ordered_hash[key] = str
|
161
|
+
rescue
|
162
|
+
# Move on and don't include the data if it is improperly coded.
|
163
|
+
end
|
164
|
+
|
165
|
+
# Full blown MARC Format Holdings Data. Oy!
|
166
|
+
elsif field.tag == '864'
|
167
|
+
|
168
|
+
link_and_sequence = field['8']
|
169
|
+
if link_and_sequence
|
170
|
+
|
171
|
+
link = link_and_sequence.split('.')[0]
|
172
|
+
sequence = link_and_sequence.split('.')[1]
|
173
|
+
|
174
|
+
# Parse the data
|
175
|
+
enum_chron_hash = Hash.new
|
176
|
+
add_field_chronology_data_to_enum_chron_hash(caption_and_pattern, link, enum_chron_hash, field)
|
177
|
+
add_field_enumeration_data_to_enum_chron_hash(caption_and_pattern, link, enum_chron_hash, field)
|
178
|
+
|
179
|
+
# Format it
|
180
|
+
str = get_enum_chron_type_of_unit_and_notes(enum_chron_hash, field)
|
181
|
+
|
182
|
+
# I don't trust that the data in subfield $8 will always be numeric floats.
|
183
|
+
begin
|
184
|
+
key = ("%04d" % link.to_i) + "-" + ("%04d" % sequence.to_i)
|
185
|
+
supplements_key_ordered_hash[key] = str.strip
|
186
|
+
rescue
|
187
|
+
# Move on and don't include the data if it is improperly coded.
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
supplements_key_ordered_hash.keys.sort.each {|key| supplements << supplements_key_ordered_hash[key] }
|
194
|
+
|
195
|
+
issues_received(1).each { |new_supplement| supplements << new_supplement }
|
196
|
+
|
197
|
+
supplements
|
198
|
+
end
|
199
|
+
|
200
|
+
def get_enum_chron_type_of_unit_and_notes(enum_chron_hash, field)
|
201
|
+
str = ''
|
202
|
+
str += get_formatted_enumeration_info(enum_chron_hash)
|
203
|
+
str += " (#{get_formatted_chronology_info(enum_chron_hash)})" unless get_formatted_chronology_info(enum_chron_hash).strip == ""
|
204
|
+
enum_chron_hash[:type_of_unit] = field['o'] if field['o']
|
205
|
+
if enum_chron_hash[:type_of_unit]
|
206
|
+
str = remove_trailing_punctuation(str)
|
207
|
+
str += ", " unless str.strip == ""
|
208
|
+
str += enum_chron_hash[:type_of_unit]
|
209
|
+
end
|
210
|
+
enum_chron_hash[:notes] = field['z'] if field['z']
|
211
|
+
if enum_chron_hash[:notes]
|
212
|
+
str = remove_trailing_punctuation(str)
|
213
|
+
str += ", " + enum_chron_hash[:notes]
|
214
|
+
end
|
215
|
+
str
|
216
|
+
end
|
217
|
+
|
218
|
+
# remove trailing punctuation
|
219
|
+
def remove_trailing_punctuation(str)
|
220
|
+
str.strip!
|
221
|
+
if str.match(/[\/:,.]$/)
|
222
|
+
str[0,str.length - 1].strip
|
223
|
+
else
|
224
|
+
str.strip
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
# Get a hash that indicates which subfields hold volume, issue, year, month
|
229
|
+
# and day info.
|
230
|
+
def get_caption_and_pattern_hash(record, field_number)
|
231
|
+
caption_and_pattern = Hash.new
|
232
|
+
record.find_all {|field| field.tag == field_number}.each do |field|
|
233
|
+
caption_and_pattern[field['8']] = Hash.new
|
234
|
+
caption_and_pattern[field['8']][:chronology] = Hash.new
|
235
|
+
|
236
|
+
# Locate the chronology subfields
|
237
|
+
field.subfields.each do |subfield|
|
238
|
+
caption_and_pattern[field['8']][:chronology][:year] = subfield.code if @@year_captions.include?(subfield.value)
|
239
|
+
caption_and_pattern[field['8']][:chronology][:month] = subfield.code if @@month_captions.include?(subfield.value)
|
240
|
+
caption_and_pattern[field['8']][:chronology][:day] = subfield.code if @@day_captions.include?(subfield.value)
|
241
|
+
caption_and_pattern[field['8']][:chronology][:season] = subfield.code if @@season_captions.include?(subfield.value)
|
242
|
+
end
|
243
|
+
|
244
|
+
# Unless the chronology data is in subfield $a...
|
245
|
+
#
|
246
|
+
# From MARC Holdongs:
|
247
|
+
#
|
248
|
+
# When only Chronology captions are used on an item (that is, the item carries no enumeration),
|
249
|
+
# the Chronology captions are contained in the relevant enumeration caption subfields ($a-$h).
|
250
|
+
# If a Chronology caption is not to be used in a display of the 863-865 Enumeration and Chronology
|
251
|
+
# field, it is enclosed in parentheses, for example, (year).
|
252
|
+
#
|
253
|
+
# 853 03$81$a(year)
|
254
|
+
# 863 40$81.1$a1964-1981
|
255
|
+
# [An annual publication identified only by year.]
|
256
|
+
unless caption_and_pattern[field['8']][:chronology].values.include?('a')
|
257
|
+
# Create a Hash to hold the enum captions
|
258
|
+
caption_and_pattern[field['8']][:enumeration] = Hash.new
|
259
|
+
|
260
|
+
# Locate the enumeration subfields
|
261
|
+
caption_and_pattern[field['8']][:enumeration][:enum_level_1_caption] = field['a']
|
262
|
+
caption_and_pattern[field['8']][:enumeration][:enum_level_2_caption] = field['b']
|
263
|
+
caption_and_pattern[field['8']][:enumeration][:enum_level_1_caption_alt] = field['g']
|
264
|
+
caption_and_pattern[field['8']][:enumeration][:enum_level_2_caption_alt] = field['h']
|
265
|
+
end
|
266
|
+
end
|
267
|
+
caption_and_pattern
|
268
|
+
end
|
269
|
+
|
270
|
+
def add_field_chronology_data_to_enum_chron_hash(caption_and_pattern, link, enumeration_hash, field)
|
271
|
+
|
272
|
+
# To handle the possibility of missing caption and pattern fields...
|
273
|
+
if caption_and_pattern[link]
|
274
|
+
|
275
|
+
enumeration_hash[:start_year] = field[caption_and_pattern[link][:chronology][:year]].split('-').first if field[caption_and_pattern[link][:chronology][:year]]
|
276
|
+
enumeration_hash[:end_year] = field[caption_and_pattern[link][:chronology][:year]].split('-').last if field[caption_and_pattern[link][:chronology][:year]]
|
277
|
+
enumeration_hash[:start_month] = field[caption_and_pattern[link][:chronology][:month]].split('-').first if field[caption_and_pattern[link][:chronology][:month]]
|
278
|
+
enumeration_hash[:end_month] = field[caption_and_pattern[link][:chronology][:month]].split('-').last if field[caption_and_pattern[link][:chronology][:month]]
|
279
|
+
enumeration_hash[:start_day] = field[caption_and_pattern[link][:chronology][:day]].split('-').first if field[caption_and_pattern[link][:chronology][:day]]
|
280
|
+
enumeration_hash[:end_day] = field[caption_and_pattern[link][:chronology][:day]].split('-').last if field[caption_and_pattern[link][:chronology][:day]]
|
281
|
+
enumeration_hash[:season] = field[caption_and_pattern[link][:chronology][:season]] if field[caption_and_pattern[link][:chronology][:season]]
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
def add_field_enumeration_data_to_enum_chron_hash(caption_and_pattern, link, enumeration_hash, field)
|
286
|
+
|
287
|
+
# To handle the possibility of missing caption and pattern fields...
|
288
|
+
if caption_and_pattern[link]
|
289
|
+
if field['a'] and caption_and_pattern[link][:enumeration] and caption_and_pattern[link][:enumeration][:enum_level_1_caption] #and (field['a'] or field['g'])
|
290
|
+
enumeration_hash[:enum_level_1_caption] = caption_and_pattern[link][:enumeration][:enum_level_1_caption]
|
291
|
+
enumeration_hash[:enum_level_1_start] = field['a'].split('-').first
|
292
|
+
enumeration_hash[:enum_level_1_end] = field['a'].split('-').last
|
293
|
+
end
|
294
|
+
|
295
|
+
if caption_and_pattern[link][:enumeration] and caption_and_pattern[link][:enumeration][:enum_level_2_caption] and (field['b'] or field['h'])
|
296
|
+
enumeration_hash[:enum_level_2_caption] = caption_and_pattern[link][:enumeration][:enum_level_2_caption]
|
297
|
+
|
298
|
+
if field['b']
|
299
|
+
enumeration_hash[:enum_level_2_start] = field['b'].split('-', 2).first
|
300
|
+
enumeration_hash[:enum_level_2_end] = field['b'].split('-', 2).last
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
if field['g'] and caption_and_pattern[link][:enumeration] and caption_and_pattern[link][:enumeration][:enum_level_1_caption_alt]
|
305
|
+
enumeration_hash[:alt_enum_level_1_caption] = caption_and_pattern[link][:enumeration][:enum_level_1_caption_alt]
|
306
|
+
enumeration_hash[:alt_enum_level_1_start] = field['g'].split('-').first
|
307
|
+
enumeration_hash[:alt_enum_level_1_end] = field['g'].split('-').last
|
308
|
+
end
|
309
|
+
|
310
|
+
if field['h']
|
311
|
+
begin
|
312
|
+
raise("#{Time.now.strftime("%D %T")} Invalid enum link for: #{self.mfhd_id}") if caption_and_pattern[link][:enumeration].nil?
|
313
|
+
enumeration_hash[:alt_enum_level_2_caption] = caption_and_pattern[link][:enumeration][:enum_level_2_caption_alt]
|
314
|
+
enumeration_hash[:alt_enum_level_2_start] = field['h'].split('-').first
|
315
|
+
enumeration_hash[:alt_enum_level_2_end] = field['h'].split('-').last
|
316
|
+
|
317
|
+
rescue Exception => ex
|
318
|
+
enumeration_hash[:alt_enum_level_2_caption] = ""
|
319
|
+
File.open("log/cataloging_errors.log", "a") {|f| f.puts ex}
|
320
|
+
end
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
def bound_copies_internal
|
326
|
+
# This Hash stores all the enumeration chronology Strings for a given holdings record.
|
327
|
+
# The Hash keys will sort to the correct order.
|
328
|
+
bound_copies_key_ordered_hash = Hash.new
|
329
|
+
# This Array will be returned containing the enumeration chronology Strings.
|
330
|
+
bound_copies = Array.new
|
331
|
+
|
332
|
+
caption_and_pattern = get_caption_and_pattern_hash(@record, '853')
|
333
|
+
@record.find_all {|field| field.tag == '863' or field.tag == '866'}.each do |field|
|
334
|
+
|
335
|
+
# Freetext holdings field
|
336
|
+
if field.tag == '866'
|
337
|
+
|
338
|
+
# I don't trust that the data in subfield $8 will always be numeric floats.
|
339
|
+
begin
|
340
|
+
key = "%04d" % field['8'].to_i
|
341
|
+
raise("#{Time.now.strftime("%D %T")} Invalid 866 for: #{self.mfhd_id}") if field['a'].nil?
|
342
|
+
str = field['a']
|
343
|
+
str += " " + field['z'] if field['z']
|
344
|
+
bound_copies_key_ordered_hash[key] = str
|
345
|
+
rescue Exception => ex
|
346
|
+
File.open("log/cataloging_errors.log", "a") {|f| f.puts ex}
|
347
|
+
# Move on and don't include the data if it is improperly coded.
|
348
|
+
end
|
349
|
+
|
350
|
+
# Full blown MARC Format Holdings Data. Oy!
|
351
|
+
elsif field.tag == '863'
|
352
|
+
|
353
|
+
# Use the $8 field to determine which 853 caption each field links to.
|
354
|
+
link_and_sequence = field['8']
|
355
|
+
if link_and_sequence
|
356
|
+
link = link_and_sequence.split('.')[0]
|
357
|
+
sequence = link_and_sequence.split('.')[1]
|
358
|
+
|
359
|
+
# Build the enumeration_hash that will be used to format the data
|
360
|
+
enum_chron_hash = Hash.new
|
361
|
+
add_field_chronology_data_to_enum_chron_hash(caption_and_pattern, link, enum_chron_hash, field)
|
362
|
+
add_field_enumeration_data_to_enum_chron_hash(caption_and_pattern, link, enum_chron_hash, field)
|
363
|
+
|
364
|
+
# Format the data in the enumeration Hash into a human readable String
|
365
|
+
str = get_enum_chron_type_of_unit_and_notes(enum_chron_hash, field)
|
366
|
+
|
367
|
+
# I don't trust that the data in subfield $8 will always be numeric floats.
|
368
|
+
begin
|
369
|
+
key = ("%04d" % link.to_i) + "-" + ("%04d" % sequence.to_i)
|
370
|
+
bound_copies_key_ordered_hash[key] = str.strip if str.strip != ""
|
371
|
+
rescue
|
372
|
+
# Move on and don't include the data if it is improperly coded.
|
373
|
+
end
|
374
|
+
end
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
bound_copies_key_ordered_hash.keys.sort.each {|key| bound_copies << bound_copies_key_ordered_hash[key] }
|
379
|
+
|
380
|
+
|
381
|
+
bound_copies
|
382
|
+
end
|
383
|
+
|
384
|
+
def additional_copies
|
385
|
+
record = to_marc
|
386
|
+
additional_copies = Array.new
|
387
|
+
record.find_all {|field| field.tag == '899'}.each do |field|
|
388
|
+
additional_copies << field['a'] if field['a']
|
389
|
+
end
|
390
|
+
additional_copies
|
391
|
+
end
|
392
|
+
|
393
|
+
# Takes a hash like the following:
|
394
|
+
#
|
395
|
+
# {
|
396
|
+
# :enum_level_1_caption => "v.",
|
397
|
+
# :enum_level_2_caption => "no.",
|
398
|
+
# :enum_level_1_start => "173", :enum_level_1_end => "173",
|
399
|
+
# :enum_level_2_start => "2", :enum_level_2_end => "26",
|
400
|
+
# :start_year => "2009", :end_year => "2009",
|
401
|
+
# :start_month => "1", :end_month => "6",
|
402
|
+
# :start_day => "19", :end_day => "29"
|
403
|
+
# }
|
404
|
+
#
|
405
|
+
# and returns a string like this:
|
406
|
+
#
|
407
|
+
# v. 173, no. 2 - v. 173, no. 26
|
408
|
+
def get_formatted_enumeration_info(enumeration_hash)
|
409
|
+
enum = ''
|
410
|
+
|
411
|
+
# With two levels of enumeration
|
412
|
+
if enumeration_hash[:enum_level_2_start]
|
413
|
+
|
414
|
+
# Single Issue
|
415
|
+
if enumeration_hash[:enum_level_2_start] == enumeration_hash[:enum_level_2_end] and
|
416
|
+
enumeration_hash[:enum_level_1_start] == enumeration_hash[:enum_level_1_end]
|
417
|
+
enum += "#{enumeration_hash[:enum_level_1_caption]} #{enumeration_hash[:enum_level_1_start]}, " if enumeration_hash[:enum_level_1_start]
|
418
|
+
enum += "no. #{enumeration_hash[:enum_level_2_start]}"
|
419
|
+
# Multiple issues in a single volume
|
420
|
+
elsif enumeration_hash[:enum_level_2_start] != enumeration_hash[:enum_level_2_end] and
|
421
|
+
enumeration_hash[:enum_level_1_start] == enumeration_hash[:enum_level_1_end]
|
422
|
+
enum += "#{enumeration_hash[:enum_level_1_caption]} #{enumeration_hash[:enum_level_1_start]}, " if enumeration_hash[:enum_level_1_start]
|
423
|
+
enum += "#{enumeration_hash[:enum_level_2_caption]} #{enumeration_hash[:enum_level_2_start]} - "
|
424
|
+
enum += "#{enumeration_hash[:enum_level_2_caption]} #{enumeration_hash[:enum_level_2_end]}"
|
425
|
+
# Issue Range
|
426
|
+
else
|
427
|
+
enum += "#{enumeration_hash[:enum_level_1_caption]} #{enumeration_hash[:enum_level_1_start]}, " if enumeration_hash[:enum_level_1_start]
|
428
|
+
enum += "#{enumeration_hash[:enum_level_2_caption]} #{enumeration_hash[:enum_level_2_start]} - "
|
429
|
+
enum += "#{enumeration_hash[:enum_level_1_caption]} #{enumeration_hash[:enum_level_1_end]}, " if enumeration_hash[:enum_level_1_end]
|
430
|
+
enum += "#{enumeration_hash[:enum_level_2_caption]} #{enumeration_hash[:enum_level_2_end]}"
|
431
|
+
end
|
432
|
+
|
433
|
+
# First Level Enumeration Only
|
434
|
+
elsif enumeration_hash[:enum_level_1_start]
|
435
|
+
if enumeration_hash[:enum_level_1_start] == enumeration_hash[:enum_level_1_end]
|
436
|
+
enum += "#{enumeration_hash[:enum_level_1_caption]} #{enumeration_hash[:enum_level_1_start]}"
|
437
|
+
else
|
438
|
+
enum += "#{enumeration_hash[:enum_level_1_caption]} #{enumeration_hash[:enum_level_1_start]}"
|
439
|
+
enum += " - #{enumeration_hash[:enum_level_1_caption]} #{enumeration_hash[:enum_level_1_end]}" if enumeration_hash[:enum_level_1_end]
|
440
|
+
end
|
441
|
+
|
442
|
+
# Hacked data like this:
|
443
|
+
# 854 00 $8 2 $a Building for a secure future $i (year)
|
444
|
+
# 864 40 $8 2.1 $a $i 2001-2004
|
445
|
+
# Notice that there is a free text caption with no data
|
446
|
+
elsif enumeration_hash[:enum_level_1_caption] and !enumeration_hash[:enum_level_1_start]
|
447
|
+
enum += enumeration_hash[:enum_level_1_caption]
|
448
|
+
end
|
449
|
+
|
450
|
+
if enumeration_hash[:alt_enum_level_1_start]
|
451
|
+
enum += " (#{enumeration_hash[:alt_enum_level_1_caption]} "
|
452
|
+
|
453
|
+
if enumeration_hash[:alt_enum_level_1_start] == enumeration_hash[:alt_enum_level_1_end]
|
454
|
+
enum += "#{enumeration_hash[:alt_enum_level_1_start]}"
|
455
|
+
else
|
456
|
+
enum += "#{enumeration_hash[:alt_enum_level_1_start]}"
|
457
|
+
enum += "-#{enumeration_hash[:alt_enum_level_1_end]}" if enumeration_hash[:alt_enum_level_1_end]
|
458
|
+
end
|
459
|
+
|
460
|
+
if enumeration_hash[:alt_enum_level_2_start]
|
461
|
+
enum += ", #{enumeration_hash[:alt_enum_level_2_caption]} "
|
462
|
+
if enumeration_hash[:alt_enum_level_2_start] == enumeration_hash[:alt_enum_level_2_end]
|
463
|
+
enum += "#{enumeration_hash[:alt_enum_level_2_start]}"
|
464
|
+
else
|
465
|
+
enum += "#{enumeration_hash[:alt_enum_level_2_start]}"
|
466
|
+
enum += "-#{enumeration_hash[:alt_enum_level_2_end]}" if enumeration_hash[:alt_enum_level_2_end]
|
467
|
+
end
|
468
|
+
end
|
469
|
+
|
470
|
+
enum += ")"
|
471
|
+
end
|
472
|
+
|
473
|
+
enum
|
474
|
+
end
|
475
|
+
|
476
|
+
def get_season(season_code)
|
477
|
+
case season_code
|
478
|
+
when "21" then "Spring"
|
479
|
+
when "22" then "Summer"
|
480
|
+
when "23" then "Autumn"
|
481
|
+
when "24" then "Winter"
|
482
|
+
else season_code
|
483
|
+
end
|
484
|
+
end
|
485
|
+
|
486
|
+
def get_season_old(season_code)
|
487
|
+
case season_code
|
488
|
+
when "21" then " (Spring)"
|
489
|
+
when "22" then " (Summer)"
|
490
|
+
when "23" then " (Autumn)"
|
491
|
+
when "24" then " (Winter)"
|
492
|
+
else ""
|
493
|
+
end
|
494
|
+
end
|
495
|
+
|
496
|
+
# Takes a hash like the following:
|
497
|
+
#
|
498
|
+
# {
|
499
|
+
# :enum_level_1_caption => "v.",
|
500
|
+
# :enum_level_1_start => "173", :enum_level_1_end => "173",
|
501
|
+
# :enum_level_2_start => "2", :enum_level_2_end => "26",
|
502
|
+
# :start_year => "2009", :end_year => "2009",
|
503
|
+
# :start_month => "1", :end_month => "6",
|
504
|
+
# :start_day => "19", :end_day => "29"
|
505
|
+
# }
|
506
|
+
#
|
507
|
+
# and returns a string like this:
|
508
|
+
#
|
509
|
+
# January 19, 2009 - June 29, 2009
|
510
|
+
def get_formatted_chronology_info(enumeration_hash)
|
511
|
+
date = ''
|
512
|
+
|
513
|
+
# Begin with the literal values...
|
514
|
+
start_month = enumeration_hash[:start_month]
|
515
|
+
end_month = enumeration_hash[:end_month]
|
516
|
+
# Try to convert them into a normalized form.
|
517
|
+
begin
|
518
|
+
start_month = Integer(enumeration_hash[:start_month].gsub(/^0*/, ""))
|
519
|
+
start_month = Date::MONTHNAMES[start_month]
|
520
|
+
end_month = Integer(enumeration_hash[:end_month].gsub(/^0*/, ""))
|
521
|
+
end_month = Date::MONTHNAMES[end_month]
|
522
|
+
rescue
|
523
|
+
# don't error out, just use the literal value that came out of the holdings record.
|
524
|
+
end
|
525
|
+
|
526
|
+
if enumeration_hash[:start_day] and enumeration_hash[:start_month] and enumeration_hash[:start_year]
|
527
|
+
# Lone Issue
|
528
|
+
if enumeration_hash[:start_year] == enumeration_hash[:end_year] and
|
529
|
+
enumeration_hash[:start_month] == enumeration_hash[:end_month] and
|
530
|
+
enumeration_hash[:start_day] == enumeration_hash[:end_day]
|
531
|
+
date += "#{start_month} #{enumeration_hash[:start_day]}, #{enumeration_hash[:start_year]}"
|
532
|
+
else
|
533
|
+
date += "#{start_month} #{enumeration_hash[:start_day]}, #{enumeration_hash[:start_year]} -"
|
534
|
+
date += " #{end_month} #{enumeration_hash[:end_day]}, #{enumeration_hash[:end_year]}"
|
535
|
+
end
|
536
|
+
elsif enumeration_hash[:start_month] and enumeration_hash[:start_year]
|
537
|
+
|
538
|
+
# If the month values were outside of the 1-12 range
|
539
|
+
# check to see if they are 21-24 for Spring, Summer, Fall, Winter
|
540
|
+
start_month = get_season(enumeration_hash[:start_month]) unless start_month
|
541
|
+
end_month = get_season(enumeration_hash[:end_month]) unless end_month
|
542
|
+
|
543
|
+
date += start_month
|
544
|
+
date += "," if start_month.match(/\d/)
|
545
|
+
date += " #{enumeration_hash[:start_year]}"
|
546
|
+
|
547
|
+
# Single Issue.
|
548
|
+
# Don't display the end month and end year if they just output the same chronology substring
|
549
|
+
# as the start month and start year.
|
550
|
+
if start_month != end_month or enumeration_hash[:start_year] != enumeration_hash[:end_year]
|
551
|
+
date += " - #{end_month}"
|
552
|
+
date += "," if end_month[-1,1].match(/\d/)
|
553
|
+
date += " #{enumeration_hash[:end_year]}"
|
554
|
+
end
|
555
|
+
|
556
|
+
elsif enumeration_hash[:start_year]
|
557
|
+
if enumeration_hash[:end_year] and enumeration_hash[:start_year] != enumeration_hash[:end_year]
|
558
|
+
date += "#{enumeration_hash[:start_year]} - #{enumeration_hash[:end_year]}"
|
559
|
+
else
|
560
|
+
date += "#{enumeration_hash[:start_year]} "
|
561
|
+
end
|
562
|
+
end
|
563
|
+
|
564
|
+
date += "#{get_season(enumeration_hash[:season])}" if enumeration_hash[:season]
|
565
|
+
|
566
|
+
date.strip
|
567
|
+
end
|
568
|
+
|
569
|
+
def notes
|
570
|
+
record = to_marc
|
571
|
+
notes = record['852'].subfields.reduce(Array.new) do |notes, subfield|
|
572
|
+
notes << subfield.value if subfield.code == 'z'
|
573
|
+
notes
|
574
|
+
end
|
575
|
+
notes
|
576
|
+
end
|
577
|
+
|
578
|
+
def unavailable_items
|
579
|
+
MfhdItem.all(
|
580
|
+
:mfhd_id => mfhd_id,
|
581
|
+
MfhdItem.item.item_statuses.item_status_type_id.not => 1,
|
582
|
+
MfhdItem.item.item_statuses.item_status_type_id.not => 11,
|
583
|
+
MfhdItem.item.item_statuses.item_status_type_id.not => 19,
|
584
|
+
MfhdItem.item.item_statuses.item_status_type_id.not => 20)
|
585
|
+
end
|
586
|
+
|
587
|
+
def other_permanent_locations
|
588
|
+
return false if self.mfhd_items.size > 999
|
589
|
+
|
590
|
+
locations = []
|
591
|
+
self.mfhd_items.each do |mfhd_item|
|
592
|
+
unless(mfhd_item.item.perm_location == self.location_id || locations.include?(mfhd_item.item.perm_loc_display))
|
593
|
+
locations << mfhd_item.item.perm_loc_display
|
594
|
+
end
|
595
|
+
end
|
596
|
+
locations
|
597
|
+
end
|
598
|
+
end
|
599
|
+
end
|
data/lib/uw_catalog/version.rb
CHANGED
data/uw_catalog.gemspec
CHANGED
@@ -11,7 +11,6 @@ Gem::Specification.new do |gem|
|
|
11
11
|
gem.summary = %q{Use UW-Madison Voyager catalog data}
|
12
12
|
gem.homepage = "https://github.com/ekrylova/uw_catalog"
|
13
13
|
|
14
|
-
gem.add_dependency('data_mapper', '~>1.2.0')
|
15
14
|
|
16
15
|
gem.files = `git ls-files`.split($/)
|
17
16
|
gem.files = [
|
@@ -19,16 +18,17 @@ Gem::Specification.new do |gem|
|
|
19
18
|
# "Rakefile",
|
20
19
|
"uw_catalog.gemspec",
|
21
20
|
"lib/uw_catalog.rb",
|
22
|
-
"lib/uw_catalog/model/location.rb",
|
23
|
-
"lib/uw_catalog/model/holding.rb",
|
24
|
-
"lib/uw_catalog/model/bib_data.rb",
|
25
|
-
"lib/uw_catalog/model/item.rb",
|
26
|
-
"lib/uw_catalog/model/items_listing.rb",
|
27
21
|
"lib/uw_catalog/version.rb",
|
28
22
|
"lib/uw_catalog/catalog.rb",
|
29
23
|
"lib/uw_catalog/data_loader.rb",
|
30
24
|
"lib/uw_catalog/voyager_item_status.rb",
|
31
|
-
"lib/uw_catalog/voyager_sql.rb"
|
25
|
+
"lib/uw_catalog/voyager_sql.rb",
|
26
|
+
"lib/uw_catalog/model/location.rb",
|
27
|
+
"lib/uw_catalog/model/holding.rb",
|
28
|
+
"lib/uw_catalog/model/holding_marc.rb",
|
29
|
+
"lib/uw_catalog/model/bib_data.rb",
|
30
|
+
"lib/uw_catalog/model/item.rb",
|
31
|
+
"lib/uw_catalog/model/items_listing.rb"
|
32
32
|
]
|
33
33
|
gem.require_paths = ["lib"]
|
34
34
|
|
@@ -39,5 +39,6 @@ Gem::Specification.new do |gem|
|
|
39
39
|
gem.add_dependency('data_mapper', '~> 1.2.0')
|
40
40
|
gem.add_dependency('dm-oracle-adapter', '~> 1.2.0')
|
41
41
|
gem.add_dependency('ruby-oci8', '~> 2.1.3')
|
42
|
+
gem.add_dependency('marc', '~> 0.5.0')
|
42
43
|
|
43
44
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: uw_catalog
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,24 +9,8 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-07-
|
12
|
+
date: 2013-07-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
-
- !ruby/object:Gem::Dependency
|
15
|
-
name: data_mapper
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
|
-
requirements:
|
19
|
-
- - ~>
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version: 1.2.0
|
22
|
-
type: :runtime
|
23
|
-
prerelease: false
|
24
|
-
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
|
-
requirements:
|
27
|
-
- - ~>
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: 1.2.0
|
30
14
|
- !ruby/object:Gem::Dependency
|
31
15
|
name: rake
|
32
16
|
requirement: !ruby/object:Gem::Requirement
|
@@ -123,6 +107,22 @@ dependencies:
|
|
123
107
|
- - ~>
|
124
108
|
- !ruby/object:Gem::Version
|
125
109
|
version: 2.1.3
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: marc
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ~>
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.5.0
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ~>
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: 0.5.0
|
126
126
|
description: Gem for the University of Wisconsin Library Voyager catalog data
|
127
127
|
email:
|
128
128
|
- ekrylova@wisc.edu
|
@@ -132,16 +132,17 @@ extra_rdoc_files: []
|
|
132
132
|
files:
|
133
133
|
- uw_catalog.gemspec
|
134
134
|
- lib/uw_catalog.rb
|
135
|
-
- lib/uw_catalog/model/location.rb
|
136
|
-
- lib/uw_catalog/model/holding.rb
|
137
|
-
- lib/uw_catalog/model/bib_data.rb
|
138
|
-
- lib/uw_catalog/model/item.rb
|
139
|
-
- lib/uw_catalog/model/items_listing.rb
|
140
135
|
- lib/uw_catalog/version.rb
|
141
136
|
- lib/uw_catalog/catalog.rb
|
142
137
|
- lib/uw_catalog/data_loader.rb
|
143
138
|
- lib/uw_catalog/voyager_item_status.rb
|
144
139
|
- lib/uw_catalog/voyager_sql.rb
|
140
|
+
- lib/uw_catalog/model/location.rb
|
141
|
+
- lib/uw_catalog/model/holding.rb
|
142
|
+
- lib/uw_catalog/model/holding_marc.rb
|
143
|
+
- lib/uw_catalog/model/bib_data.rb
|
144
|
+
- lib/uw_catalog/model/item.rb
|
145
|
+
- lib/uw_catalog/model/items_listing.rb
|
145
146
|
homepage: https://github.com/ekrylova/uw_catalog
|
146
147
|
licenses: []
|
147
148
|
post_install_message:
|