importance 0.2.0 → 0.2.1

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: e0df06e38c78ddb548f82dd7108a1ff45ac679ad21c8b6549ccba6107cbf37b3
4
- data.tar.gz: 1cd461bbaf521ab3d4358faa4accf85553d47fbb9941b8462d7e4342a154b45e
3
+ metadata.gz: 8932ca3f775616358be95d4bb6164a807dfcb19b88e9edc850ce76e8591ea0c5
4
+ data.tar.gz: 995531acbf763a74ddcf7ca870f5889e489ca1812d3144dec83673b65e73f8f7
5
5
  SHA512:
6
- metadata.gz: 855023fbe7167ff911683626c1e3f0d2eb0ae058f261f56c7f2e9d96afb01dc40e8a7e192f62fb1f47c79e824a971b8b46dee408d0b68370fc304695a0e66020
7
- data.tar.gz: 0b98ee22a71bb61a5cf7a218795eb934b418317dde08ebd22bd267757d7648c531d0ae0e432ec5e4746146ca54562620c2d397c005473fc237aa19cde80f8b23
6
+ metadata.gz: 324d49edebde11322489529b0edc6fc492ae227ca6ded396e118bb6b4f0f3a04f6e907d1e8277c3c87d046555e1d5fa54e44ad3db9151db7ea99cabf9736d7fc
7
+ data.tar.gz: ffdda200cfb6d85b6dec0741a173ba57a794b75e5a24d642c3451526a9a96a33452b36df6ce12e0b47ca3f7771eac61bf7433dc9561d18411a09c0aabc0bcfa6
data/Rakefile CHANGED
@@ -6,3 +6,13 @@ load "rails/tasks/engine.rake"
6
6
  load "rails/tasks/statistics.rake"
7
7
 
8
8
  require "bundler/gem_tasks"
9
+
10
+ require "rake/testtask"
11
+
12
+ Rake::TestTask.new(:test) do |t|
13
+ t.libs << "test"
14
+ t.pattern = "test/**/*_test.rb"
15
+ t.verbose = false
16
+ end
17
+
18
+ task default: :test
@@ -1,4 +1,4 @@
1
- require "xsv"
1
+ require "roo"
2
2
  require "csv"
3
3
 
4
4
  module Importance
@@ -36,22 +36,19 @@ module Importance
36
36
 
37
37
  raise ArgumentError, "Importer cannot be nil" if importer.nil?
38
38
 
39
- if csv_file?
40
- csv_data = CSV.read(session[:path], headers: true)
41
- @file_headers = csv_data.headers
42
- @samples = csv_data.first(5).map(&:to_h)
43
- else
44
- workbook = Xsv.open(session[:path], parse_headers: true)
45
- worksheet = workbook.first
46
- @file_headers = worksheet.first.keys
47
- @samples = worksheet.first(5)
48
- end
39
+ workbook = Roo::Spreadsheet.open(session[:path], { csv_options: { encoding: "bom|utf-8" } })
40
+ worksheet = workbook.sheet(0)
41
+ @file_headers = worksheet.row(1)
42
+ @samples = worksheet.parse[1..5]
43
+ @full_count = worksheet.count - 1
49
44
 
50
45
  @importer_attributes = importer.attributes
51
46
  @layout = "Importance::#{Importance.configuration.layout.to_s.camelize}Layout".constantize
52
47
  end
53
48
 
54
49
  # Import page. Load the file according to the mapping and import it.
50
+ # Mappings param is of the form mappings[excel_column_idx] = target_attribute
51
+ # mappings[0] = "first_name", mappings[1] = "", mappings[2] = "last_name" ...
55
52
  def import
56
53
  importer = Importance.configuration.importers[session[:importer].to_sym]
57
54
  mappings = params[:mappings]
@@ -97,33 +94,31 @@ module Importance
97
94
  File.extname(session[:path]).downcase == ".csv"
98
95
  end
99
96
 
97
+ # Yields each processed row (a hash of attribute => value) to the given block.
98
+ # Skips empty rows (all values nil or empty).
100
99
  def each_processed_row(mappings)
101
- if csv_file?
102
- CSV.foreach(session[:path], headers: true) do |row|
103
- record = process_row(row.to_h, mappings)
104
- next if record.empty? || record.values.all? { |v| v.nil? || v.to_s.strip.empty? }
105
- yield record
106
- end
107
- else
108
- workbook = Xsv.open(session[:path], parse_headers: true)
109
- worksheet = workbook.first
110
- worksheet.each do |row|
111
- record = process_row(row, mappings)
112
- next if record.empty? || record.values.all? { |v| v.nil? || v.to_s.strip.empty? }
113
- yield record
114
- end
100
+ workbook = Roo::Spreadsheet.open(session[:path], { csv_options: { encoding: "bom|utf-8" } })
101
+ worksheet = workbook.sheet(0)
102
+ worksheet.each_with_index do |row, idx|
103
+ next if idx == 0 # Skip header row
104
+ record = process_row(row, mappings)
105
+ next if record.empty? || record.values.all? { |v| v.nil? || v.to_s.strip.empty? }
106
+ yield record
115
107
  end
