labimotion 0.3.1 → 0.3.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5b8192a47d907ab3aab31d14c951ccfe6a9552f04cc57896dffc592d850c90d0
4
- data.tar.gz: 54be5a8e125a16ebbb8ee8ac48de31e42678c9473da2c7c2e32394585b746ffa
3
+ metadata.gz: 1e2976eacd1dbe12aa1caefd59638628b544d64ebd2757b677bc527e18230c1c
4
+ data.tar.gz: f1ee1381e67ab62bd66b4178f25346988c471b34c1da917e010e7753a83279ca
5
5
  SHA512:
6
- metadata.gz: 1cb3dd9177e8799a2a07c3454587f6ae7d925e99dd22ce0423a3513cf8992def50d7f900992d9c4db217617473b4ec87b0dcdc02551e3841ba66183efae6159d
7
- data.tar.gz: 595b810eee22f50e8ef15db20b2a8b37dc6ad14b2d05d0362568cd235be2cf7358b0ca089722ac09c364a57a5d9e64992fbba5afa342182f9647a602b292467e
6
+ metadata.gz: e8d3ca3477cfecd469e1d5e1a41be249a5b69da8647478ebd24a6144498dc5a110a4976f6cec56f10bc6fca013872dba164aa47be7402d511219a50d78ce8309
7
+ data.tar.gz: c6098201eb9ef587b0201e35c56b1146697e19dfead041aad7fb2b515ed4e38db2c00051508b0d631faeb979fc62edb287add0ad9be76c243da30d69d8230949
@@ -23,17 +23,20 @@ module Labimotion
23
23
  end
24
24
 
25
25
  def self.fetch_elements(collection, segments, attachments, fetch_many, fetch_one, fetch_containers)
26
- fetch_many.call(collection.elements, {
27
- 'element_klass_id' => 'Labimotion::ElementKlass',
28
- 'created_by' => 'User',
29
- })
30
- fetch_many.call(collection.collections_elements, {
31
- 'collection_id' => 'Collection',
32
- 'element_id' => 'Labimotion::Element',
33
- })
26
+ # fetch_many.call(collection.elements, {
27
+ # 'element_klass_id' => 'Labimotion::ElementKlass',
28
+ # 'created_by' => 'User',
29
+ # })
30
+ # fetch_many.call(collection.collections_elements, {
31
+ # 'collection_id' => 'Collection',
32
+ # 'element_id' => 'Labimotion::Element',
33
+ # })
34
34
  collection.elements.each do |element|
35
-
36
- element, attachments = Labimotion::Export.fetch_properties(element, attachments, &fetch_one)
35
+ element, attachments = Labimotion::Export.fetch_properties(data, element, attachments, &fetch_one)
36
+ fetch_one.call(element, {
37
+ 'element_klass_id' => 'Labimotion::ElementKlass',
38
+ 'created_by' => 'User',
39
+ })
37
40
  fetch_containers.call(element)
38
41
  segment, @attachments = Labimotion::Export.fetch_segments(element, attachments, &fetch_one)
39
42
  segments += segment if segment.present?
@@ -91,6 +94,15 @@ module Labimotion
91
94
  mol = Molecule.find(id) unless id.nil?
92
95
  properties['layers'][key]['fields'][idx]['value']['el_id'] = fetch_one.call(mol) unless mol.nil?
93
96
  end
97
+
98
+ field_samples = layer['fields'].select { |ss| ss['type'] == 'drag_sample' }
99
+ field_samples.each do |field|
100
+ # idx = properties['layers'][key]['fields'].index(field)
101
+ # id = field["value"] && field["value"]["el_id"] unless idx.nil?
102
+ # ss = Sample.find(id) unless id.nil?
103
+ # properties['layers'][key]['fields'][idx]['value']['el_id'] = fetch_one.call(ss) unless ss.nil?
104
+ end
105
+
94
106
  field_uploads = layer['fields'].select { |ss| ss['type'] == 'upload' }
95
107
  field_uploads.each do |upload|
96
108
  idx = properties['layers'][key]['fields'].index(upload)
@@ -123,7 +135,6 @@ module Labimotion
123
135
  end
124
136
  end
125
137
  end
126
-
127
138
  end
128
139
  instance.properties = properties
129
140
  [instance, attachments]
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'labimotion/utils/import_utils'
3
4
  module Labimotion
4
5
  class Import
5
6
 
@@ -50,7 +51,7 @@ module Labimotion
50
51
  element_type = fields.fetch('element_type')
51
52
  element = instances.fetch(element_type).fetch(element_uuid)
52
53
 
53
- dataset_klass = Labimotion::DatasetKlass.find_by(identifier: dk_id)
54
+ dataset_klass = Labimotion::DatasetKlass.find_by(identifier: dk_id) if dk_id.present?
54
55
  next if gt == true && dataset_klass.nil?
55
56
 
56
57
  dkr = Labimotion::DatasetKlassesRevision.find_by(uuid: fields.fetch('klass_uuid'))
@@ -88,33 +89,21 @@ module Labimotion
88
89
  ek_obj = data.fetch('Labimotion::ElementKlass').fetch(sk_obj["element_klass_id"])
89
90
  element_klass = Labimotion::ElementKlass.find_by(name: ek_obj['name']) if ek_obj.present?
90
91
  next if element_klass.nil? || ek_obj.nil? || ek_obj['is_generic'] == true
92
+
91
93
  element_uuid = fields.fetch('element_id')
92
94
  element_type = fields.fetch('element_type')
93
95
  element = instances.fetch(element_type).fetch(element_uuid)
