worlddb 0.2.2 → 0.3.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.
Files changed (84) hide show
  1. data/Manifest.txt +43 -32
  2. data/db/africa/countries.txt +10 -0
  3. data/db/america/br/cities.txt +7 -0
  4. data/db/america/br/regions.txt +27 -0
  5. data/db/america/ca/cities.txt +7 -0
  6. data/db/america/ca/regions.txt +10 -0
  7. data/db/america/countries.motor.yml +25 -0
  8. data/db/america/countries.txt +34 -0
  9. data/db/america/mx/cities.txt +15 -0
  10. data/db/america/us/cities.txt +16 -0
  11. data/db/america/us/regions.txt +10 -0
  12. data/db/america/ve/cities.txt +358 -0
  13. data/db/america/ve/regions.txt +46 -0
  14. data/db/asia/countries.txt +14 -0
  15. data/db/asia/jp/{cities.rb → cities.txt} +0 -0
  16. data/db/europe/at/cities.txt +32 -0
  17. data/db/europe/at/regions.txt +17 -0
  18. data/db/europe/be/cities.txt +1 -0
  19. data/db/europe/by/cities.txt +1 -0
  20. data/db/europe/ch/cities.txt +1 -0
  21. data/db/europe/countries.txt +65 -0
  22. data/db/europe/cy/cities.txt +1 -0
  23. data/db/europe/de/cities.txt +18 -0
  24. data/db/europe/de/regions.txt +16 -0
  25. data/db/europe/dk/cities.txt +1 -0
  26. data/db/europe/en/cities.txt +13 -0
  27. data/db/europe/es/cities.txt +5 -0
  28. data/db/europe/fr/cities.txt +4 -0
  29. data/db/europe/gr/cities.txt +1 -0
  30. data/db/europe/hr/cities.txt +1 -0
  31. data/db/europe/it/cities.txt +4 -0
  32. data/db/europe/nl/cities.txt +2 -0
  33. data/db/europe/pt/cities.txt +3 -0
  34. data/db/europe/ro/cities.txt +1 -0
  35. data/db/europe/ru/cities.txt +2 -0
  36. data/db/europe/sc/cities.txt +1 -0
  37. data/db/europe/tr/cities.txt +1 -0
  38. data/db/europe/ua/cities.txt +3 -0
  39. data/db/oceania/au/cities.txt +2 -0
  40. data/db/oceania/countries.txt +5 -0
  41. data/db/tags.yml +13 -0
  42. data/lib/worlddb.rb +6 -1
  43. data/lib/worlddb/cli/opts.rb +37 -0
  44. data/lib/worlddb/cli/runner.rb +29 -11
  45. data/lib/worlddb/models/city.rb +4 -0
  46. data/lib/worlddb/models/country.rb +3 -0
  47. data/lib/worlddb/models/region.rb +4 -0
  48. data/lib/worlddb/models/tag.rb +15 -0
  49. data/lib/worlddb/models/tagging.rb +12 -0
  50. data/lib/worlddb/reader.rb +211 -0
  51. data/lib/worlddb/schema.rb +17 -0
  52. data/lib/worlddb/version.rb +2 -1
  53. metadata +85 -36
  54. data/db/africa/countries.rb +0 -19
  55. data/db/america/ca/cities.rb +0 -31
  56. data/db/america/countries.rb +0 -44
  57. data/db/america/mx/cities.rb +0 -23
  58. data/db/america/us/cities.rb +0 -38
  59. data/db/america/ve/cities.rb +0 -2
  60. data/db/asia/countries.rb +0 -22
  61. data/db/europe/at/cities.rb +0 -70
  62. data/db/europe/be/cities.rb +0 -10
  63. data/db/europe/by/cities.rb +0 -9
  64. data/db/europe/ch/cities.rb +0 -9
  65. data/db/europe/countries.rb +0 -73
  66. data/db/europe/cy/cities.rb +0 -11
  67. data/db/europe/de/cities.rb +0 -51
  68. data/db/europe/dk/cities.rb +0 -9
  69. data/db/europe/en/cities.rb +0 -22
  70. data/db/europe/es/cities.rb +0 -13
  71. data/db/europe/fr/cities.rb +0 -12
  72. data/db/europe/gr/cities.rb +0 -9
  73. data/db/europe/hr/cities.rb +0 -9
  74. data/db/europe/it/cities.rb +0 -11
  75. data/db/europe/nl/cities.rb +0 -11
  76. data/db/europe/pt/cities.rb +0 -11
  77. data/db/europe/ro/cities.rb +0 -9
  78. data/db/europe/ru/cities.rb +0 -11
  79. data/db/europe/sc/cities.rb +0 -10
  80. data/db/europe/tr/cities.rb +0 -9
  81. data/db/europe/ua/cities.rb +0 -11
  82. data/db/oceania/au/cities.rb +0 -2
  83. data/db/oceania/countries.rb +0 -14
  84. data/db/tags.rb +0 -8
