ibge 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
  SHA1:
3
- metadata.gz: 80232f32e1ca3fe301c1abfe7a5a87981df49c71
4
- data.tar.gz: bc5e203e2309aa62d263418a9b5d4fec2807b60e
3
+ metadata.gz: 6ed56fa3c4b240472a91542f75c8a216f78ce28c
4
+ data.tar.gz: 9e49eb09876bbd6c12d1ae6778303b227c7ca68d
5
5
  SHA512:
6
- metadata.gz: d51d20081b0f09a6096f3f881d77bb6468528fbf604a85c9ff042390abc875ca3d4921ea046e26ac4e0d6d5d73986ef6b9a93e87377211c1b7744ce9898231f8
7
- data.tar.gz: 9c5c550044bd2d2cff27b079b97ec40d1ef4056ef48419b8e707e62f9cc2057ec857e4d9cdd3df1531d048f8e8049fe24b2312a62a56b8dcc1734157e46787a2
6
+ metadata.gz: 95c9383f0d6f2cdc4c8a79a7847159408ab6f1acad4e92027f8bcf41837d5a23efc6cb878c619c7a1ed6ec3160372a81d24f326e3372bde43b290293e4a0119c
7
+ data.tar.gz: 23cb3405ae6b2be14e7cd5c0afad076947b445fe62341b6c778322ae9bd05ba77cd23a5007fc361c59162c833ae9fd5e27359be1299addf37296162e7523767a
data/lib/ibge.rb CHANGED
@@ -6,13 +6,14 @@ module Ibge
6
6
  DATA_PATH = File.expand_path(File.join(__dir__, '..', 'data'))
7
7
 
8
8
  module Reader
9
- autoload :Base, 'ibge/reader/base'
10
- autoload :State, 'ibge/reader/state'
11
- autoload :MesoRegion, 'ibge/reader/meso_region'
12
- autoload :MicroRegion, 'ibge/reader/micro_region'
13
- autoload :Municipality, 'ibge/reader/municipality'
14
- autoload :District, 'ibge/reader/district'
15
- autoload :SubDistrict, 'ibge/reader/sub_district'
16
- autoload :Neighborhood, 'ibge/reader/neighborhood'
9
+ autoload :Helpers, "ibge/reader/helpers"
10
+ autoload :Base, "ibge/reader/base"
11
+ autoload :State, "ibge/reader/state"
12
+ autoload :MesoRegion, "ibge/reader/meso_region"
13
+ autoload :MicroRegion, "ibge/reader/micro_region"
14
+ autoload :Municipality, "ibge/reader/municipality"
15
+ autoload :District, "ibge/reader/district"
16
+ autoload :SubDistrict, "ibge/reader/sub_district"
17
+ autoload :Neighborhood, "ibge/reader/neighborhood"
17
18
  end
18
19
  end
@@ -3,30 +3,7 @@ require 'spreadsheet'
3
3
  module Ibge
4
4
  module Reader
5
5
  class Base
6
- class << self
7
- SOURCES = {
8
- dtb: 'DTB_2014_subdistrito.xls',
9
- sidra: 'sidra.xls'
10
- }
11
-
12
- attr_reader :defined_columns, :selected_source
13
-
14
- def columns(columns = {})
15
- @defined_columns = columns
16
- end
17
-
18
- def source(selected_source = :dtb)
19
- unless SOURCES.keys.include?(selected_source)
20
- raise ArgumentError, "Source must be one of those '#{SOURCES.keys.flatten.join(', ')}'"
21
- end
22
-
23
- @selected_source = selected_source
24
- end
25
-
26
- def sources
27
- SOURCES
28
- end
29
- end
6
+ extend Ibge::Reader::Helpers
30
7
 
31
8
  attr_reader :filename
32
9
 
@@ -35,37 +12,102 @@ module Ibge
35
12
  end
36
13
 
37
14
  def initialize(options = {})
38
- @filename = options.fetch(:filename, default_filename)
15
+ @spreadsheet = {}
16
+ @rows = {}
17
+ @selected_sheet = {}
18
+
19
+ self.selected_source = self.class.selected_source
20
+
21
+ unless options.fetch(:filename, nil).nil?
22
+ filename = options.fetch(:filename)
23
+
24
+ if filename.is_a?(Hash)
25
+ sources_filename = options.fetch(:filename).keys
26
+
27
+ sources_filename.each do |source_filename|
28
+ self.class.valid_informed_source(source_filename)
29
+ end
30
+ else
31
+ raise ArgumentError,
32
+ "Filename must be a hash with the source as key"
33
+ end
34
+ end
35
+
36
+ default_filename = default_filename_to(selected_source)
37
+
38
+ @filename = options.fetch(:filename, "#{DATA_PATH}/#{default_filename}")
39
39
  end
