rails-importer 0.0.6 → 0.0.11

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
- SHA1:
3
- metadata.gz: 0ee6bdad79ed8a4d980a915735461df003bca4d5
4
- data.tar.gz: 2105757e2d2515fdcb8f4e1483df2f85bc683f07
2
+ SHA256:
3
+ metadata.gz: 573081d673ea028ad52dedeb5b6492358a0e7e1e909b1f867e064bb01112ca9c
4
+ data.tar.gz: 83d313fdbd28f692b740e84c0ee2563f43f8ae2670489de0190da2db4e19bd5e
5
5
  SHA512:
6
- metadata.gz: 046fc96c808dfcce475bd1ada1e0c5467ec78b4d6ccee48a46d9a5029ca25d1d573d252f4f94a02249eaf96e896db33c28d64c63dc7eefa46d831cd1ee5bf996
7
- data.tar.gz: 1ff316fc036a83d9a93c82ceb5404441e3cb6a8413e42fff0b9a3969b1b9bf61147589e0321634debb76c14ff6df6f1fcd4cf2f987372e38f7d7378709607f05
6
+ metadata.gz: 3a5f67741c4dd49bde921f88451fac6cc275b2270d7137380915c0c7fcb2ce2b93528b70b5029048a6dffa2b5ba6787b17a7258f8f6f8b22a4fc6cf28f1ac157
7
+ data.tar.gz: f6cf858f4b81136dd9af761a00a882548f42d25658143cc522811ecdc1439918c9f47ec0d41adc31a62d887b55538b0c77a9b225e3ac0145aa77dcfd73e1a3b8
data/README.md CHANGED
@@ -30,8 +30,12 @@ class ExampleImporter < RailsImporter::Base
30
30
 
31
31
  importer do
32
32
  fields :name, :email, :age
33
+ #or fields({:name => "Name", :email => "E-mail", :age => "Idade"})
33
34
  each_record do |record, params|
35
+
34
36
  MyModel.find_or_create_by(name: record[:name], email: record[:email], age: record[:age])
37
+
38
+ return record # or return wherever
35
39
  end
36
40
  end
37
41
 
@@ -49,14 +53,68 @@ end
49
53
  ### How to use
50
54
 
51
55
  You can call `import` from **Importers** objects:
52
- ```erb
56
+ **file param** must be an object that responds to `.path` method
57
+ ```ruby
53
58
  file = params[:import][:file]
