berkeley_library-tind 0.5.1 → 0.6.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 +4 -3
- data/CHANGES.md +6 -0
- data/README.md +121 -2
- data/berkeley_library-tind.gemspec +1 -0
- 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/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 +101 -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 +146 -0
- data/lib/berkeley_library/tind/mapping/field_catalog_util.rb +59 -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 +143 -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 +170 -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_subfield_util.rb +154 -0
- data/lib/berkeley_library/tind/mapping/util.rb +117 -0
- data/lib/berkeley_library/tind/mapping.rb +1 -0
- data/lib/berkeley_library/tind/module_info.rb +1 -1
- data/lib/berkeley_library/util/files.rb +1 -2
- 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 +57 -0
- data/spec/berkeley_library/tind/mapping/match_tind_field_spec.rb +25 -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 +150 -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_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/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 +263 -0
- data/spec/data/mapping/record_not_qualified.xml +36 -0
- metadata +105 -2
@@ -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,101 @@
|
|
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
|
+
|
13
|
+
class << self
|
14
|
+
attr_accessor :collection_parameter_hash
|
15
|
+
attr_accessor :is_barcode
|
16
|
+
attr_accessor :is_035_from_mms_id
|
17
|
+
end
|
18
|
+
|
19
|
+
# id can be:
|
20
|
+
# 1) Alma mms id
|
21
|
+
# 2) Oskicat No
|
22
|
+
# 3) BarCode No
|
23
|
+
# When alma record is nil or un-qualified, raise error
|
24
|
+
# Input datafields - an array of record specific datafields: for example, fft datafields, datafield 035 etc.
|
25
|
+
|
26
|
+
def base_tind_record(id, datafields, alma_record = nil)
|
27
|
+
marc_record = alma_record || alma_record_from(id)
|
28
|
+
|
29
|
+
raise ArgumentError, "#{id} has no Alma record." unless marc_record
|
30
|
+
|
31
|
+
unless Util.qualified_alma_record?(marc_record)
|
32
|
+
raise ArgumentError,
|
33
|
+
"#{id} belong to a host bibliographic record which should not be uploaded to TIND."
|
34
|
+
end
|
35
|
+
|
36
|
+
tind_record(id, marc_record, datafields)
|
37
|
+
end
|
38
|
+
|
39
|
+
# This is mainly for testing purpose, each collection can have a function to save it's record
|
40
|
+
def base_save(id, tind_record, file)
|
41
|
+
raise ArgumentError, "#{id} has no TIND record or not a qualified TIND record." unless tind_record
|
42
|
+
|
43
|
+
BerkeleyLibrary::TIND::MARC::XMLWriter.open(file) do |writer|
|
44
|
+
writer.write(tind_record)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def alma_record_from(id)
|
51
|
+
record_id = get_record_id(id)
|
52
|
+
raise ArgumentError, "#{id} gets no BarCode or RecordId from Alma module." unless record_id
|
53
|
+
|
54
|
+
record_id.get_marc_record
|
55
|
+
end
|
56
|
+
|
57
|
+
def get_record_id(id)
|
58
|
+
AlmaBase.is_barcode ? BerkeleyLibrary::Alma::BarCode.new(id) : BerkeleyLibrary::Alma::RecordId.parse(id)
|
59
|
+
end
|
60
|
+
|
61
|
+
def derived_tind_fields(mms_id)
|
62
|
+
tind_fields = []
|
63
|
+
tind_fields << TindField.f_902_d
|
64
|
+
|
65
|
+
hash = AlmaBase.collection_parameter_hash
|
66
|
+
tind_fields.concat ExternalTindField.tind_fields_from_collection_information(hash)
|
67
|
+
|
68
|
+
tind_fields.concat ExternalTindField.tind_mms_id_fields(mms_id)
|
69
|
+
|
70
|
+
f_035 = add_f_035(mms_id, hash)
|
71
|
+
tind_fields << f_035 if f_035
|
72
|
+
|
73
|
+
tind_fields
|
74
|
+
end
|
75
|
+
|
76
|
+
def tind_record(id, marc_record, datafields)
|
77
|
+
tindmarc = TindMarc.new(marc_record)
|
78
|
+
# get all derived tind_fields: 1) from collection information; 2) from id
|
79
|
+
mms_id = tindmarc.field_catalog.mms_id
|
80
|
+
logger.warn("#{id} has no Control Field 001") unless mms_id
|
81
|
+
|
82
|
+
tind_fields = derived_tind_fields(mms_id)
|
83
|
+
# add inputted record specific datafields
|
84
|
+
tind_fields.concat datafields
|
85
|
+
tindmarc.tind_external_datafields = tind_fields
|
86
|
+
|
87
|
+
# creete a tind marc record
|
88
|
+
tindmarc.tind_record
|
89
|
+
end
|
90
|
+
|
91
|
+
def add_f_035(mms_id, hash)
|
92
|
+
return nil unless mms_id && AlmaBase.is_035_from_mms_id
|
93
|
+
|
94
|
+
val_980 = hash['980'][0].strip
|
95
|
+
TindField.f_035_from_alma_id(mms_id, val_980)
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
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,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","a,b,c,d,q",a,,,,,,,,"1,_",,,,,
|
3
|
+
110,710,"6,e","6,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","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","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","a,b,c,d,q",a,,,,,,,,"1,_",,,,,
|
34
|
+
710,710,"6,e","6,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
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'berkeley_library/tind/mapping/tind_subfield_util'
|
2
|
+
require 'berkeley_library/tind/mapping/misc'
|
3
|
+
require 'berkeley_library/tind/mapping/field_catalog_util'
|
4
|
+
require 'berkeley_library/tind/mapping/match_tind_field'
|
5
|
+
|
6
|
+
module BerkeleyLibrary
|
7
|
+
module TIND
|
8
|
+
module Mapping
|
9
|
+
|
10
|
+
class DataFieldsCatalog
|
11
|
+
include Misc
|
12
|
+
include TindSubfieldUtil
|
13
|
+
include CsvMapper
|
14
|
+
include Util
|
15
|
+
include AdditionalDatafieldProcess
|
16
|
+
include FieldCatalogUtil
|
17
|
+
include MatchTindField
|
18
|
+
include BerkeleyLibrary::Logging
|
19
|
+
|
20
|
+
attr_reader :control_fields
|
21
|
+
attr_reader :data_fields_group
|
22
|
+
attr_reader :data_fields_880_group
|
23
|
+
attr_reader :data_fields_880_00
|
24
|
+
attr_reader :mms_id
|
25
|
+
|
26
|
+
def initialize(record)
|
27
|
+
@control_fields = []
|
28
|
+
@data_fields_group = []
|
29
|
+
@data_fields_880_group = []
|
30
|
+
@data_fields_880_00 = []
|
31
|
+
@mms_id = ''
|
32
|
+
|
33
|
+
@data_fields = []
|
34
|
+
@data_fields_880 = []
|
35
|
+
@alma_field_tags = []
|
36
|
+
|
37
|
+
init(record)
|
38
|
+
end
|
39
|
+
|
40
|
+
def init(record)
|
41
|
+
prepare_catalog(record)
|
42
|
+
@data_fields_group = prepare_group(@data_fields)
|
43
|
+
@data_fields_880_group = prepare_group(@data_fields_880)
|
44
|
+
@mms_id = alma_mms_id
|
45
|
+
end
|
46
|
+
|
47
|
+
def prepare_catalog(record)
|
48
|
+
clean_fields = clean_subfields(record.fields)
|
49
|
+
check_abnormal_formated_subfield6(clean_fields)
|
50
|
+
allocate_fields(clean_fields)
|
51
|
+
remove_fields_with_subject_fast
|
52
|
+
end
|
53
|
+
|
54
|
+
def remove_fields_with_subject_fast
|
55
|
+
@data_fields = exluding_fields_with_fast_subject(@data_fields)
|
56
|
+
@data_fields_880 = exluding_fields_with_fast_subject(@data_fields_880)
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def allocate_fields(fields)
|
62
|
+
fields.each do |f|
|
63
|
+
next if added_control_field?(f)
|
64
|
+
next if added_880_field?(f)
|
65
|
+
|
66
|
+
tag = f.tag
|
67
|
+
next unless (found_in_mapper? tag) && (no_pre_existed_field? tag)
|
68
|
+
|
69
|
+
@data_fields << f
|
70
|
+
@alma_field_tags << f.tag
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# 880 field with a subfield6 including a tag belong to origin tags defined in csv file
|
75
|
+
def qualified_880_field?(f)
|
76
|
+
return false unless referred_tag(f)
|
77
|
+
|
78
|
+
found_in_mapper?(referred_tag(f))
|
79
|
+
end
|
80
|
+
|
81
|
+
def added_control_field?(f)
|
82
|
+
return false unless ::MARC::ControlField.control_tag?(f.tag)
|
83
|
+
|
84
|
+
@control_fields << f
|
85
|
+
true
|
86
|
+
end
|
87
|
+
|
88
|
+
def added_880_field?(f)
|
89
|
+
return false unless f.tag == '880'
|
90
|
+
|
91
|
+
# adding 880 datafield with "non-subfield6" to "00" group for keeping this record in TIND
|
92
|
+
# with log information, to let users correcting or removing this datafield from TIND record
|
93
|
+
@data_fields_880_00 << f unless valid_subfield6?(f)
|
94
|
+
|
95
|
+
if qualified_880_field?(f)
|
96
|
+
subfield6_endwith_00?(f) ? @data_fields_880_00 << f : @data_fields_880 << f
|
97
|
+
end
|
98
|
+
|
99
|
+
true
|
100
|
+
end
|
101
|
+
|
102
|
+
def valid_subfield6?(f)
|
103
|
+
return true if subfield6?(f)
|
104
|
+
|
105
|
+
logger.warn("880 field has no subfield 6 #{f.inspect}")
|
106
|
+
|
107
|
+
false
|
108
|
+
end
|
109
|
+
|
110
|
+
# Is the origin_tag of a field has related from_tag in csv file?
|
111
|
+
def found_in_mapper?(tag)
|
112
|
+
from_tags.include? tag
|
113
|
+
end
|
114
|
+
|
115
|
+
# If tag is listed in csv_mapper.one_occurrence_tags
|
116
|
+
# Check pre_existed field of this tag
|
117
|
+
# make sure to keep the first datafield for an one_occurrence_tag defined in csv mapping file
|
118
|
+
# def no_pre_existed_field?(tag)
|
119
|
+
# # no one-occurrence defined in csv
|
120
|
+
# return true unless one_occurrence_tags.include? tag
|
121
|
+
|
122
|
+
# # Checking the exsisting regular fields include the one-occurrence field defined in the csv
|
123
|
+
# return false if @alma_field_tags.compact.include? tag
|
124
|
+
|
125
|
+
# true
|
126
|
+
# end
|
127
|
+
|
128
|
+
def no_pre_existed_field?(tag)
|
129
|
+
# no one-occurrence defined in csv
|
130
|
+
return true unless one_occurrence_tags.include? tag
|
131
|
+
|
132
|
+
# Checking the exsisting regular fields include the one-occurrence field defined in the csv
|
133
|
+
!(@alma_field_tags.compact.include? tag)
|
134
|
+
end
|
135
|
+
|
136
|
+
def alma_mms_id
|
137
|
+
f_001 = @control_fields.find { |f| f if f.tag == '001' }
|
138
|
+
return nil unless f_001
|
139
|
+
|
140
|
+
f_001.value
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module BerkeleyLibrary
|
2
|
+
module TIND
|
3
|
+
module Mapping
|
4
|
+
module FieldCatalogUtil
|
5
|
+
|
6
|
+
# Excluding fields: subfield2 = 'fast' and tag or refered tag(880 fields) started with '6':
|
7
|
+
def exluding_fields_with_fast_subject(fields)
|
8
|
+
fields.reject { |f| excluding_field?(f) }
|
9
|
+
end
|
10
|
+
|
11
|
+
def prepare_group(from_fields)
|
12
|
+
datafields_hash = { normal: [], pre_tag: [], pre_tag_subfield: [] }
|
13
|
+
from_fields.each do |f|
|
14
|
+
# a regular field tag, or a tag value from 880 field captured from subfield6
|
15
|
+
tag = origin_mapping_tag(f)
|
16
|
+
next unless tag
|
17
|
+
|
18
|
+
rule = rules[Util.tag_symbol(tag)]
|
19
|
+
|
20
|
+
assing_field(rule, f, datafields_hash)
|
21
|
+
end
|
22
|
+
|
23
|
+
datafields_hash
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def excluding_field?(f)
|
29
|
+
return false unless field_6xx?(f)
|
30
|
+
return false unless subfield2_fast(f)
|
31
|
+
|
32
|
+
true
|
33
|
+
end
|
34
|
+
|
35
|
+
# Both regular and 880 field: tag or refered tag started with '6'
|
36
|
+
def field_6xx?(f)
|
37
|
+
tag = origin_mapping_tag(f)
|
38
|
+
tag =~ /^6\d{2}$/
|
39
|
+
end
|
40
|
+
|
41
|
+
def subfield2_fast(f)
|
42
|
+
subject = f['2']
|
43
|
+
return false unless subject
|
44
|
+
|
45
|
+
subject.downcase == 'fast'
|
46
|
+
end
|
47
|
+
|
48
|
+
# f is either from field whose tag having a match in csv mapping file - 'from tag' column
|
49
|
+
def assing_field(rule, f, datafields_hash)
|
50
|
+
if rule.pre_existed_tag then datafields_hash[:pre_tag] << f
|
51
|
+
elsif rule.pre_existed_tag_subfield then datafields_hash[:pre_tag_subfield] << f
|
52
|
+
else datafields_hash[:normal] << f
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|