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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/lib/labimotion/apis/generic_element_api.rb +1 -0
  3. data/lib/labimotion/apis/generic_klass_api.rb +3 -2
  4. data/lib/labimotion/apis/labimotion_api.rb +13 -0
  5. data/lib/labimotion/apis/standard_api.rb +25 -0
  6. data/lib/labimotion/apis/standard_layer_api.rb +87 -0
  7. data/lib/labimotion/apis/vocabulary_api.rb +93 -0
  8. data/lib/labimotion/constants.rb +21 -0
  9. data/lib/labimotion/entities/dataset_entity.rb +1 -1
  10. data/lib/labimotion/entities/element_entity.rb +1 -0
  11. data/lib/labimotion/entities/properties_entity.rb +229 -56
  12. data/lib/labimotion/entities/segment_entity.rb +0 -1
  13. data/lib/labimotion/entities/vocabulary_entity.rb +28 -0
  14. data/lib/labimotion/helpers/element_helpers.rb +8 -6
  15. data/lib/labimotion/helpers/generic_helpers.rb +6 -1
  16. data/lib/labimotion/helpers/param_helpers.rb +121 -82
  17. data/lib/labimotion/helpers/segment_helpers.rb +1 -1
  18. data/lib/labimotion/helpers/vocabulary_helpers.rb +16 -0
  19. data/lib/labimotion/libs/converter.rb +12 -33
  20. data/lib/labimotion/libs/data/mapper/Chemwiki.json +236 -0
  21. data/lib/labimotion/libs/data/mapper/Source.json +78 -0
  22. data/lib/labimotion/libs/data/vocab/Standard.json +385 -0
  23. data/lib/labimotion/libs/data/vocab/System.json +131 -0
  24. data/lib/labimotion/libs/dataset_builder.rb +70 -0
  25. data/lib/labimotion/libs/export_dataset.rb +165 -66
  26. data/lib/labimotion/libs/nmr_mapper.rb +204 -246
  27. data/lib/labimotion/libs/sample_association.rb +4 -0
  28. data/lib/labimotion/libs/vocabulary_handler.rb +118 -0
  29. data/lib/labimotion/models/concerns/attachment_converter.rb +5 -4
  30. data/lib/labimotion/models/concerns/datasetable.rb +1 -0
  31. data/lib/labimotion/models/concerns/segmentable.rb +2 -0
  32. data/lib/labimotion/models/element.rb +3 -0
  33. data/lib/labimotion/models/std_layer.rb +9 -0
  34. data/lib/labimotion/models/std_layers_revision.rb +9 -0
  35. data/lib/labimotion/models/vocabulary.rb +12 -0
  36. data/lib/labimotion/utils/mapper_utils.rb +169 -0
  37. data/lib/labimotion/utils/utils.rb +22 -0
  38. data/lib/labimotion/version.rb +1 -1
  39. data/lib/labimotion.rb +13 -3
  40. metadata +25 -5
@@ -25,17 +25,18 @@ module Labimotion
25
25
  def exec_converter
26
26
  return if self.has_attribute?(:con_state) == false || self.con_state.nil? || self.con_state == Labimotion::ConState::NONE
27
27
 
28
- return if attachable_id.nil? && self.con_state != Labimotion::ConState::WAIT
28
+ return if attachable_id.nil? && con_state != Labimotion::ConState::WAIT
29
29
 
30
+ current_user = User.find_by(id: created_by)
30
31
  case con_state
31
32
  when Labimotion::ConState::NMR
32
- self.con_state = Labimotion::NmrMapper.process_ds(id)
33
+ self.con_state = Labimotion::NmrMapper.process_ds(id, current_user)
33
34
  update_column(:con_state, con_state)
34
35
  when Labimotion::ConState::WAIT
35
- self.con_state = Labimotion::Converter.jcamp_converter(id)
36
+ self.con_state = Labimotion::Converter.jcamp_converter(id, current_user)
36
37
  update_column(:con_state, con_state)
37
38
  when Labimotion::ConState::CONVERTED
38
- Labimotion::Converter.metadata(id)
39
+ Labimotion::Converter.metadata(id, current_user)
39
40
  end
40
41
  end
41
42
  end
