csvash 0.1.1 → 0.2
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.
- data/.DS_Store +0 -0
- data/.travis.yml +4 -0
- data/README.md +42 -5
- data/csvash.gemspec +2 -3
- data/lib/csvash/version.rb +1 -1
- data/lib/csvash.rb +80 -7
- data/lib/generators/.DS_Store +0 -0
- data/lib/generators/initializer/.DS_Store +0 -0
- data/lib/generators/initializer/USAGE +8 -0
- data/lib/generators/initializer/initializer_generator.rb +7 -0
- data/lib/generators/initializer/templates/csvash.rb +2 -0
- data/test/.DS_Store +0 -0
- data/test/fixtures/.DS_Store +0 -0
- data/test/fixtures/example_mass_assignment.csv +5 -0
- data/test/modelifying_test.rb +39 -16
- data/test/test_helper.rb +1 -0
- metadata +17 -2
data/.DS_Store
ADDED
Binary file
|
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -6,19 +6,56 @@ Csvash automates your CSV extraction by mapping its headers with the columns con
|
|
6
6
|
|
7
7
|
Add this line to your application's Gemfile:
|
8
8
|
|
9
|
-
|
9
|
+
```ruby
|
10
|
+
gem 'csvash'
|
11
|
+
```
|
10
12
|
|
11
13
|
And then execute:
|
12
14
|
|
13
|
-
|
15
|
+
```
|
16
|
+
$ bundle
|
17
|
+
```
|
14
18
|
|
15
19
|
Or install it yourself as:
|
16
20
|
|
17
|
-
|
21
|
+
```
|
22
|
+
$ gem install csvash
|
23
|
+
```
|
18
24
|
|
19
25
|
## Usage
|
20
26
|
|
21
|
-
|
27
|
+
First of all you have to require it in your file:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
require 'csvash'
|
31
|
+
```
|
32
|
+
|
33
|
+
To get a collection of hashes containing the csv data you can call:
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
Csvash.hashify '/path/of/your/file.csv'
|
37
|
+
```
|
38
|
+
|
39
|
+
If you prefer a collection of already filled objects from a specific class you can pass the csv path and the class:
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
Csvash.modelify '/path/of/your/file.csv', User
|
43
|
+
```
|
44
|
+
|
45
|
+
##Options
|
46
|
+
|
47
|
+
There are some behavior options that can be changed with its initializer. To create it just type:
|
48
|
+
|
49
|
+
```
|
50
|
+
$ rails generate initializer csvash
|
51
|
+
```
|
52
|
+
|
53
|
+
These are the avaiable options
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
# If set to true it will only retain fields that matches the class to be filled. Default is false.
|
57
|
+
# Csvash.mass_assignment_safe = true
|
58
|
+
```
|
22
59
|
|
23
60
|
## Contributing
|
24
61
|
|
@@ -26,4 +63,4 @@ Or install it yourself as:
|
|
26
63
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
64
|
3. Commit your changes (`git commit -am 'Added some feature'`)
|
28
65
|
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
-
5. Create new Pull Request
|
66
|
+
5. Create new Pull Request
|
data/csvash.gemspec
CHANGED
@@ -3,12 +3,11 @@ require File.expand_path('../lib/csvash/version', __FILE__)
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |gem|
|
5
5
|
gem.name = "csvash"
|
6
|
-
gem.authors = ["Lukas Alexandre"]
|
7
|
-
gem.email = ["lukeskytm@gmail.com"]
|
6
|
+
gem.authors = ["Lukas Alexandre", "Uriel Juliatti"]
|
7
|
+
gem.email = ["lukeskytm@gmail.com", "uriel.juliattivalle@gmail.com"]
|
8
8
|
gem.description = %q{Csvash automates your CSV extraction by mapping its headers with the columns contents and turning them into hashes that can be easily converted into ruby models.}
|
9
9
|
gem.summary = %q{Csvash automates your CSV extraction by mapping its headers with the columns contents and turning them into hashes that can be easily converted into ruby models.}
|
10
10
|
gem.homepage = "https://github.com/lukasalexandre/csvash"
|
11
|
-
|
12
11
|
gem.files = `git ls-files`.split($\)
|
13
12
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
14
13
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
data/lib/csvash/version.rb
CHANGED
data/lib/csvash.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
|
-
require
|
1
|
+
require 'csvash/version'
|
2
2
|
require 'csv'
|
3
|
+
require 'fileutils'
|
3
4
|
|
4
5
|
module Csvash
|
5
|
-
|
6
|
+
class << self; attr_accessor :mass_assignment_safe end
|
7
|
+
|
8
|
+
# <b>DEPRECATED:</b> Please use <tt>hashify</tt> instead.
|
6
9
|
def self.import_from_path(path)
|
7
10
|
warn "[DEPRECATION] `import_from_path` is deprecated. Please use `hashify` instead."
|
8
11
|
hashify path
|
@@ -14,18 +17,27 @@ module Csvash
|
|
14
17
|
end
|
15
18
|
end
|
16
19
|
|
17
|
-
|
20
|
+
# <b>DEPRECATED:</b> Please use <tt>modelify_and_export</tt> or <tt>modelify_and_import</tt> instead.
|
21
|
+
def self.modelify(path, klass, *args)
|
18
22
|
klass = klass.to_s.classify.constantize if klass.is_a?(String) || klass.is_a?(Symbol)
|
19
|
-
|
20
|
-
|
23
|
+
method = args.first
|
24
|
+
# rejecting attributes
|
25
|
+
unless method.is_a?Hash
|
26
|
+
self.public_send method , path, klass do |collection, current_line|
|
27
|
+
handle_mass_assignment(klass, current_line)
|
28
|
+
collection << klass.new(current_line)
|
29
|
+
end
|
30
|
+
else
|
21
31
|
end
|
22
32
|
end
|
23
33
|
|
34
|
+
|
24
35
|
private
|
25
|
-
|
36
|
+
|
37
|
+
def self.import(path, *optionals, &block)
|
26
38
|
cols = nil
|
27
|
-
first_line = true
|
28
39
|
collection = []
|
40
|
+
first_line = true
|
29
41
|
|
30
42
|
CSV.foreach(path, :encoding => "ISO-8859-1:UTF-8", :col_sep => "\;") do |line|
|
31
43
|
if first_line
|
@@ -42,4 +54,65 @@ private
|
|
42
54
|
end
|
43
55
|
collection
|
44
56
|
end
|
57
|
+
|
58
|
+
def self.handle_mass_assignment(klass, line)
|
59
|
+
if mass_assignment_safe
|
60
|
+
attr_cols = klass.instance_methods(false)
|
61
|
+
line = line.delete_if {|col| !attr_cols.include? col}
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# generates a csv file into a given path
|
66
|
+
# a path must be given (ex: *path/to/file.csv)
|
67
|
+
def self.export(file, collection, &block)
|
68
|
+
rows = []
|
69
|
+
file = self.full_path(file)
|
70
|
+
fields = ""
|
71
|
+
unless collection.empty?
|
72
|
+
# retrieving instance method names (getters)
|
73
|
+
collection.first.class.instance_methods(false).delete_if {|m| rows << m unless m.to_s.include?"=" }
|
74
|
+
begin
|
75
|
+
csv_return = nil
|
76
|
+
CSV.open(file, 'wb') do |csv|
|
77
|
+
csv << rows
|
78
|
+
collection.each do |item|
|
79
|
+
lines = []
|
80
|
+
rows.each {|attribute| lines << item.send(attribute)}
|
81
|
+
csv << lines
|
82
|
+
end
|
83
|
+
csv_return = csv
|
84
|
+
end
|
85
|
+
csv_return
|
86
|
+
rescue Errno::ENOENT => e
|
87
|
+
puts e
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
# shifts the method calling towards export() or import()
|
94
|
+
# ex: modelify_and_import("path/to/file.csv", collection), modelify_and_export("path/to/custom_filename.csv", collection)
|
95
|
+
def self.method_missing(method_name, *args)
|
96
|
+
super unless method_name =~ /^modelify_and_(\w+)$/
|
97
|
+
Csvash.public_send(:modelify, *args, $1)
|
98
|
+
end
|
99
|
+
|
100
|
+
# overriding respond_to method
|
101
|
+
def respond_to?(method)
|
102
|
+
(method =~ /^modelify_and_(\w+)$/) || super
|
103
|
+
end
|
104
|
+
|
105
|
+
# creates the full path
|
106
|
+
def self.full_path(file)
|
107
|
+
splitted = file.split("/")
|
108
|
+
current_file = file.split("/").last
|
109
|
+
current_path = splitted.shift(splitted.size-1)
|
110
|
+
current_full_path = current_path.join("/") + "/"
|
111
|
+
if File.directory?(current_full_path)
|
112
|
+
(current_full_path).concat(current_file)
|
113
|
+
else
|
114
|
+
FileUtils.mkdir_p(current_full_path)
|
115
|
+
(current_full_path).concat(current_file)
|
116
|
+
end
|
117
|
+
end
|
45
118
|
end
|
Binary file
|
Binary file
|
data/test/.DS_Store
ADDED
Binary file
|
Binary file
|
data/test/modelifying_test.rb
CHANGED
@@ -1,33 +1,56 @@
|
|
1
1
|
require 'minitest/spec'
|
2
2
|
require 'minitest/autorun'
|
3
|
+
require 'fileutils'
|
3
4
|
require 'csvash'
|
4
5
|
require "./test/test_helper"
|
5
6
|
|
6
7
|
include TestHelper
|
7
8
|
|
8
9
|
describe 'Modelifying' do
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
cars_extracted.first.
|
10
|
+
describe "import" do
|
11
|
+
it "passing the class" do
|
12
|
+
cars_extracted = Csvash.modelify_and_import fetch_fixture_path('example.csv'), Car
|
13
|
+
car = Car.new(
|
14
|
+
year: '1997',
|
15
|
+
make: 'Ford',
|
16
|
+
model: 'E350',
|
17
|
+
description: 'ac, abs, moon',
|
18
|
+
price: '3000.00'
|
19
|
+
)
|
20
|
+
cars_extracted.first.instance_variables.each do |name|
|
21
|
+
cars_extracted.first.instance_variable_get(name).must_equal car.instance_variable_get(name)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
it "Mass assignment Safe Mode ON" do
|
26
|
+
Csvash.mass_assignment_safe = true
|
27
|
+
cars_extracted = Csvash.modelify_and_import fetch_fixture_path('example_mass_assignment.csv'), Car
|
28
|
+
end
|
29
|
+
end
|
30
|
+
describe "export" do
|
31
|
+
it "passing a collection of Car object" do
|
32
|
+
cars = []
|
33
|
+
car = Car.new(
|
34
|
+
year: '1997',
|
35
|
+
make: 'Ford',
|
36
|
+
model: 'E350',
|
37
|
+
description: 'ac, abs, moon',
|
38
|
+
price: '3000.00'
|
39
|
+
)
|
40
|
+
cars << car
|
41
|
+
cars_exported = Csvash.modelify_and_export fetch_fixture_path('tmp/cars.csv'), cars
|
42
|
+
cars_exported.wont_be_nil
|
43
|
+
FileUtils.rm_rf(fetch_fixture_path('tmp/'))
|
20
44
|
end
|
21
45
|
end
|
46
|
+
|
22
47
|
end
|
23
48
|
|
24
49
|
class Car
|
25
50
|
def initialize(params)
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
self.description = params[:description]
|
30
|
-
self.price = params[:price]
|
51
|
+
params.each do |key, value|
|
52
|
+
self.public_send("#{key}=", value)
|
53
|
+
end
|
31
54
|
end
|
32
55
|
attr_accessor :year, :make, :model, :description, :price
|
33
56
|
end
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: csvash
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.2'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Lukas Alexandre
|
9
|
+
- Uriel Juliatti
|
9
10
|
autorequire:
|
10
11
|
bindir: bin
|
11
12
|
cert_chain: []
|
12
|
-
date: 2012-
|
13
|
+
date: 2012-09-11 00:00:00.000000000 Z
|
13
14
|
dependencies:
|
14
15
|
- !ruby/object:Gem::Dependency
|
15
16
|
name: rake
|
@@ -32,11 +33,14 @@ description: Csvash automates your CSV extraction by mapping its headers with th
|
|
32
33
|
ruby models.
|
33
34
|
email:
|
34
35
|
- lukeskytm@gmail.com
|
36
|
+
- uriel.juliattivalle@gmail.com
|
35
37
|
executables: []
|
36
38
|
extensions: []
|
37
39
|
extra_rdoc_files: []
|
38
40
|
files:
|
41
|
+
- .DS_Store
|
39
42
|
- .gitignore
|
43
|
+
- .travis.yml
|
40
44
|
- Gemfile
|
41
45
|
- LICENSE
|
42
46
|
- README.md
|
@@ -44,7 +48,15 @@ files:
|
|
44
48
|
- csvash.gemspec
|
45
49
|
- lib/csvash.rb
|
46
50
|
- lib/csvash/version.rb
|
51
|
+
- lib/generators/.DS_Store
|
52
|
+
- lib/generators/initializer/.DS_Store
|
53
|
+
- lib/generators/initializer/USAGE
|
54
|
+
- lib/generators/initializer/initializer_generator.rb
|
55
|
+
- lib/generators/initializer/templates/csvash.rb
|
56
|
+
- test/.DS_Store
|
57
|
+
- test/fixtures/.DS_Store
|
47
58
|
- test/fixtures/example.csv
|
59
|
+
- test/fixtures/example_mass_assignment.csv
|
48
60
|
- test/fixtures/example_values.txt
|
49
61
|
- test/hashifying_test.rb
|
50
62
|
- test/modelifying_test.rb
|
@@ -75,7 +87,10 @@ specification_version: 3
|
|
75
87
|
summary: Csvash automates your CSV extraction by mapping its headers with the columns
|
76
88
|
contents and turning them into hashes that can be easily converted into ruby models.
|
77
89
|
test_files:
|
90
|
+
- test/.DS_Store
|
91
|
+
- test/fixtures/.DS_Store
|
78
92
|
- test/fixtures/example.csv
|
93
|
+
- test/fixtures/example_mass_assignment.csv
|
79
94
|
- test/fixtures/example_values.txt
|
80
95
|
- test/hashifying_test.rb
|
81
96
|
- test/modelifying_test.rb
|