@@ -8,6 +8,10 @@ class City < ActiveRecord::Base
8
8
  belongs_to :country, :class_name => 'Country', :foreign_key => 'country_id'
9
9
  belongs_to :region, :class_name => 'Region', :foreign_key => 'region_id'
10
10
 
11
+ has_many :taggings, :as => :taggable
12
+ has_many :tags, :through => :taggings
13
+
14
+
11
15
  def self.create_from_ary!( cities, more_values={} )
12
16
  cities.each do |values|
13
17
 
@@ -8,6 +8,9 @@ class Country < ActiveRecord::Base
8
8
  has_many :regions, :class_name => 'Region', :foreign_key => 'country_id'
9
9
  has_many :cities, :class_name => 'City', :foreign_key => 'country_id'
10
10
 
11
+ has_many :taggings, :as => :taggable
12
+ has_many :tags, :through => :taggings
13
+
11
14
  def self.create_from_ary!( countries )
12
15
  countries.each do |values|
13
16
 
@@ -6,6 +6,10 @@ class Region < ActiveRecord::Base
6
6
 
7
7
  has_many :cities, :class_name => 'City', :foreign_key => 'region_id'
8
8
 
9
+ has_many :taggings, :as => :taggable
10
+ has_many :tags, :through => :taggings
11
+
12
+
9
13
  def self.create_from_ary!( regions, more_values={} )
10
14
  regions.each do |values|