@@ -42,6 +42,7 @@ module Labimotion
42
42
  props['identifier'] = klass.identifier if klass.identifier.present?
43
43
  props['uuid'] = uuid
44
44
  props['klass'] = 'Dataset'
45
+ props = Labimotion::VocabularyHandler.update_vocabularies(props, args[:current_user], args[:element])
45
46
 
46
47
  ds = Labimotion::Dataset.find_by(element_type: self.class.name, element_id: id)
47
48
  if ds.present? && (ds.klass_uuid != props['klass_uuid'] || ds.properties != props)
@@ -59,6 +59,8 @@ module Labimotion
59
59
  props['uuid'] = uuid
60
60
  props['klass'] = 'Segment'
61
61
  props = Labimotion::SampleAssociation.update_sample_association(props, args[:current_user_id])
62
+ current_user = User.find_by(id: args[:current_user_id])
63
+ props = Labimotion::VocabularyHandler.update_vocabularies(props, current_user, self)
62
64
  segment = Labimotion::Segment.where(element_type: self.class.name, element_id: self.id, segment_klass_id: seg['segment_klass_id']).order(id: :desc).first
63
65
  if segment.present? && (segment.klass_uuid != props['klass_uuid'] || segment.properties != props)
64
66
  segment.update!(properties_release: klass.properties_release, properties: props, uuid: uuid, klass_uuid: props['klass_uuid'])
@@ -58,6 +58,9 @@ module Labimotion
58
58
  after_create :update_counter
59
59
  before_destroy :delete_attachment
60
60
 
61
+ def user_labels
62
+ tag&.taggable_data&.fetch('user_labels', nil)
63
+ end
61
64
 
62
65
  def attachments
