labimotion 1.4.1 → 2.0.0.rc6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/labimotion/apis/generic_element_api.rb +1 -0
- data/lib/labimotion/apis/generic_klass_api.rb +3 -2
- data/lib/labimotion/apis/labimotion_api.rb +13 -0
- data/lib/labimotion/apis/standard_api.rb +25 -0
- data/lib/labimotion/apis/standard_layer_api.rb +87 -0
- data/lib/labimotion/apis/vocabulary_api.rb +93 -0
- data/lib/labimotion/constants.rb +21 -0
- data/lib/labimotion/entities/dataset_entity.rb +1 -1
- data/lib/labimotion/entities/element_entity.rb +1 -0
- data/lib/labimotion/entities/properties_entity.rb +229 -56
- data/lib/labimotion/entities/segment_entity.rb +0 -1
- data/lib/labimotion/entities/vocabulary_entity.rb +28 -0
- data/lib/labimotion/helpers/element_helpers.rb +8 -6
- data/lib/labimotion/helpers/generic_helpers.rb +6 -1
- data/lib/labimotion/helpers/param_helpers.rb +121 -82
- data/lib/labimotion/helpers/segment_helpers.rb +1 -1
- data/lib/labimotion/helpers/vocabulary_helpers.rb +16 -0
- data/lib/labimotion/libs/converter.rb +12 -33
- data/lib/labimotion/libs/data/mapper/Chemwiki.json +236 -0
- data/lib/labimotion/libs/data/mapper/Source.json +78 -0
- data/lib/labimotion/libs/data/vocab/Standard.json +385 -0
- data/lib/labimotion/libs/data/vocab/System.json +131 -0
- data/lib/labimotion/libs/dataset_builder.rb +70 -0
- data/lib/labimotion/libs/export_dataset.rb +165 -66
- data/lib/labimotion/libs/nmr_mapper.rb +204 -246
- data/lib/labimotion/libs/sample_association.rb +4 -0
- data/lib/labimotion/libs/vocabulary_handler.rb +118 -0
- data/lib/labimotion/models/concerns/attachment_converter.rb +5 -4
- data/lib/labimotion/models/concerns/datasetable.rb +1 -0
- data/lib/labimotion/models/concerns/segmentable.rb +2 -0
- data/lib/labimotion/models/element.rb +3 -0
- data/lib/labimotion/models/std_layer.rb +9 -0
- data/lib/labimotion/models/std_layers_revision.rb +9 -0
- data/lib/labimotion/models/vocabulary.rb +12 -0
- data/lib/labimotion/utils/mapper_utils.rb +169 -0
- data/lib/labimotion/utils/utils.rb +22 -0
- data/lib/labimotion/version.rb +1 -1
- data/lib/labimotion.rb +13 -3
- metadata +25 -5
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: b55a7bdf8c25fd127bd7a7bab35676d74e3f3523cb55e03516cc28d3e2df738c
         | 
| 4 | 
            +
              data.tar.gz: a28bad0092a10adc3befb26c3803d5f969d40bf9e387a7015890c2f81cd3089e
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 94b3f84c3b2588b08f19c66bafdd17fb9eef3674040bd3dc0683132a4b5709c11f643e81afda2109741da24e4a38c6b407c4eff279c00c9292ef0942611c4ec8
         | 
| 7 | 
            +
              data.tar.gz: 19082b803643920e698b9f14c1ce89b68aac5121a5adeab473d86c16c7129ba1d9e024e1bcec83b7c802ed79409183e1129967881295b66c363912652d563191
         | 
| @@ -12,6 +12,7 @@ module Labimotion | |
| 12 12 | 
             
                helpers CollectionHelpers
         | 
| 13 13 | 
             
                helpers UserLabelHelpers
         | 
| 14 14 | 
             
                helpers Labimotion::SampleAssociationHelpers
         | 
| 15 | 
            +
                helpers Labimotion::VocabularyHelpers
         | 
| 15 16 | 
             
                helpers Labimotion::GenericHelpers
         | 
| 16 17 | 
             
                helpers Labimotion::ElementHelpers
         | 
| 17 18 | 
             
                helpers Labimotion::ParamHelpers
         | 
| @@ -6,7 +6,7 @@ require 'labimotion/libs/export_element' | |
| 6 6 | 
             
            module Labimotion
         | 
| 7 7 | 
             
              # Generic Element API
         | 
| 8 8 | 
             
              class GenericKlassAPI < Grape::API
         | 
| 9 | 
            -
             | 
| 9 | 
            +
             | 
| 10 10 | 
             
                resource :generic_klass do
         | 
| 11 11 | 
             
                  namespace :download_klass do
         | 
| 12 12 | 
             
                    desc 'export klass'
         | 
| @@ -28,7 +28,8 @@ module Labimotion | |
| 28 28 | 
             
                      Labimotion.log_exception(e, current_user)
         | 
| 29 29 | 
             
                      {}
         | 
| 30 30 | 
             
                    end
         | 
| 31 | 
            -
                  end | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
             | 
| 32 33 | 
             
                end
         | 
| 33 34 | 
             
              end
         | 
| 34 35 | 
             
            end
         | 
| @@ -0,0 +1,13 @@ | |
| 1 | 
            +
            # app/api/labimotion/central_api.rb
         | 
