fias_reader 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +7 -0
- data/README.md +65 -0
- data/Rakefile +9 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/fias_reader.gemspec +35 -0
- data/lib/fias_reader.rb +41 -0
- data/lib/fias_reader/cache.rb +38 -0
- data/lib/fias_reader/cache/address_part.rb +118 -0
- data/lib/fias_reader/cache/address_part/level_adapter.rb +137 -0
- data/lib/fias_reader/cache/guid.rb +70 -0
- data/lib/fias_reader/parse_logic.rb +48 -0
- data/lib/fias_reader/parse_logic/abstract.rb +6 -0
- data/lib/fias_reader/parse_logic/attributes.rb +12 -0
- data/lib/fias_reader/parse_logic/attributes_select.rb +12 -0
- data/lib/fias_reader/parse_logic/depth.rb +22 -0
- data/lib/fias_reader/parse_logic/logger.rb +27 -0
- data/lib/fias_reader/parse_logic/rows.rb +28 -0
- data/lib/fias_reader/parse_logic/stub.rb +22 -0
- data/lib/fias_reader/parser.rb +10 -0
- data/lib/fias_reader/reader.rb +35 -0
- data/lib/fias_reader/reader/row.rb +80 -0
- data/lib/fias_reader/scope.rb +48 -0
- data/lib/fias_reader/table.rb +28 -0
- data/lib/fias_reader/table/address_part.rb +7 -0
- data/lib/fias_reader/table/house.rb +7 -0
- data/lib/fias_reader/version.rb +3 -0
- data/lib/tasks/build.rake +11 -0
- metadata +245 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0487bfee5053fa367df10d23d433effe5c1cbf9b
|
4
|
+
data.tar.gz: c221923b51e134a479fad411d742111196bfbc30
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1c760dc5c617ac874ba55a2e0e4d64307dbb1eb6afd73ee2c3fd1046eb3abf8b504a098eed0fb8dccf9666a917d5fd44479bc15cbdfbd9a735d29de8b126bcf3
|
7
|
+
data.tar.gz: c1dcd52754c78df2c6f1c7aa7674831a16cff3b3d84afe21faff3bd47d315b38cef3ddd52b12830bbedb00f0f1ff6b49aee74bf44ffb8782541feba32e5743c0
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
# FiasReader
|
2
|
+
|
3
|
+
Библиотека для работы с XML базой ФИАС. Библиотека позволяет провести обход по всем активным записям домов.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Добваить строку в Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'fias_reader', path: '/path_to_dir/fias_reader'
|
11
|
+
```
|
12
|
+
|
13
|
+
И выполнить после:
|
14
|
+
|
15
|
+
```
|
16
|
+
$ bundle
|
17
|
+
```
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
Перед запуском лучше исполнить rake для построения индекса:
|
22
|
+
|
23
|
+
```
|
24
|
+
rake fias_reader:build DB_PATH=/path/to/dir
|
25
|
+
```
|
26
|
+
|
27
|
+
если запускать без него то индекс построится в процессе выполнения.
|
28
|
+
|
29
|
+
Для просотого обхода по всем записям домов нужно вызвать итератор следующим способом:
|
30
|
+
|
31
|
+
``` ruby
|
32
|
+
FiasReader.open('/path/to/unpacked/fais/xml/dir/').each do |row|
|
33
|
+
# somecode here
|
34
|
+
end
|
35
|
+
```
|
36
|
+
|
37
|
+
Итератор передает аргумент типа `FiasReader::Reader::Row`, который имеет методы:
|
38
|
+
* `postal_code` - почтовый индекс
|
39
|
+
* `house_number` - номер дома
|
40
|
+
* `house_building_number` - номер корпуса, опционально
|
41
|
+
* `house_structure_number` - номер строения, опционально
|
42
|
+
* `levels` - хеш всех уровни частей адреса
|
43
|
+
* Части адреса возращаются либо масивом из двух объектов(сокращенное название типа части адреса, название части адреса). В случае если часть адреса не указана возвращаем nil.
|
44
|
+
* `street` - улица
|
45
|
+
* `settlement` - населенный пункт
|
46
|
+
* `city_district` - внутригородская территория
|
47
|
+
* `city` - город
|
48
|
+
* `district` - район
|
49
|
+
* `autonomy` - автономный округ
|
50
|
+
* `state` - регион
|
51
|
+
|
52
|
+
|
53
|
+
После выполнения работы нужно удалить индекс:
|
54
|
+
|
55
|
+
```
|
56
|
+
rake fias_reader:clear
|
57
|
+
```
|
58
|
+
|
59
|
+
## Development
|
60
|
+
|
61
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
62
|
+
|
63
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
64
|
+
|
65
|
+
## Contributing
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'fias_reader'
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require 'irb'
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
data/fias_reader.gemspec
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'fias_reader/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'fias_reader'
|
8
|
+
spec.version = FiasReader::VERSION
|
9
|
+
spec.authors = ["Андрей Большов", "uno4ki"]
|
10
|
+
spec.email = ['asnow.dev@gmail.ru', 'i.have@no.mail']
|
11
|
+
|
12
|
+
spec.summary = 'FIAS reader'
|
13
|
+
spec.description = 'FIAS reader'
|
14
|
+
spec.homepage = 'http://www.thefurnish.ru/'
|
15
|
+
spec.license = 'MIT'
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = 'exe'
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ['lib']
|
21
|
+
|
22
|
+
spec.add_dependency 'ox', '~> 2.4'
|
23
|
+
spec.add_dependency 'activesupport', '~> 4.2'
|
24
|
+
spec.add_dependency 'data_mapper', '~>1.2'
|
25
|
+
spec.add_dependency 'dm-sqlite-adapter', '~>1.2'
|
26
|
+
spec.add_dependency 'sqlite3', '~>1.3'
|
27
|
+
|
28
|
+
spec.add_development_dependency 'bundler', '~> 1.11'
|
29
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
30
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
31
|
+
spec.add_development_dependency 'pry'
|
32
|
+
spec.add_development_dependency 'ruby-prof'
|
33
|
+
spec.add_development_dependency 'pry-byebug'
|
34
|
+
spec.add_development_dependency 'pry-stack_explorer'
|
35
|
+
end
|
data/lib/fias_reader.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'fias_reader/version'
|
2
|
+
|
3
|
+
require 'date'
|
4
|
+
require 'sqlite3'
|
5
|
+
require 'ox'
|
6
|
+
require 'data_mapper'
|
7
|
+
require 'dm-migrations'
|
8
|
+
require 'dm-types'
|
9
|
+
begin
|
10
|
+
require 'pry'
|
11
|
+
rescue
|
12
|
+
nil
|
13
|
+
end
|
14
|
+
require 'active_support/all'
|
15
|
+
require 'fias_reader/parse_logic/abstract'
|
16
|
+
require 'fias_reader/parse_logic/attributes'
|
17
|
+
require 'fias_reader/parse_logic/attributes_select'
|
18
|
+
require 'fias_reader/parse_logic/depth'
|
19
|
+
require 'fias_reader/parse_logic/logger'
|
20
|
+
require 'fias_reader/parse_logic/rows'
|
21
|
+
require 'fias_reader/parse_logic/stub'
|
22
|
+
require 'fias_reader/parse_logic'
|
23
|
+
require 'fias_reader/parser'
|
24
|
+
require 'fias_reader/scope'
|
25
|
+
require 'fias_reader/cache'
|
26
|
+
require 'fias_reader/cache/guid'
|
27
|
+
require 'fias_reader/cache/address_part/level_adapter'
|
28
|
+
require 'fias_reader/cache/address_part'
|
29
|
+
require 'fias_reader/table'
|
30
|
+
require 'fias_reader/table/house'
|
31
|
+
require 'fias_reader/table/address_part'
|
32
|
+
|
33
|
+
require 'fias_reader/reader/row'
|
34
|
+
require 'fias_reader/reader'
|
35
|
+
|
36
|
+
module FiasReader
|
37
|
+
# Создаем инстанс ФИАС базы. Параметр путь до файлов базы
|
38
|
+
def self.open(path)
|
39
|
+
FiasReader::Reader.new path
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module FiasReader
|
2
|
+
module Cache
|
3
|
+
FILE = '/tmp/fias_reader_cache.db'.freeze
|
4
|
+
|
5
|
+
def init(reader)
|
6
|
+
reindex = true unless File.exist?(FILE)
|
7
|
+
|
8
|
+
DataMapper.setup(:default, "sqlite://#{FILE}")
|
9
|
+
begin
|
10
|
+
DataMapper.auto_upgrade!
|
11
|
+
rescue
|
12
|
+
nil
|
13
|
+
end
|
14
|
+
adapter = DataMapper.repository(:default).adapter
|
15
|
+
adapter.execute('PRAGMA journal_mode=OFF; PRAGMA synchronous=OFF; PRAGMA locking_mode = EXCLUSIVE; PRAGMA count_changes = OFF; PRAGMA cache_size=500000; PRAGMA temp_store = MEMORY; PRAGMA auto_vacuum = NONE;')
|
16
|
+
index_build(reader) if reindex
|
17
|
+
end
|
18
|
+
|
19
|
+
def clear
|
20
|
+
File.delete(FILE)
|
21
|
+
end
|
22
|
+
|
23
|
+
def index_build(reader)
|
24
|
+
adapter = DataMapper.repository(:default).adapter
|
25
|
+
adapter.execute('BEGIN;')
|
26
|
+
puts "Индексируем части адресов..."
|
27
|
+
FiasReader::Cache::AddressPart.index reader
|
28
|
+
puts "Индексируем уровни адресов..."
|
29
|
+
adapter.execute('CREATE INDEX `aolevel_index` ON `fias_reader_cache_address_parts` (`aolevel` );')
|
30
|
+
puts "Индексируем структуру частеи адресов..."
|
31
|
+
FiasReader::Cache::AddressPart.index_levels
|
32
|
+
puts "Индексирование закончено..."
|
33
|
+
adapter.execute('COMMIT;')
|
34
|
+
end
|
35
|
+
|
36
|
+
module_function :init, :clear, :index_build
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module FiasReader
|
2
|
+
module Cache
|
3
|
+
class AddressPart
|
4
|
+
include DataMapper::Resource
|
5
|
+
ZERO_STR = '0'.freeze
|
6
|
+
|
7
|
+
# property :AOGUID, String
|
8
|
+
property :id0, Integer, key: true
|
9
|
+
property :id1, Integer, key: true
|
10
|
+
property :id2, Integer, key: true
|
11
|
+
property :id3, Integer, key: true
|
12
|
+
property :SHORTNAME, String, length: 10
|
13
|
+
property :OFFNAME, String, length: 120
|
14
|
+
property :levels_filled, Boolean
|
15
|
+
property :shortname_l1, String, length: 10
|
16
|
+
property :offname_l1, String, length: 120
|
17
|
+
property :shortname_l2, String, length: 10
|
18
|
+
property :offname_l2, String, length: 120
|
19
|
+
property :shortname_l3, String, length: 10
|
20
|
+
property :offname_l3, String, length: 120
|
21
|
+
property :shortname_l4, String, length: 10
|
22
|
+
property :offname_l4, String, length: 120
|
23
|
+
property :shortname_l5, String, length: 10
|
24
|
+
property :offname_l5, String, length: 120
|
25
|
+
property :shortname_l6, String, length: 10
|
26
|
+
property :offname_l6, String, length: 120
|
27
|
+
property :shortname_l7, String, length: 10
|
28
|
+
property :offname_l7, String, length: 120
|
29
|
+
property :shortname_l8, String, length: 10
|
30
|
+
property :offname_l8, String, length: 120
|
31
|
+
property :shortname_l9, String, length: 10
|
32
|
+
property :offname_l9, String, length: 120
|
33
|
+
property :shortname_l65, String, length: 10
|
34
|
+
property :offname_l65, String, length: 120
|
35
|
+
property :shortname_l75, String, length: 10
|
36
|
+
property :offname_l75, String, length: 120
|
37
|
+
property :shortname_l90, String, length: 10
|
38
|
+
property :offname_l90, String, length: 120
|
39
|
+
property :shortname_l91, String, length: 10
|
40
|
+
property :offname_l91, String, length: 120
|
41
|
+
property :AOLEVEL, Integer
|
42
|
+
# property :PARENTGUID, String
|
43
|
+
property :parent0, Integer
|
44
|
+
property :parent1, Integer
|
45
|
+
property :parent2, Integer
|
46
|
+
property :parent3, Integer
|
47
|
+
|
48
|
+
require 'ruby-prof'
|
49
|
+
|
50
|
+
def self.index(reader)
|
51
|
+
attrs = properties.map(&:name)
|
52
|
+
FiasReader::Table::AddressPart.new(reader).query.all do |row|
|
53
|
+
next if row[:LIVESTATUS] == ZERO_STR
|
54
|
+
begin
|
55
|
+
params = FiasReader::Cache::Guid.new(row[:AOGUID]).to_attr(:id)
|
56
|
+
params.merge! FiasReader::Cache::Guid.new(row[:PARENTGUID]).to_attr(:parent)
|
57
|
+
params[:SHORTNAME] = row[:SHORTNAME]
|
58
|
+
params[:OFFNAME] = row[:OFFNAME]
|
59
|
+
params[:AOLEVEL] = row[:AOLEVEL]
|
60
|
+
create params
|
61
|
+
rescue DataObjects::IntegrityError => e
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.index_levels
|
67
|
+
puts "Части 4..."
|
68
|
+
index_levels_batch '4'
|
69
|
+
puts "Части 6..."
|
70
|
+
index_levels_batch '6'
|
71
|
+
puts "Части 7..."
|
72
|
+
index_levels_batch '7'
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.index_levels_batch(level)
|
76
|
+
start = -1
|
77
|
+
i = 0
|
78
|
+
|
79
|
+
while start != i
|
80
|
+
start = i
|
81
|
+
all(offset: i, limit: 1000, AOLEVEL: level).each do |item|
|
82
|
+
i += 1
|
83
|
+
puts Time.new if (i % 10_000).zero?
|
84
|
+
item.parent_string
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def levels
|
90
|
+
@levels ||= FiasReader::Cache::AddressPart::LevelAdapter.new(self)
|
91
|
+
end
|
92
|
+
|
93
|
+
def parent_string
|
94
|
+
return levels if levels_filled
|
95
|
+
|
96
|
+
if parent0.nil?
|
97
|
+
levels.reset_own
|
98
|
+
else
|
99
|
+
# some bug with parent DataObjects::SyntaxError, so using first
|
100
|
+
parent_item = FiasReader::Cache::AddressPart.first(id0: parent0, id1: parent1, id2: parent2, id3: parent3)
|
101
|
+
|
102
|
+
if parent_item
|
103
|
+
levels.copy(parent_item.parent_string)
|
104
|
+
else
|
105
|
+
levels.reset_own
|
106
|
+
end
|
107
|
+
save
|
108
|
+
end
|
109
|
+
|
110
|
+
levels
|
111
|
+
end
|
112
|
+
|
113
|
+
belongs_to :parent, 'AddressPart',
|
114
|
+
parent_key: [:id0, :id1, :id2, :id3],
|
115
|
+
child_key: [:parent0, :parent1, :parent2, :parent3]
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
module FiasReader
|
2
|
+
module Cache
|
3
|
+
class AddressPart
|
4
|
+
class LevelAdapter
|
5
|
+
module AddressObjectLevel
|
6
|
+
STREET = '7'.freeze
|
7
|
+
SETTLEMENT = '6'.freeze
|
8
|
+
CITY_DISTRICT = '5'.freeze
|
9
|
+
CITY = '4'.freeze
|
10
|
+
STATE_DISTRICT = '3'.freeze
|
11
|
+
AUTONOMY = '2'.freeze
|
12
|
+
STATE = '1'.freeze
|
13
|
+
# 90 – уровень дополнительных территорий
|
14
|
+
# 91 – уровень подчиненных дополнительным территориям объектов
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_reader :item
|
18
|
+
|
19
|
+
def initialize(item)
|
20
|
+
@item = item
|
21
|
+
end
|
22
|
+
|
23
|
+
def copy(other)
|
24
|
+
@item.shortname_l1 = other.item.shortname_l1
|
25
|
+
@item.offname_l1 = other.item.offname_l1
|
26
|
+
@item.shortname_l2 = other.item.shortname_l2
|
27
|
+
@item.offname_l2 = other.item.offname_l2
|
28
|
+
@item.shortname_l3 = other.item.shortname_l3
|
29
|
+
@item.offname_l3 = other.item.offname_l3
|
30
|
+
@item.shortname_l4 = other.item.shortname_l4
|
31
|
+
@item.offname_l4 = other.item.offname_l4
|
32
|
+
@item.shortname_l5 = other.item.shortname_l5
|
33
|
+
@item.offname_l5 = other.item.offname_l5
|
34
|
+
@item.shortname_l6 = other.item.shortname_l6
|
35
|
+
@item.offname_l6 = other.item.offname_l6
|
36
|
+
@item.shortname_l7 = other.item.shortname_l7
|
37
|
+
@item.offname_l7 = other.item.offname_l7
|
38
|
+
@item.shortname_l8 = other.item.shortname_l8
|
39
|
+
@item.offname_l8 = other.item.offname_l8
|
40
|
+
@item.shortname_l9 = other.item.shortname_l9
|
41
|
+
@item.offname_l9 = other.item.offname_l9
|
42
|
+
@item.shortname_l65 = other.item.shortname_l65
|
43
|
+
@item.offname_l65 = other.item.offname_l65
|
44
|
+
@item.shortname_l75 = other.item.shortname_l75
|
45
|
+
@item.offname_l75 = other.item.offname_l75
|
46
|
+
@item.shortname_l90 = other.item.shortname_l90
|
47
|
+
@item.offname_l90 = other.item.offname_l90
|
48
|
+
@item.shortname_l91 = other.item.shortname_l91
|
49
|
+
@item.offname_l91 = other.item.offname_l91
|
50
|
+
reset_own
|
51
|
+
end
|
52
|
+
|
53
|
+
def reset_own
|
54
|
+
case @item[:AOLEVEL]
|
55
|
+
when 1
|
56
|
+
@item.shortname_l1 = @item[:SHORTNAME]
|
57
|
+
@item.offname_l1 = @item[:OFFNAME]
|
58
|
+
when 2
|
59
|
+
@item.shortname_l2 = @item[:SHORTNAME]
|
60
|
+
@item.offname_l2 = @item[:OFFNAME]
|
61
|
+
when 3
|
62
|
+
@item.shortname_l3 = @item[:SHORTNAME]
|
63
|
+
@item.offname_l3 = @item[:OFFNAME]
|
64
|
+
when 4
|
65
|
+
@item.shortname_l4 = @item[:SHORTNAME]
|
66
|
+
@item.offname_l4 = @item[:OFFNAME]
|
67
|
+
when 5
|
68
|
+
@item.shortname_l5 = @item[:SHORTNAME]
|
69
|
+
@item.offname_l5 = @item[:OFFNAME]
|
70
|
+
when 6
|
71
|
+
@item.shortname_l6 = @item[:SHORTNAME]
|
72
|
+
@item.offname_l6 = @item[:OFFNAME]
|
73
|
+
when 7
|
74
|
+
@item.shortname_l7 = @item[:SHORTNAME]
|
75
|
+
@item.offname_l7 = @item[:OFFNAME]
|
76
|
+
when 8
|
77
|
+
@item.shortname_l8 = @item[:SHORTNAME]
|
78
|
+
@item.offname_l8 = @item[:OFFNAME]
|
79
|
+
when 9
|
80
|
+
@item.shortname_l9 = @item[:SHORTNAME]
|
81
|
+
@item.offname_l9 = @item[:OFFNAME]
|
82
|
+
when 65
|
83
|
+
@item.shortname_l65 = @item[:SHORTNAME]
|
84
|
+
@item.offname_l65 = @item[:OFFNAME]
|
85
|
+
when 75
|
86
|
+
@item.shortname_l75 = @item[:SHORTNAME]
|
87
|
+
@item.offname_l75 = @item[:OFFNAME]
|
88
|
+
when 90
|
89
|
+
@item.shortname_l90 = @item[:SHORTNAME]
|
90
|
+
@item.offname_l90 = @item[:OFFNAME]
|
91
|
+
when 91
|
92
|
+
@item.shortname_l91 = @item[:SHORTNAME]
|
93
|
+
@item.offname_l91 = @item[:OFFNAME]
|
94
|
+
else
|
95
|
+
raise 'errors'
|
96
|
+
end
|
97
|
+
@item.levels_filled = true
|
98
|
+
end
|
99
|
+
|
100
|
+
# Возвращает улицу
|
101
|
+
def street
|
102
|
+
[@item.shortname_l7, @item.offname_l7]
|
103
|
+
end
|
104
|
+
|
105
|
+
# Возвращает деревню, поселок
|
106
|
+
def settlement
|
107
|
+
[@item.shortname_l6, @item.offname_l6]
|
108
|
+
end
|
109
|
+
|
110
|
+
# Возвращает внутригородской территории
|
111
|
+
def city_district
|
112
|
+
[@item.shortname_l5, @item.offname_l5]
|
113
|
+
end
|
114
|
+
|
115
|
+
# Возвращает город
|
116
|
+
def city
|
117
|
+
[@item.shortname_l4, @item.offname_l4]
|
118
|
+
end
|
119
|
+
|
120
|
+
# Возвращает район
|
121
|
+
def district
|
122
|
+
[@item.shortname_l3, @item.offname_l3]
|
123
|
+
end
|
124
|
+
|
125
|
+
# Возвращает автономный округ
|
126
|
+
def autonomy
|
127
|
+
[@item.shortname_l2, @item.offname_l2]
|
128
|
+
end
|
129
|
+
|
130
|
+
# Возвращает область
|
131
|
+
def state
|
132
|
+
[@item.shortname_l1, @item.offname_l1]
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module FiasReader
|
2
|
+
module Cache
|
3
|
+
class Guid
|
4
|
+
DASH_STR = '-'.freeze
|
5
|
+
EMPTY_STR = ''.freeze
|
6
|
+
GUID_PARTS = [
|
7
|
+
0..8,
|
8
|
+
8..16,
|
9
|
+
16..24,
|
10
|
+
24..32
|
11
|
+
].freeze
|
12
|
+
|
13
|
+
def initialize(*args)
|
14
|
+
if args.size == 1
|
15
|
+
guid = args[0]
|
16
|
+
case guid
|
17
|
+
when Hash
|
18
|
+
init_from_hash guid
|
19
|
+
when Array
|
20
|
+
init_from_array guid
|
21
|
+
else
|
22
|
+
init_from_guid guid
|
23
|
+
end
|
24
|
+
|
25
|
+
elsif args.size == 2
|
26
|
+
init_from_hash_slice args[0], args[1]
|
27
|
+
elsif args.size > 2
|
28
|
+
init_from_array args
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_attr(name)
|
33
|
+
@parts.each_with_index.each_with_object({}) do |(part, index), result|
|
34
|
+
result["#{name}#{index}"] = part
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
GUID_FORMAT_STR = '%08x'.freeze
|
39
|
+
def to_guid
|
40
|
+
@parts.each_with_object('') { |i, str| str << format(GUID_FORMAT_STR, i) }
|
41
|
+
end
|
42
|
+
|
43
|
+
def parts
|
44
|
+
@parts ||= []
|
45
|
+
end
|
46
|
+
|
47
|
+
attr_writer :parts
|
48
|
+
|
49
|
+
def init_from_array(val)
|
50
|
+
self.parts = val
|
51
|
+
end
|
52
|
+
|
53
|
+
def init_from_guid(guid)
|
54
|
+
(self.parts = []) && return unless guid
|
55
|
+
guid.tr!(DASH_STR, EMPTY_STR)
|
56
|
+
self.parts = GUID_PARTS.map { |range| guid[range].to_i(16) }
|
57
|
+
end
|
58
|
+
|
59
|
+
def init_from_hash(hash)
|
60
|
+
hash.each { |key, val| parts[key[-1].to_i] = val }
|
61
|
+
end
|
62
|
+
|
63
|
+
def init_from_hash_slice(hash, mask)
|
64
|
+
self.parts = hash.keys.select { |key| key.to_s =~ /^#{mask}\d/ }.each_with_object([]) do |key, obj|
|
65
|
+
obj[key[-1].to_i] = hash[key]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module FiasReader
|
2
|
+
module ParseLogic
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
attr_accessor :element_name, :attr_name, :attr_value, :text
|
5
|
+
|
6
|
+
def self.build(logics)
|
7
|
+
Class.new do
|
8
|
+
include FiasReader::ParseLogic::Stub
|
9
|
+
|
10
|
+
logics.reverse.each do |logic|
|
11
|
+
include logic
|
12
|
+
end
|
13
|
+
|
14
|
+
include FiasReader::ParseLogic
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
included do
|
19
|
+
# define_callbacks :initialize, :start_element, :end_element, :attr, :text
|
20
|
+
|
21
|
+
def initialize(options)
|
22
|
+
@options = options.dup.freeze
|
23
|
+
super
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def start_element(name)
|
28
|
+
@element_name = name
|
29
|
+
super
|
30
|
+
end
|
31
|
+
|
32
|
+
def end_element(name)
|
33
|
+
@element_name = name
|
34
|
+
super
|
35
|
+
end
|
36
|
+
|
37
|
+
def attr(name, value)
|
38
|
+
@attr_name = name
|
39
|
+
@attr_value = value
|
40
|
+
super
|
41
|
+
end
|
42
|
+
|
43
|
+
def text(value)
|
44
|
+
@text = value
|
45
|
+
super
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module FiasReader
|
2
|
+
module ParseLogic
|
3
|
+
module Depth
|
4
|
+
include FiasReader::ParseLogic::Abstract
|
5
|
+
|
6
|
+
def initialize(options)
|
7
|
+
@depth = 0
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
11
|
+
def start_element(name)
|
12
|
+
@depth += 1
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
def end_element(name)
|
17
|
+
@depth -= 1
|
18
|
+
super
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module FiasReader
|
2
|
+
module ParseLogic
|
3
|
+
module Logger
|
4
|
+
include FiasReader::ParseLogic::Abstract
|
5
|
+
|
6
|
+
def start_element(name)
|
7
|
+
puts "start: #{name}"
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
11
|
+
def end_element(name)
|
12
|
+
puts "end: #{name}"
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
def attr(name, value)
|
17
|
+
puts " #{name} => #{value}"
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
def text(value)
|
22
|
+
puts "text #{value}"
|
23
|
+
super
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module FiasReader
|
2
|
+
module ParseLogic
|
3
|
+
module Rows
|
4
|
+
include FiasReader::ParseLogic::Abstract
|
5
|
+
|
6
|
+
def initialize(options)
|
7
|
+
@rows_enabled = true if @options[:rows].respond_to? :call
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
11
|
+
def start_element(name)
|
12
|
+
if @rows_enabled && @depth == 2
|
13
|
+
@row = {}
|
14
|
+
@skip = false
|
15
|
+
end
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
def end_element(name)
|
20
|
+
if @rows_enabled && @depth == 1
|
21
|
+
@options[:rows].call(@row) if @row
|
22
|
+
@row = nil
|
23
|
+
end
|
24
|
+
super
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module FiasReader
|
2
|
+
module ParseLogic
|
3
|
+
module Stub
|
4
|
+
include FiasReader::ParseLogic::Abstract
|
5
|
+
|
6
|
+
def initialize(options)
|
7
|
+
end
|
8
|
+
|
9
|
+
def start_element(name)
|
10
|
+
end
|
11
|
+
|
12
|
+
def end_element(name)
|
13
|
+
end
|
14
|
+
|
15
|
+
def attr(name, value)
|
16
|
+
end
|
17
|
+
|
18
|
+
def text(value)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module FiasReader
|
2
|
+
# Инерфейс для работы XML с базой ФИАС
|
3
|
+
class Reader
|
4
|
+
attr_reader :path
|
5
|
+
def initialize(path)
|
6
|
+
@path = path
|
7
|
+
end
|
8
|
+
|
9
|
+
# Итерируем по всем активным записям домов, принимает блок в качестве аргумента
|
10
|
+
# В вызываемы блок передается объект типа FiasReader::Reader::Row.
|
11
|
+
XML_DATE_SEPARATOR = '-'.freeze
|
12
|
+
EMPTY_STRING = '0'.freeze
|
13
|
+
TODAY = Date.today.strftime('%Y0%m0%d').to_i
|
14
|
+
def each
|
15
|
+
Cache.init self
|
16
|
+
|
17
|
+
Table::House.new(self).query.all do |row|
|
18
|
+
next unless active?(row)
|
19
|
+
row = FiasReader::Reader::Row.new row
|
20
|
+
yield row if row.address_object
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def active?(row)
|
27
|
+
date_to_int(row[:ENDDATE]) >= TODAY && date_to_int(row[:STARTDATE]) < TODAY
|
28
|
+
end
|
29
|
+
|
30
|
+
def date_to_int(date)
|
31
|
+
date.tr!(XML_DATE_SEPARATOR, EMPTY_STRING)
|
32
|
+
date.to_i
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module FiasReader
|
2
|
+
class Reader
|
3
|
+
# Представление строки итерироемой Reader'ом
|
4
|
+
class Row
|
5
|
+
def initialize(house_row)
|
6
|
+
@house_row = house_row
|
7
|
+
end
|
8
|
+
|
9
|
+
# Возвращает объект части адреса к которой прикреплен дом(объект улицы)
|
10
|
+
def address_object
|
11
|
+
return @address_object unless @address_object.nil?
|
12
|
+
@address_object = FiasReader::Cache::AddressPart.first(address_object_id.to_attr(:id)) || false
|
13
|
+
end
|
14
|
+
|
15
|
+
def address_object_id
|
16
|
+
FiasReader::Cache::Guid.new(@house_row[:AOGUID])
|
17
|
+
end
|
18
|
+
|
19
|
+
# Возвращает хеш уровней частей адреса к которой прикреплен дом(объект улицы)
|
20
|
+
def levels
|
21
|
+
address_object.parent_string
|
22
|
+
end
|
23
|
+
|
24
|
+
# Возвращает номер дома
|
25
|
+
def house_number
|
26
|
+
@house_row[:HOUSENUM]
|
27
|
+
end
|
28
|
+
|
29
|
+
# Возвращает номер корпуса
|
30
|
+
def house_building_number
|
31
|
+
@house_row[:BUILDNUM]
|
32
|
+
end
|
33
|
+
|
34
|
+
# Возвращает номер строения
|
35
|
+
def house_structure_number
|
36
|
+
@house_row[:STRUCNUM]
|
37
|
+
end
|
38
|
+
|
39
|
+
# Возвращает улицу
|
40
|
+
def street
|
41
|
+
levels.street
|
42
|
+
end
|
43
|
+
|
44
|
+
# Возвращает почтовый индекс
|
45
|
+
def postal_code
|
46
|
+
@house_row[:POSTALCODE]
|
47
|
+
end
|
48
|
+
|
49
|
+
# Возвращает деревню, поселок
|
50
|
+
def settlement
|
51
|
+
levels.settlement
|
52
|
+
end
|
53
|
+
|
54
|
+
# Возвращает внутригородской территории
|
55
|
+
def city_district
|
56
|
+
levels.city_district
|
57
|
+
end
|
58
|
+
|
59
|
+
# Возвращает город
|
60
|
+
def city
|
61
|
+
levels.city
|
62
|
+
end
|
63
|
+
|
64
|
+
# Возвращает район
|
65
|
+
def district
|
66
|
+
levels.district
|
67
|
+
end
|
68
|
+
|
69
|
+
# Возвращает автономный округ
|
70
|
+
def autonomy
|
71
|
+
levels.autonomy
|
72
|
+
end
|
73
|
+
|
74
|
+
# Возвращает область
|
75
|
+
def state
|
76
|
+
levels.state
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module FiasReader
|
2
|
+
# Инерфейс для работы XML с базой ФИАС
|
3
|
+
class Scope
|
4
|
+
attr_reader :options, :logics
|
5
|
+
|
6
|
+
def initialize(table)
|
7
|
+
@table = table
|
8
|
+
@options = {}
|
9
|
+
@logics = @table.class::LOGICS.dup
|
10
|
+
end
|
11
|
+
|
12
|
+
def all
|
13
|
+
@options[:rows] = -> (row) { yield row }
|
14
|
+
parse!
|
15
|
+
end
|
16
|
+
|
17
|
+
def first
|
18
|
+
result = nil
|
19
|
+
catch :fias_parse_stop do
|
20
|
+
@options[:rows] = -> (row) do
|
21
|
+
result = row
|
22
|
+
throw :fias_parse_stop
|
23
|
+
end
|
24
|
+
parse!
|
25
|
+
end
|
26
|
+
result
|
27
|
+
end
|
28
|
+
|
29
|
+
def select(*args)
|
30
|
+
index = @logics.index(FiasReader::ParseLogic::Attributes)
|
31
|
+
@logics[index] = FiasReader::ParseLogic::AttributesSelect if index
|
32
|
+
@options[:select] = args
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
36
|
+
def parse!(parser = default_parser)
|
37
|
+
Ox.sax_parse parser, @table.file, symbolize: true
|
38
|
+
end
|
39
|
+
|
40
|
+
def default_parser
|
41
|
+
FiasReader::Parser.new(logics, @options)
|
42
|
+
end
|
43
|
+
|
44
|
+
# def logics
|
45
|
+
# @logics #+ [ParseLogic::Logger]
|
46
|
+
# end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module FiasReader
|
2
|
+
# Инерфейс для работы XML с базой ФИАС
|
3
|
+
class Table
|
4
|
+
LOGICS = [
|
5
|
+
ParseLogic::Depth,
|
6
|
+
ParseLogic::Rows,
|
7
|
+
ParseLogic::Attributes
|
8
|
+
].freeze
|
9
|
+
def initialize(reader)
|
10
|
+
@reader = reader
|
11
|
+
end
|
12
|
+
|
13
|
+
def query
|
14
|
+
FiasReader::Scope.new(self)
|
15
|
+
end
|
16
|
+
|
17
|
+
def file
|
18
|
+
File.new(file_path, 'r')
|
19
|
+
end
|
20
|
+
|
21
|
+
def file_path
|
22
|
+
Dir[
|
23
|
+
"#{@reader.path}/#{self.class::File}_*.XML",
|
24
|
+
"#{@reader.path}/#{self.class::File}_*.xml"
|
25
|
+
].first
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
namespace :fias_reader do
|
2
|
+
task :build do
|
3
|
+
raise "Вы должны указать путь к XML базе ФИАС в переменной окружения DB_PATH" unless ENV[:DB_PATH]
|
4
|
+
raise "Не верно указан путь к XML базе ФИАС в переменной окружения DB_PATH" unless File.exist? ENV[:DB_PATH]
|
5
|
+
Cache.init FiasReader.open(ENV[:DB_PATH])
|
6
|
+
end
|
7
|
+
|
8
|
+
task :clear do
|
9
|
+
Cache.clear
|
10
|
+
end
|
11
|
+
end
|
metadata
ADDED
@@ -0,0 +1,245 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fias_reader
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Андрей Большов
|
8
|
+
- uno4ki
|
9
|
+
autorequire:
|
10
|
+
bindir: exe
|
11
|
+
cert_chain: []
|
12
|
+
date: 2016-06-27 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: ox
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '2.4'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '2.4'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: activesupport
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '4.2'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '4.2'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: data_mapper
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '1.2'
|
49
|
+
type: :runtime
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '1.2'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: dm-sqlite-adapter
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '1.2'
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '1.2'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: sqlite3
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - "~>"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '1.3'
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - "~>"
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '1.3'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: bundler
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - "~>"
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '1.11'
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - "~>"
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '1.11'
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: rake
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - "~>"
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '10.0'
|
105
|
+
type: :development
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - "~>"
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '10.0'
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: rspec
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - "~>"
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '3.0'
|
119
|
+
type: :development
|
120
|
+
prerelease: false
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - "~>"
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '3.0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: pry
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
133
|
+
type: :development
|
134
|
+
prerelease: false
|
135
|
+
version_requirements: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '0'
|
140
|
+
- !ruby/object:Gem::Dependency
|
141
|
+
name: ruby-prof
|
142
|
+
requirement: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
type: :development
|
148
|
+
prerelease: false
|
149
|
+
version_requirements: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - ">="
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
154
|
+
- !ruby/object:Gem::Dependency
|
155
|
+
name: pry-byebug
|
156
|
+
requirement: !ruby/object:Gem::Requirement
|
157
|
+
requirements:
|
158
|
+
- - ">="
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: '0'
|
161
|
+
type: :development
|
162
|
+
prerelease: false
|
163
|
+
version_requirements: !ruby/object:Gem::Requirement
|
164
|
+
requirements:
|
165
|
+
- - ">="
|
166
|
+
- !ruby/object:Gem::Version
|
167
|
+
version: '0'
|
168
|
+
- !ruby/object:Gem::Dependency
|
169
|
+
name: pry-stack_explorer
|
170
|
+
requirement: !ruby/object:Gem::Requirement
|
171
|
+
requirements:
|
172
|
+
- - ">="
|
173
|
+
- !ruby/object:Gem::Version
|
174
|
+
version: '0'
|
175
|
+
type: :development
|
176
|
+
prerelease: false
|
177
|
+
version_requirements: !ruby/object:Gem::Requirement
|
178
|
+
requirements:
|
179
|
+
- - ">="
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: '0'
|
182
|
+
description: FIAS reader
|
183
|
+
email:
|
184
|
+
- asnow.dev@gmail.ru
|
185
|
+
- i.have@no.mail
|
186
|
+
executables: []
|
187
|
+
extensions: []
|
188
|
+
extra_rdoc_files: []
|
189
|
+
files:
|
190
|
+
- ".gitignore"
|
191
|
+
- ".rspec"
|
192
|
+
- ".travis.yml"
|
193
|
+
- Gemfile
|
194
|
+
- README.md
|
195
|
+
- Rakefile
|
196
|
+
- bin/console
|
197
|
+
- bin/setup
|
198
|
+
- fias_reader.gemspec
|
199
|
+
- lib/fias_reader.rb
|
200
|
+
- lib/fias_reader/cache.rb
|
201
|
+
- lib/fias_reader/cache/address_part.rb
|
202
|
+
- lib/fias_reader/cache/address_part/level_adapter.rb
|
203
|
+
- lib/fias_reader/cache/guid.rb
|
204
|
+
- lib/fias_reader/parse_logic.rb
|
205
|
+
- lib/fias_reader/parse_logic/abstract.rb
|
206
|
+
- lib/fias_reader/parse_logic/attributes.rb
|
207
|
+
- lib/fias_reader/parse_logic/attributes_select.rb
|
208
|
+
- lib/fias_reader/parse_logic/depth.rb
|
209
|
+
- lib/fias_reader/parse_logic/logger.rb
|
210
|
+
- lib/fias_reader/parse_logic/rows.rb
|
211
|
+
- lib/fias_reader/parse_logic/stub.rb
|
212
|
+
- lib/fias_reader/parser.rb
|
213
|
+
- lib/fias_reader/reader.rb
|
214
|
+
- lib/fias_reader/reader/row.rb
|
215
|
+
- lib/fias_reader/scope.rb
|
216
|
+
- lib/fias_reader/table.rb
|
217
|
+
- lib/fias_reader/table/address_part.rb
|
218
|
+
- lib/fias_reader/table/house.rb
|
219
|
+
- lib/fias_reader/version.rb
|
220
|
+
- lib/tasks/build.rake
|
221
|
+
homepage: http://www.thefurnish.ru/
|
222
|
+
licenses:
|
223
|
+
- MIT
|
224
|
+
metadata: {}
|
225
|
+
post_install_message:
|
226
|
+
rdoc_options: []
|
227
|
+
require_paths:
|
228
|
+
- lib
|
229
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
230
|
+
requirements:
|
231
|
+
- - ">="
|
232
|
+
- !ruby/object:Gem::Version
|
233
|
+
version: '0'
|
234
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
235
|
+
requirements:
|
236
|
+
- - ">="
|
237
|
+
- !ruby/object:Gem::Version
|
238
|
+
version: '0'
|
239
|
+
requirements: []
|
240
|
+
rubyforge_project:
|
241
|
+
rubygems_version: 2.6.6
|
242
|
+
signing_key:
|
243
|
+
specification_version: 4
|
244
|
+
summary: FIAS reader
|
245
|
+
test_files: []
|