94
- segment_klass = Labimotion::SegmentKlass.find_by(identifier: sk_id)
95
- next if gt == true && segment_klass.nil?
96
-
97
- skr = Labimotion::SegmentKlassesRevision.find_by(uuid: fields.fetch('klass_uuid'))
98
- segment_klass = skr.segment_klass if segment_klass.nil? && skr.present?
99
-
100
- # segment_klass = Labimotion::SegmentKlass.create!(sk_obj.slice(
101
- # 'label',
102
- # 'desc',
103
- # 'properties_template',
104
- # 'is_active',
105
- # 'place',
106
- # 'properties_release',
107
- # 'uuid',
108
- # 'identifier',
109
- # 'sync_time'
110
- # ).merge(
111
- # element_klass: element_klass,
112
- # created_by: current_user_id,
113
- # released_at: DateTime.now
114
- # )
115
- # ) if segment_klass.nil?
116
-
117
- next if segment_klass.nil?
96
+ segment_klass = Labimotion::SegmentKlass.find_by(identifier: sk_id) if sk_id.present?
97
+ segment_klass = Labimotion::SegmentKlass.find_by(uuid: fields.fetch('klass_uuid')) if segment_klass.nil?
98
+
99
+ if segment_klass.nil?
100
+ skr = Labimotion::SegmentKlassesRevision.find_by(uuid: fields.fetch('klass_uuid'))
101
+ segment_klass = skr.segment_klass if segment_klass.nil? && skr.present?
102
+ end
103
+
104
+ next if segment_klass.nil? || element.nil?
105
+
106
+ ## segment_klass = Labimotion::ImportUtils.create_segment_klass(sk_obj, segment_klass, element_klass, current_user_id)
118
107
 
119
108
  segment = Labimotion::Segment.create!(
120
109
  fields.slice(
@@ -128,52 +117,7 @@ module Labimotion
128
117
  )
129
118
  )
130
119
 
131
- properties = segment.properties
132
- properties['layers'].keys.each do |key|
133
- layer = properties['layers'][key]
134
- field_molecules = layer['fields'].select { |ss| ss['type'] == 'drag_molecule' }
135
- field_molecules.each do |field|
136
- idx = properties['layers'][key]['fields'].index(field)
137
- id = field["value"] && field["value"]["el_id"] unless idx.nil?
138
- mol = Molecule.find_or_create_by_molfile(data.fetch('Molecule')[id]['molfile']) unless id.nil?
139
- unless mol.nil?
140
- properties['layers'][key]['fields'][idx]['value']['el_id'] = mol.id
141
- properties['layers'][key]['fields'][idx]['value']['el_tip'] = "#{mol.inchikey}@@#{mol.cano_smiles}"
142
- properties['layers'][key]['fields'][idx]['value']['el_label'] = mol.iupac_name
143
- end
144
- end
145
-
146
- field_tables = layer['fields'].select { |ss| ss['type'] == 'table' }
147
- field_tables&.each do |field|
148
- tidx = layer['fields'].index(field)
149
- next unless field['sub_values'].present? && field['sub_fields'].present?
150
-
151
- field_table_molecules = field['sub_fields'].select { |ss| ss['type'] == 'drag_molecule' }
152
- if field_table_molecules.present?
153
- col_ids = field_table_molecules.map { |x| x.values[0] }
154
- col_ids.each do |col_id|
155
- field['sub_values'].each_with_index do |sub_value, vdx|
156
- next unless sub_value[col_id].present? && sub_value[col_id]['value'].present? && sub_value[col_id]['value']['el_id'].present?
157
-
158
- svalue = sub_value[col_id]['value']
159
- next unless svalue['el_id'].present? && svalue['el_inchikey'].present?
160
-
161
- tmol = Molecule.find_or_create_by_molfile(data.fetch('Molecule')[svalue['el_id']]['molfile']) unless svalue['el_id'].nil?
162
- unless tmol.nil?
163
- properties['layers'][key]['fields'][tidx]['sub_values'][vdx][col_id]['value']['el_id'] = tmol.id
164
- properties['layers'][key]['fields'][tidx]['sub_values'][vdx][col_id]['value']['el_tip'] = "#{tmol.inchikey}@@#{tmol.cano_smiles}"
165
- properties['layers'][key]['fields'][tidx]['sub_values'][vdx][col_id]['value']['el_label'] = tmol.cano_smiles
166
- properties['layers'][key]['fields'][tidx]['sub_values'][vdx][col_id]['value']['el_smiles'] = tmol.cano_smiles
167
- properties['layers'][key]['fields'][tidx]['sub_values'][vdx][col_id]['value']['el_iupac'] = tmol.iupac_name
168
- properties['layers'][key]['fields'][tidx]['sub_values'][vdx][col_id]['value']['el_inchikey'] = tmol.inchikey
169
- properties['layers'][key]['fields'][tidx]['sub_values'][vdx][col_id]['value']['el_svg'] = File.join('/images', 'molecules', tmol.molecule_svg_file)
170
- properties['layers'][key]['fields'][tidx]['sub_values'][vdx][col_id]['value']['el_molecular_weight'] = tmol.molecular_weight
171
- end
172
- end
173
- end
174
- end
175
- end
176
- end
120
+ properties = Labimotion::ImportUtils.properties_handler(data, segment.properties)
177
121
  segment.update!(properties: properties)
178
122
  update_instances.call(uuid, segment)
179
123
  end
@@ -182,5 +126,43 @@ module Labimotion
182
126
  raise
183
127
  end
184
128
  end
129
+
130
+ def self.import_elements(data, instances, gt, current_user_id, fetch_many, &update_instances)
131
+ data.fetch('Labimotion::Element', {}).each do |uuid, fields|
132
+ klass_id = fields["element_klass_id"]
133
+ ek_obj = data.fetch('Labimotion::ElementKlass', {})[klass_id]
134
+ ek_id = ek_obj["identifier"]
135
+ element_klass = Labimotion::ElementKlass.find_by(identifier: ek_id) if ek_id.present?
136
+ element_klass = Labimotion::ElementKlass.find_by(uuid: fields.fetch('klass_uuid')) if element_klass.nil?
137
+
138
+ if element_klass.nil?
139
+ ekr = Labimotion::ElementKlassesRevision.find_by(uuid: fields.fetch('klass_uuid'))
140
+ element_klass = ekr.element_klass if element_klass.nil? && ekr.present?
141
+ end
142
+ next if element_klass.nil?
143
+
144
+ element = Labimotion::Element.create!(
145
+ fields.slice(
146
+ 'name', 'properties', 'properties_release'
147
+ ).merge(
148
+ created_by: current_user_id,
149
+ element_klass: element_klass,
150
+ collections: fetch_many.call(
151
+ 'Collection', 'Labimotion::CollectionsElement', 'element_id', 'collection_id', uuid
152
+ ),
153
+ uuid: SecureRandom.uuid,
154
+ klass_uuid: ekr&.uuid || element_klass.uuid
155
+ )
156
+ )
157
+
158
+ properties = Labimotion::ImportUtils.properties_handler(data, element.properties)
159
+ element.update!(properties: properties)
160
+ update_instances.call(uuid, element)
161
+ element.container = Container.create_root_container
162
+ end
163
+ rescue StandardError => e
164
+ Rails.logger.error(e.backtrace)
165
+ raise
166
+ end
185
167
  end
186
168
  end
@@ -15,6 +15,7 @@ module Labimotion
15
15
  expose! :properties
16
16
  expose! :properties_release
17
17
  expose! :short_label
18
+ expose! :thumb_svg
18
19
  expose! :type
19
20
  expose! :uuid
20
21
  end
@@ -14,11 +14,38 @@ require 'labimotion/utils/utils'
14
14
 
15
15
  module Labimotion
16
16
  class Converter
17
-
18
17
  def self.logger
19
18
  @@converter_logger ||= Logger.new(Rails.root.join('log/converter.log')) # rubocop:disable Style/ClassVars
20
19
  end
21
20
 
21
+ def self.process_ds(id, current_user = {})
22
+ att = Attachment.find_by(id: id, con_state: Labimotion::ConState::CONVERTED)
23
+ return if att.nil? || att.attachable_id.nil? || att.attachable_type != 'Container'
24
+
25
+ dsr = []
26
+ ols = nil
27
+ if Labimotion::IS_RAILS5 == true
28
+ Zip::File.open(att.store.path) do |zip_file|
29
+ res = Labimotion::Converter.collect_metadata(zip_file) if att.filename.split('.')&.last == 'zip'
30
+ ols = res[:o] unless res&.dig(:o).nil?
31
+ dsr.push(res[:d]) unless res&.dig(:d).nil?
32
+ end
33
+ else
34
+ Zip::File.open(att.attachment_attacher.file.url) do |zip_file|
35
+ res = Labimotion::Converter.collect_metadata(zip_file) if att.filename.split('.')&.last == 'zip'
36
+ ols = res[:o] unless res&.dig(:o).nil?
37
+ dsr.push(res[:d]) unless res&.dig(:d).nil?
38
+ end
39
+ end
40
+ dsr.flatten!
41
+ dataset = build_ds(att.attachable_id, ols)
42
+ update_ds(dataset, dsr, current_user) if dataset.present?
43
+ att.update_column(:con_state, Labimotion::ConState::COMPLETED)
44
+ rescue StandardError => e
45
+ Labimotion::Converter.logger.error ["Att ID: #{att&.id}, OLS: #{ols}", "DSR: #{dsr}", e.message, *e.backtrace].join($INPUT_RECORD_SEPARATOR)
46
+ raise e
47
+ end
48
+
22
49
  def self.uri(api_name)
23
50
  url = Rails.configuration.converter.url
24
51
  "#{url}#{api_name}"
@@ -125,17 +152,7 @@ module Labimotion
125
152
  primary_store = Rails.configuration.storage.primary_store
126
153
  att.update!(storage: primary_store)
127
154
  end
128
-
129
- Zip::File.open(tmp_file.path) do |zip_file|
130
- res = Labimotion::Converter.collect_metadata(zip_file) if name.split('.')&.last == 'zip'
131
- ols = res[:o] unless res&.dig(:o).nil?
132
- dsr.push(res[:d]) unless res&.dig(:d).nil?
133
- end
134
-
135
- dsr.flatten!
136
- if dsr.length.positive? && name.split('.')&.last == 'zip'
137
- Labimotion::Converter.ts('write', att.attachable_id, ols: ols, info: dsr)
138
- end
155
+ process_ds(att.id)
139
156
  rescue StandardError => e
140
157
  raise e
141
158
  ensure
@@ -179,25 +196,22 @@ module Labimotion
179
196
  end
180
197
 
181
198
  def self.jcamp_converter(id)
182
- resp = nil
183
- begin
184
-
185
- data = Labimotion::Converter.vor_conv(id)
186
- return if data.nil?
199
+ data = Labimotion::Converter.vor_conv(id)
200
+ return if data.nil?
187
201
 
188
- Labimotion::Converter.process(data)
189
- rescue StandardError => e
190
- Labimotion::Converter.logger.error ["jcamp_converter fail: #{id}", e.message, *e.backtrace].join($INPUT_RECORD_SEPARATOR)
191
- Labimotion::ConState::ERROR
192
- end
202
+ Labimotion::Converter.process(data)
203
+ rescue StandardError => e
204
+ Labimotion::Converter.logger.error ["jcamp_converter fail: #{id}", e.message, *e.backtrace].join($INPUT_RECORD_SEPARATOR)
205
+ Labimotion::ConState::ERROR
193
206
  end
194
207
 
195
208
  def self.generate_ds(att_id, current_user = {})
196
209
  dsr_info = Labimotion::Converter.fetch_dsr(att_id)
197
210
  begin
198
211
  return unless dsr_info && dsr_info[:info]&.length.positive?
212
+
199
213
  dataset = Labimotion::Converter.build_ds(att_id, dsr_info[:ols])
200
- Labimotion::Converter.update_ds(dataset, dsr_info[:info], current_user)
214
+ Labimotion::Converter.update_ds(dataset, dsr_info[:info], current_user) if dataset.present?
201
215
  rescue StandardError => e
202
216
  Labimotion::Converter.logger.error ["Att ID: #{att_id}, OLS: #{dsr_info[:ols]}", "DSR: #{dsr_info[:info]}", e.message, *e.backtrace].join($INPUT_RECORD_SEPARATOR)
203
217
  ensure
@@ -325,6 +339,15 @@ module Labimotion
325
339
  end
326
340
  res
327
341
  end
342
+
343
+ def self.metadata(id)
344
+ att = Attachment.find(id)
345
+ return if att.nil? || att.attachable_id.nil? || att.attachable_type != 'Container'
346
+
347
+ ds = Labimotion::Dataset.find_by(element_type: 'Container', element_id: att.attachable_id)
348
+ att.update_column(:con_state, Labimotion::ConState::COMPLETED) if ds.present?
349
+ process_ds(att.id) if ds.nil?
350
+ end
328
351
  end
329
352
  end
330
353
 
@@ -27,7 +27,7 @@ module Labimotion
27
27
  name = ds.dataset_klass.label
28
28
 
29
29
  match = name.match(/\((.*?)\)/)
30
- name = match && match.length > 2 ? match[1] : name
30
+ name = match && match.length > 1 ? match[1] : name
31
31
 
32
32
  name = '1H NMR' if ds.dataset_klass.ols_term_id == 'CHMO:0000593'
33
33
  name = '13C NMR' if ds.dataset_klass.ols_term_id == 'CHMO:0000595'
@@ -99,9 +99,14 @@ module Labimotion
99
99
  wb = @xfile.workbook
100
100
  gds = Labimotion::Dataset.find_by(element_id: id, element_type: 'Container')
101
101
  cds = Container.find(id)
102
- cds.attachments.where(aasm_state: 'csv').each do |att|
102
+ cds_csv = cds.attachments.where(aasm_state: 'csv')
103
+ csv_length = cds_csv.length
104
+ return if csv_length.zero?
105
+ cds_csv.each_with_index do |att, idx|
103
106
  name = File.basename(att.filename, '.csv')
104
- sheet = @xfile.workbook.add_worksheet(name: name.slice(0, 25))
107
+ name = name.slice(0, (25 - csv_length.to_s.length - 1))
108
+ sheet_name = "#{name}_#{idx}"
109
+ sheet = @xfile.workbook.add_worksheet(name: sheet_name)
105
110
 
106
111
  if Labimotion::IS_RAILS5 == true
107
112
  File.open(att.store.path) do |fi|
@@ -6,8 +6,24 @@ require 'labimotion/utils/utils'
6
6
  module Labimotion
7
7
  ## NmrMapper
8
8
  class NmrMapper
9
+ def self.process_ds(id, current_user = {})
10
+ att = Attachment.find_by(id: id, con_state: Labimotion::ConState::NMR)
11
+ return if att.nil?
12
+
13
+ content = is_brucker_binary(id)
14
+ if content.nil?
15
+ Labimotion::ConState::NONE
16
+ else
17
+ data = process(att, id, content)
18
+ generate_ds(id, att.attachable_id, data, current_user)
19
+ Labimotion::ConState::COMPLETED
20
+ end
21
+ end
22
+
9
23
  def self.is_brucker_binary(id)
10
- att = Attachment.find(id)
24
+ att = Attachment.find_by(id: id, con_state: Labimotion::ConState::NMR)
25
+ return if att.nil?
26
+
11
27
  if Labimotion::IS_RAILS5 == true
12
28
  Zip::File.open(att.store.path) do |zip_file|
13
29
  zip_file.each do |entry|
@@ -32,8 +48,9 @@ module Labimotion
32
48
  nil
33
49
  end
34
50
 
35
- def self.process(id, content)
36
- att = Attachment.find(id)
51
+ def self.process(att, id, content)
52
+ return if att.nil? || content.nil?
53
+
37
54
  lines = content.split("\n").reject(&:empty?)
38
55
  metadata = {}
39
56
  lines.map do |ln|
@@ -42,26 +59,33 @@ module Labimotion
42
59
  end
43
60
  ols = 'CHMO:0000593' if metadata['NUC1'] == '1H'
44
61
  ols = 'CHMO:0000595' if metadata['NUC1'] == '13C'
45
- if content.present? && att.present?
46
- Labimotion::NmrMapper.ts('write', att.attachable_id,
47
- content: { metadata: metadata, ols: ols })
48
- end
62
+
63
+ { content: { metadata: metadata, ols: ols } }
64
+ # if content.present? && att.present?
65
+ # Labimotion::NmrMapper.ts('write', att.attachable_id,
66
+ # content: { metadata: metadata, ols: ols })
67
+ # end
49
68
  end
50
69
 
51
70
  def self.fetch_content(id)
52
- Labimotion::NmrMapper.ts('read', id)
71
+ atts = Attachment.where(attachable_id: id)
72
+ return if atts.nil?
73
+
74
+ atts.each do |att|
75
+ content = Labimotion::NmrMapper.ts('read', att.id)
76
+ return content if content.present?
77
+ end
53
78
  end
54
79
 
55
- def self.generate_ds(id, current_user = {})
56
- data = Labimotion::NmrMapper.fetch_content(id)
57
- return if data.nil?
58
80
 
59
- obj = Labimotion::NmrMapper.build_ds(id, data[:content])
81
+ def self.generate_ds(id, cid, data, current_user = {})
82
+ return if data.nil? || cid.nil?
83
+
84
+ obj = Labimotion::NmrMapper.build_ds(cid, data[:content])
60
85
  return if obj.nil? || obj[:ols].nil?
61
86
 
62
- Labimotion::NmrMapper.update_ds_1h(id, obj, current_user) if obj[:ols] == 'CHMO:0000593'
63
- Labimotion::NmrMapper.update_ds_1h(id, obj, current_user) if obj[:ols] == 'CHMO:0000595'
64
- Labimotion::NmrMapper.clean(id)
87
+ Labimotion::NmrMapper.update_ds_1h(cid, obj, current_user) if obj[:ols] == 'CHMO:0000593'
88
+ Labimotion::NmrMapper.update_ds_1h(cid, obj, current_user) if obj[:ols] == 'CHMO:0000595'
65
89
  end
66
90
 
67
91
  def self.update_ds_13c(id, obj)
@@ -10,6 +10,7 @@ module Labimotion
10
10
  after_update :exec_converter
11
11
  def init_converter
12
12
  return if self.has_attribute?(:con_state) == false || con_state.present?
13
+
13
14
  if Rails.configuration.try(:converter).try(:url) && ACCEPTED_FORMATS.include?(File.extname(filename&.downcase))
14
15
  self.con_state = Labimotion::ConState::WAIT
15
16
  end
@@ -22,21 +23,20 @@ module Labimotion
22
23
  end
23
24
 
24
25
  def exec_converter