40
40
 
41
41
  def read
42
- transformed_rows = rows[1..-1].map do |row|
43
- transform(row.compact.values_at(*column_range), column_range)
42
+ transformed_rows = []
43
+ previous_column_range = nil
44
+
45
+ if multiple_sources?
46
+ loaded_sources = defined_columns.keys.sort
47
+
48
+ loaded_sources.each do |loaded_source|
49
+ self.selected_source = loaded_source
50
+ @filename = default_filename_to(loaded_source)
51
+
52
+ if transformed_rows == []
53
+ transformed_rows = rows[1..-1].map do |row|
54
+ transform(row.compact.values_at(*column_range), column_range)
55
+ end
56
+
57
+ transformed_rows = transformed_rows.uniq
58
+
59
+ previous_column_range = column_range
60
+ else
61
+ transformed_rows.each do |transformed_row|
62
+ selected_rows = rows[1..-1].select do |r|
63
+ r[previous_column_range.first] == transformed_row.values.first
64
+ end
65
+
66
+ new_row = selected_rows.compact.uniq { |r| r[0] }.map do |row|
67
+ transform(row.compact.values_at(*column_range), column_range)
68
+ end
69
+
70
+ if new_row.empty?
71
+ columns = self.class.defined_columns[selected_source]
72
+
73
+ columns.each do |column|
74
+ new_row << { column[1] => "" }
75
+ end
76
+ end
77
+
78
+ transformed_row.merge!(*new_row)
79
+ end
80
+ end
81
+ end
82
+ else
83
+ transformed_rows = rows[1..-1].map do |row|
84
+ transform(row.compact.values_at(*column_range), column_range)
85
+ end
44
86
  end
45
87
 
46
- transformed_rows.uniq.sort_by { |hash| data_sort(hash) }
88
+ transformed_rows.uniq.sort_by { |h| data_sort(h) }
47
89
  end
48
90
 
49
91
  protected
50
92
 
51
- def default_filename
52
- File.join DATA_PATH, sources[selected_source]
93
+ attr_accessor :selected_source
94
+
95
+ def default_filename_to(source)
96
+ sources[source.to_sym]
53
97
  end
54
98
 
55
99
  def spreadsheet
56
- @spreadsheet ||= Spreadsheet.open filename
100
+ filename = File.join(DATA_PATH, default_filename_to(selected_source))
101
+
102
+ @spreadsheet[selected_source] ||= Spreadsheet.open filename
57
103
  end
58
104
 
59
105
  def sheet
60
- @selected_sheet ||= spreadsheet.worksheets.first
106
+ @selected_sheet[selected_source] ||= spreadsheet.worksheets.first
61
107
  end
62
108
 
63
109
  def rows
64
- @rows ||= sheet.rows
65
- end
66
-
67
- def selected_source
68
- self.class.selected_source || :dtb
110
+ @rows[selected_source] ||= sheet.rows
69
111
  end
70
112
 
71
113
  def sources
@@ -77,7 +119,7 @@ module Ibge
77
119
  end
78
120
 
79
121
  def column_keys
80
- defined_columns.keys.map(&:to_s).map(&:to_i)
122
+ defined_columns[selected_source].keys.map(&:to_s).map(&:to_i)
81
123
  end
82
124
 
83
125
  def column_range
@@ -86,9 +128,13 @@ module Ibge
86
128
 
87
129
  def transform(row, column_range)
88
130
  row.each_with_index.inject({}) do |item, (raw_data, index)|
89
- column_index = column_range[index]
131
+ column_index = column_range[index].to_s.to_sym
132
+
133
+ hash = {
134
+ defined_columns[selected_source][column_index] => raw_data
135
+ }
90
136
 
91
- item.merge!(self.class.defined_columns[column_index.to_s.to_sym] => raw_data)
137
+ item.merge!(hash)
92
138
  end
93
139
  end
94
140
 
@@ -102,6 +148,10 @@ module Ibge
102
148
 
103
149
  order_values
