worlddb 1.8.2 → 2.0.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/{History.md → HISTORY.md} +0 -0
- data/Manifest.txt +22 -5
- data/README.md +62 -2
- data/Rakefile +14 -6
- data/lib/worlddb.rb +34 -12
- data/lib/worlddb/cli/main.rb +159 -111
- data/lib/worlddb/cli/opts.rb +15 -48
- data/lib/worlddb/console.rb +6 -5
- data/lib/worlddb/deleter.rb +5 -3
- data/lib/worlddb/matcher.rb +16 -5
- data/lib/worlddb/models/city.rb +66 -30
- data/lib/worlddb/models/city_comp.rb +27 -0
- data/lib/worlddb/models/continent.rb +30 -8
- data/lib/worlddb/models/continent_comp.rb +24 -0
- data/lib/worlddb/models/country.rb +60 -36
- data/lib/worlddb/models/country_comp.rb +29 -0
- data/lib/worlddb/models/forward.rb +53 -0
- data/lib/worlddb/models/lang.rb +9 -7
- data/lib/worlddb/models/lang_comp.rb +23 -0
- data/lib/worlddb/models/name.rb +13 -0
- data/lib/worlddb/models/place.rb +16 -0
- data/lib/worlddb/models/region.rb +34 -12
- data/lib/worlddb/models/region_comp.rb +26 -0
- data/lib/worlddb/models/tagdb/tag.rb +16 -0
- data/lib/worlddb/models/tagdb/tagging.rb +15 -0
- data/lib/worlddb/models/usage.rb +10 -6
- data/lib/worlddb/reader.rb +31 -158
- data/lib/worlddb/readers/base.rb +41 -0
- data/lib/worlddb/readers/city.rb +18 -0
- data/lib/worlddb/readers/country.rb +17 -0
- data/lib/worlddb/readers/lang.rb +43 -0
- data/lib/worlddb/readers/region.rb +17 -0
- data/lib/worlddb/readers/usage.rb +35 -0
- data/lib/worlddb/schema.rb +100 -65
- data/lib/worlddb/stats.rb +9 -3
- data/lib/worlddb/utils.rb +3 -0
- data/lib/worlddb/version.rb +1 -6
- data/test/helper.rb +13 -3
- data/test/test_model_city.rb +60 -0
- data/test/test_model_comp.rb +48 -0
- data/test/test_model_country.rb +43 -0
- data/test/test_model_region.rb +50 -0
- data/test/test_models.rb +35 -0
- metadata +113 -37
- data/lib/worlddb/models/prop.rb +0 -32
- data/lib/worlddb/models/tag.rb +0 -33
- data/lib/worlddb/models/tagging.rb +0 -13
- data/test/test_values.rb +0 -114
@@ -0,0 +1,41 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module WorldDb
|
4
|
+
|
5
|
+
|
6
|
+
class BaseReader
|
7
|
+
|
8
|
+
include LogUtils::Logging
|
9
|
+
|
10
|
+
## make models available by default with namespace
|
11
|
+
# e.g. lets you use Usage instead of Model::Usage
|
12
|
+
include Models
|
13
|
+
|
14
|
+
## value helpers e.g. is_year?, is_taglist? etc.
|
15
|
+
include TextUtils::ValueHelper
|
16
|
+
|
17
|
+
|
18
|
+
attr_reader :include_path
|
19
|
+
|
20
|
+
def skip_tags?() @skip_tags == true; end
|
21
|
+
def strict?() @strict == true; end
|
22
|
+
|
23
|
+
|
24
|
+
def initialize( include_path, opts = {} )
|
25
|
+
|
26
|
+
@include_path = include_path
|
27
|
+
|
28
|
+
## option: do NOT generate/add any tags for countries/regions/cities
|
29
|
+
@skip_tags = opts[:skip_tags].present? ? true : false
|
30
|
+
## option: for now issue warning on update, that is, if key/record (country,region,city) already exists
|
31
|
+
@strict = opts[:strict].present? ? true : false
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
def read( name, more_attribs={} )
|
36
|
+
puts "error: overwrite in concrete reader class!!!" ### overwrite!!!!
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
end # class BaseReader
|
41
|
+
end # module WorldDb
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module WorldDb
|
4
|
+
|
5
|
+
class CityReader < BaseReader
|
6
|
+
|
7
|
+
def read( name, more_attribs={} )
|
8
|
+
reader = ValuesReaderV2.new( name, include_path, more_attribs )
|
9
|
+
|
10
|
+
reader.each_line do |attribs, values|
|
11
|
+
opts = { skip_tags: skip_tags? }
|
12
|
+
City.create_or_update_from_attribs( attribs, values, opts )
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end # class CityReader
|
17
|
+
end # module WorldDb
|
18
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module WorldDb
|
4
|
+
|
5
|
+
class CountryReader < BaseReader
|
6
|
+
|
7
|
+
def read( name, more_attribs={} )
|
8
|
+
reader = ValuesReaderV2.new( name, include_path, more_attribs )
|
9
|
+
|
10
|
+
reader.each_line do |attribs, values|
|
11
|
+
opts = { skip_tags: skip_tags? }
|
12
|
+
Country.create_or_update_from_attribs( attribs, values, opts )
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end # class CountryReader
|
17
|
+
end # module WorldDb
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module WorldDb
|
4
|
+
|
5
|
+
class LangReader < BaseReader
|
6
|
+
|
7
|
+
def read( name )
|
8
|
+
reader = HashReaderV2.new( name, include_path )
|
9
|
+
|
10
|
+
reader.each do |key, value|
|
11
|
+
|
12
|
+
### fix:
|
13
|
+
## move to Lang.read() for (re)use
|
14
|
+
|
15
|
+
logger.debug "adding lang >>#{key}<< >>#{value}<<..."
|
16
|
+
|
17
|
+
lang_key = key.strip
|
18
|
+
lang_title = value.strip
|
19
|
+
|
20
|
+
lang_attribs = {}
|
21
|
+
|
22
|
+
## check if it exists
|
23
|
+
lang = Lang.find_by_key( lang_key )
|
24
|
+
if lang.present?
|
25
|
+
logger.debug "update lang #{lang.id}-#{lang.key}:"
|
26
|
+
else
|
27
|
+
logger.debug "create lang:"
|
28
|
+
lang = Lang.new
|
29
|
+
lang_attribs[ :key ] = lang_key
|
30
|
+
end
|
31
|
+
|
32
|
+
lang_attribs[ :title ] = lang_title
|
33
|
+
|
34
|
+
logger.debug lang_attribs.to_json
|
35
|
+
|
36
|
+
lang.update_attributes!( lang_attribs )
|
37
|
+
end # each key,value
|
38
|
+
|
39
|
+
end # method load_langs
|
40
|
+
|
41
|
+
|
42
|
+
end # class LangReader
|
43
|
+
end # module WorldDb
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module WorldDb
|
4
|
+
|
5
|
+
class RegionReader < BaseReader
|
6
|
+
|
7
|
+
def read( name, more_attribs={} )
|
8
|
+
reader = ValuesReaderV2.new( name, include_path, more_attribs )
|
9
|
+
|
10
|
+
reader.each_line do |attribs, values|
|
11
|
+
opts = { skip_tags: skip_tags? }
|
12
|
+
Region.create_or_update_from_attribs( attribs, values, opts )
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end # class RegionReader
|
17
|
+
end # module WorldDb
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module WorldDb
|
4
|
+
|
5
|
+
class UsageReader < BaseReader
|
6
|
+
|
7
|
+
def read( name )
|
8
|
+
reader = HashReaderV2.new( name, include_path )
|
9
|
+
|
10
|
+
reader.each do |key, value|
|
11
|
+
|
12
|
+
### fix:
|
13
|
+
## move to Usage.read() for (re)use
|
14
|
+
|
15
|
+
logger.debug " adding langs >>#{value}<<to country >>#{key}<<"
|
16
|
+
|
17
|
+
country = Country.find_by_key!( key )
|
18
|
+
|
19
|
+
lang_keys = value.split(',')
|
20
|
+
lang_keys.each do |lang_key|
|
21
|
+
|
22
|
+
### remove (optional comment) from key (e.g. carribean (islands))
|
23
|
+
lang_key = lang_key.gsub( /\(.+\)/, '' )
|
24
|
+
## remove leading n trailing space
|
25
|
+
lang_key = lang_key.strip
|
26
|
+
|
27
|
+
lang = Lang.find_by_key!( lang_key )
|
28
|
+
Usage.create!( country_id: country.id, lang_id: lang.id, official: true, minor: false )
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
end # class UsageReader
|
35
|
+
end # module WorldDb
|
data/lib/worlddb/schema.rb
CHANGED
@@ -5,33 +5,90 @@ class CreateDb < ActiveRecord::Migration
|
|
5
5
|
|
6
6
|
def up
|
7
7
|
|
8
|
+
|
9
|
+
create_table :places do |t|
|
10
|
+
t.string :name, null: false
|
11
|
+
t.string :kind, null: false # -- kind/feature (note: type reserved for activerecord sti)
|
12
|
+
#####
|
13
|
+
# continent:
|
14
|
+
# CONT - continent (use CNTI or CENT why??)
|
15
|
+
# country:
|
16
|
+
# SUPR - supra (e.g. European Union)
|
17
|
+
# CNTY - country
|
18
|
+
# TERR - terr
|
19
|
+
# region:
|
20
|
+
# ADM1 - e.g. region/state/province
|
21
|
+
# ADM2 - e.g. county/district/
|
22
|
+
# ADM3 - e.g.
|
23
|
+
# city:
|
24
|
+
# MTRO - metro
|
25
|
+
# CITY - city/town/
|
26
|
+
# DIST - district/
|
27
|
+
#
|
28
|
+
# add new table for zones (e.g. informal regions e.g. tourism, wine regions, etc.) ??
|
29
|
+
# why? why not??
|
30
|
+
|
31
|
+
|
32
|
+
t.float :lat # optional for now (latitude)
|
33
|
+
t.float :lng # optional for now (longitude)
|
34
|
+
|
35
|
+
## todo: add parent for hierachy ?? or keep it in country/region/city etc. table ??
|
36
|
+
|
37
|
+
## timestamp at last
|
38
|
+
t.timestamps
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
#############
|
43
|
+
# todo: use many-to-many assoc w/ join table for name and place ???
|
44
|
+
# why? why not?
|
45
|
+
# - wien -> city n region n metro ? collect more samples of names used more than once
|
46
|
+
|
47
|
+
### alternative names for places
|
48
|
+
create_table :names do |t|
|
49
|
+
t.string :name, null: false
|
50
|
+
t.references :place, null: false
|
51
|
+
### todo/fix: add lang_id to reference lang from lang table!!! (for now make it a duplicate; e.g. keep stirng lang for now)
|
52
|
+
t.string :lang, null: false, default: 'en' # default to english for now (or use unknown/undeterminded/unspecified???)
|
53
|
+
|
54
|
+
## todo: add kind/type ? e.g. postal for postal code ??
|
55
|
+
## or wikipedia for wikipedia? or use separate table ?? (linkable/links) etc.??
|
56
|
+
|
57
|
+
## timestamp at last
|
58
|
+
t.timestamps
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
|
8
63
|
create_table :continents do |t|
|
9
|
-
t.string
|
10
|
-
t.string
|
11
|
-
t.
|
64
|
+
t.string :name, null: false
|
65
|
+
t.string :key, null: false
|
66
|
+
t.references :place, null: false
|
67
|
+
t.string :alt_names # comma separated list of alternate names (synonyms)
|
12
68
|
|
13
69
|
## timestamp at last
|
14
70
|
t.timestamps
|
15
71
|
end
|
16
72
|
|
17
|
-
add_index :continents, :key,
|
73
|
+
add_index :continents, :key, unique: true
|
18
74
|
|
19
75
|
|
20
76
|
create_table :countries do |t|
|
21
|
-
t.string
|
22
|
-
t.string
|
23
|
-
t.
|
24
|
-
t.string
|
25
|
-
t.
|
26
|
-
t.integer
|
77
|
+
t.string :name, null: false
|
78
|
+
t.string :key, null: false
|
79
|
+
t.references :place, null: false
|
80
|
+
t.string :code, null: false # short three letter code (FIFA country code e.g. ITA)
|
81
|
+
t.string :alt_names # comma separated list of alternate names (synonyms)
|
82
|
+
t.integer :pop, null: false # population count
|
83
|
+
t.integer :area, null: false # area in square km (sq. km)
|
27
84
|
t.references :continent
|
28
85
|
t.references :country # for supra(nationals) n depend(encies)
|
29
|
-
|
86
|
+
|
30
87
|
## flags (use single int named flags - why? why not?
|
31
|
-
t.boolean :s, :
|
32
|
-
t.boolean :c, :
|
33
|
-
t.boolean :d, :
|
34
|
-
|
88
|
+
t.boolean :s, null: false, default: false # supra(national) flag e.g. eu
|
89
|
+
t.boolean :c, null: false, default: false # country flag (is this needed?)
|
90
|
+
t.boolean :d, null: false, default: false # dependency flag
|
91
|
+
|
35
92
|
# extras
|
36
93
|
t.string :motor # optional auto motor (vehicle) licene plate
|
37
94
|
t.string :iso2 # optional iso two letter country code
|
@@ -45,8 +102,8 @@ create_table :countries do |t|
|
|
45
102
|
end
|
46
103
|
|
47
104
|
|
48
|
-
add_index :countries, :key, :
|
49
|
-
add_index :countries, :code, :
|
105
|
+
add_index :countries, :key, unique: true
|
106
|
+
add_index :countries, :code, unique: true
|
50
107
|
|
51
108
|
|
52
109
|
######
|
@@ -54,88 +111,66 @@ add_index :countries, :code, :unique => true
|
|
54
111
|
#
|
55
112
|
# used for state/provice/land/regioni/etc.
|
56
113
|
create_table :regions do |t|
|
57
|
-
t.string
|
58
|
-
t.string
|
114
|
+
t.string :name, null: false
|
115
|
+
t.string :key, null: false
|
116
|
+
t.references :place, null: false
|
59
117
|
t.string :code # short two or three letter code e.g. NY, OAX, etc.
|
60
118
|
t.string :abbr # optional conventional abbrevation (e.g. Stmk., Gto., etc.)
|
61
119
|
t.string :iso # iso code
|
62
120
|
t.string :nuts # nuts code (europe/eu only)
|
63
|
-
t.string
|
64
|
-
t.references :country,
|
121
|
+
t.string :alt_names # comma separated list of alternate names (synonyms)
|
122
|
+
t.references :country, null: false
|
65
123
|
t.integer :pop # optional population count
|
66
124
|
t.integer :area # optional area in square km (sq. km)
|
67
125
|
t.timestamps
|
68
126
|
end
|
69
127
|
|
70
|
-
add_index :regions, [:key, :country_id], :
|
128
|
+
add_index :regions, [:key, :country_id], unique: true
|
71
129
|
|
72
130
|
|
73
131
|
create_table :cities do |t|
|
74
|
-
t.string
|
75
|
-
t.string
|
76
|
-
t.
|
77
|
-
t.string
|
78
|
-
t.
|
132
|
+
t.string :name, null: false
|
133
|
+
t.string :key, null: false
|
134
|
+
t.references :place, null: false
|
135
|
+
t.string :code # short three letter code (ITAT/airport code e.g. NYC or VIE)
|
136
|
+
t.string :alt_names # comma separated list of alternate names (synonyms)
|
137
|
+
t.references :country, null: false
|
79
138
|
t.references :region # optional for now
|
80
139
|
t.references :city # optional parent (e.g. metro for city, or city for district)
|
81
140
|
t.integer :pop # optional population count (city proper)
|
82
141
|
t.integer :popm # optional population count (metropolitan/aglomeration)
|
83
142
|
t.integer :area # optional area in square km (sq. km)
|
84
|
-
|
85
|
-
t.float :
|
143
|
+
|
144
|
+
## t.float :lat # optional for now -- FIX: remove?? moved to places
|
145
|
+
## t.float :lng # optional for now -- FIX: remove?? moved to places
|
86
146
|
|
87
147
|
## flags (use single int named flags - why? why not?
|
88
|
-
t.boolean :m, :
|
89
|
-
t.boolean :c, :
|
90
|
-
t.boolean :d, :
|
148
|
+
t.boolean :m, null: false, default: false # metro flag
|
149
|
+
t.boolean :c, null: false, default: false # city flag (is this needed?)
|
150
|
+
t.boolean :d, null: false, default: false # district flag
|
91
151
|
|
92
|
-
### t.boolean :capital, :
|
93
|
-
|
94
|
-
t.timestamps
|
95
|
-
end
|
152
|
+
### t.boolean :capital, null: false, default: false # is national captial?
|
96
153
|
|
97
|
-
create_table :tags do |t|
|
98
|
-
t.string :key, :null => false
|
99
|
-
t.string :slug, :null => false
|
100
|
-
t.string :title # todo: make required?
|
101
|
-
t.integer :grade, :null => false, :default => 1 # grade/tier e.g. 1/2/3 for now
|
102
|
-
## todo: add parent or similar for hierachy (for tag stacks/packs)
|
103
154
|
t.timestamps
|
104
155
|
end
|
105
156
|
|
106
|
-
add_index :tags, :key, :unique => true
|
107
|
-
|
108
|
-
create_table :taggings do |t|
|
109
|
-
t.references :tag, :null => false
|
110
|
-
t.references :taggable, :polymorphic => true
|
111
|
-
t.timestamps # todo: use only t.datetime :created_at (do we get ar magic? is updated used/needed??)
|
112
|
-
end
|
113
|
-
|
114
|
-
add_index :taggings, :tag_id
|
115
|
-
add_index :taggings, [:taggable_id, :taggable_type]
|
116
|
-
|
117
157
|
|
118
158
|
create_table :langs do |t| # langs == languages (e.g. en/English, de/Deutsch, etc.)
|
119
|
-
t.string :key, :
|
120
|
-
t.string :
|
159
|
+
t.string :key, null: false
|
160
|
+
t.string :name, null: false
|
121
161
|
t.timestamps
|
122
162
|
end
|
123
163
|
|
164
|
+
|
124
165
|
create_table :usages do |t| # join table for countries_langs
|
125
|
-
t.references :country, :
|
126
|
-
t.references :lang, :
|
127
|
-
t.boolean :official, :
|
128
|
-
t.boolean :minor, :
|
166
|
+
t.references :country, null: false
|
167
|
+
t.references :lang, null: false
|
168
|
+
t.boolean :official, null: false, default: true # is_official language in country
|
169
|
+
t.boolean :minor, null: false, default: false # spoken by minority
|
129
170
|
t.float :percent # usage in percent e.g. 90.0, 0.55, etc.
|
130
171
|
t.timestamps
|
131
172
|
end
|
132
173
|
|
133
|
-
### fix: move to PropDb ? into props gem? why? why not?
|
134
|
-
create_table :props do |t|
|
135
|
-
t.string :key, :null => false
|
136
|
-
t.string :value, :null => false
|
137
|
-
t.timestamps
|
138
|
-
end
|
139
174
|
|
140
175
|
end # method up
|
141
176
|
|
data/lib/worlddb/stats.rb
CHANGED
@@ -13,12 +13,18 @@ module WorldDb
|
|
13
13
|
puts " #{'%5d' % City.where(m: true).where(c: false).count} metros"
|
14
14
|
puts " #{'%5d' % City.where(c: true).count} cities (#{City.where(c: true).where(m: true).count} metros)"
|
15
15
|
puts " #{'%5d' % City.where(d: true).count} districts"
|
16
|
-
puts " #{'%5d' % Tag.count} tags"
|
17
|
-
puts " #{'%5d' % Tagging.count} taggings"
|
16
|
+
# puts " #{'%5d' % Tag.count} tags"
|
17
|
+
# puts " #{'%5d' % Tagging.count} taggings"
|
18
|
+
puts " #{'%5d' % Place.count} places"
|
19
|
+
puts " #{'%5d' % Name.count} names"
|
18
20
|
puts " #{'%5d' % Lang.count} langs"
|
19
21
|
puts " #{'%5d' % Usage.count} usages"
|
20
22
|
end
|
21
|
-
|
23
|
+
|
24
|
+
|
25
|
+
#
|
26
|
+
# fix: move to ConfDb for (re)use !!!!!
|
27
|
+
|
22
28
|
def props
|
23
29
|
puts "Props:"
|
24
30
|
Prop.order( 'created_at asc' ).all.each do |prop|
|
data/lib/worlddb/utils.rb
CHANGED
data/lib/worlddb/version.rb
CHANGED