Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend stacks identifiers to smuggle additional attributes #580

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/controllers/iiif_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ def transformation
end

def stacks_identifier
@stacks_identifier ||= StacksIdentifier.new(escaped_identifier.sub(/^degraded_/, '') + '.jp2')
@stacks_identifier ||= StacksIdentifier.new(escaped_identifier.sub(/^degraded_/, ''), file_ext: 'jp2')
end

def canonical_params
Expand Down
37 changes: 24 additions & 13 deletions app/models/stacks_identifier.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,26 @@

# The identifier of a stacks resource
class StacksIdentifier
def initialize(options = {})
if options.is_a? String
parse_identifer(options)
elsif options[:id]
parse_identifer(options[:id])
elsif options[:druid] && options[:file_name]
self.druid = options[:druid]
@file_name = options[:file_name]
attr_reader :druid, :file_name, :options

OPTIONS_DELIMITER = '%2F!attr!%2F'
def initialize(identifier = nil, id: nil, druid: nil, file_name: nil, file_ext: nil, **options)
if identifier
parse_identifer(identifier, file_ext)
elsif id
parse_identifer(id, file_ext)
elsif druid && file_name
self.druid = druid
@file_name = [file_name, file_ext.presence].compact.join('.')
end
@options = (@options || {}).merge(options)
end

def to_s
[@druid, @file_name].join('%2F')
identifier_part = [@druid, @file_name].join('%2F')
options_part = @options.map { |k, v| "#{k}=#{v}" }.join('%2F')

[identifier_part, options_part.presence].compact.join(OPTIONS_DELIMITER)
end

def ==(other)
Expand All @@ -37,8 +44,6 @@ def treeified_path
File.join(druid_parts[1..4], file_name)
end

attr_reader :druid, :file_name

private

attr_reader :druid_parts
Expand All @@ -49,8 +54,14 @@ def druid=(druid)
@druid_parts = match
end

def parse_identifer(id)
druid, @file_name = id.split('%2F', 2)
def parse_identifer(id, file_ext)
identifier_and_file_name, attrs = id.split(OPTIONS_DELIMITER, 2)
druid, file_name = identifier_and_file_name.split('%2F', 2)
self.druid = druid
@file_name = [file_name, file_ext.presence].compact.join('.')

if attrs.present?
@options = attrs.split('%2F').map { |x| x.split('=', 2) }.to_h
end
end
end
15 changes: 15 additions & 0 deletions spec/models/stacks_identifier_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,19 @@
subject { instance.treeified_path }
it { is_expected.to eq 'nr/349/ct/7889/nr349ct7889_00_0001.jp2' }
end

context 'with some optional attributes' do
let(:instance) { described_class.new identifier }
let(:identifier) { 'nr349ct7889%2Fnr349ct7889_00_0001%2F!attr!%2Fversion=2'}

it 'parses out the right data' do
expect(instance.druid).to eq 'nr349ct7889'
expect(instance.file_name_without_ext).to eq 'nr349ct7889_00_0001'
expect(instance.options['version']).to eq '2'
end

it 'reserializes to the original value' do
expect(instance.to_s).to eq identifier
end
end
end