| 2 | 
            +
            module Labimotion
         | 
| 3 | 
            +
              class LabimotionAPI < Grape::API
         | 
| 4 | 
            +
                mount Labimotion::ConverterAPI
         | 
| 5 | 
            +
                mount Labimotion::GenericKlassAPI
         | 
| 6 | 
            +
                mount Labimotion::GenericElementAPI
         | 
| 7 | 
            +
                mount Labimotion::GenericDatasetAPI
         | 
| 8 | 
            +
                mount Labimotion::SegmentAPI
         | 
| 9 | 
            +
                mount Labimotion::LabimotionHubAPI
         | 
| 10 | 
            +
                mount Labimotion::StandardLayerAPI
         | 
| 11 | 
            +
                mount Labimotion::VocabularyAPI
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
            end
         | 
| @@ -0,0 +1,25 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'labimotion/version'
         | 
| 4 | 
            +
            require 'labimotion/libs/export_element'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module Labimotion
         | 
| 7 | 
            +
              # Generic Element API
         | 
| 8 | 
            +
              class StandardAPI < Grape::API
         | 
| 9 | 
            +
                resource :standards do
         | 
| 10 | 
            +
                  namespace :create_std_layer do
         | 
| 11 | 
            +
                    desc 'create standard layer'
         | 
| 12 | 
            +
                    params do
         | 
| 13 | 
            +
                      use :create_std_layer_params
         | 
| 14 | 
            +
                    end
         | 
| 15 | 
            +
                    post do
         | 
| 16 | 
            +
                      authenticate_admin!('standard_layers')
         | 
| 17 | 
            +
                      create_std_layer(current_user, params)
         | 
| 18 | 
            +
                      status 201
         | 
| 19 | 
            +
                    rescue ActiveRecord::RecordInvalid => e
         | 
| 20 | 
            +
                      { error: e.message }
         | 
| 21 | 
            +
                    end
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
            end
         | 
| @@ -0,0 +1,87 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'labimotion/version'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module Labimotion
         | 
| 6 | 
            +
              # Generic Element API
         | 
| 7 | 
            +
              class StandardLayerAPI < Grape::API
         | 
| 8 | 
            +
                include Grape::Kaminari
         | 
| 9 | 
            +
                helpers Labimotion::ParamHelpers
         | 
| 10 | 
            +
                helpers Labimotion::GenericHelpers
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                resource :layers do
         | 
| 13 | 
            +
                  namespace :get_all_layers do
         | 
| 14 | 
            +
                    desc 'get all standard layers for designer'
         | 
| 15 | 
            +
                    get do
         | 
| 16 | 
            +
                      list = Labimotion::StdLayer.all.sort_by { |e| e.name }
         | 
| 17 | 
            +
                      return { mc: 'ss00', data: list }
         | 
| 18 | 
            +
                    rescue StandardError => e
         | 
| 19 | 
            +
                      Labimotion.log_exception(e, current_user)
         | 
| 20 | 
            +
                      { mc: 'se00', msg: e.message, data: [] }
         | 
| 21 | 
            +
                    end
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                  namespace :get_standard_layer do
         | 
| 25 | 
            +
                    desc 'get standard layer by id'
         | 
| 26 | 
            +
                    route_param :id do
         | 
| 27 | 
            +
                      get do
         | 
| 28 | 
            +
                        authenticate_admin!('standard_layers')
         | 
| 29 | 
            +
                        entity = Labimotion::StdLayer.find(params[:id])
         | 
| 30 | 
            +
                        return { mc: 'ss00', data: entity }
         | 
| 31 | 
            +
                      rescue StandardError => e
         | 
| 32 | 
            +
                        Labimotion.log_exception(e, current_user)
         | 
| 33 | 
            +
                        { mc: 'se00', msg: e.message, data: {} }
         | 
| 34 | 
            +
                      end
         | 
| 35 | 
            +
                    end
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  namespace :save_standard_layer do
         | 
| 39 | 
            +
                    desc 'create Generic Element Klass'
         | 
| 40 | 
            +
                    params do
         | 
| 41 | 
            +
                      use :std_layer_save
         | 
| 42 | 
            +
                    end
         | 
| 43 | 
            +
                    before do
         | 
| 44 | 
            +
                      authenticate_admin!('standard_layers')
         | 
| 45 | 
            +
                      cur_layer = Labimotion::StdLayer.find_by(name: params[:key])
         | 
| 46 | 
            +
                      error!('Error! duplicate name', 409) if cur_layer.present?
         | 
| 47 | 
            +
                    end
         | 
| 48 | 
            +
                    post do
         | 
| 49 | 
            +
                      attributes = {
         | 
| 50 | 
            +
                        name: params[:key],
         | 
| 51 | 
            +
                        label: params[:label],
         | 
| 52 | 
            +
                        description: params[:description],
         | 
| 53 | 
            +
                        identifier: SecureRandom.uuid,
         | 
| 54 | 
            +
                        created_by: current_user.id,
         | 
| 55 | 
            +
                        properties: declared(params, include_missing: false)
         | 
| 56 | 
            +
                      }
         | 
| 57 | 
            +
                      layer = Labimotion::StdLayer.new(attributes)
         | 
| 58 | 
            +
                      layer.save!
         | 