63
66
  Attachment.where(attachable_id: self.id, attachable_type: self.class.name)
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Labimotion
4
+ class StdLayer < ApplicationRecord
5
+ acts_as_paranoid
6
+ self.table_name = :layers
7
+ has_many :layer_tracks, primary_key: 'identifier', foreign_key: 'identifier', class_name: 'Labimotion::StdLayersRevision'
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Labimotion
4
+ class StdLayersRevision < ApplicationRecord
5
+ acts_as_paranoid
6
+ self.table_name = :layer_tracks
7
+ belongs_to :layers, primary_key: 'identifier', foreign_key: 'identifier', class_name: 'Labimotion::StdLayer'
8
+ end
9
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+ require 'labimotion/models/concerns/generic_klass_revisions'
3
+ require 'labimotion/models/concerns/workflow'
4
+
5
+ module Labimotion
6
+ class Vocabulary < ApplicationRecord
7
+ self.table_name = :vocabularies
8
+ acts_as_paranoid
9
+
10
+
11
+ end
12
+ end
@@ -0,0 +1,169 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'time'
5
+ require 'zip'
6
+ require 'labimotion/constants'
7
+
8
+ module Labimotion
9
+ class MapperUtils
10
+ class << self
11
+ def load_config(config_json)
12
+ JSON.parse(config_json)
13
+ rescue JSON::ParserError => e
14
+ Rails.logger.error "Error parsing JSON: #{e.message}"
15
+ nil
16
+ rescue Errno::ENOENT => e
17
+ Rails.logger.error "Config file not found at #{Constants::Mapper::NMR_CONFIG}: #{e.message}"
18
+ nil
19
+ rescue StandardError => e
20
+ Rails.logger.error "Unexpected error loading config: #{e.message}"
21
+ nil
22
+ end
23
+
24
+ def load_brucker_config
25
+ config = load_config(File.read(Constants::Mapper::NMR_CONFIG))
26
+ return if config.nil? || config['sourceMap'].nil?
27
+
28
+ source_selector = config['sourceMap']['sourceSelector']
29
+ return if source_selector.blank?
30
+
31
+ parameters = config['sourceMap']['parameters']
32
+ return if parameters.blank?
33
+
34
+ config
35
+ end
36
+
37
+ def extract_data_from_zip(zip_file_url, source_map)
38
+ return nil if zip_file_url.nil?
39
+
40
+ process_zip_file(zip_file_url, source_map)
41
+ rescue Zip::Error => e
42
+ Rails.logger.error "Zip file error: #{e.message}"
43
+ nil
44
+ rescue StandardError => e
45
+ Rails.logger.error "Unexpected error extracting metadata: #{e.message}"
46
+ nil
47
+ end
48
+
49
+ def extract_parameters(file_content, parameter_names)
50
+ return nil if file_content.blank? || parameter_names.blank?
51
+
52
+ patterns = {
53
+ standard: build_parameter_pattern(parameter_names, :standard),
54
+ parm: build_parameter_pattern(parameter_names, :parm)
55
+ }
56
+
57
+ extracted_parameters = {}
58
+ begin
59
+ file_content.each_line do |line|
60
+ if (match = match_parameter(line, patterns))
61
+ value = clean_value(match[:value])
62
+ extracted_parameters[match[:param_name]] = value
63
+ end
64
+ end
65
+ rescue StandardError => e
66
+ Rails.logger.error "Error reading file content: #{e.message}"
67
+ return nil
68
+ end
69
+ extracted_parameters.compact_blank!
70
+ extracted_parameters
71
+ end
72
+
73
+ def format_timestamp(timestamp_str, give_format = nil)
74
+ return nil if timestamp_str.blank?
75
+
76
+ begin
77
+ timestamp = Integer(timestamp_str)
78
+ time_object = Time.at(timestamp).in_time_zone(Constants::DateTime::TIME_ZONE)
79
+ case give_format
80
+ when 'date'
81
+ time_object.strftime(Constants::DateTime::DATE_FORMAT)
82
+ when 'time'
83
+ time_object.strftime(Constants::DateTime::TIME_FORMAT)
84
+ else
85
+ time_object.strftime(Constants::DateTime::DATETIME_FORMAT)
86
+ end
87
+ rescue ArgumentError, TypeError => e
88
+ Rails.logger.error "Error parsing timestamp '#{timestamp_str}': #{e.message}"
89
+ nil
90
+ end
91
+ end
92
+
93
+ private
94
+
95
+ def build_parameter_pattern(parameter_names, format)
96
+ pattern = case format
97
+ when :standard
98
+ '^\\s*##?\\s*[$]?(?<param_name>%s)\\s*(?:=\\s*)?(?<value>.*?)\\s*$'
99
+ when :parm
100
+ '^\\s*(?<param_name>%s)\\s+(?<value>[^\\s].*?)(?:\\s+[A-Za-z]+)?\\s*$'
101
+ end
102
+
103
+ param_regex = parameter_names.map { |p| "\\b#{Regexp.escape(p)}\\b" }.join('|')
104
+ Regexp.new(pattern % param_regex)
105
+ end
106
+
107
+ def match_parameter(line, patterns)
108
+ patterns.each_value do |pattern|
109
+ match = line.match(pattern)
110
+ return match if match
111
+ end
112
+ nil
113
+ end
114
+
115
+ def clean_value(value)
116
+ value = value.strip
117
+ value = value[1..-2].strip if value.start_with?('<') && value.end_with?('>')
118
+ value
119
+ end
120
+
121
+ def process_zip_file(zip_file_url, source_map)
122
+ final_parameters = {}
123
+
124
+ Zip::File.open(zip_file_url) do |zip_file|
125
+ source_map['sourceSelector'].each do |source_name|
126
+ process_source(zip_file, source_map[source_name], final_parameters)
127
+ end
128
+ end
129
+
130
+ return { is_bagit: false, metadata: final_parameters } if final_parameters.present?
131
+
132
+ nil
133
+ end
134
+
135
+ def process_source(zip_file, source_config, final_parameters)
136
+ return if invalid_source_config?(source_config)
137
+
138
+ zip_file.each do |entry|
139
+ if source_file?(entry, source_config)
140
+ process_file_entry(entry, source_config['parameters'], final_parameters)
141
+ elsif bagit_metadata_file?(entry)
142
+ return { is_bagit: true, metadata: nil }
143
+ end
144
+ end
145
+ end
146
+
147
+ def process_file_entry(entry, parameters, final_parameters)
148
+ file_content = entry.get_input_stream.read.force_encoding(Constants::File::ENCODING)
149
+ extracted_parameters = extract_parameters(file_content, parameters)
150
+ final_parameters.merge!(extracted_parameters) if extracted_parameters.present?
151
+ end
152
+
153
+ def invalid_source_config?(source_config)
154
+ source_config.nil? ||
155
+ source_config['file'].nil? ||
156
+ source_config['parameters'].nil?
157
+ end
158
+
159
+ def source_file?(entry, source_config)
160
+ entry.name.include?(source_config['file'])
161
+ end
162
+
163
+ def bagit_metadata_file?(entry)
164
+ entry.name.include?('metadata/') &&
165
+ entry.name.include?('converter.json')
166
+ end
167
+ end
168
+ end
169
+ end
@@ -80,6 +80,28 @@ module Labimotion
80
80
  current_version
