This repository has been archived by the owner on Nov 9, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Mapper for Hyrax metadata. Story #12.
* The mapper can handle any fields that are defined in `Hyrax::CoreMetadata` or `Hyrax::BasicMetadata`. * If you are importing from a CSV file, the CSV headers should exactly match the property names. For an example, see: spec/fixtures/hyrax/example.csv * For fields with multiple values, there is a default delimiter that will be used to separate the values. You can set your own delimiter if you need to. * I removed the code that automatically requires files from the spec/support directory because there are some support files that define the `Hyrax` module and other hyrax-y classes. We don't want to load them for all tests because we don't want to accidentally have a dependency on Hyrax. Only load them in the exact tests where you need them. * Out of scope: Transforming data. I didn't attempt to convert any values to `RDF::URI` or `Date` objects. All values are just imported as `String`s. See: http://samvera.github.io/metadata_application_profile.html
- Loading branch information
Showing
12 changed files
with
322 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
# frozen_string_literal: true | ||
|
||
module Darlingtonia | ||
## | ||
# A mapper for Hyrax metadata. | ||
# | ||
# Maps from hash accessor syntax (`['title']`) to method call dot syntax (`.title`). | ||
# | ||
# The fields provided by this mapper are the same as the properties defined in `Hyrax::CoreMetadata` and `Hyrax::BasicMetadata`. | ||
# | ||
# @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`. | ||
# | ||
# @see HashMapper Parent class for more info and examples. | ||
class HyraxBasicMetadataMapper < HashMapper | ||
## | ||
# @return [Enumerable<Symbol>] The fields the mapper can process. | ||
def fields | ||
core_fields + basic_fields | ||
end | ||
|
||
# Properties defined with `multiple: false` in | ||
# Hyrax should return a single value instead of | ||
# an Array of values. | ||
def depositor | ||
metadata['depositor'] | ||
end | ||
|
||
def date_uploaded | ||
metadata['date_uploaded'] | ||
end | ||
|
||
def date_modified | ||
metadata['date_modified'] | ||
end | ||
|
||
def label | ||
metadata['label'] | ||
end | ||
|
||
def relative_path | ||
metadata['relative_path'] | ||
end | ||
|
||
def import_url | ||
metadata['import_url'] | ||
end | ||
|
||
## | ||
# @return [String] The delimiter that will be used to split a metadata field into separate values. | ||
# @example | ||
# mapper = HyraxBasicMetadataMapper.new | ||
# mapper.metadata = { 'language' => 'English|~|French|~|Japanese' } | ||
# mapper.language = ['English', 'French', 'Japanese'] | ||
# | ||
def delimiter | ||
@delimiter ||= '|~|' | ||
end | ||
attr_writer :delimiter | ||
|
||
## | ||
# @see MetadataMapper#map_field | ||
def map_field(name) | ||
Array(metadata[name.to_s]&.split(delimiter)) | ||
end | ||
|
||
protected | ||
|
||
# Properties defined in Hyrax::CoreMetadata | ||
def core_fields | ||
[:depositor, :title, :date_uploaded, :date_modified] | ||
end | ||
|
||
# Properties defined in Hyrax::BasicMetadata | ||
def basic_fields | ||
[:label, :relative_path, :import_url, | ||
:resource_type, :creator, :contributor, | ||
:description, :keyword, :license, | ||
:rights_statement, :publisher, :date_created, | ||
:subject, :language, :identifier, | ||
:based_near, :related_url, | ||
:bibliographic_citation, :source] | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# frozen_string_literal: true | ||
require 'spec_helper' | ||
|
||
describe Darlingtonia::HyraxBasicMetadataMapper do | ||
let(:mapper) { described_class.new } | ||
|
||
# Properties defined in Hyrax::CoreMetadata | ||
let(:core_fields) do | ||
[:depositor, :title, :date_uploaded, :date_modified] | ||
end | ||
|
||
# Properties defined in Hyrax::BasicMetadata | ||
let(:basic_fields) do | ||
[:label, :relative_path, :import_url, | ||
:resource_type, :creator, :contributor, | ||
:description, :keyword, :license, | ||
:rights_statement, :publisher, :date_created, | ||
:subject, :language, :identifier, :based_near, | ||
:related_url, :bibliographic_citation, :source] | ||
end | ||
|
||
it_behaves_like 'a Darlingtonia::Mapper' do | ||
let(:metadata) do | ||
{ title: ['A Title for a Record'], | ||
my_custom_field: ['This gets ignored'] } | ||
end | ||
let(:expected_fields) { core_fields + basic_fields } | ||
end | ||
|
||
context 'with metadata, but some missing fields' do | ||
before { mapper.metadata = metadata } | ||
let(:metadata) do | ||
{ 'depositor' => 'someone@example.org', | ||
'title' => 'A Title', | ||
'language' => 'English' } | ||
end | ||
|
||
it 'provides methods for the fields, even fields that aren\'t included in the metadata' do | ||
expect(metadata).to include('title') | ||
expect(mapper).to respond_to(:title) | ||
|
||
expect(metadata).not_to include('label') | ||
expect(mapper).to respond_to(:label) | ||
end | ||
|
||
it 'returns single values for single-value fields' do | ||
expect(mapper.depositor).to eq 'someone@example.org' | ||
expect(mapper.date_uploaded).to eq nil | ||
expect(mapper.date_modified).to eq nil | ||
expect(mapper.label).to eq nil | ||
expect(mapper.relative_path).to eq nil | ||
expect(mapper.import_url).to eq nil | ||
end | ||
|
||
it 'returns array values for multi-value fields' do | ||
expect(mapper.title).to eq ['A Title'] | ||
expect(mapper.language).to eq ['English'] | ||
expect(mapper.keyword).to eq [] | ||
expect(mapper.subject).to eq [] | ||
end | ||
end | ||
|
||
context 'fields with multiple values' do | ||
before { mapper.metadata = metadata } | ||
let(:metadata) do | ||
{ 'title' => 'A Title', | ||
'language' => 'English|~|French|~|Japanese' } | ||
end | ||
|
||
it 'splits the values using the delimiter' do | ||
expect(mapper.title).to eq ['A Title'] | ||
expect(mapper.language).to eq ['English', 'French', 'Japanese'] | ||
expect(mapper.keyword).to eq [] | ||
end | ||
|
||
it 'can set a different delimiter' do | ||
expect(mapper.delimiter).to eq '|~|' | ||
mapper.delimiter = 'ಠ_ಠ' | ||
expect(mapper.delimiter).to eq 'ಠ_ಠ' | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
title,depositor,date_uploaded,date_modified,label,relative_path,import_url,resource_type,creator,contributor,description,keyword,license,rights_statement,publisher,date_created,subject,language,identifier,based_near,related_url,bibliographic_citation,source | ||
Work 1 Title,user@example.com,2018-12-21,2018-01-01,Work 1 Label,tmp/files,https://example.com,Work 1 Type,Work 1 creator,Work 1 contrib,Desc 1,Key 1,Lic 1,RS 1,Pub 1,2018-06-06,Subj 1,English|~|Japanese,Ident 1,Based 1,https://example.com/related,Bib 1,Source 1 | ||
Work 2 Title,,1970-12-21,,Work 2 Label,,,Work 2 Type,,,Desc 2,,,,Pub 2,,Subj 2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
# frozen_string_literal: true | ||
require 'spec_helper' | ||
|
||
describe 'importing a CSV with Hyrax defaults', :clean do | ||
subject(:importer) { Darlingtonia::Importer.new(parser: parser) } | ||
let(:parser) { Darlingtonia::CsvParser.new(file: csv_file) } | ||
|
||
let(:csv_file) { File.open('spec/fixtures/hyrax/example.csv') } | ||
after { csv_file.close } | ||
|
||
before do | ||
# Force it to use the Hyrax mapper instead of the default mapper | ||
allow(Darlingtonia::HashMapper).to receive(:new).and_return(Darlingtonia::HyraxBasicMetadataMapper.new) | ||
end | ||
|
||
load File.expand_path("../../support/shared_contexts/with_work_type.rb", __FILE__) | ||
include_context 'with a work type' | ||
|
||
it 'creates the record(s)' do | ||
expect { importer.import }.to change { Work.count }.to 2 | ||
|
||
works = Work.all | ||
work1 = works.find { |w| w.title == ['Work 1 Title'] } | ||
work2 = works.find { |w| w.title == ['Work 2 Title'] } | ||
|
||
# First Record | ||
expect(work1.depositor).to eq 'user@example.com' | ||
expect(work1.date_uploaded).to eq '2018-12-21' | ||
expect(work1.date_modified).to eq '2018-01-01' | ||
expect(work1.label).to eq 'Work 1 Label' | ||
expect(work1.relative_path).to eq 'tmp/files' | ||
expect(work1.import_url).to eq 'https://example.com' | ||
expect(work1.resource_type).to eq ['Work 1 Type'] | ||
expect(work1.creator).to eq ['Work 1 creator'] | ||
expect(work1.contributor).to eq ['Work 1 contrib'] | ||
expect(work1.description).to eq ['Desc 1'] | ||
expect(work1.keyword).to eq ['Key 1'] | ||
expect(work1.license).to eq ['Lic 1'] | ||
expect(work1.rights_statement).to eq ['RS 1'] | ||
expect(work1.publisher).to eq ['Pub 1'] | ||
expect(work1.date_created).to eq ['2018-06-06'] | ||
expect(work1.subject).to eq ['Subj 1'] | ||
|
||
# An example with 2 values | ||
expect(work1.language).to contain_exactly('English', 'Japanese') | ||
|
||
expect(work1.identifier).to eq ['Ident 1'] | ||
expect(work1.based_near).to eq ['Based 1'] | ||
expect(work1.related_url).to eq ['https://example.com/related'] | ||
expect(work1.bibliographic_citation).to eq ['Bib 1'] | ||
expect(work1.source).to eq ['Source 1'] | ||
|
||
# Second Record | ||
expect(work2.depositor).to be_nil | ||
expect(work2.date_uploaded).to eq '1970-12-21' | ||
expect(work2.date_modified).to be_nil | ||
expect(work2.label).to eq 'Work 2 Label' | ||
expect(work2.relative_path).to be_nil | ||
expect(work2.import_url).to be_nil | ||
expect(work2.resource_type).to eq ['Work 2 Type'] | ||
expect(work2.creator).to eq [] | ||
expect(work2.contributor).to eq [] | ||
expect(work2.description).to eq ['Desc 2'] | ||
expect(work2.keyword).to eq [] | ||
expect(work2.license).to eq [] | ||
expect(work2.rights_statement).to eq [] | ||
expect(work2.publisher).to eq ['Pub 2'] | ||
expect(work2.date_created).to eq [] | ||
expect(work2.subject).to eq ['Subj 2'] | ||
expect(work2.language).to eq [] | ||
expect(work2.identifier).to eq [] | ||
expect(work2.based_near).to eq [] | ||
expect(work2.related_url).to eq [] | ||
expect(work2.bibliographic_citation).to eq [] | ||
expect(work2.source).to eq [] | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# frozen_string_literal: true | ||
|
||
module Hyrax | ||
module BasicMetadata | ||
def self.included(work) | ||
work.property :label, predicate: ActiveFedora::RDF::Fcrepo::Model.downloadFilename, multiple: false | ||
work.property :relative_path, predicate: ::RDF::URI.new('http://scholarsphere.psu.edu/ns#relativePath'), multiple: false | ||
work.property :import_url, predicate: ::RDF::URI.new('http://scholarsphere.psu.edu/ns#importUrl'), multiple: false | ||
work.property :resource_type, predicate: ::RDF::Vocab::DC.type | ||
work.property :creator, predicate: ::RDF::Vocab::DC11.creator | ||
work.property :contributor, predicate: ::RDF::Vocab::DC11.contributor | ||
work.property :description, predicate: ::RDF::Vocab::DC11.description | ||
work.property :keyword, predicate: ::RDF::Vocab::DC11.relation | ||
work.property :license, predicate: ::RDF::Vocab::DC.rights | ||
work.property :rights_statement, predicate: ::RDF::Vocab::EDM.rights | ||
work.property :publisher, predicate: ::RDF::Vocab::DC11.publisher | ||
work.property :date_created, predicate: ::RDF::Vocab::DC.created | ||
work.property :subject, predicate: ::RDF::Vocab::DC11.subject | ||
work.property :language, predicate: ::RDF::Vocab::DC11.language | ||
work.property :identifier, predicate: ::RDF::Vocab::DC.identifier | ||
|
||
# Note: based_near is defined differently here than in Hyrax. | ||
work.property :based_near, predicate: ::RDF::Vocab::FOAF.based_near | ||
|
||
work.property :related_url, predicate: ::RDF::RDFS.seeAlso | ||
work.property :bibliographic_citation, predicate: ::RDF::Vocab::DC.bibliographicCitation | ||
work.property :source, predicate: ::RDF::Vocab::DC.source | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# frozen_string_literal: true | ||
|
||
module Hyrax | ||
module CoreMetadata | ||
def self.included(work) | ||
work.property :depositor, predicate: ::RDF::URI.new('http://id.loc.gov/vocabulary/relators/dpt'), multiple: false | ||
|
||
work.property :title, predicate: ::RDF::Vocab::DC.title | ||
|
||
work.property :date_uploaded, predicate: ::RDF::Vocab::DC.dateSubmitted, multiple: false | ||
|
||
work.property :date_modified, predicate: ::RDF::Vocab::DC.modified, multiple: false | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters