iqvoc 4.7.0 → 4.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/Gemfile +11 -11
- data/Gemfile.lock +178 -122
- data/README.md +39 -24
- data/{test/performance/browsing_test.rb → app/aides/inline_data_helper.rb} +23 -6
- data/app/aides/maker.rb +139 -0
- data/{lib → app/aides}/multi_logger.rb +0 -0
- data/app/aides/origin.rb +47 -0
- data/app/aides/rdfapi.rb +59 -0
- data/app/aides/skos_exporter.rb +151 -0
- data/app/aides/skos_importer.rb +348 -0
- data/app/assets/javascripts/iqvoc/entityselect.js.erb +7 -9
- data/app/controllers/application_controller.rb +1 -3
- data/app/controllers/collections/versions_controller.rb +1 -3
- data/app/controllers/concepts/versions_controller.rb +9 -3
- data/app/controllers/concerns/controller_extensions.rb +109 -0
- data/app/{concerns → controllers/concerns}/reverse_match_errors.rb +0 -0
- data/app/controllers/hierarchy_controller.rb +7 -3
- data/app/controllers/instance_configuration_controller.rb +1 -1
- data/app/controllers/pages_controller.rb +10 -0
- data/app/controllers/search_results_controller.rb +2 -2
- data/app/controllers/triplestore_sync_controller.rb +2 -4
- data/app/helpers/application_helper.rb +1 -1
- data/app/helpers/widget_helper.rb +3 -3
- data/app/jobs/export_job.rb +1 -3
- data/app/jobs/import_job.rb +1 -3
- data/app/models/ability.rb +59 -0
- data/app/models/abstract_user.rb +1 -1
- data/app/models/collection/base.rb +12 -3
- data/app/models/collection/member/skos/base.rb +1 -1
- data/app/models/concept/base.rb +15 -8
- data/app/models/concept/relation/base.rb +1 -1
- data/app/models/concept/relation/skos/base.rb +1 -1
- data/app/models/concept/skos/scheme.rb +1 -1
- data/app/models/concept/validations.rb +1 -1
- data/app/models/concerns/deep_cloning.rb +92 -0
- data/app/models/concerns/first_level_object_scopes.rb +9 -0
- data/app/{concerns → models/concerns}/first_level_object_validations.rb +9 -2
- data/app/models/concerns/rankable.rb +31 -0
- data/app/models/{search_extension.rb → concerns/search_extension.rb} +0 -0
- data/app/{concerns → models/concerns}/versioning.rb +0 -6
- data/app/models/configuration_setting.rb +1 -1
- data/app/models/labeling/skos/base.rb +2 -2
- data/app/models/match/skos/base.rb +2 -2
- data/app/models/note/skos/base.rb +7 -6
- data/app/models/note/skos/change_note.rb +1 -1
- data/{lib/iqvoc/rdf_sync.rb → app/services/rdf_sync_service.rb} +3 -3
- data/app/view_models/concept_view.rb +1 -1
- data/app/views/collections/_form.html.erb +2 -2
- data/app/views/concepts/scheme/edit.html.erb +1 -1
- data/app/views/pages/components.html.erb +45 -0
- data/app/views/pages/version.html.erb +6 -0
- data/app/views/partials/concept/_reverse_match_notice.html.erb +0 -1
- data/app/views/search_results/_sidebar.html.erb +3 -3
- data/config/application.rb +4 -1
- data/config/boot.rb +1 -2
- data/config/database.yml.postgresql +23 -0
- data/config/engine.rb +0 -2
- data/config/environments/heroku.rb +1 -1
- data/config/initializers/inflections.rb +9 -3
- data/config/initializers/iqvoc.rb +1 -7
- data/config/initializers/mime_types.rb +0 -1
- data/config/locales/de.yml +2 -1
- data/config/locales/en.yml +11 -10
- data/config/routes.rb +2 -0
- data/config/travis/database.yml.mysql +9 -0
- data/config/travis/database.yml.postgresql +7 -0
- data/config/travis/database.yml.sqlite +5 -0
- data/db/migrate/20141204151558_add_foreign_key_constraints.rb +23 -0
- data/iqvoc.gemspec +2 -2
- data/lib/generators/app/template.rb +15 -7
- data/lib/iqvoc.rb +2 -1
- data/lib/iqvoc/configuration/core.rb +18 -4
- data/lib/iqvoc/configuration/instance_configuration.rb +125 -0
- data/lib/iqvoc/configuration/navigation.rb +63 -0
- data/lib/iqvoc/environments/development.rb +4 -0
- data/lib/iqvoc/environments/production.rb +11 -12
- data/lib/iqvoc/environments/test.rb +4 -1
- data/lib/iqvoc/version.rb +2 -2
- data/lib/tasks/exporter.rake +1 -4
- data/lib/tasks/importer.rake +1 -5
- data/lib/tasks/sync.rake +1 -2
- data/test/controllers/concept_movement_test.rb +11 -11
- data/test/controllers/hierarchy_test.rb +83 -79
- data/test/controllers/reverse_match_test.rb +2 -2
- data/test/integration/alphabetical_test.rb +2 -3
- data/test/integration/browse_concepts_and_labels_test.rb +2 -2
- data/test/integration/collection_circularity_test.rb +6 -6
- data/test/integration/concept_scheme_browsing_test.rb +2 -2
- data/test/integration/edit_concepts_test.rb +1 -1
- data/test/integration/export_test.rb +5 -3
- data/test/integration/import_test.rb +4 -1
- data/test/integration/instance_configuration_browsing_test.rb +2 -2
- data/test/integration/navigation_test.rb +2 -2
- data/test/integration/note_annotations_test.rb +12 -11
- data/test/integration/reverse_match_job_test.rb +19 -10
- data/test/integration/search_test.rb +6 -6
- data/test/integration/tree_test.rb +3 -3
- data/test/integration/untranslated_test.rb +1 -1
- data/test/models/concept_test.rb +13 -14
- data/test/models/inline_data_test.rb +9 -9
- data/test/models/instance_configuration_test.rb +7 -3
- data/test/models/origin_test.rb +9 -59
- data/test/models/rdf_sync_test.rb +2 -4
- data/test/models/rdfapi_test.rb +0 -2
- data/test/models/skos_collection_import_test.rb +3 -4
- data/test/models/skos_export_test.rb +3 -5
- data/test/models/skos_import_test.rb +12 -10
- data/test/test_helper.rb +0 -1
- data/vendor/assets/stylesheets/{jquery-ui.css.scss → jquery-ui.scss} +0 -0
- data/vendor/assets/stylesheets/{jquery-ui.structure.css.scss → jquery-ui.structure.scss} +0 -0
- data/vendor/assets/stylesheets/{jquery-ui.theme.css.scss → jquery-ui.theme.scss} +0 -0
- metadata +34 -28
- data/lib/iqvoc/ability.rb +0 -60
- data/lib/iqvoc/controller_extensions.rb +0 -111
- data/lib/iqvoc/deep_cloning.rb +0 -90
- data/lib/iqvoc/inline_data_helper.rb +0 -45
- data/lib/iqvoc/instance_configuration.rb +0 -123
- data/lib/iqvoc/maker.rb +0 -141
- data/lib/iqvoc/navigation.rb +0 -61
- data/lib/iqvoc/origin.rb +0 -111
- data/lib/iqvoc/rankable.rb +0 -33
- data/lib/iqvoc/rdfapi.rb +0 -60
- data/lib/iqvoc/skos_exporter.rb +0 -153
- data/lib/iqvoc/skos_importer.rb +0 -337
data/lib/iqvoc/ability.rb
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
module Iqvoc
|
2
|
-
class Ability
|
3
|
-
include CanCan::Ability
|
4
|
-
|
5
|
-
@@if_published = lambda { |o| o.published? }
|
6
|
-
|
7
|
-
def initialize(user = nil)
|
8
|
-
can :read, Iqvoc::Concept.root_class.instance
|
9
|
-
can :read, [::Concept::Base, ::Collection::Base, ::Label::Base], &@@if_published
|
10
|
-
|
11
|
-
# static pages
|
12
|
-
can :read, :help
|
13
|
-
|
14
|
-
if user # Every logged in user ...
|
15
|
-
can :use, :dashboard
|
16
|
-
can :destroy, UserSession
|
17
|
-
|
18
|
-
if user.owns_role?(:editor) || user.owns_role?(:publisher) || user.owns_role?(:administrator) # Editors and above ...
|
19
|
-
can :read, [::Concept::Base, ::Collection::Base, ::Label::Base]
|
20
|
-
can :create, [::Concept::Base, ::Collection::Base, ::Label::Base]
|
21
|
-
can [:update, :destroy, :unlock], [::Concept::Base, ::Collection::Base, ::Label::Base], locked_by: user.id, published_at: nil
|
22
|
-
can :lock, [::Concept::Base, ::Collection::Base, ::Label::Base], locked_by: nil, published_at: nil
|
23
|
-
can [:check_consistency, :send_to_review], [::Concept::Base, ::Collection::Base, ::Label::Base], published_at: nil
|
24
|
-
can :branch, [::Concept::Base, ::Collection::Base, ::Label::Base], &@@if_published
|
25
|
-
end
|
26
|
-
|
27
|
-
if user.owns_role?(:match_editor)
|
28
|
-
can :read, ::Concept::Base
|
29
|
-
can :create, ::Concept::Base
|
30
|
-
can [:update, :lock], ::Concept::Base, locked_by: user.id, published_at: nil
|
31
|
-
can :lock, ::Concept::Base, locked_by: nil, published_at: nil
|
32
|
-
can :branch, ::Concept::Base, &@@if_published
|
33
|
-
end
|
34
|
-
|
35
|
-
if user.owns_role?(:publisher) || user.owns_role?(:administrator) # Publishers and above ...
|
36
|
-
can :merge, [::Concept::Base, ::Collection::Base, ::Label::Base], published_at: nil
|
37
|
-
end
|
38
|
-
|
39
|
-
if user.owns_role?(:administrator)
|
40
|
-
can [:update, :destroy, :unlock], [::Concept::Base, ::Label::Base], published_at: nil # Mustn't be locked by myself
|
41
|
-
|
42
|
-
can :manage, User
|
43
|
-
can :manage, Iqvoc.config
|
44
|
-
|
45
|
-
can :full_export, ::Concept::Base
|
46
|
-
can :import, ::Concept::Base
|
47
|
-
can :export, ::Concept::Base
|
48
|
-
|
49
|
-
can :update, Iqvoc::Concept.root_class.instance
|
50
|
-
|
51
|
-
can :use, :administration
|
52
|
-
|
53
|
-
can :reset, :thesaurus
|
54
|
-
end
|
55
|
-
else # no user
|
56
|
-
can :create, UserSession
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
@@ -1,111 +0,0 @@
|
|
1
|
-
require 'active_support/concern'
|
2
|
-
|
3
|
-
module Iqvoc
|
4
|
-
module ControllerExtensions
|
5
|
-
extend ActiveSupport::Concern
|
6
|
-
|
7
|
-
included do
|
8
|
-
prepend_before_action :set_locale
|
9
|
-
before_action :ensure_extension
|
10
|
-
|
11
|
-
helper :all
|
12
|
-
helper_method :current_user_session, :current_user, :concept_widget_data, :collection_widget_data, :label_widget_data
|
13
|
-
|
14
|
-
rescue_from ActiveRecord::RecordNotFound, with: :handle_not_found
|
15
|
-
rescue_from CanCan::AccessDenied, with: :handle_access_denied
|
16
|
-
rescue_from ActionController::ParameterMissing, with: :handle_bad_request
|
17
|
-
end
|
18
|
-
|
19
|
-
protected
|
20
|
-
|
21
|
-
def default_url_options(options = nil)
|
22
|
-
{ format: params[:format], lang: I18n.locale }.
|
23
|
-
merge(options || {})
|
24
|
-
end
|
25
|
-
|
26
|
-
# Force an extension to every url. (LOD)
|
27
|
-
def ensure_extension
|
28
|
-
unless params[:format] || !request.get?
|
29
|
-
flash.keep
|
30
|
-
redirect_to url_for(params.merge(format: (request.format && request.format.symbol) || :html))
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def handle_access_denied(exception)
|
35
|
-
@exception = exception
|
36
|
-
@status = current_user ? 403 : 401
|
37
|
-
@user_session = UserSession.new if @status == 401
|
38
|
-
@return_url = request.fullpath
|
39
|
-
respond_to do |format|
|
40
|
-
format.html { render template: 'errors/access_denied', status: @status }
|
41
|
-
format.any { head @status }
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def handle_not_found(exception)
|
46
|
-
@exception = exception
|
47
|
-
SearchResultsController.prepare_basic_variables(self)
|
48
|
-
|
49
|
-
respond_to do |format|
|
50
|
-
format.html { render template: 'errors/not_found', status: 404 }
|
51
|
-
format.any { head 404 }
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def handle_bad_request(exception)
|
56
|
-
@exception = exception
|
57
|
-
|
58
|
-
respond_to do |format|
|
59
|
-
format.any { head 400 }
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def set_locale
|
64
|
-
if params[:lang].present? && Iqvoc::Concept.pref_labeling_languages.include?(params[:lang])
|
65
|
-
I18n.locale = params[:lang]
|
66
|
-
else
|
67
|
-
I18n.locale = Iqvoc::Concept.pref_labeling_languages.first
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def concept_widget_data(concept, rank = nil)
|
72
|
-
data = {
|
73
|
-
id: concept.origin,
|
74
|
-
name: (concept.pref_label && concept.pref_label.value.presence || ":#{concept.origin}") + (concept.additional_info ? " (#{concept.additional_info })" : '')
|
75
|
-
}
|
76
|
-
data[:rank] = rank if rank
|
77
|
-
data
|
78
|
-
end
|
79
|
-
|
80
|
-
def collection_widget_data(collection)
|
81
|
-
{
|
82
|
-
id: collection.origin,
|
83
|
-
name: collection.pref_label.to_s
|
84
|
-
}
|
85
|
-
end
|
86
|
-
|
87
|
-
def label_widget_data(label)
|
88
|
-
{
|
89
|
-
id: label.origin,
|
90
|
-
name: label.value
|
91
|
-
}
|
92
|
-
end
|
93
|
-
|
94
|
-
# Configurable Ability class
|
95
|
-
def current_ability
|
96
|
-
@current_ability ||= Iqvoc.ability_class.new(current_user)
|
97
|
-
end
|
98
|
-
|
99
|
-
def current_user_session
|
100
|
-
@current_user_session ||= UserSession.find
|
101
|
-
end
|
102
|
-
|
103
|
-
def current_user
|
104
|
-
@current_user ||= current_user_session && current_user_session.user
|
105
|
-
end
|
106
|
-
|
107
|
-
def with_layout?
|
108
|
-
!params[:layout]
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
data/lib/iqvoc/deep_cloning.rb
DELETED
@@ -1,90 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
# Copyright 2011-2013 innoQ Deutschland GmbH
|
4
|
-
#
|
5
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
-
# you may not use this file except in compliance with the License.
|
7
|
-
# You may obtain a copy of the License at
|
8
|
-
#
|
9
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
-
#
|
11
|
-
# Unless required by applicable law or agreed to in writing, software
|
12
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
-
# See the License for the specific language governing permissions and
|
15
|
-
# limitations under the License.
|
16
|
-
|
17
|
-
module Iqvoc
|
18
|
-
module DeepCloning
|
19
|
-
def self.included(base) #:nodoc:
|
20
|
-
base.alias_method_chain :dup, :deep_cloning
|
21
|
-
end
|
22
|
-
|
23
|
-
# clones an ActiveRecord model.
|
24
|
-
# if passed the :include option, it will deep clone the given associations
|
25
|
-
# if passed the :except option, it won't clone the given attributes
|
26
|
-
#
|
27
|
-
# === Usage:
|
28
|
-
#
|
29
|
-
# ==== Cloning a model without an attribute
|
30
|
-
# pirate.clone except: :name
|
31
|
-
#
|
32
|
-
# ==== Cloning a model without multiple attributes
|
33
|
-
# pirate.clone except: [:name, :nick_name]
|
34
|
-
# ==== Cloning one single association
|
35
|
-
# pirate.clone include: :mateys
|
36
|
-
#
|
37
|
-
# ==== Cloning multiple associations
|
38
|
-
# pirate.clone include: [:mateys, :treasures]
|
39
|
-
#
|
40
|
-
# ==== Cloning really deep
|
41
|
-
# pirate.clone include: {treasures: :gold_pieces}
|
42
|
-
#
|
43
|
-
# ==== Cloning really deep with multiple associations
|
44
|
-
# pirate.clone include: [:mateys, {treasures: :gold_pieces}]
|
45
|
-
#
|
46
|
-
# ==== Cloning multiple associations - but only the join table entries without cloning the associated objects themselves
|
47
|
-
# pirate.clone include_association: [:matey_ids, :treasure_ids]
|
48
|
-
#
|
49
|
-
def dup_with_deep_cloning(options = {})
|
50
|
-
kopy = dup_without_deep_cloning
|
51
|
-
|
52
|
-
if options[:except]
|
53
|
-
Array(options[:except]).each do |attribute|
|
54
|
-
kopy.write_attribute(attribute, attributes_from_column_definition[attribute.to_s])
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
if options[:include_association]
|
59
|
-
Array(options[:include_association]).each do |association_attribute|
|
60
|
-
kopy.send("#{association_attribute}=", self.send("#{association_attribute}"))
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
if options[:include]
|
65
|
-
Array(options[:include]).each do |association, deep_associations|
|
66
|
-
if (association.kind_of? Hash)
|
67
|
-
deep_associations = association[association.keys.first]
|
68
|
-
association = association.keys.first
|
69
|
-
end
|
70
|
-
opts = deep_associations.blank? ? {} : { include: deep_associations }
|
71
|
-
association_reflection = self.class.reflect_on_association(association)
|
72
|
-
cloned_object = case association_reflection.macro
|
73
|
-
when :belongs_to, :has_one
|
74
|
-
self.send(association) && self.send(association).dup(opts)
|
75
|
-
when :has_many, :has_and_belongs_to_many
|
76
|
-
fk = association_reflection.options[:foreign_key]# || self.class.to_s.underscore
|
77
|
-
self.send(association).collect do |obj|
|
78
|
-
cloned_obj = obj.dup(opts)
|
79
|
-
cloned_obj.send("#{fk}=", kopy.id) unless fk.blank?
|
80
|
-
cloned_obj
|
81
|
-
end
|
82
|
-
end
|
83
|
-
kopy.send("#{association}=", cloned_object)
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
return kopy
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
# Copyright 2011-2013 innoQ Deutschland GmbH
|
4
|
-
#
|
5
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
-
# you may not use this file except in compliance with the License.
|
7
|
-
# You may obtain a copy of the License at
|
8
|
-
#
|
9
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
-
#
|
11
|
-
# Unless required by applicable law or agreed to in writing, software
|
12
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
-
# See the License for the specific language governing permissions and
|
15
|
-
# limitations under the License.
|
16
|
-
|
17
|
-
require 'csv'
|
18
|
-
|
19
|
-
module Iqvoc
|
20
|
-
module InlineDataHelper
|
21
|
-
# delimiters for strings representing a list of values - XXX: lacks encapsulation
|
22
|
-
JOINER = ', '
|
23
|
-
SPLITTER = /[,\n] */
|
24
|
-
|
25
|
-
CSV_OPTIONS = {
|
26
|
-
col_sep: ', ',
|
27
|
-
quote_char: '"'
|
28
|
-
}
|
29
|
-
|
30
|
-
def self.parse_inline_values(inline_values)
|
31
|
-
options = CSV_OPTIONS.clone
|
32
|
-
options[:col_sep] = options[:col_sep].strip
|
33
|
-
begin
|
34
|
-
values = inline_values.parse_csv(options)
|
35
|
-
rescue CSV::MalformedCSVError => exc
|
36
|
-
values = inline_values.parse_csv(CSV_OPTIONS)
|
37
|
-
end
|
38
|
-
values ? values.map(&:strip) : []
|
39
|
-
end
|
40
|
-
|
41
|
-
def self.generate_inline_values(values)
|
42
|
-
values.to_csv(CSV_OPTIONS).strip
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
@@ -1,123 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
# Copyright 2011-2013 innoQ Deutschland GmbH
|
4
|
-
#
|
5
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
-
# you may not use this file except in compliance with the License.
|
7
|
-
# You may obtain a copy of the License at
|
8
|
-
#
|
9
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
-
#
|
11
|
-
# Unless required by applicable law or agreed to in writing, software
|
12
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
-
# See the License for the specific language governing permissions and
|
15
|
-
# limitations under the License.
|
16
|
-
|
17
|
-
require 'singleton'
|
18
|
-
|
19
|
-
module Iqvoc
|
20
|
-
# provides the interface to configuration settings
|
21
|
-
class InstanceConfiguration
|
22
|
-
include Singleton
|
23
|
-
|
24
|
-
attr_reader :defaults # XXX: dangerous (mutable object)
|
25
|
-
|
26
|
-
class UnregisteredSetting < ArgumentError
|
27
|
-
def to_s
|
28
|
-
'A setting needs to be registered with register_setting before it can be used.'
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def initialize
|
33
|
-
@defaults = {} # default settings
|
34
|
-
@records = {} # customized (non-default) settings
|
35
|
-
@settings = {} # current settings, using defaults as fallback
|
36
|
-
# NB: cannot cache immediately because defaults need to be registered first
|
37
|
-
end
|
38
|
-
|
39
|
-
# convenience wrapper for `register_setting` batch operations
|
40
|
-
# accepts a hash of key / default value pairs
|
41
|
-
def register_settings(settings)
|
42
|
-
settings.each do |key, default_value|
|
43
|
-
register_setting(key, default_value)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
# create or update a default setting
|
48
|
-
def register_setting(key, default_value)
|
49
|
-
self.class.validate_value(default_value)
|
50
|
-
|
51
|
-
@defaults[key] = default_value
|
52
|
-
|
53
|
-
# update cache
|
54
|
-
@settings[key] = @records[key] || default_value
|
55
|
-
end
|
56
|
-
|
57
|
-
# remove a default setting
|
58
|
-
# returns nil if setting does not exist
|
59
|
-
# NB: does *not* delete configuration settings from the database
|
60
|
-
def deregister_setting(key)
|
61
|
-
res = @defaults.delete(key)
|
62
|
-
|
63
|
-
# update cache
|
64
|
-
@settings.delete(key)
|
65
|
-
|
66
|
-
return res
|
67
|
-
end
|
68
|
-
|
69
|
-
# retrieve individual setting, using default value as fallback
|
70
|
-
def [](key)
|
71
|
-
initialize_cache unless @initialized
|
72
|
-
return @settings[key]
|
73
|
-
end
|
74
|
-
|
75
|
-
# store individual customized setting
|
76
|
-
def []=(key, value)
|
77
|
-
raise UnregisteredSetting unless @defaults.include?(key)
|
78
|
-
self.class.validate_value(value)
|
79
|
-
|
80
|
-
json = JSON.dump([value])[1..-2] # temporary array wrapper ensures valid JSON text
|
81
|
-
if setting = ConfigurationSetting.find_by_key(key)
|
82
|
-
setting.update_attributes(value: json)
|
83
|
-
else
|
84
|
-
ConfigurationSetting.create(key: key, value: json)
|
85
|
-
end
|
86
|
-
|
87
|
-
# update cache
|
88
|
-
@records[key] = value
|
89
|
-
@settings[key] = value
|
90
|
-
|
91
|
-
return value
|
92
|
-
end
|
93
|
-
|
94
|
-
# populate settings caches
|
95
|
-
# (subsequent updates will happen automatically via the respective setters)
|
96
|
-
def initialize_cache
|
97
|
-
return false unless ConfigurationSetting.table_exists? # pre-migration
|
98
|
-
|
99
|
-
# cache customized settings
|
100
|
-
ConfigurationSetting.all.each do |setting|
|
101
|
-
@records[setting.key] = JSON.load("[#{setting.value}]")[0] # temporary array wrapper ensures valid JSON text
|
102
|
-
end
|
103
|
-
|
104
|
-
# cache current settings
|
105
|
-
@defaults.each do |key, default_value|
|
106
|
-
value = @records[key]
|
107
|
-
@settings[key] = value.nil? ? default_value : value
|
108
|
-
end
|
109
|
-
|
110
|
-
@initialized = true
|
111
|
-
end
|
112
|
-
|
113
|
-
# checks whether value type is supported
|
114
|
-
def self.validate_value(value) # TODO: compare type to default's? (cf. controller)
|
115
|
-
if value == nil
|
116
|
-
raise TypeError, 'nil values not supported'
|
117
|
-
end
|
118
|
-
unless [TrueClass, FalseClass, String, Fixnum, Float, Array].include?(value.class)
|
119
|
-
raise TypeError, 'complex values not supported'
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
data/lib/iqvoc/maker.rb
DELETED
@@ -1,141 +0,0 @@
|
|
1
|
-
module Iqvoc
|
2
|
-
module Maker
|
3
|
-
# labels:
|
4
|
-
# -
|
5
|
-
# value: <string>
|
6
|
-
# <attribute>: <value>
|
7
|
-
# inflectionals: [<string>, ...]
|
8
|
-
# components: [<label>, ...]
|
9
|
-
#
|
10
|
-
# concepts:
|
11
|
-
# -
|
12
|
-
# <attribute>: <value>
|
13
|
-
# pref_labels: [<label>, ...]
|
14
|
-
# alt_labels: [<label>, ...]
|
15
|
-
# broader: <concept>
|
16
|
-
# narrower: <concept>
|
17
|
-
# related: [<concept>, ...]
|
18
|
-
#
|
19
|
-
# NB:
|
20
|
-
# * <label> and <concept> can either be strings referencing a previously
|
21
|
-
# declared entity or objects representing a new entity
|
22
|
-
# XXX: The latter is not currently supported yet!
|
23
|
-
# * order of concepts matters when referencing relations
|
24
|
-
# * order of labels matters when referencing components
|
25
|
-
def self.from_yaml(yml)
|
26
|
-
data = YAML.load(yml)
|
27
|
-
|
28
|
-
labels = {}
|
29
|
-
data['labels'].each { |label| # XXX: use omap to simplify format (making `value` the key instead of an attribute)?
|
30
|
-
term = label.delete('value')
|
31
|
-
|
32
|
-
components = label.delete('components').map { |term|
|
33
|
-
labels[term]
|
34
|
-
} if label['components']
|
35
|
-
|
36
|
-
options = {
|
37
|
-
inflectionals: label.delete('inflectionals'),
|
38
|
-
components: components,
|
39
|
-
label_attributes: label
|
40
|
-
}
|
41
|
-
|
42
|
-
labels[term] = self.label(term, options)
|
43
|
-
} if data['labels']
|
44
|
-
|
45
|
-
concepts = {}
|
46
|
-
data['concepts'].each { |concept| # XXX: use omap to simplify format (using a single pref_label as key)?
|
47
|
-
relations = {}
|
48
|
-
['broader', 'narrower'].each { |type| # TODO: missing related, support for poly-hierarchies
|
49
|
-
relations[type] = concepts[concept.delete(type)] if concept[type]
|
50
|
-
}
|
51
|
-
|
52
|
-
lbls = {} # TODO: rename
|
53
|
-
['pref', 'alt'].each { |type| # TODO: missing hidden
|
54
|
-
key = "#{type}_labels"
|
55
|
-
lbls[type] = concept.delete(key).map { |term|
|
56
|
-
labels[term]
|
57
|
-
} if concept[key]
|
58
|
-
}
|
59
|
-
|
60
|
-
options = {
|
61
|
-
pref_labels: lbls['pref'],
|
62
|
-
alt_labels: lbls['alt'],
|
63
|
-
concept_attributes: concept
|
64
|
-
}
|
65
|
-
|
66
|
-
identifier = options[:pref_labels].first.value
|
67
|
-
concepts[identifier] = self.concept(options)
|
68
|
-
concepts[identifier].send(Iqvoc::Concept.broader_relation_class.name.to_relation_name).
|
69
|
-
create_with_reverse_relation(relations['broader']) if relations['broader']
|
70
|
-
concepts[identifier].send(Iqvoc::Concept.broader_relation_class.narrower_class.name.to_relation_name).
|
71
|
-
create_with_reverse_relation(relations['narrower']) if relations['narrower']
|
72
|
-
} if data['concepts']
|
73
|
-
|
74
|
-
return { concepts: concepts, labels: labels }
|
75
|
-
end
|
76
|
-
|
77
|
-
# optional arguments:
|
78
|
-
# concept_attributes for custom concept attributes
|
79
|
-
# pref_labels is an array of strings or label instances to be used as prefLabels
|
80
|
-
# alt_labels is an array of strings or label instances to be used as altLabels
|
81
|
-
def self.concept(options={})
|
82
|
-
attributes = options[:concept_attributes] || {}
|
83
|
-
pref_labels = options[:pref_labels] || []
|
84
|
-
alt_labels = options[:alt_labels] || []
|
85
|
-
|
86
|
-
defaults = { # NB: must use strings, not symbols as keys due to YAML
|
87
|
-
'published_at' => 3.days.ago
|
88
|
-
}
|
89
|
-
attributes = defaults.merge(attributes)
|
90
|
-
|
91
|
-
concept = Iqvoc::Concept.base_class.create!(attributes)
|
92
|
-
|
93
|
-
pref_labels.each { |term|
|
94
|
-
label = term.is_a?(String) ? self.label(term) : term
|
95
|
-
Iqvoc::Concept.pref_labeling_class.
|
96
|
-
create!(owner: concept, target: label)
|
97
|
-
}
|
98
|
-
alt_labels.each { |term|
|
99
|
-
label = term.is_a?(String) ? self.label(term) : term
|
100
|
-
Iqvoc::Concept.further_labeling_classes.first.first.
|
101
|
-
create!(owner: concept, target: label)
|
102
|
-
}
|
103
|
-
|
104
|
-
return concept
|
105
|
-
end
|
106
|
-
|
107
|
-
# optional arguments:
|
108
|
-
# label_attributes for custom label attributes
|
109
|
-
# inflectionals is an array of strings to be used as inflectionals
|
110
|
-
# components is an array of labels to be used as compound form contents
|
111
|
-
def self.label(value, options={}) # FIXME: move into SKOS-XL extension
|
112
|
-
attributes = options[:label_attributes] || {}
|
113
|
-
inflectionals = options[:inflectionals] || []
|
114
|
-
components = options[:components] || []
|
115
|
-
|
116
|
-
defaults = { # NB: must use strings, not symbols as keys due to YAML
|
117
|
-
value: value, # intentionally not a string; symbol takes precedence
|
118
|
-
'origin' => Iqvoc::Origin.new(value).to_s,
|
119
|
-
'language' => Iqvoc::Concept.pref_labeling_languages.first,
|
120
|
-
'published_at' => 2.days.ago
|
121
|
-
}
|
122
|
-
attributes = defaults.merge(attributes)
|
123
|
-
|
124
|
-
klass = Iqvoc::XLLabel rescue Iqvoc::Label # FIXME: breaks encapsulation (hard-coded iqvoc_skosxl dependency)
|
125
|
-
label = klass.base_class.create!(attributes)
|
126
|
-
|
127
|
-
inflectionals.each { |inf|
|
128
|
-
label.inflectionals.create!(value: inf)
|
129
|
-
}
|
130
|
-
|
131
|
-
if components.length > 0
|
132
|
-
compound_form_contents = components.each_with_index.map { |label, i|
|
133
|
-
CompoundForm::Content::Base.new(label: label, order: i)
|
134
|
-
}
|
135
|
-
label.compound_forms.create!(compound_form_contents: compound_form_contents)
|
136
|
-
end
|
137
|
-
|
138
|
-
return label
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|