104
150
  end
151
+
152
+ def multiple_sources?
153
+ defined_columns.keys.size > 1
154
+ end
105
155
  end
106
156
  end
107
157
  end
@@ -0,0 +1,78 @@
1
+ module Ibge
2
+ module Reader
3
+ module Helpers
4
+ SOURCES = {
5
+ dtb: "DTB_2014_subdistrito.xls",
6
+ sidra: "sidra.xls"
7
+ }
8
+
9
+ attr_reader :defined_columns, :selected_source
10
+
11
+ def columns(columns)
12
+ if columns.empty?
13
+ raise ArgumentError,
14
+ "Columns must be provided as hash which contains " /
15
+ "the index and field name"
16
+ end
17
+
18
+ @defined_columns ||= {}
19
+ @selected_source ||= :dtb
20
+
21
+ distinct_sources = []
22
+
23
+ columns.each do |_, v|
24
+ if v.is_a?(Hash)
25
+ hash_column_definition = v.values.first
26
+
27
+ unless hash_column_definition.key?(:from_source)
28
+ raise ArgumentError, "#{v.key} must have the key from_source"
29
+ end
30
+
31
+ valid_informed_source(hash_column_definition[:from_source])
32
+
33
+ distinct_sources << hash_column_definition[:from_source]
34
+ end
35
+ end
36
+
37
+ distinct_sources = distinct_sources.compact.uniq.sort
38
+
39
+ distinct_sources.each do |source|
40
+ extracted_columns = columns.select do |_, v|
41
+ v.is_a?(Hash) && v.values.first[:from_source] == source
42
+ end
43
+
44
+ @defined_columns[source] = extracted_columns.inject({}) do |h, (k, v)|
45
+ h.merge!(k.to_s.to_sym => v.is_a?(Hash) ? v.keys.first : v)
46
+
47
+ h
48
+ end
49
+ end
50
+
51
+ if @selected_source
52
+ @defined_columns[@selected_source] = columns.select do |_, v|
53
+ v.is_a?(Symbol)
54
+ end
55
+ end
56
+ end
57
+
58
+ def source(selected_source = :dtb)
59
+ valid_informed_source(selected_source)
60
+
61
+ @selected_source = selected_source
62
+ end
63
+
64
+ def sources
65
+ SOURCES
66
+ end
67
+
68
+ def valid_informed_source(informed_source)
69
+ source_keys = sources.keys
70
+
71
+ unless source_keys.include?(informed_source)
72
+ raise ArgumentError,
73
+ "Source must be one of those '#{source_keys.join(', ')}'"
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -1,11 +1,9 @@
1
1
  module Ibge
2
2
  module Reader
3
3
  class State < Base
4
- source :sidra
5
-
6
4
  columns "0": :code,
7
5
  "1": :state_name,
8
- "2": :state_federative_unit
6
+ "2": { state_federative_unit: { from_source: :sidra } }
9
7
  end
10
8
  end
11
9
  end
data/lib/ibge/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Ibge
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
@@ -1,47 +1,97 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  describe Ibge::Reader::Base do
4
- class Reader < Ibge::Reader::Base
5
- source :sidra
4
+ context "source on top of the reader" do
5
+ class ReaderWithSource < Ibge::Reader::Base
6
+ source :sidra
6
7
 
7
- columns "0": :code
8
- end
8
+ columns "0": :code
9
+ end
9
10
 
10
- subject { Reader }
11
+ subject { ReaderWithSource }
11
12
 
12
- describe '.columns' do
13
- it { should respond_to :columns }
13
+ describe ".columns" do
14
+ it { should respond_to :columns }
14
15
 
15
- it 'maps the column index to a recognized column name' do
16
- expect(subject.defined_columns).to eq "0": :code
16
+ it "maps the column index to a recognized column name" do
17
+ expect(subject.defined_columns).to eq sidra: { "0": :code }
18
+ end
17
19
  end
18
- end
19
20
 
20
- describe '.read' do
21
- context 'without pass a :filename as option' do
22
- it 'reads the file inside data folder' do
23
- expect(subject.read).to include code: "11"
21
+ describe ".read" do
22
+ context "without pass a :filename as option" do
23
+ it "reads the file inside data folder" do
24
+ expect(subject.read).to include code: "11"
25
+ end
26
+ end
27
+
28
+ context "passing a :filename" do
29
+ it "reads the file provided" do
30
+ filename = "spec/fixtures/DTB_example_subdistrito.xls"
31
+
32
+ content = subject.read(filename: { dtb: filename })
33
+
34
+ expect(content).to include code: "11"
35
+ end
24
36
  end
