-
Notifications
You must be signed in to change notification settings - Fork 124
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add file_converter_service which converts the metadata between AF:Fil…
…e and FileMetadata resource
- Loading branch information
Showing
3 changed files
with
168 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# Conversion service for going between files on a valkyrie resource and files on an active fedora object | ||
module Wings | ||
class FileConverterService | ||
class << self | ||
def af_file_to_resource(af_file:) | ||
return unless af_file&.id.present? | ||
attrs = base_af_file_attributes(af_file: af_file) | ||
attrs = metadata_node_to_attributes(metadata_node: af_file.metadata_node, | ||
attributes: attrs) | ||
Hyrax::FileMetadata.new(attrs) | ||
end | ||
|
||
def resource_to_af_file(metadata_resource:) | ||
return unless metadata_resource&.alternate_id.present? | ||
af_file = Hydra::PCDM::File.new(id: metadata_resource.alternate_id.first.to_s) | ||
af_file.content = content(metadata_resource) | ||
af_file.original_name = metadata_resource.original_filename.first | ||
af_file.mime_type = metadata_resource.mime_type.first | ||
valkyrie_attributes_to_af_file(attributes: metadata_resource.attributes, | ||
af_file: af_file) | ||
af_file | ||
end | ||
|
||
private | ||
|
||
# extracts attributes that come from the af_file | ||
def base_af_file_attributes(af_file:) | ||
id = ::Valkyrie::ID.new(af_file.id) | ||
{ id: id, | ||
alternate_id: [id], | ||
file_identifiers: [id], | ||
created_at: af_file.create_date, | ||
updated_at: af_file.modified_date, | ||
content: af_file.content, | ||
size: af_file.size, | ||
original_filename: [af_file.original_name], | ||
mime_type: [af_file.mime_type] } | ||
end | ||
|
||
# extracts attributes that come from the metadata_node | ||
def metadata_node_to_attributes(metadata_node:, attributes:) | ||
af_attrs = metadata_node.attributes.dup | ||
af_attrs.delete('id') | ||
af_attrs.each { |k, v| attributes[k.to_sym] = Array(v) unless attributes.key?(k.to_sym) } | ||
attributes | ||
end | ||
|
||
def valkyrie_attributes_to_af_file(attributes:, af_file:) | ||
attributes.each do |k, v| | ||
next if [:id, :content].include? k | ||
mname = (k.to_s + '=').to_sym | ||
if af_file.respond_to? mname | ||
af_file.send(mname, v) | ||
elsif af_file.metadata_node.respond_to? mname | ||
af_file.metadata_node.send(mname, v) | ||
end | ||
end | ||
end | ||
|
||
def content(metadata_resource) | ||
return nil if metadata_resource.content.nil? || metadata_resource.content.size.zero? | ||
metadata_resource.content.first | ||
end | ||
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,101 @@ | ||
# frozen_string_literal: true | ||
require 'wings_helper' | ||
require 'wings/services/file_converter_service' | ||
|
||
RSpec.describe Wings::FileConverterService do | ||
let(:af_file_id) { af_file.id } | ||
let(:af_attrs) { plain_text_af_attrs } | ||
let(:af_file) do | ||
aff = Hydra::PCDM::File.new(id: 'af_1') | ||
aff.original_name = plain_text_af_attrs[:original_name] | ||
aff.mime_type = plain_text_af_attrs[:mime_type] | ||
aff.content = plain_text_af_attrs[:content] | ||
aff.format_label = plain_text_af_attrs[:format_label] | ||
aff.language = plain_text_af_attrs[:language] | ||
aff.word_count = plain_text_af_attrs[:content].split(' ').count | ||
aff.character_count = plain_text_af_attrs[:content].size | ||
aff.save | ||
aff | ||
end | ||
|
||
describe '#af_file_to_resource' do | ||
subject { described_class.af_file_to_resource(af_file: af_file) } | ||
it 'copies attributes to resource' do # rubocop:disable RSpec/ExampleLength | ||
expect(subject.id.to_s).to eq af_file_id | ||
expect(subject.alternate_id).to match_valkyrie_ids_with_active_fedora_ids [af_file_id] | ||
expect(subject.file_identifiers).to match_valkyrie_ids_with_active_fedora_ids [af_file_id] | ||
expect(subject.created_at).to eq af_file.create_date | ||
expect(subject.updated_at).to eq af_file.modified_date | ||
expect(subject.original_filename).to eq Array(plain_text_af_attrs[:original_name]) | ||
expect(subject.mime_type).to eq Array(plain_text_af_attrs[:mime_type]) | ||
expect(subject.content).to eq Array(plain_text_af_attrs[:content]) | ||
expect(subject.format_label).to eq Array(plain_text_af_attrs[:format_label]) | ||
expect(subject.language).to eq Array(plain_text_af_attrs[:language]) | ||
expect(subject.word_count).to eq Array(plain_text_af_attrs[:content].split(' ').count) | ||
expect(subject.size).to eq Array(plain_text_af_attrs[:content].size) | ||
expect(subject.character_count).to eq Array(plain_text_af_attrs[:content].size) | ||
end | ||
end | ||
|
||
describe '#resource_to_af_file' do | ||
let(:id) { 'val_2' } | ||
let(:valkyrie_id) { ::Valkyrie::ID.new(id) } | ||
let(:valkyrie_attrs) { plain_text_valkyrie_attrs } | ||
let(:file_metadata) do | ||
valkyrie_attrs[:alternate_id] = valkyrie_id | ||
valkyrie_attrs[:file_identifiers] = valkyrie_id | ||
valkyrie_attrs[:word_count] = plain_text_valkyrie_attrs[:content].split(' ').count | ||
valkyrie_attrs[:size] = plain_text_valkyrie_attrs[:content].size | ||
valkyrie_attrs[:character_count] = plain_text_valkyrie_attrs[:content].size | ||
Hyrax::FileMetadata.new(id: valkyrie_id, **valkyrie_attrs) | ||
end | ||
subject { described_class.resource_to_af_file(metadata_resource: file_metadata) } | ||
it 'copies attributes to af_file' do | ||
expect(subject.id.to_s).to eq id | ||
expect(subject.original_name).to eq plain_text_valkyrie_attrs[:original_filename] | ||
validate_af_file_metadata(plain_text_valkyrie_attrs) | ||
end | ||
end | ||
|
||
context 'round trip conversion from af_file to resource to af_file' do | ||
let(:file_metadata) { described_class.af_file_to_resource(af_file: af_file) } | ||
subject { described_class.resource_to_af_file(metadata_resource: file_metadata) } | ||
it 'copies attributes to af_file' do | ||
expect(subject.id.to_s).to eq af_file_id | ||
expect(subject.create_date).to eq af_file.create_date | ||
expect(subject.modified_date).not_to eq af_file.modified_date | ||
expect(subject.original_name).to eq plain_text_af_attrs[:original_name] | ||
validate_af_file_metadata(plain_text_af_attrs) | ||
end | ||
end | ||
|
||
private | ||
|
||
def validate_af_file_metadata(expected_attrs) # rubocop:disable Metrics/AbcSize | ||
expect(subject.mime_type).to eq expected_attrs[:mime_type] | ||
expect(subject.content).to eq expected_attrs[:content] | ||
expect(subject.format_label).to eq Array(expected_attrs[:format_label]) | ||
expect(subject.language).to eq Array(expected_attrs[:language]) | ||
expect(subject.word_count).to eq Array(expected_attrs[:content].split(' ').count) | ||
expect(subject.size).to eq expected_attrs[:content].size | ||
expect(subject.character_count).to eq Array(expected_attrs[:content].size) | ||
end | ||
|
||
def plain_text_af_attrs | ||
{ original_name: 'my_file.txt', | ||
mime_type: 'text/plain', | ||
content: 'some text content for af_file_to_resource test', | ||
format_label: 'Plain Text', | ||
language: 'en' } | ||
end | ||
|
||
def plain_text_valkyrie_attrs | ||
{ original_filename: 'my_file.html', | ||
mime_type: 'text/html', | ||
content: '<h3>different text content for valkyrie_to_af_file test</h3>', | ||
format_label: 'HTML Text', | ||
language: 'en', | ||
created_at: Time.now.getlocal - 5.days, | ||
updated_at: Time.now.getlocal } | ||
end | ||
end |