data_file 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c624f6ed68a60ae3afff5246813a4e9412459d5f
4
+ data.tar.gz: 7d3e88e31be86b9e1eb9ae434aacef2344446624
5
+ SHA512:
6
+ metadata.gz: b7f28ddbe7f0bcd16de77705f279fdf15430eacee720c341283b7f643eda316c32b35e89c88c488db1ee2e51fafb1b2e3eab62a255875e31474c44d1ad0d5eea
7
+ data.tar.gz: 78e46a94cb24e54992b3f3ec638c424d7a55f222137096bbf6861f45ca3a32047e778a87bc4b6fa880a639f633596d793b1569819ef1949b59c7687b0e52a479
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'simplecov', require: false
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Bruno Azisaka Maciel
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,3 @@
1
+ # DataFile
2
+
3
+ This gem is used to read CSV, TXT and XLS/XLSX files.
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'data_file/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "data_file"
8
+ spec.version = DataFile::VERSION
9
+ spec.authors = ["Bruno Azisaka Maciel"]
10
+ spec.email = ["bruno@azisaka.com.br"]
11
+ spec.summary = %q{Open data files with .csv, .txt, .xls, .xlsx extensions.}
12
+ spec.description = %q{With a parser and file detector, you just need to provide the file and it will do the rest.}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(spec)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ spec.add_dependency "mime-types"
25
+ spec.add_dependency "spreadsheet"
26
+ end
@@ -0,0 +1,10 @@
1
+ require "data_file/version"
2
+ require "data_file/reader"
3
+ require "data_file/reader/base"
4
+ require "data_file/reader/csv"
5
+ require "data_file/reader/excel"
6
+ require "data_file/importer"
7
+ require "data_file/detector"
8
+
9
+ module DataFile
10
+ end
@@ -0,0 +1,23 @@
1
+ require "mime-types"
2
+
3
+ module DataFile
4
+ class Detector
5
+ attr_reader :file
6
+
7
+ def initialize(file)
8
+ @file = file
9
+ end
10
+
11
+ def text?
12
+ mime_type =~ /text\/(plain|csv|comma-separated-values)/
13
+ end
14
+
15
+ def encoding
16
+ file.external_encoding.name
17
+ end
18
+
19
+ def mime_type
20
+ MIME::Types.type_for(file.path).first.content_type
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,35 @@
1
+ module DataFile
2
+ class Importer
3
+ attr_reader :reader
4
+
5
+ def initialize(reader)
6
+ @reader = reader
7
+ end
8
+
9
+ def each_row(row)
10
+ if csv?
11
+ row
12
+ else
13
+ row = rows[row]
14
+ defined?(POI) ? row.cells.map(&:value) : row.to_a
15
+ end
16
+ end
17
+
18
+ def rows
19
+ @rows ||= csv? ? reader.parser.rows : reader.parser.rows_range.to_a
20
+ end
21
+
22
+ def each(&block)
23
+ rows.each do |row|
24
+ row = each_row(row)
25
+ if !row.all?(&:blank?) && row != reader.parser.headers
26
+ block.call(row)
27
+ end
28
+ end
29
+ end
30
+
31
+ def csv?
32
+ reader.parser.is_a?(Reader::CSV)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+
3
+ module DataFile
4
+ class Reader
5
+ attr_reader :file, :file_path, :options
6
+
7
+ def initialize(file_path, options = {})
8
+ @options = { headers: true }.merge(options)
9
+ @file_path = file_path
10
+ end
11
+
12
+ def file
13
+ @file ||= File.open(file_path, 'r:iso-8859-1:utf-8')
14
+ end
15
+
16
+ def parser
17
+ @parser ||= detector.text? ? CSV.new(self) : Excel.new(self)
18
+ end
19
+
20
+ def detector
21
+ @detector ||= Detector.new(file)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,11 @@
1
+ module DataFile
2
+ class Reader
3
+ class Base
4
+ attr_reader :reader
5
+
6
+ def initialize(reader)
7
+ @reader = reader
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,22 @@
1
+ require "csv"
2
+
3
+ module DataFile
4
+ class Reader
5
+ class CSV < Base
6
+ def headers
7
+ @headers ||= (csv.headers rescue nil) || []
8
+ end
9
+
10
+ def rows
11
+ @rows ||= csv.each_with_object([]) do |row, array|
12
+ array << (row.is_a?(::CSV::Row) ? row.to_hash.values : row)
13
+ end
14
+ end
15
+
16
+ private
17
+ def csv
18
+ @csv ||= ::CSV.parse(reader.file.read, reader.options)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,40 @@
1
+ begin
2
+ require "poi"
3
+ rescue LoadError
4
+ require "spreadsheet"
5
+ end
6
+
7
+ module DataFile
8
+ class Reader
9
+ class Excel < Base
10
+ def headers
11
+ defined?(POI) ? rows[0].cells.map(&:value) : rows[0].to_a
12
+ end
13
+
14
+ def rows
15
+ worksheet.rows
16
+ end
17
+
18
+ def rows_range
19
+ (rows_index..rows.size)
20
+ end
21
+
22
+ def rows_index
23
+ reader.options[:headers] ? 1 : 0
24
+ end
25
+
26
+ def operator
27
+ defined?(POI) ? POI::Workbook : Spreadsheet
28
+ end
29
+
30
+ private
31
+ def excel
32
+ operator.open(reader.file_path)
33
+ end
34
+
35
+ def worksheet
36
+ excel.worksheets.first
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,3 @@
1
+ module DataFile
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,34 @@
1
+ require "spec_helper"
2
+ require "data_file/detector"
3
+
4
+ module DataFile
5
+ describe Detector do
6
+ let(:object) { described_class.new(file_path) }
7
+ let(:path) { "../../support/fixtures/#{file}" }
8
+ let(:file_path) { File.open(File.expand_path(path, __FILE__)) }
9
+
10
+ describe "#text?" do
11
+ subject { object.text? }
12
+
13
+ context "when the file is a xls" do
14
+ let(:file) { "test.xls" }
15
+ it { should be_false }
16
+ end
17
+
18
+ context "when the file is a xlsx" do
19
+ let(:file) { "test.xlsx" }
20
+ it { should be_false }
21
+ end
22
+
23
+ context "when the file is a txt" do
24
+ let(:file) { "test.txt" }
25
+ it { should be_true }
26
+ end
27
+
28
+ context "when the file is a csv" do
29
+ let(:file) { "test.csv" }
30
+ it { should be_true }
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,9 @@
1
+ require "spec_helper"
2
+ require "data_file/importer"
3
+
4
+ module DataFile
5
+ describe Importer do
6
+ let(:object) { described_class.new reader }
7
+ let(:reader) { double "reader" }
8
+ end
9
+ end
@@ -0,0 +1,43 @@
1
+ require "spec_helper"
2
+
3
+ module DataFile
4
+ describe Reader::CSV do
5
+ let(:csv_file) do
6
+ File.open(File.expand_path("../../../support/fixtures/test.csv", __FILE__))
7
+ end
8
+ let(:txt_file) do
9
+ File.open(File.expand_path("../../../support/fixtures/test.txt", __FILE__))
10
+ end
11
+
12
+ let(:file) { csv_file }
13
+ let(:object) { described_class.new reader }
14
+ let(:reader) { Reader.new file, options }
15
+ let(:options) { { } }
16
+
17
+ describe "#rows" do
18
+ subject { object.rows }
19
+
20
+ context "when the headers option is true" do
21
+ let(:options) { { headers: true } }
22
+
23
+ it { should == [ ["Does", "It", "Work", "?"] ] }
24
+ end
25
+
26
+ context "when the headers option is false" do
27
+ let(:options) { { headers: false } }
28
+
29
+ it { should == [ ["This", "Is", "A", "Test"],
30
+ ["Does", "It", "Work", "?"] ] }
31
+ end
32
+
33
+ context "when the headers option is not defined" do
34
+ it { should == [ ["Does", "It", "Work", "?"] ] }
35
+ end
36
+ end
37
+
38
+ describe "#headers" do
39
+ subject { object.headers }
40
+ it { should == ["This", "Is", "A", "Test"] }
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,62 @@
1
+ require "spec_helper"
2
+ require "data_file/reader"
3
+
4
+ module DataFile
5
+ describe Reader::Excel do
6
+ let(:xls_file) do
7
+ File.open(File.expand_path("../../../support/fixtures/test.xls", __FILE__))
8
+ end
9
+
10
+ let(:object) { described_class.new reader }
11
+ let(:reader) { Reader.new xls_file, options }
12
+ let(:options) { { } }
13
+
14
+ describe "#rows" do
15
+ subject { object.rows }
16
+
17
+ if defined?(POI)
18
+ it { should be_kind_of POI::Rows }
19
+ else
20
+ its(:first) { should be_kind_of Spreadsheet::Excel::Row }
21
+ end
22
+ end
23
+
24
+ describe "#rows_range" do
25
+ subject { object.rows_range }
26
+
27
+ context "when the headers option is true" do
28
+ let(:options) { { headers: true } }
29
+ it { should == (1..45) }
30
+ end
31
+
32
+ context "when the headers option is false" do
33
+ let(:options) { { headers: false } }
34
+ it { should == (0..45) }
35
+ end
36
+
37
+ context "when the headers option is not defined" do
38
+ let(:options) { { } }
39
+ it { should == (1..45) }
40
+ end
41
+ end
42
+
43
+ describe "#rows_index" do
44
+ subject { object.rows_index }
45
+
46
+ context "when the headers option is true" do
47
+ let(:options) { { headers: true } }
48
+ it { should == 1 }
49
+ end
50
+
51
+ context "when the headers option is false" do
52
+ let(:options) { { headers: false } }
53
+ it { should == 0 }
54
+ end
55
+
56
+ context "when the headers option is not defined" do
57
+ let(:options) { { } }
58
+ it { should == 1 }
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,31 @@
1
+ require "spec_helper"
2
+ require "data_file/reader"
3
+
4
+ module DataFile
5
+ describe Reader do
6
+ let(:object) { described_class.new "file_path" }
7
+
8
+ describe "#parser" do
9
+ subject { object.parser }
10
+
11
+ context "when the file is text" do
12
+ before { object.stub_chain(:detector, :text?).and_return(true) }
13
+ it { should be_kind_of Reader::CSV }
14
+ end
15
+
16
+ context "when the file is a spreadsheet" do
17
+ before { object.stub_chain(:detector, :text?).and_return(false) }
18
+ it { should be_kind_of Reader::Excel }
19
+ end
20
+ end
21
+
22
+ describe "#detector" do
23
+ let(:file) { double "file" }
24
+ before { object.stub(:file).and_return(file) }
25
+ subject { object.detector }
26
+
27
+ it { should be_kind_of(Detector) }
28
+ its(:file) { should == file }
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,16 @@
1
+ if ENV['COVERAGE']
2
+ require 'simplecov'
3
+ SimpleCov.start do
4
+ add_filter "/spec/"
5
+ end
6
+ end
7
+
8
+ require "data_file"
9
+
10
+ RSpec.configure do |config|
11
+ config.treat_symbols_as_metadata_keys_with_true_values = true
12
+ config.run_all_when_everything_filtered = true
13
+ config.filter_run :focus
14
+
15
+ config.order = 'random'
16
+ end
@@ -0,0 +1,2 @@
1
+ This,Is,A,Test
2
+ Does,It,Work,?
@@ -0,0 +1,2 @@
1
+ This,Is,A,Test
2
+ Does,It,Work,?
@@ -0,0 +1,5 @@
1
+ This,Is,A,Test
2
+ Does,It,Work,?
3
+ ?,Work,It,Does
4
+ A,B,C,D
5
+ D,C,B,A
@@ -0,0 +1,2 @@
1
+ field1,field2,field3,field4,field5
2
+ Hello,World,email@test.com,200,9.5
metadata ADDED
@@ -0,0 +1,159 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: data_file
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Bruno Azisaka Maciel
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: mime-types
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: spreadsheet
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: With a parser and file detector, you just need to provide the file and
84
+ it will do the rest.
85
+ email:
86
+ - bruno@azisaka.com.br
87
+ executables: []
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - ".gitignore"
92
+ - ".rspec"
93
+ - Gemfile
94
+ - LICENSE.txt
95
+ - README.md
96
+ - Rakefile
97
+ - data_file.gemspec
98
+ - lib/data_file.rb
99
+ - lib/data_file/detector.rb
100
+ - lib/data_file/importer.rb
101
+ - lib/data_file/reader.rb
102
+ - lib/data_file/reader/base.rb
103
+ - lib/data_file/reader/csv.rb
104
+ - lib/data_file/reader/excel.rb
105
+ - lib/data_file/version.rb
106
+ - spec/data_file/detector_spec.rb
107
+ - spec/data_file/importer_spec.rb
108
+ - spec/data_file/reader/csv_spec.rb
109
+ - spec/data_file/reader/excel_spec.rb
110
+ - spec/data_file/reader_spec.rb
111
+ - spec/spec_helper.rb
112
+ - spec/support/fixtures/test.aaa
113
+ - spec/support/fixtures/test.csv
114
+ - spec/support/fixtures/test.txt
115
+ - spec/support/fixtures/test.xls
116
+ - spec/support/fixtures/test.xlsx
117
+ - spec/support/fixtures/test_with_more_items.csv
118
+ - spec/support/fixtures/test_with_more_items.xls
119
+ - spec/support/fixtures/test_with_two_fields.csv
120
+ homepage: ''
121
+ licenses:
122
+ - MIT
123
+ metadata: {}
124
+ post_install_message:
125
+ rdoc_options: []
126
+ require_paths:
127
+ - lib
128
+ required_ruby_version: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ required_rubygems_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ requirements: []
139
+ rubyforge_project:
140
+ rubygems_version: 2.2.0
141
+ signing_key:
142
+ specification_version: 4
143
+ summary: Open data files with .csv, .txt, .xls, .xlsx extensions.
144
+ test_files:
145
+ - spec/data_file/detector_spec.rb
146
+ - spec/data_file/importer_spec.rb
147
+ - spec/data_file/reader/csv_spec.rb
148
+ - spec/data_file/reader/excel_spec.rb
149
+ - spec/data_file/reader_spec.rb
150
+ - spec/spec_helper.rb
151
+ - spec/support/fixtures/test.aaa
152
+ - spec/support/fixtures/test.csv
153
+ - spec/support/fixtures/test.txt
154
+ - spec/support/fixtures/test.xls
155
+ - spec/support/fixtures/test.xlsx
156
+ - spec/support/fixtures/test_with_more_items.csv
157
+ - spec/support/fixtures/test_with_more_items.xls
158
+ - spec/support/fixtures/test_with_two_fields.csv
159
+ has_rdoc: