bulkrax 9.4.0 → 9.4.2

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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +8 -2
  3. data/app/assets/javascripts/bulkrax/datatables.js +43 -8
  4. data/app/assets/javascripts/bulkrax/importers_stepper.js +221 -26
  5. data/app/assets/stylesheets/bulkrax/stepper/_review.scss +14 -12
  6. data/app/controllers/bulkrax/entries_controller.rb +2 -2
  7. data/app/controllers/bulkrax/exporters_controller.rb +3 -3
  8. data/app/controllers/bulkrax/guided_imports_controller.rb +3 -1
  9. data/app/controllers/bulkrax/importers_controller.rb +5 -5
  10. data/app/controllers/concerns/bulkrax/importer_file_handler.rb +1 -6
  11. data/app/errors/bulkrax/unzip_error.rb +16 -0
  12. data/app/jobs/bulkrax/importer_job.rb +40 -9
  13. data/app/matchers/bulkrax/application_matcher.rb +5 -6
  14. data/app/models/bulkrax/csv_entry.rb +1 -1
  15. data/app/models/bulkrax/importer.rb +3 -16
  16. data/app/parsers/bulkrax/application_parser.rb +50 -33
  17. data/app/parsers/bulkrax/bagit_parser.rb +12 -0
  18. data/app/parsers/bulkrax/csv_parser.rb +163 -49
  19. data/app/parsers/concerns/bulkrax/csv_parser/csv_template_generation.rb +4 -1
  20. data/app/parsers/concerns/bulkrax/csv_parser/csv_validation.rb +10 -8
  21. data/app/parsers/concerns/bulkrax/csv_parser/csv_validation_helpers.rb +69 -36
  22. data/app/parsers/concerns/bulkrax/csv_parser/csv_validation_hierarchy.rb +9 -7
  23. data/app/services/bulkrax/csv_template/file_validator.rb +1 -1
  24. data/app/services/bulkrax/csv_template/mapping_manager.rb +15 -6
  25. data/app/services/bulkrax/csv_template/split_formatter.rb +10 -3
  26. data/app/services/bulkrax/split_pattern_coercion.rb +42 -0
  27. data/app/services/bulkrax/stepper_response_formatter.rb +2 -1
  28. data/app/services/bulkrax/validation_error_csv_builder.rb +36 -12
  29. data/app/validators/bulkrax/csv_row/child_reference.rb +2 -1
  30. data/app/validators/bulkrax/csv_row/parent_reference.rb +1 -1
  31. data/app/validators/bulkrax/csv_row/required_values.rb +17 -3
  32. data/app/views/bulkrax/exporters/edit.html.erb +1 -1
  33. data/app/views/bulkrax/exporters/index.html.erb +3 -1
  34. data/app/views/bulkrax/exporters/new.html.erb +1 -1
  35. data/app/views/bulkrax/exporters/show.html.erb +1 -1
  36. data/app/views/bulkrax/guided_imports/new.html.erb +7 -0
  37. data/app/views/bulkrax/importers/_edit_item_buttons.html.erb +3 -3
  38. data/app/views/bulkrax/importers/index.html.erb +2 -0
  39. data/app/views/bulkrax/importers/new.html.erb +1 -1
  40. data/app/views/bulkrax/importers/show.html.erb +3 -1
  41. data/app/views/bulkrax/shared/_datatable_i18n.html.erb +3 -0
  42. data/config/locales/bulkrax.de.yml +95 -2
  43. data/config/locales/bulkrax.en.yml +58 -2
  44. data/config/locales/bulkrax.es.yml +95 -2
  45. data/config/locales/bulkrax.fr.yml +95 -2
  46. data/config/locales/bulkrax.it.yml +95 -2
  47. data/config/locales/bulkrax.pt-BR.yml +95 -2
  48. data/config/locales/bulkrax.zh.yml +96 -2
  49. data/db/migrate/20260424081537_remove_parents_from_bulkrax_importer_runs.rb +9 -0
  50. data/lib/bulkrax/version.rb +1 -1
  51. data/lib/bulkrax.rb +15 -1
  52. metadata +8 -4
@@ -17,13 +17,23 @@ zh:
17
17
  record_link: "%{record_type} 链接"
18
18
  unknown: 未知
19
19
  exporter:
