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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dd4b3db91de0cb6d968bd01d4bf0bad047d780c4107b6c93516c24167b57c0de
4
- data.tar.gz: 85acd9762cb804e328bb74f4d7a89f903e63815b624510d011d065cb6fdf722d
3
+ metadata.gz: 67757044a87ce6eda6eceddd937b93404eda3cc979298f2d22316ea6db0e6eb1
4
+ data.tar.gz: 603c9602c07ac03a0fab0ed20f9dc81fec5df0bfb153f758add2d05f29bd418e
5
5
  SHA512:
6
- metadata.gz: 4776bb7d6af56b198ad1e2786b9f77fba192e4d75717e113924634fc67278afc30505b2ce180ee77c5fb327e1833c23fd2f48c4c05f78e6a6ebb772a3d8cc3b3
7
- data.tar.gz: 76f821df633edfb58fad53d99229d26891d349f2cc7bc99421afc36f24a72f22ba1fa4863bf11bd6838b6628b5013540c38d21de519f29d60ec306803292bcf1
6
+ metadata.gz: '070083420acdf0dd06ab2b59c1595e4e76906b8594944ac00c091baf82c9465efd56c8a90b270d368d7f2571322ee6ec5134195f3e83f4b1764bb97880ad9015'
7
+ data.tar.gz: 744f9d63c5d552c673ab7bb4e83a147605e8c1558e60e3545a95e298cac6683114e96385d74794db6ac1fff02ab4e963d214c3f2a720f77e9653c6a1c8d2233c
data/Rakefile CHANGED
@@ -32,7 +32,3 @@ Rake::TestTask.new(:test) do |t|
32
32
  end
33
33
 
34
34
  task default: :test
35
-
36
- # Adds the Auxilium semver task
37
- spec = Gem::Specification.find_by_name "auxilium"
38
- load "#{spec.gem_dir}/lib/tasks/semver.rake"
@@ -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 'importo/application_controller'
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('.flash.no_file'))
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
- importo_ownable: Importo.config.current_import_owner.call))
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('.flash.error', error: @import.errors&.full_messages&.join('.')))
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: 'Import reverted'
31
+ redirect_to action: :index, notice: "Import reverted"
32
32
  else
33
- redirect_to action: :index, alert: 'Import could not be reverted'
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: 'Not allowed') && return unless Importo.config.admin_can_destroy.call(@import)
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
- type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', filename: import.importer.file_name('sample')
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
- type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', filename: import.importer.file_name('export')
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
- column_overrides: params.dig(:import, :column_overrides)&.keys)
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 = Sidekiq::Batch.new
129
+ batch = Importo::SidekiqBatchAdapter.new
130
130
  batch.description = "#{import.original.filename} - #{import.kind}"
131
- batch.on(:success, Importo::ImportJobCallback, import_id: import.id)
131
+ batch.properties = {import_id: import.id}
132
+ batch.on_success("Importo::ImportJobCallback")
132
133
 
133
- batch.jobs do
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 on_complete(_status, options)
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 = Sidekiq::Batch.new(bid)
33
+ batch = Importo::SidekiqBatchAdapter.find(bid)
34
34
 
35
- if !import.completed? && import.can_complete? && batch.status.complete?
36
- ImportJobCallback.new.on_complete(batch.status, {import_id: import_id})
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
@@ -0,0 +1,11 @@
1
+ module Importo
2
+ class ImportScheduledJob < ApplicationJob
3
+ def perform()
4
+ imports = Import.where(state: "scheduled", created_at: ..30.minutes.ago)
5
+
6
+ imports.each do |import|
7
+ ImportService.perform_async(import: import)
8
+ end
9
+ end
10
+ end
11
+ 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
- class ImportContext < ApplicationContext
5
- input do
6
- attribute :import, type: Import, typecaster: ->(value) { value.is_a?(Import) ? value : Import.find(value) }
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
@@ -6,8 +6,7 @@ module Importo
6
6
  context.import.import!
7
7
  context.import.importer.import!
8
8
  rescue
9
- context.import.failure!
10
- context.fail!
9
+ context.import.failure!
11
10
  end
12
11
  end
13
12
  end
@@ -2,38 +2,38 @@
2
2
 
3
3
  if defined? ActionTable
4
4
  class Importo::ImportsTable < ActionTable::ActionTable
5
- model Importo::Import
5
+ model Importo::Import
6
6
 
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]) } }
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
- 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."})
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
- # 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}"] } } } )
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
- initial_order :created_at, :desc
28
+ initial_order :created_at, :desc
29
29
 
30
- private
30
+ private
31
31
 
32
- def scope
33
- @scope = Importo.config.admin_visible_imports.call
34
- @scope
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
@@ -38,7 +38,6 @@ if defined? Mensa
38
38
  end
39
39
  end
40
40
 
41
-
42
41
  order created_at: :desc
43
42
  end
44
43
 
@@ -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: 'import.xlsx', locale: I18n.locale, owner: users(:admin))
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Importo
4
- VERSION = "3.0.14"
4
+ VERSION = "3.0.16"
5
5
  end
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.14
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-04-28 00:00:00.000000000 Z
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: slim
99
+ name: signum
100
100
  requirement: !ruby/object:Gem::Requirement
101
101
  requirements:
102
- - - ">"
102
+ - - "~>"
103
103
  - !ruby/object:Gem::Version
104
- version: '3.0'
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.0'
111
+ version: '0.3'
112
112
  - !ruby/object:Gem::Dependency
113
- name: state_machines-activerecord
113
+ name: slim
114
114
  requirement: !ruby/object:Gem::Requirement
115
115
  requirements:
116
- - - "~>"
116
+ - - ">"
117
117
  - !ruby/object:Gem::Version
118
- version: '0.5'
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.5'
125
+ version: '3.0'
126
126
  - !ruby/object:Gem::Dependency
127
- name: signum
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.3'
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.3'
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: pry
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: solargraph
267
+ name: rubocop
268
268
  requirement: !ruby/object:Gem::Requirement
269
269
  requirements:
270
- - - "~>"
270
+ - - ">="
271
271
  - !ruby/object:Gem::Version
272
- version: '0.47'
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: '0.47'
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