11
15
 
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+
3
+ module WorldDB::Models
4
+
5
+ class Tag < ActiveRecord::Base
6
+
7
+ has_many :taggings
8
+
9
+ has_many :cities, :through => :taggings, :source => :taggable, :source_type => 'WorldDB::Models::City', :class_name => 'City'
10
+ has_many :countries, :through => :taggings, :source => :taggable, :source_type => 'WorldDB::Models::Country', :class_name => 'Country'
11
+ has_many :regions, :through => :taggings, :source => :taggable, :source_type => 'WorldDB::Models::Region', :class_name => 'Region'
12
+
13
+ end # class Tag
14
+
15
+ end # module WorldDB::Models
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ module WorldDB::Models
4
+
5
+ class Tagging < ActiveRecord::Base
6
+
7
+ belongs_to :tag
8
+ belongs_to :taggable, :polymorphic => true
9
+
10
+ end # class Tagging
11
+
12
+ end # module WorldDB::Models
@@ -0,0 +1,211 @@
1
+ module WorldDB
2
+
3
+ class Reader
4
+
5
+ ## make models available in sportdb module by default with namespace
6
+ # e.g. lets you use City instead of Models::City
7
+ include WorldDB::Models
8
+
9
+
10
+ def initialize( logger=nil )
11
+ if logger.nil?
12
+ @logger = Logger.new(STDOUT)
13
+ @logger.level = Logger::INFO
14
+ else
15
+ @logger = logger
16
+ end
17
+ end
18
+
19
+ attr_reader :logger
20
+
21
+ def run( opts, args )
22
+
23
+ args.each do |arg|
24
+ name = arg # File.basename( arg, '.*' )
25
+
26
+ if opts.load?
27
+ load_countries_builtin( name ) if opts.countries?
28
+ load_regions_builtin( opts.country, name ) if opts.regions?
29
+ load_cities_builtin( opts.country, name ) if opts.cities?
30
+ else
31
+ load_countries_with_include_path( name, opts.data_path ) if opts.countries?
32
+ load_regions_with_include_path( opts.country, name, opts.data_path ) if opts.regions?
33
+ load_cities_with_include_path( opts.country, name, opts.data_path ) if opts.cities?
34
+ end
35
+ end
36
+
37
+ end
38
+
39
+ ############################
40
+ # load from file system
41
+
42
+ def load_countries_with_include_path( name, include_path )
43
+ load_fixtures_with_include_path_for( Country, name, include_path )
44
+ end
45
+
46
+ def load_regions_with_include_path( country_key, name, include_path )
47
+ country = Country.find_by_key!( country_key )
48
+ puts "Country #{country.key} >#{country.title} (#{country.tag})<"
49
+
50
+ load_fixtures_with_include_path_for( Region, name, include_path, country_id: country.id )
51
+ end
52
+
53
+ def load_cities_with_include_path( country_key, name, include_path )
54
+ country = Country.find_by_key!( country_key )
55
+ puts "Country #{country.key} >#{country.title} (#{country.tag})<"
56
+
57
+ load_fixtures_with_include_path_for( City, name, include_path, country_id: country.id )
58
+ end
59
+
60
+ ##################################
61
+ # load from gem (built-in)
62
+
63
+ def load_countries_builtin( name )
64
+ load_fixtures_builtin_for( Country, name )
65
+ end
66
+
67
+ def load_regions_builtin( country_key, name )
68
+ country = Country.find_by_key!( country_key )
69
+ puts "Country #{country.key} >#{country.title} (#{country.tag})<"
70
+
71
+ load_fixtures_builtin_for( Region, name, country_id: country.id )
72
+ end
73
+
74
+ def load_cities_builtin( country_key, name )
75
+ country = Country.find_by_key!( country_key )
76
+ puts "Country #{country.key} >#{country.title} (#{country.tag})<"
77
+
78
+ load_fixtures_builtin_for( City, name, country_id: country.id )
79
+ end
80
+
81
+
82
+ private
83
+ def load_fixtures_with_include_path_for( clazz, name, include_path, more_values={} ) # load from file system
84
+ path = "#{include_path}/#{name}.txt"
85
+
86
+ puts "*** parsing data '#{name}' (#{path})..."
87
+
88
+ text = File.read( path )
89
+
90
+ load_fixtures_worker_for( clazz, text, more_values )
91
+ end
92
+
93
+ def load_fixtures_builtin_for( clazz, name, more_values={} ) # load from gem (built-in)
94
+ path = "#{WorldDB.root}/db/#{name}.txt"
95
+
96
+ puts "*** parsing data '#{name}' (#{path})..."
97
+
98
+ text = File.read( path )
99
+
100
+ load_fixtures_worker_for( clazz, text, more_values )
101
+ end
102
+
103
+ def load_fixtures_worker_for( clazz, data, more_values )
104
+
105
+ ## NB: assumes active activerecord db connection
106
+ ##
107
+
108
+ data.each_line do |line|
109
+
110
+ if line =~ /^\s*#/
111
+ # skip komments and do NOT copy to result (keep comments secret!)
112
+ logger.debug 'skipping comment line'
113
+ next
114
+ end
115
+
116
+ if line =~ /^\s*$/
117
+ # kommentar oder leerzeile überspringen
118
+ logger.debug 'skipping blank line'
119
+ next
120
+ end
121
+
122
+ # remove leading and trailing whitespace
123
+ line = line.strip
124
+
125
+ puts "line: >>#{line}<<"
126
+
127
+ values = line.split(',')
128
+
129
+ # remove leading and trailing whitespace for values
130
+ values = values.map { |value| value.strip }
131
+
132
+ ## remove comment columns
133
+ ## todo: also removecomments from inside columns ?? why? why not??
134
+
135
+ values = values.select do |value|
136
+ if value =~ /^#/ ## start with # treat it as a comment column; e.g. remove it
137
+ puts " removing column with value >>#{value}<<"
138
+ false
139
+ else
140
+ true
141
+ end
142
+ end
143
+
144
+ puts " values: >>#{values.join('<< >>')}<<"
145
+
146
+ attribs = {
147
+ key: values[0]
148
+ }
149
+
150
+ ## title (split of optional synonyms)
151
+ # e.g. FC Bayern Muenchen|Bayern Muenchen|Bayern
152
+ titles = values[1].split('|')
153
+
154
+ attribs[ :title ] = titles[0]
155
+ ## add optional synonyms
156
+ attribs[ :synonyms ] = titles[1..-1].join('|') if titles.size > 1
157
+
158
+ attribs = attribs.merge( more_values ) # e.g. merge country_id and other defaults if present
159
+
160
+ value_numbers = []
161
+
162
+ ## check for optional values
163
+ values[2..-1].each_with_index do |value,index|
164
+ if value =~ /^region:/ ## region:
165
+ value_region_key = value[7..-1] ## cut off region: prefix
166
+ value_region = Region.find_by_key!( value_region_key )
167
+ attribs[ :region_id ] = value_region.id
168
+ elsif value =~ /^[A-Z]{3}$/ ## assume three-letter code
169
+ attribs[ :tag ] = value # todo: rename to code??
170
+ elsif value =~ /^\d+$/ ## numeric
171
+ value_numbers << value.to_i
172
+ elsif (values.size==(index+3)) && value =~ /^[a-z0-9\| ]+$/ # tags must be last entry
173
+ puts " skipping tags: #{value}"
174
+ else
175
+ # issue warning: unknown type for value
176
+ puts "*** warning: unknown type for value >#{value}<"
177
+ end
178
+ end
179
+
180
+ if value_numbers.size > 0
181
+ if clazz == City
182
+ attribs[ :pop ] = value_numbers[0] # assume first number is pop for cities
183
+ attribs[ :area ] = value_numbers[1]
184
+ else # countries,regions
185
+ attribs[ :area ] = value_numbers[1]
186
+ attribs[ :pop ] = value_numbers[0]
187
+ end
188
+ end
189
+
190
+ rec = clazz.find_by_key( attribs[ :key ] )
191
+ if rec.present?
192
+ ## nb: [17..-1] cut off WorldDB::Models:: in name
193
+ puts "*** update #{clazz.name[17..-1].downcase} #{rec.id}-#{rec.key}:"
194
+ else
195
+ puts "*** create #{clazz.name[17..-1].downcase}:"
196
+ rec = clazz.new
197
+ end
198
+
199
+ puts attribs.to_json
200
+
201
+ rec.update_attributes!( attribs )
202
+
203
+ end # data.each
204
+
205
+ ## todo/fix: add Prop.create!( name )
206
+
207
+ end # method load_fixture_worker_for
208
+
209
+
210
+ end # class Reader
211
+ end # module WorldDB
@@ -43,6 +43,23 @@ create_table :cities do |t|
43
43
  t.timestamps
