labimotion 1.4.1 → 2.0.0.rc2
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 +26 -0
- data/lib/labimotion/apis/standard_layer_api.rb +100 -0
- data/lib/labimotion/apis/vocabulary_api.rb +107 -0
- data/lib/labimotion/entities/dataset_entity.rb +2 -1
- data/lib/labimotion/entities/properties_entity.rb +167 -55
- data/lib/labimotion/entities/segment_entity.rb +1 -0
- data/lib/labimotion/entities/vocabulary_entity.rb +39 -0
- data/lib/labimotion/helpers/element_helpers.rb +8 -6
- data/lib/labimotion/helpers/param_helpers.rb +137 -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 +13 -33
- data/lib/labimotion/libs/data/vocab/Standard.json +385 -0
- data/lib/labimotion/libs/data/vocab/System.json +131 -0
- data/lib/labimotion/libs/nmr_mapper.rb +2 -1
- 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/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/version.rb +1 -1
- data/lib/labimotion.rb +10 -0
- metadata +20 -5
@@ -6,94 +6,149 @@ module Labimotion
|
|
6
6
|
## Generic Helpers
|
7
7
|
module ParamHelpers
|
8
8
|
extend Grape::API::Helpers
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
9
|
+
## Element Klass Params
|
10
|
+
params :upload_element_klass_params do
|
11
|
+
requires :name, type: String, desc: 'Klass Name'
|
12
|
+
optional :label, type: String, desc: 'Klass label'
|
13
|
+
optional :desc, type: String, desc: 'Klass desc'
|
14
|
+
optional :klass_prefix, type: String, desc: 'Klass klass_prefix'
|
15
|
+
optional :icon_name, type: String, desc: 'Klass icon_name'
|
16
|
+
requires :properties_template, type: Hash, desc: 'Klass template'
|
17
|
+
optional :properties_release, type: Hash, desc: 'Klass release'
|
18
|
+
optional :released_at, type: DateTime, desc: 'Klass released_at'
|
19
|
+
requires :uuid, type: String, desc: 'Klass uuid'
|
20
|
+
requires :place, type: Integer, desc: 'Klass place'
|
21
|
+
requires :identifier, type: String, desc: 'Klass identifier'
|
22
|
+
optional :sync_time, type: DateTime, desc: 'Klass sync_time'
|
23
|
+
optional :version, type: String, desc: 'Klass version'
|
24
|
+
end
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
26
|
+
params :create_element_klass_params do
|
27
|
+
requires :name, type: String, desc: 'Element Klass Name'
|
28
|
+
requires :label, type: String, desc: 'Element Klass Label'
|
29
|
+
requires :klass_prefix, type: String, desc: 'Element Klass Short Label Prefix'
|
30
|
+
optional :icon_name, type: String, desc: 'Element Klass Icon Name'
|
31
|
+
optional :desc, type: String, desc: 'Element Klass Desc'
|
32
|
+
optional :properties_template, type: Hash, desc: 'Element Klass properties template'
|
33
|
+
end
|
34
34
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
35
|
+
params :update_element_klass_params do
|
36
|
+
requires :id, type: Integer, desc: 'Element Klass ID'
|
37
|
+
optional :label, type: String, desc: 'Element Klass Label'
|
38
|
+
optional :klass_prefix, type: String, desc: 'Element Klass Short Label Prefix'
|
39
|
+
optional :icon_name, type: String, desc: 'Element Klass Icon Name'
|
40
|
+
optional :desc, type: String, desc: 'Element Klass Desc'
|
41
|
+
optional :place, type: String, desc: 'Element Klass Place'
|
42
|
+
end
|
43
43
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
44
|
+
## Element Params
|
45
|
+
params :create_element_params do
|
46
|
+
requires :element_klass, type: Hash
|
47
|
+
requires :name, type: String
|
48
|
+
optional :properties, type: Hash
|
49
|
+
optional :properties_release, type: Hash
|
50
|
+
optional :collection_id, type: Integer
|
51
|
+
requires :container, type: Hash
|
52
|
+
optional :user_labels, type: Array
|
53
|
+
optional :segments, type: Array, desc: 'Segments'
|
54
|
+
end
|
55
55
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
56
|
+
params :update_element_params do
|
57
|
+
requires :id, type: Integer, desc: 'element id'
|
58
|
+
optional :name, type: String
|
59
|
+
requires :properties, type: Hash
|
60
|
+
optional :properties_release, type: Hash
|
61
|
+
requires :container, type: Hash
|
62
|
+
optional :user_labels, type: Array
|
63
|
+
optional :segments, type: Array, desc: 'Segments'
|
64
|
+
end
|
65
65
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
end
|
66
|
+
## Segment Klass Params
|
67
|
+
params :upload_segment_klass_params do
|
68
|
+
requires :label, type: String, desc: 'Klass label'
|
69
|
+
optional :desc, type: String, desc: 'Klass desc'
|
70
|
+
requires :properties_template, type: Hash, desc: 'Klass template'
|
71
|
+
optional :properties_release, type: Hash, desc: 'Klass release'
|
72
|
+
optional :released_at, type: DateTime, desc: 'Klass released_at'
|
73
|
+
requires :uuid, type: String, desc: 'Klass uuid'
|
74
|
+
requires :place, type: Integer, desc: 'Klass place'
|
75
|
+
requires :identifier, type: String, desc: 'Klass identifier'
|
76
|
+
optional :sync_time, type: DateTime, desc: 'Klass sync_time'
|
77
|
+
optional :version, type: String, desc: 'Klass version'
|
78
|
+
requires :element_klass, type: Hash do
|
79
|
+
use :upload_element_klass_params
|
81
80
|
end
|
81
|
+
end
|
82
82
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
83
|
+
params :update_segment_klass_params do
|
84
|
+
requires :id, type: Integer, desc: 'Segment Klass ID'
|
85
|
+
optional :label, type: String, desc: 'Segment Klass Label'
|
86
|
+
optional :desc, type: String, desc: 'Segment Klass Desc'
|
87
|
+
optional :place, type: String, desc: 'Segment Klass Place', default: '100'
|
88
|
+
optional :identifier, type: String, desc: 'Segment Identifier'
|
89
|
+
end
|
90
90
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
91
|
+
params :create_segment_klass_params do
|
92
|
+
requires :label, type: String, desc: 'Segment Klass Label'
|
93
|
+
requires :element_klass, type: Integer, desc: 'Element Klass Id'
|
94
|
+
optional :desc, type: String, desc: 'Segment Klass Desc'
|
95
|
+
optional :place, type: String, desc: 'Segment Klass Place', default: '100'
|
96
|
+
optional :properties_template, type: Hash, desc: 'Element Klass properties template'
|
97
|
+
end
|
98
|
+
|
99
|
+
params :create_std_layer_params do
|
100
|
+
requires :name, type: String, desc: 'Element Klass Name'
|
101
|
+
requires :label, type: String, desc: 'Element Klass Label'
|
102
|
+
requires :klass_prefix, type: String, desc: 'Element Klass Short Label Prefix'
|
103
|
+
optional :icon_name, type: String, desc: 'Element Klass Icon Name'
|
104
|
+
optional :desc, type: String, desc: 'Element Klass Desc'
|
105
|
+
optional :properties_template, type: Hash, desc: 'Element Klass properties template'
|
106
|
+
end
|
107
|
+
|
108
|
+
params :std_layer_save do
|
109
|
+
requires :key, type: String, desc: 'key'
|
110
|
+
requires :cols, type: Integer, desc: 'key'
|
111
|
+
requires :label, type: String, desc: 'Label'
|
112
|
+
optional :position, type: Integer, desc: 'position'
|
113
|
+
optional :wf_position, type: Integer, desc: 'wf position'
|
114
|
+
optional :fields, type: Array, desc: 'fields'
|
115
|
+
optional :select_options, type: Hash, desc: 'selections'
|
116
|
+
end
|
117
|
+
|
118
|
+
params :std_layer_criteria do
|
119
|
+
requires :name, type: String, desc: 'Layer name'
|
120
|
+
end
|
121
|
+
|
122
|
+
params :vocab_save do
|
123
|
+
optional :name, type: String, desc: 'field'
|
124
|
+
optional :label, type: String, desc: 'Label'
|
125
|
+
optional :term_id, type: String, desc: 'ontology term_id'
|
126
|
+
requires :ontology, type: Hash, desc: 'ontology'
|
127
|
+
optional :source, type: String, desc: 'source'
|
128
|
+
optional :source_id, type: String, desc: 'source_id'
|
129
|
+
optional :layer_id, type: String, desc: 'layer_id'
|
130
|
+
optional :sub_fields, type: Array, desc: 'sub_fields'
|
131
|
+
optional :text_sub_fields, type: Array, desc: 'text_sub_fields'
|
132
|
+
requires :field_type, type: String, desc: 'field type'
|
133
|
+
requires :voc, type: Hash, desc: 'vocabulary references'
|
134
|
+
optional :select_options, type: Hash, desc: 'selections'
|
135
|
+
optional :option_layers, type: String, desc: 'option'
|
136
|
+
end
|
137
|
+
|
138
|
+
# params :vocabulary_save do
|
139
|
+
# requires :type, type: String, desc: 'type'
|
140
|
+
# requires :field, type: String, desc: 'field'
|
141
|
+
# optional :default, type: String, desc: 'default'
|
142
|
+
# optional :description, type: String, desc: 'description'
|
143
|
+
# optional :label, type: String, desc: 'label'
|
144
|
+
# optional :position, type: Integer, desc: 'position'
|
145
|
+
# optional :ontology, type: Hash, desc: 'ontology'
|
146
|
+
# optional :required, type: Boolean, desc: 'is required?'
|
147
|
+
# optional :sub_fields, type: Array, desc: 'sub_fields'
|
148
|
+
# optional :text_sub_fields, type: Array, desc: 'text_sub_fields'
|
149
|
+
# optional :source_type, type: String, desc: 'source type'
|
150
|
+
# optional :source_id, type: String, desc: 'source id'
|
151
|
+
# optional :layer_id, type: String, desc: 'layer id'
|
152
|
+
# end
|
98
153
|
end
|
99
|
-
end
|
154
|
+
end
|
@@ -72,7 +72,7 @@ module Labimotion
|
|
72
72
|
# el_attributes['properties_template'] = response['element_klass']['properties_release']
|
73
73
|
# Labimotion::ElementKlass.create!(el_attributes)
|
74
74
|
attributes['element_klass_id'] = element_klass.id
|
75
|
-
segment_klass = Labimotion::SegmentKlass.find_by(identifier: attributes['identifier'])
|
75
|
+
segment_klass = Labimotion::SegmentKlass.find_by(identifier: attributes['identifier']) if attributes['identifier'].present?
|
76
76
|
if segment_klass.present?
|
77
77
|
if segment_klass['uuid'] == attributes['uuid'] && segment_klass['version'] == attributes['version']
|
78
78
|
return { status: 'success', message: "This segment: #{attributes['label']} has the latest version!" }
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Labimotion
|
4
|
+
# Helper for associated sample
|
5
|
+
module VocabularyHelpers
|
6
|
+
extend Grape::API::Helpers
|
7
|
+
|
8
|
+
def update_vocabularies(properties, current_user, element)
|
9
|
+
Labimotion::VocabularyHandler.update_vocabularies(properties, current_user, element)
|
10
|
+
rescue StandardError => e
|
11
|
+
Labimotion.log_exception(e, current_user)
|
12
|
+
properties
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -28,7 +28,7 @@ module Labimotion
|
|
28
28
|
dsr = []
|
29
29
|
ols = nil
|
30
30
|
Zip::File.open(att.attachment_attacher.file.url) do |zip_file|
|
31
|
-
res = Labimotion::Converter.collect_metadata(zip_file) if att.filename.split('.')&.last == 'zip'
|
31
|
+
res = Labimotion::Converter.collect_metadata(zip_file, current_user) if att.filename.split('.')&.last == 'zip'
|
32
32
|
ols = res[:o] unless res&.dig(:o).nil?
|
33
33
|
dsr.push(res[:d]) unless res&.dig(:d).nil?
|
34
34
|
end
|
@@ -92,7 +92,7 @@ module Labimotion
|
|
92
92
|
{ a: oa, f: folder }
|
93
93
|
end
|
94
94
|
|
95
|
-
def self.collect_metadata(zip_file) # rubocop: disable Metrics/PerceivedComplexity
|
95
|
+
def self.collect_metadata(zip_file, current_user = {}) # rubocop: disable Metrics/PerceivedComplexity
|
96
96
|
dsr = []
|
97
97
|
ols = nil
|
98
98
|
zip_file.each do |entry|
|
@@ -114,7 +114,7 @@ module Labimotion
|
|
114
114
|
{ d: dsr, o: ols }
|
115
115
|
end
|
116
116
|
|
117
|
-
def self.handle_response(oat, response) # rubocop: disable Metrics/PerceivedComplexity
|
117
|
+
def self.handle_response(oat, response, current_user = {}) # rubocop: disable Metrics/PerceivedComplexity
|
118
118
|
dsr = []
|
119
119
|
ols = nil
|
120
120
|
|
@@ -123,10 +123,9 @@ module Labimotion
|
|
123
123
|
tmp_file.write(response.parsed_response)
|
124
124
|
tmp_file.rewind
|
125
125
|
|
126
|
-
name = response&.headers && response&.headers['content-disposition']&.split('=')&.last
|
126
|
+
# name = response&.headers && response&.headers['content-disposition']&.split('=')&.last
|
127
127
|
filename = oat.filename
|
128
128
|
name = "#{File.basename(filename, '.*')}.zip"
|
129
|
-
|
130
129
|
att = Attachment.new(
|
131
130
|
filename: name,
|
132
131
|
file_path: tmp_file.path,
|
@@ -140,7 +139,7 @@ module Labimotion
|
|
140
139
|
|
141
140
|
att.save! if att.valid?
|
142
141
|
|
143
|
-
process_ds(att.id)
|
142
|
+
process_ds(att.id, current_user)
|
144
143
|
rescue StandardError => e
|
145
144
|
raise e
|
146
145
|
ensure
|
@@ -148,7 +147,7 @@ module Labimotion
|
|
148
147
|
end
|
149
148
|
end
|
150
149
|
|
151
|
-
def self.process(data)
|
150
|
+
def self.process(data, current_user = {}) # rubocop: disable Metrics/PerceivedComplexity
|
152
151
|
return data[:a].con_state if data[:a]&.attachable_type != 'Container'
|
153
152
|
response = nil
|
154
153
|
begin
|
@@ -165,25 +164,25 @@ module Labimotion
|
|
165
164
|
)
|
166
165
|
end
|
167
166
|
if response.ok?
|
168
|
-
Labimotion::Converter.handle_response(data[:a], response)
|
167
|
+
Labimotion::Converter.handle_response(data[:a], response, current_user)
|
169
168
|
Labimotion::ConState::PROCESSED
|
170
169
|
else
|
171
170
|
Labimotion::Converter.logger.error ["Converter Response Error: id: [#{data[:a]&.id}], filename: [#{data[:a]&.filename}], response: #{response}"].join($INPUT_RECORD_SEPARATOR)
|
172
171
|
Labimotion::ConState::ERROR
|
173
172
|
end
|
174
173
|
rescue StandardError => e
|
175
|
-
Labimotion::Converter.logger.error ["process fail:
|
174
|
+
Labimotion::Converter.logger.error ["process fail: #{data[:a]&.id}", e.message, *e.backtrace].join($INPUT_RECORD_SEPARATOR)
|
176
175
|
Labimotion::ConState::ERROR
|
177
176
|
ensure
|
178
177
|
FileUtils.rm_f(ofile)
|
179
178
|
end
|
180
179
|
end
|
181
180
|
|
182
|
-
def self.jcamp_converter(id)
|
181
|
+
def self.jcamp_converter(id, current_user = {})
|
183
182
|
data = Labimotion::Converter.vor_conv(id)
|
184
183
|
return if data.nil?
|
185
184
|
|
186
|
-
Labimotion::Converter.process(data)
|
185
|
+
Labimotion::Converter.process(data, current_user)
|
187
186
|
rescue StandardError => e
|
188
187
|
Labimotion::Converter.logger.error ["jcamp_converter fail: #{id}", e.message, *e.backtrace].join($INPUT_RECORD_SEPARATOR)
|
189
188
|
Labimotion::ConState::ERROR
|
@@ -243,27 +242,8 @@ module Labimotion
|
|
243
242
|
fi['device'] = ds[:device] || ds[:value]
|
244
243
|
new_prop[Labimotion::Prop::LAYERS][ds[:layer]][Labimotion::Prop::FIELDS][idx] = fi
|
245
244
|
end
|
246
|
-
new_prop.dig(Labimotion::Prop::LAYERS, 'general', Labimotion::Prop::FIELDS)&.each_with_index do |fi, idx|
|
247
|
-
if fi['field'] == 'creator' && current_user.present?
|
248
|
-
fi['value'] = current_user.name
|
249
|
-
fi['system'] = current_user.name
|
250
|
-
new_prop[Labimotion::Prop::LAYERS]['general'][Labimotion::Prop::FIELDS][idx] = fi
|
251
|
-
end
|
252
|
-
end
|
253
245
|
element = Container.find(dataset.element_id)&.root_element
|
254
|
-
|
255
|
-
if fi['field'] == 'id'
|
256
|
-
fi['value'] = element.id
|
257
|
-
fi['system'] = element.id
|
258
|
-
new_prop[Labimotion::Prop::LAYERS]['sample_details'][Labimotion::Prop::FIELDS][idx] = fi
|
259
|
-
end
|
260
|
-
|
261
|
-
if fi['field'] == 'label'
|
262
|
-
fi['value'] = element.short_label
|
263
|
-
fi['system'] = element.short_label
|
264
|
-
new_prop[Labimotion::Prop::LAYERS]['sample_details'][Labimotion::Prop::FIELDS][idx] = fi
|
265
|
-
end
|
266
|
-
end
|
246
|
+
new_prop = Labimotion::VocabularyHandler.update_vocabularies(new_prop, current_user, element)
|
267
247
|
dataset.properties = new_prop
|
268
248
|
dataset.save!
|
269
249
|
end
|
@@ -325,13 +305,13 @@ module Labimotion
|
|
325
305
|
res
|
326
306
|
end
|
327
307
|
|
328
|
-
def self.metadata(id)
|
308
|
+
def self.metadata(id, current_user)
|
329
309
|
att = Attachment.find(id)
|
330
310
|
return if att.nil? || att.attachable_id.nil? || att.attachable_type != Labimotion::Prop::CONTAINER
|
331
311
|
|
332
312
|
ds = Labimotion::Dataset.find_by(element_type: Labimotion::Prop::CONTAINER, element_id: att.attachable_id)
|
333
313
|
att.update_column(:con_state, Labimotion::ConState::COMPLETED) if ds.present?
|
334
|
-
process_ds(att.id) if ds.nil?
|
314
|
+
process_ds(att.id, current_user) if ds.nil?
|
335
315
|
end
|
336
316
|
end
|
337
317
|
end
|