From 9152756ee34950b0adf63835e46d3daa8ad9f43d Mon Sep 17 00:00:00 2001 From: Syphax bouazzouni Date: Mon, 1 May 2023 21:12:29 +0200 Subject: [PATCH] Merge pull request #36 from ontoportal-lirmm/feature/paginate-and-filter-ontologies-endpoint Feature: Add oder by and filters for ontologies endpoint --- Gemfile.lock | 9 +- controllers/ontologies_controller.rb | 8 +- .../ontology_submissions_controller.rb | 4 +- helpers/request_params_helper.rb | 93 +++++++++++++------ helpers/submission_helper.rb | 11 ++- 5 files changed, 89 insertions(+), 36 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 33b4b6f4..8d1a1bfc 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,7 +11,7 @@ GIT GIT remote: https://github.com/ontoportal-lirmm/goo.git - revision: 1484ad56e39810208ee08a14d1319b6bc112f647 + revision: c3456c45c12ed92d4a3ae43cac7c1d4cdbf290b6 branch: development specs: goo (0.0.2) @@ -53,7 +53,7 @@ GIT GIT remote: https://github.com/ontoportal-lirmm/ontologies_linked_data.git - revision: f2168c8ad9ec447338da914d10a352df558494b5 + revision: 4ac9873f3d016259196a17cfc9c6ab8149468ec9 branch: development specs: ontologies_linked_data (0.0.1) @@ -193,7 +193,7 @@ GEM json_pure (2.6.3) jwt (2.7.0) kgio (2.11.4) - libxml-ruby (4.0.0) + libxml-ruby (4.1.0) logger (1.5.3) macaddr (1.7.2) systemu (~> 2.6.5) @@ -228,7 +228,7 @@ GEM net-protocol net-ssh (7.0.1) netrc (0.11.0) - newrelic_rpm (9.2.0) + newrelic_rpm (9.2.1) oj (2.18.5) omni_logger (0.1.4) logger @@ -344,6 +344,7 @@ PLATFORMS x86_64-darwin-21 x86_64-linux + DEPENDENCIES activesupport (~> 3.0) bcrypt_pbkdf (>= 1.0, < 2.0) diff --git a/controllers/ontologies_controller.rb b/controllers/ontologies_controller.rb index da1b748c..1a8f2ebf 100644 --- a/controllers/ontologies_controller.rb +++ b/controllers/ontologies_controller.rb @@ -47,9 +47,13 @@ class OntologiesController < ApplicationController latest.bring({:contact=>[:name, :email], :ontology=>[:acronym, :name, :administeredBy, :group, :viewingRestriction, :doNotUpdate, :flat, :hasDomain, :summaryOnly, :acl, :viewOf, :ontologyType], - :submissionStatus=>[:code], :hasOntologyLanguage=>[:acronym]}) + :submissionStatus=>[:code], :hasOntologyLanguage=>[:acronym], :metrics =>[:classes, :individuals, :properties]}) else - latest.bring(*OntologySubmission.goo_attrs_to_load(includes_param)) + includes = OntologySubmission.goo_attrs_to_load(includes_param) + + includes << {:contact=>[:name, :email]} if includes.find{|v| v.is_a?(Hash) && v.keys.first.eql?(:contact)} + + latest.bring(*includes) end end #remove the whole previous if block and replace by it: latest.bring(*OntologySubmission.goo_attrs_to_load(includes_param)) if latest diff --git a/controllers/ontology_submissions_controller.rb b/controllers/ontology_submissions_controller.rb index 8749786d..69c2a4cd 100644 --- a/controllers/ontology_submissions_controller.rb +++ b/controllers/ontology_submissions_controller.rb @@ -7,6 +7,8 @@ class OntologySubmissionsController < ApplicationController } subs = retrieve_latest_submissions(options) subs = subs.values unless page? + # Force to show ontology reviews, notes and projects by default only for this request + LinkedData::Models::Ontology.serialize_default(*(LinkedData::Models::Ontology.hypermedia_settings[:serialize_default] + [:reviews, :notes, :projects])) reply subs end @@ -30,7 +32,7 @@ class OntologySubmissionsController < ApplicationController # When asking to display all metadata, we are using bring_remaining which is more performant than including all metadata (remove this when the query to get metadata will be fixed) ont.bring(submissions: [:released, :creationDate, :status, :submissionId, {:contact=>[:name, :email], :ontology=>[:administeredBy, :acronym, :name, :summaryOnly, :ontologyType, :viewingRestriction, :acl, :group, :hasDomain, :views, :viewOf, :flat], - :submissionStatus=>[:code], :hasOntologyLanguage=>[:acronym]}, :submissionStatus]) + :submissionStatus=>[:code], :hasOntologyLanguage=>[:acronym]}, :submissionStatus], :metrics =>[:classes, :individuals, :properties]) ont.submissions.each do |sub| sub.bring_remaining diff --git a/helpers/request_params_helper.rb b/helpers/request_params_helper.rb index 251af299..cf8ba1f8 100644 --- a/helpers/request_params_helper.rb +++ b/helpers/request_params_helper.rb @@ -38,43 +38,23 @@ def apply_filters(query) ontology_group_acronym: params[:group]&.split(','), #%w[RICE CROP], ontology_name: Array(params[:name]) + Array(params[:name]&.capitalize), isOfType: params[:isOfType]&.split(','), #["http://omv.ontoware.org/2005/05/ontology#Vocabulary"], - viewingRestriction: params[:viewingRestriction]&.split(','), #["private"] + hasFormalityLevel: params[:hasFormalityLevel]&.split(','), #["http://w3id.org/nkos/nkostype#thesaurus"], + ontology_viewingRestriction: params[:viewingRestriction]&.split(','), #["private"] } inverse_filters = { status: params[:status], #"retired", submissionStatus: params[:submissionStatus] #"RDF", } - filters.each do |key , values| - attr = extract_attr(key) - next if Array(values).empty? + query = add_direct_filters(filters, query) - filter = Goo::Filter.new(attr).regex(values.first) - values.drop(1).each do |v| - filter = filter.or(Goo::Filter.new(attr).regex(v)) - end - query = query.filter(filter) - end + query = add_inverse_filters(inverse_filters, query) - inverse_filters.each do |key ,value| - attr = extract_attr(key) - next unless value + query = add_acronym_name_filters(query) - filter = Goo::Filter.new(attr).regex("^(?:(?!#{value}).)*$") - query = query.filter(filter) - end - query + add_order_by_patterns(query) end - def extract_attr(key) - attr, sub_attr, sub_sub_attr = key.to_s.split('_') - - return attr.to_sym unless sub_attr - - return {attr.to_sym => [sub_attr.to_sym]} unless sub_sub_attr - - {attr.to_sym => [sub_attr.to_sym => sub_sub_attr.to_sym]} - end def get_order_by_from(params, default_order = :asc) if is_set?(params['sortby']) @@ -101,6 +81,67 @@ def bring_unmapped_to(page_data, sub, klass) end private + def extract_attr(key) + attr, sub_attr, sub_sub_attr = key.to_s.split('_') + + return attr.to_sym unless sub_attr + + return {attr.to_sym => [sub_attr.to_sym]} unless sub_sub_attr + + {attr.to_sym => [sub_attr.to_sym => sub_sub_attr.to_sym]} + end + + def add_direct_filters(filters, query) + filters.each do |key, values| + attr = extract_attr(key) + next if Array(values).empty? + + filter = Goo::Filter.new(attr).regex(values.first) + values.drop(1).each do |v| + filter = filter.or(Goo::Filter.new(attr).regex(v)) + end + query = query.filter(filter) + end + query + end + + def add_inverse_filters(inverse_filters, query) + inverse_filters.each do |key, value| + attr = extract_attr(key) + next unless value + + filter = Goo::Filter.new(attr).regex("^(?:(?!#{value}).)*$") + query = query.filter(filter) + end + query + end + + def add_acronym_name_filters(query) + if params[:acronym] + filter = Goo::Filter.new(extract_attr(:ontology_acronym)).regex(params[:acronym]) + if params[:name] + filter.or(Goo::Filter.new(extract_attr(:ontology_name)).regex(params[:name])) + end + query = query.filter(filter) + elsif params[:name] + filter = Goo::Filter.new(extract_attr(:ontology_name)).regex(params[:name]) + query = query.filter(filter) + end + query + end + + def add_order_by_patterns(query) + if params[:order_by] + attr, sub_attr = params[:order_by].to_s.split('_') + if sub_attr + order_pattern = { attr.to_sym => { sub_attr.to_sym => (sub_attr.eql?("name") ? :asc : :desc) } } + else + order_pattern = { attr.to_sym => :desc } + end + query = query.order_by(order_pattern) + end + query + end def sort_order_item(param, order) [param.to_sym, order.to_sym] diff --git a/helpers/submission_helper.rb b/helpers/submission_helper.rb index 38108050..e19061c0 100644 --- a/helpers/submission_helper.rb +++ b/helpers/submission_helper.rb @@ -26,10 +26,15 @@ def retrieve_submissions(options) # When asking to display all metadata, we are using bring_remaining on each submission. Slower but best way to retrieve all attrs if includes_param.first == :all - includes = [:submissionId, {:contact=>[:name, :email], :ontology=>[:administeredBy, :acronym, :name, :summaryOnly, :ontologyType, :viewingRestriction, :acl, - :group, :hasDomain, :views, :viewOf, :flat], :submissionStatus=>[:code], :hasOntologyLanguage=>[:acronym]}, :submissionStatus] + includes = [:submissionId, {:contact=>[:name, :email], + :ontology=>[:administeredBy, :acronym, :name, :summaryOnly, :ontologyType, :viewingRestriction, :acl, + :group, :hasDomain, :views, :viewOf, :flat, :notes, :reviews, :projects], + :submissionStatus=>[:code], :hasOntologyLanguage=>[:acronym], :metrics =>[:classes, :individuals, :properties]}, + :submissionStatus] elsif includes.find{|v| v.is_a?(Hash) && v.keys.first.eql?(:ontology)} - includes << {:ontology=>[:administeredBy, :acronym, :name, :viewingRestriction, :group, :hasDomain]} + includes << {:ontology=>[:administeredBy, :acronym, :name, :viewingRestriction, :group, :hasDomain,:notes, :reviews, :projects]} + elsif includes.find{|v| v.is_a?(Hash) && v.keys.first.eql?(:contact)} + includes << {:contact=>[:name, :email]} end submissions = submissions_query.include(includes)