iqvoc_similar_terms 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +7 -0
- data/Gemfile +21 -0
- data/Gemfile.lock +162 -0
- data/README.md +23 -0
- data/Rakefile +21 -0
- data/app/controllers/similar_terms_controller.rb +26 -0
- data/app/views/similar_terms/show.iqrdf +41 -0
- data/config/application.rb +67 -0
- data/config/boot.rb +6 -0
- data/config/database.sqlite.yml +11 -0
- data/config/engine.rb +15 -0
- data/config/environment.rb +5 -0
- data/config/environments/development.rb +9 -0
- data/config/environments/production.rb +8 -0
- data/config/environments/test.rb +9 -0
- data/config/initializers/iqvoc.rb +5 -0
- data/config/initializers/secret_token.rb.template +16 -0
- data/config/initializers/session_store.rb +11 -0
- data/config/initializers/wrap_parameters.rb +14 -0
- data/config/routes.rb +3 -0
- data/config.ru +4 -0
- data/iqvoc_similar_terms.gemspec +25 -0
- data/lib/iqvoc/similar_terms/version.rb +5 -0
- data/lib/iqvoc/similar_terms.rb +72 -0
- data/lib/iqvoc_similar_terms.rb +15 -0
- data/public/.gitkeep +0 -0
- data/script/rails +6 -0
- data/test/functional/api_test.rb +72 -0
- data/test/test_helper.rb +3 -0
- data/test/unit/entity_resolution_test.rb +46 -0
- data/test/unit/results_test.rb +55 -0
- metadata +108 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2c8fba3ab72351ddfd52fe1b630fda27ef5130e7
|
4
|
+
data.tar.gz: a10cbe81513393f65f7e99a5cfa90f63f3eb394c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f04a7169a8cf2a9c4eba55350fac2deeaa5777ebbf2ac8f6f9457cefb94e92f6ebe291959332c1e7516f0adb0d3e436dfd0ec08f12875a5807b7be0298bb8327
|
7
|
+
data.tar.gz: 87f522ee7b45e540f998d71d1a396730bbd60b5bc9a8d17426c3e477d76839404f9f238c4c7f726f54e899cef58805040ae045e7976c36569287ee31e9281d83
|
data/.gitignore
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
source 'http://rubygems.org'
|
2
|
+
|
3
|
+
gem 'rails', '~> 3.2.1'
|
4
|
+
gem 'iqvoc', '~> 4.0.9'
|
5
|
+
|
6
|
+
group :development, :test do
|
7
|
+
gem 'pry'
|
8
|
+
gem 'pry-rails'
|
9
|
+
gem 'pry-debugger'
|
10
|
+
gem 'hirb-unicode'
|
11
|
+
gem 'zeus'
|
12
|
+
gem 'cane'
|
13
|
+
|
14
|
+
platforms :ruby do
|
15
|
+
gem 'sqlite3'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
group :test do
|
20
|
+
gem 'minitest'
|
21
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,162 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
actionmailer (3.2.13)
|
5
|
+
actionpack (= 3.2.13)
|
6
|
+
mail (~> 2.5.3)
|
7
|
+
actionpack (3.2.13)
|
8
|
+
activemodel (= 3.2.13)
|
9
|
+
activesupport (= 3.2.13)
|
10
|
+
builder (~> 3.0.0)
|
11
|
+
erubis (~> 2.7.0)
|
12
|
+
journey (~> 1.0.4)
|
13
|
+
rack (~> 1.4.5)
|
14
|
+
rack-cache (~> 1.2)
|
15
|
+
rack-test (~> 0.6.1)
|
16
|
+
sprockets (~> 2.2.1)
|
17
|
+
activemodel (3.2.13)
|
18
|
+
activesupport (= 3.2.13)
|
19
|
+
builder (~> 3.0.0)
|
20
|
+
activerecord (3.2.13)
|
21
|
+
activemodel (= 3.2.13)
|
22
|
+
activesupport (= 3.2.13)
|
23
|
+
arel (~> 3.0.2)
|
24
|
+
tzinfo (~> 0.3.29)
|
25
|
+
activeresource (3.2.13)
|
26
|
+
activemodel (= 3.2.13)
|
27
|
+
activesupport (= 3.2.13)
|
28
|
+
activesupport (3.2.13)
|
29
|
+
i18n (= 0.6.1)
|
30
|
+
multi_json (~> 1.0)
|
31
|
+
arel (3.0.2)
|
32
|
+
authlogic (3.3.0)
|
33
|
+
activerecord (>= 3.2)
|
34
|
+
activesupport (>= 3.2)
|
35
|
+
builder (3.0.4)
|
36
|
+
cancan (1.6.9)
|
37
|
+
cane (2.5.2)
|
38
|
+
parallel
|
39
|
+
coderay (1.0.9)
|
40
|
+
columnize (0.3.6)
|
41
|
+
debugger (1.5.0)
|
42
|
+
columnize (>= 0.3.1)
|
43
|
+
debugger-linecache (~> 1.2.0)
|
44
|
+
debugger-ruby_core_source (~> 1.2.0)
|
45
|
+
debugger-linecache (1.2.0)
|
46
|
+
debugger-ruby_core_source (1.2.0)
|
47
|
+
erubis (2.7.0)
|
48
|
+
fastercsv (1.5.5)
|
49
|
+
hike (1.2.2)
|
50
|
+
hirb (0.7.1)
|
51
|
+
hirb-unicode (0.0.5)
|
52
|
+
hirb (~> 0.5)
|
53
|
+
unicode-display_width (~> 0.1.1)
|
54
|
+
i18n (0.6.1)
|
55
|
+
iq_rdf (0.1.10)
|
56
|
+
activesupport
|
57
|
+
builder
|
58
|
+
bundler
|
59
|
+
iq_triplestorage (0.2.2)
|
60
|
+
iqvoc (4.0.9)
|
61
|
+
authlogic
|
62
|
+
bundler
|
63
|
+
cancan
|
64
|
+
fastercsv
|
65
|
+
iq_rdf (~> 0.1.2)
|
66
|
+
iq_triplestorage
|
67
|
+
json
|
68
|
+
kaminari
|
69
|
+
rails (~> 3.2.1)
|
70
|
+
rails_autolink
|
71
|
+
sass-rails (~> 3.2.5)
|
72
|
+
simple_form
|
73
|
+
journey (1.0.4)
|
74
|
+
json (1.7.7)
|
75
|
+
kaminari (0.14.1)
|
76
|
+
actionpack (>= 3.0.0)
|
77
|
+
activesupport (>= 3.0.0)
|
78
|
+
mail (2.5.3)
|
79
|
+
i18n (>= 0.4.0)
|
80
|
+
mime-types (~> 1.16)
|
81
|
+
treetop (~> 1.4.8)
|
82
|
+
method_source (0.8.1)
|
83
|
+
mime-types (1.22)
|
84
|
+
minitest (4.7.1)
|
85
|
+
multi_json (1.7.2)
|
86
|
+
parallel (0.6.4)
|
87
|
+
polyglot (0.3.3)
|
88
|
+
pry (0.9.12)
|
89
|
+
coderay (~> 1.0.5)
|
90
|
+
method_source (~> 0.8)
|
91
|
+
slop (~> 3.4)
|
92
|
+
pry-debugger (0.2.2)
|
93
|
+
debugger (~> 1.3)
|
94
|
+
pry (~> 0.9.10)
|
95
|
+
pry-rails (0.2.2)
|
96
|
+
pry (>= 0.9.10)
|
97
|
+
rack (1.4.5)
|
98
|
+
rack-cache (1.2)
|
99
|
+
rack (>= 0.4)
|
100
|
+
rack-ssl (1.3.3)
|
101
|
+
rack
|
102
|
+
rack-test (0.6.2)
|
103
|
+
rack (>= 1.0)
|
104
|
+
rails (3.2.13)
|
105
|
+
actionmailer (= 3.2.13)
|
106
|
+
actionpack (= 3.2.13)
|
107
|
+
activerecord (= 3.2.13)
|
108
|
+
activeresource (= 3.2.13)
|
109
|
+
activesupport (= 3.2.13)
|
110
|
+
bundler (~> 1.0)
|
111
|
+
railties (= 3.2.13)
|
112
|
+
rails_autolink (1.0.9)
|
113
|
+
rails (~> 3.1)
|
114
|
+
railties (3.2.13)
|
115
|
+
actionpack (= 3.2.13)
|
116
|
+
activesupport (= 3.2.13)
|
117
|
+
rack-ssl (~> 1.3.2)
|
118
|
+
rake (>= 0.8.7)
|
119
|
+
rdoc (~> 3.4)
|
120
|
+
thor (>= 0.14.6, < 2.0)
|
121
|
+
rake (10.0.4)
|
122
|
+
rdoc (3.12.2)
|
123
|
+
json (~> 1.4)
|
124
|
+
sass (3.2.7)
|
125
|
+
sass-rails (3.2.6)
|
126
|
+
railties (~> 3.2.0)
|
127
|
+
sass (>= 3.1.10)
|
128
|
+
tilt (~> 1.3)
|
129
|
+
simple_form (2.1.0)
|
130
|
+
actionpack (~> 3.0)
|
131
|
+
activemodel (~> 3.0)
|
132
|
+
slop (3.4.4)
|
133
|
+
sprockets (2.2.2)
|
134
|
+
hike (~> 1.2)
|
135
|
+
multi_json (~> 1.0)
|
136
|
+
rack (~> 1.0)
|
137
|
+
tilt (~> 1.1, != 1.3.0)
|
138
|
+
sqlite3 (1.3.7)
|
139
|
+
thor (0.18.1)
|
140
|
+
tilt (1.3.7)
|
141
|
+
treetop (1.4.12)
|
142
|
+
polyglot
|
143
|
+
polyglot (>= 0.3.1)
|
144
|
+
tzinfo (0.3.37)
|
145
|
+
unicode-display_width (0.1.1)
|
146
|
+
zeus (0.13.3)
|
147
|
+
method_source (>= 0.6.7)
|
148
|
+
|
149
|
+
PLATFORMS
|
150
|
+
ruby
|
151
|
+
|
152
|
+
DEPENDENCIES
|
153
|
+
cane
|
154
|
+
hirb-unicode
|
155
|
+
iqvoc (~> 4.0.9)
|
156
|
+
minitest
|
157
|
+
pry
|
158
|
+
pry-debugger
|
159
|
+
pry-rails
|
160
|
+
rails (~> 3.2.1)
|
161
|
+
sqlite3
|
162
|
+
zeus
|
data/README.md
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
Similar Terms for iQvoc
|
2
|
+
|
3
|
+
|
4
|
+
Getting Started
|
5
|
+
===============
|
6
|
+
|
7
|
+
1. Initialize database:
|
8
|
+
|
9
|
+
$ bundle exec rake db:create
|
10
|
+
$ bundle exec rake db:migrate iqvoc:db:seed_all
|
11
|
+
|
12
|
+
2. Generate secret token:
|
13
|
+
|
14
|
+
$ rake iqvoc:setup:generate_secret_token
|
15
|
+
|
16
|
+
|
17
|
+
Extensions
|
18
|
+
==========
|
19
|
+
|
20
|
+
In addition to regular SKOS, Similar Terms supports
|
21
|
+
[SKOS-XL](https://github.com/innoq/iqvoc_skosxl) and
|
22
|
+
[Inflectionals](https://github.com/innoq/iqvoc_inflectionals) - the latter
|
23
|
+
provides case-insensitive lookups.
|
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
3
|
+
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
4
|
+
|
5
|
+
require File.expand_path('../config/application', __FILE__)
|
6
|
+
require 'rake'
|
7
|
+
|
8
|
+
Iqvoc::SimilarTerms::Application.load_tasks
|
9
|
+
|
10
|
+
require 'bundler'
|
11
|
+
Bundler::GemHelper.install_tasks
|
12
|
+
|
13
|
+
desc "Build gem"
|
14
|
+
task :build do |t|
|
15
|
+
`rm *.gem; gem build *.gemspec`
|
16
|
+
end
|
17
|
+
|
18
|
+
desc "Release gem"
|
19
|
+
task :release => :build do |t|
|
20
|
+
`gem push *.gem`
|
21
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'iqvoc/similar_terms' # XXX: should not be necessary!?
|
4
|
+
|
5
|
+
class SimilarTermsController < ApplicationController
|
6
|
+
|
7
|
+
def show
|
8
|
+
authorize! :read, Iqvoc::Concept.base_class
|
9
|
+
|
10
|
+
unless params[:terms]
|
11
|
+
head 400
|
12
|
+
return
|
13
|
+
end
|
14
|
+
|
15
|
+
@terms = Iqvoc::InlineDataHelper.parse_inline_values(params[:terms])
|
16
|
+
lang = params[:lang]
|
17
|
+
|
18
|
+
@results = Iqvoc::SimilarTerms.ranked(lang, *@terms)
|
19
|
+
|
20
|
+
respond_to do |format|
|
21
|
+
format.ttl
|
22
|
+
format.rdf
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
Iqvoc.default_rdf_namespace_helper_methods.each do |meth|
|
2
|
+
document.namespaces(self.send(meth))
|
3
|
+
end
|
4
|
+
|
5
|
+
subject = url_for(request.query_parameters.
|
6
|
+
merge(:only_path => false, :anchor => ""))
|
7
|
+
|
8
|
+
document.namespaces(:sdc => "http://sindice.com/vocab/search#",
|
9
|
+
:query => subject)
|
10
|
+
|
11
|
+
document << IqRdf::Query.build_uri("top",
|
12
|
+
IqRdf::Sdc::build_uri("Query")) do |query|
|
13
|
+
query.Sdc::totalResults(@results.length)
|
14
|
+
query.Sdc::itemsPerPage(@results.length) # XXX: preliminary
|
15
|
+
query.Sdc::searchTerms(@terms)
|
16
|
+
|
17
|
+
skos = IqRdf::Namespace.find_namespace_class("skos")
|
18
|
+
processed_concepts = {} # XXX: crutch
|
19
|
+
@results.each_with_index do |data, i|
|
20
|
+
i += 1
|
21
|
+
|
22
|
+
# XXX: data structure smell
|
23
|
+
label = data[0]
|
24
|
+
concepts = data[1..-1]
|
25
|
+
|
26
|
+
result = "result#{i}"
|
27
|
+
query.Sdc::result(IqRdf::Query::build_uri(result))
|
28
|
+
document << IqRdf::Query::build_uri(result,
|
29
|
+
IqRdf::Sdc::build_uri("Result")) do |sbj|
|
30
|
+
sbj.Rdfs::label(label.value, :lang => label.language)
|
31
|
+
sbj.Sdc::rank(i)
|
32
|
+
concepts.each do |concept|
|
33
|
+
sbj.Sdc::link(IqRdf.build_uri(concept.origin))
|
34
|
+
unless processed_concepts[concept.origin]
|
35
|
+
document << IqRdf.build_uri(concept.origin, skos.build_uri("Concept"))
|
36
|
+
processed_concepts[concept.origin] = true
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require File.expand_path('../boot', __FILE__)
|
2
|
+
|
3
|
+
require 'rails/all'
|
4
|
+
|
5
|
+
if defined?(Bundler)
|
6
|
+
# If you precompile assets before deploying to production, use this line
|
7
|
+
Bundler.require *Rails.groups(:assets => %w(development test))
|
8
|
+
# If you want your assets lazily compiled in production, use this line
|
9
|
+
# Bundler.require(:default, :assets, Rails.env)
|
10
|
+
end
|
11
|
+
|
12
|
+
module Iqvoc::SimilarTerms
|
13
|
+
class Application < Rails::Application
|
14
|
+
|
15
|
+
# This tells iqvoc_similar_terms.rb whether it it runs as app or as engine
|
16
|
+
require 'iqvoc_similar_terms'
|
17
|
+
|
18
|
+
# Settings in config/environments/* take precedence over those specified here.
|
19
|
+
# Application configuration should go into files in config/initializers
|
20
|
+
# -- all .rb files in that directory are automatically loaded.
|
21
|
+
|
22
|
+
# Custom directories with classes and modules you want to be autoloadable.
|
23
|
+
# config.autoload_paths += %W(#{config.root}/extras)
|
24
|
+
|
25
|
+
# Only load the plugins named here, in the order given (default is alphabetical).
|
26
|
+
# :all can be used as a placeholder for all plugins not explicitly named.
|
27
|
+
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]
|
28
|
+
|
29
|
+
# Activate observers that should always be running.
|
30
|
+
# config.active_record.observers = :cacher, :garbage_collector, :forum_observer
|
31
|
+
|
32
|
+
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
|
33
|
+
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
|
34
|
+
# config.time_zone = 'Central Time (US & Canada)'
|
35
|
+
|
36
|
+
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
|
37
|
+
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
|
38
|
+
config.i18n.default_locale = :de
|
39
|
+
# config.i18n.available_locales = [:de, :en]
|
40
|
+
|
41
|
+
# Configure the default encoding used in templates for Ruby 1.9.
|
42
|
+
config.encoding = "utf-8"
|
43
|
+
|
44
|
+
# Configure sensitive parameters which will be filtered from the log file.
|
45
|
+
config.filter_parameters += [:password, :password_confirmation]
|
46
|
+
|
47
|
+
# Enable escaping HTML in JSON.
|
48
|
+
config.active_support.escape_html_entities_in_json = true
|
49
|
+
|
50
|
+
# Use SQL instead of Active Record's schema dumper when creating the database.
|
51
|
+
# This is necessary if your schema can't be completely dumped by the schema dumper,
|
52
|
+
# like if you have constraints or database-specific column types
|
53
|
+
# config.active_record.schema_format = :sql
|
54
|
+
|
55
|
+
# Enforce whitelist mode for mass assignment.
|
56
|
+
# This will create an empty whitelist of attributes available for mass-assignment for all models
|
57
|
+
# in your app. As such, your models will need to explicitly whitelist or blacklist accessible
|
58
|
+
# parameters by using an attr_accessible or attr_protected declaration.
|
59
|
+
config.active_record.whitelist_attributes = true
|
60
|
+
|
61
|
+
# Enable the asset pipeline
|
62
|
+
config.assets.enabled = true
|
63
|
+
|
64
|
+
# Version of your assets, change this if you want to expire all your assets
|
65
|
+
config.assets.version = "1.0.0"
|
66
|
+
end
|
67
|
+
end
|
data/config/boot.rb
ADDED
data/config/engine.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rails'
|
2
|
+
|
3
|
+
module Iqvoc
|
4
|
+
module SimilarTerms
|
5
|
+
|
6
|
+
class Engine < Rails::Engine
|
7
|
+
paths["lib/tasks"] << "lib/engine_tasks"
|
8
|
+
|
9
|
+
initializer "iqvoc_similar_terms.load_migrations" do |app|
|
10
|
+
app.config.paths['db/migrate'] += Iqvoc::SimilarTerms::Engine.paths['db/migrate'].existent
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'debug'
|
2
|
+
require 'iqvoc/environments/development'
|
3
|
+
|
4
|
+
if Iqvoc::SimilarTerms.const_defined?(:Application)
|
5
|
+
Iqvoc::SimilarTerms::Application.configure do
|
6
|
+
# Settings specified here will take precedence over those in config/environment.rb
|
7
|
+
Iqvoc::Environments.setup_development(config)
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
require 'iqvoc/environments/production'
|
2
|
+
|
3
|
+
if Iqvoc::SimilarTerms.const_defined?(:Application)
|
4
|
+
Iqvoc::SimilarTerms::Application.configure do
|
5
|
+
# Settings specified here will take precedence over those in config/environment.rb
|
6
|
+
Iqvoc::Environments.setup_production(config)
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'debug'
|
2
|
+
require 'iqvoc/environments/test'
|
3
|
+
|
4
|
+
if Iqvoc::SimilarTerms.const_defined?(:Application)
|
5
|
+
Iqvoc::SimilarTerms::Application.configure do
|
6
|
+
# Settings specified here will take precedence over those in config/environment.rb
|
7
|
+
Iqvoc::Environments.setup_test(config)
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
# Be sure to restart your server when you modify this file.
|
4
|
+
|
5
|
+
if Iqvoc::SimilarTerms.const_defined?(:Application)
|
6
|
+
|
7
|
+
# Your secret key for verifying the integrity of signed cookies.
|
8
|
+
# If you change this key, all old signed cookies will become invalid!
|
9
|
+
# Make sure the secret is at least 30 characters and all random,
|
10
|
+
# no regular words or you'll be exposed to dictionary attacks.
|
11
|
+
|
12
|
+
# Run `rake secret` and uncomment the following line
|
13
|
+
# Replace the secret-placeholder with your generated token
|
14
|
+
Iqvoc::SimilarTerms::Application.config.secret_token = "S-E-C-R-E-T"
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
2
|
+
|
3
|
+
if Iqvoc::SimilarTerms.const_defined?(:Application)
|
4
|
+
Iqvoc::SimilarTerms::Application.config.session_store :cookie_store,
|
5
|
+
:key => "_iqvoc_similar_terms_session"
|
6
|
+
end
|
7
|
+
|
8
|
+
# Use the database for sessions instead of the cookie-based default,
|
9
|
+
# which shouldn't be used to store highly confidential information
|
10
|
+
# (create the session table with "rake db:sessions:create")
|
11
|
+
# Iqvoc::Application.config.session_store :active_record_store
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
2
|
+
#
|
3
|
+
# This file contains settings for ActionController::ParamsWrapper which
|
4
|
+
# is enabled by default.
|
5
|
+
|
6
|
+
# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
|
7
|
+
ActiveSupport.on_load(:action_controller) do
|
8
|
+
wrap_parameters format: [:json]
|
9
|
+
end
|
10
|
+
|
11
|
+
# Disable root element in JSON by default.
|
12
|
+
ActiveSupport.on_load(:active_record) do
|
13
|
+
self.include_root_in_json = false
|
14
|
+
end
|
data/config/routes.rb
ADDED
data/config.ru
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
$:.push File.expand_path("../lib", __FILE__)
|
4
|
+
require "iqvoc/similar_terms/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "iqvoc_similar_terms"
|
8
|
+
s.version = Iqvoc::SimilarTerms::VERSION
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.authors = ["Frederik Dohr", "Robert Glaser", "Till Schulte-Coerne"]
|
11
|
+
s.email = ["robert.glaser@innoq.com"]
|
12
|
+
s.homepage = "" # TODO
|
13
|
+
s.summary = "" # TODO
|
14
|
+
s.description = "" # TODO
|
15
|
+
|
16
|
+
s.rubyforge_project = "iqvoc_similar_terms"
|
17
|
+
|
18
|
+
s.add_dependency "rails", "~> 3.2.1"
|
19
|
+
s.add_dependency "iqvoc", "~> 4.0.0"
|
20
|
+
|
21
|
+
s.files = `git ls-files`.split("\n")
|
22
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
23
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
24
|
+
s.require_paths = ["lib"]
|
25
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Iqvoc
|
2
|
+
module SimilarTerms # TODO: make language constraints optional
|
3
|
+
|
4
|
+
WEIGHTINGS = { # XXX: hard-coded - should be read from configuration
|
5
|
+
"Labeling::SKOS::PrefLabel" => 5,
|
6
|
+
"Labeling::SKOS::AltLabel" => 2,
|
7
|
+
"Labeling::SKOS::HiddenLabel" => 1,
|
8
|
+
# SKOS-XL
|
9
|
+
"Labeling::SKOSXL::PrefLabel" => 5,
|
10
|
+
"Labeling::SKOSXL::AltLabel" => 2,
|
11
|
+
"Labeling::SKOSXL::HiddenLabel" => 1
|
12
|
+
}
|
13
|
+
|
14
|
+
# returns an array of label/concepts pairs, sorted descendingly by weighting
|
15
|
+
def self.ranked(lang, *terms) # TODO: rename
|
16
|
+
weighted(lang, *terms).sort_by { |label, data| data[0] }.reverse.
|
17
|
+
map { |label, data| [label] + data[1..-1] } # drop weighting
|
18
|
+
end
|
19
|
+
|
20
|
+
# returns a hash of label/weighting+concepts pairs
|
21
|
+
def self.weighted(lang, *terms) # TODO: rename
|
22
|
+
concepts = terms_to_concepts(lang, *terms).
|
23
|
+
includes(:labelings => [:owner, :target])
|
24
|
+
return terms.inject({}) do |memo, term|
|
25
|
+
concepts.each do |concept|
|
26
|
+
concept.labelings.each do |ln|
|
27
|
+
concept = ln.owner
|
28
|
+
label = ln.target
|
29
|
+
weight = WEIGHTINGS[ln.class.name]
|
30
|
+
|
31
|
+
memo[label] ||= []
|
32
|
+
# weighting
|
33
|
+
memo[label][0] ||= 0
|
34
|
+
memo[label][0] += weight
|
35
|
+
# associated concepts
|
36
|
+
memo[label] << concept
|
37
|
+
memo[label].uniq! # XXX: inefficient!? can't easily use Set here though
|
38
|
+
end
|
39
|
+
end
|
40
|
+
memo
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.terms_to_concepts(lang, *terms)
|
45
|
+
concept_ids = terms_to_labels(lang, *terms).includes(:labelings).
|
46
|
+
map { |label| label.labelings.map(&:owner_id) }.flatten.uniq
|
47
|
+
return Iqvoc::Concept.base_class.where(:id => concept_ids)
|
48
|
+
end
|
49
|
+
|
50
|
+
# NB: case-insensitive only when inflectionals are available
|
51
|
+
def self.terms_to_labels(lang, *terms)
|
52
|
+
# efficiency enhancement to turn `IN` into `=` queries where possible
|
53
|
+
reduce = lambda { |arr| arr.length < 2 ? arr[0] : arr }
|
54
|
+
|
55
|
+
if Iqvoc.const_defined?(:Inflectionals)
|
56
|
+
# use normalized form for case-insensitivity (and performance)
|
57
|
+
hashes = terms.map { |term| Inflectional::Base.normalize(term) }
|
58
|
+
label_ids = Inflectional::Base.select([:label_id]).
|
59
|
+
where(:normal_hash => reduce.call(hashes)).map(&:label_id)
|
60
|
+
return Iqvoc::XLLabel.base_class.where(:language => lang,
|
61
|
+
:id => reduce.call(label_ids))
|
62
|
+
elsif Iqvoc.const_defined?(:XLLabel)
|
63
|
+
return Iqvoc::XLLabel.base_class.where(:language => lang,
|
64
|
+
:value => reduce.call(terms))
|
65
|
+
else
|
66
|
+
return Iqvoc::Label.base_class.where(:language => lang,
|
67
|
+
:value => reduce.call(terms))
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'iqvoc/similar_terms/version'
|
4
|
+
|
5
|
+
module IqvocSimilarTerms
|
6
|
+
|
7
|
+
unless Iqvoc.const_defined?(:SimilarTerms) && Iqvoc::SimilarTerms.const_defined?(:Application)
|
8
|
+
require File.join(File.dirname(__FILE__), '../config/engine')
|
9
|
+
end
|
10
|
+
|
11
|
+
ActiveSupport.on_load(:after_iqvoc_config) do
|
12
|
+
require 'iqvoc'
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
data/public/.gitkeep
ADDED
File without changes
|
data/script/rails
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
|
3
|
+
|
4
|
+
APP_PATH = File.expand_path('../../config/application', __FILE__)
|
5
|
+
require File.expand_path('../../config/boot', __FILE__)
|
6
|
+
require 'rails/commands'
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '../test_helper')
|
4
|
+
require 'iqvoc/rdfapi' # XXX: only required with Zeus
|
5
|
+
|
6
|
+
class SimilarTermsTest < ActionController::TestCase
|
7
|
+
|
8
|
+
setup do
|
9
|
+
@controller = SimilarTermsController.new
|
10
|
+
|
11
|
+
forest = Iqvoc::RDFAPI.devour("forest", "a", "skos:Concept") # FIXME: should be ":forest", but https://github.com/innoq/iqvoc/issues/195
|
12
|
+
Iqvoc::RDFAPI.devour(forest, "skos:prefLabel", '"forest"@en')
|
13
|
+
Iqvoc::RDFAPI.devour(forest, "skos:altLabel", '"woods"@en')
|
14
|
+
forest.save
|
15
|
+
|
16
|
+
car = Iqvoc::RDFAPI.devour("car", "a", "skos:Concept") # FIXME: should be ":car"; see above
|
17
|
+
Iqvoc::RDFAPI.devour(car, "skos:prefLabel", '"car"@en')
|
18
|
+
Iqvoc::RDFAPI.devour(car, "skos:altLabel", '"automobile"@en')
|
19
|
+
car.save
|
20
|
+
end
|
21
|
+
|
22
|
+
test "routing" do
|
23
|
+
assert_raises ActionController::RoutingError do
|
24
|
+
get :show
|
25
|
+
end
|
26
|
+
assert_raises ActionController::RoutingError do
|
27
|
+
get :show, :format => "ttl"
|
28
|
+
end
|
29
|
+
|
30
|
+
get :show, :lang => "en", :format => "ttl"
|
31
|
+
assert_response 400
|
32
|
+
|
33
|
+
get :show, :lang => "en", :format => "ttl", :terms => "foo"
|
34
|
+
assert_response 200
|
35
|
+
assert !@response.body.include?("a sdc:Result")
|
36
|
+
end
|
37
|
+
|
38
|
+
test "RDF representations" do
|
39
|
+
get :show, :lang => "en", :format => "ttl", :terms => "forest"
|
40
|
+
assert_response :success
|
41
|
+
assert @response.body.include?(<<-EOS)
|
42
|
+
@prefix sdc: <http://sindice.com/vocab/search#>.
|
43
|
+
EOS
|
44
|
+
assert @response.body.include?(<<-EOS)
|
45
|
+
@prefix skos: <http://www.w3.org/2004/02/skos/core#>.
|
46
|
+
EOS
|
47
|
+
assert @response.body.include?(<<-EOS)
|
48
|
+
@prefix query: <http://test.host/en/similar.ttl?terms=forest#>.
|
49
|
+
EOS
|
50
|
+
assert @response.body.include?(<<-EOS)
|
51
|
+
query:top a sdc:Query;
|
52
|
+
EOS
|
53
|
+
assert @response.body.include?(<<-EOS)
|
54
|
+
query:result1 a sdc:Result;
|
55
|
+
rdfs:label "forest"@en;
|
56
|
+
sdc:rank 1;
|
57
|
+
sdc:link :forest.
|
58
|
+
EOS
|
59
|
+
assert @response.body.include?(<<-EOS)
|
60
|
+
query:result2 a sdc:Result;
|
61
|
+
rdfs:label "woods"@en;
|
62
|
+
sdc:rank 2;
|
63
|
+
sdc:link :forest.
|
64
|
+
EOS
|
65
|
+
assert @response.body.include?(<<-EOS)
|
66
|
+
:forest a skos:Concept.
|
67
|
+
EOS
|
68
|
+
# ensure there are no duplicates
|
69
|
+
assert_equal 2, @response.body.split("a skos:Concept").length
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '../test_helper')
|
4
|
+
require 'iqvoc/rdfapi' # XXX: only required with Zeus
|
5
|
+
require 'iqvoc/similar_terms' # XXX: should not be necessary!?
|
6
|
+
|
7
|
+
class EntityResolutionTest < ActiveSupport::TestCase
|
8
|
+
|
9
|
+
setup do
|
10
|
+
forest = Iqvoc::RDFAPI.devour(":forest", "a", "skos:Concept")
|
11
|
+
Iqvoc::RDFAPI.devour(forest, "skos:prefLabel", '"forest"@en')
|
12
|
+
Iqvoc::RDFAPI.devour(forest, "skos:altLabel", '"woods"@en')
|
13
|
+
forest.save
|
14
|
+
end
|
15
|
+
|
16
|
+
test "concept resolution" do
|
17
|
+
concepts = Iqvoc::SimilarTerms.terms_to_concepts("en","forest")
|
18
|
+
assert_equal 1, concepts.length
|
19
|
+
assert_equal Iqvoc::Concept.base_class, concepts[0].class
|
20
|
+
|
21
|
+
concepts = Iqvoc::SimilarTerms.terms_to_concepts("de","forest")
|
22
|
+
assert_equal 0, concepts.count
|
23
|
+
|
24
|
+
concepts = Iqvoc::SimilarTerms.terms_to_concepts("en", "foo")
|
25
|
+
assert_equal 0, concepts.count
|
26
|
+
end
|
27
|
+
|
28
|
+
test "label resolution" do
|
29
|
+
labels = Iqvoc::SimilarTerms.terms_to_labels("en", "forest")
|
30
|
+
assert_equal ActiveRecord::Relation, labels.class
|
31
|
+
labels = labels.all
|
32
|
+
assert_equal 1, labels.length
|
33
|
+
assert_equal Iqvoc::Label.base_class, labels[0].class
|
34
|
+
assert_equal "forest", labels[0].value
|
35
|
+
assert_equal "en", labels[0].language
|
36
|
+
|
37
|
+
labels = Iqvoc::SimilarTerms.terms_to_labels("de", "forest")
|
38
|
+
assert_equal 0, labels.count
|
39
|
+
|
40
|
+
labels = Iqvoc::SimilarTerms.terms_to_labels("en", "foo")
|
41
|
+
assert_equal 0, labels.count
|
42
|
+
|
43
|
+
# TODO: test XLLabel and Inflectional variants
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '../test_helper')
|
4
|
+
require 'iqvoc/rdfapi' # XXX: only required with Zeus
|
5
|
+
require 'iqvoc/similar_terms' # XXX: should not be necessary!?
|
6
|
+
|
7
|
+
class ResultsTest < ActiveSupport::TestCase
|
8
|
+
|
9
|
+
setup do
|
10
|
+
forest = Iqvoc::RDFAPI.devour(":forest", "a", "skos:Concept")
|
11
|
+
Iqvoc::RDFAPI.devour(forest, "skos:prefLabel", '"forest"@en')
|
12
|
+
Iqvoc::RDFAPI.devour(forest, "skos:altLabel", '"woods"@en')
|
13
|
+
forest.save
|
14
|
+
|
15
|
+
car = Iqvoc::RDFAPI.devour(":car", "a", "skos:Concept")
|
16
|
+
Iqvoc::RDFAPI.devour(car, "skos:prefLabel", '"car"@en')
|
17
|
+
Iqvoc::RDFAPI.devour(car, "skos:altLabel", '"automobile"@en')
|
18
|
+
car.save
|
19
|
+
end
|
20
|
+
|
21
|
+
test "ranked results" do
|
22
|
+
results = Iqvoc::SimilarTerms.ranked("en", "forest")
|
23
|
+
assert_equal 2, results.length
|
24
|
+
assert_equal Iqvoc::Label.base_class, results[0][0].class
|
25
|
+
assert_equal "forest", results[0][0].value
|
26
|
+
assert_equal ":forest", results[0][1].origin
|
27
|
+
assert_equal "woods", results[1][0].value
|
28
|
+
assert_equal ":forest", results[1][1].origin
|
29
|
+
|
30
|
+
results = Iqvoc::SimilarTerms.ranked("en", "woods", "car")
|
31
|
+
assert_equal 4, results.length
|
32
|
+
assert_equal "forest", results[0][0].value
|
33
|
+
assert_equal ":forest", results[0][1].origin
|
34
|
+
assert_equal "car", results[1][0].value
|
35
|
+
assert_equal ":car", results[1][1].origin
|
36
|
+
assert_equal "woods", results[2][0].value
|
37
|
+
assert_equal ":forest", results[2][1].origin
|
38
|
+
assert_equal "automobile", results[3][0].value
|
39
|
+
assert_equal ":car", results[3][1].origin
|
40
|
+
assert_equal results[0].length, results[0].uniq.length
|
41
|
+
end
|
42
|
+
|
43
|
+
test "weighted results" do
|
44
|
+
results = Iqvoc::SimilarTerms.weighted("en", "forest")
|
45
|
+
assert_equal 2, results.keys.length
|
46
|
+
expected = { "forest" => 5, "woods" => 2 }
|
47
|
+
results.each do |label, data|
|
48
|
+
assert_equal Iqvoc::Label.base_class, label.class
|
49
|
+
assert_equal 2, data.length
|
50
|
+
assert_equal expected[label.value], data[0]
|
51
|
+
assert_equal Iqvoc::Concept.base_class, data[1].class
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
metadata
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: iqvoc_similar_terms
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Frederik Dohr
|
8
|
+
- Robert Glaser
|
9
|
+
- Till Schulte-Coerne
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2013-04-15 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rails
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.2.1
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - ~>
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: 3.2.1
|
29
|
+
- !ruby/object:Gem::Dependency
|
30
|
+
name: iqvoc
|
31
|
+
requirement: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - ~>
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: 4.0.0
|
36
|
+
type: :runtime
|
37
|
+
prerelease: false
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ~>
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 4.0.0
|
43
|
+
description: ''
|
44
|
+
email:
|
45
|
+
- robert.glaser@innoq.com
|
46
|
+
executables: []
|
47
|
+
extensions: []
|
48
|
+
extra_rdoc_files: []
|
49
|
+
files:
|
50
|
+
- .gitignore
|
51
|
+
- Gemfile
|
52
|
+
- Gemfile.lock
|
53
|
+
- README.md
|
54
|
+
- Rakefile
|
55
|
+
- app/controllers/similar_terms_controller.rb
|
56
|
+
- app/views/similar_terms/show.iqrdf
|
57
|
+
- config.ru
|
58
|
+
- config/application.rb
|
59
|
+
- config/boot.rb
|
60
|
+
- config/database.sqlite.yml
|
61
|
+
- config/engine.rb
|
62
|
+
- config/environment.rb
|
63
|
+
- config/environments/development.rb
|
64
|
+
- config/environments/production.rb
|
65
|
+
- config/environments/test.rb
|
66
|
+
- config/initializers/iqvoc.rb
|
67
|
+
- config/initializers/secret_token.rb.template
|
68
|
+
- config/initializers/session_store.rb
|
69
|
+
- config/initializers/wrap_parameters.rb
|
70
|
+
- config/routes.rb
|
71
|
+
- iqvoc_similar_terms.gemspec
|
72
|
+
- lib/iqvoc/similar_terms.rb
|
73
|
+
- lib/iqvoc/similar_terms/version.rb
|
74
|
+
- lib/iqvoc_similar_terms.rb
|
75
|
+
- public/.gitkeep
|
76
|
+
- script/rails
|
77
|
+
- test/functional/api_test.rb
|
78
|
+
- test/test_helper.rb
|
79
|
+
- test/unit/entity_resolution_test.rb
|
80
|
+
- test/unit/results_test.rb
|
81
|
+
homepage: ''
|
82
|
+
licenses: []
|
83
|
+
metadata: {}
|
84
|
+
post_install_message:
|
85
|
+
rdoc_options: []
|
86
|
+
require_paths:
|
87
|
+
- lib
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - '>='
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - '>='
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
requirements: []
|
99
|
+
rubyforge_project: iqvoc_similar_terms
|
100
|
+
rubygems_version: 2.0.0
|
101
|
+
signing_key:
|
102
|
+
specification_version: 4
|
103
|
+
summary: ''
|
104
|
+
test_files:
|
105
|
+
- test/functional/api_test.rb
|
106
|
+
- test/test_helper.rb
|
107
|
+
- test/unit/entity_resolution_test.rb
|
108
|
+
- test/unit/results_test.rb
|