44
44
  end
45
45
 
46
+ create_table :tags do |t|
47
+ t.string :key, :null => false
48
+ t.string :title # todo: make required?
49
+ ## todo: add parent or similar for hierachy (for tag stacks/packs)
50
+ t.timestamps
51
+ end
52
+
53
+ create_table :taggings do |t|
54
+ t.references :tag, :null => false
55
+ t.references :taggable, :polymorphic => true
56
+ t.timestamps # todo: use only t.datetime :created_at (do we get ar magic? is updated used/needed??)
57
+ end
58
+
59
+ add_index :taggings, :tag_id
60
+ add_index :taggings, [:taggable_id, :taggable_type]
61
+
62
+
46
63
  create_table :props do |t|
47
64
  t.string :key, :null => false
48
65
  t.string :value, :null => false
@@ -1,4 +1,5 @@
1
1
 
2
2
  module WorldDB
3
- VERSION = '0.2.2'
3
+ VERSION = '0.3.0'
4
4
  end
5
+
metadata CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 2
9
- - 2
10
- version: 0.2.2
8
+ - 3
9
+ - 0
10
+ version: 0.3.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Gerald Bauer
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-11-08 00:00:00 Z
18
+ date: 2012-11-11 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: activerecord
@@ -70,51 +70,97 @@ extensions: []
70
70
 
71
71
  extra_rdoc_files:
72
72
  - Manifest.txt
73
+ - db/africa/countries.txt
74
+ - db/america/br/cities.txt
75
+ - db/america/br/regions.txt
76
+ - db/america/ca/cities.txt
77
+ - db/america/ca/regions.txt
78
+ - db/america/countries.txt
79
+ - db/america/mx/cities.txt
80
+ - db/america/us/cities.txt
81
+ - db/america/us/regions.txt
82
+ - db/america/ve/cities.txt
83
+ - db/america/ve/regions.txt
84
+ - db/asia/countries.txt
85
+ - db/asia/jp/cities.txt
86
+ - db/europe/at/cities.txt
87
+ - db/europe/at/regions.txt
88
+ - db/europe/be/cities.txt
89
+ - db/europe/by/cities.txt
90
+ - db/europe/ch/cities.txt
91
+ - db/europe/countries.txt
92
+ - db/europe/cy/cities.txt
93
+ - db/europe/de/cities.txt
94
+ - db/europe/de/regions.txt
95
+ - db/europe/dk/cities.txt
96
+ - db/europe/en/cities.txt
97
+ - db/europe/es/cities.txt
98
+ - db/europe/fr/cities.txt
99
+ - db/europe/gr/cities.txt
100
+ - db/europe/hr/cities.txt
101
+ - db/europe/it/cities.txt
102
+ - db/europe/nl/cities.txt
103
+ - db/europe/pt/cities.txt
104
+ - db/europe/ro/cities.txt
105
+ - db/europe/ru/cities.txt
106
+ - db/europe/sc/cities.txt
107
+ - db/europe/tr/cities.txt
108
+ - db/europe/ua/cities.txt
109
+ - db/oceania/au/cities.txt
110
+ - db/oceania/countries.txt
73
111
  files:
