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.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build.yml +15 -3
  3. data/.gitignore +3 -0
  4. data/.idea/inspectionProfiles/Project_Default.xml +10 -0
  5. data/.idea/tind.iml +4 -3
  6. data/CHANGES.md +6 -0
  7. data/README.md +121 -2
  8. data/berkeley_library-tind.gemspec +1 -0
  9. data/bin/alma-multiple-tind +50 -0
  10. data/bin/alma-single-tind +48 -0
  11. data/bin/save_tind_records +80 -0
  12. data/bin/tind-marc +73 -0
  13. data/lib/berkeley_library/tind/mapping/additional_datafield_process.rb +128 -0
  14. data/lib/berkeley_library/tind/mapping/alma.rb +42 -0
  15. data/lib/berkeley_library/tind/mapping/alma_base.rb +101 -0
  16. data/lib/berkeley_library/tind/mapping/alma_multiple_tind.rb +31 -0
  17. data/lib/berkeley_library/tind/mapping/alma_single_tind.rb +28 -0
  18. data/lib/berkeley_library/tind/mapping/config.rb +44 -0
  19. data/lib/berkeley_library/tind/mapping/csv_mapper.rb +35 -0
  20. data/lib/berkeley_library/tind/mapping/csv_multiple_mapper.rb +41 -0
  21. data/lib/berkeley_library/tind/mapping/data/one_to_multiple_mapping.csv +4 -0
  22. data/lib/berkeley_library/tind/mapping/data/one_to_one_mapping.csv +39 -0
  23. data/lib/berkeley_library/tind/mapping/external_tind_field.rb +103 -0
  24. data/lib/berkeley_library/tind/mapping/field_catalog.rb +146 -0
  25. data/lib/berkeley_library/tind/mapping/field_catalog_util.rb +59 -0
  26. data/lib/berkeley_library/tind/mapping/match_tind_field.rb +77 -0
  27. data/lib/berkeley_library/tind/mapping/misc.rb +69 -0
  28. data/lib/berkeley_library/tind/mapping/multiple_rule.rb +36 -0
  29. data/lib/berkeley_library/tind/mapping/single_rule.rb +143 -0
  30. data/lib/berkeley_library/tind/mapping/tind_control_subfield.rb +59 -0
  31. data/lib/berkeley_library/tind/mapping/tind_field.rb +49 -0
  32. data/lib/berkeley_library/tind/mapping/tind_field_from_leader.rb +27 -0
  33. data/lib/berkeley_library/tind/mapping/tind_field_from_multiple_map.rb +59 -0
  34. data/lib/berkeley_library/tind/mapping/tind_field_from_single_map.rb +170 -0
  35. data/lib/berkeley_library/tind/mapping/tind_field_util.rb +112 -0
  36. data/lib/berkeley_library/tind/mapping/tind_marc.rb +134 -0
  37. data/lib/berkeley_library/tind/mapping/tind_subfield_util.rb +154 -0
  38. data/lib/berkeley_library/tind/mapping/util.rb +117 -0
  39. data/lib/berkeley_library/tind/mapping.rb +1 -0
  40. data/lib/berkeley_library/tind/module_info.rb +1 -1
  41. data/lib/berkeley_library/util/files.rb +1 -2
  42. data/spec/berkeley_library/tind/mapping/additional_datafield_process_spec.rb +35 -0
  43. data/spec/berkeley_library/tind/mapping/alma_base_spec.rb +115 -0
  44. data/spec/berkeley_library/tind/mapping/alma_multiple_tind_spec.rb +20 -0
  45. data/spec/berkeley_library/tind/mapping/alma_single_tind_spec.rb +87 -0
  46. data/spec/berkeley_library/tind/mapping/alma_spec.rb +28 -0
  47. data/spec/berkeley_library/tind/mapping/config_spec.rb +19 -0
  48. data/spec/berkeley_library/tind/mapping/csv_mapper_spec.rb +27 -0
  49. data/spec/berkeley_library/tind/mapping/csv_multiple_mapper_spec.rb +27 -0
  50. data/spec/berkeley_library/tind/mapping/external_tind_field_spec.rb +45 -0
  51. data/spec/berkeley_library/tind/mapping/field_catalog_spec.rb +78 -0
  52. data/spec/berkeley_library/tind/mapping/field_catalog_util_spec.rb +57 -0
  53. data/spec/berkeley_library/tind/mapping/match_tind_field_spec.rb +25 -0
  54. data/spec/berkeley_library/tind/mapping/misc_spec.rb +51 -0
  55. data/spec/berkeley_library/tind/mapping/multiple_rule_spec.rb +44 -0
  56. data/spec/berkeley_library/tind/mapping/single_rule_spec.rb +52 -0
  57. data/spec/berkeley_library/tind/mapping/tind_control_subfield_spec.rb +96 -0
  58. data/spec/berkeley_library/tind/mapping/tind_field_from_leader_spec.rb +21 -0
  59. data/spec/berkeley_library/tind/mapping/tind_field_from_multiple_map_spec.rb +31 -0
  60. data/spec/berkeley_library/tind/mapping/tind_field_from_single_map_spec.rb +150 -0
  61. data/spec/berkeley_library/tind/mapping/tind_field_spec.rb +60 -0
  62. data/spec/berkeley_library/tind/mapping/tind_field_util_spec.rb +68 -0
  63. data/spec/berkeley_library/tind/mapping/tind_marc_spec.rb +88 -0
  64. data/spec/berkeley_library/tind/mapping/tind_subfield_util_spec.rb +48 -0
  65. data/spec/berkeley_library/tind/mapping/util_spec.rb +56 -0
  66. data/spec/berkeley_library/tind/marc/xml_writer_spec.rb +24 -0
  67. data/spec/data/mapping/991032333019706532-sru.xml +216 -0
  68. data/spec/data/mapping/one_to_multiple_mapping.csv +4 -0
  69. data/spec/data/mapping/one_to_one_mapping.csv +39 -0
  70. data/spec/data/mapping/record.xml +263 -0
  71. data/spec/data/mapping/record_not_qualified.xml +36 -0
  72. metadata +105 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 24232cda73f63d90367c05453c325f468d6103d667e820671f19c251cabd3814