81
81
  end
82
82
 
83
+ def self.find_field(properties, field_path, separator = '.')
84
+ return if properties.nil? || field_path.nil?
85
+
86
+ layer_name, field_name = field_path.split(separator)
87
+ fields = properties.dig(Labimotion::Prop::LAYERS, layer_name, Labimotion::Prop::FIELDS)
88
+ return unless fields
89
+
90
+ fields.find { |f| f['field'] == field_name }
91
+ end
92
+
93
+ def self.find_options_val(field, properties)
94
+ return if field.nil? || properties.nil? || field['option_layers'].nil? || field['value'].nil?
95
+
96
+ option_layers = properties.dig(Labimotion::Prop::SEL_OPTIONS, field['option_layers'])
97
+ options = option_layers && option_layers['options']
98
+ return if options.nil?
99
+
100
+ sel_option = options.find { |o| o['key'] = field['value'] }
101
+ sel_option && sel_option['label']
102
+
103
+ end
104
+
83
105
  def self.pkg(pkg)
84
106
  pkg = {} if pkg.nil?
85
107
  pkg['eln'] = Chemotion::Application.config.version
@@ -2,5 +2,5 @@
2
2
 
3
3
  ## Labimotion Version
4
4
  module Labimotion
5
- VERSION = '1.4.1'
5
+ VERSION = '2.0.0.rc6'
6
6
  end
data/lib/labimotion.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  # In your_gem_name.rb or main Ruby file
2
2
  module Labimotion
3
-
4
3
  autoload :CONF, 'labimotion/conf'
5
4
  autoload :VERSION, 'labimotion/version'
5
+ autoload :Constants, 'labimotion/constants'
6
6
 
7
7
  def self.logger
8
8
  @@labimotion_logger ||= Logger.new(Rails.root.join('log/labimotion.log')) # rubocop:disable Style/ClassVars
@@ -13,15 +13,19 @@ module Labimotion
13
13
  Labimotion.logger.error(exception.backtrace.join("\n"))
14
14
  end
15
15
 
16
+ autoload :MapperUtils, 'labimotion/utils/mapper_utils'
16
17
  autoload :Utils, 'labimotion/utils/utils'
17
18
 
18
19
  ######## APIs
20
+ autoload :LabimotionAPI, 'labimotion/apis/labimotion_api'
19
21
  autoload :GenericKlassAPI, 'labimotion/apis/generic_klass_api'
20
22
  autoload :GenericElementAPI, 'labimotion/apis/generic_element_api'
21
23
  autoload :GenericDatasetAPI, 'labimotion/apis/generic_dataset_api'
22
24
  autoload :SegmentAPI, 'labimotion/apis/segment_api'
23
25
  autoload :LabimotionHubAPI, 'labimotion/apis/labimotion_hub_api'
24
26
  autoload :ConverterAPI, 'labimotion/apis/converter_api'
27
+ autoload :StandardLayerAPI, 'labimotion/apis/standard_layer_api'
28
+ autoload :VocabularyAPI, 'labimotion/apis/vocabulary_api'
25
29
 
26
30
  ######## Entities
27
31
  autoload :PropertiesEntity, 'labimotion/entities/properties_entity'
@@ -43,6 +47,7 @@ module Labimotion
43
47
  autoload :ElementRevisionEntity, 'labimotion/entities/element_revision_entity'
44
48
  autoload :SegmentRevisionEntity, 'labimotion/entities/segment_revision_entity'
45
49
  ## autoload :DatasetRevisionEntity, 'labimotion/entities/dataset_revision_entity'