25
37
  end
26
38
 
27
- context 'passing a :filename' do
28
- it 'reads the file provided' do
29
- filename = "spec/fixtures/DTB_example_subdistrito.xls"
39
+ describe ".selected_source" do
40
+ it "show the default file source to read" do
41
+ expect(subject.selected_source).to eq :sidra
42
+ end
43
+ end
30
44
 
31
- expect(subject.read(filename: filename)).to include code: "11"
45
+ describe "#filename" do
46
+ it "sets the default to file inside data folder" do
47
+ expect(subject.new.filename).to include "data/sidra.xls"
32
48
  end
33
49
  end
34
50
  end
35
51
 
36
- describe '.selected_source' do
37
- it 'show the default file source to read' do
38
- expect(subject.selected_source).to eq :sidra
52
+ context "without source defined" do
53
+ class ReaderWithoutSource < Ibge::Reader::Base
54
+ columns "0": :code
39
55
  end
40
- end
41
56
 
42
- describe '#filename' do
43
- it 'sets the default to file inside data folder' do
44
- expect(subject.new.filename).to include 'data/sidra.xls'
57
+ subject { ReaderWithoutSource }
58
+
59
+ describe ".columns" do
60
+ it { should respond_to :columns }
61
+
62
+ it "maps the column index to a recognized column name" do
63
+ expect(subject.defined_columns).to eq dtb: { "0": :code }
64
+ end
65
+ end
66
+
67
+ describe ".read" do
68
+ context "without pass a :filename as option" do
69
+ it "reads the file inside data folder" do
70
+ expect(subject.read).to include code: "11"
71
+ end
72
+ end
73
+
74
+ context "passing a :filename" do
75
+ it "reads the file provided" do
76
+ filename = "spec/fixtures/DTB_example_subdistrito.xls"
77
+
78
+ content = subject.read(filename: { dtb: filename })
79
+
80
+ expect(content).to include code: "11"
81
+ end
82
+ end
83
+ end
84
+
85
+ describe ".selected_source" do
86
+ it "show the default file source to read" do
87
+ expect(subject.selected_source).to eq :dtb
88
+ end
89
+ end
90
+
91
+ describe "#filename" do
92
+ it "sets the default to file inside data folder" do
93
+ expect(subject.new.filename).to include "data/DTB_2014_subdistrito.xls"
94
+ end
45
95
  end
46
96
  end
47
97
  end
@@ -3,13 +3,21 @@ require 'spec_helper'
3
3
  describe Ibge::Reader::District do
4
4
  subject { described_class }
5
5
 
6
+ let(:columns) do
7
+ {
8
+ dtb: {
9
+ "0": :state_code,
10
+ "2": :meso_region_code,
11
+ "4": :micro_region_code,
12
+ "6": :municipality_code,
13
+ "9": :code,
14
+ "10": :full_code,
15
+ "11": :name
16
+ }
17
+ }
18
+ end
19
+
6
20
  it 'should have defined columns' do
7
- expect(subject.defined_columns).to include "0": :state_code,
8
- "2": :meso_region_code,
9
- "4": :micro_region_code,
10
- "6": :municipality_code,
11
- "9": :code,
12
- "10": :full_code,
13
- "11": :name
21
+ expect(subject.defined_columns).to eq columns
14
22
  end
15
23
  end
@@ -3,9 +3,17 @@ require 'spec_helper'
3
3
  describe Ibge::Reader::MesoRegion do
4
4
  subject { described_class }
5
5
 
6
+ let(:columns) do
7
+ {
8
+ dtb: {
9
+ "0": :state_code,
10
+ "2": :code,
11
+ "3": :name
12
+ }
13
+ }
14
+ end
15
+
6
16
  it 'should have defined columns' do
7
- expect(subject.defined_columns).to include "0": :state_code,
8
- "2": :code,
9
- "3": :name
17
+ expect(subject.defined_columns).to eq columns
10
18
  end
11
19
  end
@@ -3,10 +3,18 @@ require 'spec_helper'
3
3
  describe Ibge::Reader::MicroRegion do
4
4
  subject { described_class }
5
5
 
