zizia 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.rubocop.yml +65 -0
  4. data/.rubocop_todo.yml +21 -0
  5. data/.solr_wrapper +8 -0
  6. data/.travis.yml +11 -0
  7. data/Gemfile +12 -0
  8. data/README.md +77 -0
  9. data/Rakefile +34 -0
  10. data/docs/_config.yml +1 -0
  11. data/docs/index.md +98 -0
  12. data/lib/zizia/always_invalid_validator.rb +17 -0
  13. data/lib/zizia/hash_mapper.rb +44 -0
  14. data/lib/zizia/hyrax_basic_metadata_mapper.rb +149 -0
  15. data/lib/zizia/hyrax_record_importer.rb +261 -0
  16. data/lib/zizia/importer.rb +61 -0
  17. data/lib/zizia/input_record.rb +65 -0
  18. data/lib/zizia/log_stream.rb +43 -0
  19. data/lib/zizia/metadata_mapper.rb +83 -0
  20. data/lib/zizia/metadata_only_stack.rb +70 -0
  21. data/lib/zizia/parser.rb +132 -0
  22. data/lib/zizia/parsers/csv_parser.rb +45 -0
  23. data/lib/zizia/record_importer.rb +57 -0
  24. data/lib/zizia/spec/fakes/fake_parser.rb +22 -0
  25. data/lib/zizia/spec/shared_examples/a_mapper.rb +32 -0
  26. data/lib/zizia/spec/shared_examples/a_message_stream.rb +11 -0
  27. data/lib/zizia/spec/shared_examples/a_parser.rb +73 -0
  28. data/lib/zizia/spec/shared_examples/a_validator.rb +46 -0
  29. data/lib/zizia/spec.rb +15 -0
  30. data/lib/zizia/streams/formatted_message_stream.rb +70 -0
  31. data/lib/zizia/validator.rb +117 -0
  32. data/lib/zizia/validators/csv_format_validator.rb +26 -0
  33. data/lib/zizia/validators/title_validator.rb +30 -0
  34. data/lib/zizia/version.rb +5 -0
  35. data/lib/zizia.rb +73 -0
  36. data/log/.keep +0 -0
  37. data/spec/fixtures/bad_example.csv +2 -0
  38. data/spec/fixtures/example.csv +4 -0
  39. data/spec/fixtures/hyrax/example.csv +3 -0
  40. data/spec/fixtures/images/animals/cat.png +0 -0
  41. data/spec/fixtures/images/zizia.png +0 -0
  42. data/spec/fixtures/zizia.png +0 -0
  43. data/spec/integration/import_csv_spec.rb +28 -0
  44. data/spec/integration/import_hyrax_csv.rb +71 -0
  45. data/spec/spec_helper.rb +18 -0
  46. data/spec/stdout_stream_spec.rb +9 -0
  47. data/spec/support/hyrax/basic_metadata.rb +30 -0
  48. data/spec/support/hyrax/core_metadata.rb +15 -0
  49. data/spec/support/shared_contexts/with_work_type.rb +101 -0
  50. data/spec/zizia/csv_format_validator_spec.rb +38 -0
  51. data/spec/zizia/csv_parser_spec.rb +73 -0
  52. data/spec/zizia/formatted_message_stream_spec.rb +35 -0
  53. data/spec/zizia/hash_mapper_spec.rb +8 -0
  54. data/spec/zizia/hyrax_basic_metadata_mapper_spec.rb +190 -0
  55. data/spec/zizia/hyrax_record_importer_spec.rb +178 -0
  56. data/spec/zizia/importer_spec.rb +46 -0
  57. data/spec/zizia/input_record_spec.rb +71 -0
  58. data/spec/zizia/parser_spec.rb +47 -0
  59. data/spec/zizia/record_importer_spec.rb +70 -0
  60. data/spec/zizia/title_validator_spec.rb +23 -0
  61. data/spec/zizia/validator_spec.rb +9 -0
  62. data/spec/zizia/version_spec.rb +7 -0
  63. data/spec/zizia_spec.rb +19 -0
  64. data/zizia.gemspec +34 -0
  65. metadata +246 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 488d9a3f2c71f53ed2134084ed2c9acb446b1eae14f4ce9c0a8959557297a733
4
+ data.tar.gz: c4bc95f1c51e4f619329ad287cdbe15234501bdf0695d8beb42f0d9c99355339
5
+ SHA512:
6
+ metadata.gz: 5e53b4a49325cab2f77a6fd714e73b9de8c269fff9960daf211897ecad7cd40c81d75ad92ef68a8d8d7bf6bf822b1044e4969888c887bb7e21d4b8198ab2d4e0
7
+ data.tar.gz: 010b019094941db98acbe9bfd2a92df88f150a45d9cd1de23337dcf74b0525c4f1430715a9c0a87a01dea9b8bf5bc3dac714fb9be4df7fca64ab1e8161fe84d7
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ pkg
2
+ tmp
3
+ Gemfile.lock
4
+ .byebug_history
5
+ .fcrepo_wrapper_test.yml
6
+ .solr_wrapper_test.yml
7
+ zizia_import.log
8
+ *~
9
+ \#*\#
10
+ /.emacs.desktop
11
+ /.emacs.desktop.lock
12
+ *.elc
13
+ auto-save-list
14
+ tramp
15
+ .\#*
data/.rubocop.yml ADDED
@@ -0,0 +1,65 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
3
+ inherit_gem:
4
+ bixby: bixby_default.yml
5
+
6
+ AllCops:
7
+ TargetRubyVersion: 2.3
8
+
9
+ Lint/HandleExceptions:
10
+ Exclude:
11
+ - 'spec/**/*'
12
+ - 'lib/zizia/spec/**/*'
13
+
14
+ Metrics/AbcSize:
15
+ Exclude:
16
+ - 'spec/support/hyrax/basic_metadata.rb'
17
+ - 'lib/zizia/hyrax_record_importer.rb'
18
+
19
+ Metrics/BlockLength:
20
+ Exclude:
21
+ - 'spec/**/*'
22
+ - 'lib/zizia/spec/**/*'
23
+
24
+ Metrics/ClassLength:
25
+ Enabled: false
26
+
27
+ Metrics/CyclomaticComplexity:
28
+ Exclude:
29
+ - lib/zizia/hyrax_basic_metadata_mapper.rb
30
+ - lib/zizia/hyrax_record_importer.rb
31
+
32
+ Metrics/LineLength:
33
+ Enabled: false
34
+
35
+ Metrics/MethodLength:
36
+ Exclude:
37
+ - 'spec/support/hyrax/basic_metadata.rb'
38
+ - 'lib/zizia/hyrax_basic_metadata_mapper.rb'
39
+ - lib/zizia/hyrax_record_importer.rb
40
+
41
+ Metrics/PerceivedComplexity:
42
+ Exclude:
43
+ - lib/zizia/hyrax_record_importer.rb
44
+
45
+ Naming/AccessorMethodName:
46
+ Exclude:
47
+ - lib/zizia/hyrax_record_importer.rb
48
+
49
+ RSpec/DescribeClass:
50
+ Exclude:
51
+ - 'spec/integration/**/*'
52
+ - 'spec/*_spec.rb'
53
+
54
+ RSpec/ExampleLength:
55
+ Exclude:
56
+ - 'spec/zizia/hyrax_basic_metadata_mapper_spec.rb'
57
+ - 'spec/integration/import_hyrax_csv.rb'
58
+
59
+ RSpec/MultipleExpectations:
60
+ Exclude:
61
+ - 'spec/zizia/hyrax_basic_metadata_mapper_spec.rb'
62
+ - 'spec/integration/import_hyrax_csv.rb'
63
+
64
+ Style/StructInheritance:
65
+ Enabled: false
data/.rubocop_todo.yml ADDED
@@ -0,0 +1,21 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2019-02-21 09:32:03 -0500 using RuboCop version 0.52.1.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 1
10
+ Metrics/CyclomaticComplexity:
11
+ Max: 7
12
+
13
+ # Offense count: 1
14
+ # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
15
+ # URISchemes: http, https
16
+ Metrics/LineLength:
17
+ Max: 228
18
+
19
+ # Offense count: 1
20
+ Metrics/PerceivedComplexity:
21
+ Max: 8
data/.solr_wrapper ADDED
@@ -0,0 +1,8 @@
1
+ version: 6.6.5
2
+ port: 8985
3
+ instance_dir: tmp/solr-test
4
+ download_dir: tmp/solr_downloads
5
+ collection:
6
+ persist: false
7
+ dir: solr/config
8
+ name: hydra-test
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ sudo: false
3
+ cache: bundler
4
+ dist: trusty
5
+
6
+ rvm:
7
+ - 2.3.8
8
+ - 2.4.5
9
+ - 2.5.3
10
+ script:
11
+ - bundle exec rake
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
+
7
+ gemspec
8
+
9
+ unless ENV['CI']
10
+ gem 'guard'
11
+ gem 'pry'
12
+ end
data/README.md ADDED
@@ -0,0 +1,77 @@
1
+ # Zizia
2
+
3
+ <table width="100%">
4
+ <tr><td>
5
+ <img alt="Zizia image" src="https://camo.githubusercontent.com/87eafa4a5b6a84802eab583e532bb33881b8a7ab/68747470733a2f2f7777772e706572766572646f6e6b2e636f6d2f77696c64253230666c6f776572732f506172736e69702f476f6c64656e253230416c6578616e646572732f323030383038253230476f6c64656e253230416c6578616e646572253230285a697a69612532306175726561292532302d2532304e47532532302d253230746865253230426f6f6b2532306f6625323057696c64253230466c6f776572732e6a7067" width="500px">
6
+ </td><td>
7
+ Object import for Hyrax. See the <a href="https://www.rubydoc.info/gems/zizia">API documentation</a> for more
8
+ information. See the <a href="https://curationexperts.github.io/zizia/">Getting Started</a> guide for a gentle introduction.
9
+ <br/><br/>
10
+
11
+
12
+ [![Gem Version](https://badge.fury.io/rb/zizia.svg)](https://badge.fury.io/rb/zizia)
13
+ [![Build Status](https://travis-ci.org/curationexperts/zizia.svg?branch=master)](https://travis-ci.org/curationexperts/zizia)
14
+ [![Yard Docs](http://img.shields.io/badge/yard-docs-blue.svg)](http://www.rubydoc.info/gems/zizia)
15
+
16
+ </td></tr>
17
+ </table>
18
+
19
+ ## Usage
20
+
21
+ In your project's `Gemfile`, add: `gem 'zizia'`, then run `bundle install`.
22
+
23
+ To do a basic Hyrax import, first ensure that a [work type is registered](http://www.rubydoc.info/github/samvera/hyrax/Hyrax/Configuration#register_curation_concern-instance_method)
24
+ with your `Hyrax` application. Then write a class like this:
25
+
26
+ ```ruby
27
+ require 'zizia'
28
+
29
+ class MyImporter
30
+ def initialize(csv_file)
31
+ @csv_file = csv_file
32
+ raise "Cannot find expected input file #{csv_file}" unless File.exist?(csv_file)
33
+ end
34
+
35
+ def import
36
+ attrs = {
37
+ collection_id: collection_id, # pass a collection id to the record importer and all records will be added to that collection
38
+ depositor_id: depositor_id, # pass a Hyrax user_key here and that Hyrax user will own all objects created during this import
39
+ deduplication_field: 'identifier' # pass a field with a persistent identifier (e.g., ARK) and it will check to see if a record with that identifier already
40
+ } # exists, update its metadata if so, and only if it doesn't find a record with that identifier will it make a new object.
41
+
42
+ file = File.open(@csv_file)
43
+ parser = Zizia::CsvParser.new(file: file)
44
+ record_importer = Zizia::HyraxRecordImporter.new(attributes: attrs)
45
+ Zizia::Importer.new(parser: parser, record_importer: record_importer).import
46
+ file.close # unless a block is passed to File.open, the file must be explicitly closed
47
+ end
48
+ end
49
+ ```
50
+
51
+ You can find [an example csv file for import to Hyrax](https://github.com/curationexperts/zizia/blob/master/spec/fixtures/hyrax/example.csv) in the fixtures directory. Files for attachment should have the filename in a column
52
+ with a heading of `files`, and the location of the files should be specified via an
53
+ environment variables called `IMPORT_PATH`. If `IMPORT_PATH` is not set, `HyraxRecordImporter` will look in `/opt/data` by default.
54
+
55
+ ## Customizing
56
+ To input any kind of file other than CSV, you need to provide a `Parser` (out of the box, we support simple CSV import with `CsvParser`). We will be writing guides about
57
+ how to support custom mappers (for metadata outside of Hyrax's core and basic metadata fields).
58
+
59
+ This software is primarily intended for use in a [Hyrax](https://github.com/samvera/hyrax) project.
60
+ However, its dependency on `hyrax` is kept strictly optional so most of its code can be reused to
61
+ good effect elsewhere. Note: As of release 2.0, `HyraxBasicMetadataMapper` will be the default mapper.
62
+
63
+ ## Development
64
+
65
+ ```sh
66
+ git clone https://github.com/curationexperts/zizia
67
+ cd zizia
68
+
69
+ bundle install
70
+ bundle exec rake ci
71
+ ```
72
+
73
+ ### RSpec Support
74
+
75
+ This gem ships with RSpec shared examples and other support tools intended to ease testing and ensure
76
+ interoperability of client code. These can be included by adding `require 'zizia/spec'` to a
77
+ `spec_helper.rb` or `rails_helper.rb` file in your application's test suite.
data/Rakefile ADDED
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require 'bundler/setup'
5
+ rescue LoadError
6
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
7
+ end
8
+
9
+ require 'fcrepo_wrapper'
10
+ require 'solr_wrapper'
11
+ require 'active_fedora/rake_support'
12
+
13
+ require 'rspec/core/rake_task'
14
+ require 'rubocop/rake_task'
15
+
16
+ Bundler::GemHelper.install_tasks
17
+
18
+ desc 'Run style checker'
19
+ RuboCop::RakeTask.new(:rubocop) do |task|
20
+ task.fail_on_error = true
21
+ end
22
+
23
+ desc 'Run specs'
24
+ RSpec::Core::RakeTask.new(:spec)
25
+
26
+ desc 'Run specs with Fedora & Solr servers'
27
+ task :spec_with_server do
28
+ with_test_server { Rake::Task['spec'].invoke }
29
+ end
30
+
31
+ desc 'Check style and run specs'
32
+ task ci: %w[rubocop spec_with_server]
33
+
34
+ task default: :ci
data/docs/_config.yml ADDED
@@ -0,0 +1 @@
1
+ theme: jekyll-theme-minimal
data/docs/index.md ADDED
@@ -0,0 +1,98 @@
1
+ # Importing to Hyrax with Zizia
2
+
3
+ ## Getting Started
4
+ The simplest use case is importing content that matches [Hyrax's core and basic metadata fields](http://samvera.github.io/metadata_application_profile.html), plus a few extra fields that let Hyrax know how to display the content properly. At a very high level we're going to:
5
+ 1. Write a simple import test first
6
+ 1. Get the test passing
7
+ 1. Write a rake task to run your import with real data
8
+
9
+ **Note:** This guide assumes that you already have a working Hyrax instance with at least one work type. If you need help doing that, see [the Hyrax documentation](https://github.com/samvera/hyrax#creating-a-hyrax-based-app). This guide is going to assume we're using an `Image` work type and attaching image files, but should be applicable to any work type or kind of attachment.
10
+
11
+ ### 1. Write a simple import test
12
+ 1. Make a directory for your importer: `mkdir app/importers`
13
+ 1. Make a directory for your importer tests: `mkdir spec/importers`
14
+ 1. Make a directory for your fixture files: `mkdir spec/fixtures/images`
15
+ 1. Put three small images in `spec/fixtures/images` In this guide, we're using copyright free images from https://www.pexels.com/, `birds.jpg`, `cat.jpg`, and `dog.jpg`.
16
+ 1. Make a directory for your CSV fixture files: `mkdir spec/fixtures/csv_import`
17
+ 1. Put a file like this in `spec/fixtures/csv_import`:
18
+ ```
19
+ title,source,visibility
20
+ "A Cute Dog",https://www.pexels.com/photo/animal-blur-canine-close-up-551628/,open
21
+ "An Interesting Cat",https://www.pexels.com/photo/person-holding-white-cat-1383397/,open
22
+ "A Flock of Birds",https://www.pexels.com/photo/animal-avian-beak-birds-203088/,open
23
+ ```
24
+ 1. Make a file called `spec/importers/modular_importer_spec.rb` that contains this:
25
+ ```ruby
26
+ # frozen_string_literal: true
27
+
28
+ require 'rails_helper'
29
+ require 'active_fedora/cleaner'
30
+
31
+ RSpec.describe ModularImporter do
32
+ let(:modular_csv) { 'spec/fixtures/csv_import/modular_input.csv' }
33
+ let(:user) { ::User.batch_user }
34
+
35
+ before do
36
+ DatabaseCleaner.clean
37
+ ActiveFedora::Cleaner.clean!
38
+ end
39
+
40
+ it "imports a csv" do
41
+ expect { ModularImporter.new(modular_csv).import }.to change { Work.count }.by 3
42
+ end
43
+ end
44
+ ```
45
+ 1. Make a file called `app/importers/modular_importer.rb` that contains just enough of an importer class that your test can run and give a meaningful error:
46
+ ```ruby
47
+ class ModularImporter
48
+ def initialize(csv_file)
49
+ @csv_file = csv_file
50
+ raise "Cannot find expected input file #{csv_file}" unless File.exist?(csv_file)
51
+ end
52
+
53
+ def import
54
+ end
55
+ end
56
+ ```
57
+ 1. Run your test:
58
+ ```
59
+ bundle exec rspec spec/importers/modular_importer_spec.rb
60
+ ```
61
+ It should fail with a message like
62
+ ```
63
+ expected `Work.count` to have changed by 3, but was changed by 0
64
+ ```
65
+
66
+ So, at this point, your test is running, but the importer isn't yet creating any records.
67
+
68
+ ### 2. Get the test passing
69
+ 1. Add the zizia gem to your `Gemfile` and run bundle update:
70
+ ```
71
+ gem `zizia`
72
+ ```
73
+ 2. Edit `app/importer/modular_importer.rb` so it looks like this:
74
+ ```ruby
75
+ require 'zizia'
76
+
77
+ class ModularImporter
78
+ def initialize(csv_file)
79
+ @csv_file = csv_file
80
+ raise "Cannot find expected input file #{csv_file}" unless File.exist?(csv_file)
81
+ end
82
+
83
+ def import
84
+ file = File.open(@csv_file)
85
+ Zizia::Importer.new(parser: Zizia::CsvParser.new(file: file), record_importer: Zizia::HyraxRecordImporter.new).import
86
+ file.close # Note that we must close any files we open.
87
+ end
88
+ end
89
+ ```
90
+ 3. Now your test should pass with output something like this:
91
+
92
+ ```
93
+ ModularImporter
94
+ Creating record: ["A Cute Dog"].Record created at: jw827b648Record created at: jw827b648Creating record: ["An Interesting Cat"].Record created at: 3n203z084Record created at: 3n203z084Creating record: ["A Flock of Birds"].Record created at: wm117n96bRecord created at: wm117n96b imports a csv
95
+
96
+ Finished in 7.56 seconds (files took 9.06 seconds to load)
97
+ 1 example, 0 failures
98
+ ```
@@ -0,0 +1,17 @@
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
@@ -0,0 +1,44 @@
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
@@ -0,0 +1,149 @@
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