worlddb 2.0.9 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|