| 59 | 
            +
                      { mc: 'ss00', data: layer }
         | 
| 60 | 
            +
                    rescue ActiveRecord::RecordInvalid => e
         | 
| 61 | 
            +
                      Labimotion.log_exception(e, current_user)
         | 
| 62 | 
            +
                      { mc: 'se00', msg: e.message, data: {} }
         | 
| 63 | 
            +
                    end
         | 
| 64 | 
            +
                  end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                  namespace :delete_standard_layer do
         | 
| 67 | 
            +
                    desc 'delete standard layer by id'
         | 
| 68 | 
            +
                    params do
         | 
| 69 | 
            +
                      requires :id, type: Integer, desc: 'Standard layer id'
         | 
| 70 | 
            +
                    end
         | 
| 71 | 
            +
                    route_param :id do
         | 
| 72 | 
            +
                      before do
         | 
| 73 | 
            +
                        authenticate_admin!('standard_layers')
         | 
| 74 | 
            +
                      end
         | 
| 75 | 
            +
                      delete do
         | 
| 76 | 
            +
                        entity = Labimotion::StdLayer.find(params[:id])
         | 
| 77 | 
            +
                        entity.destroy
         | 
| 78 | 
            +
                        return { mc: 'ss00', data: {} }
         | 
| 79 | 
            +
                      rescue StandardError => e
         | 
| 80 | 
            +
                        Labimotion.log_exception(e, current_user)
         | 
| 81 | 
            +
                        { mc: 'se00', msg: e.message, data: [] }
         | 
| 82 | 
            +
                      end
         | 
| 83 | 
            +
                    end
         | 
| 84 | 
            +
                  end
         | 
| 85 | 
            +
                end
         | 
| 86 | 
            +
              end
         | 
| 87 | 
            +
            end
         | 
| @@ -0,0 +1,93 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'labimotion/version'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module Labimotion
         | 
| 6 | 
            +
              # Generic Element API
         | 
| 7 | 
            +
              class VocabularyAPI < Grape::API
         | 
| 8 | 
            +
                include Grape::Kaminari
         | 
| 9 | 
            +
                helpers Labimotion::ParamHelpers
         | 
| 10 | 
            +
                helpers Labimotion::GenericHelpers
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                resource :vocab do
         | 
| 13 | 
            +
                  namespace :save_vocabulary do
         | 
| 14 | 
            +
                    desc 'Save vocabularies'
         | 
| 15 | 
            +
                    params do
         | 
| 16 | 
            +
                      use :vocab_save
         | 
| 17 | 
            +
                    end
         | 
| 18 | 
            +
                    before do
         | 
| 19 | 
            +
                      authenticate_admin!('vocabularies')
         | 
| 20 | 
            +
                    rescue ActiveRecord::RecordNotFound
         | 
| 21 | 
            +
                      error!('404 Not Found', 404)
         | 
| 22 | 
            +
                    end
         | 
| 23 | 
            +
                    post do
         | 
| 24 | 
            +
                      attributes = {
         | 
| 25 | 
            +
                        name: params[:name],
         | 
| 26 | 
            +
                        label: params[:label],
         | 
| 27 | 
            +
                        field_type: params[:field_type],
         | 
| 28 | 
            +
                        opid: 8,
         | 
| 29 | 
            +
                        term_id: params[:term_id],
         | 
| 30 | 
            +
                        source: params[:source],
         | 
| 31 | 
            +
                        source_id: params[:source_id],
         | 
| 32 | 
            +
                        layer_id: params[:layer_id],
         | 
| 33 | 
            +
                        field_id: params[:name],
         | 
| 34 | 
            +
                        identifier: params[:source_id],
         | 
| 35 | 
            +
                        created_by: current_user.id,
         | 
| 36 | 
            +
                        properties: declared(params, include_missing: false),
         | 
| 37 | 
            +
                      }
         | 
| 38 | 
            +
                      voc = Labimotion::Vocabulary.new(attributes)
         | 
| 39 | 
            +
                      voc.save!
         | 
| 40 | 
            +
                      { mc: 'ss00', data: voc }
         | 
| 41 | 
            +
                    rescue StandardError => e
         | 
| 42 | 
            +
                      Labimotion.log_exception(e, current_user)
         | 
| 43 | 
            +
                      { mc: 'se00', msg: e.message, data: {} }
         | 
| 44 | 
            +
                    end
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                  namespace :get_all_vocabularies do
         | 
| 48 | 
            +
                    desc 'get all standard layers for designer'
         | 
| 49 | 
            +
                    get do
         | 
| 50 | 
            +
                      authenticate_admin!('vocabularies')
         | 
| 51 | 
            +
                      combined_data = Labimotion::VocabularyHandler.load_all_vocabularies
         | 
| 52 | 
            +
                      return { mc: 'ss00', data: combined_data }
         | 
| 53 | 
            +
                    rescue StandardError => e
         | 
| 54 | 
            +
                      Labimotion.log_exception(e, current_user)
         | 
| 55 | 
            +
                      { mc: 'se00', msg: e.message, data: [] }
         | 
| 56 | 
            +
                    end
         | 
| 57 | 
            +
                  end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                  namespace :field_klasses do
         | 
| 60 | 
            +
                    desc 'get all field klasses for admin function'
         | 
