zipcode-fr 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/zipcode-fr.rb +103 -0
  3. metadata +72 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 49ba8c551db2a645e35f59f485073ea85ec78c43
4
+ data.tar.gz: b4079b54250461c4b1d6a2c9b1a6b2724d7ace87
5
+ SHA512:
6
+ metadata.gz: e39eef729b7634e97b4441af2abe6e70314bc078603fe295ecab2380672dee6c8f06dfb125c7dee72d8305d7ae8c43aa0cef8b61c32570c5f0c48a26d0d0a3f5
7
+ data.tar.gz: 616c5eb703167666cbae11c086bf3534fbb4ea258ee9352852588a9aab658a0a7eeb2256d200427e336f307ae99dd162cff9ed2284110d0e8426ab8ea5dd8d57
data/lib/zipcode-fr.rb ADDED
@@ -0,0 +1,103 @@
1
+ module ZipCode
2
+ module FR
3
+ require 'csv'
4
+
5
+ module_function
6
+
7
+ @indexes ||= {}
8
+
9
+ def load
10
+ # TODO: non-optimal, but not overly long either
11
+ index!(:name, reader)
12
+ index!(:zip, reader)
13
+ @loaded = true
14
+ end
15
+
16
+ def ready?
17
+ @loaded
18
+ end
19
+
20
+ private def data_source
21
+ path = 'vendor/data/code_postaux_v201410.csv'
22
+ File.expand_path(File.join(File.dirname(__FILE__), '..', path))
23
+ end
24
+
25
+ private def reader_options
26
+ {
27
+ col_sep: ';',
28
+ encoding: 'ISO-8859-1',
29
+ }
30
+ end
31
+
32
+ private def open
33
+ CSV.open(data_source, 'rb', reader_options) do |csv|
34
+ csv.take(1) # skip header manually to preserve tell()
35
+ yield csv
36
+ end
37
+ end
38
+
39
+ private def reader
40
+ Enumerator.new do |y|
41
+ open do |io|
42
+ pos = io.tell
43
+ io.each { |row| y << [pos, clean(row)]; pos = io.tell }
44
+ end
45
+ end
46
+ end
47
+
48
+ private def clean(row)
49
+ row_to_h(row_clean(row))
50
+ end
51
+
52
+ private def row_clean(row)
53
+ row.map { |e| e.strip.encode('UTF-8') }
54
+ end
55
+
56
+ private def row_to_h(row)
57
+ [:insee, :name, :zip, :alt_name].zip(row).to_h
58
+ end
59
+
60
+ def index!(name, data, key = nil)
61
+ key ||= name
62
+ index = Hash.new { |h, k| h[k] = [] unless h.frozen? }
63
+
64
+ data.each do |pos, record|
65
+ val = record[key]
66
+ val.length.times { |i| index[val[0..i].hash] << pos }
67
+ end
68
+
69
+ index.freeze
70
+
71
+ @indexes[name] = index
72
+ end
73
+
74
+ private def index(name)
75
+ if @indexes.key?(name)
76
+ @indexes[name]
77
+ else
78
+ fail "no index named #{name.inspect}"
79
+ end
80
+ end
81
+
82
+ private def read_at(*positions, count: 1)
83
+ Enumerator.new do |y|
84
+ open do |io|
85
+ positions.each do |pos|
86
+ io.seek(pos)
87
+ io.take(count).each { |row| y << clean(row) }
88
+ end
89
+ end
90
+ end
91
+ end
92
+
93
+ def search(name, str, case_insensitive: true)
94
+ str = str.upcase if case_insensitive
95
+ read_at(*index(name)[str.hash])
96
+ end
97
+
98
+ def complete(name, str, key = nil)
99
+ key ||= name
100
+ search(name, str).map { |e| e[key] }
101
+ end
102
+ end
103
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: zipcode-fr
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Loic Nageleisen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-07-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: pry
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: rubocop
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
+ description: Query french zip codes and cities
42
+ email: loic.nageleisen@gmail.com
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files: []
46
+ files:
47
+ - lib/zipcode-fr.rb
48
+ homepage: https://github.com/lloeki/zipcode-fr
49
+ licenses:
50
+ - MIT
51
+ metadata: {}
52
+ post_install_message:
53
+ rdoc_options: []
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ requirements: []
67
+ rubyforge_project:
68
+ rubygems_version: 2.4.5
69
+ signing_key:
70
+ specification_version: 4
71
+ summary: Query french zip codes and cities
72
+ test_files: []