active_admin_import 4.2.0 → 5.1.0
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/.github/workflows/test.yml +43 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile +3 -2
- data/README.md +3 -3
- data/active_admin_import.gemspec +3 -3
- data/lib/active_admin_import/dsl.rb +12 -3
- data/lib/active_admin_import/import_result.rb +11 -1
- data/lib/active_admin_import/importer.rb +2 -2
- data/lib/active_admin_import/model.rb +3 -1
- data/lib/active_admin_import/options.rb +1 -1
- data/lib/active_admin_import/version.rb +1 -1
- data/spec/fixtures/files/authors_values_exceeded_headers.csv +3 -0
- data/spec/import_spec.rb +76 -0
- metadata +16 -13
- data/.travis.yml +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 84ba0d9c89bd483eef55da51f9a06ec6327c4bbfffa79abc8431e578bb347c26
|
4
|
+
data.tar.gz: 9c13aefd9dc6397c7fee814ca4f4f7251d9cfb8c399249570acf902b928eacab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bad8987eeac221884549f9c36d28ced4afc5ed02ee6b65cbf68436053d1ac19644d270e3c20b10aa00b4eb7117289d030e8970036331e803716be6ac10a4bd8c
|
7
|
+
data.tar.gz: 3c8dd843c7fbdb989417a9a0a2611f0c66759f4662c02ed101d37bf36d51f15ecf4b88c49353599f4df5e978f6e19a36eab17cab8be4b65e985594665afc3080
|
@@ -0,0 +1,43 @@
|
|
1
|
+
name: Test
|
2
|
+
|
3
|
+
on:
|
4
|
+
- push
|
5
|
+
- pull_request
|
6
|
+
|
7
|
+
jobs:
|
8
|
+
build:
|
9
|
+
runs-on: ubuntu-latest
|
10
|
+
|
11
|
+
strategy:
|
12
|
+
matrix:
|
13
|
+
ruby_version:
|
14
|
+
- '2.6'
|
15
|
+
- '2.7'
|
16
|
+
- '3.0'
|
17
|
+
rails_version:
|
18
|
+
- '5.2.6'
|
19
|
+
- '6.0.4'
|
20
|
+
- '6.1.4'
|
21
|
+
- '7.0.0'
|
22
|
+
exclude:
|
23
|
+
- ruby_version: '3.0'
|
24
|
+
rails_version: '5.2.6'
|
25
|
+
- ruby_version: '2.6'
|
26
|
+
rails_version: '7.0.0'
|
27
|
+
|
28
|
+
name: Ruby ${{ matrix.ruby_version }} / Rails ${{ matrix.rails_version }}
|
29
|
+
|
30
|
+
env:
|
31
|
+
RAILS: ${{ matrix.rails_version }}
|
32
|
+
|
33
|
+
steps:
|
34
|
+
- uses: actions/checkout@v2
|
35
|
+
|
36
|
+
- name: Setup Ruby
|
37
|
+
uses: ruby/setup-ruby@v1
|
38
|
+
with:
|
39
|
+
ruby-version: ${{ matrix.ruby_version }}
|
40
|
+
bundler-cache: true
|
41
|
+
|
42
|
+
- name: Test
|
43
|
+
run: bundle exec rspec spec
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,11 @@
|
|
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
|
+
|
2
9
|
## [4.2.0] - 2020-02-05
|
3
10
|
- generic exception for import added #175 | @linqueta
|
4
11
|
|
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/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# ActiveAdminImport
|
2
2
|
|
3
|
-
[![
|
3
|
+
[![Build Status ][build_badge]][build_link]
|
4
4
|
[![Coverage Status][coveralls_badge]][coveralls_link]
|
5
5
|
[![Code Climate ][codeclimate_badge]][codeclimate_link]
|
6
6
|
[![Gem Version ][rubygems_badge]][rubygems_link]
|
@@ -91,8 +91,8 @@ Tool | Description
|
|
91
91
|
[rchardet]: https://github.com/jmhodges/rchardet
|
92
92
|
[activerecord-import]: https://github.com/zdennis/activerecord-import
|
93
93
|
|
94
|
-
[build_badge]: https://
|
95
|
-
[build_link]: https://
|
94
|
+
[build_badge]: https://github.com/activeadmin-plugins/active_admin_import/actions/workflows/test.yml/badge.svg
|
95
|
+
[build_link]: https://github.com/activeadmin-plugins/active_admin_import/actions
|
96
96
|
[coveralls_badge]: https://coveralls.io/repos/activeadmin-plugins/active_admin_import/badge.svg
|
97
97
|
[coveralls_link]: https://coveralls.io/github/activeadmin-plugins/active_admin_import
|
98
98
|
[codeclimate_badge]: https://codeclimate.com/github/activeadmin-plugins/active_admin_import/badges/gpa.svg
|
data/active_admin_import.gemspec
CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.require_paths = ['lib']
|
17
17
|
gem.version = ActiveAdminImport::VERSION
|
18
18
|
gem.add_runtime_dependency 'activerecord-import', '>= 0.27'
|
19
|
-
gem.add_runtime_dependency 'rchardet', '
|
20
|
-
gem.add_runtime_dependency 'rubyzip', '
|
21
|
-
gem.add_dependency 'activeadmin', '>= 1.0.0
|
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
|
@@ -54,11 +54,14 @@ module ActiveAdminImport
|
|
54
54
|
options.assert_valid_keys(*Options::VALID_OPTIONS)
|
55
55
|
|
56
56
|
options = Options.options_for(config, options)
|
57
|
-
params_key = ActiveModel::Naming.param_key(options[:template_object])
|
58
57
|
|
59
58
|
collection_action :import, method: :get do
|
60
59
|
authorize!(ActiveAdminImport::Auth::IMPORT, active_admin_config.resource_class)
|
61
|
-
@active_admin_import_model = options[:template_object]
|
60
|
+
@active_admin_import_model = if options[:template_object].is_a?(Proc)
|
61
|
+
options[:template_object].call
|
62
|
+
else
|
63
|
+
options[:template_object]
|
64
|
+
end
|
62
65
|
render template: options[:template]
|
63
66
|
end
|
64
67
|
|
@@ -75,7 +78,12 @@ module ActiveAdminImport
|
|
75
78
|
authorize!(ActiveAdminImport::Auth::IMPORT, active_admin_config.resource_class)
|
76
79
|
_params = params.respond_to?(:to_unsafe_h) ? params.to_unsafe_h : params
|
77
80
|
params = ActiveSupport::HashWithIndifferentAccess.new _params
|
78
|
-
@active_admin_import_model = options[:template_object]
|
81
|
+
@active_admin_import_model = if options[:template_object].is_a?(Proc)
|
82
|
+
options[:template_object].call
|
83
|
+
else
|
84
|
+
options[:template_object]
|
85
|
+
end
|
86
|
+
params_key = ActiveModel::Naming.param_key(@active_admin_import_model.class)
|
79
87
|
@active_admin_import_model.assign_attributes(params[params_key].try(:deep_symbolize_keys) || {})
|
80
88
|
# go back to form
|
81
89
|
return render template: options[:template] unless @active_admin_import_model.valid?
|
@@ -94,6 +102,7 @@ module ActiveAdminImport
|
|
94
102
|
end
|
95
103
|
rescue ActiveRecord::Import::MissingColumnError,
|
96
104
|
NoMethodError,
|
105
|
+
ArgumentError,
|
97
106
|
ActiveRecord::StatementInvalid,
|
98
107
|
CSV::MalformedCSVError,
|
99
108
|
ActiveAdminImport::Exception => e
|
@@ -33,11 +33,21 @@ module ActiveAdminImport
|
|
33
33
|
limit = options[:limit] || failed.count
|
34
34
|
failed.first(limit).map do |record|
|
35
35
|
errors = record.errors
|
36
|
-
failed_values = errors.
|
36
|
+
failed_values = attribute_names_for(errors).map do |key|
|
37
37
|
key == :base ? nil : record.public_send(key)
|
38
38
|
end
|
39
39
|
errors.full_messages.zip(failed_values).map { |ms| ms.compact.join(' - ') }.join(', ')
|
40
40
|
end.join(' ; ')
|
41
41
|
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def attribute_names_for(errors)
|
46
|
+
if Gem::Version.new(Rails.version) >= Gem::Version.new('7.0')
|
47
|
+
errors.attribute_names
|
48
|
+
else
|
49
|
+
errors.keys
|
50
|
+
end
|
51
|
+
end
|
42
52
|
end
|
43
53
|
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
|
|
@@ -115,7 +115,7 @@ module ActiveAdminImport
|
|
115
115
|
batch_size = options[:batch_size].to_i
|
116
116
|
File.open(file.path) do |f|
|
117
117
|
# capture headers if not exist
|
118
|
-
prepare_headers { CSV.parse(f.readline,
|
118
|
+
prepare_headers { CSV.parse(f.readline, **@csv_options).first }
|
119
119
|
f.each_line do |line|
|
120
120
|
lines << line if line.present?
|
121
121
|
if lines.size == batch_size || f.eof?
|
@@ -103,6 +103,8 @@ module ActiveAdminImport
|
|
103
103
|
|
104
104
|
def encode_file
|
105
105
|
data = File.read(file_path)
|
106
|
+
return if data.empty?
|
107
|
+
|
106
108
|
File.open(file_path, 'w') do |f|
|
107
109
|
f.write(encode(data))
|
108
110
|
end
|
@@ -110,7 +112,7 @@ module ActiveAdminImport
|
|
110
112
|
|
111
113
|
def unzip_file
|
112
114
|
Zip::File.open(file_path) do |zip_file|
|
113
|
-
self.file = Tempfile.new(CONST::TMP_FILE)
|
115
|
+
self.file = Tempfile.new(CONST::TMP_FILE, binmode: true)
|
114
116
|
data = zip_file.entries.select(&:file?).first.get_input_stream.read
|
115
117
|
file << data
|
116
118
|
file.close
|
data/spec/import_spec.rb
CHANGED
@@ -96,6 +96,38 @@ describe 'import', type: :feature do
|
|
96
96
|
end
|
97
97
|
include_examples 'successful inserts for author'
|
98
98
|
end
|
99
|
+
|
100
|
+
context 'when template object passed like proc' do
|
101
|
+
before do
|
102
|
+
add_post_resource(template_object: -> { ActiveAdminImport::Model.new(author_id: author.id) },
|
103
|
+
validate: true,
|
104
|
+
before_batch_import: lambda do |importer|
|
105
|
+
importer.csv_lines.map! { |row| row << importer.model.author_id }
|
106
|
+
importer.headers.merge!(:'Author Id' => :author_id)
|
107
|
+
end
|
108
|
+
)
|
109
|
+
|
110
|
+
visit '/admin/posts/import'
|
111
|
+
upload_file!(:posts_for_author)
|
112
|
+
end
|
113
|
+
|
114
|
+
include_examples 'successful inserts for author'
|
115
|
+
|
116
|
+
context 'after successful import try without file' do
|
117
|
+
let(:after_successful_import_do!) do
|
118
|
+
# reload page
|
119
|
+
visit '/admin/posts/import'
|
120
|
+
# submit form without file
|
121
|
+
find_button('Import').click
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'should render validation error' do
|
125
|
+
after_successful_import_do!
|
126
|
+
|
127
|
+
expect(page).to have_content I18n.t('active_admin_import.no_file_error')
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
99
131
|
end
|
100
132
|
|
101
133
|
context 'for csv with author name' do
|
@@ -371,6 +403,20 @@ describe 'import', type: :feature do
|
|
371
403
|
end
|
372
404
|
end
|
373
405
|
end
|
406
|
+
|
407
|
+
context 'when zipped with Win1251 file' do
|
408
|
+
let(:options) do
|
409
|
+
attributes = { force_encoding: :auto }
|
410
|
+
{ template_object: ActiveAdminImport::Model.new(attributes) }
|
411
|
+
end
|
412
|
+
it 'should import file' do
|
413
|
+
with_zipped_csv(:authors_win1251_win_endline) do
|
414
|
+
upload_file!(:authors_win1251_win_endline, :zip)
|
415
|
+
expect(page).to have_content 'Successfully imported 2 authors'
|
416
|
+
expect(Author.count).to eq(2)
|
417
|
+
end
|
418
|
+
end
|
419
|
+
end
|
374
420
|
end
|
375
421
|
|
376
422
|
context 'with different header attribute names' do
|
@@ -410,6 +456,36 @@ describe 'import', type: :feature do
|
|
410
456
|
expect(Author.count).to eq(2)
|
411
457
|
end
|
412
458
|
end
|
459
|
+
|
460
|
+
context 'with empty csv and auto detect encoding' do
|
461
|
+
let(:options) do
|
462
|
+
attributes = { force_encoding: :auto }
|
463
|
+
{ template_object: ActiveAdminImport::Model.new(attributes) }
|
464
|
+
end
|
465
|
+
|
466
|
+
before do
|
467
|
+
upload_file!(:empty)
|
468
|
+
end
|
469
|
+
|
470
|
+
it 'should render warning' do
|
471
|
+
expect(page).to have_content I18n.t('active_admin_import.file_empty_error')
|
472
|
+
expect(Author.count).to eq(0)
|
473
|
+
end
|
474
|
+
end
|
475
|
+
|
476
|
+
context 'with csv which has exceeded values' do
|
477
|
+
before do
|
478
|
+
upload_file!(:authors_values_exceeded_headers)
|
479
|
+
end
|
480
|
+
|
481
|
+
it 'should render warning' do
|
482
|
+
# 5 columns: 'birthday, name, last_name, created_at, updated_at'
|
483
|
+
# 6 values: '"1988-11-16", "Jane", "Roe", " exceeded value", datetime, datetime'
|
484
|
+
msg = 'Number of values (6) exceeds number of columns (5)'
|
485
|
+
expect(page).to have_content I18n.t('active_admin_import.file_error', message: msg)
|
486
|
+
expect(Author.count).to eq(0)
|
487
|
+
end
|
488
|
+
end
|
413
489
|
end
|
414
490
|
|
415
491
|
context 'with callback procs options' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_admin_import
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.1.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: 2023-11-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord-import
|
@@ -28,28 +28,28 @@ dependencies:
|
|
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
|
@@ -73,9 +73,9 @@ executables: []
|
|
73
73
|
extensions: []
|
74
74
|
extra_rdoc_files: []
|
75
75
|
files:
|
76
|
+
- ".github/workflows/test.yml"
|
76
77
|
- ".gitignore"
|
77
78
|
- ".rubocop.yml"
|
78
|
-
- ".travis.yml"
|
79
79
|
- CHANGELOG.md
|
80
80
|
- Gemfile
|
81
81
|
- LICENSE
|
@@ -113,6 +113,7 @@ files:
|
|
113
113
|
- spec/fixtures/files/authors_invalid_db.csv
|
114
114
|
- spec/fixtures/files/authors_invalid_model.csv
|
115
115
|
- spec/fixtures/files/authors_no_headers.csv
|
116
|
+
- spec/fixtures/files/authors_values_exceeded_headers.csv
|
116
117
|
- spec/fixtures/files/authors_win1251_win_endline.csv
|
117
118
|
- spec/fixtures/files/authors_with_ids.csv
|
118
119
|
- spec/fixtures/files/authors_with_semicolons.csv
|
@@ -134,7 +135,7 @@ homepage: http://github.com/Fivell/active_admin_import
|
|
134
135
|
licenses:
|
135
136
|
- MIT
|
136
137
|
metadata: {}
|
137
|
-
post_install_message:
|
138
|
+
post_install_message:
|
138
139
|
rdoc_options: []
|
139
140
|
require_paths:
|
140
141
|
- lib
|
@@ -149,8 +150,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
149
150
|
- !ruby/object:Gem::Version
|
150
151
|
version: '0'
|
151
152
|
requirements: []
|
152
|
-
|
153
|
-
|
153
|
+
rubyforge_project:
|
154
|
+
rubygems_version: 2.7.6.2
|
155
|
+
signing_key:
|
154
156
|
specification_version: 4
|
155
157
|
summary: ActiveAdmin import based on activerecord-import gem.
|
156
158
|
test_files:
|
@@ -162,6 +164,7 @@ test_files:
|
|
162
164
|
- spec/fixtures/files/authors_invalid_db.csv
|
163
165
|
- spec/fixtures/files/authors_invalid_model.csv
|
164
166
|
- spec/fixtures/files/authors_no_headers.csv
|
167
|
+
- spec/fixtures/files/authors_values_exceeded_headers.csv
|
165
168
|
- spec/fixtures/files/authors_win1251_win_endline.csv
|
166
169
|
- spec/fixtures/files/authors_with_ids.csv
|
167
170
|
- spec/fixtures/files/authors_with_semicolons.csv
|