| 61 | 
            +
                    get do
         | 
| 62 | 
            +
                      authenticate_admin!('vocabularies')
         | 
| 63 | 
            +
                      vocabularies = Labimotion::VocabularyHandler.load_app_vocabularies
         | 
| 64 | 
            +
                      merged_data = Labimotion::FieldKlassEntity.represent(vocabularies, serializable: true)
         | 
| 65 | 
            +
                      merged_data
         | 
| 66 | 
            +
                    rescue StandardError => e
         | 
| 67 | 
            +
                      Labimotion.log_exception(e, current_user)
         | 
| 68 | 
            +
                      []
         | 
| 69 | 
            +
                    end
         | 
| 70 | 
            +
                  end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                  namespace :delete_vocabulary do
         | 
| 73 | 
            +
                    desc 'delete vocabulary by id'
         | 
| 74 | 
            +
                    params do
         | 
| 75 | 
            +
                      requires :id, type: Integer, desc: 'Vocabulary id'
         | 
| 76 | 
            +
                    end
         | 
| 77 | 
            +
                    route_param :id do
         | 
| 78 | 
            +
                      before do
         | 
| 79 | 
            +
                        authenticate_admin!('vocabularies')
         | 
| 80 | 
            +
                      end
         | 
| 81 | 
            +
                      delete do
         | 
| 82 | 
            +
                        entity = Labimotion::Vocabulary.find(params[:id])
         | 
| 83 | 
            +
                        entity.destroy
         | 
| 84 | 
            +
                        return { mc: 'ss00', data: {} }
         | 
| 85 | 
            +
                      rescue StandardError => e
         | 
| 86 | 
            +
                        Labimotion.log_exception(e, current_user)
         | 
| 87 | 
            +
                        { mc: 'se00', msg: e.message, data: [] }
         | 
| 88 | 
            +
                      end
         | 
| 89 | 
            +
                    end
         | 
| 90 | 
            +
                  end
         | 
| 91 | 
            +
                end
         | 
| 92 | 
            +
              end
         | 
| 93 | 
            +
            end
         | 
| @@ -0,0 +1,21 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Labimotion
         | 
| 4 | 
            +
              module Constants
         | 
| 5 | 
            +
                module DateTime
         | 
| 6 | 
            +
                  DATE_FORMAT = '%Y-%m-%d'
         | 
| 7 | 
            +
                  DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S %Z'
         | 
| 8 | 
            +
                  TIME_FORMAT = '%H:%M:%S %Z'
         | 
| 9 | 
            +
                  TIME_ZONE = 'UTC'
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                module File
         | 
| 13 | 
            +
                  ENCODING = 'UTF-8'
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                module Mapper
         | 
| 17 | 
            +
                  NMR_CONFIG = ::File.join(__dir__, 'libs', 'data', 'mapper', 'Source.json').freeze
         | 
| 18 | 
            +
                  WIKI_CONFIG = ::File.join(__dir__, 'libs', 'data', 'mapper', 'Chemwiki.json').freeze
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
            end
         | 
| @@ -3,7 +3,7 @@ | |
| 3 3 | 
             
            require 'labimotion/entities/application_entity'
         | 
| 4 4 | 
             
            module Labimotion
         | 
| 5 5 | 
             
              # Dataset entity
         | 
| 6 | 
            -
              class DatasetEntity <  | 
| 6 | 
            +
              class DatasetEntity < PropertiesEntity
         | 
| 7 7 | 
             
                expose :id, :dataset_klass_id, :properties, :properties_release, :element_id, :element_type, :klass_ols, :klass_label, :klass_uuid
         | 
| 8 8 | 
             
                def klass_ols
         | 
| 9 9 | 
             
                  object&.dataset_klass&.ols_term_id
         | 
| @@ -1,91 +1,264 @@ | |
| 1 1 | 
             
            require 'labimotion/entities/application_entity'
         | 
| 2 2 |  | 
| 3 | 
            -
            # Entity module
         | 
| 4 3 | 
             
            module Labimotion
         | 
| 5 4 | 
             
              class PropertiesEntity < Labimotion::ApplicationEntity
         | 
| 6 | 
            -
             | 
| 7 | 
            -
                # TODO: Refactor this method to something more readable/understandable
         | 
| 8 5 | 
             
                def properties
         | 
| 9 | 
            -
                   | 
| 10 | 
            -
                     | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 14 | 
            -
                      sid = field.dig('value', 'el_id')
         | 
| 15 | 
            -
                      next unless sid.present?
         | 
| 16 | 
            -
             | 
| 17 | 
            -
                      el = field['type'] == Labimotion::FieldType::DRAG_SAMPLE ? Sample.find_by(id: sid) : Molecule.find_by(id: sid)
         | 
| 18 | 
            -
                      next unless el.present?
         | 
| 19 | 
            -
                      next unless object.properties.dig(Labimotion::Prop::LAYERS, key, Labimotion::Prop::FIELDS, idx, 'value').present?
         | 
| 20 | 
            -
             | 
| 21 | 
            -
                      object.properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]['value']['el_label'] = el.short_label if field['type'] == Labimotion::FieldType::DRAG_SAMPLE
         | 
| 22 | 
            -
                      object.properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]['value']['el_tip'] = el.short_label if field['type'] == Labimotion::FieldType::DRAG_SAMPLE
         | 