116
108
  end
117
109
 
110
+ # Turn a row of the form ["Hans", "Robert", 1970, "male", "Apple Inc.", "hr@apple.com"]
111
+ # and a mapping of the form {"0"=>"first_name", "1"=>"last_name", "2"=>"", "3"=>"", "4"=>"", "5"=>"email"}
112
+ # into a record of the form { first_name: "Hans", last_name: "Robert", email: "hr@apple.com" }
118
113
  def process_row(row, mappings)
119
114
  record = {}
120
- row.each do |row_header, value|
121
- attribute = mappings.permit!.to_h.find { |column_name, attribute_name| column_name == row_header }
122
- next if attribute.nil?
123
- attribute = attribute[1]
124
- next if attribute.nil? || attribute == ""
125
- record[attribute.to_sym] = value
115
+
116
+ mappings.each do |column_index, attribute_name|
117
+ next if attribute_name.nil? || attribute_name == ""
118
+ value = row[column_index.to_i]
119
+ record[attribute_name.to_sym] = value
126
120
  end
121
+
127
122
  record
128
123
  end
129
124
 
@@ -4,14 +4,14 @@
4
4
  <table class="importance-table <%= @layout.table_class %>">
5
5
  <thead>
6
6
  <tr>
7
- <% @file_headers.each do |file_header| %>
7
+ <% @file_headers.each_with_index do |file_header, file_header_idx| %>
8
8
  <th>
9
9
  <%= t('importance.use_column_as') %>
10
10
  <%
11
11
  attribute_mappings = Importance::Header.match_attributes_to_headers(@importer_attributes, @file_headers)
12
12
  default_value = Importance::Header.default_value_for_header(file_header, attribute_mappings)
13
13
  %>
14
- <%= form.select "mappings[#{file_header}]",
14
+ <%= form.select "mappings[#{file_header_idx}]",
15
15
  options_for_select(
16
16
  [[t('importance.ignore'), ""]] +
17
17
  @importer_attributes.map { |attr| [attr.labels.first, attr.key] },
@@ -29,13 +29,16 @@
29
29
  <tbody>
30
30
  <% @samples.each do |sample| %>
31
31
  <tr>
32
- <% @file_headers.each do |file_header| %>
33
- <td><%= sample[file_header] %></td>
32
+ <% @file_headers.each_with_index do |file_header, file_header_idx| %>
33
+ <td><%= sample[file_header_idx] %></td>
34
34
  <% end %>
35
35
  </tr>
36
36
  <% end %>
37
37
  </tbody>
38
38
  </table>
39
+ <p>
40
+ <%= t('importance.import_description', count: @samples.count, full_count: @full_count) %>
41
+ </p>
39
42
  </div>
40
43
  <% end %>
41
44
 
@@ -3,3 +3,4 @@ de:
3
3
  use_column_as: Spalte verwenden als
4
4
  ignore: Ignorieren
5
5
  import: Importieren
6
+ import_description: "Es werden %{count} von %{full_count} Beispieldatensätzen angezeigt."
@@ -3,3 +3,4 @@ en:
3
3
  use_column_as: Use column as
4
4
  ignore: Ignore
5
5
  import: Import
6
+ import_description: "Showing %{count} of %{full_count} sample records."
@@ -3,3 +3,4 @@ fr:
3
3
  use_column_as: Utiliser la colonne comme
4
4
  ignore: Ignorer
5
5
  import: Importer
6
+ import_description: "Affichage de %{count} sur %{full_count} exemples d'enregistrements."
@@ -3,3 +3,4 @@ it:
3
3
  use_column_as: Utilizzare come
4
4
  ignore: Ignora
5
5
  import: Importare
6
+ import_description: "Mostrati %{count} di %{full_count} record di esempio."
@@ -1,3 +1,3 @@
1
1
  module Importance
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: importance
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lukas_Skywalker
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-06-07 00:00:00.000000000 Z
11
+ date: 2025-10-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -25,19 +25,19 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: 7.0.2
27
27
  - !ruby/object:Gem::Dependency
28
- name: xsv
28
+ name: roo
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.3'
33
+ version: '3.0'
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
- version: '1.3'
40
+ version: '3.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: ostruct
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -45,27 +45,13 @@ dependencies:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0.6'
48
- type: :development
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: '0.6'
55
- - !ruby/object:Gem::Dependency
56
- name: debug
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '1.10'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '1.10'
69
55
  description: Importance is a Rails engine that allows users to upload Excel and CSV
70
56
  files and interactively map columns to model attributes. It handles files with arbitrary
71
57
  headers by letting users select which columns to import and which to ignore, with
@@ -127,7 +113,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
127
113
  - !ruby/object:Gem::Version
128
114
  version: '0'
129
115
  requirements: []
130
- rubygems_version: 3.5.16
116
+ rubygems_version: 3.5.22
131
117
  signing_key:
132
118
  specification_version: 4
133
119
  summary: Flexible Excel and CSV import engine with column mapping for Rails applications