importo 3.0.14 → 3.0.16
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/Rakefile +0 -4
- data/app/adapters/importo/sidekiq_batch_adapter.rb +35 -0
- data/app/controllers/importo/imports_controller.rb +10 -10
- data/app/importers/concerns/importable.rb +7 -5
- data/app/importers/importo/import_job_callback.rb +1 -5
- data/app/jobs/importo/import_job.rb +4 -4
- data/app/jobs/importo/import_scheduled_job.rb +11 -0
- data/app/models/importo/import.rb +1 -1
- data/app/services/importo/import_context.rb +10 -3
- data/app/services/importo/import_service.rb +1 -2
- data/app/tables/importo/imports_table.rb +23 -23
- data/app/tables/importo/mensa_imports_table.rb +0 -1
- data/lib/importo/test_helpers.rb +2 -1
- data/lib/importo/version.rb +1 -1
- metadata +23 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 67757044a87ce6eda6eceddd937b93404eda3cc979298f2d22316ea6db0e6eb1
|
4
|
+
data.tar.gz: 603c9602c07ac03a0fab0ed20f9dc81fec5df0bfb153f758add2d05f29bd418e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '070083420acdf0dd06ab2b59c1595e4e76906b8594944ac00c091baf82c9465efd56c8a90b270d368d7f2571322ee6ec5134195f3e83f4b1764bb97880ad9015'
|
7
|
+
data.tar.gz: 744f9d63c5d552c673ab7bb4e83a147605e8c1558e60e3545a95e298cac6683114e96385d74794db6ac1fff02ab4e963d214c3f2a720f77e9653c6a1c8d2233c
|
data/Rakefile
CHANGED
@@ -0,0 +1,35 @@
|
|
1
|
+
module Importo
|
2
|
+
class SidekiqBatchAdapter
|
3
|
+
attr_reader :description
|
4
|
+
attr_accessor :properties
|
5
|
+
attr_writer :instance
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@instance = Sidekiq::Batch.new
|
9
|
+
end
|
10
|
+
|
11
|
+
delegate :description=, :bid, to: :@instance
|
12
|
+
|
13
|
+
def on_success(job)
|
14
|
+
@instance.on(:success, job.constantize, properties)
|
15
|
+
end
|
16
|
+
|
17
|
+
def add
|
18
|
+
@instance.jobs do
|
19
|
+
yield
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def finished?
|
24
|
+
@instance.status.complete?
|
25
|
+
end
|
26
|
+
|
27
|
+
class << self
|
28
|
+
def find(id)
|
29
|
+
instance = new
|
30
|
+
instance.instance = Sidekiq::Batch.new(id)
|
31
|
+
instance
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_dependency
|
3
|
+
require_dependency "importo/application_controller"
|
4
4
|
|
5
5
|
module Importo
|
6
6
|
class ImportsController < ApplicationController
|
@@ -11,16 +11,16 @@ module Importo
|
|
11
11
|
def create
|
12
12
|
unless import_params
|
13
13
|
@import = Import.new(kind: params[:kind], locale: I18n.locale)
|
14
|
-
Signum.error(Current.user, text: t(
|
14
|
+
Signum.error(Current.user, text: t(".flash.no_file"))
|
15
15
|
render :new
|
16
16
|
return
|
17
17
|
end
|
18
18
|
@import = Import.new(import_params.merge(locale: I18n.locale,
|
19
|
-
|
19
|
+
importo_ownable: Importo.config.current_import_owner.call))
|
20
20
|
if @import.valid? && @import.schedule!
|
21
21
|
redirect_to importo.new_import_path(params[:kind] || @import.kind)
|
22
22
|
else
|
23
|
-
Signum.error(Current.user, text: t(
|
23
|
+
Signum.error(Current.user, text: t(".flash.error", error: @import.errors&.full_messages&.join(".")))
|
24
24
|
render :new
|
25
25
|
end
|
26
26
|
end
|
@@ -28,15 +28,15 @@ module Importo
|
|
28
28
|
def undo
|
29
29
|
@import = Import.where(importo_ownable: Importo.config.current_import_owner.call).find(params[:id])
|
30
30
|
if @import.can_revert? && @import.revert
|
31
|
-
redirect_to action: :index, notice:
|
31
|
+
redirect_to action: :index, notice: "Import reverted"
|
32
32
|
else
|
33
|
-
redirect_to action: :index, alert:
|
33
|
+
redirect_to action: :index, alert: "Import could not be reverted"
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
37
|
def destroy
|
38
38
|
@import = Import.find(params[:id])
|
39
|
-
redirect_to(action: :index, alert:
|
39
|
+
redirect_to(action: :index, alert: "Not allowed") && return unless Importo.config.admin_can_destroy.call(@import)
|
40
40
|
|
41
41
|
@import.destroy
|
42
42
|
redirect_to action: :index
|
@@ -45,13 +45,13 @@ module Importo
|
|
45
45
|
def sample
|
46
46
|
import = Import.new(kind: params[:kind], locale: I18n.locale)
|
47
47
|
send_data import.importer.sample_file.read,
|
48
|
-
|
48
|
+
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", filename: import.importer.file_name("sample")
|
49
49
|
end
|
50
50
|
|
51
51
|
def export
|
52
52
|
import = Import.new(kind: params[:kind], locale: I18n.locale)
|
53
53
|
send_data import.importer.export_file.read,
|
54
|
-
|
54
|
+
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", filename: import.importer.file_name("export")
|
55
55
|
end
|
56
56
|
|
57
57
|
def index
|
@@ -62,7 +62,7 @@ module Importo
|
|
62
62
|
|
63
63
|
def import_params
|
64
64
|
params.require(:import).permit(:original, :kind, :column_overrides,
|
65
|
-
|
65
|
+
column_overrides: params.dig(:import, :column_overrides)&.keys)
|
66
66
|
end
|
67
67
|
end
|
68
68
|
end
|
@@ -126,11 +126,13 @@ module Importable
|
|
126
126
|
def import!
|
127
127
|
raise ArgumentError, "Invalid data structure" unless structure_valid?
|
128
128
|
|
129
|
-
batch =
|
129
|
+
batch = Importo::SidekiqBatchAdapter.new
|
130
130
|
batch.description = "#{import.original.filename} - #{import.kind}"
|
131
|
-
batch.
|
131
|
+
batch.properties = {import_id: import.id}
|
132
|
+
batch.on_success("Importo::ImportJobCallback")
|
132
133
|
|
133
|
-
batch.
|
134
|
+
batch.add do
|
135
|
+
bid = batch.bid
|
134
136
|
column_with_delay = columns.select { |k, v| v.delay.present? }
|
135
137
|
loop_data_rows do |attributes, index|
|
136
138
|
if column_with_delay.present?
|
@@ -139,8 +141,8 @@ module Importable
|
|
139
141
|
v.delay.call(attributes[k])
|
140
142
|
end.compact
|
141
143
|
end
|
142
|
-
Importo::ImportJob.set(wait_until: (delay.max * index).seconds.from_now).perform_async(JSON.dump(attributes), index, import.id) if delay.present?
|
143
|
-
Importo::ImportJob.perform_async(JSON.dump(attributes), index, import.id) unless delay.present?
|
144
|
+
Importo::ImportJob.set(wait_until: (delay.max * index).seconds.from_now).perform_async(JSON.dump(attributes), index, import.id, bid) if delay.present?
|
145
|
+
Importo::ImportJob.perform_async(JSON.dump(attributes), index, import.id, bid) unless delay.present?
|
144
146
|
end
|
145
147
|
end
|
146
148
|
|
@@ -2,7 +2,7 @@ module Importo
|
|
2
2
|
class ImportJobCallback
|
3
3
|
include Rails.application.routes.url_helpers
|
4
4
|
|
5
|
-
def
|
5
|
+
def on_success(_status, options)
|
6
6
|
options = options.deep_stringify_keys
|
7
7
|
import = Import.find(options["import_id"])
|
8
8
|
if import.present?
|
@@ -21,9 +21,5 @@ module Importo
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
24
|
-
|
25
|
-
def on_success(status, options)
|
26
|
-
on_complete(status, options)
|
27
|
-
end
|
28
24
|
end
|
29
25
|
end
|
@@ -20,7 +20,7 @@ module Importo
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
def perform(attributes, index, import_id)
|
23
|
+
def perform(attributes, index, import_id, bid)
|
24
24
|
self.class.execute_row(attributes, index, import_id, false, bid)
|
25
25
|
end
|
26
26
|
|
@@ -30,10 +30,10 @@ module Importo
|
|
30
30
|
import = Import.find(import_id)
|
31
31
|
record = import.importer.process_data_row(attributes, index, last_attempt: last_attempt)
|
32
32
|
|
33
|
-
batch =
|
33
|
+
batch = Importo::SidekiqBatchAdapter.find(bid)
|
34
34
|
|
35
|
-
if !import.completed? && import.can_complete? && batch.
|
36
|
-
ImportJobCallback.new.
|
35
|
+
if !import.completed? && import.can_complete? && batch.finished?
|
36
|
+
ImportJobCallback.new.on_success(batch.status, {import_id: import_id})
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
@@ -76,7 +76,7 @@ module Importo
|
|
76
76
|
invalid_headers: importer.invalid_header_names.join(", ")))
|
77
77
|
end
|
78
78
|
rescue => e
|
79
|
-
errors.add(:original, I18n.t("importo.errors.parse_error", error: e.message))
|
79
|
+
errors.add(:original, I18n.t("importo.errors.parse_error", error: e.message)) unless state == "failed"
|
80
80
|
end
|
81
81
|
|
82
82
|
def importer
|
@@ -1,9 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Importo
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
if defined?(Servitium) && ApplicationContext < Servitium::Context
|
5
|
+
class ImportContext < ApplicationContext
|
6
|
+
input do
|
7
|
+
attribute :import, type: Import, typecaster: ->(value) { value.is_a?(Import) ? value : Import.find(value) }
|
8
|
+
end
|
7
9
|
end
|
10
|
+
else
|
11
|
+
class ImportContext < ApplicationContext
|
12
|
+
attribute :import, :model, class_name: "Importo::Import"
|
13
|
+
end
|
14
|
+
|
8
15
|
end
|
9
16
|
end
|
@@ -2,38 +2,38 @@
|
|
2
2
|
|
3
3
|
if defined? ActionTable
|
4
4
|
class Importo::ImportsTable < ActionTable::ActionTable
|
5
|
-
|
5
|
+
model Importo::Import
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
7
|
+
column(:created_at, html_value: proc { |import| l(import.created_at.in_time_zone(Time.zone), format: :short).to_s })
|
8
|
+
column(:user, sortable: false) { |import| import.importo_ownable.name }
|
9
|
+
column(:kind, sortable: false)
|
10
|
+
column(:original, sortable: false) { |import| link_to(import.original.filename, main_app.rails_blob_path(import.original, disposition: "attachment"), target: "_blank") }
|
11
|
+
column(:state)
|
12
|
+
column(:result, sortable: false) { |import| import.result.attached? ? link_to(import.result_message, main_app.rails_blob_path(import.result, disposition: "attachment"), target: "_blank") : import.result_message }
|
13
|
+
column(:extra_links, sortable: false) { |import| Importo.config.admin_extra_links.call(import).map { |name, link| link_to(link[:text], link[:url], title: link[:title], target: "_blank", class: link[:icon]) } }
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
15
|
+
column :actions, title: "", sortable: false do |import|
|
16
|
+
content_tag(:span) do
|
17
|
+
if import.can_revert?
|
18
|
+
concat link_to(content_tag(:i, nil, class: "fa fa-undo"), importo.undo_import_path(import), data: {turbo_method: :post, turbo_confirm: "Are you sure? This will undo this import."})
|
19
|
+
end
|
20
|
+
if Importo.config.admin_can_destroy.call(import)
|
21
|
+
concat link_to(content_tag(:i, nil, class: "fa fa-trash"), importo.import_path(import), class: "float-right", data: {turbo_method: :delete, turbo_confirm: "Are you sure? This will prevent duplicate imports from being detected."})
|
22
|
+
end
|
22
23
|
end
|
23
24
|
end
|
24
|
-
end
|
25
25
|
|
26
|
-
|
26
|
+
# filter(:importo_ownable){ parameter: :ownable, collection_proc: -> { Importo::Import.order(created_at: :desc).limit(200).map(&:importo_ownable).uniq.sort_by(&:name).map { |o| [o.name, "#{o.class.name}##{o.id}"] } } } )
|
27
27
|
|
28
|
-
|
28
|
+
initial_order :created_at, :desc
|
29
29
|
|
30
|
-
|
30
|
+
private
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
def scope
|
33
|
+
@scope = Importo.config.admin_visible_imports.call
|
34
|
+
@scope
|
35
|
+
end
|
35
36
|
end
|
36
|
-
end
|
37
37
|
else
|
38
38
|
class Importo::ImportsTable
|
39
39
|
end
|
data/lib/importo/test_helpers.rb
CHANGED
@@ -23,13 +23,14 @@ module Importo
|
|
23
23
|
Roo::Excelx.new(excel.set_encoding("BINARY"))
|
24
24
|
end
|
25
25
|
|
26
|
-
def import_sheet(kind, sheet, filename:
|
26
|
+
def import_sheet(kind, sheet, filename: "import.xlsx", locale: I18n.locale, owner: @owner)
|
27
27
|
import = Importo::Import.new(kind: kind, locale: locale, importo_ownable: owner)
|
28
28
|
|
29
29
|
import.original.attach(io: sheet, filename: filename, content_type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", identify: false)
|
30
30
|
import.save!
|
31
31
|
|
32
32
|
ImportService.perform(import: import)
|
33
|
+
ImportJobCallback.new.on_success({import_id: import.id})
|
33
34
|
import
|
34
35
|
end
|
35
36
|
end
|
data/lib/importo/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: importo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.16
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andre Meij
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2024-
|
12
|
+
date: 2024-09-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: caxlsx
|
@@ -96,47 +96,47 @@ dependencies:
|
|
96
96
|
- !ruby/object:Gem::Version
|
97
97
|
version: '1.2'
|
98
98
|
- !ruby/object:Gem::Dependency
|
99
|
-
name:
|
99
|
+
name: signum
|
100
100
|
requirement: !ruby/object:Gem::Requirement
|
101
101
|
requirements:
|
102
|
-
- - "
|
102
|
+
- - "~>"
|
103
103
|
- !ruby/object:Gem::Version
|
104
|
-
version: '3
|
104
|
+
version: '0.3'
|
105
105
|
type: :runtime
|
106
106
|
prerelease: false
|
107
107
|
version_requirements: !ruby/object:Gem::Requirement
|
108
108
|
requirements:
|
109
|
-
- - "
|
109
|
+
- - "~>"
|
110
110
|
- !ruby/object:Gem::Version
|
111
|
-
version: '3
|
111
|
+
version: '0.3'
|
112
112
|
- !ruby/object:Gem::Dependency
|
113
|
-
name:
|
113
|
+
name: slim
|
114
114
|
requirement: !ruby/object:Gem::Requirement
|
115
115
|
requirements:
|
116
|
-
- - "
|
116
|
+
- - ">"
|
117
117
|
- !ruby/object:Gem::Version
|
118
|
-
version: '0
|
118
|
+
version: '3.0'
|
119
119
|
type: :runtime
|
120
120
|
prerelease: false
|
121
121
|
version_requirements: !ruby/object:Gem::Requirement
|
122
122
|
requirements:
|
123
|
-
- - "
|
123
|
+
- - ">"
|
124
124
|
- !ruby/object:Gem::Version
|
125
|
-
version: '0
|
125
|
+
version: '3.0'
|
126
126
|
- !ruby/object:Gem::Dependency
|
127
|
-
name:
|
127
|
+
name: state_machines-activerecord
|
128
128
|
requirement: !ruby/object:Gem::Requirement
|
129
129
|
requirements:
|
130
130
|
- - "~>"
|
131
131
|
- !ruby/object:Gem::Version
|
132
|
-
version: '0.
|
132
|
+
version: '0.5'
|
133
133
|
type: :runtime
|
134
134
|
prerelease: false
|
135
135
|
version_requirements: !ruby/object:Gem::Requirement
|
136
136
|
requirements:
|
137
137
|
- - "~>"
|
138
138
|
- !ruby/object:Gem::Version
|
139
|
-
version: '0.
|
139
|
+
version: '0.5'
|
140
140
|
- !ruby/object:Gem::Dependency
|
141
141
|
name: turbo-rails
|
142
142
|
requirement: !ruby/object:Gem::Requirement
|
@@ -236,7 +236,7 @@ dependencies:
|
|
236
236
|
- !ruby/object:Gem::Version
|
237
237
|
version: '0'
|
238
238
|
- !ruby/object:Gem::Dependency
|
239
|
-
name:
|
239
|
+
name: debug
|
240
240
|
requirement: !ruby/object:Gem::Requirement
|
241
241
|
requirements:
|
242
242
|
- - ">="
|
@@ -264,19 +264,19 @@ dependencies:
|
|
264
264
|
- !ruby/object:Gem::Version
|
265
265
|
version: '0.3'
|
266
266
|
- !ruby/object:Gem::Dependency
|
267
|
-
name:
|
267
|
+
name: rubocop
|
268
268
|
requirement: !ruby/object:Gem::Requirement
|
269
269
|
requirements:
|
270
|
-
- - "
|
270
|
+
- - ">="
|
271
271
|
- !ruby/object:Gem::Version
|
272
|
-
version: '
|
272
|
+
version: '1'
|
273
273
|
type: :development
|
274
274
|
prerelease: false
|
275
275
|
version_requirements: !ruby/object:Gem::Requirement
|
276
276
|
requirements:
|
277
|
-
- - "
|
277
|
+
- - ">="
|
278
278
|
- !ruby/object:Gem::Version
|
279
|
-
version: '
|
279
|
+
version: '1'
|
280
280
|
- !ruby/object:Gem::Dependency
|
281
281
|
name: standard
|
282
282
|
requirement: !ruby/object:Gem::Requirement
|
@@ -302,6 +302,7 @@ files:
|
|
302
302
|
- MIT-LICENSE
|
303
303
|
- README.md
|
304
304
|
- Rakefile
|
305
|
+
- app/adapters/importo/sidekiq_batch_adapter.rb
|
305
306
|
- app/assets/config/importo_manifest.js
|
306
307
|
- app/assets/javascripts/importo/application.js
|
307
308
|
- app/assets/stylesheets/importo/application.css
|
@@ -319,6 +320,7 @@ files:
|
|
319
320
|
- app/importers/importo/import_job_callback.rb
|
320
321
|
- app/jobs/importo/application_job.rb
|
321
322
|
- app/jobs/importo/import_job.rb
|
323
|
+
- app/jobs/importo/import_scheduled_job.rb
|
322
324
|
- app/jobs/importo/purge_import_job.rb
|
323
325
|
- app/mailers/importo/application_mailer.rb
|
324
326
|
- app/models/importo/application_record.rb
|