labimotion 1.4.1 → 2.0.0.rc6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/labimotion/apis/generic_element_api.rb +1 -0
- data/lib/labimotion/apis/generic_klass_api.rb +3 -2
- data/lib/labimotion/apis/labimotion_api.rb +13 -0
- data/lib/labimotion/apis/standard_api.rb +25 -0
- data/lib/labimotion/apis/standard_layer_api.rb +87 -0
- data/lib/labimotion/apis/vocabulary_api.rb +93 -0
- data/lib/labimotion/constants.rb +21 -0
- data/lib/labimotion/entities/dataset_entity.rb +1 -1
- data/lib/labimotion/entities/element_entity.rb +1 -0
- data/lib/labimotion/entities/properties_entity.rb +229 -56
- data/lib/labimotion/entities/segment_entity.rb +0 -1
- data/lib/labimotion/entities/vocabulary_entity.rb +28 -0
- data/lib/labimotion/helpers/element_helpers.rb +8 -6
- data/lib/labimotion/helpers/generic_helpers.rb +6 -1
- data/lib/labimotion/helpers/param_helpers.rb +121 -82
- data/lib/labimotion/helpers/segment_helpers.rb +1 -1
- data/lib/labimotion/helpers/vocabulary_helpers.rb +16 -0
- data/lib/labimotion/libs/converter.rb +12 -33
- data/lib/labimotion/libs/data/mapper/Chemwiki.json +236 -0
- data/lib/labimotion/libs/data/mapper/Source.json +78 -0
- data/lib/labimotion/libs/data/vocab/Standard.json +385 -0
- data/lib/labimotion/libs/data/vocab/System.json +131 -0
- data/lib/labimotion/libs/dataset_builder.rb +70 -0
- data/lib/labimotion/libs/export_dataset.rb +165 -66
- data/lib/labimotion/libs/nmr_mapper.rb +204 -246
- data/lib/labimotion/libs/sample_association.rb +4 -0
- data/lib/labimotion/libs/vocabulary_handler.rb +118 -0
- data/lib/labimotion/models/concerns/attachment_converter.rb +5 -4
- data/lib/labimotion/models/concerns/datasetable.rb +1 -0
- data/lib/labimotion/models/concerns/segmentable.rb +2 -0
- data/lib/labimotion/models/element.rb +3 -0
- data/lib/labimotion/models/std_layer.rb +9 -0
- data/lib/labimotion/models/std_layers_revision.rb +9 -0
- data/lib/labimotion/models/vocabulary.rb +12 -0
- data/lib/labimotion/utils/mapper_utils.rb +169 -0
- data/lib/labimotion/utils/utils.rb +22 -0
- data/lib/labimotion/version.rb +1 -1
- data/lib/labimotion.rb +13 -3
- metadata +25 -5
@@ -1,300 +1,258 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'labimotion/libs/dataset_builder'
|
3
4
|
require 'labimotion/version'
|
5
|
+
require 'labimotion/utils/mapper_utils'
|
4
6
|
require 'labimotion/utils/utils'
|
5
7
|
|
6
8
|
module Labimotion
|
7
9
|
## NmrMapper
|
8
10
|
class NmrMapper
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
generate_ds(id, att.attachable_id, data, current_user)
|
26
|
-
Labimotion::ConState::COMPLETED
|
11
|
+
# Constants specific to NMR mapping
|
12
|
+
module Constants
|
13
|
+
# Duplicate fields that need special handling
|
14
|
+
DUP_FIELDS = %w[time version].freeze
|
15
|
+
|
16
|
+
# Field groups for different processing stages
|
17
|
+
FG_FINALIZE = %w[set.temperature general.date general.time software.Name software.Version].freeze
|
18
|
+
FG_SYSTEM = %w[general.creator sample_details.label sample_details.id].freeze
|
19
|
+
|
20
|
+
# Valid NMR nuclei types
|
21
|
+
OBSERVED = %w[1H 13C].freeze
|
22
|
+
|
23
|
+
# OLS terms for different NMR types
|
24
|
+
module OlsTerms
|
25
|
+
NMR_1H = 'CHMO:0000593'
|
26
|
+
NMR_13C = 'CHMO:0000595'
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
if att&.attachment_attacher&.file&.url
|
35
|
-
Zip::File.open(att.attachment_attacher.file.url) do |zip_file|
|
36
|
-
zip_file.each do |entry|
|
37
|
-
if entry.name.include?('/pdata/') && entry.name.include?('parm.txt')
|
38
|
-
metadata = entry.get_input_stream.read.force_encoding('UTF-8')
|
39
|
-
return { is_bagit: false, metadata: metadata }
|
40
|
-
elsif entry.name.include?('metadata/') && entry.name.include?('converter.json')
|
41
|
-
return { is_bagit: true, metadata: nil }
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
{ is_bagit: false, metadata: nil }
|
47
|
-
end
|
30
|
+
class << self
|
31
|
+
def process_ds(id, current_user = {})
|
32
|
+
att = find_attachment(id)
|
33
|
+
return Labimotion::ConState::NONE if att.nil?
|
48
34
|
|
49
|
-
|
50
|
-
|
35
|
+
result = process(att)
|
36
|
+
return Labimotion::ConState::NONE if result.nil?
|
51
37
|
|
52
|
-
|
53
|
-
metadata = {}
|
54
|
-
lines.map do |ln|
|
55
|
-
arr = ln.split(/\s+/)
|
56
|
-
metadata[arr[0]] = arr[1..-1].join(' ') if arr.length > 1
|
38
|
+
handle_process_result(result, att, id, current_user)
|
57
39
|
end
|
58
|
-
ols = 'CHMO:0000593' if metadata['NUC1'] == '1H'
|
59
|
-
ols = 'CHMO:0000595' if metadata['NUC1'] == '13C'
|
60
|
-
|
61
|
-
{ content: { metadata: metadata, ols: ols } }
|
62
|
-
# if content.present? && att.present?
|
63
|
-
# Labimotion::NmrMapper.ts('write', att.attachable_id,
|
64
|
-
# content: { metadata: metadata, ols: ols })
|
65
|
-
# end
|
66
|
-
end
|
67
40
|
|
68
|
-
|
69
|
-
|
70
|
-
|
41
|
+
def process(att)
|
42
|
+
config = Labimotion::MapperUtils.load_brucker_config
|
43
|
+
return if config.nil?
|
44
|
+
|
45
|
+
attacher = att&.attachment_attacher
|
46
|
+
extracted_data = Labimotion::MapperUtils.extract_data_from_zip(attacher&.file&.url, config['sourceMap'])
|
47
|
+
return if extracted_data.nil?
|
71
48
|
|
72
|
-
|
73
|
-
|
74
|
-
return content if content.present?
|
49
|
+
extracted_data[:parameters] = config['sourceMap']['parameters']
|
50
|
+
extracted_data
|
75
51
|
end
|
76
|
-
end
|
77
52
|
|
53
|
+
def generate_ds(_id, cid, data, current_user = {}, element = nil)
|
54
|
+
return if data.nil? || cid.nil?
|
78
55
|
|
79
|
-
|
80
|
-
|
56
|
+
obj = Labimotion::NmrMapper.build_ds(cid, data[:content])
|
57
|
+
return if obj.nil? || obj[:ols].nil?
|
81
58
|
|
82
|
-
|
83
|
-
|
59
|
+
Labimotion::NmrMapper.update_ds(cid, obj, current_user, element)
|
60
|
+
end
|
84
61
|
|
85
|
-
|
86
|
-
|
87
|
-
|
62
|
+
def update_ds(_cid, obj, current_user, element)
|
63
|
+
dataset = obj[:dataset]
|
64
|
+
dataset.properties = process_prop(obj, current_user, element)
|
65
|
+
dataset.save!
|
66
|
+
end
|
88
67
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
# new_prop = dataset.properties
|
68
|
+
def build_ds(id, content)
|
69
|
+
ds = find_container(id)
|
70
|
+
return if ds.nil? || content.nil?
|
93
71
|
|
94
|
-
|
95
|
-
|
96
|
-
end
|
72
|
+
Labimotion::DatasetBuilder.build(ds, content)
|
73
|
+
end
|
97
74
|
|
98
|
-
|
99
|
-
return if field['field'] != field_name || value&.empty?
|
75
|
+
private
|
100
76
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
77
|
+
def finalize_ds(new_prop)
|
78
|
+
Constants::FG_FINALIZE.each do |field_path|
|
79
|
+
field = Labimotion::Utils.find_field(new_prop, field_path)
|
80
|
+
next unless field
|
105
81
|
|
106
|
-
|
107
|
-
dataset = obj[:dataset]
|
108
|
-
metadata = obj[:metadata]
|
109
|
-
new_prop = dataset.properties
|
110
|
-
new_prop.dig(Labimotion::Prop::LAYERS, 'general', Labimotion::Prop::FIELDS)&.each_with_index do |fi, idx|
|
111
|
-
# new_prop = set_data(new_prop, fi, idx, 'general', 'title', metadata['NAME'])
|
112
|
-
if fi['field'] == 'title' && metadata['NAME'].present?
|
113
|
-
## fi['label'] = fi['label']
|
114
|
-
fi['value'] = metadata['NAME']
|
115
|
-
fi['device'] = metadata['NAME']
|
116
|
-
fi['dkey'] = 'NAME'
|
117
|
-
new_prop[Labimotion::Prop::LAYERS]['general'][Labimotion::Prop::FIELDS][idx] = fi
|
82
|
+
update_finalized_field(field)
|
118
83
|
end
|
84
|
+
new_prop
|
85
|
+
end
|
119
86
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
fi['dkey'] = 'Date_'
|
125
|
-
new_prop[Labimotion::Prop::LAYERS]['general'][Labimotion::Prop::FIELDS][idx] = fi
|
126
|
-
end
|
87
|
+
def sys_to_ds(new_prop, element, current_user)
|
88
|
+
Constants::FG_SYSTEM.each do |field_path|
|
89
|
+
field = Labimotion::Utils.find_field(new_prop, field_path)
|
90
|
+
next unless field
|
127
91
|
|
128
|
-
|
129
|
-
## fi['label'] = fi['label']
|
130
|
-
fi['value'] = metadata['Time']
|
131
|
-
fi['device'] = metadata['Time']
|
132
|
-
fi['dkey'] = 'Time'
|
133
|
-
new_prop[Labimotion::Prop::LAYERS]['general'][Labimotion::Prop::FIELDS][idx] = fi
|
92
|
+
update_system_field(field, current_user, element)
|
134
93
|
end
|
94
|
+
new_prop
|
95
|
+
end
|
96
|
+
|
97
|
+
def params_to_ds(obj, new_prop)
|
98
|
+
metadata = obj[:metadata]
|
99
|
+
parameters = obj[:parameters]
|
100
|
+
|
101
|
+
parameters.each do |param_key, field_path|
|
102
|
+
next if skip_parameter?(metadata, param_key)
|
135
103
|
|
136
|
-
|
137
|
-
## fi['label'] = fi['label']
|
138
|
-
fi['value'] = current_user.name
|
139
|
-
new_prop[Labimotion::Prop::LAYERS]['general'][Labimotion::Prop::FIELDS][idx] = fi
|
104
|
+
update_param_field(new_prop, field_path, param_key, metadata)
|
140
105
|
end
|
106
|
+
new_prop
|
141
107
|
end
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
fi['value'] = element.id
|
151
|
-
new_prop[Labimotion::Prop::LAYERS]['sample_details'][Labimotion::Prop::FIELDS][idx] = fi
|
152
|
-
end
|
108
|
+
|
109
|
+
def process_prop(obj, current_user, element)
|
110
|
+
new_prop = obj[:dataset].properties
|
111
|
+
new_prop
|
112
|
+
.then { |prop| params_to_ds(obj, prop) }
|
113
|
+
.then { |prop| sys_to_ds(prop, element, current_user) }
|
114
|
+
.then { |prop| finalize_ds(prop) }
|
115
|
+
.then { |prop| Labimotion::VocabularyHandler.update_vocabularies(prop, current_user, element) }
|
153
116
|
end
|
154
117
|
|
155
|
-
|
156
|
-
|
157
|
-
## fi['label'] = fi['label']
|
158
|
-
fi['value'] = metadata['INSTRUM']
|
159
|
-
fi['device'] = metadata['INSTRUM']
|
160
|
-
fi['dkey'] = 'INSTRUM'
|
161
|
-
new_prop[Labimotion::Prop::LAYERS]['instrument'][Labimotion::Prop::FIELDS][idx] = fi
|
162
|
-
end
|
118
|
+
def find_attachment(id)
|
119
|
+
Attachment.find_by(id: id, con_state: Labimotion::ConState::NMR)
|
163
120
|
end
|
164
121
|
|
165
|
-
|
166
|
-
if
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
122
|
+
def handle_process_result(result, att, id, current_user)
|
123
|
+
if result[:is_bagit]
|
124
|
+
handle_bagit_result(att, id, current_user)
|
125
|
+
elsif invalid_metadata?(result)
|
126
|
+
Labimotion::ConState::NONE
|
127
|
+
else
|
128
|
+
handle_nmr_result(result, att, current_user)
|
172
129
|
end
|
173
130
|
end
|
174
131
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
fi['device'] = metadata['SOLVENT']
|
180
|
-
fi['dkey'] = 'SOLVENT'
|
181
|
-
fi['value'] = 'chloroform-D1 (CDCl3)' if metadata['SOLVENT'] == 'CDCl3'
|
182
|
-
new_prop[Labimotion::Prop::LAYERS]['sample_preparation'][Labimotion::Prop::FIELDS][idx] = fi
|
183
|
-
end
|
132
|
+
def handle_bagit_result(att, id, current_user)
|
133
|
+
att.update_column(:con_state, Labimotion::ConState::CONVERTED)
|
134
|
+
Labimotion::Converter.metadata(id, current_user)
|
135
|
+
Labimotion::ConState::COMPLETED
|
184
136
|
end
|
185
137
|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
new_prop[Labimotion::Prop::LAYERS]['set'][Labimotion::Prop::FIELDS][idx] = fi
|
138
|
+
def invalid_metadata?(result)
|
139
|
+
result[:metadata].nil? ||
|
140
|
+
Constants::OBSERVED.exclude?(result[:metadata]['NUC1'])
|
141
|
+
end
|
142
|
+
|
143
|
+
def handle_nmr_result(result, att, current_user)
|
144
|
+
ds = find_container(att.attachable_id)
|
145
|
+
return Labimotion::ConState::NONE unless valid_container?(ds)
|
146
|
+
|
147
|
+
prepare_mapper_result(ds, result, current_user)
|
148
|
+
Labimotion::ConState::COMPLETED
|
149
|
+
end
|
150
|
+
|
151
|
+
def find_container(cid)
|
152
|
+
Container.find_by(id: cid)
|
153
|
+
end
|
154
|
+
|
155
|
+
def valid_container?(container)
|
156
|
+
container.present? &&
|
157
|
+
container.parent&.container_type == 'analysis' &&
|
158
|
+
container.root_element.present?
|
159
|
+
end
|
160
|
+
|
161
|
+
def prepare_mapper_result(container, result, current_user)
|
162
|
+
metadata = result[:metadata]
|
163
|
+
ols = determine_ols_term(metadata['NUC1'])
|
164
|
+
|
165
|
+
data = {
|
166
|
+
content: {
|
167
|
+
metadata: metadata,
|
168
|
+
ols: ols,
|
169
|
+
parameters: result[:parameters]
|
170
|
+
}
|
171
|
+
}
|
172
|
+
|
173
|
+
generate_ds(nil, container.id, data, current_user, container.root_element)
|
174
|
+
end
|
175
|
+
|
176
|
+
def determine_ols_term(nuc1)
|
177
|
+
case nuc1
|
178
|
+
when '1H' then Constants::OlsTerms::NMR_1H
|
179
|
+
when '13C' then Constants::OlsTerms::NMR_13C
|
229
180
|
end
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
181
|
+
end
|
182
|
+
|
183
|
+
def skip_parameter?(metadata, param_key)
|
184
|
+
metadata[param_key.to_s].blank? &&
|
185
|
+
Constants::DUP_FIELDS.exclude?(param_key.to_s.downcase)
|
186
|
+
end
|
187
|
+
|
188
|
+
def update_param_field(properties, field_path, param_key, metadata)
|
189
|
+
field = Labimotion::Utils.find_field(properties, field_path)
|
190
|
+
return unless field
|
191
|
+
|
192
|
+
update_field_value(field, param_key, metadata)
|
193
|
+
update_field_extend(field, param_key, metadata)
|
194
|
+
end
|
195
|
+
|
196
|
+
def update_duplicate_field(field_name, metadata)
|
197
|
+
case field_name
|
198
|
+
when 'time' then metadata['DATE']
|
199
|
+
when 'Version' then metadata['TITLE']
|
236
200
|
end
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
201
|
+
end
|
202
|
+
|
203
|
+
def update_field_value(field, param_key, metadata)
|
204
|
+
field['value'] = format_field_value(field, param_key, metadata)
|
205
|
+
rescue StandardError => e
|
206
|
+
Rails.logger.error "Error converting value for #{param_key}: #{e.message}"
|
207
|
+
field['value'] = ''
|
208
|
+
end
|
209
|
+
|
210
|
+
def format_field_value(field, param_key, metadata)
|
211
|
+
if field['type'] == 'integer'
|
212
|
+
Integer(metadata[param_key.to_s])
|
213
|
+
elsif Constants::DUP_FIELDS.include?(param_key.to_s.downcase)
|
214
|
+
update_duplicate_field(field['field'], metadata)
|
215
|
+
else
|
216
|
+
metadata[param_key.to_s]
|
243
217
|
end
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
218
|
+
end
|
219
|
+
|
220
|
+
def update_finalized_field(field)
|
221
|
+
case field['field']
|
222
|
+
when 'temperature'
|
223
|
+
field['value_system'] = 'K'
|
224
|
+
when 'date', 'time'
|
225
|
+
field['value'] = Labimotion::MapperUtils.format_timestamp(field['value'], field['field'])
|
226
|
+
when 'Name'
|
227
|
+
field['value'] = 'TopSpin' if field['value'].to_s.include?('TopSpin')
|
228
|
+
when 'Version'
|
229
|
+
field['value'] = field['value'].to_s.split('TopSpin').last.strip if field['value'].to_s.include?('TopSpin')
|
250
230
|
end
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
231
|
+
end
|
232
|
+
|
233
|
+
def update_system_field(field, current_user, element)
|
234
|
+
field['value'] = determine_field_value(field['field'], current_user, element)
|
235
|
+
end
|
236
|
+
|
237
|
+
def determine_field_value(field_name, current_user, element)
|
238
|
+
case field_name
|
239
|
+
when 'creator'
|
240
|
+
current_user&.name if current_user.present?
|
241
|
+
when 'label', 'id'
|
242
|
+
get_sample_value(field_name, element)
|
257
243
|
end
|
258
244
|
end
|
259
|
-
dataset.properties = new_prop
|
260
|
-
dataset.save!
|
261
|
-
end
|
262
245
|
|
263
|
-
|
264
|
-
|
265
|
-
end
|
246
|
+
def get_sample_value(field_name, element)
|
247
|
+
return unless element.present? && element.is_a?(Sample)
|
266
248
|
|
267
|
-
|
268
|
-
|
269
|
-
end
|
249
|
+
field_name == 'label' ? element.short_label : element.id
|
250
|
+
end
|
270
251
|
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
ols = content[:ols]
|
276
|
-
metadata = content[:metadata]
|
277
|
-
|
278
|
-
return if ols.nil? || metadata.nil?
|
279
|
-
|
280
|
-
klass = Labimotion::DatasetKlass.find_by(ols_term_id: ols)
|
281
|
-
return if klass.nil?
|
282
|
-
|
283
|
-
uuid = SecureRandom.uuid
|
284
|
-
props = klass.properties_release
|
285
|
-
props['uuid'] = uuid
|
286
|
-
props['pkg'] = Labimotion::Utils.pkg(props['pkg'])
|
287
|
-
props['klass'] = 'Dataset'
|
288
|
-
dataset = Labimotion::Dataset.create!(
|
289
|
-
uuid: uuid,
|
290
|
-
dataset_klass_id: klass.id,
|
291
|
-
element_type: 'Container',
|
292
|
-
element_id: ds.id,
|
293
|
-
properties: props,
|
294
|
-
properties_release: klass.properties_release,
|
295
|
-
klass_uuid: klass.uuid,
|
296
|
-
)
|
297
|
-
{ dataset: dataset, metadata: metadata, ols: ols }
|
252
|
+
def update_field_extend(field, param_key, metadata)
|
253
|
+
field['device'] = metadata[param_key.to_s]
|
254
|
+
field['dkey'] = param_key.to_s
|
255
|
+
end
|
298
256
|
end
|
299
257
|
end
|
300
258
|
end
|
@@ -78,6 +78,8 @@ module Labimotion
|
|
78
78
|
field_samples = layer[Labimotion::Prop::FIELDS].select { |ss| ss['type'] == Labimotion::FieldType::DRAG_SAMPLE }
|
79
79
|
field_samples.each do |field|
|
80
80
|
idx = properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS].index(field)
|
81
|
+
return if field.is_a?(String) || properties.is_a?(String)
|
82
|
+
|
81
83
|
sid = field.dig('value', 'el_id')
|
82
84
|
next if sid.blank?
|
83
85
|
|
@@ -100,6 +102,8 @@ module Labimotion
|
|
100
102
|
field_elements = layer[Labimotion::Prop::FIELDS].select { |ss| ss['type'] == Labimotion::FieldType::DRAG_ELEMENT }
|
101
103
|
field_elements.each do |field|
|
102
104
|
idx = properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS].index(field)
|
105
|
+
next if field['value'].is_a?(String)
|
106
|
+
|
103
107
|
sid = field.dig('value', 'el_id')
|
104
108
|
next if element.nil? || sid.blank? || sid == element.id
|
105
109
|
|
@@ -0,0 +1,118 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Labimotion
|
4
|
+
class VocabularyHandler
|
5
|
+
class << self
|
6
|
+
def update_vocabularies(properties, current_user, element)
|
7
|
+
properties[Labimotion::Prop::LAYERS].each do |key, layer|
|
8
|
+
update_layer_vocabularies(layer, key, properties, current_user, element)
|
9
|
+
end
|
10
|
+
properties
|
11
|
+
rescue StandardError => e
|
12
|
+
Labimotion.log_exception(e, current_user)
|
13
|
+
properties
|
14
|
+
end
|
15
|
+
|
16
|
+
def load_all_vocabularies
|
17
|
+
load_from_files + load_from_database
|
18
|
+
end
|
19
|
+
|
20
|
+
def load_app_vocabularies
|
21
|
+
load_from_files
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def update_layer_vocabularies(layer, key, properties, current_user, element)
|
27
|
+
field_vocabularies = layer[Labimotion::Prop::FIELDS].select { |field| field['is_voc'] }
|
28
|
+
field_vocabularies.each do |field|
|
29
|
+
idx = layer[Labimotion::Prop::FIELDS].index(field)
|
30
|
+
val = get_vocabulary_value(field, current_user, element)
|
31
|
+
update_field_value(properties, key, idx, val) if val.present?
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def get_vocabulary_value(field, current_user, element)
|
36
|
+
case field['source']
|
37
|
+
when 'System'
|
38
|
+
get_system_value(field)
|
39
|
+
when 'User'
|
40
|
+
get_user_value(field, current_user)
|
41
|
+
when 'Element'
|
42
|
+
get_element_value(field, element)
|
43
|
+
when 'Segment'
|
44
|
+
get_segment_value(field, element)
|
45
|
+
when 'Dataset'
|
46
|
+
# TODO: Implement Dataset logic here
|
47
|
+
nil
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def get_system_value(field)
|
52
|
+
current_time = Time.now.strftime('%d/%m/%Y %H:%M')
|
53
|
+
case field['identifier']
|
54
|
+
when 'dateTime-update'
|
55
|
+
current_time
|
56
|
+
when 'dateTime-create'
|
57
|
+
current_time if field['value'].blank?
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def get_user_value(field, current_user)
|
62
|
+
current_user.name if field['identifier'] == 'user-name' && current_user.present?
|
63
|
+
end
|
64
|
+
|
65
|
+
def get_element_value(field, element)
|
66
|
+
case field['identifier']
|
67
|
+
when 'element-id'
|
68
|
+
element.id.to_s
|
69
|
+
when 'element-short_label'
|
70
|
+
element.short_label if element.has_attribute?(:short_label)
|
71
|
+
when 'element-name'
|
72
|
+
element.name if element.has_attribute?(:name)
|
73
|
+
when 'element-class'
|
74
|
+
element.class.name === 'Labimotion::Element' ? element.element_klass.label : element.class.name
|
75
|
+
else
|
76
|
+
ek = element.element_klass
|
77
|
+
return if ek.nil? || ek.identifier != field['source_id']
|
78
|
+
|
79
|
+
el_prop = element.properties
|
80
|
+
fields = el_prop[Labimotion::Prop::LAYERS][field['layer_id']][Labimotion::Prop::FIELDS]
|
81
|
+
fields.find { |ss| ss['field'] == field['field_id'] }&.dig('value')
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def get_segment_value(field, element)
|
86
|
+
segments = element.segments.joins(:segment_klass).find_by('segment_klasses.identifier = ?', field['source_id'])
|
87
|
+
return if segments.nil?
|
88
|
+
|
89
|
+
seg_prop = segments.properties
|
90
|
+
fields = seg_prop[Labimotion::Prop::LAYERS][field['layer_id']][Labimotion::Prop::FIELDS]
|
91
|
+
fields.find { |ss| ss['field'] == field['field_id'] }&.dig('value')
|
92
|
+
end
|
93
|
+
|
94
|
+
def update_field_value(properties, key, idx, val)
|
95
|
+
properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]['value'] = val
|
96
|
+
properties
|
97
|
+
end
|
98
|
+
|
99
|
+
def load_from_files
|
100
|
+
merged_data = []
|
101
|
+
merged_data.concat(load_json_file('System.json'))
|
102
|
+
merged_data.concat(load_json_file('Standard.json'))
|
103
|
+
merged_data
|
104
|
+
end
|
105
|
+
|
106
|
+
def load_json_file(filename)
|
107
|
+
file_path = File.join(__dir__, 'data', 'vocab', filename)
|
108
|
+
file_content = File.read(file_path)
|
109
|
+
JSON.parse(file_content)
|
110
|
+
end
|
111
|
+
|
112
|
+
def load_from_database
|
113
|
+
vocabularies = Labimotion::Vocabulary.all.sort_by(&:name)
|
114
|
+
Labimotion::VocabularyEntity.represent(vocabularies, serializable: true)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|