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,88 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ module Labimotion
4
+ ## ApplicationEntity
5
+ class ApplicationEntity < Grape::Entity
6
+ CUSTOM_ENTITY_OPTIONS = %i[anonymize_below anonymize_with].freeze
7
+
8
+ format_with(:eln_timestamp) do |datetime|
9
+ datetime.present? ? datetime&.strftime('%Y-%m-%d %H:%M:%S %Z') : nil
10
+ end
11
+
12
+ def self.expose!(*args)
13
+ fields = args.first
14
+ options = args.last.is_a?(Hash) ? args.pop : {}
15
+ options = merge_options(options) # merges additional params set in #with_options
16
+ expose_fields_with_anonymization!(fields, options)
17
+ end
18
+
19
+ # rubocop:disable Metrics/MethodLength
20
+ def self.expose_fields_with_anonymization!(fields, options)
21
+ anonymize_below = options[:anonymize_below] || 0
22
+ anonymize_with = options.key?(:anonymize_with) ? options[:anonymize_with] : '***'
23
+
24
+ Array(fields).each do |field|
25
+ expose(field, options) do |represented_object, _options|
26
+ if detail_levels[represented_object.class] < anonymize_below
27
+ anonymize_with
28
+ elsif respond_to?(field, true) # Entity has a method with the same name
29
+ send(field)
30
+ elsif represented_object.respond_to?(field)
31
+ represented_object.public_send(field)
32
+ else
33
+ represented_object[field] # works both for AR and Hash objects
34
+ end
35
+ end
36
+ end
37
+ end
38
+ private_class_method :expose_fields_with_anonymization!
39
+ # rubocop:enable Metrics/MethodLength
40
+
41
+ def self.expose_timestamps(timestamp_fields: %i[created_at updated_at], **additional_args)
42
+ timestamp_fields.each do |field|
43
+ expose field, format_with: :eln_timestamp, **additional_args
44
+ end
45
+ end
46
+
47
+ # overridden method from Grape::Entity to support our custom anonymization options
48
+ # https://github.com/ruby-grape/grape-entity/blob/v0.7.1/lib/grape_entity/entity.rb#L565
49
+ def self.valid_options(options)
50
+ options.each_key do |key|
51
+ next if OPTIONS.include?(key) || CUSTOM_ENTITY_OPTIONS.include?(key)
52
+
53
+ raise ArgumentError, "#{key.inspect} is not a valid option."
54
+ end
55
+
56
+ options[:using] = options.delete(:with) if options.key?(:with)
57
+ options
58
+ end
59
+ private_class_method :valid_options
60
+
61
+ private
62
+
63
+ def displayed_in_list?
64
+ options[:displayed_in_list] == true
65
+ end
66
+
67
+ def current_user
68
+ unless options[:current_user]
69
+ raise MissingCurrentUserError, "#{self.class} requires a current user to work properly"
70
+ end
71
+
72
+ options[:current_user]
73
+ end
74
+
75
+ def detail_levels
76
+ maximal_default_levels = Hash.new(10) # every requested detail level will be returned as 10
77
+ minimal_default_levels = Hash.new(0) # every requested detail level will be returned as 0
78
+ return maximal_default_levels if !options.key?(:detail_levels) || options[:detail_levels].empty?
79
+
80
+ # When explicitly configured detail levels are available, we want to return only those and all other
81
+ # requests (by using `detail_levels[SomeUnconfiguredModel]`) should return the minimum detail level
82
+ minimal_default_levels.merge(options[:detail_levels])
83
+ end
84
+
85
+ class MissingCurrentUserError < StandardError
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ require 'labimotion/entities/application_entity'
4
+ module Labimotion
5
+ # Dataset entity
6
+ class DatasetEntity < ApplicationEntity
7
+ expose :id, :dataset_klass_id, :properties, :properties_release, :element_id, :element_type, :klass_ols, :klass_label, :klass_uuid
8
+ def klass_ols
9
+ object&.dataset_klass&.ols_term_id
10
+ end
11
+
12
+ def klass_label
13
+ object&.dataset_klass&.label
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+ require 'labimotion/entities/generic_klass_entity'
3
+ module Labimotion
4
+ class DatasetKlassEntity < GenericKlassEntity
5
+ expose(
6
+ :ols_term_id,
7
+ )
8
+ end
9
+ end
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'labimotion/entities/application_entity'
4
+ ## TODO: Refactor labimotion to use the same entities as chemotion
5
+ module Labimotion
6
+ class ElementEntity < ApplicationEntity
7
+ with_options(anonymize_below: 0) do
8
+ expose! :can_copy
9
+ expose! :container, using: 'Entities::ContainerEntity'
10
+ expose! :created_by
11
+ expose! :id
12
+ expose! :is_restricted
13
+ expose! :klass_uuid
14
+ expose! :name
15
+ expose! :properties
16
+ expose! :properties_release
17
+ expose! :short_label
18
+ expose! :type
19
+ expose! :uuid
20
+ end
21
+
22
+ with_options(anonymize_below: 10) do
23
+ expose! :element_klass, anonymize_with: nil, using: 'Labimotion::ElementKlassEntity'
24
+ expose! :segments, anonymize_with: [], using: 'Labimotion::SegmentEntity'
25
+ expose! :tag, anonymize_with: nil, using: 'Entities::ElementTagEntity'
26
+ end
27
+
28
+ expose_timestamps
29
+
30
+
31
+ private
32
+
33
+ def is_restricted
34
+ detail_levels[Labimotion::Element] < 10
35
+ end
36
+
37
+ # TODO: Refactor this method to something more readable/understandable
38
+ def properties
39
+ (object.properties['layers']&.keys || []).each do |key|
40
+ # layer = object.properties[key]
41
+ field_sample_molecules = object.properties['layers'][key]['fields'].select { |ss| ss['type'] == 'drag_sample' || ss['type'] == 'drag_molecule' }
42
+ field_sample_molecules.each do |field|
43
+ idx = object.properties['layers'][key]['fields'].index(field)
44
+ sid = field.dig('value', 'el_id')
45
+ next unless sid.present?
46
+
47
+ el = field['type'] == 'drag_sample' ? Sample.find_by(id: sid) : Molecule.find_by(id: sid)
48
+ next unless el.present?
49
+ next unless object.properties.dig('layers', key, 'fields', idx, 'value').present?
50
+
51
+ object.properties['layers'][key]['fields'][idx]['value']['el_label'] = el.short_label if field['type'] == 'drag_sample'
52
+ object.properties['layers'][key]['fields'][idx]['value']['el_tip'] = el.short_label if field['type'] == 'drag_sample'
53
+ object.properties['layers'][key]['fields'][idx]['value']['el_svg'] = field['type'] == 'drag_sample' ? el.get_svg_path : File.join('/images', 'molecules', el.molecule_svg_file)
54
+ end
55
+
56
+ field_tables = object.properties['layers'][key]['fields'].select { |ss| ss['type'] == 'table' }
57
+ field_tables.each do |field|
58
+ idx = object.properties['layers'][key]['fields'].index(field)
59
+ next unless field['sub_values'].present? && field['sub_fields'].present?
60
+
61
+ field_table_molecules = field['sub_fields'].select { |ss| ss['type'] == 'drag_molecule' }
62
+ object.properties['layers'][key]['fields'][idx] = set_table(field, field_table_molecules, 'Molecule') if field_table_molecules.present?
63
+
64
+ field_table_samples = field['sub_fields'].select { |ss| ss['type'] == 'drag_sample' }
65
+ object.properties['layers'][key]['fields'][idx] = set_table(field, field_table_samples, 'Sample') if field_table_samples.present?
66
+ end
67
+ end
68
+ object.properties
69
+ end
70
+
71
+ def type
72
+ object.element_klass.name # 'genericEl' #object.type
73
+ end
74
+
75
+ def set_table(field, field_table_objs, obj)
76
+ col_ids = field_table_objs.map { |x| x.values[0] }
77
+ col_ids.each do |col_id|
78
+ field['sub_values'].each do |sub_value|
79
+ next unless sub_value[col_id].present? && sub_value[col_id]['value'].present? && sub_value[col_id]['value']['el_id'].present?
80
+
81
+ find_obj = obj.constantize.find_by(id: sub_value[col_id]['value']['el_id'])
82
+ next unless find_obj.present?
83
+
84
+ case obj
85
+ when 'Molecule'
86
+ sub_value[col_id]['value']['el_svg'] = File.join('/images', 'molecules', find_obj.molecule_svg_file)
87
+ sub_value[col_id]['value']['el_inchikey'] = find_obj.inchikey
88
+ sub_value[col_id]['value']['el_smiles'] = find_obj.cano_smiles
89
+ sub_value[col_id]['value']['el_iupac'] = find_obj.iupac_name
90
+ sub_value[col_id]['value']['el_molecular_weight'] = find_obj.molecular_weight
91
+ when 'Sample'
92
+ sub_value[col_id]['value']['el_svg'] = find_obj.get_svg_path
93
+ sub_value[col_id]['value']['el_label'] = find_obj.short_label
94
+ sub_value[col_id]['value']['el_short_label'] = find_obj.short_label
95
+ sub_value[col_id]['value']['el_name'] = find_obj.name
96
+ sub_value[col_id]['value']['el_external_label'] = find_obj.external_label
97
+ sub_value[col_id]['value']['el_molecular_weight'] = find_obj.decoupled ? find_obj.molecular_mass : find_obj.molecule.molecular_weight
98
+ end
99
+ end
100
+ end
101
+ field
102
+ end
103
+
104
+ def can_copy
105
+ true
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ require 'labimotion/entities/generic_klass_entity'
4
+
5
+ module Labimotion
6
+ # ElementKlassEntity
7
+ class ElementKlassEntity < GenericKlassEntity
8
+ expose :name, :icon_name, :klass_prefix, :is_generic
9
+ end
10
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'labimotion/entities/application_entity'
4
+ module Labimotion
5
+ # ElementRevisionEntity
6
+ class ElementRevisionEntity < ApplicationEntity
7
+ expose :id, :element_id, :uuid, :name, :klass_uuid, :properties, :created_at
8
+ def created_at
9
+ object.created_at.strftime('%d.%m.%Y, %H:%M')
10
+ end
11
+
12
+ def properties
13
+ object.properties['layers']&.keys.each do |key|
14
+ field_sample_molecules = object.properties['layers'][key]['fields'].select { |ss| ss['type'] == 'drag_sample' || ss['type'] == 'drag_molecule' }
15
+ field_sample_molecules.each do |field|
16
+ idx = object.properties['layers'][key]['fields'].index(field)
17
+ sid = field.dig('value', 'el_id')
18
+ next unless sid.present?
19
+
20
+ el = field['type'] == 'drag_sample' ? Sample.find_by(id: sid) : Molecule.find_by(id: sid)
21
+ next unless el.present?
22
+ next unless object.properties.dig('layers', key, 'fields', idx, 'value').present?
23
+
24
+ object.properties['layers'][key]['fields'][idx]['value']['el_label'] = el.short_label if field['type'] == 'drag_sample'
25
+ object.properties['layers'][key]['fields'][idx]['value']['el_tip'] = el.short_label if field['type'] == 'drag_sample'
26
+ object.properties['layers'][key]['fields'][idx]['value']['el_svg'] = field['type'] == 'drag_sample' ? el.get_svg_path : File.join('/images', 'molecules', el.molecule_svg_file)
27
+ end
28
+
29
+ field_tables = object.properties['layers'][key]['fields'].select { |ss| ss['type'] == 'table' }
30
+ field_tables.each do |field|
31
+ next unless field['sub_values'].present? && field['sub_fields'].present?
32
+
33
+ field_table_molecules = field['sub_fields'].select { |ss| ss['type'] == 'drag_molecule' }
34
+ next unless field_table_molecules.present?
35
+
36
+ col_ids = field_table_molecules.map { |x| x.values[0] }
37
+ col_ids.each do |col_id|
38
+ field_table_values = field['sub_values'].each do |sub_value|
39
+ next unless sub_value[col_id].present? && sub_value[col_id]['value'].present? && sub_value[col_id]['value']['el_id'].present?
40
+
41
+ find_mol = Molecule.find_by(id: sub_value[col_id]['value']['el_id'])
42
+ next unless find_mol.present?
43
+
44
+ sub_value[col_id]['value']['el_svg'] = File.join('/images', 'molecules', find_mol.molecule_svg_file)
45
+ sub_value[col_id]['value']['el_inchikey'] = find_mol.inchikey
46
+ sub_value[col_id]['value']['el_smiles'] = find_mol.cano_smiles
47
+ sub_value[col_id]['value']['el_iupac'] = find_mol.iupac_name
48
+ sub_value[col_id]['value']['el_molecular_weight'] = find_mol.molecular_weight
49
+ end
50
+ end
51
+ end
52
+ end
53
+ object.properties['select_options'] = object.properties_release['select_options']
54
+ object.properties
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ require 'labimotion/entities/application_entity'
4
+ module Labimotion
5
+ ## ElementEntity
6
+ class ElnElementEntity < ApplicationEntity
7
+ with_options(anonymize_below: 0) do
8
+ expose! :created_by
9
+ expose! :id
10
+ expose! :is_restricted
11
+ expose! :klass_uuid
12
+ expose! :name
13
+ expose! :properties
14
+ expose! :properties_release
15
+ expose! :short_label
16
+ expose! :type
17
+ expose! :uuid
18
+ end
19
+
20
+ expose(
21
+ :can_copy, unless: ->(_instance, _options) { displayed_in_list? }
22
+ )
23
+
24
+ private
25
+
26
+ def properties
27
+ (object.properties['layers']&.keys || []).each do |key|
28
+ # layer = object.properties[key]
29
+ field_sample_molecules = object.properties['layers'][key]['fields'].select do |ss|
30
+ ss['type'] == 'drag_sample' || ss['type'] == 'drag_molecule'
31
+ end
32
+ field_sample_molecules.each do |field|
33
+ idx = object.properties['layers'][key]['fields'].index(field)
34
+ sid = field.dig('value', 'el_id')
35
+ next unless sid.present?
36
+
37
+ el = field['type'] == 'drag_sample' ? Sample.find_by(id: sid) : Molecule.find_by(id: sid)
38
+ next unless el.present?
39
+ next unless object.properties.dig('layers', key, 'fields', idx, 'value').present?
40
+
41
+ if field['type'] == 'drag_sample'
42
+ object.properties['layers'][key]['fields'][idx]['value']['el_label'] =
43
+ el.short_label
44
+ end
45
+ if field['type'] == 'drag_sample'
46
+ object.properties['layers'][key]['fields'][idx]['value']['el_tip'] =
47
+ el.short_label
48
+ end
49
+ object.properties['layers'][key]['fields'][idx]['value']['el_svg'] =
50
+ field['type'] == 'drag_sample' ? el.get_svg_path : File.join('/images', 'molecules', el.molecule_svg_file)
51
+ end
52
+
53
+ field_tables = object.properties['layers'][key]['fields'].select { |ss| ss['type'] == 'table' }
54
+ field_tables.each do |field|
55
+ idx = object.properties['layers'][key]['fields'].index(field)
56
+ next unless field['sub_values'].present? && field['sub_fields'].present?
57
+
58
+ field_table_molecules = field['sub_fields'].select { |ss| ss['type'] == 'drag_molecule' }
59
+ if field_table_molecules.present?
60
+ object.properties['layers'][key]['fields'][idx] =
61
+ set_table(field, field_table_molecules, 'Molecule')
62
+ end
63
+
64
+ field_table_samples = field['sub_fields'].select { |ss| ss['type'] == 'drag_sample' }
65
+ if field_table_samples.present?
66
+ object.properties['layers'][key]['fields'][idx] =
67
+ set_table(field, field_table_samples, 'Sample')
68
+ end
69
+ end
70
+ end
71
+ object.properties
72
+ end
73
+
74
+ def type
75
+ object.element_klass.name
76
+ end
77
+
78
+ def set_table(field, field_table_objs, obj)
79
+ col_ids = field_table_objs.map { |x| x.values[0] }
80
+ col_ids.each do |col_id|
81
+ field['sub_values'].each do |sub_value|
82
+ unless sub_value[col_id].present? && sub_value[col_id]['value'].present? && sub_value[col_id]['value']['el_id'].present?
83
+ next
84
+ end
85
+
86
+ find_obj = obj.constantize.find_by(id: sub_value[col_id]['value']['el_id'])
87
+ next unless find_obj.present?
88
+
89
+ case obj
90
+ when 'Molecule'
91
+ sub_value[col_id]['value']['el_svg'] = File.join('/images', 'molecules', find_obj.molecule_svg_file)
92
+ sub_value[col_id]['value']['el_inchikey'] = find_obj.inchikey
93
+ sub_value[col_id]['value']['el_smiles'] = find_obj.cano_smiles
94
+ sub_value[col_id]['value']['el_iupac'] = find_obj.iupac_name
95
+ sub_value[col_id]['value']['el_molecular_weight'] = find_obj.molecular_weight
96
+ when 'Sample'
97
+ sub_value[col_id]['value']['el_svg'] = find_obj.get_svg_path
98
+ sub_value[col_id]['value']['el_label'] = find_obj.short_label
99
+ sub_value[col_id]['value']['el_short_label'] = find_obj.short_label
100
+ sub_value[col_id]['value']['el_name'] = find_obj.name
101
+ sub_value[col_id]['value']['el_external_label'] = find_obj.external_label
102
+ sub_value[col_id]['value']['el_molecular_weight'] =
103
+ find_obj.decoupled ? find_obj.molecular_mass : find_obj.molecule.molecular_weight
104
+ end
105
+ end
106
+ end
107
+ field
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'labimotion/entities/application_entity'
4
+
5
+ # Entity module
6
+ module Labimotion
7
+ class GenericEntity < Labimotion::ApplicationEntity
8
+ expose :id, :is_active, :label, :desc, :place, :released_at
9
+
10
+ expose :element_klass_id do |obj|
11
+ obj[:element_klass_id] || 0
12
+ end
13
+
14
+ expose :klass_name do |obj|
15
+ obj[:name] || ''
16
+ end
17
+
18
+ expose :ols_term_id do |obj|
19
+ obj[:ols_term_id] || ''
20
+ end
21
+
22
+ expose :icon_name do |obj|
23
+ obj[:icon_name] || ''
24
+ end
25
+
26
+ expose :klass_prefix do |obj|
27
+ obj[:klass_prefix] || ''
28
+ end
29
+
30
+ expose :is_generic do |obj|
31
+ obj[:is_generic] || true
32
+ end
33
+
34
+ expose :uuid do |obj|
35
+ obj[:uuid] || ''
36
+ end
37
+
38
+ expose :properties_release do |obj|
39
+ obj[:properties_release] || {}
40
+ end
41
+
42
+ expose :element_klass do |obj|
43
+ if obj[:element_klass_id]
44
+ Labimotion::GenericEntity.represent(obj.element_klass)
45
+ else
46
+ {}
47
+ end
48
+ end
49
+
50
+ expose :identifier do |obj|
51
+ obj[:identifier] || ''
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ require 'labimotion/entities/application_entity'
4
+ module Labimotion
5
+ # GenericKlassEntity
6
+ class GenericKlassEntity < ApplicationEntity
7
+ expose :id, :uuid, :label, :desc, :properties_template, :properties_release, :is_active,
8
+ :place, :released_at, :identifier, :sync_time, :created_by, :updated_by, :created_at, :updated_at
9
+ expose_timestamps(timestamp_fields: [:released_at])
10
+ expose_timestamps(timestamp_fields: [:created_at])
11
+ expose_timestamps(timestamp_fields: [:updated_at])
12
+ expose_timestamps(timestamp_fields: [:sync_time])
13
+ end
14
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'labimotion/entities/application_entity'
4
+
5
+ # Entity module
6
+ module Labimotion
7
+ class GenericPublicEntity < Labimotion::ApplicationEntity
8
+ expose! :name
9
+ expose! :desc
10
+ expose! :icon_name
11
+ expose! :klass_prefix
12
+ expose! :klass_name
13
+ expose! :label
14
+ expose! :identifier
15
+ expose! :released_at
16
+ expose! :properties_release, if: :displayed
17
+ expose :element_klass do |obj|
18
+ if obj[:element_klass_id]
19
+ { :label => obj.element_klass.label, :icon_name => obj.element_klass.icon_name }
20
+ else
21
+ {}
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Labimotion
4
+ # KlassRevisionEntity
5
+ class KlassRevisionEntity < ApplicationEntity
6
+ expose :id, :uuid, :properties_release, :released_at
7
+
8
+ expose :klass_id do |object|
9
+ klass_id = object.element_klass_id if object.respond_to? :element_klass_id
10
+ klass_id = object.segment_klass_id if object.respond_to? :segment_klass_id
11
+ klass_id = object.dataset_klass_id if object.respond_to? :dataset_klass_id
12
+ klass_id
13
+ end
14
+
15
+ def released_at
16
+ object.released_at&.strftime('%d.%m.%Y, %H:%M')
17
+ end
18
+ end
19
+ end
20
+
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'labimotion/entities/application_entity'
4
+ module Labimotion
5
+ ## Segment entity
6
+ class SegmentEntity < ApplicationEntity
7
+ expose :id, :segment_klass_id, :element_type, :element_id, :properties, :properties_release, :uuid, :klass_uuid, :klass_label
8
+
9
+ def klass_label
10
+ object.segment_klass.label
11
+ end
12
+
13
+ def properties # rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity, Metrics/AbcSize, Metrics/MethodLength
14
+ return unless object.respond_to?(:properties)
15
+
16
+ return if object&.properties.dig('layers').blank?
17
+
18
+ object&.properties['layers'].each_key do |key| # rubocop:disable Metrics/BlockLength
19
+ next if object&.properties.dig('layers', key, 'fields').blank?
20
+
21
+ field_sample_molecules = object&.properties['layers'][key]['fields'].select { |ss| ss['type'] == 'drag_molecule' }
22
+ field_sample_molecules.each do |field|
23
+ idx = object&.properties['layers'][key]['fields'].index(field)
24
+ sid = field.dig('value', 'el_id')
25
+ next if sid.blank?
26
+
27
+ el = Molecule.find_by(id: sid)
28
+ next if el.blank?
29
+
30
+ next if object&.properties.dig('layers', key, 'fields', idx, 'value').blank?
31
+
32
+ object&.properties['layers'][key]['fields'][idx]['value']['el_svg'] = File.join('/images', 'molecules', el.molecule_svg_file)
33
+ end
34
+
35
+ field_tables = object.properties['layers'][key]['fields'].select { |ss| ss['type'] == 'table' }
36
+ field_tables.each do |field|
37
+ next unless field['sub_values'].present? && field['sub_fields'].present?
38
+
39
+ field_table_molecules = field['sub_fields'].select { |ss| ss['type'] == 'drag_molecule' }
40
+ next if field_table_molecules.blank?
41
+
42
+ col_ids = field_table_molecules.map { |x| x.values[0] }
43
+ col_ids.each do |col_id|
44
+ field['sub_values'].each do |sub_value|
45
+ next unless sub_value[col_id].present? && sub_value[col_id]['value'].present? && sub_value[col_id]['value']['el_id'].present?
46
+
47
+ find_mol = Molecule.find_by(id: sub_value[col_id]['value']['el_id'])
48
+ next if find_mol.blank?
49
+
50
+ sub_value[col_id]['value']['el_svg'] = File.join('/images', 'molecules', find_mol.molecule_svg_file)
51
+ sub_value[col_id]['value']['el_inchikey'] = find_mol.inchikey
52
+ sub_value[col_id]['value']['el_smiles'] = find_mol.cano_smiles
53
+ sub_value[col_id]['value']['el_iupac'] = find_mol.iupac_name
54
+ sub_value[col_id]['value']['el_molecular_weight'] = find_mol.molecular_weight
55
+ end
56
+ end
57
+ end
58
+ end
59
+ object&.properties
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+ require 'labimotion/entities/generic_klass_entity'
3
+ require 'labimotion/entities/element_klass_entity'
4
+ module Labimotion
5
+ class SegmentKlassEntity < Labimotion::GenericKlassEntity
6
+ expose :element_klass, using: Labimotion::ElementKlassEntity
7
+ end
8
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ require 'labimotion/entities/application_entity'
4
+ module Labimotion
5
+ class SegmentRevisionEntity < ApplicationEntity
6
+ expose :id, :segment_id, :uuid, :klass_uuid, :properties, :created_at
7
+ def created_at
8
+ object.created_at.strftime('%d.%m.%Y, %H:%M')
9
+ end
10
+
11
+ def properties
12
+ object.properties['layers']&.keys.each do |key|
13
+ field_sample_molecules = object.properties['layers'][key]['fields'].select { |ss| ss['type'] == 'drag_sample' || ss['type'] == 'drag_molecule' }
14
+ field_sample_molecules.each do |field|
15
+ idx = object.properties['layers'][key]['fields'].index(field)
16
+ sid = field.dig('value', 'el_id')
17
+ next unless sid.present?
18
+
19
+ el = field['type'] == 'drag_sample' ? Sample.find_by(id: sid) : Molecule.find_by(id: sid)
20
+ next unless el.present?
21
+ next unless object.properties.dig('layers', key, 'fields', idx, 'value').present?
22
+
23
+ object.properties['layers'][key]['fields'][idx]['value']['el_label'] = el.short_label if field['type'] == 'drag_sample'
24
+ object.properties['layers'][key]['fields'][idx]['value']['el_tip'] = el.short_label if field['type'] == 'drag_sample'
25
+ object.properties['layers'][key]['fields'][idx]['value']['el_svg'] = field['type'] == 'drag_sample' ? el.get_svg_path : File.join('/images', 'molecules', el.molecule_svg_file)
26
+ end
27
+
28
+ field_tables = object.properties['layers'][key]['fields'].select { |ss| ss['type'] == 'table' }
29
+ field_tables.each do |field|
30
+ next unless field['sub_values'].present? && field['sub_fields'].present?
31
+
32
+ field_table_molecules = field['sub_fields'].select { |ss| ss['type'] == 'drag_molecule' }
33
+ next unless field_table_molecules.present?
34
+
35
+ col_ids = field_table_molecules.map { |x| x.values[0] }
36
+ col_ids.each do |col_id|
37
+ field_table_values = field['sub_values'].each do |sub_value|
38
+ next unless sub_value[col_id].present? && sub_value[col_id]['value'].present? && sub_value[col_id]['value']['el_id'].present?
39
+
40
+ find_mol = Molecule.find_by(id: sub_value[col_id]['value']['el_id'])
41
+ next unless find_mol.present?
42
+
43
+ sub_value[col_id]['value']['el_svg'] = File.join('/images', 'molecules', find_mol.molecule_svg_file)
44
+ sub_value[col_id]['value']['el_inchikey'] = find_mol.inchikey
45
+ sub_value[col_id]['value']['el_smiles'] = find_mol.cano_smiles
46
+ sub_value[col_id]['value']['el_iupac'] = find_mol.iupac_name
47
+ sub_value[col_id]['value']['el_molecular_weight'] = find_mol.molecular_weight
48
+ end
49
+ end
50
+ end
51
+ end
52
+ object.properties
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+ require 'grape'
3
+
4
+ module Labimotion
5
+ ## ElementHelpers
6
+ module ConverterHelpers
7
+ extend Grape::API::Helpers
8
+
9
+ def demo(params)
10
+ ### TODO: implement demo
11
+ end
12
+ end
13
+ end