6
+ let(:columns) do
7
+ {
8
+ dtb: {
9
+ "0": :state_code,
10
+ "2": :meso_region_code,
11
+ "4": :code,
12
+ "5": :name
13
+ }
14
+ }
15
+ end
16
+
6
17
  it 'should have defined columns' do
7
- expect(subject.defined_columns).to include "0": :state_code,
8
- "2": :meso_region_code,
9
- "4": :code,
10
- "5": :name
18
+ expect(subject.defined_columns).to eq columns
11
19
  end
12
20
  end
@@ -3,12 +3,20 @@ require 'spec_helper'
3
3
  describe Ibge::Reader::Municipality do
4
4
  subject { described_class }
5
5
 
6
+ let(:columns) do
7
+ {
8
+ dtb: {
9
+ "0": :state_code,
10
+ "2": :meso_region_code,
11
+ "4": :micro_region_code,
12
+ "6": :code,
13
+ "7": :full_code,
14
+ "8": :name
15
+ }
16
+ }
17
+ end
18
+
6
19
  it 'should have defined columns' do
7
- expect(subject.defined_columns).to include "0": :state_code,
8
- "2": :meso_region_code,
9
- "4": :micro_region_code,
10
- "6": :code,
11
- "7": :full_code,
12
- "8": :name
20
+ expect(subject.defined_columns).to eq columns
13
21
  end
14
22
  end
@@ -3,7 +3,17 @@ require 'spec_helper'
3
3
  describe Ibge::Reader::Neighborhood do
4
4
  subject { described_class }
5
5
 
6
+ let(:columns) do
7
+ {
8
+ sidra: {
9
+ "0": :state_code,
10
+ "3": :municipality_full_code,
11
+ "5": :name
12
+ }
13
+ }
14
+ end
15
+
6
16
  it 'should have defined columns' do
7
- expect(subject.defined_columns).to include "0": :state_code, "3": :municipality_full_code, "5": :name
17
+ expect(subject.defined_columns).to eq columns
8
18
  end
9
19
  end
@@ -1,9 +1,28 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  describe Ibge::Reader::State do
4
4
  subject { described_class }
5
5
 
6
- it 'should have defined columns' do
7
- expect(subject.defined_columns).to include "0": :code, "1": :state_name
6
+ let(:columns) do
7
+ {
8
+ dtb: {
9
+ "0": :code,
10
+ "1": :state_name
11
+ },
12
+
13
+ sidra: {
14
+ "2": :state_federative_unit
15
+ }
16
+ }
17
+ end
18
+
19
+ it "should have defined columns" do
20
+ expect(subject.defined_columns).to eq columns
21
+ end
22
+
23
+ it "should read from multiple sources" do
24
+ expect(subject.read).to include code: "11",
25
+ state_name: "Rondônia",
26
+ state_federative_unit: "RO"
8
27
  end
9
28
  end
@@ -3,14 +3,22 @@ require 'spec_helper'
3
3
  describe Ibge::Reader::SubDistrict do
4
4
  subject { described_class }
5
5
 
6
+ let(:columns) do
7
+ {
8
+ dtb: {
9
+ "0": :state_code,
10
+ "2": :meso_region_code,
11
+ "4": :micro_region_code,
12
+ "6": :municipality_code,
13
+ "9": :district_code,
14
+ "12": :code,
15
+ "13": :full_code,
16
+ "14": :name
17
+ }
18
+ }
19
+ end
20
+
6
21
  it 'should have defined columns' do
7
- expect(subject.defined_columns).to include "0": :state_code,
8
- "2": :meso_region_code,
9
- "4": :micro_region_code,
10
- "6": :municipality_code,
11
- "9": :district_code,
12
- "12": :code,
13
- "13": :full_code,
14
- "14": :name
22
+ expect(subject.defined_columns).to include columns
15
23
  end
16
24
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ibge
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
  - Bruno Arueira
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-13 00:00:00.000000000 Z
11
+ date: 2015-08-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: spreadsheet
@@ -73,6 +73,7 @@ files:
73
73
  - lib/ibge.rb
74
74
  - lib/ibge/reader/base.rb
75
75
  - lib/ibge/reader/district.rb
76
+ - lib/ibge/reader/helpers.rb
76
77
  - lib/ibge/reader/meso_region.rb
77
78
  - lib/ibge/reader/micro_region.rb
78
79
  - lib/ibge/reader/municipality.rb