25
- #return if attachable_id.nil?
26
- return if self.has_attribute?(:con_state) == false || con_state.nil? || con_state == Labimotion::ConState::NONE
26
+ return if self.has_attribute?(:con_state) == false || self.con_state.nil? || self.con_state == Labimotion::ConState::NONE
27
+
28
+ return if attachable_id.nil? && self.con_state != Labimotion::ConState::WAIT
29
+
27
30
  case con_state
28
31
  when Labimotion::ConState::NMR
29
- content = Labimotion::NmrMapperRepo.is_brucker_binary(id)
30
- if content.nil?
31
- self.con_state = Labimotion::ConState::NONE
32
- else
33
- Labimotion::NmrMapperRepo.process(id, content)
34
- self.con_state = Labimotion::ConState::PROCESSED
35
- end
32
+ self.con_state = Labimotion::NmrMapper.process_ds(id)
33
+ update_column(:con_state, con_state)
36
34
  when Labimotion::ConState::WAIT
37
35
  self.con_state = Labimotion::Converter.jcamp_converter(id)
36
+ update_column(:con_state, con_state)
37
+ when Labimotion::ConState::CONVERTED
38
+ Labimotion::Converter.metadata(id)
38
39
  end
39
- update_column(:con_state, con_state)
40
40
  end
41
41
  end
42
42
  end
@@ -101,13 +101,20 @@ module Labimotion
101
101
  end
102
102
 
103
103
  def thumb_svg
104
- image_atts = attachments.select do |a_img|
105
- a_img&.content_type&.match(Regexp.union(%w[jpg jpeg png tiff tif]))
106
- end
104
+ if Labimotion::IS_RAILS5 == true
105
+ image_atts = attachments.select do |a_img|
106
+ a_img&.content_type&.match(Regexp.union(%w[jpg jpeg png tiff tif]))
107
+ end
107
108
 
108
- attachment = image_atts[0] || attachments[0]
109
- preview = attachment.read_thumbnail if attachment
110
- preview && Base64.encode64(preview) || 'not available'
109
+ attachment = image_atts[0] || attachments[0]
110
+ preview = attachment.read_thumbnail if attachment
111
+ preview && Base64.encode64(preview) || 'not available'
112
+ else
113
+ image_atts = attachments.select(&:type_image?)
114
+ attachment = image_atts[0] || attachments[0]
115
+ preview = attachment&.read_thumbnail
116
+ (preview && Base64.encode64(preview)) || 'not available'
117
+ end
111
118
  end
112
119
 
113
120
 
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Labimotion
4
+ ## Import Utils
5
+ class ImportUtils
6
+ def self.proc_sample(layer, key, data, properties)
7
+ field_samples = layer['fields'].select { |ss| ss['type'] == 'drag_sample' }
8
+ field_samples.each do |field|
9
+ idx = properties['layers'][key]['fields'].index(field)
10
+ id = field["value"] && field["value"]["el_id"] unless idx.nil?
11
+
12
+ # mol = Molecule.find_or_create_by_molfile(data.fetch('Molecule')[id]['molfile']) unless id.nil?
13
+ # unless mol.nil?
14
+ # properties['layers'][key]['fields'][idx]['value']['el_id'] = mol.id
15
+ # properties['layers'][key]['fields'][idx]['value']['el_tip'] = "#{mol.inchikey}@@#{mol.cano_smiles}"
16
+ # properties['layers'][key]['fields'][idx]['value']['el_label'] = mol.iupac_name
17
+ # end
18
+ end
19
+ properties
20
+ rescue StandardError => e
21
+ Rails.logger.error(e.backtrace)
22
+ raise
23
+ end
24
+
25
+ def self.proc_molecule(layer, key, data, properties)
26
+ field_molecules = layer['fields'].select { |ss| ss['type'] == 'drag_molecule' }
27
+ field_molecules.each do |field|
28
+ idx = properties['layers'][key]['fields'].index(field)
29
+ id = field["value"] && field["value"]["el_id"] unless idx.nil?
30
+ mol = Molecule.find_or_create_by_molfile(data.fetch('Molecule')[id]['molfile']) unless id.nil?
31
+ unless mol.nil?
32
+ properties['layers'][key]['fields'][idx]['value']['el_id'] = mol.id
33
+ properties['layers'][key]['fields'][idx]['value']['el_tip'] = "#{mol.inchikey}@@#{mol.cano_smiles}"
34
+ properties['layers'][key]['fields'][idx]['value']['el_label'] = mol.iupac_name
35
+ end
36
+ end
37
+ properties
38
+ rescue StandardError => e
39
+ Rails.logger.error(e.backtrace)
40
+ raise
41
+ end
42
+
43
+ def self.proc_table(layer, key, data, properties)
44
+ field_tables = layer['fields'].select { |ss| ss['type'] == 'table' }
45
+ field_tables&.each do |field|
46
+ tidx = layer['fields'].index(field)
47
+ next unless field['sub_values'].present? && field['sub_fields'].present?
48
+
49
+ field_table_molecules = field['sub_fields'].select { |ss| ss['type'] == 'drag_molecule' }
50
+ if field_table_molecules.present?
51
+ col_ids = field_table_molecules.map { |x| x.values[0] }
52
+ col_ids.each do |col_id|
53
+ field['sub_values'].each_with_index do |sub_value, vdx|
54
+ next unless sub_value[col_id].present? && sub_value[col_id]['value'].present? && sub_value[col_id]['value']['el_id'].present?
55
+
56
+ svalue = sub_value[col_id]['value']
57
+ next unless svalue['el_id'].present? && svalue['el_inchikey'].present?
58
+
59
+ tmol = Molecule.find_or_create_by_molfile(data.fetch('Molecule')[svalue['el_id']]['molfile']) unless svalue['el_id'].nil?
60
+ unless tmol.nil?
61
+ properties['layers'][key]['fields'][tidx]['sub_values'][vdx][col_id]['value']['el_id'] = tmol.id
62
+ properties['layers'][key]['fields'][tidx]['sub_values'][vdx][col_id]['value']['el_tip'] = "#{tmol.inchikey}@@#{tmol.cano_smiles}"
63
+ properties['layers'][key]['fields'][tidx]['sub_values'][vdx][col_id]['value']['el_label'] = tmol.cano_smiles
64
+ properties['layers'][key]['fields'][tidx]['sub_values'][vdx][col_id]['value']['el_smiles'] = tmol.cano_smiles
65
+ properties['layers'][key]['fields'][tidx]['sub_values'][vdx][col_id]['value']['el_iupac'] = tmol.iupac_name
66
+ properties['layers'][key]['fields'][tidx]['sub_values'][vdx][col_id]['value']['el_inchikey'] = tmol.inchikey
67
+ properties['layers'][key]['fields'][tidx]['sub_values'][vdx][col_id]['value']['el_svg'] = File.join('/images', 'molecules', tmol.molecule_svg_file)
68
+ properties['layers'][key]['fields'][tidx]['sub_values'][vdx][col_id]['value']['el_molecular_weight'] = tmol.molecular_weight
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ properties
75
+ rescue StandardError => e
76
+ Rails.logger.error(e.backtrace)
77
+ raise
78
+ end
79
+
80
+ def self.properties_handler(data, properties)
81
+ properties && properties['layers'] && properties['layers'].keys&.each do |key|
82
+ layer = properties['layers'][key]
83
+ properties = proc_molecule(layer, key, data, properties)
84
+ properties = proc_table(layer, key, data, properties)
85
+ # properties = proc_sample(layer, key, data, properties)
86
+ end
87
+ properties
88
+ rescue StandardError => e
89
+ Rails.logger.error(e.backtrace)
90
+ raise
91
+ end
92
+
93
+ def self.create_segment_klass(sk_obj, segment_klass, element_klass, current_user_id)
94
+ return if segment_klass.present? || element_klass.nil? || sk_obj.nil?
95
+
96
+ segment_klass = Labimotion::SegmentKlass.create!(sk_obj.slice(
97
+ 'label',
98
+ 'desc',
99
+ 'properties_template',
100
+ 'is_active',
101
+ 'place',
102
+ 'properties_release',
103
+ 'uuid',
104
+ 'identifier',
105
+ 'sync_time'
106
+ ).merge(
107
+ element_klass: element_klass,
108
+ created_by: current_user_id,
109
+ released_at: DateTime.now
110
+ )
111
+ )
112
+
113
+ segment_klass
114
+ end
115
+ end
116
+ end
@@ -1,7 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ ## Labimotion Version
3
4
  module Labimotion
