Skip to content

Commit

Permalink
add file_converter_service which converts the metadata between AF:Fil…
Browse files Browse the repository at this point in the history
…e and FileMetadata resource
  • Loading branch information
elrayle committed Sep 18, 2019
1 parent 11f167a commit 44b9eeb
Show file tree
Hide file tree
Showing 3 changed files with 168 additions and 0 deletions.
1 change: 1 addition & 0 deletions app/models/hyrax/file_metadata.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class FileMetadata < Valkyrie::Resource
attribute :original_filename, ::Valkyrie::Types::Set
attribute :mime_type, ::Valkyrie::Types::Set
attribute :use, ::Valkyrie::Types::Set # AF::File type
attribute :content, ::Valkyrie::Types::Set

# attributes set by fits
attribute :format_label, ::Valkyrie::Types::Set
Expand Down
66 changes: 66 additions & 0 deletions lib/wings/services/file_converter_service.rb
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
101 changes: 101 additions & 0 deletions spec/wings/services/file_converter_service_spec.rb
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

0 comments on commit 44b9eeb

Please sign in to comment.