Skip to content
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 Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ gem 'json-ld'


# Rack middleware
gem 'ffi'
gem 'ffi', '~> 1.15.5'
gem 'rack-accept', '~> 0.4'
gem 'rack-attack', '~> 6.6.1', require: 'rack/attack'
gem 'rack-cache', '~> 1.13.0'
Expand Down
16 changes: 8 additions & 8 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ GIT

GIT
remote: https://github.com/ontoportal-lirmm/goo.git
revision: b2a635fb1e8206e6e3010be4dbe033b47eb58481
revision: a95245b8c964431505ca6315907440996c59a00d
branch: development
specs:
goo (0.0.2)
Expand Down Expand Up @@ -40,7 +40,7 @@ GIT

GIT
remote: https://github.com/ontoportal-lirmm/ncbo_cron.git
revision: 6bb53a13f514a60513afe25e37c5c69475140452
revision: fabd04ef4fa37989d526fc6a7aa1e98830008dae
branch: master
specs:
ncbo_cron (0.0.1)
Expand All @@ -57,7 +57,7 @@ GIT

GIT
remote: https://github.com/ontoportal-lirmm/ontologies_linked_data.git
revision: a5b56a68e6dc8ecfc9db708d44350342dac38ce6
revision: 4cd56da111c2037bf0b606574e6b325bfa74a2f1
branch: development
specs:
ontologies_linked_data (0.0.1)
Expand Down Expand Up @@ -117,7 +117,7 @@ GEM
bcrypt_pbkdf (1.1.1-x86_64-darwin)
bigdecimal (1.4.2)
builder (3.3.0)
capistrano (3.19.0)
capistrano (3.19.1)
airbrussh (>= 1.0.0)
i18n
rake (>= 10.0.0)
Expand Down Expand Up @@ -165,7 +165,7 @@ GEM
faraday-patron (1.0.0)
faraday-rack (1.0.0)
faraday-retry (1.0.3)
ffi (1.16.3)
ffi (1.15.5)
gapic-common (0.21.1)
faraday (>= 1.9, < 3.a)
faraday-retry (>= 1.0, < 3.a)
Expand Down Expand Up @@ -256,7 +256,7 @@ GEM
method_source (1.1.0)
mime-types (3.5.2)
mime-types-data (~> 3.2015)
mime-types-data (3.2024.0604)
mime-types-data (3.2024.0702)
mini_mime (1.1.5)
minitest (4.7.5)
minitest-stub_any_instance (1.0.3)
Expand Down Expand Up @@ -394,7 +394,7 @@ GEM
strscan (3.1.0)
systemu (2.6.5)
temple (0.10.3)
tilt (2.3.0)
tilt (2.4.0)
timeout (0.4.1)
trailblazer-option (0.1.2)
tzinfo (2.0.6)
Expand Down Expand Up @@ -429,7 +429,7 @@ DEPENDENCIES
cube-ruby
ed25519 (>= 1.2, < 2.0)
faraday (~> 1.9)
ffi
ffi (~> 1.15.5)
goo!
haml (~> 5.2.2)
json-ld
Expand Down
82 changes: 43 additions & 39 deletions controllers/ontologies_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,29 @@ class OntologiesController < ApplicationController
reply(latest || {})
end

# Ontology latest submission datacite metadata as Json
get "/:acronym/latest_submission/datacite_metadata_json" do
params["display"] = 'all'
latest = find_latest_submission
latest.bring(*OntologySubmission.goo_attrs_to_load(includes_param)) if latest
if latest
to_data_cite_facet(latest).to_json
else
reply {}
end
end

get "/:acronym/latest_submission/ecoportal_metadata_json" do
params["display"] = 'all'
latest = find_latest_submission
latest.bring(*OntologySubmission.goo_attrs_to_load(includes_param)) if latest
if latest
to_eco_portal_facet(latest).to_json
else
reply {}
end
end

##
# Update latest submission of an ontology
REQUIRES_REPROCESS = ["prefLabelProperty", "definitionProperty", "synonymProperty", "authorProperty", "classType", "hierarchyProperty", "obsoleteProperty", "obsoleteParent"]
Expand All @@ -64,7 +87,7 @@ class OntologiesController < ApplicationController
submission.save
if (params.keys & REQUIRES_REPROCESS).length > 0 || request_has_file?
cron = NcboCron::Models::OntologySubmissionParser.new
cron.queue_submission(submission, {all: true})
cron.queue_submission(submission, { all: true })
end
else
error 422, submission.errors
Expand All @@ -76,13 +99,13 @@ class OntologiesController < ApplicationController
##
# Create an ontology
post do
create_ontology
create_ontology_with_params
end

##
# Create an ontology with constructed URL
put '/:acronym' do
create_ontology
create_ontology_with_params
end

##
Expand Down Expand Up @@ -123,7 +146,7 @@ class OntologiesController < ApplicationController
restricted_download = LinkedData::OntologiesAPI.settings.restrict_download.include?(acronym)
error 403, "License restrictions on download for #{acronym}" if restricted_download && !current_user.admin?
error 403, "Ontology #{acronym} is not accessible to your user" if ont.restricted? && !ont.accessible?(current_user)
latest_submission = ont.latest_submission(status: :rdf) # Should resolve to latest successfully loaded submission
latest_submission = ont.latest_submission(status: :rdf) # Should resolve to latest successfully loaded submission
error 404, "There is no latest submission loaded for download" if latest_submission.nil?
latest_submission.bring(:uploadFilePath)

Expand All @@ -148,46 +171,27 @@ class OntologiesController < ApplicationController
end

private

def create_ontology
params ||= @params

# acronym must be well formed
params['acronym'] = params['acronym'].upcase # coerce new ontologies to upper case

# ontology acronym must be unique
ont = Ontology.find(params['acronym']).first
if ont.nil?
ont = instance_from_params(Ontology, params)
def find_latest_submission
ont = Ontology.find(params["acronym"]).first
error 404, "You must provide a valid `acronym` to retrieve an ontology" if ont.nil?
include_status = params["include_status"]
ont.bring(:acronym, :submissions)
if include_status
latest = ont.latest_submission(status: include_status.to_sym)
else
error_msg = <<-ERR
Ontology already exists, see #{ont.id}
To add a new submission, POST to: /ontologies/#{params['acronym']}/submission.
To modify the resource, use PATCH.
ERR
error 409, error_msg
end

# ontology name must be unique
ont_names = Ontology.where.include(:name).to_a.map {|o| o.name }
if ont_names.include?(ont.name)
error 409, "Ontology name is already in use by another ontology."
latest = ont.latest_submission(status: :any)
end
check_last_modified(latest) if latest
latest
end

def create_ontology_with_params
ont = create_ontology
if ont.valid?
ont.save
# Send an email to the administrator to warn him about the newly created ontology
begin
if !LinkedData.settings.admin_emails.nil? && !LinkedData.settings.admin_emails.empty?
LinkedData::Utils::Notifications.new_ontology(ont)
end
rescue Exception => e
end
reply 201, ont
else
error 422, ont.errors
end

reply 201, ont
end
end

Expand All @@ -204,7 +208,7 @@ def create_ontology
else
onts = Ontology.where.filter(Goo::Filter.new(:viewOf).unbound).include(Ontology.goo_attrs_to_load(includes_param)).to_a
end
options = {also_include_views: allow_views, status: (params["include_status"] || "ANY")}
options = { also_include_views: allow_views, status: (params["include_status"] || "ANY") }
subs = retrieve_latest_submissions(options)
metrics_include = LinkedData::Models::Metric.goo_attrs_to_load(includes_param)
LinkedData::Models::OntologySubmission.where.models(subs.values).include(metrics: metrics_include).all
Expand All @@ -220,7 +224,7 @@ def create_ontology
metrics = nil
end

resp << {ontology: ont, latest_submission: subs[ont.acronym], metrics: metrics}
resp << { ontology: ont, latest_submission: subs[ont.acronym], metrics: metrics }
end

reply resp
Expand Down
28 changes: 24 additions & 4 deletions controllers/ontology_submissions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ class OntologySubmissionsController < ApplicationController
get "/submissions" do
check_last_modified_collection(LinkedData::Models::OntologySubmission)
options = {
also_include_views: params["also_include_views"],
status: (params["include_status"] || "ANY")
also_include_views: params["also_include_views"],
status: (params["include_status"] || "ANY")
}
subs = retrieve_latest_submissions(options)
subs = subs.values unless page?
Expand Down Expand Up @@ -43,7 +43,16 @@ class OntologySubmissionsController < ApplicationController
# Create a new submission for an existing ontology
post do
ont = Ontology.find(params["acronym"]).include(Ontology.attributes).first
error 422, "You must provide a valid `acronym` to create a new submission" if ont.nil?
params["name"] ||= params["titles"]&.first&.dig('title')