| 23 | 
            -
                      object.properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]['value']['el_svg'] = field['type'] == Labimotion::FieldType::DRAG_SAMPLE ? el.get_svg_path : File.join('/images', 'molecules', el&.molecule_svg_file || 'nosvg')
         | 
| 24 | 
            -
                    end
         | 
| 6 | 
            +
                  process_layers do |key, layer|
         | 
| 7 | 
            +
                    process_fields(key, layer)
         | 
| 8 | 
            +
                  end
         | 
| 9 | 
            +
                  object.properties
         | 
| 10 | 
            +
                end
         | 
| 25 11 |  | 
| 26 | 
            -
             | 
| 27 | 
            -
                    field_sys_reactions.each do |field|
         | 
| 28 | 
            -
                      idx = object.properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS].index(field)
         | 
| 29 | 
            -
                      sid = field.dig('value', 'el_id')
         | 
| 30 | 
            -
                      next unless sid.present?
         | 
| 12 | 
            +
                private
         | 
| 31 13 |  | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 14 | 
            +
                def process_layers
         | 
| 15 | 
            +
                  (object&.properties.is_a?(Hash) && (object.properties[Labimotion::Prop::LAYERS]&.keys || [])).each do |key|
         | 
| 16 | 
            +
                    yield(key, object.properties[Labimotion::Prop::LAYERS][key])
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
                end
         | 
| 37 19 |  | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 20 | 
            +
                def process_fields(key, layer)
         | 
| 21 | 
            +
                  process_sample_and_molecule_fields(key, layer)
         | 
| 22 | 
            +
                  process_reaction_fields(key, layer)
         | 
| 23 | 
            +
                  process_table_fields(key, layer)
         | 
| 24 | 
            +
                  # process_voc_fields(key, layer)
         | 
| 25 | 
            +
                end
         | 
| 40 26 |  | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 44 | 
            -
                     | 
| 27 | 
            +
                def process_sample_and_molecule_fields(key, layer)
         | 
| 28 | 
            +
                  select_fields(layer,
         | 
| 29 | 
            +
                                [Labimotion::FieldType::DRAG_SAMPLE, Labimotion::FieldType::DRAG_MOLECULE]).each do |field, idx|
         | 
| 30 | 
            +
                    update_sample_or_molecule_field(key, field, idx)
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                def process_reaction_fields(key, layer)
         | 
| 35 | 
            +
                  select_fields(layer, [Labimotion::FieldType::SYS_REACTION]).each do |field, idx|
         | 
| 36 | 
            +
                    update_reaction_field(key, field, idx)
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                def process_table_fields(key, layer)
         | 
| 41 | 
            +
                  select_fields(layer, [Labimotion::FieldType::TABLE]).each do |field, idx|
         | 
| 42 | 
            +
                    update_table_field(key, field, idx)
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                def process_voc_fields(key, layer)
         | 
| 47 | 
            +
                  select_fields(layer, nil, true).each do |field, idx|
         | 
| 48 | 
            +
                    update_voc_field(key, field, idx)
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                def select_fields(layer, types = nil, is_voc = false)
         | 
| 53 | 
            +
                  fields = layer[Labimotion::Prop::FIELDS]
         | 
| 54 | 
            +
                  fields = fields.select { |f| types.include?(f['type']) } if types
         | 
| 55 | 
            +
                  fields = fields.select { |f| f['is_voc'] == true } if is_voc
         | 
| 56 | 
            +
                  fields.map { |f| [f, layer[Labimotion::Prop::FIELDS].index(f)] }
         | 
| 57 | 
            +
                end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                def update_sample_or_molecule_field(key, field, idx)
         | 
| 60 | 
            +
                  sid = field.dig('value', 'el_id')
         | 
| 61 | 
            +
                  return unless sid.present?
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                  el = field['type'] == Labimotion::FieldType::DRAG_SAMPLE ? Sample.find_by(id: sid) : Molecule.find_by(id: sid)
         | 
| 64 | 
            +
                  return unless el.present? && object.properties.dig(Labimotion::Prop::LAYERS, key, Labimotion::Prop::FIELDS, idx,
         | 
| 65 | 
            +
                                                                     'value').present?
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                  label = field['type'] == Labimotion::FieldType::DRAG_SAMPLE ? el&.short_label : el.iupac_name
         | 
| 68 | 
            +
                  update_field_value(key, idx, {
         | 
| 69 | 
            +
                                       'el_label' => label,
         | 
| 70 | 
            +
                                       'el_tip' => label,
         | 
| 71 | 
            +
                                       'el_svg' => if field['type'] == Labimotion::FieldType::DRAG_SAMPLE
         | 
| 72 | 
            +
                                                     el&.get_svg_path
         | 
| 73 | 
            +
                                                   else
         | 
| 74 | 
            +
                                                     File.join('/images',
         | 
| 75 | 
            +
                                                               'molecules', el&.molecule_svg_file || 'nosvg')
         | 
| 76 | 
            +
                                                   end
         | 
| 77 | 
            +
                                     })
         | 
| 78 | 
            +
                end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                def update_reaction_field(key, field, idx)
         | 
| 81 | 
            +
                  sid = field.dig('value', 'el_id')
         | 