54
- records = ExampleImporter.import(file, extra_param: 'Extra')
59
+ records = ExampleImporter.import(file)
55
60
  ```
56
61
 
57
62
  Or with context:
63
+ ```ruby
64
+ file = params[:import][:file]
65
+ records = ExampleImporter.import(file, context: :simple)
66
+ ```
67
+
68
+ Overwrite default fields (called in the block `importer do`):
69
+ ```ruby
70
+ file = params[:import][:file]
71
+ records = ExampleImporter.import(file, fields: [:name, :email, :age])
72
+ ```
58
73
 
59
- ```erb
74
+ With extra params:
75
+ ```ruby
60
76
  file = params[:import][:file]
61
- records = ExampleImporter.import(file, context: :simple, extra_param: 'Extra')
62
- ```
77
+ records = ExampleImporter.import(file, {user: 'john@mail.com'})
78
+ ```
79
+ Then inside each record you can get params:
80
+ ```ruby
81
+ class ExampleImporter < RailsImporter::Base
82
+ importer do
83
+ # ...
84
+ each_record do |record, params|
85
+ # ...
86
+ params[:user]
87
+ # ...
88
+ end
89
+ # ...
90
+ end
91
+ end
92
+ ```
93
+
94
+ With full options:
95
+ ```ruby
96
+ file = params[:import][:file]
97
+ records = ExampleImporter.import(file,
98
+ context: :simple,
99
+ fields: [:name, :email, :age],
100
+ {user: 'john@mail.com', account: '1'})
101
+ ```
102
+
103
+ To return imported values, you need to return values inside of `each_record`:
104
+ ```ruby
105
+ class ExampleImporter < RailsImporter::Base
106
+ importer do
107
+ # ...
108
+ each_record do |record, params|
109
+ # ...
110
+ u = Model.new(record)
111
+ u.created_by = params[:user]
112
+ ok = !!u.save
113
+ return {record: u, success: ok}
114
+ end
115
+ # ...
116
+ end
117
+ end
118
+ records = ExampleImporter.import(file, {user: 'john@mail.com'})
119
+ # [{record: ..., success: true}, {record: ..., success: false}]
120
+ ```
@@ -1,4 +1,7 @@
1
1
  en:
2
2
  importer:
3
3
  error:
4
- invalid_file_type: "Invalid file type allowed: %{file_types}"
4
+ invalid_file: "Invalid File instance."
5
+ invalid_file_type: "Invalid file type allowed: %{file_types}"
6
+ convert_number_to_text: "Error when convert number to text"
7
+
@@ -8,18 +8,23 @@ module RailsImporter
8
8
  class << self
9
9
  def import(file, *args)
10
10
  context = args.try(:context) || :default
11
+ custom_fields = args.try(:fields) || nil
11
12
  result = []
12
13
  begin
13
- ext = (File.extname(file.path)[1..-1] rescue nil)
14
- if file.respond_to?(:path) and self.file_types.include?(ext.to_sym)
15
- rows = self.send("import_from_#{ext}", file)
16
- if rows.present? and rows.is_a?(Array)
17
- result = rows.map do |record|
18
- self.importers[context][:each_record].call(record, *args) if self.importers[context][:each_record].is_a?(Proc)
19
- end.compact
14
+ if file.respond_to?(:path)
15
+ ext = (File.extname(file.path)[1..-1] rescue '')
16
+ if self.file_types.include?(ext.to_sym)
17
+ rows = self.send('import_from_%s' % ext, file, context, custom_fields)
18
+ if rows.present? && rows.is_a?(Array)
19
+ result = rows.map do |record|
20
+ self.importers[context][:each_record].call(record, *args) if self.importers[context][:each_record].is_a?(Proc)
21
+ end.compact
22
+ end
23
+ else
24
+ result = I18n.t(:invalid_file_type, file_types: self.file_types.join(', '), scope: [:importer, :error])
20
25
  end
21
26
  else
22
- I18n.t(:invalid_file_type, file_types: self.file_types.join(', '), scope: [:importer, :error])
27
+ result = I18n.t(:invalid_file, scope: [:importer, :error])
23
28
  end
24
29
  rescue Exception => e
25
30
  result = e.message
@@ -37,7 +42,7 @@ module RailsImporter
37
42
  # end
38
43
  # end
39
44
 
40
- def importer(name=:default, &block)
45
+ def importer(name = :default, &block)
41
46
  (self.importers ||= {})[name] ||= {fields: [], xml_structure: [:records, :record], each_record: nil}
42
47
  @importer_name = name
43
48
  block.call if block_given?
@@ -57,19 +62,19 @@ module RailsImporter
57
62
  end
58
63
 
59
64
  private
60
- def import_from_csv(file, context=:default)
65
+ def import_from_csv(file, context = :default, custom_fields = :nil)
61
66
  records = []
62
67
  line = 0
63
68
  CSV.foreach(file.path, {:headers => false, :col_sep => ';', :force_quotes => true}) do |row|
64
- if line>0
65
- records << object_values(row, context) unless array_blank?(row)
69
+ if line > 0
70
+ records << object_values(row, context, custom_fields) unless array_blank?(row)
66
71
  end
67
- line+=1
72
+ line += 1
68
73
  end
69
74
  records
70
75
  end
71
76
 
72
- def import_from_xml(file, context=:default)
77
+ def import_from_xml(file, context = :default, custom_fields = :nil)
73
78
  records = []
74
79
  xml_structure = self.importers[context][:xml_structure]
75
80
  xml = Hash.from_xml(file.read)
@@ -77,59 +82,85 @@ module RailsImporter
77
82
  xml = xml[node.to_s]
78
83
  end
79
84
  xml.each do |elem|
80
- records << object_values(elem.values, context) unless array_blank?(elem.values)
85
+ records << object_values(elem.values, context, custom_fields) unless array_blank?(elem.values)
81
86
  end
82
87
  records
83
88
  end
84
89
 
85
- def import_from_xls(file, context=:default)
90
+ def import_from_xls(file, context = :default, custom_fields = :nil)
86
91
  records = []
87
92
  Spreadsheet.client_encoding = 'UTF-8'
88
93
  document = Spreadsheet.open(file.path)
89
94
  spreadsheet = document.worksheet 0
90
95
  spreadsheet.each_with_index do |row, i|
91
- next unless i>0
92
- records << object_values(row, context) unless array_blank?(row)
96
+ next if i.zero?
97
+ records << object_values(row, context, custom_fields) unless array_blank?(row)
93
98
  end
94
99
  records
95
100
  end
96
101
 
97
- def object_values(array, context=:default)
98
- attributes = self.importers[context][:fields]
102
+ def object_values(array, context = :default, custom_fields = nil)
103
+ attributes = custom_fields || self.importers[context][:fields]
99
104
  attributes = attributes.keys if attributes.is_a?(Hash)
100
- args = array[0...attributes.size]
101
- hValues = Hash[attributes.zip(args)]
105
+ values = equalize_columns_of_values(attributes, array)
106
+ hash_values = Hash[attributes.zip(values)]
102
107
  attributes.each do |attr|
103
- if hValues[attr].present?
104
- if hValues[attr].is_a?(Numeric)
105
- hValues[attr] = hValues[attr].to_i if hValues[attr].modulo(1).zero?
106
- hValues[attr] = (hValues[attr].to_s.strip rescue '#ERRO AO CONVERTER NUMERO PARA TEXTO')
107
- elsif hValues[attr].is_a?(Date)
108
- hValues[attr] = (I18n.l(hValues[attr], format: '%d/%m/%Y') rescue hValues[attr]).to_s
109
- elsif hValues[attr].is_a?(DateTime)
110
- hValues[attr] = (I18n.l(hValues[attr], format: '%d/%m/%Y %H:%i:%s') rescue hValues[attr]).to_s
108
+ if hash_values[attr].present?
109
+ if hash_values[attr].is_a?(Numeric)
110
+ hash_values[attr] = hash_values[attr].to_i if hash_values[attr].modulo(1).zero?
111
+ hash_values[attr] = (hash_values[attr].to_s.strip rescue I18n.t(:convert_number_to_text, scope: [:importer, :error]))
112
+ elsif hash_values[attr].is_a?(Date)
113
+ hash_values[attr] = (I18n.l(hash_values[attr], format: '%d/%m/%Y') rescue hash_values[attr]).to_s
114
+ elsif hash_values[attr].is_a?(DateTime)
115
+ hash_values[attr] = (I18n.l(hash_values[attr], format: '%d/%m/%Y %H:%i:%s') rescue hash_values[attr]).to_s
111
116
  else
112
117
  #PARA QUALQUER OUTRO VALOR, FORÇA CONVERTER PARA STRING
113
- hValues[attr] = (hValues[attr].to_s.strip rescue '')
118
+ hash_values[attr] = (hash_values[attr].to_s.strip rescue '')
114
119
  end
115
120
  else
116
- hValues[attr] = ''
121
+ hash_values[attr] = ''
117
122
  end
118
123
  end
119
- OpenStruct.new(hValues)
124
+ OpenStruct.new(hash_values)
120
125
  end
121
126
 
122
127
  def array_blank?(array)
123
- array.all? {|i|i.nil? or i==''}
128
+ array.all?(&:blank?)
124
129
  end
125
130
 
126
131
  def importer_value(key, attributes)
127
132
  if attributes.present?
128
- self.importers[@importer_name][key] = attributes
133
+ if key == :fields
134
+ self.importers[@importer_name][key] = normalize_fields(attributes)
135
+ else
136
+ self.importers[@importer_name][key] = attributes
137
+ end
129
138
  else
130
139
  self.importers[@importer_name][key]
131
140
  end
132
141
  end
142
+
143
+ def normalize_fields(attributes)
144
+ if attributes.first.is_a?(Hash)
145
+ attributes.inject(:merge)
146
+ elsif attributes.first.is_a?(Array)
147
+ attributes.flatten
148
+ else
149
+ attributes
150
+ end
151
+ end
152
+
153
+ def equalize_columns_of_values(attributes, values=[])
154
+ if attributes.size > values.size
155
+ diff_size = (attributes.size - values.size).abs
156
+ values + Array.new(diff_size, nil)
157
+ elsif attributes.size < values.size
158
+ values[0...attributes.size]
159
+ else
160
+ values
161
+ end
162
+ end
163
+
133
164
  end
134
165
 
135
166
  end
@@ -1,3 +1,3 @@
1
1
  module RailsImporter
2
- VERSION = "0.0.6"
2
+ VERSION = "0.0.11"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-importer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bruno Porto
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-02-13 00:00:00.000000000 Z
11
+ date: 2021-05-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -16,20 +16,20 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '3'
19
+ version: '4'
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: '6'
22
+ version: '7'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: '3'
29
+ version: '4'
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: '6'
32
+ version: '7'
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: spreadsheet
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -67,7 +67,6 @@ files:
67
67
  - lib/generators/templates/generic_importer.erb
68
68
  - lib/rails-importer.rb
69
69
  - lib/rails_importer.rb
70
- - lib/rails_importer/_importer.rb
71
70
  - lib/rails_importer/base.rb
72
71
  - lib/rails_importer/engine.rb
73
72
  - lib/rails_importer/version.rb
@@ -75,7 +74,7 @@ homepage: https://github.com/brunoporto/rails-importer
75
74
  licenses:
76
75
  - MIT
77
76
  metadata: {}
78
- post_install_message:
77
+ post_install_message:
79
78
  rdoc_options: []
80
79
  require_paths:
81
80
  - lib
@@ -90,9 +89,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
90
89
  - !ruby/object:Gem::Version
91
90
  version: '0'
92
91
  requirements: []
93
- rubyforge_project:
94
- rubygems_version: 2.5.1
95
- signing_key:
92
+ rubygems_version: 3.2.15
93
+ signing_key:
96
94
  specification_version: 4
97
95
  summary: Rails Importer
98
96
  test_files: []
@@ -1,138 +0,0 @@
1
- require 'ostruct'
2
-
3
- module RailsImporter
4
-
5
- def self.included(base)
6
- base.extend ClassMethods
7
-
8
- base.define_singleton_method 'colunas' do |*args|
9
- @importacao_colunas = nil unless @importacao_colunas.present?
10
- if args.present?
11
- @importacao_colunas = (args.first.is_a?(Hash) ? args.inject(:merge) : args)
12
- else
13
- @importacao_colunas
14
- end
15
- end
16
-
17
- base.define_singleton_method 'estrutura_xml' do |*args|
18
- @importacao_estrutura_xml = nil unless @importacao_estrutura_xml.present?
19
- if args.present?
20
- @importacao_estrutura_xml = args
21
- else
22
- @importacao_estrutura_xml
23
- end
24
- end
25
-
26
- base.define_singleton_method 'para_cada_linha' do |&block|
27
- define_singleton_method('importar_registro') do |registro, *args|
28
- block.call(registro, *args)
29
- end
30
- end
31
-
32
- end
33
-
34
- def self.tipos_de_arquivos
35
- [:csv, :xls, :xml]
36
- end
37
-
38
- module ClassMethods
39
-
40
- def importacao(&block)
41
- block.call if block_given?
42
- self.class.class_eval do
43
- define_method :importar do |arquivo, *args|
44
- retorno = []
45
- begin
46
- ext = (File.extname(arquivo.path)[1..-1] rescue nil)
47
- if arquivo.respond_to?(:path) and RailsImporter.tipos_de_arquivos.include?(ext.to_sym)
48
- registros = self.send("#{ext}_para_array", arquivo)
49
- if registros.present? and registros.is_a?(Array)
50
- retorno = registros.map do |registro|
51
- importar_registro(registro, *args)
52
- end
53
- end
54
- else
55
- raise "Tipo de arquivo inválido. Arquivos permitidos: #{RailsImporter.tipos_de_arquivos.join(', ')}"
56
- end
57
- rescue Exception => e
58
- retorno = e.message
59
- end
60
- retorno
61
- end
62
- end
63
- end
64
-
65
- private
66
- def csv_para_array(arquivo)
67
- registros = []
68
- linha=0
69
- CSV.foreach(arquivo.path, {:headers => false, :col_sep => ';', :force_quotes => true}) do |row|
70
- if linha>0
71
- registros << object_values(row) unless array_blank?(row)
72
- end
73
- linha+=1
74
- end
75
- registros
76
- end
77
-
78
- def xml_para_array(arquivo)
79
- registros = []
80
- estrutura_xml = self.send(:estrutura_xml)
81
- if estrutura_xml.present? and estrutura_xml.is_a?(Array) and estrutura_xml.count > 0
82
- xml = Hash.from_xml(arquivo.read)
83
- estrutura_xml.each do |node|
84
- xml = xml[node.to_s]
85
- end
86
- xml.each do |elem|
87
- registros << object_values(elem.values) unless array_blank?(elem.values)
88
- end
89
- else
90
- raise 'Você precisa informar a estrutura_xml no seu Model'
91
- end
92
- registros
93
- end
94
-
95
- def xls_para_array(arquivo)
96
- registros = []
97
- Spreadsheet.client_encoding = 'UTF-8'
98
- documento = Spreadsheet.open(arquivo.path)
99
- planilha = documento.worksheet 0
100
- planilha.each_with_index do |row, i|
101
- next unless i>0
102
- registros << object_values(row) unless array_blank?(row)
103
- end
104
- registros
105
- end
106
-
107
- def object_values(array)
108
- atributos = self.send(:colunas)
109
- atributos = atributos.keys if atributos.is_a?(Hash)
110
- args = array[0...atributos.size]
111
- hValores = Hash[atributos.zip(args)]
112
- #Ajustando valores inválidos
113
- atributos.each do |atributo|
114
- if hValores[atributo].present?
115
- if hValores[atributo].is_a?(Numeric)
116
- hValores[atributo] = hValores[atributo].to_i if hValores[atributo].modulo(1).zero?
117
- hValores[atributo] = (hValores[atributo].to_s.strip rescue '#ERRO AO CONVERTER NUMERO PARA TEXTO')
118
- elsif hValores[atributo].is_a?(Date)
119
- hValores[atributo] = (I18n.l(hValores[atributo], format: '%d/%m/%Y') rescue hValores[atributo]).to_s
120
- elsif hValores[atributo].is_a?(DateTime)
121
- hValores[atributo] = (I18n.l(hValores[atributo], format: '%d/%m/%Y %H:%i:%s') rescue hValores[atributo]).to_s
122
- else
123
- #PARA QUALQUER OUTRO VALOR, FORÇA CONVERTER PARA STRING
124
- hValores[atributo] = (hValores[atributo].to_s.strip rescue '')
125
- end
126
- else
127
- hValores[atributo] = ''
128
- end
129
- end
130
- OpenStruct.new(hValores)
131
- end
132
-
133
- def array_blank?(array)
134
- array.all? {|i|i.nil? or i==''}
135
- end
136
-
137
- end
138
- end