Skip to content

Commit

Permalink
Merge branch 'development' into stage
Browse files Browse the repository at this point in the history
  • Loading branch information
syphax-bouazzouni committed Jan 1, 2024
2 parents 0d83a4d + 5bb4876 commit d821dbe
Show file tree
Hide file tree
Showing 28 changed files with 873 additions and 88 deletions.
7 changes: 7 additions & 0 deletions app/assets/stylesheets/admin.scss
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@
}
}

.yasgui .autocompleteWrapper, .yasgui .tabContextButton{
display: none !important;
}
.yasqe .yasqe_buttons .yasqe_share{
display: none !important;
}

.alert-box span {
font-weight: bold;
text-transform: uppercase;
Expand Down
1 change: 1 addition & 0 deletions app/assets/stylesheets/application.css.scss.erb
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
@import "tom-select/dist/scss/tom-select";
@import "tippy.js/dist/tippy";
@import 'tippy.js/themes/light-border';
@import '@triply/yasgui/build/yasgui.min';
@import "feedback";
@import "login";
@import "components/index";
Expand Down
2 changes: 1 addition & 1 deletion app/assets/stylesheets/home.scss
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ i.fa.fa-caret-square-o-down {
.home-statistics-container{
border-radius: 8px;
box-shadow: 2px 0px 60px rgba(0, 0, 0, 0.10);
padding: 30px 40px;
padding: 30px 40px 10px 40px;

}
.home-statistics-container > div {
Expand Down
16 changes: 15 additions & 1 deletion app/controllers/admin_controller.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class AdminController < ApplicationController
include TurboHelper, HomeHelper
include TurboHelper, HomeHelper, SparqlHelper
layout :determine_layout
before_action :cache_setup

Expand All @@ -10,6 +10,20 @@ class AdminController < ApplicationController
PARSE_LOG_URL = lambda { |acronym| "#{ONTOLOGY_URL.call(acronym)}/log" }
REPORT_NEVER_GENERATED = "NEVER GENERATED"


def sparql_endpoint
graph = params["named-graph-uri"]
if !session[:user]&.admin? && !graph.blank?
acronym = graph.split('/')[-3]
@ontology = LinkedData::Client::Models::Ontology.find_by_acronym(acronym).first
render(inline: 'Query not permitted') && return if @ontology.nil? || @ontology.errors
end

response = helpers.ontology_sparql_query(params[:query], graph)

render inline: response
end

def index
@users = LinkedData::Client::Models::User.all
@ontology_visits = ontology_visits_data
Expand Down
15 changes: 13 additions & 2 deletions app/controllers/ontologies_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class OntologiesController < ApplicationController
include MappingStatistics
include OntologyUpdater
include TurboHelper
include SparqlHelper
include SubmissionFilter

require 'multi_json'
Expand All @@ -22,7 +23,7 @@ class OntologiesController < ApplicationController

before_action :authorize_and_redirect, :only => [:edit, :update, :create, :new]
before_action :submission_metadata, only: [:show]
KNOWN_PAGES = Set.new(["terms", "classes", "mappings", "notes", "widgets", "summary", "properties", "instances", "schemes", "collections"])
KNOWN_PAGES = Set.new(["terms", "classes", "mappings", "notes", "widgets", "summary", "properties", "instances", "schemes", "collections", "sparql"])
EXTERNAL_MAPPINGS_GRAPH = "http://data.bioontology.org/metadata/ExternalMappings"
INTERPORTAL_MAPPINGS_GRAPH = "http://data.bioontology.org/metadata/InterportalMappings"

Expand Down Expand Up @@ -208,6 +209,14 @@ def collections
end
end


def sparql
if request.xhr?
render partial: 'ontologies/sections/sparql', layout: false
else
render partial: 'ontologies/sections/sparql', layout: 'ontology_viewer'
end
end
# GET /ontologies/ACRONYM
# GET /ontologies/1.xml
def show
Expand Down Expand Up @@ -240,7 +249,7 @@ def show

# Note: find_by_acronym includes ontology views
@ontology = LinkedData::Client::Models::Ontology.find_by_acronym(params[:ontology]).first
ontology_not_found(params[:ontology]) if @ontology.nil?
ontology_not_found(params[:ontology]) if @ontology.nil? || @ontology.errors

# Handle the case where an ontology is converted to summary only.
# See: https://github.com/ncbo/bioportal_web_ui/issues/133.
Expand Down Expand Up @@ -288,6 +297,8 @@ def show
self.schemes
when 'collections'
self.collections
when 'sparql'
self.sparql
else
self.summary
end
Expand Down
14 changes: 14 additions & 0 deletions app/controllers/statistics_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class StatisticsController < ApplicationController
include StatisticsHelper, ComponentsHelper

layout :determine_layout

def index
projects = LinkedData::Client::Models::Project.all({include: 'created'})
users = LinkedData::Client::Models::User.all({include: 'created'})
year_month_count, @year_month_visits = ontologies_by_year_month
@merged_data = merge_time_evolution_data([group_by_year_month(users),
group_by_year_month(projects),
year_month_count])
end
end
7 changes: 2 additions & 5 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,8 @@ module ApplicationHelper


def ontologies_analytics
LinkedData::Client::Analytics.all.to_h.map do |key, ontology_analytics|
next if key.eql?(:links) || key.eql?(:context)

[key.to_s, ontology_analytics.to_h.values.map { |x| x&.values }.flatten.compact.sum]
end.compact.to_h
data = LinkedData::Client::Analytics.last_month.onts
data.map{|x| [x[:ont].to_s, x[:views]]}.to_h
end

def get_apikey
Expand Down
6 changes: 4 additions & 2 deletions app/helpers/components_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,19 @@ def tree_close_icon
end


def chart_component(title: '', type: , labels: , datasets: , index_axis: 'x')
def chart_component(title: '', type: , labels: , datasets: , index_axis: 'x', show_legend: false)
data = {
controller: 'load-chart',
'load-chart-type-value': type,
'load-chart-title-value': title,
'load-chart-labels-value': labels,
'load-chart-index-axis-value': index_axis,
'load-chart-datasets-value': datasets
'load-chart-datasets-value': datasets,
'load-chart-legend-value': show_legend,
}
content_tag(:canvas, nil, data: data)
end

def info_tooltip(text)
render Display::InfoTooltipComponent.new(text: text)
end
Expand Down
19 changes: 12 additions & 7 deletions app/helpers/ontologies_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ def classes_link(ontology, count)

def metadata_filled_count(submission = @submission_latest, ontology = @ontology)
return if submission.nil?

reject = [:csvDump, :dataDump, :openSearchDescription, :metrics, :prefLabelProperty, :definitionProperty,
:definitionProperty, :synonymProperty, :authorProperty, :hierarchyProperty, :obsoleteProperty,
:ontology, :endpoint, :submissionId, :submissionStatus, :uploadFilePath, :context, :links, :ontology]
Expand Down Expand Up @@ -384,18 +384,23 @@ def lazy_load_section(section_title, &block)
end

def visits_chart_dataset(visits_data)
[
visits_chart_dataset_array({'Visits': visits_data})
end

def visits_chart_dataset_array(visits_data, fill: true)
visits_data = visits_data.map do |label , x|
{
label: 'Visits',
data: visits_data,
label: label,
data: x,
borderWidth: 2,
borderRadius: 5,
borderSkipped: false,
cubicInterpolationMode: 'monotone',
tension: 0.4,
fill: true
fill: fill
}
].to_json
end
visits_data.to_json
end

def submission_ready?(submission)
Expand All @@ -410,7 +415,7 @@ def sections_to_show
sections += %w[properties]
sections += %w[schemes collections] if skos?
sections += %w[instances] unless skos?
sections += %w[notes mappings widgets]
sections += %w[notes mappings widgets sparql]
end
sections
end
Expand Down
67 changes: 67 additions & 0 deletions app/helpers/sparql_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
module SparqlHelper
def change_from_clause(query, graph)
unless graph.blank?
graph = graph.gsub($REST_URL, 'http://data.bioontology.org')

if query.match?(/FROM <[^>]+>/i)
# Use a regular expression to replace all instances of FROM <uri>
query = query.gsub(/FROM <[^>]+>/i, "")
else
query = query.gsub("WHERE", "FROM <#{graph}> WHERE")
end

query = query.gsub(/GRAPH <[^>]+>/i, "")
end
query
end
def ontology_sparql_query(query, graph = '')
query = change_from_clause(query, graph)
sparql_query(query)
end
def is_allowed_query?(sparql_query)
forbidden_operations = [
'INSERT DATA',
'DELETE DATA',
'DELETE/INSERT',
'DELETE',
'INSERT',
'DELETE WHERE',
'LOAD',
'CLEAR',
'CREATE',
'DROP',
'COPY',
'MOVE',
'ADD'
]

# Define a regular expression to match SELECT queries
select_query_regex = /\A\s*SELECT\b/m

# Check if the query contains any forbidden operations outside SELECT queries
return false if forbidden_operations.any? { |op| sparql_query.upcase.include?(op) && !sparql_query.match(select_query_regex) }

true
end

def sparql_query(query)
return 'No SPARQL endpoint configured' if $SPARQL_URL.blank?
return 'INSERT Queries not permitted' unless is_allowed_query?(query)
endpoint = $SPARQL_URL.gsub('test', 'sparql')
begin
conn = Faraday.new do |conn|
conn.options.timeout = 60
end
response = conn.get("#{endpoint}?query=#{encode_param(query)}")
response.body.force_encoding('ISO-8859-1').encode('UTF-8')
rescue
"Query timeout"
end
end
def sparql_query_container(graph: nil)
content_tag(:div, '', data: {controller: 'sparql',
'sparql-proxy-value': '/sparql_proxy/',
'sparql-graph-value': graph})
end

end
60 changes: 60 additions & 0 deletions app/helpers/statistics_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
module StatisticsHelper

def ontologies_by_year_month
data = LinkedData::Client::Analytics.all.to_h
data.delete(:links)
data.delete(:context)
year_month_count = {}
year_month_visits = {}
acronyms = []
data.each do |acronym, ont|
ont.each do |year, months|
next if year.eql?(:links) || year.eql?(:context)
months.each do |month, count|
next if month.eql?(:links) || month.eql?(:context)
year_month_count[[year.to_s.to_i, month.to_s.to_i]] ||= []
year_month_visits[[year.to_s.to_i, month.to_s.to_i]] = count + (year_month_visits[[year.to_s.to_i, month.to_s.to_i]] || 0)

if !count.zero? && !acronyms.include?(acronym)
year_month_count[[year.to_s.to_i, month.to_s.to_i]] << acronym
acronyms << acronym
end
end
end
end
year_month_visits = year_month_visits.sort_by { |(year, month), _| [year, month] }.to_h
[year_month_count, year_month_visits]
end

def string_year_month(year, month)
DateTime.parse("#{year}/#{month}").strftime("%b %Y")
end
def group_by_year_month(data)
data.group_by{|x| [Date.parse(x.created).year, Date.parse(x.created).month] }.sort_by { |(year, month), _| [year, month] }.to_h
end

def merge_time_evolution_data(data)
min_year = data.map{|x| x.keys.first.first}.min
old = data.size.times.map { |x| 0 }

visits_data = { visits: data.size.times.map { |x| [] }, labels: [] }

(min_year..Date.today.year).each do |year|
(1..12).each do |month|
data.each_with_index do |x , i|
old[i] += x[[year, month]]&.size || 0
end

next if old.sum.zero?

data.each_index do |i|
visits_data[:visits][i] << old[i]
end

visits_data[:labels] << string_year_month(year, month)
end
end
visits_data
end

end
3 changes: 3 additions & 0 deletions app/javascript/controllers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ application.register("show-modal", ShowModalController)
import SkosCollectionColorsController from "./skos_collection_colors_controller"
application.register("skos-collection-colors", SkosCollectionColorsController)

import SparqlController from "./sparql_controller"
application.register("sparql", SparqlController)

import TextTruncateController from "./text_truncate_controller"
application.register("text-truncate", TextTruncateController)

Expand Down
5 changes: 3 additions & 2 deletions app/javascript/controllers/load_chart_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ export default class extends Controller {
datasets: Array,
type: { type: String, default: 'line' },
title: String,
indexAxis: { type: String, default: 'x' }
indexAxis: { type: String, default: 'x' },
legend: { type: Boolean, default: false }
}

connect () {
Expand All @@ -34,7 +35,7 @@ export default class extends Controller {
text: this.titleValue
},
legend: {
display: false
display: this.legendValue
}
},
responsive: true,
Expand Down
25 changes: 25 additions & 0 deletions app/javascript/controllers/sparql_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Controller } from '@hotwired/stimulus'
import { getYasgui } from '../mixins/useYasgui'

// Connects to data-controller="sparql"
export default class extends Controller {
static values = {
proxy: String,
graph: String,
}
connect () {
localStorage.removeItem('yagui__config');
this.yasgui = getYasgui(this.element,
{
corsProxy: this.proxyValue,
copyEndpointOnNewTab: true,
requestConfig: {
endpoint: this.proxyValue,
acceptHeaderGraph: false,
acceptHeaderUpdate: false,
namedGraphs: [this.graphValue],
}
})

}
}
6 changes: 6 additions & 0 deletions app/javascript/mixins/useYasgui.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import Yasgui from "@triply/yasgui";

export const getYasgui = (elem, config) => {
return new Yasgui(elem, config)
}

Loading

0 comments on commit d821dbe

Please sign in to comment.