74
112
  - History.markdown
75
113
  - Manifest.txt
76
114
  - README.markdown
77
115
  - Rakefile
78
116
  - bin/worlddb
79
- - db/africa/countries.rb
117
+ - db/africa/countries.txt
80
118
  - db/africa/de.countries.yml
81
- - db/america/ca/cities.rb
82
- - db/america/countries.rb
119
+ - db/america/br/cities.txt
120
+ - db/america/br/regions.txt
121
+ - db/america/ca/cities.txt
122
+ - db/america/ca/regions.txt
123
+ - db/america/countries.motor.yml
124
+ - db/america/countries.txt
83
125
  - db/america/de.countries.yml
84
126
  - db/america/es.countries.yml
85
- - db/america/mx/cities.rb
86
- - db/america/us/cities.rb
87
- - db/america/ve/cities.rb
88
- - db/asia/countries.rb
127
+ - db/america/mx/cities.txt
128
+ - db/america/us/cities.txt
129
+ - db/america/us/regions.txt
130
+ - db/america/ve/cities.txt
131
+ - db/america/ve/regions.txt
132
+ - db/asia/countries.txt
89
133
  - db/asia/de.countries.yml
90
- - db/asia/jp/cities.rb
91
- - db/europe/at/cities.rb
92
- - db/europe/be/cities.rb
93
- - db/europe/by/cities.rb
94
- - db/europe/ch/cities.rb
95
- - db/europe/countries.rb
96
- - db/europe/cy/cities.rb
134
+ - db/asia/jp/cities.txt
135
+ - db/europe/at/cities.txt
136
+ - db/europe/at/regions.txt
137
+ - db/europe/be/cities.txt
138
+ - db/europe/by/cities.txt
139
+ - db/europe/ch/cities.txt
140
+ - db/europe/countries.txt
141
+ - db/europe/cy/cities.txt
97
142
  - db/europe/de.countries.yml
98
- - db/europe/de/cities.rb
99
- - db/europe/dk/cities.rb
100
- - db/europe/en/cities.rb
143
+ - db/europe/de/cities.txt
144
+ - db/europe/de/regions.txt
145
+ - db/europe/dk/cities.txt
146
+ - db/europe/en/cities.txt
101
147
  - db/europe/es.countries.yml
102
- - db/europe/es/cities.rb
103
- - db/europe/fr/cities.rb
104
- - db/europe/gr/cities.rb
105
- - db/europe/hr/cities.rb
106
- - db/europe/it/cities.rb
107
- - db/europe/nl/cities.rb
108
- - db/europe/pt/cities.rb
109
- - db/europe/ro/cities.rb
110
- - db/europe/ru/cities.rb
111
- - db/europe/sc/cities.rb
112
- - db/europe/tr/cities.rb
113
- - db/europe/ua/cities.rb
114
- - db/oceania/au/cities.rb
115
- - db/oceania/countries.rb
148
+ - db/europe/es/cities.txt
149
+ - db/europe/fr/cities.txt
150
+ - db/europe/gr/cities.txt
151
+ - db/europe/hr/cities.txt
152
+ - db/europe/it/cities.txt
153
+ - db/europe/nl/cities.txt
154
+ - db/europe/pt/cities.txt
155
+ - db/europe/ro/cities.txt
156
+ - db/europe/ru/cities.txt
157
+ - db/europe/sc/cities.txt
158
+ - db/europe/tr/cities.txt
159
+ - db/europe/ua/cities.txt
160
+ - db/oceania/au/cities.txt
161
+ - db/oceania/countries.txt
116
162
  - db/oceania/de.countries.yml
117
- - db/tags.rb
163
+ - db/tags.yml
118
164
  - lib/worlddb.rb
119
165
  - lib/worlddb/cli/opts.rb
120
166
  - lib/worlddb/cli/runner.rb
@@ -123,6 +169,9 @@ files:
123
169
  - lib/worlddb/models/country.rb
124
170
  - lib/worlddb/models/prop.rb
125
171
  - lib/worlddb/models/region.rb
172
+ - lib/worlddb/models/tag.rb
173
+ - lib/worlddb/models/tagging.rb
174
+ - lib/worlddb/reader.rb
126
175
  - lib/worlddb/schema.rb
127
176
  - lib/worlddb/version.rb
128
177
  homepage: http://geraldb.github.com/world.db