if params["name"] && params["acronym"] && ont.nil?
params["hasOntologyLanguage"] = "SKOS"
params["administeredBy"] = [ current_user.username ]
ont = create_ontology
elsif ont.nil?
error 422, "You must provide a valid `acronym` to create a new submission"
end

reply 201, create_submission(ont)
end

Expand All @@ -59,6 +68,18 @@ class OntologySubmissionsController < ApplicationController
reply ont_submission
end

# Ontology a submission datacite metadata as Json
get "/:ontology_submission_id/datacite_metadata_json" do
params["display"] = 'all'
ont = Ontology.find(params["acronym"]).include(:acronym).first
check_last_modified_segment(LinkedData::Models::OntologySubmission, [ont.acronym])
ont_submission = ont.submission(params["ontology_submission_id"])
error 404, "`submissionId` not found" if ont_submission.nil?
# ont_submission.bring(*OntologySubmission.goo_attrs_to_load(includes_param))
ont_submission.bring(*OntologySubmission.goo_attrs_to_load(includes_param))
to_data_cite_facet(ont_submission)
end

##
# Update an existing submission of an ontology
REQUIRES_REPROCESS = ["prefLabelProperty", "definitionProperty", "synonymProperty", "authorProperty", "classType", "hierarchyProperty", "obsoleteProperty", "obsoleteParent"]
Expand Down Expand Up @@ -170,5 +191,4 @@ def delete_submissions(startId, endId)

end


end
82 changes: 82 additions & 0 deletions helpers/concerns/data_cite_metadata_exporter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
module Sinatra
module Concerns
module DataCiteMetadataExporter

def to_date_cite(sub)
hash = {
url: sub.publication.first ? sub.publication.first&.to_s : sub.URI&.to_s,
version: sub.version,
description: sub.description,
publicationYear: sub.released&.year,
publisher: sub.publisher.map{|p| p.name}.join(', '),
creators: to_data_cite_creators(sub.hasCreator),
identifier: search_doi(sub.identifier) || sub.identifier.first&.to_s,
identifierType: identifier_type(sub),
titles: [{title: sub.ontology.name, titleType: ''}] + sub.alternative.map { |x| { title: x, titleType: 'AlternativeTitle' } },
resourceTypeGeneral: 'Dataset',
resourceType: sub.isOfType.to_s.split('/').last
}

identifier = hash.delete(:identifier)
identifier_type = hash.delete(:identifierType)
hash[:doi] = identifier if identifier_type.eql?('DOI')

hash[:types] = {
resourceTypeGeneral: hash.delete(:resourceTypeGeneral),
resourceType: hash.delete(:resourceType),
}
hash
end

private

def identifier_type(sub)
identifiers = sub.identifier

return 'None' if identifiers.nil? || identifiers.empty?

search_doi(identifiers).nil? ? 'Other' : 'DOI'
end

def to_data_cite_creators(creators)
creators.map do |creator|
{
nameType: creator.agentType.eql?('person') ? 'Personal' : 'Organizational',
givenName: creator.name.split(' ').first,
familyName: creator.name.split(' ').drop(1).join(' '),
creatorName: creator.name,
affiliations: to_data_cite_affiliations(creator.affiliations),
nameIdentifiers: to_data_cite_identifiers(creator.identifiers)
}
end
end

def to_data_cite_identifiers(identifiers)
identifiers.map do |identifier|
{
nameIdentifierScheme: identifier.schemaAgency,
schemeURI: identifier.schemeURI,
nameIdentifier: identifier.notation
}
end

end

def to_data_cite_affiliations(affiliations)
affiliations.map do |affiliation|
identifier = affiliation.identifiers.first
{
affiliationIdentifierScheme: identifier&.schemaAgency,
affiliationIdentifier: "#{identifier&.schemeURI}#{identifier&.notation}",
affiliation: affiliation.name
}
end
end

def search_doi(identifiers)
identifiers.select { |i| i.start_with?('http://doi.org') || i.start_with?('https://doi.org') }.first&.to_s
end

end
end
end
Loading