zizia 4.0.2.alpha.01 → 4.0.3.alpha.01
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- metadata +2 -28
- data/lib/zizia/always_invalid_validator.rb +0 -17
- data/lib/zizia/csv_template.rb +0 -9
- data/lib/zizia/engine.rb +0 -32
- data/lib/zizia/hash_mapper.rb +0 -44
- data/lib/zizia/hyrax/hyrax_basic_metadata_mapper.rb +0 -149
- data/lib/zizia/hyrax/hyrax_default_updater.rb +0 -11
- data/lib/zizia/hyrax/hyrax_delete_files_updater.rb +0 -16
- data/lib/zizia/hyrax/hyrax_metadata_only_updater.rb +0 -58
- data/lib/zizia/hyrax/hyrax_record_importer.rb +0 -247
- data/lib/zizia/hyrax/metadata_only_stack.rb +0 -70
- data/lib/zizia/importer.rb +0 -58
- data/lib/zizia/input_record.rb +0 -65
- data/lib/zizia/metadata_mapper.rb +0 -83
- data/lib/zizia/parser.rb +0 -132
- data/lib/zizia/parsers/csv_parser.rb +0 -45
- data/lib/zizia/record_importer.rb +0 -44
- data/lib/zizia/spec/fakes/fake_parser.rb +0 -22
- data/lib/zizia/spec/shared_examples/a_mapper.rb +0 -32
- data/lib/zizia/spec/shared_examples/a_parser.rb +0 -73
- data/lib/zizia/spec/shared_examples/a_validator.rb +0 -29
- data/lib/zizia/spec.rb +0 -14
- data/lib/zizia/validator.rb +0 -106
- data/lib/zizia/validators/csv_format_validator.rb +0 -26
- data/lib/zizia/validators/title_validator.rb +0 -30
- data/lib/zizia/version.rb +0 -5
- data/lib/zizia.rb +0 -66
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1a3b63826827c01a64976c80bff369266b9006772d6bf9c6de4cdcfc8b5ee2d6
|
4
|
+
data.tar.gz: a1fb2e5d4e00db022d50e9637d9369e999a3b4e39c7c03d5f1fc4f294213c715
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9dc28d1191c9b15d12432facf356ae659b842fb912c16b5bc9d3dd3f929d353c916b22b6a53269953ec75702ef90e8b36674062fcb4ec382d87617630c787a87
|
7
|
+
data.tar.gz: d125f72d2bb4fd2b6154cd5e5ffa0c76da6afdb1c8e8786d6d61d853ba9890246edb0db3dd5f41e6b743dbb2610c1a37fe9dc935f0cf6e9c6400e7ca95eebd4e
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zizia
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.0.
|
4
|
+
version: 4.0.3.alpha.01
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Data Curation Experts
|
@@ -612,32 +612,6 @@ extensions: []
|
|
612
612
|
extra_rdoc_files: []
|
613
613
|
files:
|
614
614
|
- README.md
|
615
|
-
- lib/zizia.rb
|
616
|
-
- lib/zizia/always_invalid_validator.rb
|
617
|
-
- lib/zizia/csv_template.rb
|
618
|
-
- lib/zizia/engine.rb
|
619
|
-
- lib/zizia/hash_mapper.rb
|
620
|
-
- lib/zizia/hyrax/hyrax_basic_metadata_mapper.rb
|
621
|
-
- lib/zizia/hyrax/hyrax_default_updater.rb
|
622
|
-
- lib/zizia/hyrax/hyrax_delete_files_updater.rb
|
623
|
-
- lib/zizia/hyrax/hyrax_metadata_only_updater.rb
|
624
|
-
- lib/zizia/hyrax/hyrax_record_importer.rb
|
625
|
-
- lib/zizia/hyrax/metadata_only_stack.rb
|
626
|
-
- lib/zizia/importer.rb
|
627
|
-
- lib/zizia/input_record.rb
|
628
|
-
- lib/zizia/metadata_mapper.rb
|
629
|
-
- lib/zizia/parser.rb
|
630
|
-
- lib/zizia/parsers/csv_parser.rb
|
631
|
-
- lib/zizia/record_importer.rb
|
632
|
-
- lib/zizia/spec.rb
|
633
|
-
- lib/zizia/spec/fakes/fake_parser.rb
|
634
|
-
- lib/zizia/spec/shared_examples/a_mapper.rb
|
635
|
-
- lib/zizia/spec/shared_examples/a_parser.rb
|
636
|
-
- lib/zizia/spec/shared_examples/a_validator.rb
|
637
|
-
- lib/zizia/validator.rb
|
638
|
-
- lib/zizia/validators/csv_format_validator.rb
|
639
|
-
- lib/zizia/validators/title_validator.rb
|
640
|
-
- lib/zizia/version.rb
|
641
615
|
homepage:
|
642
616
|
licenses:
|
643
617
|
- Apache-2.0
|
@@ -645,7 +619,7 @@ metadata: {}
|
|
645
619
|
post_install_message:
|
646
620
|
rdoc_options: []
|
647
621
|
require_paths:
|
648
|
-
-
|
622
|
+
- "."
|
649
623
|
required_ruby_version: !ruby/object:Gem::Requirement
|
650
624
|
requirements:
|
651
625
|
- - ">="
|
@@ -1,17 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Zizia
|
4
|
-
##
|
5
|
-
# A Validator that always gives an error named `:everytime`.
|
6
|
-
#
|
7
|
-
# @example
|
8
|
-
# validator = AlwaysInvalidValidator.new
|
9
|
-
# validator.validate(:anything, :at, :all) # => [Error<#...>]
|
10
|
-
class AlwaysInvalidValidator < Validator
|
11
|
-
##
|
12
|
-
# @return [Array<Validator::Error>]
|
13
|
-
def validate(*)
|
14
|
-
[Error.new(self, :everytime)]
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
data/lib/zizia/csv_template.rb
DELETED
data/lib/zizia/engine.rb
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rails/all'
|
4
|
-
require 'carrierwave'
|
5
|
-
require 'carrierwave/orm/activerecord'
|
6
|
-
require 'redcarpet'
|
7
|
-
require 'devise'
|
8
|
-
require 'hyrax'
|
9
|
-
require 'riiif'
|
10
|
-
require 'hydra-role-management'
|
11
|
-
|
12
|
-
module Zizia
|
13
|
-
class Engine < ::Rails::Engine
|
14
|
-
isolate_namespace Zizia
|
15
|
-
|
16
|
-
config.generators do |g|
|
17
|
-
g.test_framework :rspec
|
18
|
-
end
|
19
|
-
|
20
|
-
initializer :zizia_assets_precompile do |app|
|
21
|
-
app.config.assets.precompile << %w[zizia/application.js zizia/application.css]
|
22
|
-
end
|
23
|
-
|
24
|
-
initializer :append_migrations do |app|
|
25
|
-
unless app.root.to_s.match root.to_s
|
26
|
-
config.paths['db/migrate'].expanded.each do |expanded_path|
|
27
|
-
app.config.paths['db/migrate'] << expanded_path
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
data/lib/zizia/hash_mapper.rb
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Zizia
|
4
|
-
##
|
5
|
-
# A generic metadata mapper for input records
|
6
|
-
#
|
7
|
-
# Maps from hash accessor syntax (`['title']`) to method call dot syntax (`.title`)
|
8
|
-
#
|
9
|
-
# The fields provided by this mapper are dynamically determined by the fields
|
10
|
-
# available in the provided metadata hash.
|
11
|
-
#
|
12
|
-
# All field values are given as multi-valued arrays.
|
13
|
-
#
|
14
|
-
# @example
|
15
|
-
# mapper = HashMapper.new
|
16
|
-
# mapper.fields # => []
|
17
|
-
#
|
18
|
-
# mapper.metadata = { title: 'Comet in Moominland', author: 'Tove Jansson' }
|
19
|
-
# mapper.fields # => [:title, :author]
|
20
|
-
# mapper.title # => ['Comet in Moominland']
|
21
|
-
# mapper.author # => ['Tove Jansson']
|
22
|
-
#
|
23
|
-
class HashMapper < MetadataMapper
|
24
|
-
##
|
25
|
-
# @param meta [#to_h]
|
26
|
-
# @return [Hash<String, String>]
|
27
|
-
def metadata=(meta)
|
28
|
-
@metadata = meta.to_h
|
29
|
-
end
|
30
|
-
|
31
|
-
##
|
32
|
-
# @return [Enumerable<Symbol>] The fields the mapper can process
|
33
|
-
def fields
|
34
|
-
return [] if metadata.nil?
|
35
|
-
metadata.keys.map(&:to_sym)
|
36
|
-
end
|
37
|
-
|
38
|
-
##
|
39
|
-
# @see MetadataMapper#map_field
|
40
|
-
def map_field(name)
|
41
|
-
Array(metadata[name.to_s])
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
@@ -1,149 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'uri'
|
3
|
-
|
4
|
-
module Zizia
|
5
|
-
##
|
6
|
-
# A mapper for Hyrax metadata.
|
7
|
-
#
|
8
|
-
# Maps from hash accessor syntax (`['title']`) to method call dot syntax (`.title`).
|
9
|
-
#
|
10
|
-
# The fields provided by this mapper are the same as the properties defined in `Hyrax::CoreMetadata` and `Hyrax::BasicMetadata`.
|
11
|
-
#
|
12
|
-
# @note This mapper allows you to set values for all the Hyrax fields, but depending on how you create the records, some of the values might get clobbered. For example, if you use Hyrax's actor stack to create records, it might overwrite fields like `date_modified` or `depositor`.
|
13
|
-
#
|
14
|
-
# @see HashMapper Parent class for more info and examples.
|
15
|
-
class HyraxBasicMetadataMapper < HashMapper
|
16
|
-
# If your CSV headers don't exactly match the
|
17
|
-
# the method name for the property's setter
|
18
|
-
# method, add a mapping here.
|
19
|
-
# Example: the method name is work.resource_type,
|
20
|
-
# but in the CSV file, the header is
|
21
|
-
# 'resource type' (without the underscore).
|
22
|
-
CSV_HEADERS = {
|
23
|
-
resource_type: 'resource type',
|
24
|
-
description: 'abstract or summary',
|
25
|
-
rights_statement: 'rights statement',
|
26
|
-
date_created: 'date created',
|
27
|
-
based_near: 'location',
|
28
|
-
related_url: 'related url'
|
29
|
-
}.freeze
|
30
|
-
|
31
|
-
##
|
32
|
-
# @return [Enumerable<Symbol>] The fields the mapper can process.
|
33
|
-
def fields
|
34
|
-
core_fields + basic_fields + [:visibility]
|
35
|
-
end
|
36
|
-
|
37
|
-
# Properties defined with `multiple: false` in
|
38
|
-
# Hyrax should return a single value instead of
|
39
|
-
# an Array of values.
|
40
|
-
def depositor
|
41
|
-
single_value('depositor')
|
42
|
-
end
|
43
|
-
|
44
|
-
def date_modified
|
45
|
-
single_value('date_modified')
|
46
|
-
end
|
47
|
-
|
48
|
-
def label
|
49
|
-
single_value('label')
|
50
|
-
end
|
51
|
-
|
52
|
-
def relative_path
|
53
|
-
single_value('relative_path')
|
54
|
-
end
|
55
|
-
|
56
|
-
def import_url
|
57
|
-
single_value('import_url')
|
58
|
-
end
|
59
|
-
|
60
|
-
# We should accept visibility values that match the UI and transform them into
|
61
|
-
# the controlled vocabulary term expected by Hyrax
|
62
|
-
def visibility
|
63
|
-
case metadata[matching_header('visibility')]&.downcase&.gsub(/\s+/, "")
|
64
|
-
when 'public'
|
65
|
-
'open'
|
66
|
-
when 'open'
|
67
|
-
'open'
|
68
|
-
when 'registered'
|
69
|
-
'authenticated'
|
70
|
-
when "authenticated"
|
71
|
-
'authenticated'
|
72
|
-
when ::Hyrax::Institution.name&.downcase&.gsub(/\s+/, "")
|
73
|
-
'authenticated'
|
74
|
-
when ::Hyrax::Institution.name_full&.downcase&.gsub(/\s+/, "")
|
75
|
-
'authenticated'
|
76
|
-
when 'private'
|
77
|
-
'restricted'
|
78
|
-
when 'restricted'
|
79
|
-
'restricted'
|
80
|
-
else
|
81
|
-
'restricted' # This is the default if nothing else matches
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
def files
|
86
|
-
map_field('files')
|
87
|
-
end
|
88
|
-
|
89
|
-
##
|
90
|
-
# @return [String] The delimiter that will be used to split a metadata field into separate values.
|
91
|
-
# @example
|
92
|
-
# mapper = HyraxBasicMetadataMapper.new
|
93
|
-
# mapper.metadata = { 'language' => 'English|~|French|~|Japanese' }
|
94
|
-
# mapper.language = ['English', 'French', 'Japanese']
|
95
|
-
#
|
96
|
-
def delimiter
|
97
|
-
@delimiter ||= '|~|'
|
98
|
-
end
|
99
|
-
attr_writer :delimiter
|
100
|
-
|
101
|
-
##
|
102
|
-
# @see MetadataMapper#map_field
|
103
|
-
def map_field(name)
|
104
|
-
method_name = name.to_s
|
105
|
-
method_name = CSV_HEADERS[name] if CSV_HEADERS.keys.include?(name)
|
106
|
-
key = matching_header(method_name)
|
107
|
-
Array(metadata[key]&.split(delimiter))
|
108
|
-
end
|
109
|
-
|
110
|
-
protected
|
111
|
-
|
112
|
-
# Some fields should have single values instead
|
113
|
-
# of array values.
|
114
|
-
def single_value(field_name)
|
115
|
-
metadata[matching_header(field_name)]
|
116
|
-
end
|
117
|
-
|
118
|
-
# Lenient matching for headers.
|
119
|
-
# If the user has headers like:
|
120
|
-
# 'Title' or 'TITLE' or 'Title '
|
121
|
-
# it should match the :title field.
|
122
|
-
def matching_header(field_name)
|
123
|
-
metadata.keys.find do |key|
|
124
|
-
next unless key
|
125
|
-
key.downcase.strip == field_name
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
# Properties defined in Hyrax::CoreMetadata
|
130
|
-
# Note that date_uploaded is NOT set here, even though it is defined in
|
131
|
-
# Hyrax::CoreMetadata. Hyrax expects to set date_uploaded itself, and
|
132
|
-
# sending a metadata value for that field interferes with Hyrax expected
|
133
|
-
# behavior.
|
134
|
-
def core_fields
|
135
|
-
[:depositor, :title, :date_modified]
|
136
|
-
end
|
137
|
-
|
138
|
-
# Properties defined in Hyrax::BasicMetadata
|
139
|
-
def basic_fields
|
140
|
-
[:label, :relative_path, :import_url,
|
141
|
-
:resource_type, :creator, :contributor,
|
142
|
-
:description, :keyword, :license,
|
143
|
-
:rights_statement, :publisher, :date_created,
|
144
|
-
:subject, :language, :identifier,
|
145
|
-
:based_near, :related_url,
|
146
|
-
:bibliographic_citation, :source]
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
@@ -1,11 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module Zizia
|
3
|
-
class HyraxDefaultUpdater < HyraxMetadataOnlyUpdater
|
4
|
-
attr_reader :attrs
|
5
|
-
|
6
|
-
def actor_stack
|
7
|
-
terminator = Hyrax::Actors::Terminator.new
|
8
|
-
Hyrax::DefaultMiddlewareStack.build_stack.build(terminator)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module Zizia
|
3
|
-
class HyraxDeleteFilesUpdater < HyraxMetadataOnlyUpdater
|
4
|
-
attr_reader :attrs
|
5
|
-
|
6
|
-
def actor_stack
|
7
|
-
terminator = Hyrax::Actors::Terminator.new
|
8
|
-
Hyrax::DefaultMiddlewareStack.build_stack.build(terminator)
|
9
|
-
end
|
10
|
-
|
11
|
-
def update
|
12
|
-
existing_record.file_sets.map(&:destroy)
|
13
|
-
super
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
@@ -1,58 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module Zizia
|
3
|
-
class HyraxMetadataOnlyUpdater
|
4
|
-
attr_accessor :depositor,
|
5
|
-
:existing_record,
|
6
|
-
:update_record,
|
7
|
-
:based_near_attributes,
|
8
|
-
:csv_import_detail
|
9
|
-
|
10
|
-
def initialize(csv_import_detail:,
|
11
|
-
existing_record:,
|
12
|
-
update_record:,
|
13
|
-
attrs:)
|
14
|
-
@csv_import_detail = csv_import_detail
|
15
|
-
@depositor = ::User.find(csv_import_detail.depositor_id)
|
16
|
-
@update_record = update_record
|
17
|
-
@existing_record = existing_record
|
18
|
-
@attrs = attrs
|
19
|
-
end
|
20
|
-
|
21
|
-
def attrs
|
22
|
-
@attrs.reject { |k, _v| k == :uploaded_files }
|
23
|
-
end
|
24
|
-
|
25
|
-
def actor_stack
|
26
|
-
terminator = Hyrax::Actors::Terminator.new
|
27
|
-
Zizia::MetadataOnlyStack.build_stack.build(terminator)
|
28
|
-
end
|
29
|
-
|
30
|
-
def started
|
31
|
-
Rails.logger.info "[zizia] event: record_update_started, batch_id: #{csv_import_detail.batch_id}, collection_id: #{csv_import_detail.collection_id}, #{csv_import_detail.deduplication_field}: #{update_record.respond_to?(csv_import_detail.deduplication_field) ? update_record.send(csv_import_detail.deduplication_field.deduplication_field) : update_record}"
|
32
|
-
end
|
33
|
-
|
34
|
-
def succeeded
|
35
|
-
Rails.logger.info "[zizia] event: record_updated, batch_id: #{csv_import_detail.batch_id}, record_id: #{csv_import_detail.existing_record.id}, collection_id: #{csv_import_detail.collection_id}, #{csv_import_detail.deduplication_field}: #{existing_record.respond_to?(csv_import_detail.deduplication_field) ? existing_record.send(csv_import_detail.deduplication_field) : existing_record}"
|
36
|
-
end
|
37
|
-
|
38
|
-
def failed(attr)
|
39
|
-
Rails.logger.error "[zizia] event: validation_failed, batch_id: #{csv_import_detail.batch_id}, collection_id: #{csv_import_detail.collection_id}, attribute: #{attr.capitalize}, message: #{msg}, record_title: record_title: #{attrs[:title] ? attrs[:title] : attrs}"
|
40
|
-
end
|
41
|
-
|
42
|
-
def create_actor_env
|
43
|
-
Hyrax::Actors::Environment.new(existing_record, ::Ability.new(depositor), attrs)
|
44
|
-
end
|
45
|
-
|
46
|
-
def update
|
47
|
-
if actor_stack.update(create_actor_env)
|
48
|
-
csv_import_detail.success_count += 1
|
49
|
-
else
|
50
|
-
existing_record.errors.each_key do |attr, _msg|
|
51
|
-
failed(attr)
|
52
|
-
end
|
53
|
-
csv_import_detail.failure_count += 1
|
54
|
-
end
|
55
|
-
csv_import_detail.save
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
@@ -1,247 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module Zizia
|
3
|
-
class HyraxRecordImporter < RecordImporter
|
4
|
-
# TODO: Get this from Hyrax config
|
5
|
-
DEFAULT_CREATOR_KEY = 'batchuser@example.com'
|
6
|
-
|
7
|
-
attr_accessor :csv_import_detail
|
8
|
-
|
9
|
-
# @!attribute [rw] depositor
|
10
|
-
# @return [User]
|
11
|
-
attr_accessor :depositor
|
12
|
-
|
13
|
-
# @!attribute [rw] collection_id
|
14
|
-
# @return [String] The fedora ID for a Collection.
|
15
|
-
attr_accessor :collection_id
|
16
|
-
|
17
|
-
# @!attribute [rw] batch_id
|
18
|
-
# @return [String] an id number associated with the process that kicked off this import run
|
19
|
-
attr_accessor :batch_id
|
20
|
-
|
21
|
-
# @!attribute [rw] deduplication_field
|
22
|
-
# @return [String] if this is set, look for records with a match in this field
|
23
|
-
# and update the metadata instead of creating a new record. This will NOT re-import file attachments.
|
24
|
-
attr_accessor :deduplication_field
|
25
|
-
|
26
|
-
# @!attribute [rw] success_count
|
27
|
-
# @return [String] the number of records this importer has successfully created
|
28
|
-
attr_accessor :success_count
|
29
|
-
|
30
|
-
# @!attribute [rw] failure_count
|
31
|
-
# @return [String] the number of records this importer has failed to create
|
32
|
-
attr_accessor :failure_count
|
33
|
-
|
34
|
-
# @param attributes [Hash] Attributes that come
|
35
|
-
# from the UI or importer rather than from
|
36
|
-
# the CSV/mapper. These are useful for logging
|
37
|
-
# and tracking the output of an import job for
|
38
|
-
# a given collection, user, or batch.
|
39
|
-
# If a deduplication_field is provided, the system will
|
40
|
-
# look for existing works with that field and matching
|
41
|
-
# value and will update the record instead of creating a new record.
|
42
|
-
# @example
|
43
|
-
# attributes: { collection_id: '123',
|
44
|
-
# depositor_id: '456',
|
45
|
-
# batch_id: '789',
|
46
|
-
# deduplication_field: 'legacy_id'
|
47
|
-
# }
|
48
|
-
def initialize(attributes: {})
|
49
|
-
# These attributes are persisted in the CsvImportDetail model
|
50
|
-
@csv_import_detail = attributes[:csv_import_detail]
|
51
|
-
@deduplication_field = csv_import_detail.deduplication_field
|
52
|
-
@collection_id = csv_import_detail.collection_id
|
53
|
-
@batch_id = csv_import_detail.batch_id
|
54
|
-
@success_count = csv_import_detail.success_count
|
55
|
-
@failure_count = csv_import_detail.failure_count
|
56
|
-
find_depositor(csv_import_detail.depositor_id)
|
57
|
-
end
|
58
|
-
|
59
|
-
# "depositor" is a required field for Hyrax. If
|
60
|
-
# it hasn't been set, set it to the Hyrax default
|
61
|
-
# batch user.
|
62
|
-
def find_depositor(user_key)
|
63
|
-
user = ::User.find_by_user_key(user_key) if user_key
|
64
|
-
user ||= ::User.find(user_key) if user_key
|
65
|
-
user ||= ::User.find_or_create_system_user(DEFAULT_CREATOR_KEY)
|
66
|
-
self.depositor = user
|
67
|
-
end
|
68
|
-
|
69
|
-
##
|
70
|
-
# @param record [ImportRecord]
|
71
|
-
# @return [ActiveFedora::Base]
|
72
|
-
# Search for any existing records that match on the deduplication_field
|
73
|
-
def find_existing_record(record)
|
74
|
-
return unless deduplication_field
|
75
|
-
return unless record.respond_to?(deduplication_field)
|
76
|
-
return if record.mapper.send(deduplication_field).nil?
|
77
|
-
return if record.mapper.send(deduplication_field).empty?
|
78
|
-
existing_records = import_type.where("#{deduplication_field}": record.mapper.send(deduplication_field).to_s)
|
79
|
-
raise "More than one record matches deduplication_field #{deduplication_field} with value #{record.mapper.send(deduplication_field)}" if existing_records.count > 1
|
80
|
-
existing_records&.first
|
81
|
-
end
|
82
|
-
|
83
|
-
##
|
84
|
-
# @param record [ImportRecord]
|
85
|
-
#
|
86
|
-
# @return [void]
|
87
|
-
def import(record:)
|
88
|
-
existing_record = find_existing_record(record)
|
89
|
-
create_for(record: record) unless existing_record
|
90
|
-
update_for(existing_record: existing_record, update_record: record) if existing_record
|
91
|
-
rescue Faraday::ConnectionFailed, Ldp::HttpError => e
|
92
|
-
Rails.logger.error "[zizia] #{e}"
|
93
|
-
rescue RuntimeError => e
|
94
|
-
Rails.logger.error "[zizia] #{e}"
|
95
|
-
raise e
|
96
|
-
end
|
97
|
-
|
98
|
-
# TODO: You should be able to specify the import type in the import
|
99
|
-
def import_type
|
100
|
-
raise 'No curation_concern found for import' unless
|
101
|
-
defined?(Hyrax) && Hyrax&.config&.curation_concerns&.any?
|
102
|
-
|
103
|
-
Hyrax.config.curation_concerns.first
|
104
|
-
end
|
105
|
-
|
106
|
-
# The path on disk where file attachments can be found
|
107
|
-
def file_attachments_path
|
108
|
-
ENV['IMPORT_PATH'] || '/opt/data'
|
109
|
-
end
|
110
|
-
|
111
|
-
# Create a Hyrax::UploadedFile for each file attachment
|
112
|
-
# TODO: What if we can't find the file?
|
113
|
-
# TODO: How do we specify where the files can be found?
|
114
|
-
# @param [Zizia::InputRecord]
|
115
|
-
# @return [Array] an array of Hyrax::UploadedFile ids
|
116
|
-
def create_upload_files(record)
|
117
|
-
return unless record.mapper.respond_to?(:files)
|
118
|
-
files_to_attach = record.mapper.files
|
119
|
-
return [] if files_to_attach.nil? || files_to_attach.empty?
|
120
|
-
|
121
|
-
uploaded_file_ids = []
|
122
|
-
files_to_attach.each do |filename|
|
123
|
-
file = File.open(find_file_path(filename))
|
124
|
-
uploaded_file = Hyrax::UploadedFile.create(user: depositor, file: file)
|
125
|
-
uploaded_file_ids << uploaded_file.id
|
126
|
-
file.close
|
127
|
-
end
|
128
|
-
uploaded_file_ids
|
129
|
-
end
|
130
|
-
|
131
|
-
##
|
132
|
-
# Within the directory specified by ENV['IMPORT_PATH'], find the first
|
133
|
-
# instance of a file matching the given filename.
|
134
|
-
# If there is no matching file, raise an exception.
|
135
|
-
# @param [String] filename
|
136
|
-
# @return [String] a full pathname to the found file
|
137
|
-
def find_file_path(filename)
|
138
|
-
filepath = Dir.glob("#{ENV['IMPORT_PATH']}/**/#{filename}").first
|
139
|
-
raise "Cannot find file #{filename}... Are you sure it has been uploaded and that the filename matches?" if filepath.nil?
|
140
|
-
filepath
|
141
|
-
end
|
142
|
-
|
143
|
-
##
|
144
|
-
# When submitting location data (a.k.a. the "based near" attribute) via the UI,
|
145
|
-
# Hyrax expects to receive a `based_near_attributes` hash in a specific format.
|
146
|
-
# We need to take geonames urls as provided by the customer and transform them to
|
147
|
-
# mimic what the Hyrax UI would ordinarily produce. These will get turned into
|
148
|
-
# Hyrax::ControlledVocabularies::Location objects upon ingest.
|
149
|
-
# The expected hash looks like this:
|
150
|
-
# "based_near_attributes"=>
|
151
|
-
# {
|
152
|
-
# "0"=> {
|
153
|
-
# "id"=>"http://sws.geonames.org/5667009/", "_destroy"=>""
|
154
|
-
# },
|
155
|
-
# "1"=> {
|
156
|
-
# "id"=>"http://sws.geonames.org/6252001/", "_destroy"=>""
|
157
|
-
# },
|
158
|
-
# }
|
159
|
-
# @return [Hash] a "based_near_attributes" hash as
|
160
|
-
def based_near_attributes(based_near)
|
161
|
-
original_geonames_uris = based_near
|
162
|
-
return if original_geonames_uris.empty?
|
163
|
-
based_near_attributes = {}
|
164
|
-
original_geonames_uris.each_with_index do |uri, i|
|
165
|
-
based_near_attributes[i.to_s] = { 'id' => uri_to_sws(uri), "_destroy" => "" }
|
166
|
-
end
|
167
|
-
based_near_attributes
|
168
|
-
end
|
169
|
-
|
170
|
-
#
|
171
|
-
# Take a user-facing geonames URI and return an sws URI, of the form Hyrax expects
|
172
|
-
# (e.g., "http://sws.geonames.org/6252001/")
|
173
|
-
# @param [String] uri
|
174
|
-
# @return [String] an sws style geonames uri
|
175
|
-
def uri_to_sws(uri)
|
176
|
-
uri = URI(uri)
|
177
|
-
geonames_number = uri.path.split('/')[1]
|
178
|
-
"http://sws.geonames.org/#{geonames_number}/"
|
179
|
-
end
|
180
|
-
|
181
|
-
private
|
182
|
-
|
183
|
-
# Update an existing object using the Hyrax actor stack
|
184
|
-
# We assume the object was created as expected if the actor stack returns true.
|
185
|
-
# Note that for now the update stack will only update metadata and update collection membership, it will not re-import files.
|
186
|
-
def update_for(existing_record:, update_record:)
|
187
|
-
updater = case csv_import_detail.update_actor_stack
|
188
|
-
when 'HyraxMetadataOnly'
|
189
|
-
Zizia::HyraxMetadataOnlyUpdater.new(csv_import_detail: csv_import_detail,
|
190
|
-
existing_record: existing_record,
|
191
|
-
update_record: update_record,
|
192
|
-
attrs: process_attrs(record: update_record))
|
193
|
-
when 'HyraxDelete'
|
194
|
-
Zizia::HyraxDeleteFilesUpdater.new(csv_import_detail: csv_import_detail,
|
195
|
-
existing_record: existing_record,
|
196
|
-
update_record: update_record,
|
197
|
-
attrs: process_attrs(record: update_record))
|
198
|
-
when 'HyraxOnlyNew'
|
199
|
-
return unless existing_record[deduplication_field] != update_record.try(deduplication_field)
|
200
|
-
Zizia::HyraxDefaultUpdater.new(csv_import_detail: csv_import_detail,
|
201
|
-
existing_record: existing_record,
|
202
|
-
update_record: update_record,
|
203
|
-
attrs: process_attrs(record: update_record))
|
204
|
-
end
|
205
|
-
updater.update
|
206
|
-
end
|
207
|
-
|
208
|
-
def process_attrs(record:)
|
209
|
-
additional_attrs = {
|
210
|
-
uploaded_files: create_upload_files(record),
|
211
|
-
depositor: depositor.user_key
|
212
|
-
}
|
213
|
-
|
214
|
-
attrs = record.attributes.merge(additional_attrs)
|
215
|
-
attrs = attrs.merge(member_of_collections_attributes: { '0' => { id: collection_id } }) if collection_id
|
216
|
-
|
217
|
-
# Ensure nothing is passed in the files field,
|
218
|
-
# since this is reserved for Hyrax and is where uploaded_files will be attached
|
219
|
-
attrs.delete(:files)
|
220
|
-
based_near = attrs.delete(:based_near)
|
221
|
-
attrs.merge(based_near_attributes: based_near_attributes(based_near)) unless based_near.nil? || based_near.empty?
|
222
|
-
end
|
223
|
-
|
224
|
-
# Create an object using the Hyrax actor stack
|
225
|
-
# We assume the object was created as expected if the actor stack returns true.
|
226
|
-
def create_for(record:)
|
227
|
-
Rails.logger.info "[zizia] event: record_import_started, batch_id: #{batch_id}, collection_id: #{collection_id}, record_title: #{record.respond_to?(:title) ? record.title : record}"
|
228
|
-
|
229
|
-
created = import_type.new
|
230
|
-
attrs = process_attrs(record: record)
|
231
|
-
actor_env = Hyrax::Actors::Environment.new(created,
|
232
|
-
::Ability.new(depositor),
|
233
|
-
attrs)
|
234
|
-
|
235
|
-
if Hyrax::CurationConcern.actor.create(actor_env)
|
236
|
-
Rails.logger.info "[zizia] event: record_created, batch_id: #{batch_id}, record_id: #{created.id}, collection_id: #{collection_id}, record_title: #{attrs[:title]&.first}"
|
237
|
-
csv_import_detail.success_count += 1
|
238
|
-
else
|
239
|
-
created.errors.each do |attr, msg|
|
240
|
-
Rails.logger.error "[zizia] event: validation_failed, batch_id: #{batch_id}, collection_id: #{collection_id}, attribute: #{attr.capitalize}, message: #{msg}, record_title: record_title: #{attrs[:title] ? attrs[:title] : attrs}"
|
241
|
-
end
|
242
|
-
csv_import_detail.failure_count += 1
|
243
|
-
end
|
244
|
-
csv_import_detail.save
|
245
|
-
end
|
246
|
-
end
|
247
|
-
end
|