| 82 | 
            +
                  return unless sid.present?
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                  el = Reaction.find_by(id: sid)
         | 
| 85 | 
            +
                  if el.blank?
         | 
| 86 | 
            +
                    update_field_value(key, idx, { 'el_tip' => 'ERROR', 'el_svg' => '' })
         | 
| 87 | 
            +
                    return
         | 
| 88 | 
            +
                  end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                  return unless object.properties.dig(Labimotion::Prop::LAYERS, key, Labimotion::Prop::FIELDS, idx,
         | 
| 91 | 
            +
                                                      'value').present?
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                  update_field_value(key, idx, {
         | 
| 94 | 
            +
                                       'el_label' => el.short_label,
         | 
| 95 | 
            +
                                       'el_tip' => el.short_label,
         | 
| 96 | 
            +
                                       'el_svg' => el.reaction_svg_file
         | 
| 97 | 
            +
                                     })
         | 
| 98 | 
            +
                end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                def update_table_field(key, field, idx)
         | 
| 101 | 
            +
                  return unless field['sub_values'].present? && field[Labimotion::Prop::SUBFIELDS].present?
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                  field_table_molecules = field[Labimotion::Prop::SUBFIELDS].select do |ss|
         | 
| 104 | 
            +
                    ss['type'] == Labimotion::FieldType::DRAG_MOLECULE
         | 
| 105 | 
            +
                  end
         | 
| 106 | 
            +
                  if field_table_molecules.present?
         | 
| 107 | 
            +
                    object.properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx] =
         | 
| 108 | 
            +
                      set_table(field, field_table_molecules, Labimotion::Prop::MOLECULE)
         | 
| 109 | 
            +
                  end
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                  field_table_samples = field[Labimotion::Prop::SUBFIELDS].select do |ss|
         | 
| 112 | 
            +
                    ss['type'] == Labimotion::FieldType::DRAG_SAMPLE
         | 
| 113 | 
            +
                  end
         | 
| 114 | 
            +
                  return unless field_table_samples.present?
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                  object.properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx] =
         | 
| 117 | 
            +
                    set_table(field, field_table_samples, Labimotion::Prop::SAMPLE)
         | 
| 118 | 
            +
                end
         | 
| 119 | 
            +
             | 
| 120 | 
            +
                def update_voc_field(key, field, idx)
         | 
| 121 | 
            +
                  root_element = get_root_element
         | 
| 122 | 
            +
                  case field['source']
         | 
| 123 | 
            +
                  when Labimotion::Prop::ELEMENT
         | 
| 124 | 
            +
                    update_element_voc_field(key, field, idx, root_element)
         | 
| 125 | 
            +
                  when Labimotion::Prop::SEGMENT
         | 
| 126 | 
            +
                    update_segment_voc_field(key, field, idx, root_element)
         | 
| 127 | 
            +
                  when Labimotion::Prop::DATASET
         | 
| 128 | 
            +
                    update_dataset_voc_field(key, field, idx, root_element)
         | 
| 129 | 
            +
                  end
         | 
| 130 | 
            +
                end
         | 
| 45 131 |  | 
| 46 | 
            -
             | 
| 47 | 
            -
             | 
| 48 | 
            -
             | 
| 49 | 
            -
             | 
| 132 | 
            +
                def get_root_element
         | 
| 133 | 
            +
                  case object.class.name
         | 
| 134 | 
            +
                  when Labimotion::Prop::L_ELEMENT
         | 
| 135 | 
            +
                    object
         | 
| 136 | 
            +
                  when Labimotion::Prop::L_SEGMENT
         | 
| 137 | 
            +
                    object&.element
         | 
| 138 | 
            +
                  when Labimotion::Prop::L_DATASET
         | 
| 139 | 
            +
                    object&.element&.root_element
         | 
| 140 | 
            +
                  end
         | 
| 141 | 
            +
                end
         | 
| 50 142 |  | 
| 51 | 
            -
             | 
| 52 | 
            -
             | 
| 143 | 
            +
                def update_element_voc_field(key, field, idx, root_element)
         | 
| 144 | 
            +
                  return unless field['identifier'] == 'element.name'
         | 
| 145 | 
            +
             | 
| 146 | 
            +
                  update_field_value(key, idx, root_element&.name)
         | 
| 147 | 
            +
                end
         | 
| 53 148 |  | 
| 54 | 
            -
             | 
| 55 | 
            -
             | 
| 149 | 
            +
                def update_segment_voc_field(key, field, idx, root_element)
         | 
| 150 | 
            +
                  segs = root_element&.segments&.select { |ss| field['source_id'] == ss.segment_klass&.identifier }
         | 
| 151 | 
            +
                  return if segs.empty? || field['layer_id'].blank? || field['field_id'].blank?
         | 
| 152 | 
            +
             | 
| 153 | 
            +
                  seg = segs&.first
         | 
| 154 | 
            +
                  seg_fields = seg.properties.dig(Labimotion::Prop::LAYERS, field['layer_id'],
         | 
| 155 | 
            +
                                                  Labimotion::Prop::FIELDS).select do |ff|
         | 
| 156 | 
            +
                    ff['field'] == field['field_id']
         | 
| 157 | 
            +
                  end
         | 
| 158 | 
            +
                  seg_field = seg_fields&.first
         | 
