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

V3 annotation, annotationPage and choice object improvements #30

Merged
merged 4 commits into from
Jul 26, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
52 changes: 45 additions & 7 deletions lib/iiif/v3/presentation/annotation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,35 @@ module V3
module Presentation
class Annotation < IIIF::V3::AbstractResource

TYPE = 'Annotation'
TYPE = 'Annotation'.freeze

def required_keys
super + %w{ motivation }
super + %w{ id motivation target }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not seeing target anywhere in the Presentation 3.0 API JSON-examples. Where does this come from?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Annotation itself isn't in the 3.0 API; it has its own spec: http://www.openannotation.org/spec/core/ In the spec it is hasTarget but our JSON expresses it as target

I learned about Annotations for the Triannon linked data project I did a while ago; but mostly I looked at examples -- our purl, Tom Crane's, etc.

end

def abstract_resource_only_keys
super + [ { key: 'body', type: IIIF::V3::Presentation::Resource } ]
def prohibited_keys
super + CONTENT_RESOURCE_PROPERTIES + PAGING_PROPERTIES +
%w{ nav_date viewing_direction start_canvas content_annotations }
end

def any_type_keys
super + %w{ body }
end

def uri_only_keys
super + %w{ id }
end

def string_only_keys
super + %w{ time_mode }
super + %w{ motivation time_mode }
end

def legal_time_mode_values
%w{ trim scale loop }
%w{ trim scale loop }.freeze
end

def legal_viewing_hint_values
super + %w{ none }
end

def initialize(hsh={})
Expand All @@ -30,7 +43,32 @@ def initialize(hsh={})
def validate
super

# time mode values
if self.has_key?('body') && self['body'].kind_of?(IIIF::V3::Presentation::ImageResource)
img_res_class_str = "IIIF::V3::Presentation::ImageResource"

unless self.motivation == 'painting'
m = "#{self.class} motivation must be 'painting' when body is a kind of #{img_res_class_str}"
raise IIIF::V3::Presentation::IllegalValueError, m
end

body_resource = self['body']
body_id = body_resource['id']
if body_id && body_id =~ /^https?:/
validate_uri(body_id, 'anno body ImageResource id') # can raise IllegalValueError
else
m = "when #{self.class} body is a kind of #{img_res_class_str}, ImageResource id must be an http(s) URI"
raise IIIF::V3::Presentation::IllegalValueError, m
end

body_service = *body_resource['service']
body_service_context = *body_resource['service']['@context']
expected_context = IIIF::V3::Presentation::Service::IIIF_IMAGE_V2_CONTEXT
unless body_service && body_service_context && body_service_context.include?(expected_context)
m = "when #{self.class} body is a kind of #{img_res_class_str}, ImageResource's service @context must include #{expected_context}"
raise IIIF::V3::Presentation::IllegalValueError, m
end
end

if self.has_key?('time_mode')
unless self.legal_time_mode_values.include?(self['time_mode'])
m = "timeMode for #{self.class} must be one of #{self.legal_time_mode_values}."
Expand Down
Loading