berkeley_library-tind 0.5.1 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/build.yml +15 -3
- data/.gitignore +3 -0
- data/.idea/inspectionProfiles/Project_Default.xml +10 -0
- data/.idea/tind.iml +10 -9
- data/.rubocop.yml +1 -1
- data/CHANGES.md +15 -1
- data/README.md +165 -2
- data/berkeley_library-tind.gemspec +2 -2
- data/bin/alma-multiple-tind +50 -0
- data/bin/alma-single-tind +48 -0
- data/bin/save_tind_records +80 -0
- data/bin/tind-marc +73 -0
- data/lib/berkeley_library/tind/export/ods_exporter.rb +4 -6
- data/lib/berkeley_library/tind/mapping/additional_datafield_process.rb +128 -0
- data/lib/berkeley_library/tind/mapping/alma.rb +42 -0
- data/lib/berkeley_library/tind/mapping/alma_base.rb +108 -0
- data/lib/berkeley_library/tind/mapping/alma_multiple_tind.rb +31 -0
- data/lib/berkeley_library/tind/mapping/alma_single_tind.rb +28 -0
- data/lib/berkeley_library/tind/mapping/config.rb +44 -0
- data/lib/berkeley_library/tind/mapping/csv_mapper.rb +35 -0
- data/lib/berkeley_library/tind/mapping/csv_multiple_mapper.rb +41 -0
- data/lib/berkeley_library/tind/mapping/data/one_to_multiple_mapping.csv +4 -0
- data/lib/berkeley_library/tind/mapping/data/one_to_one_mapping.csv +39 -0
- data/lib/berkeley_library/tind/mapping/external_tind_field.rb +103 -0
- data/lib/berkeley_library/tind/mapping/field_catalog.rb +137 -0
- data/lib/berkeley_library/tind/mapping/field_catalog_util.rb +105 -0
- data/lib/berkeley_library/tind/mapping/match_tind_field.rb +77 -0
- data/lib/berkeley_library/tind/mapping/misc.rb +69 -0
- data/lib/berkeley_library/tind/mapping/multiple_rule.rb +36 -0
- data/lib/berkeley_library/tind/mapping/single_rule.rb +149 -0
- data/lib/berkeley_library/tind/mapping/tind_control_subfield.rb +59 -0
- data/lib/berkeley_library/tind/mapping/tind_field.rb +49 -0
- data/lib/berkeley_library/tind/mapping/tind_field_from_leader.rb +27 -0
- data/lib/berkeley_library/tind/mapping/tind_field_from_multiple_map.rb +59 -0
- data/lib/berkeley_library/tind/mapping/tind_field_from_single_map.rb +182 -0
- data/lib/berkeley_library/tind/mapping/tind_field_util.rb +112 -0
- data/lib/berkeley_library/tind/mapping/tind_marc.rb +134 -0
- data/lib/berkeley_library/tind/mapping/tind_record_util.rb +135 -0
- data/lib/berkeley_library/tind/mapping/tind_subfield_util.rb +154 -0
- data/lib/berkeley_library/tind/mapping/util.rb +136 -0
- data/lib/berkeley_library/tind/mapping.rb +1 -0
- data/lib/berkeley_library/tind/module_info.rb +1 -1
- data/spec/berkeley_library/tind/mapping/additional_datafield_process_spec.rb +35 -0
- data/spec/berkeley_library/tind/mapping/alma_base_spec.rb +115 -0
- data/spec/berkeley_library/tind/mapping/alma_multiple_tind_spec.rb +20 -0
- data/spec/berkeley_library/tind/mapping/alma_single_tind_spec.rb +87 -0
- data/spec/berkeley_library/tind/mapping/alma_spec.rb +28 -0
- data/spec/berkeley_library/tind/mapping/config_spec.rb +19 -0
- data/spec/berkeley_library/tind/mapping/csv_mapper_spec.rb +27 -0
- data/spec/berkeley_library/tind/mapping/csv_multiple_mapper_spec.rb +27 -0
- data/spec/berkeley_library/tind/mapping/external_tind_field_spec.rb +45 -0
- data/spec/berkeley_library/tind/mapping/field_catalog_spec.rb +78 -0
- data/spec/berkeley_library/tind/mapping/field_catalog_util_spec.rb +105 -0
- data/spec/berkeley_library/tind/mapping/match_tind_field_spec.rb +24 -0
- data/spec/berkeley_library/tind/mapping/misc_spec.rb +51 -0
- data/spec/berkeley_library/tind/mapping/multiple_rule_spec.rb +44 -0
- data/spec/berkeley_library/tind/mapping/single_rule_spec.rb +52 -0
- data/spec/berkeley_library/tind/mapping/tind_control_subfield_spec.rb +96 -0
- data/spec/berkeley_library/tind/mapping/tind_field_from_leader_spec.rb +21 -0
- data/spec/berkeley_library/tind/mapping/tind_field_from_multiple_map_spec.rb +31 -0
- data/spec/berkeley_library/tind/mapping/tind_field_from_single_map_spec.rb +167 -0
- data/spec/berkeley_library/tind/mapping/tind_field_spec.rb +60 -0
- data/spec/berkeley_library/tind/mapping/tind_field_util_spec.rb +68 -0
- data/spec/berkeley_library/tind/mapping/tind_marc_spec.rb +88 -0
- data/spec/berkeley_library/tind/mapping/tind_record_util_spec.rb +30 -0
- data/spec/berkeley_library/tind/mapping/tind_subfield_util_spec.rb +48 -0
- data/spec/berkeley_library/tind/mapping/util_spec.rb +56 -0
- data/spec/berkeley_library/tind/marc/xml_writer_spec.rb +24 -0
- data/spec/data/api/pre_assigned_response.json +15 -0
- data/spec/data/api/result_file.csv +3 -0
- data/spec/data/api/upload_file.json +1 -0
- data/spec/data/api/upload_response.json +13 -0
- data/spec/data/mapping/991032333019706532-sru.xml +216 -0
- data/spec/data/mapping/one_to_multiple_mapping.csv +4 -0
- data/spec/data/mapping/one_to_one_mapping.csv +39 -0
- data/spec/data/mapping/record.xml +266 -0
- data/spec/data/mapping/record_not_qualified.xml +36 -0
- metadata +89 -54
- data/lib/berkeley_library/util/files.rb +0 -39
@@ -0,0 +1,128 @@
|
|
1
|
+
# 1. Combine repeated fields
|
2
|
+
# 2. Remove characters pre_defined
|
3
|
+
module BerkeleyLibrary
|
4
|
+
module TIND
|
5
|
+
module Mapping
|
6
|
+
module AdditionalDatafieldProcess
|
7
|
+
|
8
|
+
# process 1: remove and combine repeated fields - defined in Config module
|
9
|
+
def remove_repeats(fields)
|
10
|
+
Config.no_duplicated_tags.each { |tag| remove_repeated_fields(tag, fields) }
|
11
|
+
fields
|
12
|
+
end
|
13
|
+
|
14
|
+
# process 2: remove charaters in subfields defined in Config module
|
15
|
+
def clean_subfields(fields)
|
16
|
+
fields.each do |f|
|
17
|
+
next unless field_in_tags?(f, Config.clean_tags)
|
18
|
+
|
19
|
+
clean_subfields_in_field(f)
|
20
|
+
end
|
21
|
+
fields
|
22
|
+
end
|
23
|
+
|
24
|
+
# 1. Find all datafield with the tag,
|
25
|
+
# if more than one found, combine repeated datafields which have a same tag into one
|
26
|
+
# 2. Find all 880 datafields with subfield6 referring to the tag,
|
27
|
+
# if more than one found, combine repeated datafields with one subfield 6,
|
28
|
+
# a related datafield will be modified to have the same sequence in subfield 6 as in this 880 subfield 6
|
29
|
+
def remove_repeated_fields(tag, fields)
|
30
|
+
repeated_fields = fields_on_tag(tag, fields)
|
31
|
+
remove_repeated(repeated_fields, fields)
|
32
|
+
|
33
|
+
repeated_880_fields = fields_880_on_subfield6_referredtag(tag, fields)
|
34
|
+
remove_repeated(repeated_880_fields, fields)
|
35
|
+
fields
|
36
|
+
end
|
37
|
+
|
38
|
+
# clean subfields of a datafield
|
39
|
+
def clean_subfields_in_field(field)
|
40
|
+
field.subfields.each { |sf| clean_subfield(sf) }
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def field_in_tags?(field, tags)
|
46
|
+
tag = field.tag
|
47
|
+
tag_to_match = tag == '880' ? referred_tag(field) : tag
|
48
|
+
return false unless tag_to_match
|
49
|
+
|
50
|
+
tags.include? tag_to_match
|
51
|
+
end
|
52
|
+
|
53
|
+
def fields_on_tag(tag, fields)
|
54
|
+
fields.select { |f| f.tag == tag }
|
55
|
+
end
|
56
|
+
|
57
|
+
def fields_880_on_subfield6_referredtag(tag, fields)
|
58
|
+
fields.select { |f| field_880_has_referred_tag?(tag, f) }
|
59
|
+
end
|
60
|
+
|
61
|
+
# Marc with tag in 'Config.no_duplicated_tags' are not supposed to have the same multiple subfields
|
62
|
+
# but sometime, sourc data error happens
|
63
|
+
# solution:
|
64
|
+
# taking the first subfield 6
|
65
|
+
# taking the first other subfield when there are multiple same subfields
|
66
|
+
# if 880 and regular field having unmatching subfield 6 in sequnce number, they will go to log file
|
67
|
+
# A user will check the log and correct data in Alma or TIND accordingly
|
68
|
+
def combined_subfields(fields)
|
69
|
+
sf_arr = []
|
70
|
+
subfield_6 = the_first_subfield6(fields)
|
71
|
+
sf_arr << subfield_6 if subfield_6
|
72
|
+
identical_subfields = no_duplicated_first_subfields(fields)
|
73
|
+
sf_arr.concat identical_subfields
|
74
|
+
sf_arr
|
75
|
+
end
|
76
|
+
|
77
|
+
# if there are multiple same subfields, pick up the first one, ignore the others
|
78
|
+
def no_duplicated_first_subfields(fields)
|
79
|
+
indentical_subfields = []
|
80
|
+
|
81
|
+
fields.each do |f|
|
82
|
+
subfields = subfields_without_subfield6(f)
|
83
|
+
subfields.each { |sf| indentical_subfields << sf if not_in_identical_subfields?(indentical_subfields, sf) }
|
84
|
+
end
|
85
|
+
|
86
|
+
indentical_subfields
|
87
|
+
end
|
88
|
+
|
89
|
+
def subfield_codes(subfields)
|
90
|
+
subfields.map(&:code)
|
91
|
+
end
|
92
|
+
|
93
|
+
def not_in_identical_subfields?(subfields, subfield)
|
94
|
+
!subfield_codes(subfields).include? subfield.code
|
95
|
+
end
|
96
|
+
|
97
|
+
# return a combined datafield from repeated datafields - with the same tag
|
98
|
+
def identical_field(repeated_fields)
|
99
|
+
tag = repeated_fields[0].tag
|
100
|
+
indicator = first_indicator(repeated_fields)
|
101
|
+
subfield_arr = combined_subfields(repeated_fields)
|
102
|
+
Util.datafield(tag, indicator, subfield_arr)
|
103
|
+
end
|
104
|
+
|
105
|
+
# remove repeated fields
|
106
|
+
def rm_fields(fields_tobe_removed, fields)
|
107
|
+
fields.delete_if { |f| fields_tobe_removed.include? f }
|
108
|
+
end
|
109
|
+
|
110
|
+
# suppose all repeated datafield have the same indictor
|
111
|
+
def first_indicator(fields)
|
112
|
+
indicator1 = fields[0].indicator1
|
113
|
+
indicator2 = fields[0].indicator2
|
114
|
+
[indicator1, indicator2]
|
115
|
+
end
|
116
|
+
|
117
|
+
# remove and keep one repeated datafield
|
118
|
+
def remove_repeated(repeated_fields, fields)
|
119
|
+
return fields unless repeated_fields.length > 1
|
120
|
+
|
121
|
+
rm_fields(repeated_fields, fields)
|
122
|
+
fields << identical_field(repeated_fields)
|
123
|
+
fields
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'marc'
|
2
|
+
|
3
|
+
module BerkeleyLibrary
|
4
|
+
module TIND
|
5
|
+
module Mapping
|
6
|
+
class Alma
|
7
|
+
include Util
|
8
|
+
|
9
|
+
attr_reader :record
|
10
|
+
|
11
|
+
def initialize(xml_file)
|
12
|
+
@record = alma_record(xml_file)
|
13
|
+
end
|
14
|
+
|
15
|
+
def control_field
|
16
|
+
@record.fields.each { |f| return f if f.tag.to_s == '008' }
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def field_880(subfield6_value)
|
21
|
+
@record.fields.each { |f| return f if f.tag.to_s == '880' && f['6'] == subfield6_value }
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def field(tag)
|
26
|
+
@record.fields.each { |f| return f if f.tag.to_s == tag }
|
27
|
+
nil
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def alma_record(xml_file)
|
33
|
+
file = File.open(xml_file)
|
34
|
+
content = file.readlines.map(&:chomp)
|
35
|
+
xml = content.join(' ')
|
36
|
+
Util.from_xml(xml)
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
# 902__$d derived from current date is added in this module
|
2
|
+
|
3
|
+
module BerkeleyLibrary
|
4
|
+
module TIND
|
5
|
+
module Mapping
|
6
|
+
module AlmaBase
|
7
|
+
include BerkeleyLibrary::Logging
|
8
|
+
|
9
|
+
@collection_parameter_hash = {}
|
10
|
+
@is_barcode = false
|
11
|
+
@is_035_from_mms_id = false
|
12
|
+
@including_origin_tags = []
|
13
|
+
@excluding_origin_tags = []
|
14
|
+
|
15
|
+
class << self
|
16
|
+
attr_accessor :collection_parameter_hash
|
17
|
+
attr_accessor :is_barcode
|
18
|
+
attr_accessor :is_035_from_mms_id
|
19
|
+
attr_accessor :including_origin_tags
|
20
|
+
attr_accessor :excluding_origin_tags
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
# id can be:
|
25
|
+
# 1) Alma mms id
|
26
|
+
# 2) Oskicat No
|
27
|
+
# 3) BarCode No
|
28
|
+
# When alma record is nil or un-qualified, raise error
|
29
|
+
# Input datafields - an array of record specific datafields: for example, fft datafields, datafield 035 etc.
|
30
|
+
|
31
|
+
def base_tind_record(id, datafields, alma_record = nil)
|
32
|
+
marc_record = alma_record || alma_record_from(id)
|
33
|
+
|
34
|
+
raise ArgumentError, "#{id} has no Alma record." unless marc_record
|
35
|
+
|
36
|
+
unless Util.qualified_alma_record?(marc_record)
|
37
|
+
raise ArgumentError,
|
38
|
+
"#{id} belong to a host bibliographic record which should not be uploaded to TIND."
|
39
|
+
end
|
40
|
+
|
41
|
+
tind_record(id, marc_record, datafields)
|
42
|
+
end
|
43
|
+
|
44
|
+
# This is mainly for testing purpose, each collection can have a function to save it's record
|
45
|
+
def base_save(id, tind_record, file)
|
46
|
+
raise ArgumentError, "#{id} has no TIND record or not a qualified TIND record." unless tind_record
|
47
|
+
|
48
|
+
BerkeleyLibrary::TIND::MARC::XMLWriter.open(file) do |writer|
|
49
|
+
writer.write(tind_record)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def alma_record_from(id)
|
56
|
+
record_id = get_record_id(id)
|
57
|
+
raise ArgumentError, "#{id} gets no BarCode or RecordId from Alma module." unless record_id
|
58
|
+
|
59
|
+
record_id.get_marc_record
|
60
|
+
end
|
61
|
+
|
62
|
+
def get_record_id(id)
|
63
|
+
AlmaBase.is_barcode ? BerkeleyLibrary::Alma::BarCode.new(id) : BerkeleyLibrary::Alma::RecordId.parse(id)
|
64
|
+
end
|
65
|
+
|
66
|
+
def derived_tind_fields(mms_id)
|
67
|
+
tind_fields = []
|
68
|
+
tind_fields << TindField.f_902_d
|
69
|
+
|
70
|
+
hash = AlmaBase.collection_parameter_hash
|
71
|
+
tind_fields.concat ExternalTindField.tind_fields_from_collection_information(hash)
|
72
|
+
|
73
|
+
tind_fields.concat ExternalTindField.tind_mms_id_fields(mms_id)
|
74
|
+
|
75
|
+
f_035 = add_f_035(mms_id, hash)
|
76
|
+
tind_fields << f_035 if f_035
|
77
|
+
|
78
|
+
tind_fields
|
79
|
+
end
|
80
|
+
|
81
|
+
def tind_record(id, marc_record, datafields)
|
82
|
+
return nil unless Util.collection_config_correct?
|
83
|
+
|
84
|
+
tindmarc = TindMarc.new(marc_record)
|
85
|
+
# get all derived tind_fields: 1) from collection information; 2) from id
|
86
|
+
mms_id = tindmarc.field_catalog.mms_id
|
87
|
+
logger.warn("#{id} has no Control Field 001") unless mms_id
|
88
|
+
|
89
|
+
tind_fields = derived_tind_fields(mms_id)
|
90
|
+
# add inputted record specific datafields
|
91
|
+
tind_fields.concat datafields
|
92
|
+
tindmarc.tind_external_datafields = tind_fields
|
93
|
+
|
94
|
+
# creete a tind marc record
|
95
|
+
tindmarc.tind_record
|
96
|
+
end
|
97
|
+
|
98
|
+
def add_f_035(mms_id, hash)
|
99
|
+
return nil unless mms_id && AlmaBase.is_035_from_mms_id
|
100
|
+
|
101
|
+
val_980 = hash['980'][0].strip
|
102
|
+
TindField.f_035_from_alma_id(mms_id, val_980)
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'marc'
|
2
|
+
require 'berkeley_library/tind'
|
3
|
+
require 'berkeley_library/alma'
|
4
|
+
module BerkeleyLibrary
|
5
|
+
module TIND
|
6
|
+
module Mapping
|
7
|
+
|
8
|
+
class AlmaMultipleTIND
|
9
|
+
include Util
|
10
|
+
include AlmaBase
|
11
|
+
include BerkeleyLibrary::Logging
|
12
|
+
|
13
|
+
# id can be
|
14
|
+
# 1) Alma mms id
|
15
|
+
# 2) Oskicat No
|
16
|
+
# 3) BarCode No
|
17
|
+
def initialize(id)
|
18
|
+
@id = id
|
19
|
+
@marc_record = alma_record_from(id)
|
20
|
+
end
|
21
|
+
|
22
|
+
# If alma record is nil or un-qualified, it returns nil
|
23
|
+
# Input datafields - an array of record specific datafields: for example, fft datafields, datafield 035 etc.
|
24
|
+
def record(datafields)
|
25
|
+
base_tind_record(@id, datafields, @marc_record)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'marc'
|
2
|
+
require 'berkeley_library/tind'
|
3
|
+
require 'berkeley_library/alma'
|
4
|
+
|
5
|
+
module BerkeleyLibrary
|
6
|
+
module TIND
|
7
|
+
module Mapping
|
8
|
+
class AlmaSingleTIND
|
9
|
+
include Util
|
10
|
+
include AlmaBase
|
11
|
+
include BerkeleyLibrary::Logging
|
12
|
+
|
13
|
+
def initialize; end
|
14
|
+
|
15
|
+
# id can be
|
16
|
+
# 1) Alma mms id
|
17
|
+
# 2) Oskicat No
|
18
|
+
# 3) BarCode No
|
19
|
+
# If alma record is nil or un-qualified, it returns nil
|
20
|
+
# Input datafields - an array of record specific datafields: for example, fft datafields, datafield 035 etc.
|
21
|
+
def record(id, datafields)
|
22
|
+
base_tind_record(id, datafields)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'marc'
|
2
|
+
|
3
|
+
module BerkeleyLibrary
|
4
|
+
module TIND
|
5
|
+
module Mapping
|
6
|
+
class Config
|
7
|
+
|
8
|
+
class << self
|
9
|
+
|
10
|
+
def one_to_one_map_file
|
11
|
+
ENV.fetch('ONE_TO_ONE_MAP_FILE', File.expand_path('data/one_to_one_mapping.csv', __dir__))
|
12
|
+
end
|
13
|
+
|
14
|
+
def one_to_multiple_map_file
|
15
|
+
ENV.fetch('ONE_TO_ONE_MAP_FILE', File.expand_path('data/one_to_multiple_mapping.csv', __dir__))
|
16
|
+
end
|
17
|
+
|
18
|
+
def no_duplicated_tags
|
19
|
+
%w[245 260 852 901 902 980].freeze
|
20
|
+
end
|
21
|
+
|
22
|
+
def punctuations
|
23
|
+
%w[, : ; / =].freeze
|
24
|
+
end
|
25
|
+
|
26
|
+
def clean_tags
|
27
|
+
%w[245 260 300].freeze
|
28
|
+
end
|
29
|
+
|
30
|
+
def collection_subfield_names
|
31
|
+
{
|
32
|
+
'336' => ['a'],
|
33
|
+
'852' => ['c'],
|
34
|
+
'980' => ['a'],
|
35
|
+
'982' => ['a', 'b'],
|
36
|
+
'991' => ['a']
|
37
|
+
}.freeze
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'csv'
|
2
|
+
require 'berkeley_library/tind/mapping/util'
|
3
|
+
|
4
|
+
module BerkeleyLibrary
|
5
|
+
module TIND
|
6
|
+
module Mapping
|
7
|
+
module CsvMapper
|
8
|
+
@rows = []
|
9
|
+
class << self
|
10
|
+
attr_accessor :rows
|
11
|
+
end
|
12
|
+
|
13
|
+
CsvMapper.rows = Util.csv_rows(Config.one_to_one_map_file)
|
14
|
+
|
15
|
+
def from_tags
|
16
|
+
CsvMapper.rows.map { |row| row[:tag_origin] }.compact
|
17
|
+
end
|
18
|
+
|
19
|
+
def rules
|
20
|
+
CsvMapper.rows.to_h { |row| ["tag_#{row[:tag_origin]}".to_sym, SingleRule.new(row)] }
|
21
|
+
end
|
22
|
+
|
23
|
+
# tags allow to keep the first datafield from original marc record
|
24
|
+
def one_occurrence_tags
|
25
|
+
tags = []
|
26
|
+
CsvMapper.rows.each do |row|
|
27
|
+
tags << row[:tag_origin] if row[:keep_one_if_multiple_available]
|
28
|
+
end
|
29
|
+
tags.compact
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'csv'
|
2
|
+
|
3
|
+
module BerkeleyLibrary
|
4
|
+
module TIND
|
5
|
+
module Mapping
|
6
|
+
module CsvMultipleMapper
|
7
|
+
@rows = []
|
8
|
+
class << self
|
9
|
+
attr_accessor :rows
|
10
|
+
end
|
11
|
+
|
12
|
+
CsvMultipleMapper.rows = Util.csv_rows(Config.one_to_multiple_map_file)
|
13
|
+
def from_tags
|
14
|
+
tags = []
|
15
|
+
CsvMultipleMapper.rows.each do |row|
|
16
|
+
tag = row[:tag_origin]
|
17
|
+
tags << tag unless tags.include?(tag)
|
18
|
+
end
|
19
|
+
tags
|
20
|
+
end
|
21
|
+
|
22
|
+
def rules
|
23
|
+
from_tags.to_h { |tag| [Util.tag_symbol(tag), rules_on_tag(tag)] }
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def rules_on_tag(tag)
|
29
|
+
rules = []
|
30
|
+
CsvMultipleMapper.rows.each do |row|
|
31
|
+
origin_tag = row[:tag_origin]
|
32
|
+
rules << MultipleRule.new(row) if origin_tag == tag
|
33
|
+
end
|
34
|
+
|
35
|
+
rules
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
tag_origin,tag_destination,subfield_single_from,subfield_single_to,order,subfield_combined_from_1,subfield_combined_to_1,symbol_1 ,subfield_combined_from_2,subfield_combined_to_2,symbol_2,subfield_combined_from_3,subfield_combined_to_3,symbol_3,New_indecator,Position_from,Position_to,Map_if_no_this_tag_existed,Map_if_no_this_tag_subfield_existed, Keep_one_if_multiple_available
|
2
|
+
100,700,"6,e","6,e","6,a,e","a,b,c,d,q",a,,,,,,,,"1,_",,,,,
|
3
|
+
110,710,"6,e","6,e","6,a,e","a,b",a,,,,,,,,"2,_",,,,,
|
4
|
+
111,711,6,6,,"a,c,d,e,f,n,p,t",a,,,,,,,,"_,_",,,,,
|
5
|
+
242,246,6,6,,"a,b,p,n",a,,,,,,,,,,,,,
|
6
|
+
245,245,"6,a","6,a","6,a,b,p","n,p",p,,,,,"b,f,k",b,,"_,_",,,,,
|
7
|
+
246,246,6,6,,"a,b,p,n",a,,,,,,,,"_,_",,,,,
|
8
|
+
250,250,"6,a","6,a",,,,,,,,,,,"_,_",,,,,
|
9
|
+
255,255,"6,a,b,c","6,a,b,c",,,,,,,,,,,"_,_",,,,,
|
10
|
+
260,260,"6,a,b,c","6,a,b,c",,,,,,,,,,,"_,_",,,,,
|
11
|
+
264,260,"6,a,b,c","6,a,b,c",,,,,,,,,,,"_,_",,,260,,1
|
12
|
+
300,300,"6,b,c","6,b,c","6,a,b,c","3,a",a,,,,,,,,"_,_",,,,,
|
13
|
+
351,505,6,6,,"a,b",a,,,,,,,,"_,_",,,,,
|
14
|
+
490,490,6,6,,"a,v",a,,,,,,,,"_,_",,,,,
|
15
|
+
500,500,"6,a","6,a",,,,,,,,,,,"_,_",,,,,
|
16
|
+
502,502,6,6,,"a,b,c,d,g,o",a,,,,,,,,"_,_",,,,,
|
17
|
+
505,505,6,6,,"a,g,r,t",a,,,,,,,,"_,_",,,,,
|
18
|
+
507,255,"6,a","6,a",,,,,,,,,,,"_,_",,,,255__a,
|
19
|
+
520,520,"6,a","6,a",,,,,,,,,,,"_,_",,,,,
|
20
|
+
522,522,"6,a","6,a",,,,,,,,,,,"_,_",,,,,
|
21
|
+
524,524,"6,a","6,a",,,,,,,,,,,"_,_",,,,,
|
22
|
+
536,536,"6,a","6,a",,,,,,,,,,,"_,_",,,,,
|
23
|
+
541,541,6,6,,"c,a,d",a,,,,,,,,"_,_",,,,,
|
24
|
+
545,545,"6,a","6,a",,,,,,,,,,,"_,_",,,,,
|
25
|
+
546,546,"6,a","6,a",,,,,,,,,,,"_,_",,,,,
|
26
|
+
600,600,6,6,,"a,b,c,d,f,j,k,l,m,n,o,p,q,r,s,t",a,,"x,y,z,v",a,a--a,,,,"_,_",,,,,
|
27
|
+
610,610,6,6,,"a,b,c,d,f,j,k,l,m,n,o,p,q,r,s,t",a,,"x,y,z,v",a,a--a,,,,"_,_",,,,,
|
28
|
+
611,611,6,6,,"a,b,c,d,f,j,k,l,m,n,o,p,q,r,s,t",a,,"x,y,z,v",a,a--a,,,,"_,_",,,,,
|
29
|
+
630,630,6,6,,"a,b,c,d,f,j,k,l,m,n,o,p,q,r,s,t",a,,"x,y,z,v",a,a--a,,,,"_,_",,,,,
|
30
|
+
650,650,6,6,,"a,b,c",a,,"x,y,z,v",a,a--a,,,,"_,_",,,,,
|
31
|
+
651,651,6,6,,a,a,,"x,y,z,v",a,a--a,,,,"_,_",,,,,
|
32
|
+
655,655,"6,2","6,2",,a,a,,"x,y,z,v",a,a--a,,,,"_,_",,,,,
|
33
|
+
700,700,"6,e","6,e","6,a,e","a,b,c,d,q",a,,,,,,,,"1,_",,,,,
|
34
|
+
710,710,"6,e","6,e","6,a,e","a,b",a,,,,,,,,"2,_",,,,,
|
35
|
+
711,711,6,6,,"a,c,d,e,f,n,p,t",a,,,,,,,,"_,_",,,,,
|
36
|
+
720,700,"6,a,e","6,a,e",,,,,,,,,,,"1,_",,,,,
|
37
|
+
752,651,6,6,,,,,"a,b,c,d,f,g",a,a--a,,,,"_,_",,,,,
|
38
|
+
773,773,"6,t,j,k,o","6,t,j,k,o",,,,,,,,,,,"_,_",,,,,
|
39
|
+
907,901,"6,a","6,m",,,,,,,,,,,"_,_",,,,,
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'marc'
|
2
|
+
|
3
|
+
# Derived fields from this module
|
4
|
+
# 1) From collection information:
|
5
|
+
# 336__$a
|
6
|
+
# 852__$c
|
7
|
+
# 982__$a,b
|
8
|
+
# 991__$a
|
9
|
+
# 2) From mms_id
|
10
|
+
# 901__$m
|
11
|
+
# 85641$u,y
|
12
|
+
|
13
|
+
module BerkeleyLibrary
|
14
|
+
module TIND
|
15
|
+
module Mapping
|
16
|
+
module ExternalTindField
|
17
|
+
class << self
|
18
|
+
include BerkeleyLibrary::Logging
|
19
|
+
|
20
|
+
def tind_fields_from_collection_information(hash)
|
21
|
+
raise ArgumentError, 'Collection parameters are incorrect.' unless valid_collection_hash?(hash)
|
22
|
+
|
23
|
+
collection_fields(hash)
|
24
|
+
end
|
25
|
+
|
26
|
+
def tind_mms_id_fields(mms_id)
|
27
|
+
raise ArgumentError, 'mms_id is nil' unless mms_id
|
28
|
+
|
29
|
+
mms_id_fields(mms_id)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def collection_fields(hash)
|
35
|
+
fields = []
|
36
|
+
hash.each_key do |tag|
|
37
|
+
tindfield = tindfield_on_tag(tag, hash)
|
38
|
+
fields << tindfield if tindfield
|
39
|
+
end
|
40
|
+
|
41
|
+
fields
|
42
|
+
end
|
43
|
+
|
44
|
+
def mms_id_fields(mms_id)
|
45
|
+
fields = []
|
46
|
+
fields << tind_field_901_m(mms_id)
|
47
|
+
fields << tind_field_856_4_1(mms_id)
|
48
|
+
end
|
49
|
+
|
50
|
+
def tind_field_901_m(alma_id)
|
51
|
+
::MARC::DataField.new('901', ' ', ' ', ['m', alma_id])
|
52
|
+
end
|
53
|
+
|
54
|
+
def tind_field_856_4_1(alma_id)
|
55
|
+
u = "https://search.library.berkeley.edu/discovery/fulldisplay?context=L&vid=01UCS_BER:UCB&docid=alma#{alma_id}"
|
56
|
+
y = 'View library catalog record.'
|
57
|
+
subfield1 = Util.subfield('u', u)
|
58
|
+
subfield2 = Util.subfield('y', y)
|
59
|
+
|
60
|
+
::MARC::DataField.new('856', '4', '1', subfield1, subfield2)
|
61
|
+
end
|
62
|
+
|
63
|
+
def tindfield_on_tag(tag, hash)
|
64
|
+
subfield_names = Config.collection_subfield_names[tag]
|
65
|
+
subfield_values = hash[tag]
|
66
|
+
return nil if subfield_values.empty?
|
67
|
+
|
68
|
+
subfields = tind_subfields(subfield_values, subfield_names)
|
69
|
+
Util.datafield(tag, [' ', ' '], subfields)
|
70
|
+
end
|
71
|
+
|
72
|
+
def tind_subfields(subfield_values, subfield_names)
|
73
|
+
subfields = []
|
74
|
+
subfield_values.each_with_index do |value, i|
|
75
|
+
name = subfield_names[i]
|
76
|
+
subfield = Util.subfield(name, value.strip)
|
77
|
+
subfields << subfield
|
78
|
+
end
|
79
|
+
subfields
|
80
|
+
end
|
81
|
+
|
82
|
+
def valid_collection_hash?(hash)
|
83
|
+
return false unless valid_item?(hash, '336', 1) &&
|
84
|
+
valid_item?(hash, '852', 1) && valid_item?(hash, '980', 1) && valid_item?(hash, '982', 2) && valid_991(hash)
|
85
|
+
|
86
|
+
true
|
87
|
+
end
|
88
|
+
|
89
|
+
def valid_item?(hash, key, num)
|
90
|
+
(hash.key? key) && (hash[key].length == num)
|
91
|
+
end
|
92
|
+
|
93
|
+
def valid_991(hash)
|
94
|
+
cout = hash['991'].length
|
95
|
+
[0, 1].include?(cout)
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
end
|