| 159 | 
            +
                  update_field_value(key, idx, seg_field['value'])
         | 
| 160 | 
            +
                end
         | 
| 161 | 
            +
             | 
| 162 | 
            +
                def update_dataset_voc_field(key, field, idx, root_element)
         | 
| 163 | 
            +
                  dk = DatasetKlass.find_by(identifier: field['source_id'])
         | 
| 164 | 
            +
                  dk['ols_term_id']
         | 
| 165 | 
            +
                  anas = root_element.analyses.select do |ana|
         | 
| 166 | 
            +
                    ana.extended_metadata['kind'].split('|')&.first&.strip == dk['ols_term_id']
         | 
| 167 | 
            +
                  end
         | 
| 168 | 
            +
                  anas.each do |ana|
         | 
| 169 | 
            +
                    ana.children.each do |cds|
         | 
| 170 | 
            +
                      next unless cds.dataset.present?
         | 
| 171 | 
            +
             | 
| 172 | 
            +
                      ds_prop = cds.dataset.properties
         | 
| 173 | 
            +
                      ds_fields = ds_prop.dig(Labimotion::Prop::LAYERS, field['layer_id'], Labimotion::Prop::FIELDS).select do |ff|
         | 
| 174 | 
            +
                        ff['field'] == field['field_id']
         | 
| 175 | 
            +
                      end
         | 
| 176 | 
            +
                      ds_field = ds_fields&.first
         | 
| 177 | 
            +
                      if object.properties[Labimotion::Prop::LAYERS][key].present? && ds_field['value'].present?
         | 
| 178 | 
            +
                        update_field_value(key, idx, ds_field['value'])
         | 
| 179 | 
            +
                      end
         | 
| 56 180 | 
             
                    end
         | 
| 57 181 | 
             
                  end
         | 
| 58 | 
            -
             | 
| 182 | 
            +
                end
         | 
| 183 | 
            +
             | 
| 184 | 
            +
                def update_field_value(key, idx, value, act = 'merge')
         | 
| 185 | 
            +
                  field_path = object.properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]
         | 
| 186 | 
            +
                  original_value = field_path['value']
         | 
| 187 | 
            +
             | 
| 188 | 
            +
                  field_path['value'] = merge_values(original_value, value, act)
         | 
| 189 | 
            +
                end
         | 
| 190 | 
            +
             | 
| 191 | 
            +
                def merge_by_type(original_value, new_value)
         | 
| 192 | 
            +
                  if original_value.is_a?(Hash)
         | 
| 193 | 
            +
                    merge_hash_values(original_value, new_value)
         | 
| 194 | 
            +
                  # elsif original_value.is_a?(Array)
         | 
| 195 | 
            +
                  #   merge_array_values(original_value, new_value)
         | 
| 196 | 
            +
                  else
         | 
| 197 | 
            +
                    new_value
         | 
| 198 | 
            +
                  end
         | 
| 199 | 
            +
                end
         | 
| 200 | 
            +
             | 
| 201 | 
            +
                def merge_values(original_value, new_value, act)
         | 
| 202 | 
            +
                  return new_value if act == 'overwrite'
         | 
| 203 | 
            +
                  return new_value if original_value.blank?
         | 
| 204 | 
            +
                  return original_value if new_value.blank?
         | 
| 205 | 
            +
             | 
| 206 | 
            +
                  merge_by_type(original_value, new_value)
         | 
| 59 207 | 
             
                end
         | 
| 60 208 |  | 
| 61 209 | 
             
                def set_table(field, field_table_objs, obj)
         | 
| 62 210 | 
             
                  col_ids = field_table_objs.map { |x| x.values[0] }
         | 
| 63 211 | 
             
                  col_ids.each do |col_id|
         | 
| 64 212 | 
             
                    field['sub_values'].each do |sub_value|
         | 
| 65 | 
            -
                       | 
| 213 | 
            +
                      unless sub_value[col_id].present? && sub_value[col_id]['value'].present? && sub_value[col_id]['value']['el_id'].present?
         | 
| 214 | 
            +
                        next
         | 
| 215 | 
            +
                      end
         | 
| 66 216 |  | 
| 67 217 | 
             
                      find_obj = obj.constantize.find_by(id: sub_value[col_id]['value']['el_id'])
         | 
| 68 218 | 
             
                      next if find_obj.blank?
         | 
| 69 219 |  | 
| 70 220 | 
             
                      case obj
         | 
| 71 221 | 
             
                      when Labimotion::Prop::MOLECULE
         | 
| 72 | 
            -
                        sub_value | 
| 73 | 
            -
                        sub_value[col_id]['value']['el_inchikey'] = find_obj.inchikey
         | 
| 74 | 
            -
                        sub_value[col_id]['value']['el_smiles'] = find_obj.cano_smiles
         | 
| 75 | 
            -
                        sub_value[col_id]['value']['el_iupac'] = find_obj.iupac_name
         | 
| 76 | 
            -
                        sub_value[col_id]['value']['el_molecular_weight'] = find_obj.molecular_weight
         | 
| 222 | 
            +
                        update_molecule_sub_value(sub_value, col_id, find_obj)
         | 
| 77 223 | 
             
                      when Labimotion::Prop::SAMPLE
         | 