4
- data.tar.gz: 98d09880d886d8f351f0a038b8513aefe5dfe5c3a72108f634d79f7ad2485506
3
+ metadata.gz: ade606682d0d814a4debfbe0be2a6741ae72977d710511d5df70118569dea764
4
+ data.tar.gz: 2da4f7cd4b7f0c1cf6f8dcf9bf3346d89599e9130f28a185cb0cab0a37a39d3d
5
5
  SHA512:
6
- metadata.gz: 15c2560d8bee4b55fbb66a51f101afd731ef02bf542c7e4433ea0b095efa492a9b7429a7bb8929226079bb24a40a9f5e27432c6c855812a0a29d913d6877958e
7
- data.tar.gz: 6133181a93ef7a1204e6c73ea56a5fdee80f40817bfbe87c3c03ed063ec070e8c6f50dff732bbd987e30b929c14ba6e0b056a0b259f8327273f24e7048a069dc
6
+ metadata.gz: ed708269e8c628616c89643c49cb3394401febf8f9a0f4defde88abad17a8ac2f5b43663345cd0513aa2e7b02e41fb3475446f55aa7ad394aa83ad62ae114565
7
+ data.tar.gz: b4f851305ad936b9f7cb46c8a521358cdfff34f51aebfb6d121481545777476af8adce6c3b8c0042aeaeca2ee00a7d1826f955f46ee5ad1f11361c7ed1843b72
@@ -10,9 +10,21 @@ jobs:
10
10
  runs-on: ${{ matrix.os }}
11
11
 
12
12
  steps:
13
- - uses: actions/checkout@v2
14
- - uses: ruby/setup-ruby@v1
13
+ - name: Check out repository
14
+ uses: actions/checkout@v2
15
+
16
+ - name: Set up Ruby
17
+ uses: ruby/setup-ruby@v1
15
18
  with:
16
19
  ruby-version: ${{ matrix.ruby }}
17
20
  bundler-cache: true # runs 'bundle install' and caches installed gems automatically