20
+ hints:
21
+ generated_metadata: 这些导出的字段目前无法导入。
22
+ include_thumbnails: 这些导出的字段目前无法导入。
23
+ limit: 留空或填 0 表示所有记录
20
24
  labels:
21
25
  all: 全部
22
26
  collection: 收藏
27
+ collection_entries: 收藏条目
28
+ download: 下载
29
+ export_format: 导出格式
23
30
  export_from: 导出
24
31
  export_source: 出口来源
25
32
  export_type: 出口类型
26
33
  field_mapping: 田间测绘
34
+ file_set_entries: 文件集条目
35
+ filter_by_date: 按日期筛选
36
+ finish_date: 结束日期
27
37
  full: 元数据和文件
28
38
  generated_metadata: 是否包含生成的元数据?
29
39
  importer: 进口商
@@ -33,7 +43,20 @@ zh:
33
43
  name: 姓名
34
44
  parser_fields: 解析器字段
35
45
  parser_klass: 解析器
46
+ start_date: 开始日期
47
+ status: 状态
48
+ total_entries: 条目总数
49
+ total_work_entries: 作品总数
36
50
  user: 用户
51
+ work_entries: 作品条目
52
+ workflow_status:
53
+ approved: 已批准
54
+ broken_url: URL 失效
55
+ deleted: 已删除
56
+ in_process: 处理中
57
+ ingested: 已摄入
58
+ needs_repair: 需要修复
59
+ unapproved: 未批准
37
60
  worktype: 工作类型
38
61
  prompts:
39
62
  export_from: 请选择导出源
@@ -45,8 +68,14 @@ zh:
45
68
  one: 1 个错误导致此导出器无法保存:
46
69
  other: "%{count} 错误导致无法保存此导出器:"
47
70
  headings:
71
+ edit_exporter: 编辑导出程序
72
+ edit_importer: 编辑导入程序
73
+ exporters: 导出程序
48
74
  importers: 进口商
75
+ new_exporter: 新建导出程序
76
+ new_importer: 新建导入程序
49
77
  upload_corrected_entries: 上传更正后的条目:%{name}
78
+ upload_corrected_entries_action: 上传更正后的条目
50
79
  importer:
51
80
  bagit:
52
81
  bags_to_import: 进口袋或包:
@@ -77,6 +106,9 @@ zh:
77
106
  private: 私人的
78
107
  public: 民众
79
108
  edit_form:
109
+ entry_modal_title: 更新条目的选项
110
+ entry_rebuild_hint: 重新构建元数据和文件。
111
+ entry_remove_and_recreate_hint: 删除现有作品,然后重新创建作品的元数据和文件。
80
112
  modal_title: 更新导入程序的选项
81
113
  remove_and_rerun_hint: 删除所有作品,然后从头开始重新导入。这将删除所有文件和关联关系,并且自上次导入以来所做的任何编辑都将丢失。
82
114
  update_and_harvest_hint: 更新导入器表单中的值,并更新源中已更改的项目。
@@ -96,19 +128,23 @@ zh:
96
128
  override_rights_statement: 如果选中,则始终使用选定的权限语句。如果未选中,则使用记录中的权限或权限语句,并且仅当 dc:rights 为空时才使用提供的值。
97
129
  labels:
98
130
  admin_set: 管理集
131
+ collection_entries: 收藏条目
99
132
  entry_id: 条目 ID
100
133
  exporter: 出口商
134
+ file_set_entries: 文件集条目
101
135
  frequency: 频率
102
136
  identifier: 标识符
103
137
  importer: 进口商
104
138
  limit: 限制
105
139
  name: 姓名
140
+ parser_fields: 解析器字段
106
141
  parser_klass: 解析器
107
142
  total_collections: 总收藏
108
143
  total_file_sets: 文件集总数
109
144
  total_work_entries: 总作品
110
145
  type: 类型
111
146
  user: 用户
147
+ work_entries: 作品条目
112
148
  oai:
113
149
  hints:
114
150
  metadata_prefix: 例如 oai_dc、dcterms 或 oai_qdc
@@ -185,6 +221,8 @@ zh:
185
221
  review_total: 总计 %{total} — %{collections} 个收藏集,%{works} 个作品,%{file_sets} 个文件集