| 78 | 
            -
                        sub_value | 
| 79 | 
            -
                        sub_value[col_id]['value']['el_label'] = find_obj.short_label
         | 
| 80 | 
            -
                        sub_value[col_id]['value']['el_short_label'] = find_obj.short_label
         | 
| 81 | 
            -
                        sub_value[col_id]['value']['el_name'] = find_obj.name
         | 
| 82 | 
            -
                        sub_value[col_id]['value']['el_external_label'] = find_obj.external_label
         | 
| 83 | 
            -
                        sub_value[col_id]['value']['el_molecular_weight'] = find_obj.decoupled ? find_obj.molecular_mass : find_obj.molecule.molecular_weight
         | 
| 224 | 
            +
                        update_sample_sub_value(sub_value, col_id, find_obj)
         | 
| 84 225 | 
             
                      end
         | 
| 85 226 | 
             
                    end
         | 
| 86 227 | 
             
                  end
         | 
| 87 228 | 
             
                  field
         | 
| 88 229 | 
             
                end
         | 
| 89 230 |  | 
| 231 | 
            +
                def update_molecule_sub_value(sub_value, col_id, find_obj)
         | 
| 232 | 
            +
                  sub_value[col_id]['value'].merge!({
         | 
| 233 | 
            +
                                                      'el_svg' => File.join('/images', 'molecules', find_obj.molecule_svg_file),
         | 
| 234 | 
            +
                                                      'el_inchikey' => find_obj.inchikey,
         | 
| 235 | 
            +
                                                      'el_smiles' => find_obj.cano_smiles,
         | 
| 236 | 
            +
                                                      'el_iupac' => find_obj.iupac_name,
         | 
| 237 | 
            +
                                                      'el_molecular_weight' => find_obj.molecular_weight
         | 
| 238 | 
            +
                                                    })
         | 
| 239 | 
            +
                end
         | 
| 240 | 
            +
             | 
| 241 | 
            +
                def update_sample_sub_value(sub_value, col_id, find_obj)
         | 
| 242 | 
            +
                  sub_value[col_id]['value'].merge!({
         | 
| 243 | 
            +
                                                      'el_svg' => find_obj.get_svg_path,
         | 
| 244 | 
            +
                                                      'el_label' => find_obj.short_label,
         | 
| 245 | 
            +
                                                      'el_short_label' => find_obj.short_label,
         | 
| 246 | 
            +
                                                      'el_name' => find_obj.name,
         | 
| 247 | 
            +
                                                      'el_external_label' => find_obj.external_label,
         | 
| 248 | 
            +
                                                      'el_molecular_weight' => find_obj.decoupled ? find_obj.molecular_mass : find_obj.molecule.molecular_weight
         | 
| 249 | 
            +
                                                    })
         | 
| 250 | 
            +
                end
         | 
| 251 | 
            +
             | 
| 252 | 
            +
                def merge_hash_values(original, new_value)
         | 
| 253 | 
            +
                  return original unless new_value.is_a?(Hash)
         | 
| 254 | 
            +
             | 
| 255 | 
            +
                  original.merge(new_value)
         | 
| 256 | 
            +
                end
         | 
| 257 | 
            +
             | 
| 258 | 
            +
                def merge_array_values(original, new_value)
         | 
| 259 | 
            +
                  return original unless new_value.respond_to?(:to_a)
         | 
| 260 | 
            +
             | 
| 261 | 
            +
                  (original + new_value.to_a).uniq
         | 
| 262 | 
            +
                end
         | 
| 90 263 | 
             
              end
         | 
| 91 264 | 
             
            end
         | 
| @@ -0,0 +1,28 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
            #
         | 
| 3 | 
            +
            require 'labimotion/entities/application_entity'
         | 
| 4 | 
            +
            module Labimotion
         | 
| 5 | 
            +
              # Dataset entity
         | 
| 6 | 
            +
              class VocabularyEntity < ApplicationEntity
         | 
| 7 | 
            +
                expose :id, :identifier, :name, :label, :field_type, :opid, :term_id,
         | 
| 8 | 
            +
                       :field_id, :properties, :source, :source_id, :layer_id
         | 
| 9 | 
            +
                expose :voc do |obj|
         | 
| 10 | 
            +
                  voc = (obj[:properties] && obj[:properties]['voc']) || {}
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  case voc['source']
         | 
| 13 | 
            +
                  when Labimotion::Prop::ELEMENT
         | 
| 14 | 
            +
                    if voc['identifier'] == 'element.name'
         | 
| 15 | 
            +
                      # voc['source_name'] = ElementKlass.find_by(identifier: voc['source_id'])&.name
         | 
| 16 | 
            +
                    end
         | 
| 17 | 
            +
                  when Labimotion::Prop::SEGMENT
         | 
| 18 | 
            +
                    voc['source_name'] = SegmentKlass.find_by(identifier: voc['source_id'])&.label
         | 
| 19 | 
            +
                  when Labimotion::Prop::DATASET
         | 
| 20 | 
            +
                    voc['source_name'] = DatasetKlass.find_by(identifier: voc['source_id'])&.label
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
                  voc
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
                expose :ontology do |obj|
         | 
| 25 | 
            +
                  (obj[:properties] && obj[:properties]['ontology']) || {}
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
            end
         |