18
- - run: bundle exec rake
21
+
22
+ - name: Run checks
23
+ run: bundle exec rake
24
+
25
+ - name: Upload artifacts
26
+ if: ${{ always() }}
27
+ uses: actions/upload-artifact@v3
28
+ with:
29
+ name: artifacts
30
+ path: artifacts/**
data/.gitignore CHANGED
@@ -7,6 +7,9 @@
7
7
  # Additional IDEA/RubyMine ignores
8
8
  .idea/.rakeTasks
9
9
 
10
+ # Visual Studio Code ignores
11
+ .vscode
12
+
10
13
  # Don't commit Gemfile.lock for libraries
11
14
  Gemfile.lock
12
15
 
@@ -10,6 +10,14 @@
10
10
  <inspection_tool class="LanguageDetectionInspection" enabled="false" level="WARNING" enabled_by_default="false" />
11
11
  <inspection_tool class="Rubocop" enabled="false" level="WARNING" enabled_by_default="false" />
12
12
  <inspection_tool class="RubyCaseWithoutElseBlockInspection" enabled="false" level="WARNING" enabled_by_default="false" />
13
+ <inspection_tool class="RubyClassMethodNamingConvention" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
14
+ <inspection_tool class="RubyClassModuleNamingConvention" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
15
+ <inspection_tool class="RubyClassVariableNamingConvention" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
16
+ <inspection_tool class="RubyConstantNamingConvention" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
17
+ <inspection_tool class="RubyGlobalVariableNamingConvention" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
18
+ <inspection_tool class="RubyInstanceMethodNamingConvention" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
19
+ <inspection_tool class="RubyInstanceVariableNamingConvention" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
20
+ <inspection_tool class="RubyLocalVariableNamingConvention" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
13
21
  <inspection_tool class="RubyMismatchedArgumentType" enabled="true" level="WARNING" enabled_by_default="true">
14
22
  <option name="myCheckNilability" value="false" />
15
23
  </inspection_tool>
@@ -28,6 +36,8 @@
28
36
  <inspection_tool class="RubyMismatchedVariableType" enabled="true" level="WARNING" enabled_by_default="true">
29
37
  <option name="myCheckNilability" value="false" />
30
38
  </inspection_tool>
39
+ <inspection_tool class="RubyNilAnalysis" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
40
+ <inspection_tool class="RubyParameterNamingConvention" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
31
41
  <inspection_tool class="RubyStringKeysInHashInspection" enabled="true" level="INFORMATION" enabled_by_default="true" />
32
42
  <inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
33
43
  <option name="processCode" value="true" />
data/.idea/tind.iml CHANGED
@@ -15,6 +15,7 @@
15
15
  <orderEntry type="library" scope="PROVIDED" name="addressable (v2.8.0, RVM: ruby-2.7.5) [gem]" level="application" />
16
16
  <orderEntry type="library" scope="PROVIDED" name="amazing_print (v1.4.0, RVM: ruby-2.7.5) [gem]" level="application" />
17
17
  <orderEntry type="library" scope="PROVIDED" name="ast (v2.4.2, RVM: ruby-2.7.5) [gem]" level="application" />
18
+ <orderEntry type="library" scope="PROVIDED" name="berkeley_library-alma (v0.0.4, RVM: ruby-2.7.5) [gem]" level="application" />
18
19
  <orderEntry type="library" scope="PROVIDED" name="berkeley_library-logging (v0.2.6, RVM: ruby-2.7.5) [gem]" level="application" />
19
20
  <orderEntry type="library" scope="PROVIDED" name="berkeley_library-marc (v0.3.1, RVM: ruby-2.7.5) [gem]" level="application" />
20
21
  <orderEntry type="library" scope="PROVIDED" name="berkeley_library-util (v0.1.1, RVM: ruby-2.7.5) [gem]" level="application" />
@@ -39,7 +40,7 @@
39
40
  <orderEntry type="library" scope="PROVIDED" name="http-cookie (v1.0.4, RVM: ruby-2.7.5) [gem]" level="application" />
40
41
  <orderEntry type="library" scope="PROVIDED" name="i18n (v1.10.0, RVM: ruby-2.7.5) [gem]" level="application" />
41
42
  <orderEntry type="library" scope="PROVIDED" name="ice_nine (v0.11.2, RVM: ruby-2.7.5) [gem]" level="application" />
42
- <orderEntry type="library" scope="PROVIDED" name="lograge (v0.11.2, RVM: ruby-2.7.5) [gem]" level="application" />
43
+ <orderEntry type="library" scope="PROVIDED" name="lograge (v0.12.0, RVM: ruby-2.7.5) [gem]" level="application" />
43
44
  <orderEntry type="library" scope="PROVIDED" name="loofah (v2.15.0, RVM: ruby-2.7.5) [gem]" level="application" />
44
45
  <orderEntry type="library" scope="PROVIDED" name="marc (v1.1.1, RVM: ruby-2.7.5) [gem]" level="application" />
45
46
  <orderEntry type="library" scope="PROVIDED" name="method_source (v1.0.0, RVM: ruby-2.7.5) [gem]" level="application" />
@@ -47,7 +48,7 @@
47
48
  <orderEntry type="library" scope="PROVIDED" name="mime-types-data (v3.2022.0105, RVM: ruby-2.7.5) [gem]" level="application" />
48
49
  <orderEntry type="library" scope="PROVIDED" name="minitest (v5.15.0, RVM: ruby-2.7.5) [gem]" level="application" />
49
50
  <orderEntry type="library" scope="PROVIDED" name="netrc (v0.11.0, RVM: ruby-2.7.5) [gem]" level="application" />
50
- <orderEntry type="library" scope="PROVIDED" name="nokogiri (v1.13.1, RVM: ruby-2.7.5) [gem]" level="application" />
51
+ <orderEntry type="library" scope="PROVIDED" name="nokogiri (v1.13.3, RVM: ruby-2.7.5) [gem]" level="application" />
51
52
  <orderEntry type="library" scope="PROVIDED" name="oj (v3.13.11, RVM: ruby-2.7.5) [gem]" level="application" />
52
53
  <orderEntry type="library" scope="PROVIDED" name="ougai (v1.9.1, RVM: ruby-2.7.5) [gem]" level="application" />
53
54
  <orderEntry type="library" scope="PROVIDED" name="parallel (v1.21.0, RVM: ruby-2.7.5) [gem]" level="application" />
@@ -110,7 +111,7 @@
110
111
  </RakeTaskImpl>
111
112
  <RakeTaskImpl description="Run all specs in spec directory, with coverage" fullCommand="coverage" id="coverage" />
112
113
  <RakeTaskImpl description="Run tests, check test coverage, check code style, check for vulnerabilities, build gem" fullCommand="default" id="default" />
113
- <RakeTaskImpl description="Build berkeley_library-tind.gemspec as berkeley_library-tind-0.4.3.gem" fullCommand="gem" id="gem" />
114
+ <RakeTaskImpl description="Build berkeley_library-tind.gemspec as berkeley_library-tind-0.6.0.gem" fullCommand="gem" id="gem" />
114
115
  <RakeTaskImpl description="Run RuboCop with auto-correct, and output results to console" fullCommand="ra" id="ra" />
115
116
  <RakeTaskImpl description="Run rubocop with HTML output" fullCommand="rubocop" id="rubocop" />
116
117
  <RakeTaskImpl id="rubocop">
data/CHANGES.md CHANGED
@@ -1,3 +1,9 @@
1
+ # 0.6.0 (2023-04-06)
2
+
3
+ - Adds `BerkeleyLibrary::TIND::Mapping` module to map MARC records from Alma to TIND.
4
+ - `BerkeleyLibrary::TIND::MARC::XMLWriter` now assumes that any object that response to `:write`
5
+ and `:close` is suffiently `IO`-like to write to.
6
+
1
7
  # 0.5.1 (2023-03-23)
2
8
 
3
9
  - Fix an issue where `BerkeleyLibrary::TIND::MARC::XMLWriter` would drop fields with nonstandard tags (e.g. `FFT` fields)
data/README.md CHANGED
@@ -30,7 +30,7 @@ To access the TIND API, you will need to set:
30
30
  it a "key", so that's the term we use here.)
31
31
 
32
32
  These can be set directly, via accessors in the `BerkeleyLibrary::TIND::Config` module;
33
- if they are not set, a value will be read from the environment, and if no
33
+ if they are not set, a value will be read from the environment, and if no
34
34
  value is present in the environment and Rails is loaded, from the Rails
35
35
  application configuration (`Rails.application.config`).
36
36
 
@@ -43,9 +43,18 @@ application configuration (`Rails.application.config`).
43
43
  object, but will always be returned as a `URI` object, and an invalid
44
44
  string setting will raise `URI::InvalidURIError`.
45
45
 
46
+ ### Alma configuration
47
+
48
+ When mapping Alma records to TIND (see below), this gem uses
49
+ [`berkeley_library-alma`](https://github.com/BerkeleyLibrary/alma) to load
50
+ Alma records. The scripts in the `bin` directory use the default Alma
51
+ configuration; see the `berkeley_library-alma`
52
+ [README](https://github.com/BerkeleyLibrary/alma#configuration) for
53
+ details.
54
+
46
55
  ## Command-line tool: `tind-export`
47
56
 
48
- The `tind-export` command allows you to list TIND collections, or to
57
+ The `tind-export` command allows you to list TIND collections, or to
49
58
  export a TIND collection from the command line. (If the gem is installed,
50
59
  `tind-export` should be in your `$PATH`. If you've cloned the gem source,
51
60
  you can invoke it with `bin/tind-export` from the project root directory.)
@@ -85,3 +94,113 @@ For the full list of options, type `tind-export --help`. Note that you can set
85
94
  the TIND base URL and API key either via the environment, as above, or as options
86
95
  passed to the `tind-export` command. If both an explicit option and an environment
87
96
  variable are set for either, the explicit option takes precedence.
97
+
98
+ ## Mapping MARC records from Alma to TIND
99
+
100
+ ### Transforming Class:
101
+
102
+ 1. BerkeleyLibrary::TIND::Mapping::AlmaSingleTIND (Transforming one Alma record => One TIND record)
103
+ 2. BerkeleyLibrary::TIND::Mapping::AlmaMultipleTIND (Transforming one Alma record => Multiple TIND records)
104
+
105
+ ### Source of TIND fields
106
+
107
+ 1. Mapped from an Alma record (automatically)
108
+
109
+ 2. Derived from collection information, mms_id, and date (automatically)
110
+
111
+ - 336$a
112
+ - 852$c
113
+ - 980$a
114
+ - 982$a,$b
115
+ - 991$a - (optional)
116
+ - 902$d
117
+ - 901$m
118
+ - 85641$u,$y
119
+
120
+ 3. Added at the time of transforming TIND record (fields of a collection or its record)
121
+
122
+ - FFT
123
+ - 035$a
124
+ - 998$a
125
+ - ...
126
+
127
+ ### Example
128
+
129
+ 1. Setup collection information
130
+
131
+ - 336: type of resource
132
+ - 852: collection's repository name
133
+ - 980: collection's 980 value
134
+ - 982: collection's short name and long name
135
+ - 991: collection' restricted name (optional)
136
+
137
+ ``` ruby
138
+
139
+ def setup_collection
140
+ BerkeleyLibrary::TIND::Mapping::AlmaBase.collection_parameter_hash = {
141
+ '336' => ['Image'],
142
+ '852' => ['East Asian Library'],
143
+ '980' => ['pre_1912'],
144
+ '982' => ['Pre 1912 Chinese Materials - short name', 'Pre 1912 Chinese Materials - long name'],
145
+ '991' => []
146
+ }
147
+
148
+ # BerkeleyLibrary::TIND::Mapping::AlmaBase.is_035_from_mms_id = true
149
+
150
+ # Flag on getting Alma record using Barcode
151
+ BerkeleyLibrary::TIND::Mapping::AlmaBase.is_barcode = true
152
+ end
153
+ ```
154
+
155
+ 2. Praparing additional fields
156
+
157
+ Adding field using:
158
+ - field methods from module: BerkeleyLibrary::TIND::Mapping::TindField
159
+ - Or the original method from Ruby Marc when field method found in above module
160
+ ::MARC::DataField.new(tag, indicator1, indicator, [code1, value1], [code2, value2] ...)
161
+
162
+ ```ruby
163
+
164
+ def additional_tind_fields_1
165
+ txt = 'v001_0064'
166
+ url = 'https://digitalassets.lib.berkeley.edu/pre1912ChineseMaterials/ucb/ready/991032333019706532/991032333019706532_v001_0064.jpg'
167
+ fft = BerkeleyLibrary::TIND::Mapping::TindField.f_fft(url, txt)
168
+
169
+ f = ::MARC::DataField.new('998', ' ', ' ', ['a', 'fake-value'])
170
+ [fft] << f
171
+ end
172
+
173
+ def additional_tind_fields_2
174
+ txt = 'v001_0065'
175
+ url = 'https://digitalassets.lib.berkeley.edu/pre1912ChineseMaterials/ucb/ready/991032333019706532/991032333019706532_v001_0065.jpg'
176
+ fft = BerkeleyLibrary::TIND::Mapping::TindField.f_fft(url, txt)
177
+ [fft]
178
+ end
179
+ ```
180
+
181
+ 3. Transforming one Alma record => One TIND record
182
+
183
+ ```ruby
184
+ setup_collection
185
+
186
+ # id can be 1)mms_id; 2)Millennium no ; or 3)Barcode
187
+ id = 'C084093187'
188
+
189
+ alma_tind = BerkeleyLibrary::TIND::Mapping::AlmaSingleTIND.new
190
+ tind_record = alma_tind.record(id, additional_tind_fields_1)
191
+ ```
192
+
193
+
194
+ 4. Or transforming one Alma record => Multiple TIND records
195
+
196
+ ``` ruby
197
+ setup_collection
198
+
199
+ # id can be 1) mms_id; 2) Millennium bib number; or 3) Item barcode
200
+ # id = '991085821143406532'
201
+ id = 'C084093187'
202
+
203
+ alma_tind = BerkeleyLibrary::TIND::Mapping::AlmaMultipleTIND.new(id)
204
+ tind_record_1 = alma_tind.record(additional_tind_fields_1)
205
+ tind_record_2 = alma_tind.record(additional_tind_fields_2)
206
+ ```
@@ -23,6 +23,7 @@ Gem::Specification.new do |spec|
23
23
 
24
24
  spec.required_ruby_version = ruby_version
25
25
 
26
+ spec.add_dependency 'berkeley_library-alma', '~> 0.0.1'
26
27
  spec.add_dependency 'berkeley_library-logging', '~> 0.2'
27
28
  spec.add_dependency 'berkeley_library-marc', '~> 0.3.0', '>= 0.3.1'
28
29
  spec.add_dependency 'berkeley_library-util', '~> 0.1'
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ begin
4
+ # This should work if (1) the gem is installed, or
5
+ # (2) we're in development and used `bundle exec`
6
+ require 'berkeley_library/tind'
7
+ require 'berkeley_library/alma'
8
+ rescue LoadError
9
+ # If we're in development, `require 'bundler/setup'`
10
+ # is roughly equivalent to `bundle exec`
11
+ require 'bundler/setup'
12
+ require 'berkeley_library/tind'
13
+ require 'berkeley_library/alma'
14
+ end
15
+
16
+ def setup
17
+ # set collection name information
18
+ BerkeleyLibrary::TIND::Mapping::AlmaBase.collection_parameter_hash = {
19
+ '336' => ['Image'],
20
+ '852' => ['East Asian Library'],
21
+ '980' => ['pre_1912'],
22
+ '982' => ['Pre 1912 Chinese Materials - short name', 'Pre 1912 Chinese Materials - long name'],
23
+ '991' => []
24
+ }
25
+
26
+ # flag: set it to true if using barcode getting Alma record; default is false
27
+ # BerkeleyLibrary::TIND::Mapping::AlmaBase.is_barcode = true
28
+ end
29
+
30
+ def additional_tind_fields
31
+ txt = 'v001_0064'
32
+ url = 'https://digitalassets.lib.berkeley.edu/pre1912ChineseMaterials/ucb/ready/991032333019706532/991032333019706532_v001_0064.jpg'
33
+ fft = BerkeleyLibrary::TIND::Mapping::TindField.f_fft(url, txt)
34
+ datafields = [fft]
35
+
36
+ f_035 = BerkeleyLibrary::TIND::Mapping::TindField.f_035_from_alma_id('pre_1912', '991085821143406532')
37
+ datafields << f_035
38
+ end
39
+
40
+ ########### Use this, when creating multiple TIND records from a single Alma record ############
41
+ alma_id = '991085821143406532'
42
+ # alma_id = '99108582114340653' # a bad alma_id
43
+ # alma_id = '991084606989706532' # Host histrical record
44
+
45
+ setup
46
+
47
+ BerkeleyLibrary::Alma::Config.default!
48
+ alma_multiple_tind = BerkeleyLibrary::TIND::Mapping::AlmaMultipleTIND.new(alma_id)
49
+ tind_record = alma_multiple_tind.record(additional_tind_fields)
50
+ alma_multiple_tind.save_tind_record_to_file(tind_record, 'tmp/multiple.xml')
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ begin
4
+ # This should work if (1) the gem is installed, or
5
+ # (2) we're in development and used `bundle exec`
6
+ require 'berkeley_library/tind'
7
+ require 'berkeley_library/alma'
8
+ rescue LoadError
9
+ # If we're in development, `require 'bundler/setup'`
10
+ # is roughly equivalent to `bundle exec`
11
+ require 'bundler/setup'
12
+ require 'berkeley_library/tind'
13
+ require 'berkeley_library/alma'
14
+ end
15
+
16
+ def setup
17
+ BerkeleyLibrary::TIND::Mapping::AlmaBase.collection_parameter_hash = {
18
+ '336' => ['Image'],
19
+ '852' => ['East Asian Library'],
20
+ '980' => ['pre_1912'],
21
+ '982' => ['Pre 1912 Chinese Materials - short name', 'Pre 1912 Chinese Materials - long name'],
22
+ '991' => []
23
+ }
24
+ BerkeleyLibrary::TIND::Mapping::AlmaBase.is_035_from_mms_id = true
25
+ BerkeleyLibrary::TIND::Mapping::AlmaBase.is_barcode = false
26
+ end
27
+
28
+ def additional_tind_fields
29
+ txt = 'v001_0064'
30
+ url = 'https://digitalassets.lib.berkeley.edu/pre1912ChineseMaterials/ucb/ready/991032333019706532/991032333019706532_v001_0064.jpg'
31
+ fft = BerkeleyLibrary::TIND::Mapping::TindField.f_fft(url, txt)
32
+ f = ::MARC::DataField.new('998', ' ', ' ', ['a', 'fake-value'])
33
+ [fft] << f
34
+ end
35
+
36
+ ############## Use this, when creating a TIND record from each Alma record ############
37
+ # alma_id = '991085821143406532'
38
+ # alma_id_bad = '99108582114340653' # a bad alma_id
39
+ # alma_id_not_qualified = '991084606989706532' # Host historical record
40
+ barcode = 'C084093187'
41
+
42
+ id = barcode
43
+ setup
44
+
45
+ BerkeleyLibrary::Alma::Config.default!
46
+ alma_single_tind = BerkeleyLibrary::TIND::Mapping::AlmaSingleTIND.new
47
+ tind_record = alma_single_tind.record(id, additional_tind_fields)
48
+ alma_single_tind.save_tind_record_to_file(id, tind_record, 'tmp/test_single.xml')
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ begin
4
+ # This should work if (1) the gem is installed, or
5
+ # (2) we're in development and used `bundle exec`
6
+ require 'berkeley_library/tind'
7
+ require 'berkeley_library/alma'
8
+ rescue LoadError
9
+ # If we're in development, `require 'bundler/setup'`
10
+ # is roughly equivalent to `bundle exec`
11
+ require 'bundler/setup'
12
+ require 'berkeley_library/tind'
13
+ require 'berkeley_library/alma'
14
+ end
15
+
16
+ def setup
17
+ BerkeleyLibrary::TIND::Mapping::AlmaBase.collection_parameter_hash = {
18
+ '336' => ['Image'],
19
+ '852' => ['Bioscience, Natural Resources & Public Health Library'],
20
+ '980' => ['Forestry'],
21
+ '982' => ['Forestry', 'Forestry'],
22
+ '991' => []
23
+ }
24
+
25
+ # BerkeleyLibrary::TIND::Mapping::AlmaBase.is_barcode = true
26
+ end
27
+
28
+ def fake_additional_tind_fields1
29
+ fields = []
30
+ txt = '001'
31
+ url = 'https://digitalassets.lib.berkeley.edu/forestry/ucb/images/b142086125_i180839998/b142086125_i180839998_001.jpg'
32
+ fft = BerkeleyLibrary::TIND::Mapping::TindField.f_fft(url, txt)
33
+ f_998 = ::MARC::DataField.new('998', ' ', ' ', ['a', 'fake-value'])
34
+ f_035 = BerkeleyLibrary::TIND::Mapping::TindField.f_035('b142086125')
35
+ fields << f_998
36
+ fields << f_035
37
+ fields << fft
38
+ end
39
+
40
+ def fake_additional_tind_fields2
41
+ fields = []
42
+ txt = '002'
43
+ url = 'https://digitalassets.lib.berkeley.edu/forestry/ucb/images/b142086125_i180839998/b142086125_i180839998_002.jpg'
44
+ fft = BerkeleyLibrary::TIND::Mapping::TindField.f_fft(url, txt)
45
+
46
+ f_998 = ::MARC::DataField.new('998', ' ', ' ', ['a', 'fake-value'])
47
+
48
+ f_035 = BerkeleyLibrary::TIND::Mapping::TindField.f_035('b142107827')
49
+ fields << f_998
50
+ fields << f_035
51
+ fields << fft
52
+ end
53
+
54
+ def tind_records
55
+ records = []
56
+ alma_tind = BerkeleyLibrary::TIND::Mapping::AlmaSingleTIND.new
57
+
58
+ record1 = alma_tind.record('b142086125', fake_additional_tind_fields1)
59
+ record2 = alma_tind.record('b142107827', fake_additional_tind_fields2)
60
+ records << record1
61
+ records << record2
62
+ end
63
+
64
+ def save_batch(file, with_tind_xmlwritter)
65
+ setup
66
+ writer = ::MARC::XMLWriter.new(file)
67
+ writer = BerkeleyLibrary::TIND::MARC::XMLWriter.new(file) if with_tind_xmlwritter
68
+
69
+ tind_records.each do |record|
70
+ record.leader = nil if with_tind_xmlwritter
71
+ writer.write(record)
72
+ end
73
+ writer.close
74
+ end
75
+
76
+ # save with tind xmlwritter
77
+ save_batch('tmp/test_tind_xmlwritter.xml', true)
78
+
79
+ # save with Marc xmlwritter
80
+ save_batch('tmp/test_marc_xmlwritter.xml', false)
data/bin/tind-marc ADDED
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ begin
4
+ # This should work if (1) the gem is installed, or
5
+ # (2) we're in development and used `bundle exec`
6
+ require 'berkeley_library/tind'
7
+ require 'berkeley_library/alma'
8
+ rescue LoadError
9
+ # If we're in development, `require 'bundler/setup'`
10
+ # is roughly equivalent to `bundle exec`
11
+ require 'bundler/setup'
12
+ require 'berkeley_library/tind'
13
+ require 'berkeley_library/alma'
14
+ end
15
+
16
+ # 1. get Alma record
17
+ BerkeleyLibrary::Alma::Config.default!
18
+ # oskicat_num = 'b11082434'
19
+ # alma_num = '991011084939706532'
20
+ # alma no 880 field
21
+ alma_num = '991085821143406532'
22
+
23
+ # alma no 880 field
24
+ # alma_num = '991039355849706532'
25
+ record_id = BerkeleyLibrary::Alma::RecordId.parse(alma_num)
26
+ oskicat_record = record_id.get_marc_record
27
+
28
+ # 2. get collection information fields
29
+ # This information from "collection name" table on share driver
30
+ collection_parameters = {
31
+ '336' => ['Image'],
32
+ '852' => ['East Asian Library'],
33
+ '980' => ['pre_1912'],
34
+ '982' => ['Pre 1912 Chinese Materials', 'Pre 1912 Chinese Materials'],
35
+ '991' => []
36
+ }
37
+
38
+ collection_tind_fields = BerkeleyLibrary::TIND::Mapping::ExternalTindField.tind_fields_from_collection_information(collection_parameters)
39
+
40
+ # 3. get other external tind fields
41
+ other_external_tind_fields = []
42
+ tind_fields_from_alma_id = BerkeleyLibrary::TIND::Mapping::ExternalTindField.tind_mms_id_fields('991011084939706532')
43
+
44
+ other_external_tind_fields.concat tind_fields_from_alma_id
45
+
46
+ # 4. get fft fields
47
+
48
+ new_subfield1 = BerkeleyLibrary::TIND::Mapping::Util.subfield('a', 'https://digitalassets.lib.berkeley.edu/pre1912ChineseMaterials/ucb/ready/991032333019706532/991032333019706532_v001_0064.jpg')
49
+ new_subfield2 = BerkeleyLibrary::TIND::Mapping::Util.subfield('d', 'v001_0064')
50
+ fft_datafield = BerkeleyLibrary::TIND::Mapping::Util.datafield('FFT', [' ', ' '], [new_subfield1, new_subfield2])
51
+ ffts = [fft_datafield]
52
+
53
+ # 5. put all external tind fields together
54
+ external_tind_fields = collection_tind_fields
55
+ external_tind_fields.concat other_external_tind_fields
56
+ external_tind_fields.concat ffts
57
+
58
+ # 6. create tind-marc object,
59
+ tindmarc = BerkeleyLibrary::TIND::Mapping::TindMarc.new(oskicat_record)
60
+
61
+ # 7. add external tind fields(these tind fields will paticipate in "additional process")
62
+ tindmarc.tind_external_datafields = external_tind_fields
63
+
64
+ ##### output ####
65
+ # 8. Get tind fields mapped from alma
66
+ # tindmarc.tindfields
67
+
68
+ # 9. get a tind record which including external tind fields
69
+ # tindmarc.tind_record
70
+
71
+ # 10. save the tind record to an xml file
72
+
73
+ tindmarc.save('tmp/test.xml')
@@ -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