50
+ autoload :VocabularyEntity, 'labimotion/entities/vocabulary_entity'
46
51
 
47
52
  ######## Helpers
48
53
  autoload :GenericHelpers, 'labimotion/helpers/generic_helpers'
@@ -54,9 +59,11 @@ module Labimotion
54
59
  autoload :ConverterHelpers, 'labimotion/helpers/converter_helpers'
55
60
  autoload :SampleAssociationHelpers, 'labimotion/helpers/sample_association_helpers'
56
61
  autoload :RepositoryHelpers, 'labimotion/helpers/repository_helpers'
62
+ autoload :VocabularyHelpers, 'labimotion/helpers/vocabulary_helpers'
57
63
 
58
64
  ######## Libs
59
65
  autoload :Converter, 'labimotion/libs/converter'
66
+ autoload :DatasetBuilder, 'labimotion/libs/dataset_builder'
60
67
  autoload :NmrMapper, 'labimotion/libs/nmr_mapper'
61
68
  autoload :NmrMapperRepo, 'labimotion/libs/nmr_mapper_repo' ## for Chemotion Repository
62
69
  autoload :TemplateHub, 'labimotion/libs/template_hub'
@@ -64,6 +71,7 @@ module Labimotion
64
71
  autoload :SampleAssociation, 'labimotion/libs/sample_association'
65
72
  autoload :PropertiesHandler, 'labimotion/libs/properties_handler'
66
73
  autoload :AttachmentHandler, 'labimotion/libs/attachment_handler'
74
+ autoload :VocabularyHandler, 'labimotion/libs/vocabulary_handler'
67
75
 
68
76
  ######## Utils
69
77
  autoload :Prop, 'labimotion/utils/prop'
@@ -84,6 +92,7 @@ module Labimotion
84
92
  autoload :ElementKlass, 'labimotion/models/element_klass'
85
93
  autoload :SegmentKlass, 'labimotion/models/segment_klass'
86
94
  autoload :DatasetKlass, 'labimotion/models/dataset_klass'
95
+ autoload :Vocabulary, 'labimotion/models/vocabulary'
87
96
 
88
97
  autoload :ElementsRevision, 'labimotion/models/elements_revision'
89
98
  autoload :SegmentsRevision, 'labimotion/models/segments_revision'
@@ -97,6 +106,9 @@ module Labimotion
97
106
  autoload :ElementsElement, 'labimotion/models/elements_element'
98
107
  autoload :CollectionsElement, 'labimotion/models/collections_element'
99
108
 
109
+ autoload :StdLayer, 'labimotion/models/std_layer'
110
+ autoload :StdLayersRevision, 'labimotion/models/std_layers_revision'
111
+
100
112
  ######## Models/Concerns
101
113
  autoload :GenericKlassRevisions, 'labimotion/models/concerns/generic_klass_revisions'
102
114
  autoload :GenericRevisions, 'labimotion/models/concerns/generic_revisions'
@@ -104,6 +116,4 @@ module Labimotion
104
116
  autoload :Datasetable, 'labimotion/models/concerns/datasetable'
105
117
  autoload :AttachmentConverter, 'labimotion/models/concerns/attachment_converter.rb'
106
118
  autoload :LinkedProperties, 'labimotion/models/concerns/linked_properties'
107
-
108
-
109
119
  end
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: 1.4.1
4
+ version: 2.0.0.rc6
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: 2024-10-24 00:00:00.000000000 Z
12
+ date: 2025-02-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -38,11 +38,16 @@ files:
38
38
  - lib/labimotion/apis/generic_dataset_api.rb
39
39
  - lib/labimotion/apis/generic_element_api.rb
40
40
  - lib/labimotion/apis/generic_klass_api.rb
41
+ - lib/labimotion/apis/labimotion_api.rb
41
42
  - lib/labimotion/apis/labimotion_hub_api.rb
42
43
  - lib/labimotion/apis/segment_api.rb
44
+ - lib/labimotion/apis/standard_api.rb
45
+ - lib/labimotion/apis/standard_layer_api.rb
46
+ - lib/labimotion/apis/vocabulary_api.rb
43
47
  - lib/labimotion/collection/export.rb
44
48
  - lib/labimotion/collection/import.rb
