diff --git a/app/controllers/iiif_controller.rb b/app/controllers/iiif_controller.rb index 8f33ca7cc1..2658f2bdd1 100644 --- a/app/controllers/iiif_controller.rb +++ b/app/controllers/iiif_controller.rb @@ -238,6 +238,9 @@ def manifest "profile" => "https://github.com/benwbrum/fromthepage/wiki/FromThePage-Support-for-the-IIIF-Presentation-API-and-Web-Annotations#plaintext-for-full-text-search", "@id" => iiif_work_export_plaintext_searchable_url(work.id) } + if work.collection.metadata_entry? + manifest.seeAlso << structured_data_reference(work) + end manifest.service << status_service_for_manifest(work) sequence = iiif_sequence_from_work_id(work_id) manifest.sequences << sequence @@ -348,6 +351,46 @@ def layer render :plain => layer.to_json(pretty: true), :content_type => "application/json" end + # endpoint containing actual contents of strucured data + def structured_data_endpoint + if @page + on = { + '@type' => 'sc:Canvas', + '@id' => iiif_canvas_url(@work.id,@page.id), + 'within' => iiif_manifest_url(@work.id) + } + response = page_field_contributions(@page) + else + on = { + '@type' => 'sc:Manifest', + '@id' => iiif_manifest_url(@work.id) + } + response = work_metadata_contributions(@work) + end + response['on'] = on + response['@id'] = structured_data_id(@work,@page) + response['label'] = structured_data_label(@work,@page) + if @page && !@page.notes.blank? + response['notes'] = url_for({:controller => 'iiif', :action => 'list', :page_id => @page.id, :annotation_type => 'notes', :only_path => false}) + end + if @page + response['page_status'] = JSON.parse(status_service_for_page(@page).to_json) + end + response['work_status'] = JSON.parse(status_service_for_manifest(@work).to_json) + + + render :plain => response.to_json(pretty: true), :content_type => "application/json" + end + + # id to structured data endpoint + def structured_data_id(work, page=nil) + if page.nil? + iiif_work_strucured_data_url(work.id) + else + iiif_page_strucured_data_url(work.id, page.id) + end + end + def sequence work_id = @work.id sequence = iiif_sequence_from_work_id(work_id) @@ -447,6 +490,26 @@ def export_work_html end private + def structured_data_label(work, page=nil) + if page + "Structured data (field-based or spreadsheet transcriptions) for canvas" + else + "Structured data (user-created metadata) for manifest" + end + end + + + # stanza to embed within manifests or canvas documents + def structured_data_reference(work, page=nil) + { + '@id' => structured_data_id(work,page), + 'label' => structured_data_label(work,page), + 'format' => 'application/ld+json', + "@context" => "http://www.fromthepage.org/jsonld/structured/1/context.json", + "profile" => "https://github.com/benwbrum/fromthepage/wiki/FromThePage-Support-for-the-IIIF-Presentation-API-and-Web-Annotations#structured-data-service" + } + end + def iiif_page_note(page, noteid) note = IIIF::Presentation::Annotation.new({'motivation' => 'oa:commenting'}) #note['@id'] = url_for({:controller => 'iiif', :action => 'note', :page_id => @page.id, :note_id => noteid, :only_path => false}) @@ -782,6 +845,10 @@ def add_seeAlso_to_canvas(canvas,page) "@id" => iiif_page_export_plaintext_translation_emended_url(page.work_id, page.id) } end + if page.collection.field_based + canvas.seeAlso << structured_data_reference(page.work,page) + end + end def annotationlist_from_page(page,type) diff --git a/app/helpers/export_helper.rb b/app/helpers/export_helper.rb index 7829c56848..63f3e41ee9 100644 --- a/app/helpers/export_helper.rb +++ b/app/helpers/export_helper.rb @@ -610,4 +610,92 @@ def post_process_xml(xml, work) return doc end end + + + def work_metadata_contributions(work) + { + contributors: work_metadata_contributors_to_array, + configuration: field_configuration_to_array(work.collection, TranscriptionField::FieldType::METADATA), + data: work_metadata_to_hash(work), + } + end + + def page_field_contributions(page) + { + contributors: page_contributors_to_array(page), + configuration: field_configuration_to_array(page.work.collection, TranscriptionField::FieldType::TRANSCRIPTION), + data: field_data_to_hash(page), + } + end + + + + def work_metadata_to_hash + nil + end + + def field_data_to_hash(page) + page.table_cells.map{|cell| {row: cell.row, label: cell.header, value: cell.content}} + end + + def spreadsheet_data_to_array + end + + def field_configuration_to_array(collection, field_type) + array = [] + if field_type == TranscriptionField::FieldType::TRANSCRIPTION + fields = collection.transcription_fields + else + fields = collection.metadata_fields + end + fields.each do |field| + element = {label: field.label, input_type: field.input_type, position: field.position, line: field.line_number} + if field.options + if field.input_type == 'multiselect' + element[:options] = field.options.split(/[\n\r]+/) + else + element[:options] = field.options.split(";") + end + end + if field.page_number + element[:page_number] = field.page_number + end + if field.input_type == 'spreadsheet' + columns=[] + field.spreadsheet_columns.each do |column| + column_config = {label: column.label, input_type: column.input_type, position: column.position} + if column.options + column_config[:options] = column.options.split(";") + end + columns << column_config + end + + element[:spreadsheet_columns] = columns + end + array << element + end + + array + end + + def page_contributors_to_array(page) + array = [] + + user_ids = page.deeds.where(deed_type: DeedType.transcriptions_or_corrections).pluck(:user_id).uniq + User.find(user_ids).each do |user| + element = { user_name: user.display_name} + element[:real_name] = user.real_name unless user.real_name.blank? + element[:orcid] = user.real_name unless user.orcid.blank? + array << element + end + + array + end + + def work_metadata_contributors_to_array(work) + nil + end + + + end diff --git a/config/routes.rb b/config/routes.rb index 9a052f5b20..6af2e83500 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -352,8 +352,10 @@ get '/iiif/:page_id/list/:annotation_type', :to => 'iiif#list' get '/iiif/:page_id/notes', :to => 'iiif#notes' get '/iiif/:page_id/note/:note_id', :to => 'iiif#note' - get '/iiif/:work_id/canvas/:page_id', :to => 'iiif#canvas' + get '/iiif/:work_id/canvas/:page_id', :to => 'iiif#canvas', as: 'iiif_canvas' get '/iiif/:work_id/status', :to => 'iiif#manifest_status' + get '/iiif/:work_id/structured', :to => 'iiif#structured_data_endpoint', as: 'iiif_work_strucured_data' + get '/iiif/:work_id/structured/:page_id', :to => 'iiif#structured_data_endpoint', as: 'iiif_page_strucured_data' get '/iiif/:work_id/:page_id/status', :to => 'iiif#canvas_status' # {scheme}://{host}/{prefix}/{identifier}/annotation/{name} get '/iiif/:page_id/annotation/:annotation_type', :to => 'iiif#annotation'