186
222
  review_visibility: 能见度:
187
223
  server_error: 验证过程中服务器出错。请重试或联系客服。
224
+ existing_record_badge: 已存在
225
+ existing_record_title: 此记录已存在于存储库中,导入时将进行关联。
188
226
  shared_badge: 共享
189
227
  starting: 开始...
190
228
  upload_csv_and_zip: CSV 文件和其他文件单独上传
@@ -199,9 +237,20 @@ zh:
199
237
  validating: 正在验证……
200
238
  validation_failed: 验证失败,请重试。
201
239
  validation_timeout: 验证超时。您的文件可能过大。请尝试上传较小的文件或联系技术支持。
240
+ validation_truncated_note: 已截断至 %{shown} 条 — 请下载错误 CSV 以查看完整列表
241
+ validation_truncated_tooltip: 为保持页面整洁,此列表已限制显示条数。完整列表包含在可下载的错误 CSV 文件中。
202
242
  visibility_institution: 机构
203
243
  visibility_private: 私人的
204
244
  visibility_public: 民众
245
+ warning_category_circular_reference: 循环引用
246
+ warning_category_default_work_type_used: 使用了默认的作品类型
247
+ warning_category_duplicate_source_identifier: CSV 中的源标识符重复
248
+ warning_category_existing_source_identifier: 已存在的源标识符(将被更新)
249
+ warning_category_invalid_child_reference: 无效的子引用
250
+ warning_category_invalid_controlled_value: 无效的受控词汇值
251
+ warning_category_invalid_parent_reference: 无效的父引用
252
+ warning_category_missing_required_value: 缺少必填值
253
+ warning_category_missing_source_identifier: 缺少源标识符
205
254
  zip_limit: 仅允许上传 1 个 ZIP 文件。以下文件未添加:
206
255
  nav:
207
256
  back: 后退
@@ -209,6 +258,7 @@ zh:
209
258
  next_step: 下一个
210
259
  skip_validation: 跳过验证
211
260
  start_import: 开始导入
261
+ feedback_link: 报告错误 / 反馈
212
262
  page_subtitle: 通过 CSV 导入收藏集、作品和文件
213
263
  page_title: 开始批量导入
214
264
  step1:
@@ -263,6 +313,7 @@ zh:
263
313
  large_import_message_html: 您即将导入<span class="total-items-count">%{count}</span>个项目。大量导入操作耗时更长,且更难排查问题。建议您分批导入。
264
314
  large_import_warning: 大量进口警告
265
315
  ready_to_import: 准备进口
316
+ section_errors: 错误
266
317
  section_files: 文件
267
318
  section_records: 记录
268
319
  section_settings: 设置
@@ -314,8 +365,7 @@ zh:
314
365
  missing_required_hint: 将此列添加到您的 CSV 文件中
315
366
  missing_required_title: 缺少必填字段
316
367
  missing_rights_desc: 您的 CSV 文件不包含 rights_statement 列。您可以在下一步中将其添加到 CSV 文件中,或选择默认的权利声明。
317
- multiple_csv_same_dir: ZIP 文件中的同一目录下发现了多个 CSV 文件
318
- multiple_csv_same_level: 在 ZIP 文件中的同一层级发现了多个 CSV 文件
368
+ multiple_csv: ZIP 文件中的同一最浅层级下发现了多个 CSV 文件,无法确定主 CSV。请在该层级仅保留一个 CSV,其他 CSV 必须位于更深的目录中。
319
369
  no_csv_in_zip: ZIP 文件中未找到 CSV 文件
320
370
  no_csv_uploaded: 未上传 CSV 元数据文件。
321
371
  no_files_uploaded: 未上传任何文件。
@@ -324,6 +374,14 @@ zh:
324
374
  errors:
325
375
  message: "引用的父级 '%{value}' 在此 CSV 中不存在对应的 %{field}。"
326
376
  suggestion: "请检查拼写错误或添加父级记录。"
377
+ child_reference_validator:
378
+ errors:
379
+ message: "引用的子级 '%{value}' 在此 CSV 中不存在对应的 %{field}。"
380
+ suggestion: "请检查拼写错误或添加子级记录。"
381
+ circular_reference_validator:
382
+ errors:
383
+ message: "'%{value}' 属于循环的父子关系。"
384
+ suggestion: "请检查父级/子级列并移除错误的引用。"
327
385
  passed: 验证通过