45
49
  - lib/labimotion/conf.rb
50
+ - lib/labimotion/constants.rb
46
51
  - lib/labimotion/entities/application_entity.rb
47
52
  - lib/labimotion/entities/dataset_entity.rb
48
53
  - lib/labimotion/entities/dataset_klass_entity.rb
@@ -58,6 +63,7 @@ files:
58
63
  - lib/labimotion/entities/segment_entity.rb
59
64
  - lib/labimotion/entities/segment_klass_entity.rb
60
65
  - lib/labimotion/entities/segment_revision_entity.rb
66
+ - lib/labimotion/entities/vocabulary_entity.rb
61
67
  - lib/labimotion/helpers/converter_helpers.rb
62
68
  - lib/labimotion/helpers/dataset_helpers.rb
63
69
  - lib/labimotion/helpers/element_helpers.rb
@@ -67,14 +73,21 @@ files:
67
73
  - lib/labimotion/helpers/sample_association_helpers.rb
68
74
  - lib/labimotion/helpers/search_helpers.rb
69
75
  - lib/labimotion/helpers/segment_helpers.rb
76
+ - lib/labimotion/helpers/vocabulary_helpers.rb
70
77
  - lib/labimotion/libs/attachment_handler.rb
71
78
  - lib/labimotion/libs/converter.rb
79
+ - lib/labimotion/libs/data/mapper/Chemwiki.json
80
+ - lib/labimotion/libs/data/mapper/Source.json
81
+ - lib/labimotion/libs/data/vocab/Standard.json
82
+ - lib/labimotion/libs/data/vocab/System.json
83
+ - lib/labimotion/libs/dataset_builder.rb
72
84
  - lib/labimotion/libs/export_dataset.rb
73
85
  - lib/labimotion/libs/export_element.rb
74
86
  - lib/labimotion/libs/nmr_mapper.rb
75
87
  - lib/labimotion/libs/properties_handler.rb
76
88
  - lib/labimotion/libs/sample_association.rb
77
89
  - lib/labimotion/libs/template_hub.rb
90
+ - lib/labimotion/libs/vocabulary_handler.rb
78
91
  - lib/labimotion/models/collections_element.rb
79
92
  - lib/labimotion/models/concerns/attachment_converter.rb
80
93
  - lib/labimotion/models/concerns/datasetable.rb
@@ -98,10 +111,14 @@ files:
98
111
  - lib/labimotion/models/segment_klass.rb
99
112
  - lib/labimotion/models/segment_klasses_revision.rb
100
113
  - lib/labimotion/models/segments_revision.rb
114
+ - lib/labimotion/models/std_layer.rb
115
+ - lib/labimotion/models/std_layers_revision.rb
116
+ - lib/labimotion/models/vocabulary.rb
101
117
  - lib/labimotion/utils/con_state.rb
102
118
  - lib/labimotion/utils/export_utils.rb
103
119
  - lib/labimotion/utils/field_type.rb
104
120
  - lib/labimotion/utils/import_utils.rb
121
+ - lib/labimotion/utils/mapper_utils.rb
105
122
  - lib/labimotion/utils/prop.rb
106
123
  - lib/labimotion/utils/search.rb
107
124
  - lib/labimotion/utils/serializer.rb
@@ -111,7 +128,10 @@ files:
111
128
  homepage: https://github.com/LabIMotion/labimotion
112
129
  licenses:
113
130
  - AGPL-3.0
114
- metadata: {}
131
+ metadata:
132
+ homepage_uri: https://github.com/LabIMotion/labimotion
133
+ source_code_uri: https://github.com/LabIMotion/labimotion
134
+ bug_tracker_uri: https://github.com/LabIMotion/labimotion/discussions
115
135
  post_install_message:
116
136
  rdoc_options: []
117
137
  require_paths:
@@ -123,9 +143,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
123
143
  version: '0'
124
144
  required_rubygems_version: !ruby/object:Gem::Requirement
125
145
  requirements:
126
- - - ">="
146
+ - - ">"
127
147
  - !ruby/object:Gem::Version
128
- version: '0'
148
+ version: 1.3.1
129
149
  requirements: []
130
150
  rubygems_version: 3.1.6
131
151
  signing_key: