labimotion 2.2.0.rc9 → 2.2.0.rc11

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.
data/README.md ADDED
@@ -0,0 +1,68 @@
1
+ # LabIMotion [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.3755759.svg)](https://doi.org/10.5281/zenodo.8305411)
2
+
3
+ LabIMotion is a software that offers the flexibility to design new modules tailored to the specific needs of the scientists.
4
+ Generic elements, segments, and datasets are organized using Components, which are introduced as layers and fields. Each generic element, segment, or dataset can include multiple layers, with the potential for multiple fields within each layer. This hierarchical structure enables a flexible and comprehensive organization of data and information.
5
+
6
+
7
+
8
+ ![Design Principles](https://www.chemotion.net/assets/images/generic_feature_outline-a58eee8e02ca7247e54f7ad17ee2c102.png)
9
+
10
+
11
+ ## Version 1.0.18 of LabIMotion, featuring:
12
+
13
+ * Generic Designer
14
+ * Workflow of Generic Element
15
+ * Repetitation of layers
16
+ * Drag Element to Element
17
+ * Dataset Metadata
18
+ * LabIMotion Template Hub Synchronization [**[LabIMotion Template Hub]**]
19
+
20
+ ---
21
+
22
+ This repository contains a backend service for the LabIMotion. It is written in **[Ruby]**.
23
+
24
+ ### Community
25
+
26
+ * [GitHub discussions](https://github.com/labimotion/labimotion/discussions)
27
+
28
+ ### Code
29
+
30
+ * [GitHub code](https://github.com/labimotion/labimotion) and [bug tracker](https://github.com/labimotion/labimotion/issues)
31
+
32
+ ---
33
+
34
+
35
+ ## Documentation
36
+
37
+ Documentation for users **⸢ [Documentation] ⸥**
38
+
39
+ Documentation for developers **⸢ [Technical Documentation] ⸥**
40
+
41
+ ---
42
+
43
+ ## License
44
+
45
+ Code released under the [AGPL-3.0 License]([https://www.gnu.org/licenses/agpl-3.0.txt](https://www.gnu.org/licenses/agpl-3.0.txt)).
46
+
47
+ ---
48
+
49
+ ## Acknowledgments
50
+
51
+ This project has been funded by the **[DFG]**.
52
+
53
+ [![DFG Logo]][DFG]
54
+
55
+
56
+ Funded by the [Deutsche Forschungsgemeinschaft (DFG, German Research Foundation)](https://www.dfg.de/) under the [National Research Data Infrastructure – NFDI4Chem](https://nfdi4chem.de/) – Projektnummer **441958208** since 2020.
57
+
58
+
59
+
60
+ <!----------------------------------------------------------------------------->
61
+ [Documentation]: https://www.chemotion.net/docs/labimotion/
62
+ [Technical Documentation]: https://www.rubydoc.info/gems/labimotion
63
+ [DFG]: https://www.dfg.de/en/
64
+ [DFG Logo]: https://www.dfg.de/zentralablage/bilder/service/logos_corporate_design/logo_negativ_267.png
65
+ [Nicole Jung]: mailto:nicole.jung@kit.edu
66
+ [Karlsruhe Institute of Technology]: https://www.kit.edu/english/
67
+ [Ruby]: https://www.ruby-lang.org/
68
+ [LabIMotion Template Hub]: https://www.chemotion-repository.net/home/genericHub
@@ -432,7 +432,6 @@ module Labimotion
432
432
  desc 'Return serialized elements of current user'
433
433
  params do
434
434
  optional :collection_id, type: Integer, desc: 'Collection id'
435
- optional :sync_collection_id, type: Integer, desc: 'SyncCollectionsUser id'
436
435
  optional :el_type, type: String, desc: 'element klass name'
437
436
  optional :from_date, type: Integer, desc: 'created_date from in ms'
438
437
  optional :to_date, type: Integer, desc: 'created_date to in ms'
@@ -12,8 +12,11 @@ module Labimotion
12
12
  mount Labimotion::LabimotionHubAPI
13
13
  mount Labimotion::StandardLayerAPI
14
14
  mount Labimotion::VocabularyAPI
15
+ mount Labimotion::UserAPI
15
16
  mount Labimotion::MttAPI
16
17
  mount Labimotion::DoseRespRequestAPI
17
18
  mount Labimotion::ElementVariationAPI
19
+ mount Labimotion::LabimotionDoiAPI
20
+ mount Labimotion::LabimotionTemplateBrowseAPI
18
21
  end
19
22
  end
@@ -0,0 +1,170 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Labimotion
4
+ # DOI lifecycle (reserve + release) and publication metadata for
5
+ # LabIMotion templates: ElementKlass / SegmentKlass / DatasetKlass.
6
+ class LabimotionDoiAPI < Grape::API
7
+ # rubocop:disable Metrics/BlockLength
8
+ # Grape route and helper DSL blocks are necessarily large.
9
+ KLASS_TYPES = ::Usecases::Labimotion::TemplateDoiHelpers::KLASS_BY_TYPE.keys.freeze
10
+
11
+ helpers do
12
+ def resolve_klass!(type, id)
13
+ model = ::Usecases::Labimotion::TemplateDoiHelpers::KLASS_BY_TYPE[type]
14
+ error!('unknown template type', 404) unless model
15
+
16
+ record = model.find_by(id: id)
17
+ error!('template not found', 404) unless record
18
+
19
+ record
20
+ end
21
+
22
+ def render_template_doi(record)
23
+ type = ::Usecases::Labimotion::TemplateDoiHelpers.klass_type_for(record)
24
+ dois = ::Doi.labimotion_dois(record)
25
+ # `doi` is the current (most recently reserved) DOI; `released_doi` is the
26
+ # latest released (minted) one. They differ once a new version has been
27
+ # reserved on top of a released one, so the modal can show both at once.
28
+ doi = dois.last
29
+ released_doi = dois.reverse.find(&:minted)
30
+ Labimotion::LabimotionTemplateDoiEntity.represent(
31
+ type: type,
32
+ klass_id: record.id,
33
+ doi: doi,
34
+ released_doi_version: released_doi && ::Doi.labimotion_doi_version(released_doi),
35
+ publication: (record.properties_template || {})['publication'],
36
+ released_at: record.released_at,
37
+ released_by: record.released_by,
38
+ new_version_available: ::Usecases::Labimotion::TemplateDoiHelpers.new_version_available?(record),
39
+ next_doi_version: ::Doi.labimotion_version_segment(record),
40
+ template_url: ::Usecases::Labimotion::TemplateDoiHelpers.template_url(record)
41
+ )
42
+ end
43
+
44
+ # Public, read-only view of one released DOI version.
45
+ def released_doi_version(doi)
46
+ full = doi.full_doi
47
+ {
48
+ doi: full,
49
+ doi_url: "https://dx.doi.org/#{full}",
50
+ version: ::Doi.labimotion_doi_version(doi),
51
+ minted_at: doi.minted_at
52
+ }
53
+ end
54
+
55
+ # Public payload for a template that has at least one released DOI: the
56
+ # latest released DOI promoted to the top level, plus its publication
57
+ # metadata, hub deep-link and every released version. `record_id` matches
58
+ # the hub grid's row id (identifier || uuid) so the frontend can merge it.
59
+ def released_template_doi(record, dois)
60
+ versions = dois.sort_by(&:id).map { |doi| released_doi_version(doi) }
61
+ publication = (record.properties_template || {})['publication']
62
+ publication = publication.is_a?(Hash) ? publication.slice('title', 'description', 'authors', 'license') : {}
63
+ versions.last.merge(
64
+ record_id: record.try(:identifier).presence || record.try(:uuid).presence || record.id,
65
+ identifier: record.try(:identifier),
66
+ uuid: record.try(:uuid),
67
+ label: record.try(:label),
68
+ template_version: record.try(:version),
69
+ next_doi_version: ::Doi.labimotion_version_segment(record),
70
+ template_url: ::Usecases::Labimotion::TemplateDoiHelpers.template_url(record),
71
+ publication: publication,
72
+ versions: versions
73
+ )
74
+ end
75
+ end
76
+
77
+ namespace :labimotion_doi do
78
+ # Public, anonymous read-only DOI info for the LabIMotion Template Hub.
79
+ # Whitelisted in RepoAPI::PUBLIC_URLS so it bypasses authenticate!; only
80
+ # released (minted) DOIs and their public publication metadata are exposed.
81
+ namespace :public do
82
+ route_param :type, type: String, values: KLASS_TYPES do
83
+ desc 'Released DOIs + publication metadata for every released template of a type'
84
+ get :released do
85
+ model = ::Usecases::Labimotion::TemplateDoiHelpers::KLASS_BY_TYPE[params[:type]]
86
+ grouped = ::Doi.where(doiable_type: model.name).where.not(minted_at: nil)
87
+ .order(:id).group_by(&:doiable_id)
88
+ records = model.where(id: grouped.keys).index_by(&:id)
89
+ released = grouped.filter_map do |klass_id, dois|
90
+ record = records[klass_id]
91
+ record && released_template_doi(record, dois)
92
+ end
93
+ { released_dois: released }
94
+ end
95
+ end
96
+ end
97
+
98
+ route_param :type, type: String, values: KLASS_TYPES do
99
+ desc "DOI state (reserved / released) per template of a type, for the designer grid's DOI icon"
100
+ get :states do
101
+ model = ::Usecases::Labimotion::TemplateDoiHelpers::KLASS_BY_TYPE[params[:type]]
102
+ grouped = ::Doi.where(doiable_type: model.name).order(:id).group_by(&:doiable_id)
103
+ states = grouped.transform_values do |list|
104
+ released = list.last.minted == true
105
+ { reserved: !released, released: released }
106
+ end
107
+ { states: states }
108
+ end
109
+
110
+ route_param :id, type: Integer do
111
+ desc 'Returns the current DOI/publication state for a template'
112
+ get do
113
+ record = resolve_klass!(params[:type], params[:id])
114
+ render_template_doi(record)
115
+ end
116
+
117
+ desc "Returns the DataCite metadata XML for every one of the template's DOI versions"
118
+ get :metadata_xml do
119
+ record = resolve_klass!(params[:type], params[:id])
120
+ dois = ::Doi.labimotion_dois(record)
121
+ error!('no DOI reserved', 404) if dois.empty?
122
+
123
+ versions = dois.map do |doi|
124
+ {
125
+ version: ::Doi.labimotion_doi_version(doi),
126
+ full_doi: doi.full_doi,
127
+ minted: doi.minted == true,
128
+ xml: ::Usecases::Labimotion::BuildTemplateDoiXml.new(record, doi, current_user).call
129
+ }
130
+ end
131
+ { versions: versions }
132
+ end
133
+
134
+ desc 'Updates the publication metadata of a template'
135
+ params do
136
+ requires :publication, type: Hash
137
+ end
138
+ put :publication_metadata do
139
+ record = resolve_klass!(params[:type], params[:id])
140
+ uc = ::Usecases::Labimotion::UpdateTemplatePublicationMetadata.new(
141
+ record, current_user, params[:publication]
142
+ ).call
143
+ error!(uc.error, 422) unless uc.success?
144
+
145
+ render_template_doi(record.reload)
146
+ end
147
+
148
+ desc 'Reserves a DataCite DOI for a template'
149
+ post :reserve_doi do
150
+ record = resolve_klass!(params[:type], params[:id])
151
+ uc = ::Usecases::Labimotion::ReserveTemplateDoi.new(record, current_user).call
152
+ error!(uc.error, 422) unless uc.success?
153
+
154
+ render_template_doi(record.reload)
155
+ end
156
+
157
+ desc 'Releases (mints) the reserved DOI for a template'
158
+ post :release_doi do
159
+ record = resolve_klass!(params[:type], params[:id])
160
+ uc = ::Usecases::Labimotion::ReleaseTemplateDoi.new(record, current_user).call
161
+ error!(uc.error, 422) unless uc.success?
162
+
163
+ render_template_doi(record.reload)
164
+ end
165
+ end
166
+ end
167
+ end
168
+ # rubocop:enable Metrics/BlockLength
169
+ end
170
+ end
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Labimotion
4
+ # Public, read-only browsing of released LabIMotion templates for the Template
5
+ # Hub "Find a Template" tab: pick a type, a template, then a release version.
6
+ # Returns every released version (revision) of one template, each with its own
7
+ # properties_release so the frontend can render the example inline.
8
+ # Whitelisted in RepoAPI::PUBLIC_URLS so anonymous hub visitors can use it.
9
+ class LabimotionTemplateBrowseAPI < Grape::API
10
+ KLASS_BY_TYPE = ::Usecases::Labimotion::TemplateDoiHelpers::KLASS_BY_TYPE
11
+ KLASS_TYPES = KLASS_BY_TYPE.keys.freeze
12
+ # type => [revision model, foreign key to the klass]
13
+ REVISION_BY_TYPE = {
14
+ 'element' => [::Labimotion::ElementKlassesRevision, :element_klass_id],
15
+ 'segment' => [::Labimotion::SegmentKlassesRevision, :segment_klass_id],
16
+ 'dataset' => [::Labimotion::DatasetKlassesRevision, :dataset_klass_id]
17
+ }.freeze
18
+
19
+ # rubocop:disable Metrics/BlockLength
20
+ # The helpers block is large due to the many template/version/DOI shaping helpers.
21
+ helpers do
22
+ def find_template(model, identifier)
23
+ model.find_by(identifier: identifier) || model.find_by(uuid: identifier)
24
+ end
25
+
26
+ # Numeric sort key for a "major.minor" version string.
27
+ def version_sort_key(version)
28
+ version.to_s.split('.').map(&:to_i)
29
+ end
30
+
31
+ def template_summary(record, type)
32
+ element_klass = record.try(:element_klass)
33
+ {
34
+ type: type,
35
+ identifier: record.try(:identifier),
36
+ uuid: record.try(:uuid),
37
+ name: record.try(:name),
38
+ label: record.try(:label),
39
+ desc: record.try(:desc),
40
+ klass_prefix: record.try(:klass_prefix),
41
+ icon_name: record.try(:icon_name),
42
+ current_version: record.try(:version),
43
+ element_klass: element_klass && { label: element_klass.label, icon_name: element_klass.icon_name }
44
+ }
45
+ end
46
+
47
+ def version_entry(version, released_at, uuid, properties_release)
48
+ { version: version, released_at: released_at, uuid: uuid, properties_release: properties_release }
49
+ end
50
+
51
+ # The current klass's released version is appended only when no revision
52
+ # already captures it, so the latest is always selectable.
53
+ def append_current?(record, versions)
54
+ record.try(:released_at).present? && versions.none? { |v| v[:version] == record.try(:version) }
55
+ end
56
+
57
+ # Drops blank-version entries and orders newest-first.
58
+ def sort_versions(versions)
59
+ versions.reject { |v| v[:version].to_s.strip.empty? }
60
+ .sort_by { |v| version_sort_key(v[:version]) }.reverse
61
+ end
62
+
63
+ # All released versions of a template, newest first. Built from the
64
+ # revision snapshots, plus the current klass (see append_current?).
65
+ def released_versions(record, type)
66
+ rev_model, foreign_key = REVISION_BY_TYPE[type]
67
+ scope = rev_model.where(foreign_key => record.id).where.not(released_at: nil)
68
+ versions = scope.map { |rev| version_entry(rev.version, rev.released_at, rev.uuid, rev.properties_release) }
69
+ if append_current?(record, versions)
70
+ versions << version_entry(record.try(:version), record.released_at,
71
+ record.try(:uuid), record.try(:properties_release))
72
+ end
73
+ sort_versions(versions)
74
+ end
75
+
76
+ # The template's DOI publication metadata (shown alongside the DOI).
77
+ def template_publication(record)
78
+ pub = (record.properties_template || {})['publication']
79
+ pub.is_a?(Hash) ? pub.slice('title', 'description', 'authors', 'license') : {}
80
+ end
81
+
82
+ # Released (minted) DOIs of the template, each tagged with its DOI version
83
+ # and its DataCite (kernel-4) metadata XML (the downloadable DOI metadata).
84
+ # The frontend maps a chosen template version to the applicable DOI version
85
+ # and shows/downloads the matching entry.
86
+ def released_dois(record)
87
+ ::Doi.labimotion_dois(record).select(&:minted).map do |doi|
88
+ full = doi.full_doi
89
+ { version: ::Doi.labimotion_doi_version(doi), doi: full,
90
+ doi_url: "https://dx.doi.org/#{full}", minted_at: doi.minted_at,
91
+ xml: ::Usecases::Labimotion::BuildTemplateDoiXml.new(record, doi).call }
92
+ end
93
+ end
94
+ end
95
+ # rubocop:enable Metrics/BlockLength
96
+
97
+ namespace :labimotion_template_browse do
98
+ route_param :type, type: String, values: KLASS_TYPES do
99
+ desc 'Released versions (revisions) of one template, each with properties_release'
100
+ params do
101
+ requires :identifier, type: String, desc: 'template identifier or uuid'
102
+ end
103
+ get :versions do
104
+ model = KLASS_BY_TYPE[params[:type]]
105
+ error!('unknown template type', 404) unless model
106
+
107
+ record = find_template(model, params[:identifier])
108
+ error!('template not found', 404) unless record
109
+
110
+ {
111
+ template: template_summary(record, params[:type]),
112
+ versions: released_versions(record, params[:type]),
113
+ dois: released_dois(record),
114
+ publication: template_publication(record)
115
+ }
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'labimotion/version'
4
+
5
+ module Labimotion
6
+ # User API
7
+ class UserAPI < Grape::API
8
+ helpers Labimotion::ParamHelpers
9
+ helpers Labimotion::GenericHelpers
10
+
11
+ resource :limo do
12
+ resource :users do
13
+ namespace :list do
14
+ desc 'List users by keyword'
15
+ params do
16
+ requires :name, type: String, desc: 'Keyword'
17
+ optional :limit, type: Integer, default: 5, desc: 'Limit (max 10)'
18
+ optional :type, type: String, default: 'Person', desc: 'User type'
19
+ end
20
+ get do
21
+ error!('401 Unauthorized', 401) unless current_user
22
+ return { mc: 'ss00', msg: 'Entered name too short', data: [] } if params[:name].to_s.length < 3
23
+
24
+ query = 'first_name ILIKE :q OR last_name ILIKE :q OR name ILIKE :q OR name_abbreviation ILIKE :q'
25
+ users = User.where(query, q: "%#{params[:name]}%")
26
+ .where(type: params[:type])
27
+ .limit([params[:limit].to_i, 10].min)
28
+ data = Labimotion::UserEntity.represent(users)
29
+ { mc: 'ss00', data: data }
30
+ rescue StandardError => e
31
+ Labimotion.log_exception(e, current_user)
32
+ { mc: 'se00', msg: e.message, data: [] }
33
+ end
34
+ end
35
+
36
+ desc 'Get user info by id'
37
+ params do
38
+ requires :id, type: Integer, desc: 'User id'
39
+ end
40
+ route_param :id do
41
+ get do
42
+ error!('401 Unauthorized', 401) unless current_user
43
+ user = User.find(params[:id])
44
+ data = Labimotion::UserEntity.represent(user)
45
+ { mc: 'ss00', data: data }
46
+ rescue ActiveRecord::RecordNotFound
47
+ error!('404 Not Found', 404)
48
+ rescue StandardError => e
49
+ Labimotion.log_exception(e, current_user)
50
+ { mc: 'se00', msg: e.message, data: {} }
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Labimotion
4
+ # Serializes the DOI + publication state for a LabIMotion template
5
+ # (ElementKlass / SegmentKlass / DatasetKlass). Built ad-hoc by
6
+ # Labimotion::LabimotionDoiAPI; not a direct AR record entity.
7
+ class LabimotionTemplateDoiEntity < Grape::Entity
8
+ expose :type
9
+ expose :klass_id
10
+ expose :doi do |obj|
11
+ next nil unless obj[:doi]
12
+
13
+ {
14
+ id: obj[:doi].id,
15
+ suffix: obj[:doi].suffix,
16
+ full_doi: obj[:doi].full_doi,
17
+ version: ::Doi.labimotion_doi_version(obj[:doi]),
18
+ minted: obj[:doi].minted == true,
19
+ minted_at: obj[:doi].minted_at
20
+ }
21
+ end
22
+ expose :released_doi_version
23
+ expose :publication
24
+ expose :released_at
25
+ expose :released_by
26
+ expose :new_version_available
27
+ expose :next_doi_version
28
+ expose :template_url
29
+ end
30
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'labimotion/entities/application_entity'
4
+ module Labimotion
5
+ # User entity
6
+ class UserEntity < Labimotion::ApplicationEntity
7
+ expose :id, :email, :first_name, :last_name, :name, :name_abbreviation
8
+ end
9
+ end
@@ -215,7 +215,7 @@ module Labimotion
215
215
  layer, field = params[:sort_column].split('.')
216
216
 
217
217
  element_klass = Labimotion::ElementKlass.find_by(name: params[:el_type])
218
- allowed_fields = element_klass.properties_release.dig(Labimotion::Prop::LAYERS, layer, Labimotion::Prop::FIELDS)&.pluck('field') || []
218
+ allowed_fields = element_klass&.properties_release&.dig(Labimotion::Prop::LAYERS, layer, Labimotion::Prop::FIELDS)&.pluck('field') || []
219
219
 
220
220
  if field.in?(allowed_fields)
221
221
  query = ActiveRecord::Base.sanitize_sql(
@@ -247,27 +247,21 @@ module Labimotion
247
247
  end
248
248
 
249
249
  def list_serialized_elements(params, current_user)
250
- collection_id =
251
- if params[:collection_id]
252
- Collection
253
- .belongs_to_or_shared_by(current_user.id, current_user.group_ids)
254
- .find_by(id: params[:collection_id])&.id
255
- elsif params[:sync_collection_id]
256
- current_user
257
- .all_sync_in_collections_users
258
- .find_by(id: params[:sync_collection_id])&.collection&.id
259
- end
250
+ scope = Labimotion::Element.none
260
251
 
261
- scope =
262
- if collection_id
263
- Labimotion::Element
264
- .joins(:element_klass, :collections_elements)
265
- .where(
266
- element_klasses: { name: params[:el_type] },
267
- collections_elements: { collection_id: collection_id },
268
- ).includes(:tag, collections: :sync_collections_users)
252
+ if params[:collection_id]
253
+ begin
254
+ collection = Collection.accessible_for(current_user).find(params[:collection_id])
255
+ scope = collection.elements
256
+ .joins(:element_klass)
257
+ .where(element_klasses: { name: params[:el_type] })
258
+ .includes(:tag)
259
+ rescue ActiveRecord::RecordNotFound
260
+ Labimotion::Element.none
261
+ end
269
262
  else
270
- Labimotion::Element.none
263
+ # All collection of current_user
264
+ scope = Labimotion::Element.for_user(current_user.id)
271
265
  end
272
266
 
273
267
  ## TO DO: refactor labimotion
@@ -278,7 +272,7 @@ module Labimotion
278
272
  layer, field = params[:sort_column].split('.')
279
273
 
280
274
  element_klass = Labimotion::ElementKlass.find_by(name: params[:el_type])
281
- allowed_fields = element_klass.properties_release.dig(Labimotion::Prop::LAYERS, layer, Labimotion::Prop::FIELDS)&.pluck('field') || []
275
+ allowed_fields = element_klass&.properties_release&.dig(Labimotion::Prop::LAYERS, layer, Labimotion::Prop::FIELDS)&.pluck('field') || []
282
276
 
283
277
  if field.in?(allowed_fields)
284
278
  query = ActiveRecord::Base.sanitize_sql(
@@ -125,7 +125,8 @@ module Labimotion
125
125
  tmp_file.rewind
126
126
 
127
127
  filename = oat.filename
128
- name = "#{File.basename(filename, '.*')}.zip"
128
+ # name = "#{File.basename(filename, '.*')}.zip"
129
+ name = "#{File.basename(filename, '.*')}#{File.extname(filename) == '.zip' ? '.bagit.zip' : '.zip'}"
129
130
  att = Attachment.new(
130
131
  filename: name,
131
132
  file_path: tmp_file.path,
@@ -34,7 +34,7 @@ module Labimotion
34
34
  return Labimotion::ConState::NONE if att.nil?
35
35
 
36
36
  result = process(att)
37
- return Labimotion::ConState::NONE if result.nil?
37
+ return Labimotion::ConState::WAIT if result.nil?
38
38
 
39
39
  handle_process_result(result, att, id, current_user)
40
40
  end
@@ -136,7 +136,7 @@ module Labimotion
136
136
  if result[:is_bagit]
137
137
  handle_bagit_result(att, id, current_user)
138
138
  elsif invalid_metadata?(result)
139
- Labimotion::ConState::NONE
139
+ Labimotion::ConState::WAIT
140
140
  else
141
141
  handle_nmr_result(result, att, current_user)
142
142
  end
@@ -31,6 +31,7 @@ module Labimotion
31
31
  case con_state
32
32
  when Labimotion::ConState::NMR
33
33
  self.con_state = Labimotion::NmrMapper.process_ds(id, current_user)
34
+ return exec_converter if con_state == Labimotion::ConState::WAIT
34
35
  update_column(:con_state, con_state)
35
36
  when Labimotion::ConState::WAIT
36
37
  self.con_state = Labimotion::Converter.jcamp_converter(id, current_user)
@@ -26,9 +26,9 @@ module Labimotion
26
26
  joins(collections: :user).where(collections: { user_id: user_id })
27
27
  )
28
28
 
29
- # Shared (synced) records
29
+ # Shared records
30
30
  shared = apply_filters.call(
31
- joins(collections: :sync_collections_users).where(sync_collections_users: { user_id: user_id })
31
+ left_joins(:collection_shares).where(collection_shares: { shared_with_id: user_id })
32
32
  )
33
33
 
34
34
  # Combine (remove duplicates), order, and limit
@@ -141,9 +141,9 @@ module Labimotion
141
141
  joins(collections: :user).where(collections: { user_id: user_id })
142
142
  )
143
143
 
144
- # Shared (synced) elements
144
+ # Shared elements
145
145
  shared = apply_filters.call(
146
- joins(collections: :sync_collections_users).where(sync_collections_users: { user_id: user_id })
146
+ left_joins(:collection_shares).where(collection_shares: { shared_with_id: user_id })
147
147
  )
148
148
 
149
149
  # Combine (remove duplicates), order, and limit
@@ -12,7 +12,7 @@ module Labimotion
12
12
  end
13
13
 
14
14
  def self.elements_search(params, current_user, c_id, dl)
15
- collection = Collection.belongs_to_or_shared_by(current_user.id, current_user.group_ids).find(c_id)
15
+ collection = Collection.accessible_for(current_user).find(c_id)
16
16
  element_scope = Labimotion::Element.joins(:collections_elements).where('collections_elements.collection_id = ?', collection.id).joins(:element_klass).where('element_klasses.id = elements.element_klass_id AND element_klasses.name = ?', params[:selection][:genericElName])
17
17
  element_scope = element_scope.where('elements.name like (?)', "%#{params[:selection][:searchName]}%") if params[:selection][:searchName].present?
18
18
  element_scope = element_scope.where('elements.short_label like (?)', "%#{params[:selection][:searchShowLabel]}%") if params[:selection][:searchShowLabel].present?
@@ -97,7 +97,7 @@ module Labimotion
97
97
  def self.samples_search(c_id = @c_id)
98
98
  sqls = []
99
99
  sps = params[:selection][:searchProperties]
100
- collection = Collection.belongs_to_or_shared_by(current_user.id, current_user.group_ids).find(c_id)
100
+ collection = Collection.accessible_for(current_user).find(c_id)
101
101
  element_scope = Sample.joins(:collections_samples).where('collections_samples.collection_id = ?', collection.id)
102
102
  return element_scope if sps.empty?
103
103
 
@@ -2,5 +2,5 @@
2
2
 
3
3
  ## Labimotion Version
4
4
  module Labimotion
5
- VERSION = '2.2.0.rc9'
5
+ VERSION = '2.2.0.rc11'
6
6
  end
data/lib/labimotion.rb CHANGED
@@ -27,9 +27,12 @@ module Labimotion
27
27
  autoload :ExporterAPI, 'labimotion/apis/exporter_api'
28
28
  autoload :StandardLayerAPI, 'labimotion/apis/standard_layer_api'
29
29
  autoload :VocabularyAPI, 'labimotion/apis/vocabulary_api'
30
+ autoload :UserAPI, 'labimotion/apis/user_api'
30
31
  autoload :MttAPI, 'labimotion/apis/mtt_api'
31
32
  autoload :DoseRespRequestAPI, 'labimotion/apis/dose_resp_request_api'
32
33
  autoload :ElementVariationAPI, 'labimotion/apis/element_variation_api'
34
+ autoload :LabimotionDoiAPI, 'labimotion/apis/labimotion_doi_api'
35
+ autoload :LabimotionTemplateBrowseAPI, 'labimotion/apis/labimotion_template_browse_api'
33
36
 
34
37
  ######## Entities
35
38
  autoload :PropertiesEntity, 'labimotion/entities/properties_entity'
@@ -52,7 +55,9 @@ module Labimotion
52
55
  autoload :SegmentRevisionEntity, 'labimotion/entities/segment_revision_entity'
53
56
  ## autoload :DatasetRevisionEntity, 'labimotion/entities/dataset_revision_entity'
54
57
  autoload :VocabularyEntity, 'labimotion/entities/vocabulary_entity'
58
+ autoload :UserEntity, 'labimotion/entities/user_entity'
55
59
  autoload :ElementVariationEntity, 'labimotion/entities/element_variation_entity'
60
+ autoload :LabimotionTemplateDoiEntity, 'labimotion/entities/labimotion_template_doi_entity'
56
61
 
57
62
  ######## Helpers
58
63
  autoload :GenericHelpers, 'labimotion/helpers/generic_helpers'