328
386
  passed_warnings: 验证通过,但存在警告
329
387
  recognized_fields: 已识别字段:%{fields}
@@ -340,11 +398,23 @@ zh:
340
398
  errors:
341
399
  message: "字段 '%{field}' 是必填项,但此行中该字段为空。"
342
400
  suggestion: "请为 '%{field}' 添加一个值。"
401
+ validation_error_csv_builder:
402
+ empty_column: "第 %{column} 列没有标题,将在导入时被忽略"
403
+ missing_file: "缺少文件:%{filename}"
404
+ missing_required_column: "缺少必填列 '%{field}' (%{model})"
405
+ unrecognized_column: "无法识别的列 '%{column}'"
406
+ unrecognized_column_with_suggestion: "无法识别的列 '%{column}'(是否想输入 '%{suggestion}'?)"
343
407
  unable_to_process: 无法处理文件进行验证
408
+ empty_column: '第 %{column} 列(无标题)'
344
409
  notices_desc: '这些通知可能会影响您的 CSV 的导入方式:'
345
410
  notices_title: 导入通知
346
411
  unrecognized_desc: 导入过程中将忽略以下列:
347
412
  unrecognized_title: 未识别字段
413
+ unzip:
414
+ errors:
415
+ multiple_csv: ZIP 文件中的同一最浅层级下发现了多个 CSV 文件,无法确定主 CSV。请在该层级仅保留一个 CSV,其他 CSV 必须位于更深的目录中。
416
+ no_csv: ZIP 文件中未找到 CSV 文件
417
+ unsafe_entry: "ZIP 文件包含路径不安全的条目(%{name})。条目不得使用绝对路径或父目录引用。"
348
418
  validations:
349
419
  errors_prohibited:
350
420
  one: 1 个错误导致此导入程序无法保存:
@@ -400,11 +470,35 @@ zh:
400
470
  name: 姓名
401
471
  next_run: 下一轮
402
472
  status: 地位
473
+ status_set_at: 状态设置时间
403
474
  total_collection_entries: 总收款条目
404
475
  total_file_set_entries: 文件集条目总数
405
476
  total_work_entries: 总工作条目
406
477
  type: 类型
407
478
  updated_at: 更新于
479
+ datatable:
480
+ filters:
481
+ filter_by_entry_class: 按条目类筛选
482
+ filter_by_status: 按状态筛选
483
+ language:
484
+ empty_table: 表中没有可用数据
485
+ info: 显示第 _START_ 至 _END_ 项,共 _TOTAL_ 项
486
+ info_empty: 显示第 0 至 0 项,共 0 项
487
+ info_filtered: (从 _MAX_ 项中筛选)
488
+ length_menu: 显示 _MENU_ 项
489
+ loading_records: 加载中...
490
+ next: 下一页
491
+ previous: 上一页
492
+ processing: 处理中...
493
+ search: '搜索:'
494
+ zero_records: 未找到匹配的记录
495
+ status:
496
+ complete: 完成
497
+ complete_with_failures: 完成(含失败)
498
+ deleted: 已删除
499
+ failed: 失败
500
+ pending: 待处理
501
+ skipped: 已跳过
408
502
  helpers:
409
503
  action:
410
504
  exporter:
@@ -0,0 +1,9 @@
1
+ class RemoveParentsFromBulkraxImporterRuns < ActiveRecord::Migration[5.2]
2
+ def up
3
+ remove_column :bulkrax_importer_runs, :parents, if_exists: true
4
+ end
5
+
6
+ def down
7
+ add_column :bulkrax_importer_runs, :parents, :text, array: true, default: "{}", unless_exists: true
8
+ end
9
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bulkrax
4
- VERSION = '9.4.0'
4
+ VERSION = '9.4.2'
5
5
  end
data/lib/bulkrax.rb CHANGED
@@ -36,7 +36,6 @@ module Bulkrax
36
36
  class Configuration
37
37
  attr_accessor :api_definition,
38
38
  :default_field_mapping,
39
- :default_work_type,
40
39
  :export_path,
41
40
  :field_mappings,
42
41
  :guided_import_enabled,
@@ -56,6 +55,21 @@ module Bulkrax
56
55
  :reserved_properties,
57
56
  :server_name
58
57
 
58
+ ##
59
+ # The default work type used when a CSV row has no `model` value. Bulkrax
60
+ # treats this as a class name (String) — it's used for hash lookups, I18n
61
+ # interpolation, and `.constantize`. Consumers historically sometimes
62
+ # configured it as a Class constant (e.g. `config.default_work_type = MyWork`),
63
+ # which silently broke validators that key on String model names. The reader
64
+ # coerces to String so callers can stop scattering `.to_s` everywhere.
65
+ # @return [String, nil]
66
+ attr_writer :default_work_type
67
+
68
+ def default_work_type
69
+ return nil if @default_work_type.nil?
70
+ @default_work_type.to_s
71
+ end
72
+
59
73
  ##
60
74
  # @return [#call] with arity 2. The first parameter is a {Bulkrax::ApplicationParser} and the
61
75
  # second parameter is an Integer for the index of the record encountered in the import.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bulkrax
3
3
  version: !ruby/object:Gem::Version
4
- version: 9.4.0
4
+ version: 9.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rob Kaufman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-04-15 00:00:00.000000000 Z
11
+ date: 2026-04-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -264,14 +264,14 @@ dependencies:
264
264
  requirements:
265
265
  - - "~>"
266
266
  - !ruby/object:Gem::Version
267
- version: 1.3.13
267
+ version: '1.4'
268
268
  type: :development
269
269
  prerelease: false
270
270
  version_requirements: !ruby/object:Gem::Requirement
271
271
  requirements:
272
272
  - - "~>"
273
273
  - !ruby/object:Gem::Version
274
- version: 1.3.13
274
+ version: '1.4'
275
275
  - !ruby/object:Gem::Dependency
276
276
  name: simplecov
277
277
  requirement: !ruby/object:Gem::Requirement
@@ -365,6 +365,7 @@ files:
365
365
  - app/controllers/concerns/bulkrax/download_behavior.rb
366
366
  - app/controllers/concerns/bulkrax/guided_import_demo_scenarios.rb
367
367
  - app/controllers/concerns/bulkrax/importer_file_handler.rb
368
+ - app/errors/bulkrax/unzip_error.rb
368
369
  - app/factories/bulkrax/object_factory.rb
369
370
  - app/factories/bulkrax/object_factory_interface.rb
370
371
  - app/factories/bulkrax/valkyrie_object_factory.rb
@@ -452,6 +453,7 @@ files:
452
453
  - app/services/bulkrax/csv_template/value_determiner.rb
453
454
  - app/services/bulkrax/factory_class_finder.rb
454
455
  - app/services/bulkrax/remove_relationships_for_importer.rb
456
+ - app/services/bulkrax/split_pattern_coercion.rb
455
457
  - app/services/bulkrax/stepper_response_formatter.rb
456
458
  - app/services/bulkrax/validation_error_csv_builder.rb
457
459
  - app/services/hyrax/custom_queries/find_by_source_identifier.rb
@@ -488,6 +490,7 @@ files:
488
490
  - app/views/bulkrax/importers/upload_corrected_entries.html.erb
489
491
  - app/views/bulkrax/shared/_bulkrax_errors.html.erb
490
492
  - app/views/bulkrax/shared/_bulkrax_field_mapping.html.erb
493
+ - app/views/bulkrax/shared/_datatable_i18n.html.erb
491
494
  - app/views/bulkrax/shared/_entries_tab.html.erb
492
495
  - app/views/hyrax/dashboard/sidebar/_bulkrax_sidebar_additions.html.erb
493
496
  - app/views/hyrax/dashboard/sidebar/_repository_content.html.erb
@@ -545,6 +548,7 @@ files:
545
548
  - db/migrate/20240916182823_add_next_import_at_to_bulkrax_importers.rb
546
549
  - db/migrate/20241203010707_entry_error_denormalization.rb
547
550
  - db/migrate/20241205212513_faster_first_entry.rb
551
+ - db/migrate/20260424081537_remove_parents_from_bulkrax_importer_runs.rb
548
552
  - lib/bulkrax.rb
549
553
  - lib/bulkrax/data/demo_scenarios.json
550
554
  - lib/bulkrax/engine.rb