labimotion 0.1.6

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.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/lib/labimotion/api.rb +19 -0
  3. data/lib/labimotion/apis/converter_api.rb +68 -0
  4. data/lib/labimotion/apis/generic_dataset_api.rb +50 -0
  5. data/lib/labimotion/apis/generic_element_api.rb +339 -0
  6. data/lib/labimotion/apis/labimotion_hub_api.rb +53 -0
  7. data/lib/labimotion/apis/segment_api.rb +144 -0
  8. data/lib/labimotion/entities/application_entity.rb +88 -0
  9. data/lib/labimotion/entities/dataset_entity.rb +16 -0
  10. data/lib/labimotion/entities/dataset_klass_entity.rb +9 -0
  11. data/lib/labimotion/entities/element_entity.rb +108 -0
  12. data/lib/labimotion/entities/element_klass_entity.rb +10 -0
  13. data/lib/labimotion/entities/element_revision_entity.rb +57 -0
  14. data/lib/labimotion/entities/eln_element_entity.rb +110 -0
  15. data/lib/labimotion/entities/generic_entity.rb +54 -0
  16. data/lib/labimotion/entities/generic_klass_entity.rb +14 -0
  17. data/lib/labimotion/entities/generic_public_entity.rb +25 -0
  18. data/lib/labimotion/entities/klass_revision_entity.rb +20 -0
  19. data/lib/labimotion/entities/segment_entity.rb +62 -0
  20. data/lib/labimotion/entities/segment_klass_entity.rb +8 -0
  21. data/lib/labimotion/entities/segment_revision_entity.rb +55 -0
  22. data/lib/labimotion/helpers/converter_helpers.rb +13 -0
  23. data/lib/labimotion/helpers/dataset_helpers.rb +38 -0
  24. data/lib/labimotion/helpers/element_helpers.rb +268 -0
  25. data/lib/labimotion/helpers/generic_helpers.rb +252 -0
  26. data/lib/labimotion/helpers/repository_helpers.rb +14 -0
  27. data/lib/labimotion/helpers/sample_association_helpers.rb +126 -0
  28. data/lib/labimotion/helpers/search_helpers.rb +62 -0
  29. data/lib/labimotion/helpers/segment_helpers.rb +97 -0
  30. data/lib/labimotion/libs/converter.rb +325 -0
  31. data/lib/labimotion/libs/export_dataset.rb +121 -0
  32. data/lib/labimotion/libs/nmr_mapper.rb +265 -0
  33. data/lib/labimotion/libs/nmr_mapper_repo.rb +263 -0
  34. data/lib/labimotion/libs/template_hub.rb +55 -0
  35. data/lib/labimotion/models/collections_element.rb +42 -0
  36. data/lib/labimotion/models/concerns/attachment_converter.rb +42 -0
  37. data/lib/labimotion/models/concerns/datasetable.rb +50 -0
  38. data/lib/labimotion/models/concerns/generic_klass_revisions.rb +39 -0
  39. data/lib/labimotion/models/concerns/generic_revisions.rb +43 -0
  40. data/lib/labimotion/models/concerns/segmentable.rb +74 -0
  41. data/lib/labimotion/models/dataset.rb +14 -0
  42. data/lib/labimotion/models/dataset_klass.rb +25 -0
  43. data/lib/labimotion/models/dataset_klasses_revision.rb +9 -0
  44. data/lib/labimotion/models/datasets_revision.rb +9 -0
  45. data/lib/labimotion/models/element.rb +121 -0
  46. data/lib/labimotion/models/element_klass.rb +25 -0
  47. data/lib/labimotion/models/element_klasses_revision.rb +9 -0
  48. data/lib/labimotion/models/elements_element.rb +11 -0
  49. data/lib/labimotion/models/elements_revision.rb +8 -0
  50. data/lib/labimotion/models/elements_sample.rb +11 -0
  51. data/lib/labimotion/models/segment.rb +14 -0
  52. data/lib/labimotion/models/segment_klass.rb +24 -0
  53. data/lib/labimotion/models/segment_klasses_revision.rb +9 -0
  54. data/lib/labimotion/models/segments_revision.rb +9 -0
  55. data/lib/labimotion/utils/con_state.rb +13 -0
  56. data/lib/labimotion/utils/export.rb +112 -0
  57. data/lib/labimotion/utils/import.rb +186 -0
  58. data/lib/labimotion/utils/search.rb +112 -0
  59. data/lib/labimotion/utils/serializer.rb +78 -0
  60. data/lib/labimotion/version.rb +6 -0
  61. data/lib/labimotion.rb +95 -0
  62. metadata +119 -0
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+ require 'grape'
3
+ module Labimotion
4
+ ## DatasetHelpers
5
+ module DatasetHelpers
6
+ extend Grape::API::Helpers
7
+
8
+ def klass_list(is_active)
9
+ if is_active == true
10
+ Labimotion::DatasetKlass.where(is_active: true).order('place') || []
11
+ else
12
+ Labimotion::DatasetKlass.all.order('place') || []
13
+ end
14
+ end
15
+
16
+ def create_repo_klass(params, current_user)
17
+ response = Labimotion::TemplateHub.fetch_identifier('DatasetKlass', params[:identifier])
18
+ attributes = response.slice('ols_term_id', 'label', 'desc', 'uuid', 'identifier') # .except(:id, :is_active, :place, :created_by, :created_at, :updated_at)
19
+ attributes['properties_template'] = response['properties_release']
20
+ attributes['place'] = ((Labimotion::DatasetKlass.all.length * 10) || 0) + 10
21
+ attributes['is_active'] = false
22
+ attributes['updated_by'] = current_user.id
23
+ attributes['sync_by'] = current_user.id
24
+ attributes['sync_time'] = DateTime.now
25
+ if Labimotion::DatasetKlass.find_by(ols_term_id: attributes['ols_term_id']).present?
26
+ ds = Labimotion::DatasetKlass.find_by(ols_term_id: attributes['ols_term_id'])
27
+ ds.update!(attributes)
28
+ else
29
+ attributes['created_by'] = current_user.id
30
+ Labimotion::DatasetKlass.create!(attributes)
31
+ end
32
+ rescue => e
33
+ Labimotion.log_exception(e, current_user)
34
+ # { error: e.message }
35
+ raise e
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,268 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'grape'
4
+ require 'labimotion/version'
5
+ # require 'labimotion/models/element_klass'
6
+ module Labimotion
7
+ ## ElementHelpers
8
+ module ElementHelpers
9
+ extend Grape::API::Helpers
10
+
11
+ def klass_list(is_generic_only)
12
+ if is_generic_only == true
13
+ Labimotion::ElementKlass.where(is_active: true, is_generic: true).order('place') || []
14
+ else
15
+ Labimotion::ElementKlass.where(is_active: true).order('place') || []
16
+ end
17
+ end
18
+
19
+ def create_element_klass(current_user, params)
20
+ uuid = SecureRandom.uuid
21
+ template = { uuid: uuid, layers: {}, select_options: {} }
22
+ attributes = declared(params, include_missing: false)
23
+ attributes[:properties_template]['uuid'] = uuid if attributes[:properties_template].present?
24
+ attributes[:properties_template] = template unless attributes[:properties_template].present?
25
+ attributes[:properties_template]['eln'] = Chemotion::Application.config.version if attributes[:properties_template].present?
26
+ attributes[:properties_template]['labimotion'] = Labimotion::VERSION if attributes[:properties_template].present?
27
+ attributes[:properties_template]['klass'] = 'ElementKlass' if attributes[:properties_template].present?
28
+ attributes[:is_active] = false
29
+ attributes[:uuid] = uuid
30
+ attributes[:released_at] = DateTime.now
31
+ attributes[:properties_release] = attributes[:properties_template]
32
+ attributes[:created_by] = current_user.id
33
+
34
+ new_klass = Labimotion::ElementKlass.create!(attributes)
35
+ new_klass.reload
36
+ new_klass.create_klasses_revision(current_user.id)
37
+ klass_names_file = Rails.root.join('config', 'klasses.json')
38
+ klasses = Labimotion::ElementKlass.where(is_active: true)&.pluck(:name) || []
39
+ File.write(klass_names_file, klasses)
40
+ klasses
41
+ rescue => e
42
+ Labimotion.log_exception(e, current_user)
43
+ raise e
44
+ end
45
+
46
+ def update_element_klass(current_user, params)
47
+ place = params[:place] || 100
48
+ begin
49
+ place = place.to_i if place.present? && place.to_i == place.to_f
50
+ rescue StandardError
51
+ place = 100
52
+ end
53
+ klass = Labimotion::ElementKlass.find(params[:id])
54
+ klass.label = params[:label] if params[:label].present?
55
+ klass.klass_prefix = params[:klass_prefix] if params[:klass_prefix].present?
56
+ klass.icon_name = params[:icon_name] if params[:icon_name].present?
57
+ klass.desc = params[:desc] if params[:desc].present?
58
+ klass.place = place
59
+ klass.save!
60
+ klass
61
+ rescue => e
62
+ Labimotion.log_exception(e, current_user)
63
+ raise e
64
+ end
65
+
66
+ def create_element(current_user, params)
67
+ klass = params[:element_klass] || {}
68
+ uuid = SecureRandom.uuid
69
+ params[:properties]['uuid'] = uuid
70
+ params[:properties]['klass_uuid'] = klass[:uuid]
71
+ params[:properties]['eln'] = Chemotion::Application.config.version
72
+ params[:properties]['labimotion'] = Labimotion::VERSION
73
+ params[:properties]['klass'] = 'Element'
74
+ properties = params[:properties]
75
+ properties.delete('flow') unless properties['flow'].nil?
76
+ properties.delete('select_options') unless properties['select_options'].nil?
77
+ attributes = {
78
+ name: params[:name],
79
+ element_klass_id: klass[:id],
80
+ uuid: uuid,
81
+ klass_uuid: klass[:uuid],
82
+ properties: properties,
83
+ properties_release: params[:properties_release],
84
+ created_by: current_user.id,
85
+ }
86
+ element = Labimotion::Element.new(attributes)
87
+
88
+ if params[:collection_id]
89
+ collection = current_user.collections.find(params[:collection_id])
90
+ element.collections << collection
91
+ end
92
+ all_coll = Collection.get_all_collection_for_user(current_user.id)
93
+ element.collections << all_coll
94
+ element.save!
95
+ element.properties = update_sample_association(element, params[:properties], current_user)
96
+ element.container = update_datamodel(params[:container], current_user)
97
+ element.save!
98
+ element.save_segments(segments: params[:segments], current_user_id: current_user.id)
99
+ element
100
+ rescue => e
101
+ Labimotion.log_exception(e, current_user)
102
+ raise e
103
+ end
104
+
105
+ def update_element_by_id(current_user, params)
106
+ element = Labimotion::Element.find(params[:id])
107
+ update_datamodel(params[:container], current_user)
108
+ properties = update_sample_association(element, params[:properties], current_user)
109
+ params.delete(:container)
110
+ params.delete(:properties)
111
+ attributes = declared(params.except(:segments), include_missing: false)
112
+ properties['eln'] = Chemotion::Application.config.version
113
+ properties['labimotion'] = Labimotion::VERSION
114
+ if element.klass_uuid != properties['klass_uuid'] || element.properties != properties || element.name != params[:name]
115
+ properties['klass'] = 'Element'
116
+ uuid = SecureRandom.uuid
117
+ properties['uuid'] = uuid
118
+
119
+ properties.delete('flow') unless properties['flow'].nil?
120
+ properties.delete('select_options') unless properties['select_options'].nil?
121
+
122
+ attributes['properties'] = properties
123
+ attributes['properties']['uuid'] = uuid
124
+ attributes['uuid'] = uuid
125
+ attributes['klass_uuid'] = properties['klass_uuid']
126
+
127
+ element.update(attributes)
128
+ end
129
+ element.save_segments(segments: params[:segments], current_user_id: current_user.id)
130
+ element
131
+ rescue => e
132
+ Labimotion.log_exception(e, current_user)
133
+ raise e
134
+ end
135
+
136
+ def upload_generics_files(current_user, params)
137
+ attach_ary = []
138
+ att_ary = create_uploads(
139
+ 'Element',
140
+ params[:att_id],
141
+ params[:elfiles],
142
+ params[:elInfo],
143
+ current_user.id,
144
+ ) if params[:elfiles].present? && params[:elInfo].present?
145
+
146
+ (attach_ary << att_ary).flatten! unless att_ary&.empty?
147
+
148
+ att_ary = create_uploads(
149
+ 'Segment',
150
+ params[:att_id],
151
+ params[:sefiles],
152
+ params[:seInfo],
153
+ current_user.id
154
+ ) if params[:sefiles].present? && params[:seInfo].present?
155
+
156
+ (attach_ary << att_ary).flatten! unless att_ary&.empty?
157
+
158
+ if params[:attfiles].present? || params[:delfiles].present? then
159
+ att_ary = create_attachments(
160
+ params[:attfiles],
161
+ params[:delfiles],
162
+ params[:att_type],
163
+ params[:att_id],
164
+ params[:attfilesIdentifier],
165
+ current_user.id
166
+ )
167
+ end
168
+ (attach_ary << att_ary).flatten! unless att_ary&.empty?
169
+
170
+ if Labimotion::IS_RAILS5 == true
171
+ TransferThumbnailToPublicJob.set(queue: "transfer_thumbnail_to_public_#{current_user.id}").perform_now(attach_ary) unless attach_ary.empty?
172
+ TransferFileFromTmpJob.set(queue: "transfer_file_from_tmp_#{current_user.id}").perform_now(attach_ary) unless attach_ary.empty?
173
+ end
174
+ true
175
+ rescue => e
176
+ Labimotion.log_exception(e, current_user)
177
+ ## false
178
+ raise e
179
+ end
180
+
181
+ def element_revisions(params)
182
+ klass = Labimotion::Element.find(params[:id])
183
+ list = klass.elements_revisions unless klass.nil?
184
+ list&.sort_by(&:created_at)&.reverse
185
+ rescue => e
186
+ Labimotion.log_exception(e, current_user)
187
+ raise e
188
+ end
189
+
190
+ def list_user_elements(scope, params)
191
+ from = params[:from_date]
192
+ to = params[:to_date]
193
+ by_created_at = params[:filter_created_at] || false
194
+
195
+ if params[:sort_column]&.include?('.')
196
+ layer, field = params[:sort_column].split('.')
197
+
198
+ element_klass = Labimotion::ElementKlass.find_by(name: params[:el_type])
199
+ allowed_fields = element_klass.properties_release.dig('layers', layer, 'fields')&.pluck('field') || []
200
+
201
+ if field.in?(allowed_fields)
202
+ query = ActiveRecord::Base.sanitize_sql(
203
+ [
204
+ "LEFT JOIN LATERAL(
205
+ SELECT field->'value' AS value
206
+ FROM jsonb_array_elements(properties->'layers'->:layer->'fields') a(field)
207
+ WHERE field->>'field' = :field
208
+ ) a ON true",
209
+ { layer: layer, field: field },
210
+ ],
211
+ )
212
+ scope = scope.joins(query).order('value ASC NULLS FIRST')
213
+ else
214
+ scope = scope.order(updated_at: :desc)
215
+ end
216
+ else
217
+ scope = scope.order(updated_at: :desc)
218
+ end
219
+
220
+ scope = scope.created_time_from(Time.at(from)) if from && by_created_at
221
+ scope = scope.created_time_to(Time.at(to) + 1.day) if to && by_created_at
222
+ scope = scope.updated_time_from(Time.at(from)) if from && !by_created_at
223
+ scope = scope.updated_time_to(Time.at(to) + 1.day) if to && !by_created_at
224
+ scope
225
+ rescue => e
226
+ Labimotion.log_exception(e, current_user)
227
+ raise e
228
+ end
229
+
230
+ def list_serialized_elements(params, current_user)
231
+ collection_id =
232
+ if params[:collection_id]
233
+ Collection
234
+ .belongs_to_or_shared_by(current_user.id, current_user.group_ids)
235
+ .find_by(id: params[:collection_id])&.id
236
+ elsif params[:sync_collection_id]
237
+ current_user
238
+ .all_sync_in_collections_users
239
+ .find_by(id: params[:sync_collection_id])&.collection&.id
240
+ end
241
+
242
+ scope =
243
+ if collection_id
244
+ Labimotion::Element
245
+ .joins(:element_klass, :collections_elements)
246
+ .where(
247
+ element_klasses: { name: params[:el_type] },
248
+ collections_elements: { collection_id: collection_id },
249
+ ).includes(:tag, collections: :sync_collections_users).order('created_at DESC')
250
+ else
251
+ Labimotion::Element.none
252
+ end
253
+
254
+ ## TO DO: refactor labimotion
255
+ from = params[:from_date]
256
+ to = params[:to_date]
257
+ by_created_at = params[:filter_created_at] || false
258
+ scope = scope.created_time_from(Time.at(from)) if from && by_created_at
259
+ scope = scope.created_time_to(Time.at(to) + 1.day) if to && by_created_at
260
+ scope = scope.updated_time_from(Time.at(from)) if from && !by_created_at
261
+ scope = scope.updated_time_to(Time.at(to) + 1.day) if to && !by_created_at
262
+ scope
263
+ rescue => e
264
+ Labimotion.log_exception(e, current_user)
265
+ raise e
266
+ end
267
+ end
268
+ end
@@ -0,0 +1,252 @@
1
+ # frozen_string_literal: true
2
+ require 'grape'
3
+ require 'labimotion/version'
4
+ # Helper for associated sample
5
+ module Labimotion
6
+ ## Generic Helpers
7
+ module GenericHelpers
8
+ extend Grape::API::Helpers
9
+
10
+ def authenticate_admin!(type)
11
+ error!('401 Unauthorized', 401) unless current_user.generic_admin[type]
12
+ end
13
+
14
+ def fetch_klass(name, id)
15
+ klz = "Labimotion::#{name}".constantize.find_by(id: id)
16
+ error!("#{name.gsub(/(Klass)/, '')} is invalid. Please re-select.", 500) if klz.nil?
17
+ klz
18
+ rescue => e
19
+ Labimotion.log_exception(e, current_user)
20
+ raise e
21
+ end
22
+
23
+ def deactivate_klass(params)
24
+ klz = fetch_klass(params[:klass], params[:id])
25
+ klz&.update!(is_active: params[:is_active])
26
+ generate_klass_file unless klz.class.name != 'ElementKlass'
27
+ klz
28
+ rescue => e
29
+ Labimotion.log_exception(e, current_user)
30
+ raise e
31
+ end
32
+
33
+ def delete_klass(params)
34
+ authenticate_admin!(params[:klass].gsub(/(Klass)/, 's').downcase)
35
+ klz = fetch_klass(params[:klass], params[:id])
36
+ klz&.destroy!
37
+ generate_klass_file unless klz.class.name != 'ElementKlass'
38
+ status 201
39
+ rescue => e
40
+ Labimotion.log_exception(e, current_user)
41
+ raise e
42
+ end
43
+
44
+ def update_template(params)
45
+ klz = fetch_klass(params[:klass], params[:id])
46
+ uuid = SecureRandom.uuid
47
+ properties = params[:properties_template]
48
+ if Labimotion::IS_RAILS5 == false
49
+ properties['uuid'] = uuid unless params[:is_release] == true && @klz.identifier.present?
50
+ else
51
+ properties['uuid'] = uuid
52
+ end
53
+ properties['eln'] = Chemotion::Application.config.version
54
+ properties['labimotion'] = Labimotion::VERSION
55
+ properties['klass'] = @klz.class.name
56
+ klz.updated_by = current_user.id
57
+ klz.properties_template = properties
58
+ klz.save!
59
+ klz.reload
60
+ klz.create_klasses_revision(current_user.id) if params[:is_release] == true
61
+ klz
62
+ rescue => e
63
+ Labimotion.log_exception(e, current_user)
64
+ raise e
65
+ end
66
+
67
+ def delete_klass_revision(params)
68
+ revision = "Labimotion::#{params[:klass]}esRevision".constantize.find(params[:id])
69
+ klass = "Labimotion::#{params[:klass]}".constantize.find_by(id: params[:klass_id]) unless revision.nil?
70
+ error!('Revision is invalid.', 404) if revision.nil?
71
+ error!('Can not delete the active revision.', 405) if revision.uuid == klass.uuid
72
+ revision&.destroy!
73
+ rescue => e
74
+ Labimotion.log_exception(e, current_user)
75
+ raise e
76
+ end
77
+
78
+ def delete_revision(params)
79
+ revision = "Labimotion::#{params[:klass]}sRevision".constantize.find(params[:id])
80
+ element = "Labimotion::#{params[:klass]}".constantize.find_by(id: params[:element_id]) unless revision.nil?
81
+ error!('Revision is invalid.', 404) if revision.nil?
82
+ error!('Can not delete the active revision.', 405) if revision.uuid == element.uuid
83
+ revision&.destroy!
84
+ rescue => e
85
+ Labimotion.log_exception(e, current_user)
86
+ raise e
87
+ end
88
+
89
+ def list_klass_revisions(params)
90
+ klass = "Labimotion::#{params[:klass]}".constantize.find_by(id: params[:id])
91
+ list = klass.send("#{params[:klass].underscore}es_revisions") unless klass.nil?
92
+ list.sort_by(&:released_at).reverse
93
+ rescue => e
94
+ Labimotion.log_exception(e, current_user)
95
+ raise e
96
+ end
97
+
98
+
99
+ ###############
100
+
101
+
102
+ def generate_klass_file
103
+ klass_dir = File.join(Rails.root, 'data')
104
+ !File.directory?(klass_dir) && FileUtils.mkdir_p(klass_dir)
105
+ klass_names_file = File.join(klass_dir, 'klasses.json')
106
+ klasses = Labimotion::ElementKlass.where(is_active: true)&.pluck(:name) || []
107
+ File.write(klass_names_file, klasses)
108
+ rescue => e
109
+ Labimotion.log_exception(e, current_user)
110
+ raise e
111
+ end
112
+
113
+ def fetch_properties_uploads(properties)
114
+ uploads = []
115
+ properties['layers'].keys.each do |key|
116
+ layer = properties['layers'][key]
117
+ field_uploads = layer['fields'].select { |ss| ss['type'] == 'upload' }
118
+ field_uploads.each do |field|
119
+ ((field['value'] && field['value']['files']) || []).each do |file|
120
+ uploads.push({ layer: key, field: field['field'], uid: file['uid'], filename: file['filename'] })
121
+ end
122
+ end
123
+ end
124
+ uploads
125
+ rescue => e
126
+ Labimotion.log_exception(e, current_user)
127
+ raise e
128
+ end
129
+
130
+ def update_properties_upload(element, properties, att, pa)
131
+ return if pa.nil?
132
+
133
+ idx = properties['layers'][pa[:layer]]['fields'].index { |fl| fl['field'] == pa[:field] }
134
+ fidx = properties['layers'][pa[:layer]]['fields'][idx]['value']['files'].index { |fi| fi['uid'] == pa[:uid] }
135
+ properties['layers'][pa[:layer]]['fields'][idx]['value']['files'][fidx]['aid'] = att.id
136
+ properties['layers'][pa[:layer]]['fields'][idx]['value']['files'][fidx]['uid'] = att.identifier
137
+ element.update_columns(properties: properties)
138
+ rescue => e
139
+ Labimotion.log_exception(e, current_user)
140
+ raise e
141
+ end
142
+
143
+ def create_uploads(type, id, files, param_info, user_id)
144
+ return if files.nil? || param_info.nil? || files.empty? || param_info.empty?
145
+
146
+ attach_ary = []
147
+ map_info = JSON.parse(param_info)
148
+ map_info&.keys&.each do |key|
149
+ next if map_info[key]['files'].empty?
150
+
151
+ if type == 'Segment'
152
+ element = Labimotion::Segment.find_by(element_id: id, segment_klass_id: key)
153
+ elsif type == 'Element'
154
+ element = Labimotion::Element.find_by(id: id)
155
+ end
156
+ next if element.nil?
157
+
158
+ uploads = fetch_properties_uploads(element.properties)
159
+
160
+ map_info[key]['files'].each do |fobj|
161
+ file = (files || []).select { |ff| ff['filename'] == fobj['uid'] }&.first
162
+ pa = uploads.select { |ss| ss[:uid] == file[:filename] }&.first || nil
163
+ next unless (tempfile = file[:tempfile])
164
+
165
+ a = Attachment.new(
166
+ bucket: file[:container_id],
167
+ filename: fobj['filename'],
168
+ con_state: Labimotion::ConState::NONE,
169
+ file_path: file[:tempfile],
170
+ created_by: user_id,
171
+ created_for: user_id,
172
+ content_type: file[:type],
173
+ attachable_type: map_info[key]['type'],
174
+ attachable_id: element.id,
175
+ )
176
+ begin
177
+ a.save!
178
+
179
+ update_properties_upload(element, element.properties, a, pa)
180
+ attach_ary.push(a.id)
181
+ ensure
182
+ tempfile.close
183
+ tempfile.unlink
184
+ end
185
+ end
186
+ element.send("#{type.downcase}s_revisions")&.last&.destroy!
187
+ element.save!
188
+ end
189
+ attach_ary
190
+ rescue => e
191
+ Labimotion.log_exception(e, current_user)
192
+ error!('Error while uploading files.', 500)
193
+ raise e
194
+ end
195
+
196
+ def create_attachments(files, del_files, type, id, user_id)
197
+ attach_ary = []
198
+ (files || []).each do |file|
199
+ next unless (tempfile = file[:tempfile])
200
+
201
+ a = Attachment.new(
202
+ bucket: file[:container_id],
203
+ filename: file[:filename],
204
+ con_state: Labimotion::ConState::NONE,
205
+ file_path: file[:tempfile],
206
+ created_by: user_id,
207
+ created_for: user_id,
208
+ content_type: file[:type],
209
+ attachable_type: type,
210
+ attachable_id: id,
211
+ )
212
+ begin
213
+ a.save!
214
+ attach_ary.push(a.id)
215
+ ensure
216
+ tempfile.close
217
+ tempfile.unlink
218
+ end
219
+ end
220
+ unless (del_files || []).empty?
221
+ Attachment.where('id IN (?) AND attachable_type = (?)', del_files.map!(&:to_i),
222
+ type).update_all(attachable_id: nil)
223
+ end
224
+ attach_ary
225
+ rescue => e
226
+ Labimotion.log_exception(e, current_user)
227
+ raise e
228
+ end
229
+
230
+ def fetch_repo_generic_template(klass, identifier)
231
+ Chemotion::Generic::Fetch::Template.exec(API::TARGET, klass, identifier)
232
+ end
233
+
234
+ def fetch_repo_generic_template_list(name = false)
235
+ Chemotion::Generic::Fetch::Template.list(API::TARGET, name)
236
+ end
237
+
238
+ def fetch_repo(name)
239
+ current_klasses = "Labimotion::#{name}".constantize.where.not(identifier: nil)&.pluck(:identifier) || []
240
+ response = Labimotion::TemplateHub.list(name)
241
+ if response && response['list'].present? && response['list'].length.positive?
242
+ filter_list = response['list']&.reject do |ds|
243
+ current_klasses.include?(ds['identifier'])
244
+ end || []
245
+ end
246
+ filter_list || []
247
+ rescue => e
248
+ Labimotion.log_exception(e, current_user)
249
+ raise e
250
+ end
251
+ end
252
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+ require 'grape'
3
+
4
+ module Labimotion
5
+ ## RepositoryHelpers
6
+ module RepositoryHelpers
7
+ extend Grape::API::Helpers
8
+
9
+ def copy_datsets(**args)
10
+ return if args[:dataset].nil?
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,126 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Labimotion
4
+ # Helper for associated sample
5
+ module SampleAssociationHelpers
6
+ extend Grape::API::Helpers
7
+
8
+ def build_sample(sid, cols, current_user, cr_opt)
9
+ parent_sample = Sample.find(sid)
10
+
11
+ case cr_opt
12
+ when 0
13
+ subsample = parent_sample
14
+ collections = Collection.where(id: cols).where.not(id: subsample.collections.pluck(:id))
15
+ subsample.collections << collections unless collections.empty?
16
+ when 1
17
+ subsample = parent_sample.create_subsample(current_user, cols, true)
18
+ when 2
19
+ subsample = parent_sample.dup
20
+ subsample.parent = nil
21
+ collections = (Collection.where(id: cols) | Collection.where(user_id: current_user.id, label: 'All', is_locked: true))
22
+ subsample.collections << collections
23
+ subsample.container = Container.create_root_container
24
+ else
25
+ return nil
26
+ end
27
+
28
+ return nil if subsample.nil?
29
+
30
+ subsample.save!
31
+ subsample.reload
32
+ subsample
33
+ rescue => e
34
+ Labimotion.log_exception(e, current_user)
35
+ nil
36
+ end
37
+
38
+ def build_table_sample(element, field_tables)
39
+ sds = []
40
+ field_tables.each do |field|
41
+ next unless field['sub_values'].present? && field['sub_fields'].present?
42
+
43
+ field_table_samples = field['sub_fields'].select { |ss| ss['type'] == 'drag_sample' }
44
+ next unless field_table_samples.present?
45
+
46
+ col_ids = field_table_samples.map { |x| x.values[0] }
47
+ col_ids.each do |col_id|
48
+ field['sub_values'].each do |sub_value|
49
+ next unless sub_value[col_id].present? && sub_value[col_id]['value'].present? && sub_value[col_id]['value']['el_id'].present?
50
+
51
+ svalue = sub_value[col_id]['value']
52
+ sid = svalue['el_id']
53
+ next unless sid.present?
54
+
55
+ sds << sid unless svalue['is_new']
56
+ next unless svalue['is_new']
57
+
58
+ cr_opt = svalue['cr_opt']
59
+
60
+ subsample = build_sample(sid, element.collections, current_user, cr_opt) unless sid.nil? || cr_opt.nil?
61
+ next if subsample.nil?
62
+
63
+ sds << subsample.id
64
+ sub_value[col_id]['value']['el_id'] = subsample.id
65
+ sub_value[col_id]['value']['is_new'] = false
66
+ Labimotion::ElementsSample.find_or_create_by(element_id: element.id, sample_id: subsample.id)
67
+ end
68
+ end
69
+ end
70
+ sds
71
+ rescue => e
72
+ Labimotion.log_exception(e, current_user)
73
+ []
74
+ end
75
+
76
+ def update_sample_association(element, properties, current_user)
77
+ sds = []
78
+ els = []
79
+ properties['layers'].keys.each do |key|
80
+ layer = properties['layers'][key]
81
+ field_samples = layer['fields'].select { |ss| ss['type'] == 'drag_sample' }
82
+ field_samples.each do |field|
83
+ idx = properties['layers'][key]['fields'].index(field)
84
+ sid = field.dig('value', 'el_id')
85
+ next if sid.blank?
86
+
87
+ sds << sid unless properties.dig('layers', key, 'fields', idx, 'value', 'is_new') == true
88
+ next unless properties.dig('layers', key, 'fields', idx, 'value', 'is_new') == true
89
+
90
+ cr_opt = field.dig('value', 'cr_opt')
91
+
92
+ subsample = build_sample(sid, element.collections, current_user, cr_opt) unless sid.nil? || cr_opt.nil?
93
+ next if subsample.nil?
94
+
95
+ sds << subsample.id
96
+ properties['layers'][key]['fields'][idx]['value']['el_id'] = subsample.id
97
+ properties['layers'][key]['fields'][idx]['value']['el_label'] = subsample.short_label
98
+ properties['layers'][key]['fields'][idx]['value']['el_tip'] = subsample.short_label
99
+ properties['layers'][key]['fields'][idx]['value']['is_new'] = false
100
+ Labimotion::ElementsSample.find_or_create_by(element_id: element.id, sample_id: subsample.id)
101
+ end
102
+ field_tables = properties['layers'][key]['fields'].select { |ss| ss['type'] == 'table' }
103
+ sds << build_table_sample(element, field_tables)
104
+
105
+ field_elements = layer['fields'].select { |ss| ss['type'] == 'drag_element' }
106
+ field_elements.each do |field|
107
+ idx = properties['layers'][key]['fields'].index(field)
108
+ sid = field.dig('value', 'el_id')
109
+ next if sid.blank? || sid == element.id
110
+
111
+ el = Labimotion::Element.find_by(id: sid)
112
+ next if el.nil?
113
+
114
+ Labimotion::ElementsElement.find_or_create_by(parent_id: element.id, element_id: el.id)
115
+ els << el.id
116
+ end
117
+
118
+ end
119
+ Labimotion::ElementsSample.where(element_id: element.id).where.not(sample_id: sds)&.destroy_all
120
+ Labimotion::ElementsElement.where(parent_id: element.id).where.not(element_id: els&.flatten)&.destroy_all
121
+ properties
122
+ rescue => e
123
+ Labimotion.log_exception(e, current_user)
124
+ end
125
+ end
126
+ end