4
5
  IS_RAILS5 = true
5
- VERSION = '0.3.1' if Labimotion::IS_RAILS5 == true
6
- VERSION = '1.0.7' if Labimotion::IS_RAILS5 == false
6
+ VERSION_ELN = '1.0.17'
7
+ VERSION_REPO = '0.3.3'
8
+
9
+ VERSION = Labimotion::VERSION_REPO if Labimotion::IS_RAILS5 == true
10
+ VERSION = Labimotion::VERSION_ELN if Labimotion::IS_RAILS5 == false
7
11
  end
data/lib/labimotion.rb CHANGED
@@ -61,8 +61,11 @@ module Labimotion
61
61
  autoload :ConState, 'labimotion/utils/con_state'
62
62
  autoload :Serializer, 'labimotion/utils/serializer'
63
63
  autoload :Search, 'labimotion/utils/search'
64
- autoload :Export, 'labimotion/utils/export'
65
- autoload :Import, 'labimotion/utils/import'
64
+
65
+
66
+ ######## Collection
67
+ autoload :Export, 'labimotion/collection/export'
68
+ autoload :Import, 'labimotion/collection/import'
66
69
 
67
70
  ######## Models
68
71
  autoload :Element, 'labimotion/models/element'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: labimotion
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chia-Lin Lin
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2023-09-10 00:00:00.000000000 Z
12
+ date: 2023-10-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -34,12 +34,13 @@ extensions: []
34
34
  extra_rdoc_files: []
35
35
  files:
36
36
  - lib/labimotion.rb
37
- - lib/labimotion/api.rb
38
37
  - lib/labimotion/apis/converter_api.rb
39
38
  - lib/labimotion/apis/generic_dataset_api.rb
40
39
  - lib/labimotion/apis/generic_element_api.rb
41
40
  - lib/labimotion/apis/labimotion_hub_api.rb
42
41
  - lib/labimotion/apis/segment_api.rb
42
+ - lib/labimotion/collection/export.rb
43
+ - lib/labimotion/collection/import.rb
43
44
  - lib/labimotion/entities/application_entity.rb
44
45
  - lib/labimotion/entities/dataset_entity.rb
45
46
  - lib/labimotion/entities/dataset_klass_entity.rb
@@ -65,7 +66,6 @@ files:
65
66
  - lib/labimotion/libs/converter.rb
66
67
  - lib/labimotion/libs/export_dataset.rb
67
68
  - lib/labimotion/libs/nmr_mapper.rb
68
- - lib/labimotion/libs/nmr_mapper_repo.rb
69
69
  - lib/labimotion/libs/template_hub.rb
70
70
  - lib/labimotion/models/collections_element.rb
71
71
  - lib/labimotion/models/concerns/attachment_converter.rb
@@ -90,15 +90,14 @@ files:
90
90
  - lib/labimotion/models/segment_klasses_revision.rb
91
91
  - lib/labimotion/models/segments_revision.rb
92
92
  - lib/labimotion/utils/con_state.rb
93
- - lib/labimotion/utils/export.rb
94
- - lib/labimotion/utils/import.rb
93
+ - lib/labimotion/utils/import_utils.rb
95
94
  - lib/labimotion/utils/search.rb
96
95
  - lib/labimotion/utils/serializer.rb
97
96
  - lib/labimotion/utils/utils.rb
98
97
  - lib/labimotion/version.rb
99
- homepage: https://github.com/phuang26/labimotion
98
+ homepage: https://gitlab.kit.edu/kit/labimotion/labimotion
100
99
  licenses:
101
- - MIT
100
+ - GPL-3.0
102
101
  metadata: {}
103
102
  post_install_message:
104
103
  rdoc_options: []
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- ## This is the first version of the dataset class
4
- module Labimotion
5
- ## This is the first version of the dataset class
6
- class Api
7
- def initialize
8
- # Initialization code
9
- end
10
-
11
- def gget_data
12
- 'Hello, worlddddddddddddddddddddd!'
13
- end
14
-
15
- def self.hello
16
- 'Hellooooooooooooooooooooo!'
17
- end
18
- end
19
- end
@@ -1,278 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'labimotion/version'
3
- require 'labimotion/utils/utils'
4
-
5
- module Labimotion
6
- class NmrMapperRepo
7
- def self.is_brucker_binary(id)
8
- att = Attachment.find(id)
9
- if Labimotion::IS_RAILS5 == true
10
- Zip::File.open(att.store.path) do |zip_file|
11
- zip_file.each do |entry|
12
- if entry.name.include?('/pdata/') && entry.name.include?('parm.txt')
13
- metadata = entry.get_input_stream.read.force_encoding('UTF-8')
14
- return metadata
15
- end
16
- end
17
- end
18
- else
19
- if att&.attachment_attacher&.file&.url
20
- Zip::File.open(att.attachment_attacher.file.url) do |zip_file|
21
- zip_file.each do |entry|
22
- if entry.name.include?('/pdata/') && entry.name.include?('parm.txt')
23
- metadata = entry.get_input_stream.read.force_encoding('UTF-8')
24
- return metadata
25
- end
26
- end
27
- end
28
- end
29
- end
30
-
31
- nil
32
- end
33
-
34
- def self.process(id, content)
35
- att = Attachment.find(id)
36
- lines = content.split("\n").reject(&:empty?)
37
- metadata = {}
38
- lines.map do |ln|
39
- arr = ln.split(/\s+/)
40
- metadata[arr[0]] = arr[1..-1].join(' ') if arr.length > 1
41
- end
42
- ols = 'CHMO:0000593' if metadata['NUC1'] == '1H'
43
- ols = 'CHMO:0000595' if metadata['NUC1'] == '13C'
44
- if content.present? && att.present?
45
- Labimotion::NmrMapper.ts('write', att.attachable_id,
46
- content: { metadata: metadata, ols: ols })
47
- end
48
- end
49
-
50
- def self.fetch_content(id)
51
- Labimotion::NmrMapper.ts('read', id)
52
- end
53
-
54
- def self.generate_ds(id, current_user = {})
55
- data = Labimotion::NmrMapper.fetch_content(id)
56
- return if data.nil?
57
-
58
- obj = Labimotion::NmrMapper.build_ds(id, data[:content])
59
- return if obj.nil? || obj[:ols].nil?
60
-
61
- Labimotion::NmrMapper.update_ds_1h(id, obj, current_user) if obj[:ols] == 'CHMO:0000593'
62
- Labimotion::NmrMapper.update_ds_1h(id, obj, current_user) if obj[:ols] == 'CHMO:0000595'
63
- Labimotion::NmrMapper.clean(id)
64
- end
65
-
66
- def self.update_ds_13c(id, obj)
67
- # dataset = obj[:dataset]
68
- # metadata = obj[:metadata]
69
- # new_prop = dataset.properties
70
-
71
- # dataset.properties = new_prop
72
- # dataset.save!
73
- end
74
-
75
- def self.set_data(prop, field, idx, layer_name, field_name, value)
76
- return if field['field'] != field_name || value&.empty?
77
-
78
- field['value'] = value
79
- prop['layers'][layer_name]['fields'][idx] = field
80
- prop
81
- end
82
-
83
- def self.update_ds_1h(id, obj, current_user)
84
- dataset = obj[:dataset]
85
- metadata = obj[:metadata]
86
- new_prop = dataset.properties
87
- new_prop.dig('layers', 'general', 'fields')&.each_with_index do |fi, idx|
88
- # new_prop = set_data(new_prop, fi, idx, 'general', 'title', metadata['NAME'])
89
- if fi['field'] == 'title' && metadata['NAME'].present?
90
- ## fi['label'] = fi['label']
91
- fi['value'] = metadata['NAME']
92
- fi['device'] = metadata['NAME']
93
- fi['dkey'] = 'NAME'
94
- new_prop['layers']['general']['fields'][idx] = fi
95
- end
96
-
97
- if fi['field'] == 'date' && metadata['Date_'].present?
98
- ## fi['label'] = fi['label']
99
- fi['value'] = metadata['Date_']
100
- fi['device'] = metadata['Date_']
101
- fi['dkey'] = 'Date_'
102
- new_prop['layers']['general']['fields'][idx] = fi
103
- end
104
-
105
- if fi['field'] == 'time' && metadata['Time'].present?
106
- ## fi['label'] = fi['label']
107
- fi['value'] = metadata['Time']
108
- fi['device'] = metadata['Time']
109
- fi['dkey'] = 'Time'
110
- new_prop['layers']['general']['fields'][idx] = fi
111
- end
112
-
113
- if fi['field'] == 'creator' && current_user.present?
114
- ## fi['label'] = fi['label']
115
- fi['value'] = current_user.name
116
- new_prop['layers']['general']['fields'][idx] = fi
117
- end
118
- end
119
- element = Container.find(id)&.root_element
120
- element.present? && element&.class&.name == 'Sample' && new_prop.dig('layers', 'sample_details', 'fields')&.each_with_index do |fi, idx|
121
- if fi['field'] == 'label'
122
- fi['value'] = element.short_label
123
- new_prop['layers']['sample_details']['fields'][idx] = fi
124
- end
125
- if fi['field'] == 'id'
126
- fi['value'] = element.id
127
- new_prop['layers']['sample_details']['fields'][idx] = fi
128
- end
129
- end
130
-
131
- new_prop.dig('layers', 'instrument', 'fields')&.each_with_index do |fi, idx|
132
- if fi['field'] == 'instrument' && metadata['INSTRUM'].present?
133
- # fi['label'] = fi['label']
134
- fi['value'] = metadata['INSTRUM']
135
- fi['device'] = metadata['INSTRUM']
136
- fi['dkey'] = 'INSTRUM'
137
- new_prop['layers']['instrument']['fields'][idx] = fi
138
- end
139
- end
140
-
141
-
142
- new_prop.dig('layers', 'equipment', 'fields')&.each_with_index do |fi, idx|
143
- if fi['field'] == 'probehead' && metadata['PROBHD'].present?
144
- # fi['label'] = fi['label']
145
- fi['value'] = metadata['PROBHD']
146
- fi['device'] = metadata['PROBHD']
147
- fi['dkey'] = 'PROBHD'
148
- new_prop['layers']['equipment']['fields'][idx] = fi
149
- end
150
- end
151
-
152
- new_prop.dig('layers', 'sample_preparation', 'fields')&.each_with_index do |fi, idx|
153
- if fi['field'] == 'solvent' && metadata['SOLVENT'].present?
154
- # fi['label'] = fi['label']
155
- fi['value'] = metadata['SOLVENT']
156
- fi['device'] = metadata['SOLVENT']
157
- fi['dkey'] = 'SOLVENT'
158
- fi['value'] = 'chloroform-D1 (CDCl3)' if metadata['SOLVENT'] == 'CDCl3'
159
- new_prop['layers']['sample_preparation']['fields'][idx] = fi
160
- end
161
- end
162
-
163
-
164
- new_prop.dig('layers', 'set', 'fields')&.each_with_index do |fi, idx|
165
- if fi['field'] == 'temperature' && metadata['TE'].present?
166
- # fi['label'] = fi['label']
167
- fi['value'] = metadata['TE'].split(/\s+/).first
168
- fi['device'] = metadata['TE']
169
- fi['dkey'] = 'TE'
170
- fi['value_system'] = metadata['TE'].split(/\s+/).last
171
- new_prop['layers']['set']['fields'][idx] = fi
172
- end
173
- if fi['field'] == 'ns' && metadata['NS'].present?
174
- # fi['label'] = fi['label']
175
- fi['value'] = metadata['NS']
176
- fi['device'] = metadata['NS']
177
- fi['dkey'] = 'NS'
178
- new_prop['layers']['set']['fields'][idx] = fi
179
- end
180
- if fi['field'] == 'PULPROG' && metadata['PULPROG'].present?
181
- # fi['label'] = fi['label']
182
- fi['value'] = metadata['PULPROG']
183
- fi['device'] = metadata['PULPROG']
184
- fi['dkey'] = 'PULPROG'
185
- new_prop['layers']['set']['fields'][idx] = fi
186
- end
187
- if fi['field'] == 'td' && metadata['TD'].present?
188
- # fi['label'] = fi['label']
189
- fi['value'] = metadata['TD']
190
- fi['device'] = metadata['TD']
191
- fi['dkey'] = 'TD'
192
- new_prop['layers']['set']['fields'][idx] = fi
193
- end
194
- if fi['field'] == 'done' && metadata['D1'].present?
195
- # fi['label'] = fi['label']
196
- fi['value'] = metadata['D1']
197
- fi['device'] = metadata['D1']
198
- fi['dkey'] = 'D1'
199
- new_prop['layers']['set']['fields'][idx] = fi
200
- end
201
- if fi['field'] == 'sf' && metadata['SF'].present?
202
- ## fi['label'] = fi['label']
203
- fi['value'] = metadata['SF']
204
- fi['device'] = metadata['SF']
205
- fi['dkey'] = 'SF'
206
- new_prop['layers']['set']['fields'][idx] = fi
207
- end
208
- if fi['field'] == 'sfoone' && metadata['SFO1'].present?
209
- ## fi['label'] = fi['label']
210
- fi['value'] = metadata['SFO1']
211
- fi['device'] = metadata['SFO1']
212
- fi['dkey'] = 'SFO1'
213
- new_prop['layers']['set']['fields'][idx] = fi
214
- end
215
- if fi['field'] == 'sfotwo' && metadata['SFO2'].present?
216
- ## fi['label'] = fi['label']
217
- fi['value'] = metadata['SFO2']
218
- fi['device'] = metadata['SFO2']
219
- fi['dkey'] = 'SFO2'
220
- new_prop['layers']['set']['fields'][idx] = fi
221
- end
222
- if fi['field'] == 'nucone' && metadata['NUC1'].present?
223
- ## fi['label'] = fi['label']
224
- fi['value'] = metadata['NUC1']
225
- fi['device'] = metadata['NUC1']
226
- fi['dkey'] = 'NUC1'
227
- new_prop['layers']['set']['fields'][idx] = fi
228
- end
229
- if fi['field'] == 'nuctwo' && metadata['NUC2'].present?
230
- ## fi['label'] = fi['label']
231
- fi['value'] = metadata['NUC2']
232
- fi['device'] = metadata['NUC2']
233
- fi['dkey'] = 'NUC2'
234
- new_prop['layers']['set']['fields'][idx] = fi
235
- end
236
- end
237
- dataset.properties = new_prop
238
- dataset.save!
239
- end
240
-
241
-
242
- def self.ts(method, identifier, params = nil)
243
- Rails.cache.send(method, "#{Labimotion::NmrMapper.new.class.name}#{identifier}", params)end
244
-
245
- def self.clean(id)
246
- Labimotion::NmrMapper.ts('delete', id)
247
- end
248
-
249
- def self.build_ds(id, content)
250
- ds = Container.find_by(id: id)
251
- return if ds.nil? || content.nil?
252
-
253
- ols = content[:ols]
254
- metadata = content[:metadata]
255
-
256
- return if ols.nil? || metadata.nil?
257
-
258
- klass = Labimotion::DatasetKlass.find_by(ols_term_id: ols)
259
- return if klass.nil?
260
-
261
- uuid = SecureRandom.uuid
262
- props = klass.properties_release
263
- props['uuid'] = uuid
264
- props['pkg'] = Labimotion::Utils.pkg(props['pkg'])
265
- props['klass'] = 'Dataset'
266
- dataset = Labimotion::Dataset.create!(
267
- uuid: uuid,
268
- dataset_klass_id: klass.id,
269
- element_type: 'Container',
270
- element_id: ds.id,
271
- properties: props,
272
- properties_release: klass.properties_release,
273
- klass_uuid: klass.uuid
274
- )
275
- { dataset: dataset, metadata: metadata, ols: ols }
276
- end
277
- end
278
- end