worlddb 2.0.9 → 2.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 +4 -4
- data/HISTORY.md +1 -1
- data/Manifest.txt +1 -38
- data/README.md +0 -67
- data/Rakefile +7 -11
- data/lib/worlddb.rb +8 -187
- data/lib/worlddb/cli/main.rb +3 -8
- data/lib/worlddb/{version.rb → cli/version.rb} +9 -7
- data/lib/worlddb/console.rb +5 -10
- metadata +10 -110
- data/.gemtest +0 -0
- data/lib/worlddb/deleter.rb +0 -32
- data/lib/worlddb/matcher.rb +0 -143
- data/lib/worlddb/models/city.rb +0 -240
- data/lib/worlddb/models/city_comp.rb +0 -27
- data/lib/worlddb/models/continent.rb +0 -41
- data/lib/worlddb/models/continent_comp.rb +0 -24
- data/lib/worlddb/models/country.rb +0 -328
- data/lib/worlddb/models/country_code.rb +0 -41
- data/lib/worlddb/models/country_comp.rb +0 -35
- data/lib/worlddb/models/forward.rb +0 -57
- data/lib/worlddb/models/lang.rb +0 -18
- data/lib/worlddb/models/lang_comp.rb +0 -23
- data/lib/worlddb/models/name.rb +0 -13
- data/lib/worlddb/models/place.rb +0 -16
- data/lib/worlddb/models/region.rb +0 -176
- data/lib/worlddb/models/region_comp.rb +0 -26
- data/lib/worlddb/models/tagdb/tag.rb +0 -16
- data/lib/worlddb/models/tagdb/tagging.rb +0 -15
- data/lib/worlddb/models/usage.rb +0 -17
- data/lib/worlddb/patterns.rb +0 -54
- data/lib/worlddb/reader.rb +0 -224
- data/lib/worlddb/reader_file.rb +0 -86
- data/lib/worlddb/reader_zip.rb +0 -160
- data/lib/worlddb/readers/city.rb +0 -81
- data/lib/worlddb/readers/country.rb +0 -78
- data/lib/worlddb/readers/lang.rb +0 -107
- data/lib/worlddb/readers/region.rb +0 -79
- data/lib/worlddb/readers/usage.rb +0 -98
- data/lib/worlddb/schema.rb +0 -202
- data/lib/worlddb/stats.rb +0 -31
- data/test/helper.rb +0 -29
- data/test/test_fixture_matchers.rb +0 -112
- data/test/test_model_city.rb +0 -60
- data/test/test_model_comp.rb +0 -48
- data/test/test_model_country.rb +0 -53
- data/test/test_model_region.rb +0 -50
- data/test/test_models.rb +0 -35
data/lib/worlddb/console.rb
CHANGED
@@ -1,15 +1,10 @@
|
|
1
|
-
|
2
|
-
## e.g. irb -r worlddb/console
|
1
|
+
# encoding: utf-8
|
3
2
|
|
4
|
-
require 'worlddb'
|
5
3
|
|
6
|
-
|
4
|
+
## for use to run with interactive ruby (irb)
|
5
|
+
## e.g. irb -r worlddb/console
|
7
6
|
|
8
|
-
require '
|
9
|
-
require 'pp' # pretty printer
|
10
|
-
require 'uri'
|
11
|
-
require 'json'
|
12
|
-
require 'yaml'
|
7
|
+
require 'worlddb/models'
|
13
8
|
|
14
9
|
|
15
10
|
## shortcuts for models
|
@@ -28,7 +23,7 @@ City = WorldDb::Model::City
|
|
28
23
|
|
29
24
|
DB_CONFIG = {
|
30
25
|
adapter: 'sqlite3',
|
31
|
-
database: 'world.db'
|
26
|
+
database: './world.db'
|
32
27
|
}
|
33
28
|
|
34
29
|
pp DB_CONFIG
|
metadata
CHANGED
@@ -1,101 +1,45 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: worlddb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gerald Bauer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-12-
|
11
|
+
date: 2014-12-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: worlddb-models
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
20
|
-
type: :runtime
|
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: logutils
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :runtime
|
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: textutils
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: 0.9.9
|
19
|
+
version: 2.1.0
|
48
20
|
type: :runtime
|
49
21
|
prerelease: false
|
50
22
|
version_requirements: !ruby/object:Gem::Requirement
|
51
23
|
requirements:
|
52
24
|
- - ">="
|
53
25
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: tagutils
|
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'
|
26
|
+
version: 2.1.0
|
69
27
|
- !ruby/object:Gem::Dependency
|
70
28
|
name: gli
|
71
29
|
requirement: !ruby/object:Gem::Requirement
|
72
30
|
requirements:
|
73
31
|
- - ">="
|
74
32
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
33
|
+
version: 2.12.2
|
76
34
|
type: :runtime
|
77
35
|
prerelease: false
|
78
36
|
version_requirements: !ruby/object:Gem::Requirement
|
79
37
|
requirements:
|
80
38
|
- - ">="
|
81
39
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: rubyzip
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - ">="
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
90
|
-
type: :runtime
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - ">="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
40
|
+
version: 2.12.2
|
97
41
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
42
|
+
name: sqlite3
|
99
43
|
requirement: !ruby/object:Gem::Requirement
|
100
44
|
requirements:
|
101
45
|
- - ">="
|
@@ -146,7 +90,6 @@ extra_rdoc_files:
|
|
146
90
|
- Manifest.txt
|
147
91
|
- README.md
|
148
92
|
files:
|
149
|
-
- ".gemtest"
|
150
93
|
- HISTORY.md
|
151
94
|
- Manifest.txt
|
152
95
|
- README.md
|
@@ -155,45 +98,8 @@ files:
|
|
155
98
|
- lib/worlddb.rb
|
156
99
|
- lib/worlddb/cli/main.rb
|
157
100
|
- lib/worlddb/cli/opts.rb
|
101
|
+
- lib/worlddb/cli/version.rb
|
158
102
|
- lib/worlddb/console.rb
|
159
|
-
- lib/worlddb/deleter.rb
|
160
|
-
- lib/worlddb/matcher.rb
|
161
|
-
- lib/worlddb/models/city.rb
|
162
|
-
- lib/worlddb/models/city_comp.rb
|
163
|
-
- lib/worlddb/models/continent.rb
|
164
|
-
- lib/worlddb/models/continent_comp.rb
|
165
|
-
- lib/worlddb/models/country.rb
|
166
|
-
- lib/worlddb/models/country_code.rb
|
167
|
-
- lib/worlddb/models/country_comp.rb
|
168
|
-
- lib/worlddb/models/forward.rb
|
169
|
-
- lib/worlddb/models/lang.rb
|
170
|
-
- lib/worlddb/models/lang_comp.rb
|
171
|
-
- lib/worlddb/models/name.rb
|
172
|
-
- lib/worlddb/models/place.rb
|
173
|
-
- lib/worlddb/models/region.rb
|
174
|
-
- lib/worlddb/models/region_comp.rb
|
175
|
-
- lib/worlddb/models/tagdb/tag.rb
|
176
|
-
- lib/worlddb/models/tagdb/tagging.rb
|
177
|
-
- lib/worlddb/models/usage.rb
|
178
|
-
- lib/worlddb/patterns.rb
|
179
|
-
- lib/worlddb/reader.rb
|
180
|
-
- lib/worlddb/reader_file.rb
|
181
|
-
- lib/worlddb/reader_zip.rb
|
182
|
-
- lib/worlddb/readers/city.rb
|
183
|
-
- lib/worlddb/readers/country.rb
|
184
|
-
- lib/worlddb/readers/lang.rb
|
185
|
-
- lib/worlddb/readers/region.rb
|
186
|
-
- lib/worlddb/readers/usage.rb
|
187
|
-
- lib/worlddb/schema.rb
|
188
|
-
- lib/worlddb/stats.rb
|
189
|
-
- lib/worlddb/version.rb
|
190
|
-
- test/helper.rb
|
191
|
-
- test/test_fixture_matchers.rb
|
192
|
-
- test/test_model_city.rb
|
193
|
-
- test/test_model_comp.rb
|
194
|
-
- test/test_model_country.rb
|
195
|
-
- test/test_model_region.rb
|
196
|
-
- test/test_models.rb
|
197
103
|
homepage: https://github.com/worlddb/world.db.ruby
|
198
104
|
licenses:
|
199
105
|
- Public Domain
|
@@ -220,10 +126,4 @@ rubygems_version: 2.4.2
|
|
220
126
|
signing_key:
|
221
127
|
specification_version: 4
|
222
128
|
summary: worlddb - world.db command line tool
|
223
|
-
test_files:
|
224
|
-
- test/test_model_comp.rb
|
225
|
-
- test/test_models.rb
|
226
|
-
- test/test_model_city.rb
|
227
|
-
- test/test_fixture_matchers.rb
|
228
|
-
- test/test_model_country.rb
|
229
|
-
- test/test_model_region.rb
|
129
|
+
test_files: []
|
data/.gemtest
DELETED
File without changes
|
data/lib/worlddb/deleter.rb
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module WorldDb
|
4
|
-
|
5
|
-
class Deleter
|
6
|
-
|
7
|
-
## make models available in worlddb module by default with namespace
|
8
|
-
# e.g. lets you use City instead of Models::City
|
9
|
-
include WorldDb::Models
|
10
|
-
|
11
|
-
def run
|
12
|
-
# for now delete all tables
|
13
|
-
|
14
|
-
## Tagging.delete_all # - use TagDb.delete!
|
15
|
-
## Tag.delete_all
|
16
|
-
|
17
|
-
CountryCode.delete_all
|
18
|
-
Name.delete_all
|
19
|
-
Place.delete_all
|
20
|
-
City.delete_all
|
21
|
-
Region.delete_all
|
22
|
-
Country.delete_all
|
23
|
-
Continent.delete_all
|
24
|
-
Usage.delete_all
|
25
|
-
Lang.delete_all
|
26
|
-
|
27
|
-
# Prop.delete_all # - use ConfDb.delete!
|
28
|
-
end
|
29
|
-
|
30
|
-
end # class Deleter
|
31
|
-
|
32
|
-
end # module WorldDb
|
data/lib/worlddb/matcher.rb
DELETED
@@ -1,143 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
module WorldDb
|
4
|
-
|
5
|
-
module Matcher
|
6
|
-
|
7
|
-
def match_xxx_for_country( name, xxx ) # xxx e.g. cities|regions|beers|breweries
|
8
|
-
# auto-add required country code (from folder structure)
|
9
|
-
# note: always let match_xxx_for_country_n_region go first
|
10
|
-
|
11
|
-
# note: allow /cities and /1--hokkaido--cities
|
12
|
-
xxx_pattern = "(?:#{xxx}|[0-9]+--[^\\/]+?--#{xxx})" # note: double escape \\ required for backslash
|
13
|
-
|
14
|
-
##
|
15
|
-
## todo: add $-anchor at the end of pattern - why? why not?? (will include .txt or .yaml??)
|
16
|
-
|
17
|
-
if name =~ /(?:^|\/)([a-z]{2,3})-[^\/]+\/#{xxx_pattern}/ || # (1)
|
18
|
-
name =~ /(?:^|\/)[0-9]+--([a-z]{2,3})-[^\/]+\/#{xxx_pattern}/ || # (2)
|
19
|
-
name =~ /(?:^|\/)([a-z]{2,3})\/#{xxx_pattern}/ || # (3)
|
20
|
-
name =~ /(?:^|\/)([a-z]{2,3})-[^\/]+\/[0-9]+--[^\/]+\/#{xxx_pattern}/ || # (4)
|
21
|
-
name =~ /(?:^|\/)([a-z]{2,3})-[^\/]+--#{xxx}/ # (5)
|
22
|
-
|
23
|
-
country_key = $1.dup
|
24
|
-
yield( country_key )
|
25
|
-
true # bingo - match found
|
26
|
-
|
27
|
-
######
|
28
|
-
# (1) new style: e.g. /at-austria/beers or ^at-austria!/cities
|
29
|
-
#
|
30
|
-
# (2) new-new style e.g. /1--at-austria--central/cities
|
31
|
-
#
|
32
|
-
# (3) classic style: e.g. /at/beers (europe/at/cities)
|
33
|
-
#
|
34
|
-
# (4) new style w/ region w/o abbrev/code e.g. /ja-japon/1--hokkaido/cities
|
35
|
-
#
|
36
|
-
# (5) compact style (country part of filename):
|
37
|
-
# e.g. /at-austria--cities or /europe/at-austria--cities
|
38
|
-
else
|
39
|
-
false # no match found
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
|
44
|
-
def match_xxx_for_country_n_region( name, xxx ) # xxx e.g. wine|wineries
|
45
|
-
|
46
|
-
# auto-add required country n region code (from folder structure)
|
47
|
-
|
48
|
-
## -- allow opt_folders after long regions (e.g. additional subregion/zone)
|
49
|
-
## -- allow anything (prefixes) before -- for xxx
|
50
|
-
# e.g. at-austria!/1--n-niederoesterreich--eastern/wagram--wines
|
51
|
-
# at-austria!/1--n-niederoesterreich--eastern/wagram--wagram--wines
|
52
|
-
|
53
|
-
# note: allow /cities and /1--hokkaido--cities and /hokkaido--cities too
|
54
|
-
xxx_pattern = "(?:#{xxx}|[^\\/]+--#{xxx})" # note: double escape \\ required for backslash
|
55
|
-
|
56
|
-
## allow optional folders -- TODO: add restriction ?? e.g. must be 4+ alphas ???
|
57
|
-
opt_folders_pattern = "(?:\/[^\/]+)*"
|
58
|
-
## note: for now only (style #2) n (style #3) that is long region allow opt folders
|
59
|
-
|
60
|
-
if name =~ /(?:^|\/)([a-z]{2,3})-[^\/]+\/([a-z]{1,3})-[^\/]+\/#{xxx_pattern}/ || # (1)
|
61
|
-
name =~ /(?:^|\/)[0-9]+--([a-z]{2,3})-[^\/]+\/[0-9]+--([a-z]{1,3})-[^\/]+#{opt_folders_pattern}\/#{xxx_pattern}/ || # (2)
|
62
|
-
name =~ /(?:^|\/)([a-z]{2,3})-[^\/]+\/[0-9]+--([a-z]{1,3})-[^\/]+#{opt_folders_pattern}\/#{xxx_pattern}/ || # (3)
|
63
|
-
name =~ /(?:^|\/)[0-9]+--([a-z]{2,3})-[^\/]+\/([a-z]{1,3})-[^\/]+\/#{xxx_pattern}/ # (4)
|
64
|
-
|
65
|
-
#######
|
66
|
-
# nb: country must start name (^) or coming after / e.g. europe/at-austria/...
|
67
|
-
# (1)
|
68
|
-
# new style: e.g. /at-austria/w-wien/cities or
|
69
|
-
# ^at-austria!/w-wien/cities
|
70
|
-
# (2)
|
71
|
-
# new new style e.g. /1--at-austria--central/1--w-wien--eastern/cities
|
72
|
-
#
|
73
|
-
# (3)
|
74
|
-
# new new mixed style e.g. /at-austria/1--w-wien--eastern/cities
|
75
|
-
# "classic" country plus new new region
|
76
|
-
#
|
77
|
-
# (4)
|
78
|
-
# new new mixed style e.g. /1--at-austria--central/w-wien/cities
|
79
|
-
# new new country plus "classic" region
|
80
|
-
|
81
|
-
country_key = $1.dup
|
82
|
-
region_key = $2.dup
|
83
|
-
yield( country_key, region_key )
|
84
|
-
true # bingo - match found
|
85
|
-
else
|
86
|
-
false # no match found
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
|
91
|
-
def match_cities_for_country( name, &blk )
|
92
|
-
## todo: check if there's a better (more ruby way) to pass along code block ??
|
93
|
-
## e.g. try
|
94
|
-
## match_xxx_for_country( name, 'cities') { |country_key| yield(country_key) }
|
95
|
-
|
96
|
-
match_xxx_for_country( name, 'cities', &blk )
|
97
|
-
end
|
98
|
-
|
99
|
-
def match_regions_for_country( name, &blk )
|
100
|
-
## also try synonyms e.g. old regions (if not match for states)
|
101
|
-
found = match_xxx_for_country( name, 'states', &blk )
|
102
|
-
found = match_xxx_for_country( name, 'regions', &blk ) unless found
|
103
|
-
found
|
104
|
-
end
|
105
|
-
|
106
|
-
def match_regions_abbr_for_country( name, &blk ) # NB: . gets escaped for regex, that is, \.
|
107
|
-
## also try synonyms e.g. old regions (if not match for states)
|
108
|
-
found = match_xxx_for_country( name, 'states\.abbr', &blk )
|
109
|
-
found = match_xxx_for_country( name, 'regions\.abbr', &blk ) unless found
|
110
|
-
found
|
111
|
-
end
|
112
|
-
|
113
|
-
def match_regions_iso_for_country( name, &blk ) # NB: . gets escaped for regex, that is, \.
|
114
|
-
## also try synonyms e.g. old regions (if not match for states)
|
115
|
-
found = match_xxx_for_country( name, 'states\.iso', &blk )
|
116
|
-
found = match_xxx_for_country( name, 'regions\.iso', &blk ) unless found
|
117
|
-
found
|
118
|
-
end
|
119
|
-
|
120
|
-
def match_regions_nuts_for_country( name, &blk ) # NB: . gets escaped for regex, that is, \.
|
121
|
-
## also try synonyms e.g. old regions (if not match for states)
|
122
|
-
found = match_xxx_for_country( name, 'states\.nuts', &blk )
|
123
|
-
found = match_xxx_for_country( name, 'regions\.nuts', &blk ) unless found
|
124
|
-
found
|
125
|
-
end
|
126
|
-
|
127
|
-
|
128
|
-
def match_countries_for_continent( name )
|
129
|
-
if name =~ /^([a-z][a-z\-_]+[a-z])\/countries/ # e.g. africa/countries or america/countries
|
130
|
-
### NB: continent changed to regions (e.g. middle-east, caribbean, north-america, etc.)
|
131
|
-
## auto-add continent (from folder structure) as tag
|
132
|
-
## fix: allow dash/hyphen/minus in tag
|
133
|
-
continent = $1.dup
|
134
|
-
yield( continent )
|
135
|
-
true
|
136
|
-
else
|
137
|
-
false # no match found
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
end # module Matcher
|
142
|
-
|
143
|
-
end # module WorldDb
|
data/lib/worlddb/models/city.rb
DELETED
@@ -1,240 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module WorldDb
|
4
|
-
module Model
|
5
|
-
|
6
|
-
###
|
7
|
-
## Todo:
|
8
|
-
## use four classes instead of one ?
|
9
|
-
# e.g. Use class class Metro n class City n class District n class CityBase ?? - why? why not?
|
10
|
-
#
|
11
|
-
# find a better name for CityBase ??
|
12
|
-
# Locality ??
|
13
|
-
# or CityCore or CityStd or CityAll or CityGeneric
|
14
|
-
# or CityLike or CityTable or CityTbl or ???
|
15
|
-
|
16
|
-
class City < ActiveRecord::Base
|
17
|
-
|
18
|
-
extend TextUtils::TagHelper # will add self.find_tags, self.find_tags_in_attribs!, etc.
|
19
|
-
|
20
|
-
# NB: use extend - is_<type>? become class methods e.g. self.is_<type>? for use in
|
21
|
-
# self.create_or_update_from_values
|
22
|
-
extend TextUtils::ValueHelper # e.g. self.is_year?, self.is_region?, self.is_address?, self.is_taglist? etc.
|
23
|
-
|
24
|
-
|
25
|
-
self.table_name = 'cities'
|
26
|
-
|
27
|
-
belongs_to :place, class_name: 'Place', foreign_key: 'place_id'
|
28
|
-
belongs_to :country, class_name: 'Country', foreign_key: 'country_id'
|
29
|
-
belongs_to :region, class_name: 'Region', foreign_key: 'region_id'
|
30
|
-
|
31
|
-
## self referencing hierachy within cities e.g. m|metro > c|city > d|district
|
32
|
-
|
33
|
-
## fix: use condition check for m|d|c flag?? why? why not? (NB: flags are NOT exclusive e.g. possible metro|city)
|
34
|
-
|
35
|
-
## (1) metro - level up
|
36
|
-
has_many :cities, class_name: 'City', foreign_key: 'city_id'
|
37
|
-
|
38
|
-
## (2) city
|
39
|
-
belongs_to :metro, class_name: 'City', foreign_key: 'city_id' ## for now alias for parent - use parent?
|
40
|
-
has_many :districts, class_name: 'City', foreign_key: 'city_id' ## for now alias for cities - use cities?
|
41
|
-
|
42
|
-
## (3) district - level down
|
43
|
-
belongs_to :city, class_name: 'City', foreign_key: 'city_id' ## for now alias for parent - use parent?
|
44
|
-
|
45
|
-
has_many_tags
|
46
|
-
|
47
|
-
###
|
48
|
-
# NB: use is_ for flags to avoid conflict w/ assocs (e.g. metro?, city? etc.)
|
49
|
-
|
50
|
-
def is_metro?() m? == true; end
|
51
|
-
def is_city?() c? == true; end
|
52
|
-
def is_district?() d? == true; end
|
53
|
-
|
54
|
-
before_create :on_create
|
55
|
-
before_update :on_update
|
56
|
-
|
57
|
-
def on_create
|
58
|
-
place_rec = Place.create!( name: name, kind: place_kind )
|
59
|
-
self.place_id = place_rec.id
|
60
|
-
end
|
61
|
-
|
62
|
-
def on_update
|
63
|
-
## fix/todo: check - if name or kind changed - only update if changed ?? why? why not??
|
64
|
-
place.update_attributes!( name: name, kind: place_kind )
|
65
|
-
end
|
66
|
-
|
67
|
-
def place_kind # use place_kind_of_code ??
|
68
|
-
### fix/todo: make sure city records won't overlap (e.g. using metro n city flag at the same time; use separate records)
|
69
|
-
#//////////////////////////////////
|
70
|
-
#// fix: add nested record syntax e.g. city w/ metro population
|
71
|
-
#// use (metro: 4444) e.g. must start with (<nested_type>: props) !!! or similar
|
72
|
-
#//
|
73
|
-
if is_metro?
|
74
|
-
'MTRO'
|
75
|
-
elsif is_district?
|
76
|
-
'DIST'
|
77
|
-
else
|
78
|
-
'CITY'
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
|
83
|
-
validates :key, format: { with: /#{CITY_KEY_PATTERN}/, message: CITY_KEY_PATTERN_MESSAGE }
|
84
|
-
validates :code, format: { with: /#{CITY_CODE_PATTERN}/, message: CITY_CODE_PATTERN_MESSAGE }, allow_nil: true
|
85
|
-
|
86
|
-
|
87
|
-
scope :by_key, ->{ order( 'key asc' ) } # order by key (a-z)
|
88
|
-
scope :by_name, ->{ order( 'name asc' ) } # order by title (a-z)
|
89
|
-
scope :by_pop, ->{ order( 'pop desc' ) } # order by pop(ulation)
|
90
|
-
scope :by_popm, ->{ order( 'popm desc' ) } # order by pop(ulation) metropolitan area
|
91
|
-
scope :by_area, ->{ order( 'area desc' ) } # order by area (in square km)
|
92
|
-
|
93
|
-
|
94
|
-
def all_names( opts={} )
|
95
|
-
### fix:
|
96
|
-
## allow to passing in sep or separator e.g. | or other
|
97
|
-
|
98
|
-
return name if alt_names.blank?
|
99
|
-
|
100
|
-
buf = ''
|
101
|
-
buf << name
|
102
|
-
buf << ' | '
|
103
|
-
buf << alt_names.split('|').join(' | ')
|
104
|
-
buf
|
105
|
-
end
|
106
|
-
|
107
|
-
|
108
|
-
def self.create_or_update_from_values( values, more_attribs={} )
|
109
|
-
## key & title & country required
|
110
|
-
|
111
|
-
attribs, more_values = find_key_n_title( values )
|
112
|
-
attribs = attribs.merge( more_attribs )
|
113
|
-
|
114
|
-
## check for optional values
|
115
|
-
City.create_or_update_from_attribs( attribs, more_values )
|
116
|
-
end
|
117
|
-
|
118
|
-
|
119
|
-
def self.create_or_update_from_titles( titles, more_attribs = {} )
|
120
|
-
# ary of titles e.g. ['Wien', 'Graz'] etc.
|
121
|
-
|
122
|
-
titles.each do |title|
|
123
|
-
values = [title]
|
124
|
-
City.create_or_update_from_values( values, more_attribs )
|
125
|
-
end # each city
|
126
|
-
end # method create_or_update_from_titles
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
def self.create_or_update_from_attribs( new_attributes, values, opts={} )
|
131
|
-
# attribs -> key/value pairs e.g. hash
|
132
|
-
# values -> ary of string values/strings (key not yet known; might be starting of value e.g. city:wien)
|
133
|
-
|
134
|
-
## opts e.g. :skip_tags true|false
|
135
|
-
|
136
|
-
## fix: add/configure logger for ActiveRecord!!!
|
137
|
-
logger = LogKernel::Logger.root
|
138
|
-
|
139
|
-
value_numbers = []
|
140
|
-
value_tag_keys = []
|
141
|
-
|
142
|
-
### check for "default" tags - that is, if present new_attributes[:tags] remove from hash
|
143
|
-
value_tag_keys += find_tags_in_attribs!( new_attributes )
|
144
|
-
|
145
|
-
new_attributes[ :c ] = true # assume city type by default (use metro,district to change in fixture)
|
146
|
-
|
147
|
-
## check for optional values
|
148
|
-
|
149
|
-
values.each_with_index do |value,index|
|
150
|
-
if match_region_for_country( value, new_attributes[:country_id] ) do |region|
|
151
|
-
new_attributes[ :region_id ] = region.id
|
152
|
-
end
|
153
|
-
elsif match_country( value ) do |country|
|
154
|
-
new_attributes[ :country_id ] = country.id
|
155
|
-
end
|
156
|
-
elsif match_metro( value ) do |city|
|
157
|
-
new_attributes[ :city_id ] = city.id
|
158
|
-
end
|
159
|
-
elsif match_metro_pop( value ) do |num| # m:
|
160
|
-
new_attributes[ :popm ] = num
|
161
|
-
new_attributes[ :m ] = true # auto-mark city as m|metro too
|
162
|
-
end
|
163
|
-
elsif match_metro_flag( value ) do |_| # metro(politan area)
|
164
|
-
new_attributes[ :c ] = false # turn off default c|city flag; make it m|metro only
|
165
|
-
new_attributes[ :m ] = true
|
166
|
-
end
|
167
|
-
elsif match_city( value ) do |city| # parent city for district
|
168
|
-
new_attributes[ :city_id ] = city.id
|
169
|
-
new_attributes[ :c ] = false # turn off default c|city flag; make it d|district only
|
170
|
-
new_attributes[ :d ] = true
|
171
|
-
end
|
172
|
-
elsif match_km_squared( value ) do |num| # allow numbers like 453 km²
|
173
|
-
value_numbers << num
|
174
|
-
end
|
175
|
-
elsif match_number( value ) do |num| # numeric (nb: can use any _ or spaces inside digits e.g. 1_000_000 or 1 000 000)
|
176
|
-
value_numbers << num
|
177
|
-
end
|
178
|
-
elsif value =~ /#{CITY_CODE_PATTERN}/ ## assume three-letter code
|
179
|
-
new_attributes[ :code ] = value
|
180
|
-
elsif (values.size==(index+1)) && is_taglist?( value ) # tags must be last entry
|
181
|
-
logger.debug " found tags: >>#{value}<<"
|
182
|
-
value_tag_keys += find_tags( value )
|
183
|
-
else
|
184
|
-
# issue warning: unknown type for value
|
185
|
-
logger.warn "unknown type for value >#{value}<"
|
186
|
-
end
|
187
|
-
end # each value
|
188
|
-
|
189
|
-
if value_numbers.size > 0
|
190
|
-
new_attributes[ :pop ] = value_numbers[0] # assume first number is pop for cities
|
191
|
-
new_attributes[ :area ] = value_numbers[1]
|
192
|
-
end
|
193
|
-
|
194
|
-
rec = City.find_by_key( new_attributes[ :key ] )
|
195
|
-
|
196
|
-
if rec.present?
|
197
|
-
logger.debug "update City #{rec.id}-#{rec.key}:"
|
198
|
-
else
|
199
|
-
logger.debug "create City:"
|
200
|
-
rec = City.new
|
201
|
-
end
|
202
|
-
|
203
|
-
logger.debug new_attributes.to_json
|
204
|
-
|
205
|
-
rec.update_attributes!( new_attributes )
|
206
|
-
|
207
|
-
##################
|
208
|
-
## add taggings
|
209
|
-
|
210
|
-
## todo/fix: reuse - move add taggings into method etc.
|
211
|
-
|
212
|
-
if value_tag_keys.size > 0
|
213
|
-
|
214
|
-
if opts[:skip_tags].present?
|
215
|
-
logger.debug " skipping add taggings (flag skip_tag)"
|
216
|
-
else
|
217
|
-
value_tag_keys.uniq! # remove duplicates
|
218
|
-
logger.debug " adding #{value_tag_keys.size} taggings: >>#{value_tag_keys.join('|')}<<..."
|
219
|
-
|
220
|
-
### fix/todo: check tag_ids and only update diff (add/remove ids)
|
221
|
-
|
222
|
-
value_tag_keys.each do |key|
|
223
|
-
tag = Tag.find_by_key( key )
|
224
|
-
if tag.nil? # create tag if it doesn't exit
|
225
|
-
logger.debug " creating tag >#{key}<"
|
226
|
-
tag = Tag.create!( key: key )
|
227
|
-
end
|
228
|
-
rec.tags << tag
|
229
|
-
end
|
230
|
-
end
|
231
|
-
end
|
232
|
-
|
233
|
-
rec
|
234
|
-
end # method create_or_update_from_values
|
235
|
-
|
236
|
-
|
237
|
-
end # class Cities
|
238
|
-
|
239
|
-
end # module Model
|
240
|
-
end # module WorldDb
|