active_admin_import 4.1.0 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +4 -1
- data/.travis.yml +10 -4
- data/CHANGELOG.md +17 -0
- data/Gemfile +3 -2
- data/active_admin_import.gemspec +4 -4
- data/lib/active_admin_import/dsl.rb +5 -1
- data/lib/active_admin_import/exception.rb +5 -0
- data/lib/active_admin_import/import_result.rb +4 -1
- data/lib/active_admin_import/importer.rb +16 -10
- data/lib/active_admin_import/model.rb +2 -1
- data/lib/active_admin_import/version.rb +1 -1
- data/lib/active_admin_import.rb +1 -0
- data/spec/fixtures/files/authors.csv +3 -3
- data/spec/import_result_spec.rb +11 -10
- data/spec/import_spec.rb +57 -8
- data/spec/spec_helper.rb +1 -0
- data/tasks/test.rake +1 -1
- metadata +15 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ba919b0429b44accf46af4dcdc52ef1ddcf691a446cddf1bc434b38982c6b0c2
|
4
|
+
data.tar.gz: b54c35f3d81a3b170a8a27b657f1c0b8137c49716fab6b1ba0717845f1b15649
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d949ae03350ff838eb97856d4c34afb610708dde36bee45d32b56de0bd1bf48a5e0adb4e67aaa549e1e35393cca146be755258fbc213422ab9a91b299769688e
|
7
|
+
data.tar.gz: 4ddc52d5273f06837f54a3806e56ebdad52c2a60581aa452b196de25885697348b13af8f56e27716ed2234b3771072f3f93e365035cdfc02b1539e7aa8385fb1
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,21 @@
|
|
1
1
|
# Changelog
|
2
|
+
## [5.0.0] - 2021-11-16
|
3
|
+
- Ruby 3 compatibility added #190 | @clinejj
|
4
|
+
- Support for a non UTF-8 file when zip uploading #185| @naokirin
|
5
|
+
- Rails 6 supported #183 | @pnghai
|
6
|
+
- Drop ruby 2.4 support #192 | @Fivell
|
7
|
+
|
8
|
+
|
9
|
+
## [4.2.0] - 2020-02-05
|
10
|
+
- generic exception for import added #175 | @linqueta
|
11
|
+
|
12
|
+
## [4.1.2] - 2019-12-16
|
13
|
+
- allow application/octet-stream content-type #172 | @dmitry-sinina
|
14
|
+
- Allow activerecord-import >= 0.27 #171 | @sagium
|
15
|
+
|
16
|
+
## [4.1.1] - 2019-09-20
|
17
|
+
- Fix column slicing #168 | @doredesign
|
18
|
+
- Handle errors on base #163
|
2
19
|
|
3
20
|
## [4.1.0] - 2019-01-15
|
4
21
|
- Upgrade dependencies: `activerecord-import` to >=0.27.1 | @jkowens
|
data/Gemfile
CHANGED
@@ -6,12 +6,13 @@ gemspec
|
|
6
6
|
|
7
7
|
|
8
8
|
group :test do
|
9
|
-
default_rails_version = "~> 5.
|
9
|
+
default_rails_version = "~> 5.2.4"
|
10
10
|
rails_version = ENV['RAILS'] || default_rails_version
|
11
|
+
gem 'sassc-rails'
|
11
12
|
gem 'rails', rails_version
|
12
13
|
gem 'rspec-rails'
|
13
14
|
gem 'coveralls', require: false # Test coverage website. Go to https://coveralls.io
|
14
|
-
gem
|
15
|
+
gem "sqlite3", "~> 1.4.0"
|
15
16
|
gem 'launchy'
|
16
17
|
gem 'database_cleaner'
|
17
18
|
gem 'capybara'
|
data/active_admin_import.gemspec
CHANGED
@@ -15,8 +15,8 @@ Gem::Specification.new do |gem|
|
|
15
15
|
gem.name = 'active_admin_import'
|
16
16
|
gem.require_paths = ['lib']
|
17
17
|
gem.version = ActiveAdminImport::VERSION
|
18
|
-
gem.add_runtime_dependency 'activerecord-import', '
|
19
|
-
gem.add_runtime_dependency 'rchardet', '
|
20
|
-
gem.add_runtime_dependency 'rubyzip', '
|
21
|
-
gem.add_dependency 'activeadmin', '>= 1.0.0
|
18
|
+
gem.add_runtime_dependency 'activerecord-import', '>= 0.27'
|
19
|
+
gem.add_runtime_dependency 'rchardet', '>= 1.6'
|
20
|
+
gem.add_runtime_dependency 'rubyzip', '>= 1.2'
|
21
|
+
gem.add_dependency 'activeadmin', '>= 1.0.0'
|
22
22
|
end
|
@@ -92,7 +92,11 @@ module ActiveAdminImport
|
|
92
92
|
else
|
93
93
|
instance_exec result, options, &DEFAULT_RESULT_PROC
|
94
94
|
end
|
95
|
-
rescue ActiveRecord::Import::MissingColumnError,
|
95
|
+
rescue ActiveRecord::Import::MissingColumnError,
|
96
|
+
NoMethodError,
|
97
|
+
ActiveRecord::StatementInvalid,
|
98
|
+
CSV::MalformedCSVError,
|
99
|
+
ActiveAdminImport::Exception => e
|
96
100
|
Rails.logger.error(I18n.t('active_admin_import.file_error', message: e.message))
|
97
101
|
Rails.logger.error(e.backtrace.join("\n"))
|
98
102
|
flash[:error] = I18n.t('active_admin_import.file_error', message: e.message[0..200])
|
@@ -33,7 +33,10 @@ module ActiveAdminImport
|
|
33
33
|
limit = options[:limit] || failed.count
|
34
34
|
failed.first(limit).map do |record|
|
35
35
|
errors = record.errors
|
36
|
-
|
36
|
+
failed_values = errors.keys.map do |key|
|
37
|
+
key == :base ? nil : record.public_send(key)
|
38
|
+
end
|
39
|
+
errors.full_messages.zip(failed_values).map { |ms| ms.compact.join(' - ') }.join(', ')
|
37
40
|
end.join(' ; ')
|
38
41
|
end
|
39
42
|
end
|
@@ -37,7 +37,7 @@ module ActiveAdminImport
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def cycle(lines)
|
40
|
-
@csv_lines = CSV.parse(lines.join,
|
40
|
+
@csv_lines = CSV.parse(lines.join, **@csv_options)
|
41
41
|
import_result.add(batch_import, lines.count)
|
42
42
|
end
|
43
43
|
|
@@ -70,7 +70,7 @@ module ActiveAdminImport
|
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
|
-
# Use
|
73
|
+
# Use this method when CSV file contains unnecessary columns
|
74
74
|
#
|
75
75
|
# Example:
|
76
76
|
#
|
@@ -81,16 +81,22 @@ module ActiveAdminImport
|
|
81
81
|
# end
|
82
82
|
#
|
83
83
|
def batch_slice_columns(slice_columns)
|
84
|
-
use_indexes
|
85
|
-
|
86
|
-
|
84
|
+
# Only set @use_indexes for the first batch so that @use_indexes are in correct
|
85
|
+
# position for subsequent batches
|
86
|
+
unless defined?(@use_indexes)
|
87
|
+
@use_indexes = []
|
88
|
+
headers.values.each_with_index do |val, index|
|
89
|
+
@use_indexes << index if val.in?(slice_columns)
|
90
|
+
end
|
91
|
+
return csv_lines if @use_indexes.empty?
|
92
|
+
|
93
|
+
# slice CSV headers
|
94
|
+
@headers = headers.to_a.values_at(*@use_indexes).to_h
|
87
95
|
end
|
88
|
-
|
89
|
-
# slice CSV headers
|
90
|
-
@headers = headers.to_a.values_at(*use_indexes).to_h
|
96
|
+
|
91
97
|
# slice CSV values
|
92
98
|
csv_lines.map! do |line|
|
93
|
-
line.values_at(
|
99
|
+
line.values_at(*@use_indexes)
|
94
100
|
end
|
95
101
|
end
|
96
102
|
|
@@ -109,7 +115,7 @@ module ActiveAdminImport
|
|
109
115
|
batch_size = options[:batch_size].to_i
|
110
116
|
File.open(file.path) do |f|
|
111
117
|
# capture headers if not exist
|
112
|
-
prepare_headers { CSV.parse(f.readline,
|
118
|
+
prepare_headers { CSV.parse(f.readline, **@csv_options).first }
|
113
119
|
f.each_line do |line|
|
114
120
|
lines << line if line.present?
|
115
121
|
if lines.size == batch_size || f.eof?
|
@@ -21,6 +21,7 @@ module ActiveAdminImport
|
|
21
21
|
application/csv
|
22
22
|
application/vnd.ms-excel
|
23
23
|
application/vnd.msexcel
|
24
|
+
application/octet-stream
|
24
25
|
text/tsv
|
25
26
|
text/x-tsv
|
26
27
|
text/tab-separated-values
|
@@ -109,7 +110,7 @@ module ActiveAdminImport
|
|
109
110
|
|
110
111
|
def unzip_file
|
111
112
|
Zip::File.open(file_path) do |zip_file|
|
112
|
-
self.file = Tempfile.new(CONST::TMP_FILE)
|
113
|
+
self.file = Tempfile.new(CONST::TMP_FILE, binmode: true)
|
113
114
|
data = zip_file.entries.select(&:file?).first.get_input_stream.read
|
114
115
|
file << data
|
115
116
|
file.close
|
data/lib/active_admin_import.rb
CHANGED
@@ -3,6 +3,7 @@ require 'activerecord-import'
|
|
3
3
|
require 'active_admin'
|
4
4
|
require 'active_admin_import/version'
|
5
5
|
require 'active_admin_import/engine'
|
6
|
+
require 'active_admin_import/exception'
|
6
7
|
require 'active_admin_import/import_result'
|
7
8
|
require 'active_admin_import/options'
|
8
9
|
require 'active_admin_import/dsl'
|
@@ -1,3 +1,3 @@
|
|
1
|
-
Name,Last name
|
2
|
-
|
3
|
-
|
1
|
+
Birthday,Name,Last name
|
2
|
+
1986-05-01,John,Doe
|
3
|
+
1988-11-16,Jane,Roe
|
data/spec/import_result_spec.rb
CHANGED
@@ -5,17 +5,18 @@ describe ActiveAdminImport::ImportResult do
|
|
5
5
|
context 'failed_message' do
|
6
6
|
let(:import_result) { ActiveAdminImport::ImportResult.new }
|
7
7
|
|
8
|
-
before do
|
9
|
-
Author.create(name: 'John', last_name: 'Doe')
|
10
|
-
Author.create(name: 'Jane', last_name: 'Roe')
|
11
8
|
|
9
|
+
let(:failed_instances) do
|
10
|
+
[
|
11
|
+
Author.new(last_name: 'Doe').tap {|r| r.errors.add(:last_name, :taken) },
|
12
|
+
Author.new(name: "", last_name: 'Doe').tap {|r| r.errors.add(:name, :blank); r.errors.add(:last_name, :taken) },
|
13
|
+
Author.new.tap {|r| r.errors.add(:base, 'custom') }
|
14
|
+
]
|
15
|
+
end
|
16
|
+
|
17
|
+
before do
|
12
18
|
@result = double \
|
13
|
-
failed_instances:
|
14
|
-
# {:last_name=>["has already been taken"]}
|
15
|
-
Author.create(name: 'Jim', last_name: 'Doe'),
|
16
|
-
# {:name=>["can't be blank"], :last_name=>["has already been taken"]}
|
17
|
-
Author.create(name: nil, last_name: 'Doe')
|
18
|
-
]
|
19
|
+
failed_instances: failed_instances
|
19
20
|
end
|
20
21
|
|
21
22
|
it 'should work without any failed instances' do
|
@@ -26,7 +27,7 @@ describe ActiveAdminImport::ImportResult do
|
|
26
27
|
import_result.add(@result, 4)
|
27
28
|
expect(import_result.failed_message)
|
28
29
|
.to eq(
|
29
|
-
"Last name has already been taken - Doe ; Name can't be blank - , Last name has already been taken - Doe"
|
30
|
+
"Last name has already been taken - Doe ; Name can't be blank - , Last name has already been taken - Doe ; custom"
|
30
31
|
)
|
31
32
|
end
|
32
33
|
|
data/spec/import_spec.rb
CHANGED
@@ -371,6 +371,20 @@ describe 'import', type: :feature do
|
|
371
371
|
end
|
372
372
|
end
|
373
373
|
end
|
374
|
+
|
375
|
+
context 'when zipped with Win1251 file' do
|
376
|
+
let(:options) do
|
377
|
+
attributes = { force_encoding: :auto }
|
378
|
+
{ template_object: ActiveAdminImport::Model.new(attributes) }
|
379
|
+
end
|
380
|
+
it 'should import file' do
|
381
|
+
with_zipped_csv(:authors_win1251_win_endline) do
|
382
|
+
upload_file!(:authors_win1251_win_endline, :zip)
|
383
|
+
expect(page).to have_content 'Successfully imported 2 authors'
|
384
|
+
expect(Author.count).to eq(2)
|
385
|
+
end
|
386
|
+
end
|
387
|
+
end
|
374
388
|
end
|
375
389
|
|
376
390
|
context 'with different header attribute names' do
|
@@ -430,15 +444,40 @@ describe 'import', type: :feature do
|
|
430
444
|
upload_file!(:authors)
|
431
445
|
expect(Author.count).to eq(2)
|
432
446
|
end
|
447
|
+
|
448
|
+
context 'when the option before_import raises a ActiveAdminImport::Exception' do
|
449
|
+
let(:options) { { before_import: ->(_) { raise ActiveAdminImport::Exception, 'error message' } } }
|
450
|
+
|
451
|
+
before { upload_file!(:authors) }
|
452
|
+
|
453
|
+
it 'should show error' do
|
454
|
+
expect(page).to have_content I18n.t('active_admin_import.file_error', message: 'error message')
|
455
|
+
expect(Author.count).to eq(0)
|
456
|
+
end
|
457
|
+
end
|
458
|
+
|
459
|
+
context 'when the option before_batch_import raises a ActiveAdminImport::Exception' do
|
460
|
+
let(:options) { { before_batch_import: ->(_) { raise ActiveAdminImport::Exception, 'error message' } } }
|
461
|
+
|
462
|
+
before { upload_file!(:authors) }
|
463
|
+
|
464
|
+
it 'should show error' do
|
465
|
+
expect(page).to have_content I18n.t('active_admin_import.file_error', message: 'error message')
|
466
|
+
expect(Author.count).to eq(0)
|
467
|
+
end
|
468
|
+
end
|
433
469
|
end
|
434
470
|
end
|
435
471
|
|
436
472
|
context "with slice_columns option" do
|
473
|
+
let(:batch_size) { 2 }
|
474
|
+
|
437
475
|
before do
|
438
476
|
add_author_resource template_object: ActiveAdminImport::Model.new,
|
439
477
|
before_batch_import: lambda { |importer|
|
440
478
|
importer.batch_slice_columns(slice_columns)
|
441
|
-
}
|
479
|
+
},
|
480
|
+
batch_size: batch_size
|
442
481
|
visit "/admin/authors/import"
|
443
482
|
upload_file!(:authors)
|
444
483
|
end
|
@@ -446,13 +485,23 @@ describe 'import', type: :feature do
|
|
446
485
|
context "slice last column and superfluous column" do
|
447
486
|
let(:slice_columns) { %w(name last_name not_existing_column) }
|
448
487
|
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
[
|
453
|
-
|
454
|
-
|
455
|
-
|
488
|
+
shared_examples_for "birthday column removed" do
|
489
|
+
it "should not fill `birthday` column" do
|
490
|
+
expect(Author.pluck(:name, :last_name, :birthday)).to match_array(
|
491
|
+
[
|
492
|
+
["Jane", "Roe", nil],
|
493
|
+
["John", "Doe", nil]
|
494
|
+
]
|
495
|
+
)
|
496
|
+
end
|
497
|
+
end
|
498
|
+
|
499
|
+
it_behaves_like "birthday column removed"
|
500
|
+
|
501
|
+
context "when doing more than one batch" do
|
502
|
+
let(:batch_size) { 1 }
|
503
|
+
|
504
|
+
it_behaves_like "birthday column removed"
|
456
505
|
end
|
457
506
|
end
|
458
507
|
|
data/spec/spec_helper.rb
CHANGED
@@ -20,6 +20,7 @@ system 'rake setup' unless File.exist?(ENV['RAILS_ROOT'])
|
|
20
20
|
require 'active_model'
|
21
21
|
# require ActiveRecord to ensure that Ransack loads correctly
|
22
22
|
require 'active_record'
|
23
|
+
require 'action_view'
|
23
24
|
require 'active_admin'
|
24
25
|
ActiveAdmin.application.load_paths = [ENV['RAILS_ROOT'] + '/app/admin']
|
25
26
|
require ENV['RAILS_ROOT'] + '/config/environment.rb'
|
data/tasks/test.rake
CHANGED
@@ -3,5 +3,5 @@ desc 'Creates a test rails app for the specs to run against'
|
|
3
3
|
task :setup do
|
4
4
|
require 'rails/version'
|
5
5
|
system('mkdir spec/rails') unless File.exist?('spec/rails')
|
6
|
-
system "bundle exec rails new spec/rails/rails-#{Rails::VERSION::STRING} -m spec/support/rails_template.rb --skip-spring --skip-turbolinks"
|
6
|
+
system "bundle exec rails new spec/rails/rails-#{Rails::VERSION::STRING} -m spec/support/rails_template.rb --skip-spring --skip-turbolinks --skip-bootsnap"
|
7
7
|
end
|
metadata
CHANGED
@@ -1,55 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_admin_import
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Igor Fedoronchuk
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-11-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord-import
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0.27'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0.27'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rchardet
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '1.6'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.6'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rubyzip
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '1.2'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '1.2'
|
55
55
|
- !ruby/object:Gem::Dependency
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 1.0.0
|
61
|
+
version: 1.0.0
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 1.0.0
|
68
|
+
version: 1.0.0
|
69
69
|
description: The most efficient way to import for Active Admin
|
70
70
|
email:
|
71
71
|
- fedoronchuk@gmail.com
|
@@ -99,6 +99,7 @@ files:
|
|
99
99
|
- lib/active_admin_import/authorization.rb
|
100
100
|
- lib/active_admin_import/dsl.rb
|
101
101
|
- lib/active_admin_import/engine.rb
|
102
|
+
- lib/active_admin_import/exception.rb
|
102
103
|
- lib/active_admin_import/import_result.rb
|
103
104
|
- lib/active_admin_import/importer.rb
|
104
105
|
- lib/active_admin_import/model.rb
|
@@ -133,7 +134,7 @@ homepage: http://github.com/Fivell/active_admin_import
|
|
133
134
|
licenses:
|
134
135
|
- MIT
|
135
136
|
metadata: {}
|
136
|
-
post_install_message:
|
137
|
+
post_install_message:
|
137
138
|
rdoc_options: []
|
138
139
|
require_paths:
|
139
140
|
- lib
|
@@ -148,9 +149,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
148
149
|
- !ruby/object:Gem::Version
|
149
150
|
version: '0'
|
150
151
|
requirements: []
|
151
|
-
|
152
|
-
|
153
|
-
signing_key:
|
152
|
+
rubygems_version: 3.1.6
|
153
|
+
signing_key:
|
154
154
|
specification_version: 4
|
155
155
|
summary: ActiveAdmin import based on activerecord-import gem.
|
156
156
|
test_files:
|