worlddb 0.2.2 → 0.3.0

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