zipcode-fr 0.1.0
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 +7 -0
- data/lib/zipcode-fr.rb +103 -0
- 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: []
|