iqvoc_similar_terms 2.7.0 → 2.11.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/workflows/ci.yml +67 -0
- data/.gitignore +7 -0
- data/Gemfile +14 -15
- data/Gemfile.lock +483 -314
- data/README.md +5 -6
- data/app/assets/javascripts/manifest.js +2 -0
- data/app/assets/stylesheets/manifest.scss +3 -0
- data/app/controllers/similar_terms_controller.rb +27 -11
- data/app/models/services/similar_terms_service.rb +141 -0
- data/app/views/similar_terms/_form.html.erb +21 -0
- data/app/views/similar_terms/new.html.erb +21 -0
- data/app/views/similar_terms/show.html.erb +32 -28
- data/bin/bundle +3 -0
- data/bin/rails +3 -9
- data/bin/rake +3 -6
- data/bin/setup +33 -0
- data/bin/update +31 -0
- data/bin/yarn +17 -0
- data/config/application.rb +30 -48
- data/config/boot.rb +3 -5
- data/config/cable.yml +10 -0
- data/config/database.yml.postgresql +26 -0
- data/config/environment.rb +4 -4
- data/config/initializers/content_security_policy.rb +25 -0
- data/config/initializers/filter_parameter_logging.rb +8 -0
- data/config/initializers/inflections.rb +16 -0
- data/config/initializers/iqvoc.rb +5 -4
- data/config/initializers/new_framework_defaults_6_1.rb +67 -0
- data/config/initializers/permissions_policy.rb +11 -0
- data/config/locales/de.yml +6 -0
- data/config/locales/en.yml +6 -0
- data/config/routes.rb +2 -2
- data/config/storage.yml +34 -0
- data/config.ru +4 -2
- data/faucet.config.js +46 -0
- data/iqvoc_similar_terms.gemspec +1 -1
- data/lib/iqvoc/similar_terms/version.rb +1 -1
- data/lib/iqvoc/similar_terms.rb +12 -97
- data/lib/iqvoc_similar_terms.rb +1 -0
- data/package-lock.json +2333 -0
- data/package.json +29 -0
- data/test/concept_test.nt +5 -0
- data/test/concept_test.ttl +8 -1
- data/test/controllers/similar_terms_controller_test.rb +167 -0
- data/test/models/entity_resolution_test.rb +6 -6
- data/test/models/results_test.rb +43 -17
- metadata +31 -23
- data/.travis.yml +0 -30
- data/bin/spring +0 -18
- data/config/initializers/iqvoc_similiar_terms.rb +0 -1
- data/config/initializers/wrap_parameters.rb +0 -14
- data/test/controllers/api_test.rb +0 -58
- data/test/controllers/onebox_test.rb +0 -37
@@ -1,7 +1,8 @@
|
|
1
1
|
Iqvoc.config.register_setting("title", "iQvoc Similar Terms")
|
2
2
|
|
3
|
-
Iqvoc::Configuration::Navigation.add_grouped(
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
Iqvoc::Configuration::Navigation.add_grouped(
|
4
|
+
{
|
5
|
+
text: proc { t("txt.views.similar_terms.title") },
|
6
|
+
href: proc { new_similar_path },
|
7
|
+
controller: "similar_terms"
|
7
8
|
}, -3)
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
2
|
+
#
|
3
|
+
# This file contains migration options to ease your Rails 6.1 upgrade.
|
4
|
+
#
|
5
|
+
# Once upgraded flip defaults one by one to migrate to the new default.
|
6
|
+
#
|
7
|
+
# Read the Guide for Upgrading Ruby on Rails for more info on each option.
|
8
|
+
|
9
|
+
# Support for inversing belongs_to -> has_many Active Record associations.
|
10
|
+
# Rails.application.config.active_record.has_many_inversing = true
|
11
|
+
|
12
|
+
# Track Active Storage variants in the database.
|
13
|
+
# Rails.application.config.active_storage.track_variants = true
|
14
|
+
|
15
|
+
# Apply random variation to the delay when retrying failed jobs.
|
16
|
+
# Rails.application.config.active_job.retry_jitter = 0.15
|
17
|
+
|
18
|
+
# Stop executing `after_enqueue`/`after_perform` callbacks if
|
19
|
+
# `before_enqueue`/`before_perform` respectively halts with `throw :abort`.
|
20
|
+
# Rails.application.config.active_job.skip_after_callbacks_if_terminated = true
|
21
|
+
|
22
|
+
# Specify cookies SameSite protection level: either :none, :lax, or :strict.
|
23
|
+
#
|
24
|
+
# This change is not backwards compatible with earlier Rails versions.
|
25
|
+
# It's best enabled when your entire app is migrated and stable on 6.1.
|
26
|
+
# Rails.application.config.action_dispatch.cookies_same_site_protection = :lax
|
27
|
+
|
28
|
+
# Generate CSRF tokens that are encoded in URL-safe Base64.
|
29
|
+
#
|
30
|
+
# This change is not backwards compatible with earlier Rails versions.
|
31
|
+
# It's best enabled when your entire app is migrated and stable on 6.1.
|
32
|
+
# Rails.application.config.action_controller.urlsafe_csrf_tokens = true
|
33
|
+
|
34
|
+
# Specify whether `ActiveSupport::TimeZone.utc_to_local` returns a time with an
|
35
|
+
# UTC offset or a UTC time.
|
36
|
+
# ActiveSupport.utc_to_local_returns_utc_offset_times = true
|
37
|
+
|
38
|
+
# Change the default HTTP status code to `308` when redirecting non-GET/HEAD
|
39
|
+
# requests to HTTPS in `ActionDispatch::SSL` middleware.
|
40
|
+
# Rails.application.config.action_dispatch.ssl_default_redirect_status = 308
|
41
|
+
|
42
|
+
# Use new connection handling API. For most applications this won't have any
|
43
|
+
# effect. For applications using multiple databases, this new API provides
|
44
|
+
# support for granular connection swapping.
|
45
|
+
# Rails.application.config.active_record.legacy_connection_handling = false
|
46
|
+
|
47
|
+
# Make `form_with` generate non-remote forms by default.
|
48
|
+
# Rails.application.config.action_view.form_with_generates_remote_forms = false
|
49
|
+
|
50
|
+
# Set the default queue name for the analysis job to the queue adapter default.
|
51
|
+
# Rails.application.config.active_storage.queues.analysis = nil
|
52
|
+
|
53
|
+
# Set the default queue name for the purge job to the queue adapter default.
|
54
|
+
# Rails.application.config.active_storage.queues.purge = nil
|
55
|
+
|
56
|
+
# Set the default queue name for the incineration job to the queue adapter default.
|
57
|
+
# Rails.application.config.action_mailbox.queues.incineration = nil
|
58
|
+
|
59
|
+
# Set the default queue name for the routing job to the queue adapter default.
|
60
|
+
# Rails.application.config.action_mailbox.queues.routing = nil
|
61
|
+
|
62
|
+
# Set the default queue name for the mail deliver job to the queue adapter default.
|
63
|
+
# Rails.application.config.action_mailer.deliver_later_queue_name = nil
|
64
|
+
|
65
|
+
# Generate a `Link` header that gives a hint to modern browsers about
|
66
|
+
# preloading assets when using `javascript_include_tag` and `stylesheet_link_tag`.
|
67
|
+
# Rails.application.config.action_view.preload_links_header = true
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# Define an application-wide HTTP permissions policy. For further
|
2
|
+
# information see https://developers.google.com/web/updates/2018/06/feature-policy
|
3
|
+
#
|
4
|
+
# Rails.application.config.permissions_policy do |f|
|
5
|
+
# f.camera :none
|
6
|
+
# f.gyroscope :none
|
7
|
+
# f.microphone :none
|
8
|
+
# f.usb :none
|
9
|
+
# f.fullscreen :self
|
10
|
+
# f.payment :self, "https://secure.example.com"
|
11
|
+
# end
|
data/config/locales/de.yml
CHANGED
@@ -2,5 +2,11 @@ de:
|
|
2
2
|
txt:
|
3
3
|
views:
|
4
4
|
similar_terms:
|
5
|
+
no_results: Keine Ergebnisse
|
5
6
|
title: Ähnliche Begriffe
|
6
7
|
results_heading: ähnliche Begriffe für '%{terms}'
|
8
|
+
results: Ihre Suche nach <span class="text-primary">%{terms}</span> ergab %{count} Treffer
|
9
|
+
synonyms_only: Nur Synonyme anzeigen
|
10
|
+
about:
|
11
|
+
title: Der Dienst Ähnliche Begriffe
|
12
|
+
description: Zum Suchwort werden eine Auswahl semantisch passender Begriffe aus dem Wortgut vorgeschlagen. Neben Begriffen mit Schlagwortfunktion enthält die Auflistung auch die deutschen alternativen Benennungen zum Suchwort.
|
data/config/locales/en.yml
CHANGED
@@ -2,5 +2,11 @@ en:
|
|
2
2
|
txt:
|
3
3
|
views:
|
4
4
|
similar_terms:
|
5
|
+
no_results: No results
|
5
6
|
title: Similar Terms
|
6
7
|
results_heading: similar terms for '%{terms}'
|
8
|
+
results: Your search <span class="text-primary">%{terms}</span> yielded %{results_size} results
|
9
|
+
synonyms_only: Show synonyms only
|
10
|
+
about:
|
11
|
+
title: About similar terms
|
12
|
+
description: "The Similar Terms service supports users in generating search queries. It suggest semantically similar words from the vocabulary for the entered search term. This service can be used to semantically extend search queries and improve search results.\n\nSemantically similar is understood to mean synonyms (alternative labels) and terms with a semantic-associative relationship to the search term (related terms)."
|
data/config/routes.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Rails.application.routes.draw do
|
2
2
|
scope ":lang", :constraints => Iqvoc.routing_constraint do
|
3
|
-
get "similar" => "similar_terms#
|
4
|
-
|
3
|
+
get "similar/new" => "similar_terms#new", as: 'new_similar'
|
4
|
+
get "similar" => "similar_terms#create"
|
5
5
|
end
|
6
6
|
end
|
data/config/storage.yml
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
test:
|
2
|
+
service: Disk
|
3
|
+
root: <%= Rails.root.join("tmp/storage") %>
|
4
|
+
|
5
|
+
local:
|
6
|
+
service: Disk
|
7
|
+
root: <%= Rails.root.join("storage") %>
|
8
|
+
|
9
|
+
# Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)
|
10
|
+
# amazon:
|
11
|
+
# service: S3
|
12
|
+
# access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
|
13
|
+
# secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
|
14
|
+
# region: us-east-1
|
15
|
+
# bucket: your_own_bucket
|
16
|
+
|
17
|
+
# Remember not to checkin your GCS keyfile to a repository
|
18
|
+
# google:
|
19
|
+
# service: GCS
|
20
|
+
# project: your_project
|
21
|
+
# credentials: <%= Rails.root.join("path/to/gcs.keyfile") %>
|
22
|
+
# bucket: your_own_bucket
|
23
|
+
|
24
|
+
# Use rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key)
|
25
|
+
# microsoft:
|
26
|
+
# service: AzureStorage
|
27
|
+
# storage_account_name: your_account_name
|
28
|
+
# storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %>
|
29
|
+
# container: your_container_name
|
30
|
+
|
31
|
+
# mirror:
|
32
|
+
# service: Mirror
|
33
|
+
# primary: local
|
34
|
+
# mirrors: [ amazon, google, microsoft ]
|
data/config.ru
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
# This file is used by Rack-based servers to start the application.
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
require_relative "config/environment"
|
4
|
+
|
5
|
+
run Rails.application
|
6
|
+
Rails.application.load_server
|
data/faucet.config.js
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
module.exports = {
|
2
|
+
js: [
|
3
|
+
{
|
4
|
+
source: "./node_modules/jquery/dist/jquery.js",
|
5
|
+
target: "./public/assets/javascripts/jquery.js",
|
6
|
+
exports: "jQuery",
|
7
|
+
compact: "mangle"
|
8
|
+
},
|
9
|
+
{
|
10
|
+
source: "./app/assets/javascripts/manifest.js",
|
11
|
+
target: "./public/assets/javascripts/manifest.js",
|
12
|
+
externals: { jquery: "jQuery" },
|
13
|
+
},
|
14
|
+
{
|
15
|
+
source: "./node_modules/bootstrap/dist/js/bootstrap.bundle.min.js",
|
16
|
+
target: "./public/assets/javascripts/bootstrap.bundle.min.js",
|
17
|
+
externals: { jquery: "jQuery" },
|
18
|
+
compact: "minify"
|
19
|
+
}
|
20
|
+
],
|
21
|
+
sass: [{
|
22
|
+
source: "./app/assets/stylesheets/manifest.scss",
|
23
|
+
target: "./public/assets/stylesheets/manifest.css"
|
24
|
+
}],
|
25
|
+
static: [
|
26
|
+
{
|
27
|
+
source: "./node_modules/iqvoc/app/assets/images",
|
28
|
+
target: "./public/assets/images"
|
29
|
+
},
|
30
|
+
{
|
31
|
+
source: "./node_modules/iqvoc/app/assets/fonts",
|
32
|
+
target: "./public/assets/fonts"
|
33
|
+
},
|
34
|
+
{
|
35
|
+
source: "./node_modules/font-awesome/fonts",
|
36
|
+
target: "./public/assets/fonts",
|
37
|
+
fingerprint: false
|
38
|
+
}
|
39
|
+
],
|
40
|
+
manifest: {
|
41
|
+
target: "./public/assets/manifest.json",
|
42
|
+
key: "short",
|
43
|
+
webRoot: "./public"
|
44
|
+
},
|
45
|
+
watchDirs: ["./app/assets"]
|
46
|
+
};
|
data/iqvoc_similar_terms.gemspec
CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
|
|
15
15
|
|
16
16
|
s.rubyforge_project = "iqvoc_similar_terms"
|
17
17
|
|
18
|
-
s.add_dependency "iqvoc", "
|
18
|
+
s.add_dependency "iqvoc", "~> 4.14.4"
|
19
19
|
|
20
20
|
s.files = `git ls-files`.split("\n")
|
21
21
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
data/lib/iqvoc/similar_terms.rb
CHANGED
@@ -1,109 +1,24 @@
|
|
1
1
|
module Iqvoc
|
2
2
|
module SimilarTerms # TODO: make language constraints optional
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
@@weightings = {
|
5
|
+
'Labeling::SKOS::PrefLabel' => 5,
|
6
|
+
'Labeling::SKOS::AltLabel' => 2,
|
7
|
+
'Labeling::SKOS::HiddenLabel' => 0,
|
8
8
|
# SKOS-XL
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
'Labeling::SKOSXL::PrefLabel' => 5,
|
10
|
+
'Labeling::SKOSXL::AltLabel' => 2,
|
11
|
+
'Labeling::SKOSXL::HiddenLabel' => 0
|
12
12
|
}
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
sort_by { |label, data| label }.
|
18
|
-
sort_by { |label, data| data[0] }.
|
19
|
-
reverse.
|
20
|
-
map { |label, data| [label] + data[1..-1] } # drop weighting
|
21
|
-
end
|
22
|
-
|
23
|
-
# returns a hash of label/weighting+concepts pairs -- XXX: unused/deprecated
|
24
|
-
def self.weighted(lang, *terms) # TODO: rename
|
25
|
-
concepts = terms_to_concepts(lang, *terms).
|
26
|
-
includes(:labelings => [:owner, :target]).
|
27
|
-
where("labels.language" => lang) # applies language constraint to results
|
28
|
-
return terms.inject({}) do |memo, term|
|
29
|
-
concepts.published.each do |concept|
|
30
|
-
concept.labelings.each do |ln|
|
31
|
-
concept = ln.owner
|
32
|
-
label = ln.target
|
33
|
-
weight = WEIGHTINGS[ln.class.name]
|
34
|
-
|
35
|
-
memo[label] ||= []
|
36
|
-
# weighting
|
37
|
-
memo[label][0] ||= 0
|
38
|
-
memo[label][0] += weight
|
39
|
-
# associated concepts
|
40
|
-
memo[label] << concept unless memo[label].include? concept
|
41
|
-
concept.narrower_relations.published.map { |nr| nr.target.pref_label }.each do |pref_label|
|
42
|
-
memo[pref_label] ||= []
|
43
|
-
memo[pref_label][0] ||= 0
|
44
|
-
memo[pref_label][0] += 0
|
45
|
-
# associated concepts
|
46
|
-
pref_label.concepts.published.each do |c|
|
47
|
-
memo[pref_label] << c unless memo[pref_label].include? c
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
# evaluate only if iqvoc_compound_forms engine is loaded
|
54
|
-
if Iqvoc.const_defined?(:CompoundForms)
|
55
|
-
label = Iqvoc::XLLabel.base_class.find_by(value: term)
|
56
|
-
if memo.empty? && label.present?
|
57
|
-
label.compound_in.each do |compound_in|
|
58
|
-
memo[compound_in] ||= []
|
59
|
-
memo[compound_in][0] ||= 0
|
60
|
-
memo[compound_in][0] += 0
|
61
|
-
compound_in.concepts.published.each do |concept|
|
62
|
-
memo[compound_in] << concept unless memo[compound_in].include? concept
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
memo
|
14
|
+
def self.register_weighting(klass_str, value)
|
15
|
+
Mutex.new.synchronize do
|
16
|
+
@@weightings[klass_str] = value
|
68
17
|
end
|
69
18
|
end
|
70
19
|
|
71
|
-
|
72
|
-
|
73
|
-
concepts = terms_to_concepts(lang, *terms).
|
74
|
-
includes(:labelings => [:owner, :target]).
|
75
|
-
where("labels.language" => lang) # applies language constraint to results
|
76
|
-
return concepts.map do |concept|
|
77
|
-
concept.labelings.map { |ln| ln.target }
|
78
|
-
end.flatten.sort_by { |label| label.value }
|
79
|
-
end
|
80
|
-
|
81
|
-
def self.terms_to_concepts(lang, *terms)
|
82
|
-
concept_ids = terms_to_labels(lang, *terms).includes(:labelings).
|
83
|
-
map { |label| label.labelings.map(&:owner_id) }.flatten.uniq
|
84
|
-
return Iqvoc::Concept.base_class.where(:id => concept_ids)
|
20
|
+
def self.weightings
|
21
|
+
@@weightings
|
85
22
|
end
|
86
|
-
|
87
|
-
# NB: case-insensitive only when inflectionals are available
|
88
|
-
def self.terms_to_labels(lang, *terms)
|
89
|
-
# efficiency enhancement to turn `IN` into `=` queries where possible
|
90
|
-
reduce = lambda { |arr| arr.length < 2 ? arr[0] : arr }
|
91
|
-
|
92
|
-
if Iqvoc.const_defined?(:Inflectionals)
|
93
|
-
# use normalized form for case-insensitivity (and performance)
|
94
|
-
hashes = terms.map { |term| Inflectional::Base.normalize(term) }
|
95
|
-
label_ids = Inflectional::Base.select([:label_id]).
|
96
|
-
where(:normal_hash => reduce.call(hashes)).map(&:label_id)
|
97
|
-
return Iqvoc::XLLabel.base_class.where(:language => lang,
|
98
|
-
:id => reduce.call(label_ids))
|
99
|
-
elsif Iqvoc.const_defined?(:XLLabel)
|
100
|
-
return Iqvoc::XLLabel.base_class.where(:language => lang,
|
101
|
-
:value => reduce.call(terms))
|
102
|
-
else
|
103
|
-
return Iqvoc::Label.base_class.where(:language => lang,
|
104
|
-
:value => reduce.call(terms))
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
23
|
end
|
109
24
|
end
|