earth-ruby19 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (187) hide show
  1. data/Gemfile +5 -0
  2. data/Gemfile.lock +138 -0
  3. data/LICENSE +20 -0
  4. data/README.markdown +38 -0
  5. data/lib/earth.rb +146 -0
  6. data/lib/earth/active_record_ext.rb +9 -0
  7. data/lib/earth/air.rb +13 -0
  8. data/lib/earth/air/aircraft.rb +21 -0
  9. data/lib/earth/air/aircraft/data_miner.rb +184 -0
  10. data/lib/earth/air/aircraft_class.rb +10 -0
  11. data/lib/earth/air/aircraft_class/data_miner.rb +42 -0
  12. data/lib/earth/air/aircraft_manufacturer.rb +9 -0
  13. data/lib/earth/air/aircraft_manufacturer/data_miner.rb +20 -0
  14. data/lib/earth/air/airline.rb +16 -0
  15. data/lib/earth/air/airline/data_miner.rb +57 -0
  16. data/lib/earth/air/airport.rb +44 -0
  17. data/lib/earth/air/airport/data_miner.rb +80 -0
  18. data/lib/earth/air/data_miner.rb +15 -0
  19. data/lib/earth/air/flight_configuration.rb +7 -0
  20. data/lib/earth/air/flight_configuration/data_miner.rb +16 -0
  21. data/lib/earth/air/flight_distance_class.rb +7 -0
  22. data/lib/earth/air/flight_distance_class/data_miner.rb +16 -0
  23. data/lib/earth/air/flight_domesticity.rb +6 -0
  24. data/lib/earth/air/flight_domesticity/data_miner.rb +57 -0
  25. data/lib/earth/air/flight_fuel_type.rb +12 -0
  26. data/lib/earth/air/flight_fuel_type/data_miner.rb +12 -0
  27. data/lib/earth/air/flight_propulsion.rb +7 -0
  28. data/lib/earth/air/flight_propulsion/data_miner.rb +16 -0
  29. data/lib/earth/air/flight_seat_class.rb +12 -0
  30. data/lib/earth/air/flight_seat_class/data_miner.rb +36 -0
  31. data/lib/earth/air/flight_segment.rb +29 -0
  32. data/lib/earth/air/flight_segment/data_miner.rb +330 -0
  33. data/lib/earth/air/flight_service.rb +7 -0
  34. data/lib/earth/air/flight_service/data_miner.rb +16 -0
  35. data/lib/earth/all.rb +11 -0
  36. data/lib/earth/automobile.rb +8 -0
  37. data/lib/earth/automobile/automobile_fuel_type.rb +18 -0
  38. data/lib/earth/automobile/automobile_fuel_type/data_miner.rb +45 -0
  39. data/lib/earth/automobile/automobile_make.rb +14 -0
  40. data/lib/earth/automobile/automobile_make/data_miner.rb +68 -0
  41. data/lib/earth/automobile/automobile_make_fleet_year.rb +15 -0
  42. data/lib/earth/automobile/automobile_make_fleet_year/data_miner.rb +29 -0
  43. data/lib/earth/automobile/automobile_make_year.rb +14 -0
  44. data/lib/earth/automobile/automobile_make_year/data_miner.rb +45 -0
  45. data/lib/earth/automobile/automobile_model.rb +14 -0
  46. data/lib/earth/automobile/automobile_model/data_miner.rb +38 -0
  47. data/lib/earth/automobile/automobile_model_year.rb +15 -0
  48. data/lib/earth/automobile/automobile_model_year/data_miner.rb +51 -0
  49. data/lib/earth/automobile/automobile_size_class.rb +14 -0
  50. data/lib/earth/automobile/automobile_size_class/data_miner.rb +43 -0
  51. data/lib/earth/automobile/automobile_variant.rb +17 -0
  52. data/lib/earth/automobile/automobile_variant/data_miner.rb +460 -0
  53. data/lib/earth/automobile/data_miner.rb +8 -0
  54. data/lib/earth/base.rb +7 -0
  55. data/lib/earth/bus.rb +1 -0
  56. data/lib/earth/bus/bus_class.rb +19 -0
  57. data/lib/earth/bus/bus_class/data_miner.rb +41 -0
  58. data/lib/earth/bus/data_miner.rb +1 -0
  59. data/lib/earth/conversions_ext.rb +45 -0
  60. data/lib/earth/data_miner.rb +10 -0
  61. data/lib/earth/diet.rb +2 -0
  62. data/lib/earth/diet/data_miner.rb +2 -0
  63. data/lib/earth/diet/diet_class.rb +15 -0
  64. data/lib/earth/diet/diet_class/data_miner.rb +36 -0
  65. data/lib/earth/diet/food_group.rb +17 -0
  66. data/lib/earth/diet/food_group/data_miner.rb +26 -0
  67. data/lib/earth/fuel.rb +2 -0
  68. data/lib/earth/fuel/data_miner.rb +2 -0
  69. data/lib/earth/fuel/fuel_price.rb +13 -0
  70. data/lib/earth/fuel/fuel_price/data_miner.rb +20 -0
  71. data/lib/earth/fuel/fuel_type.rb +18 -0
  72. data/lib/earth/fuel/fuel_type/data_miner.rb +37 -0
  73. data/lib/earth/hospitality.rb +1 -0
  74. data/lib/earth/hospitality/data_miner.rb +1 -0
  75. data/lib/earth/hospitality/lodging_class.rb +9 -0
  76. data/lib/earth/hospitality/lodging_class/data_miner.rb +30 -0
  77. data/lib/earth/industry.rb +10 -0
  78. data/lib/earth/industry/industry.rb +23 -0
  79. data/lib/earth/industry/industry_product.rb +22 -0
  80. data/lib/earth/industry/industry_product_line.rb +20 -0
  81. data/lib/earth/industry/industry_sector.rb +20 -0
  82. data/lib/earth/industry/merchant.rb +18 -0
  83. data/lib/earth/industry/merchant_category.rb +22 -0
  84. data/lib/earth/industry/merchant_category_industry.rb +20 -0
  85. data/lib/earth/industry/product_line.rb +22 -0
  86. data/lib/earth/industry/product_line_industry_product.rb +20 -0
  87. data/lib/earth/industry/sector.rb +19 -0
  88. data/lib/earth/inflectors.rb +9 -0
  89. data/lib/earth/locality.rb +10 -0
  90. data/lib/earth/locality/census_division.rb +22 -0
  91. data/lib/earth/locality/census_division/data_miner.rb +64 -0
  92. data/lib/earth/locality/census_region.rb +13 -0
  93. data/lib/earth/locality/census_region/data_miner.rb +17 -0
  94. data/lib/earth/locality/climate_division.rb +17 -0
  95. data/lib/earth/locality/climate_division/data_miner.rb +20 -0
  96. data/lib/earth/locality/country.rb +13 -0
  97. data/lib/earth/locality/country/data_miner.rb +19 -0
  98. data/lib/earth/locality/data_miner.rb +10 -0
  99. data/lib/earth/locality/egrid_region.rb +15 -0
  100. data/lib/earth/locality/egrid_region/data_miner.rb +35 -0
  101. data/lib/earth/locality/egrid_subregion.rb +16 -0
  102. data/lib/earth/locality/egrid_subregion/data_miner.rb +65 -0
  103. data/lib/earth/locality/petroleum_administration_for_defense_district.rb +13 -0
  104. data/lib/earth/locality/petroleum_administration_for_defense_district/data_miner.rb +21 -0
  105. data/lib/earth/locality/state.rb +22 -0
  106. data/lib/earth/locality/state/data_miner.rb +37 -0
  107. data/lib/earth/locality/urbanity.rb +10 -0
  108. data/lib/earth/locality/urbanity/data_miner.rb +15 -0
  109. data/lib/earth/locality/zip_code.rb +23 -0
  110. data/lib/earth/locality/zip_code/data_miner.rb +43 -0
  111. data/lib/earth/pet.rb +4 -0
  112. data/lib/earth/pet/breed.rb +15 -0
  113. data/lib/earth/pet/breed/data_miner.rb +25 -0
  114. data/lib/earth/pet/breed_gender.rb +14 -0
  115. data/lib/earth/pet/breed_gender/data_miner.rb +21 -0
  116. data/lib/earth/pet/data_miner.rb +4 -0
  117. data/lib/earth/pet/gender.rb +10 -0
  118. data/lib/earth/pet/gender/data_miner.rb +13 -0
  119. data/lib/earth/pet/species.rb +40 -0
  120. data/lib/earth/pet/species/data_miner.rb +42 -0
  121. data/lib/earth/rail.rb +1 -0
  122. data/lib/earth/rail/data_miner.rb +1 -0
  123. data/lib/earth/rail/rail_class.rb +16 -0
  124. data/lib/earth/rail/rail_class/data_miner.rb +36 -0
  125. data/lib/earth/residence.rb +8 -0
  126. data/lib/earth/residence/air_conditioner_use.rb +13 -0
  127. data/lib/earth/residence/air_conditioner_use/data_miner.rb +22 -0
  128. data/lib/earth/residence/clothes_machine_use.rb +10 -0
  129. data/lib/earth/residence/clothes_machine_use/data_miner.rb +28 -0
  130. data/lib/earth/residence/data_miner.rb +8 -0
  131. data/lib/earth/residence/dishwasher_use.rb +10 -0
  132. data/lib/earth/residence/dishwasher_use/data_miner.rb +28 -0
  133. data/lib/earth/residence/residence_appliance.rb +16 -0
  134. data/lib/earth/residence/residence_appliance/data_miner.rb +20 -0
  135. data/lib/earth/residence/residence_class.rb +16 -0
  136. data/lib/earth/residence/residence_class/data_miner.rb +15 -0
  137. data/lib/earth/residence/residence_fuel_price.rb +18 -0
  138. data/lib/earth/residence/residence_fuel_price/data_miner.rb +200 -0
  139. data/lib/earth/residence/residence_fuel_type.rb +32 -0
  140. data/lib/earth/residence/residence_fuel_type/data_miner.rb +18 -0
  141. data/lib/earth/residence/residential_energy_consumption_survey_response.rb +39 -0
  142. data/lib/earth/residence/residential_energy_consumption_survey_response/data_miner.rb +283 -0
  143. data/spec/lib/earth_spec.rb +25 -0
  144. data/spec/spec_helper.rb +11 -0
  145. data/vendor/geokit-rails/CHANGELOG.rdoc +46 -0
  146. data/vendor/geokit-rails/MIT-LICENSE +20 -0
  147. data/vendor/geokit-rails/README.markdown +561 -0
  148. data/vendor/geokit-rails/Rakefile +18 -0
  149. data/vendor/geokit-rails/about.yml +9 -0
  150. data/vendor/geokit-rails/assets/api_keys_template +61 -0
  151. data/vendor/geokit-rails/init.rb +1 -0
  152. data/vendor/geokit-rails/install.rb +14 -0
  153. data/vendor/geokit-rails/lib/geokit-rails.rb +24 -0
  154. data/vendor/geokit-rails/lib/geokit-rails/acts_as_mappable.rb +456 -0
  155. data/vendor/geokit-rails/lib/geokit-rails/adapters/abstract.rb +31 -0
  156. data/vendor/geokit-rails/lib/geokit-rails/adapters/mysql.rb +22 -0
  157. data/vendor/geokit-rails/lib/geokit-rails/adapters/postgresql.rb +22 -0
  158. data/vendor/geokit-rails/lib/geokit-rails/adapters/sqlserver.rb +43 -0
  159. data/vendor/geokit-rails/lib/geokit-rails/defaults.rb +22 -0
  160. data/vendor/geokit-rails/lib/geokit-rails/geocoder_control.rb +16 -0
  161. data/vendor/geokit-rails/lib/geokit-rails/ip_geocode_lookup.rb +46 -0
  162. data/vendor/geokit-rails/test/acts_as_mappable_test.rb +474 -0
  163. data/vendor/geokit-rails/test/boot.rb +25 -0
  164. data/vendor/geokit-rails/test/database.yml +20 -0
  165. data/vendor/geokit-rails/test/fixtures/companies.yml +7 -0
  166. data/vendor/geokit-rails/test/fixtures/custom_locations.yml +54 -0
  167. data/vendor/geokit-rails/test/fixtures/locations.yml +54 -0
  168. data/vendor/geokit-rails/test/fixtures/mock_addresses.yml +17 -0
  169. data/vendor/geokit-rails/test/fixtures/mock_families.yml +2 -0
  170. data/vendor/geokit-rails/test/fixtures/mock_houses.yml +9 -0
  171. data/vendor/geokit-rails/test/fixtures/mock_organizations.yml +5 -0
  172. data/vendor/geokit-rails/test/fixtures/mock_people.yml +5 -0
  173. data/vendor/geokit-rails/test/fixtures/stores.yml +0 -0
  174. data/vendor/geokit-rails/test/ip_geocode_lookup_test.rb +77 -0
  175. data/vendor/geokit-rails/test/models/company.rb +3 -0
  176. data/vendor/geokit-rails/test/models/custom_location.rb +12 -0
  177. data/vendor/geokit-rails/test/models/location.rb +4 -0
  178. data/vendor/geokit-rails/test/models/mock_address.rb +4 -0
  179. data/vendor/geokit-rails/test/models/mock_family.rb +3 -0
  180. data/vendor/geokit-rails/test/models/mock_house.rb +3 -0
  181. data/vendor/geokit-rails/test/models/mock_organization.rb +4 -0
  182. data/vendor/geokit-rails/test/models/mock_person.rb +4 -0
  183. data/vendor/geokit-rails/test/models/store.rb +3 -0
  184. data/vendor/geokit-rails/test/schema.rb +60 -0
  185. data/vendor/geokit-rails/test/tasks.rake +31 -0
  186. data/vendor/geokit-rails/test/test_helper.rb +23 -0
  187. metadata +476 -0
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ gem 'data_miner', :path => ENV['LOCAL_DATA_MINER'] if ENV['LOCAL_DATA_MINER']
2
+
3
+ source :rubygems
4
+
5
+ gemspec :path => '.'
data/Gemfile.lock ADDED
@@ -0,0 +1,138 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ GData (0.0.4)
5
+ builder (>= 2.1.2)
6
+ hoe (>= 1.2.1)
7
+ activemodel (3.0.0)
8
+ activesupport (= 3.0.0)
9
+ builder (~> 2.1.2)
10
+ i18n (~> 0.4.1)
11
+ activerecord (3.0.0)
12
+ activemodel (= 3.0.0)
13
+ activesupport (= 3.0.0)
14
+ arel (~> 1.0.0)
15
+ tzinfo (~> 0.3.23)
16
+ activesupport (3.0.0)
17
+ amatch (0.2.5)
18
+ andand (1.3.1)
19
+ arel (1.0.1)
20
+ activesupport (~> 3.0.0)
21
+ blockenspiel (0.3.2)
22
+ builder (2.1.2)
23
+ cohort_scope (0.0.7)
24
+ activerecord (>= 3.0.0.beta4)
25
+ activesupport (>= 3.0.0.beta4)
26
+ conversions (1.4.5)
27
+ activesupport (>= 2.3.4)
28
+ data_miner (0.5.4)
29
+ activerecord (>= 2.3.4)
30
+ activesupport (>= 2.3.4)
31
+ andand (>= 1.3.1)
32
+ blockenspiel (= 0.3.2)
33
+ conversions (>= 1.4.4)
34
+ errata (>= 0.2.1)
35
+ escape (>= 0.0.4)
36
+ log4r (>= 1.1.7)
37
+ remote_table (>= 0.2.30)
38
+ taps (>= 0.3.11)
39
+ diff-lcs (1.1.2)
40
+ errata (0.2.3)
41
+ activesupport (>= 2.3.4)
42
+ remote_table (>= 0.2.20)
43
+ escape (0.0.4)
44
+ falls_back_on (0.0.3)
45
+ activerecord
46
+ fastercsv (1.5.3)
47
+ gemcutter (0.6.1)
48
+ geokit (1.5.0)
49
+ git (1.2.5)
50
+ hoe (2.6.2)
51
+ rake (>= 0.8.7)
52
+ rubyforge (>= 2.0.4)
53
+ hpricot (0.8.2)
54
+ i18n (0.4.1)
55
+ jeweler (1.4.0)
56
+ gemcutter (>= 0.1.0)
57
+ git (>= 1.2.5)
58
+ rubyforge (>= 2.0.0)
59
+ json_pure (1.4.6)
60
+ libxml-ruby (1.1.4)
61
+ log4r (1.1.8)
62
+ loose_tight_dictionary (0.0.8)
63
+ activesupport (>= 2.3.4)
64
+ amatch (>= 0.2.5)
65
+ andand (>= 1.3.1)
66
+ fastercsv (>= 1.5.3)
67
+ mime-types (1.16)
68
+ nokogiri (1.4.3.1)
69
+ rack (1.2.1)
70
+ rake (0.8.7)
71
+ rcov (0.9.9)
72
+ rdoc (2.5.11)
73
+ remote_table (0.2.30)
74
+ activesupport (>= 2.3.4)
75
+ escape (>= 0.0.4)
76
+ fastercsv (>= 1.5.0)
77
+ nokogiri (>= 1.4.1)
78
+ roo (= 1.3.11)
79
+ slither (>= 0.99.3)
80
+ rest-client (1.4.2)
81
+ mime-types (>= 1.16)
82
+ roo (1.3.11)
83
+ GData (>= 0.0.4)
84
+ hpricot (>= 0.6)
85
+ libxml-ruby (>= 1.1.3)
86
+ rubyzip (>= 0.9.1)
87
+ spreadsheet (>= 0.6.4)
88
+ rspec (2.0.0.beta.22)
89
+ rspec-core (= 2.0.0.beta.22)
90
+ rspec-expectations (= 2.0.0.beta.22)
91
+ rspec-mocks (= 2.0.0.beta.22)
92
+ rspec-core (2.0.0.beta.22)
93
+ rspec-expectations (2.0.0.beta.22)
94
+ diff-lcs (>= 1.1.2)
95
+ rspec-mocks (2.0.0.beta.22)
96
+ rspec-core (= 2.0.0.beta.22)
97
+ rspec-expectations (= 2.0.0.beta.22)
98
+ ruby-ole (1.2.10.1)
99
+ rubyforge (2.0.4)
100
+ json_pure (>= 1.1.7)
101
+ rubyzip (0.9.4)
102
+ sequel (3.15.0)
103
+ sinatra (1.0)
104
+ rack (>= 1.0)
105
+ slither (0.99.3)
106
+ spreadsheet (0.6.4.1)
107
+ ruby-ole
108
+ sqlite3-ruby (1.3.1)
109
+ taps (0.3.12)
110
+ json_pure (>= 1.2.0, < 1.5.0)
111
+ rack (>= 1.0.1)
112
+ rest-client (~> 1.4.0)
113
+ sequel (~> 3.15.0)
114
+ sinatra (~> 1.0.0)
115
+ sqlite3-ruby (~> 1.2)
116
+ tzinfo (0.3.23)
117
+ weighted_average (0.0.5)
118
+ activerecord (>= 3.0.0.beta2)
119
+ arel (>= 0.3.3)
120
+
121
+ PLATFORMS
122
+ ruby
123
+
124
+ DEPENDENCIES
125
+ activerecord (>= 3.0.0.beta4)
126
+ cohort_scope (>= 0.0.7)
127
+ conversions (>= 1.4.5)
128
+ data_miner (>= 0.5.3)
129
+ falls_back_on (>= 0.0.3)
130
+ geokit (>= 1.5.0)
131
+ jeweler
132
+ loose_tight_dictionary (>= 0.0.8)
133
+ rake
134
+ rcov
135
+ rdoc
136
+ rspec (>= 2.0.0.beta.17)
137
+ sqlite3-ruby (>= 1.3.0)
138
+ weighted_average (>= 0.0.4)
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Andy Rossmeissl
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,38 @@
1
+ # earth
2
+
3
+ Earth is a collection of data models that represent various things found here on Earth, such as pet breeds, kinds of rail travel, zip codes, and Petroleum Administration for Defense Districts.
4
+
5
+ The data that these models represent can be pulled from http://data.brighterplanet.com
6
+
7
+ ## Usage
8
+
9
+ require 'earth'
10
+ Earth.init :automobile, :locality
11
+ ft = AutomobileFuelType.first
12
+ ...
13
+
14
+ You can also run data imports via the data_miner gem.
15
+
16
+ require 'earth'
17
+ Earth.init :fuel
18
+ Earth.taps_server # 'http://user:pass@data.brighterplanet.com'
19
+
20
+ DataMiner.run :resource_names #> [FuelPrice]</tt>
21
+
22
+ ## Collaboration cycle
23
+ Brighter Planet vigorously encourages collaborative improvement of its emitter libraries. Collaboration requires a (free) GitHub account.
24
+
25
+ ### You
26
+ 1. Fork the earth repository on GitHub.
27
+ 1. Write a test proving the existing implementation's inadequacy. Ensure that the test fails. Commit the test.
28
+ 1. Improve the code until your new test passes and commit your changes.
29
+ 1. Push your changes to your GitHub fork.
30
+ 1. Submit a pull request to brighterplanet.
31
+
32
+ ### Brighter Planet
33
+ 1. Receive a pull request.
34
+ 1. Pull changes from forked repository.
35
+ 1. Ensure tests pass.
36
+ 1. Review changes for scientific accuracy.
37
+ 1. Merge changes to master repository and publish.
38
+ 1. Direct production environment to use new emitter version.
data/lib/earth.rb ADDED
@@ -0,0 +1,146 @@
1
+ require 'active_record'
2
+ require 'cohort_scope'
3
+ require 'earth/base'
4
+ require 'earth/conversions_ext'
5
+ require 'earth/inflectors'
6
+ require 'data_miner'
7
+ require 'falls_back_on'
8
+ require 'falls_back_on/active_record_ext'
9
+ require 'weighted_average'
10
+ require 'loose_tight_dictionary'
11
+
12
+ # The earth module is an interface for establishing a taps server (used to fetch
13
+ # data) and for loading data models from various domains.
14
+ module Earth
15
+ extend self
16
+
17
+ def taps_server
18
+ if defined?(@taps_server)
19
+ @taps_server
20
+ else
21
+ @taps_server = nil
22
+ end
23
+ end
24
+
25
+ # taps_server is a URL. See the data_miner gem docs
26
+ def taps_server=(val)
27
+ @taps_server = val
28
+ end
29
+
30
+ # Takes argument like Earth.resource_names(['air'])
31
+ # Default is search all domains
32
+ # For example, <tt>[ 'Aircraft', 'Airline' ]</tt>
33
+ def resource_names(search_domains = nil)
34
+ (search_domains || domains).map do |domain|
35
+ Dir[File.join(Earth.gem_root, 'lib', 'earth', domain, '*.rb')]
36
+ end.flatten.uniq.map { |p| File.basename(p, '.rb').camelcase } - %w{ DataMiner }
37
+ end
38
+
39
+ def gem_root
40
+ File.expand_path File.join(File.dirname(__FILE__), '..')
41
+ end
42
+
43
+ def domains
44
+ %w{air automobile bus diet fuel locality pet rail residence}
45
+ end
46
+
47
+ # Earth.init will load any specified domains, any needed ActiveRecord plugins,
48
+ # and will apply each domain model's schema to the database if the
49
+ # :apply_schemas option is given. See Earth.domains for the list of allowable
50
+ # domains.
51
+ #
52
+ # Earth.init should be performed after a connection is made to the database and
53
+ # before any domain models are referenced.
54
+ def init(*args)
55
+ load_plugins
56
+
57
+ domains = []
58
+ options = {}
59
+ args.each do |arg|
60
+ if arg.is_a?(Hash)
61
+ options = arg
62
+ else
63
+ domains << arg
64
+ end
65
+ end
66
+
67
+ load_domains(domains, options)
68
+ load_schemas if options[:apply_schemas]
69
+ end
70
+
71
+ def database_options
72
+ if ActiveRecord::Base.connection.adapter_name.downcase == 'sqlite'
73
+ {}
74
+ else
75
+ { :options => 'ENGINE=InnoDB default charset=utf8' }
76
+ end
77
+ end
78
+
79
+ private
80
+ def load_domains(domains, options)
81
+ if domains.empty? or domains.include?(:all)
82
+ # sabshere 9/16/10 why maintain this separately?
83
+ require 'earth/all'
84
+ require 'earth/data_miner' if options[:apply_schemas] or options[:load_data_miner]
85
+ elsif !domains.include?(:none)
86
+ domains.each do |domain|
87
+ require "earth/#{domain}"
88
+ if options[:apply_schemas] or options[:load_data_miner]
89
+ begin
90
+ require "earth/#{domain}/data_miner"
91
+ rescue LoadError
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+
98
+ def load_plugins
99
+ require 'earth/active_record_ext'
100
+ Dir[File.join(Earth.gem_root, 'vendor', '**', 'init.rb')].each do |pluginit|
101
+ $:.unshift File.join(File.dirname(pluginit), 'lib')
102
+ load pluginit
103
+ end
104
+ end
105
+
106
+ def load_schemas
107
+ force_fallback_table
108
+ load_data_miner_schemas
109
+ end
110
+
111
+ # sabshere 9/17/10 this sucks. the falls_back_on gem sucks.
112
+ def force_fallback_table
113
+ c = ActiveRecord::Base.connection
114
+ if c.table_exists? 'fallbacks'
115
+ raise "The earth gem expects a different schema for the fallbacks table." unless c.column_exists?('fallbacks', 'name') and
116
+ c.column_exists?('fallbacks', 'values') and
117
+ c.column_exists?('fallbacks', 'created_at') and
118
+ c.column_exists?('fallbacks', 'updated_at')
119
+ else
120
+ c.create_table 'fallbacks' do |t|
121
+ t.string 'name'
122
+ t.text 'values'
123
+ t.datetime 'created_at'
124
+ t.datetime 'updated_at'
125
+ end
126
+ end
127
+ end
128
+
129
+ def load_data_miner_schemas
130
+ models = Module.constants.select do |k|
131
+ const = Object.const_get(k) if Object.const_defined?(k)
132
+ if const.instance_of?(Class)
133
+ const.superclass == ActiveRecord::Base ||
134
+ const.superclass == Earth::Base
135
+ else
136
+ false
137
+ end
138
+ end
139
+ models.sort.each do |model|
140
+ klass = Object.const_get(model)
141
+ if klass.respond_to?(:execute_schema) and !klass.table_exists?
142
+ klass.execute_schema
143
+ end
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,9 @@
1
+ require 'active_record'
2
+ ::ActiveRecord::Base.class_eval do
3
+ def self.run_data_miner_on_belongs_to_associations
4
+ reflect_on_all_associations(:belongs_to).each do |a|
5
+ next if a.options[:polymorphic]
6
+ a.klass.run_data_miner!
7
+ end
8
+ end
9
+ end
data/lib/earth/air.rb ADDED
@@ -0,0 +1,13 @@
1
+ require 'earth/air/aircraft'
2
+ require 'earth/air/aircraft_class'
3
+ require 'earth/air/aircraft_manufacturer'
4
+ require 'earth/air/airline'
5
+ require 'earth/air/airport'
6
+ require 'earth/air/flight_configuration'
7
+ require 'earth/air/flight_distance_class'
8
+ require 'earth/air/flight_domesticity'
9
+ require 'earth/air/flight_fuel_type'
10
+ require 'earth/air/flight_propulsion'
11
+ require 'earth/air/flight_seat_class'
12
+ require 'earth/air/flight_segment'
13
+ require 'earth/air/flight_service'
@@ -0,0 +1,21 @@
1
+ class Aircraft < ActiveRecord::Base
2
+ set_primary_key :icao_code
3
+
4
+ belongs_to :aircraft_class, :foreign_key => 'brighter_planet_aircraft_class_code'
5
+ belongs_to :manufacturer, :foreign_key => 'manufacturer_name', :class_name => 'AircraftManufacturer'
6
+ has_many :segments, :foreign_key => 'bts_aircraft_type_code', :class_name => "FlightSegment", :primary_key => 'bts_aircraft_type_code'
7
+
8
+ falls_back_on :m3 => lambda { weighted_average(:m3, :weighted_by => [:segments, :passengers]) }, # 9.73423082858437e-08 r7110: 8.6540464368905e-8 r6972: 8.37e-8
9
+ :m2 => lambda { weighted_average(:m2, :weighted_by => [:segments, :passengers]) }, # -0.000134350543484608 r7110: -0.00015337661447817 r6972: -4.09e-5
10
+ :m1 => lambda { weighted_average(:m1, :weighted_by => [:segments, :passengers]) }, # 6.7728101555467 r7110: 4.7781966869412 r6972: 7.85
11
+ :endpoint_fuel => lambda { weighted_average(:endpoint_fuel, :weighted_by => [:segments, :passengers]) }, # 1527.81790006167 r7110: 1065.3476555284 r6972: 1.72e3
12
+ :seats => lambda { weighted_average(:seats, :weighted_by => [:segments, :passengers]) } # 62.1741
13
+
14
+ data_miner do
15
+ tap "Brighter Planet's sanitized aircraft data", Earth.taps_server
16
+
17
+ process "pull dependencies" do
18
+ run_data_miner_on_belongs_to_associations
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,184 @@
1
+ Aircraft.class_eval do
2
+
3
+ # TODO use http://www.transtats.bts.gov/Download_Lookup.asp?Lookup=L_AIRCRAFT_TYPE
4
+ def self.bts_name_dictionary
5
+ @_bts_dictionary ||= LooseTightDictionary.new RemoteTable.new(:url => 'http://www.transtats.bts.gov/Download_Lookup.asp?Lookup=L_AIRCRAFT_TYPE', :select => lambda { |record| record['Code'].to_i.between?(1, 998) }),
6
+ :tightenings => RemoteTable.new(:url => 'http://spreadsheets.google.com/pub?key=tiS_6CCDDM_drNphpYwE_iw&single=true&gid=0&output=csv', :headers => false),
7
+ :identities => RemoteTable.new(:url => 'http://spreadsheets.google.com/pub?key=tiS_6CCDDM_drNphpYwE_iw&single=true&gid=3&output=csv', :headers => false),
8
+ :blockings => RemoteTable.new(:url => 'http://spreadsheets.google.com/pub?key=tiS_6CCDDM_drNphpYwE_iw&single=true&gid=4&output=csv', :headers => false),
9
+ :blocking_only => true,
10
+ :right_reader => lambda { |record| record['Description'] }
11
+ end
12
+
13
+ # warning: self-referential, assumes it will be used once first import step is done
14
+ def self.icao_name_dictionary
15
+ @_icao_dictionary ||= LooseTightDictionary.new Aircraft.all,
16
+ :tightenings => RemoteTable.new(:url => 'http://spreadsheets.google.com/pub?key=tiS_6CCDDM_drNphpYwE_iw&single=true&gid=0&output=csv', :headers => false),
17
+ :identities => RemoteTable.new(:url => 'http://spreadsheets.google.com/pub?key=tiS_6CCDDM_drNphpYwE_iw&single=true&gid=3&output=csv', :headers => false),
18
+ :blockings => RemoteTable.new(:url => 'http://spreadsheets.google.com/pub?key=tiS_6CCDDM_drNphpYwE_iw&single=true&gid=4&output=csv', :headers => false),
19
+ :right_reader => lambda { |record| record.manufacturer_name.to_s + ' ' + record.name.to_s }
20
+ end
21
+
22
+ class Aircraft::BtsMatcher
23
+ attr_reader :wants
24
+ def initialize(wants)
25
+ @wants = wants
26
+ end
27
+ def match(raw_faa_icao_record)
28
+ @_match ||= Hash.new
29
+ return @_match[raw_faa_icao_record] if @_match.has_key?(raw_faa_icao_record)
30
+ faa_icao_record = [ raw_faa_icao_record['Manufacturer'] + ' ' + raw_faa_icao_record['Model'] ]
31
+ bts_record = Aircraft.bts_name_dictionary.left_to_right faa_icao_record
32
+ retval = case wants
33
+ when :bts_aircraft_type_code
34
+ bts_record['Code']
35
+ when :bts_name
36
+ bts_record['Description']
37
+ end if bts_record
38
+ @_match[raw_faa_icao_record] = retval
39
+ end
40
+ end
41
+
42
+ class Aircraft::FuelUseMatcher
43
+ def match(raw_fuel_use_record)
44
+ @_match ||= Hash.new
45
+ return @_match[raw_fuel_use_record] if @_match.has_key?(raw_fuel_use_record)
46
+
47
+ aircraft_record = if raw_fuel_use_record['ICAO'] =~ /\A[0-9A-Z]+\z/
48
+ Aircraft.find_by_icao_code raw_fuel_use_record['ICAO']
49
+ end
50
+
51
+ aircraft_record ||= if raw_fuel_use_record['Aircraft Name'].present?
52
+ Aircraft.icao_name_dictionary.left_to_right [ raw_fuel_use_record['Aircraft Name'] ]
53
+ end
54
+
55
+ if aircraft_record
56
+ @_match[raw_fuel_use_record] = aircraft_record.icao_code
57
+ else
58
+ raise "Didn't find a match for #{raw_fuel_use_record['Aircraft Name']} (#{raw_fuel_use_record['ICAO']}), which we found in the fuel use spreadsheet"
59
+ end
60
+ end
61
+ end
62
+
63
+ class Aircraft::Guru
64
+ # for errata
65
+ def is_a_dc_plane?(row)
66
+ row['Designator'] =~ /^DC\d/i
67
+ end
68
+
69
+ # def is_a_crj_900?(row)
70
+ # row['Designator'].downcase == 'crj9'
71
+ # end
72
+
73
+ def is_a_g159?(row)
74
+ row['Designator'] =~ /^G159$/
75
+ end
76
+
77
+ def is_a_galx?(row)
78
+ row['Designator'] =~ /^GALX$/
79
+ end
80
+
81
+ def method_missing(method_id, *args, &block)
82
+ if method_id.to_s =~ /\Ais_n?o?t?_?attributed_to_([^\?]+)/
83
+ manufacturer_name = $1
84
+ manufacturer_regexp = Regexp.new(manufacturer_name.gsub('_', ' ?'), Regexp::IGNORECASE)
85
+ matches = manufacturer_regexp.match(args.first['Manufacturer']) # row['Manufacturer'] =~ /mcdonnell douglas/i
86
+ method_id.to_s.include?('not_attributed') ? matches.nil? : !matches.nil?
87
+ else
88
+ super
89
+ end
90
+ end
91
+ end
92
+
93
+ data_miner do
94
+ schema Earth.database_options do
95
+ string 'icao_code'
96
+ string 'manufacturer_name'
97
+ string 'name'
98
+ string 'bts_name'
99
+ string 'bts_aircraft_type_code'
100
+ string 'brighter_planet_aircraft_class_code'
101
+ string 'fuel_use_aircraft_name'
102
+ float 'm3'
103
+ string 'm3_units'
104
+ float 'm2'
105
+ string 'm2_units'
106
+ float 'm1'
107
+ string 'm1_units'
108
+ float 'endpoint_fuel'
109
+ string 'endpoint_fuel_units'
110
+ float 'seats'
111
+ float 'distance'
112
+ string 'distance_units'
113
+ float 'load_factor'
114
+ float 'freight_share'
115
+ float 'payload'
116
+ float 'weighting'
117
+ index 'bts_aircraft_type_code'
118
+ end
119
+
120
+ ('A'..'Z').each do |letter|
121
+ # ('Z'..'Z').each do |letter|
122
+ import( "ICAO aircraft codes starting with the letter #{letter} used by the FAA",
123
+ :url => "http://www.faa.gov/air_traffic/publications/atpubs/CNT/5-2-#{letter}.htm",
124
+ :errata => Errata.new(:url => 'http://spreadsheets.google.com/pub?key=tObVAGyqOkCBtGid0tJUZrw',
125
+ :responder => Aircraft::Guru.new),
126
+ :encoding => 'windows-1252',
127
+ :row_xpath => '//table/tr[2]/td/table/tr',
128
+ :column_xpath => 'td' ) do
129
+ key 'icao_code', :field_name => 'Designator'
130
+ store 'bts_aircraft_type_code', :matcher => Aircraft::BtsMatcher.new(:bts_aircraft_type_code)
131
+ store 'bts_name', :matcher => Aircraft::BtsMatcher.new(:bts_name)
132
+ store 'manufacturer_name', :field_name => 'Manufacturer'
133
+ store 'name', :field_name => 'Model'
134
+ end
135
+ end
136
+
137
+ # TODO fixme need to remake aircraft classes dictionary based on ICAO codes
138
+ # sabshere 5/17/10 or maybe we can replace this with typ/weight class from FAA (?)
139
+ import "Brighter Planet's aircraft class codes",
140
+ :url => 'http://static.brighterplanet.com/science/data/transport/air/bts_aircraft_type/bts_aircraft_types-brighter_planet_aircraft_classes.csv' do
141
+ key 'bts_aircraft_type_code', :field_name => 'bts_aircraft_type'
142
+ store 'brighter_planet_aircraft_class_code'
143
+ end
144
+
145
+ # EEA
146
+ import "pre-calculated fuel use equation coefficients",
147
+ :url => 'http://static.brighterplanet.com/science/data/transport/air/fuel_use/aircraft_fuel_use_formulae.ods',
148
+ :select => lambda { |row| row['ICAO'].present? or row['Aircraft Name'].present? } do
149
+ key 'icao_code', :matcher => Aircraft::FuelUseMatcher.new
150
+ store 'fuel_use_aircraft_name', :field_name => 'Aircraft Name'
151
+ store 'm3'
152
+ store 'm2'
153
+ store 'm1'
154
+ store 'endpoint_fuel', :field_name => 'b'
155
+ end
156
+
157
+ process "Derive some average flight characteristics from flight segments" do
158
+ FlightSegment.run_data_miner!
159
+ aircraft = Aircraft.arel_table
160
+ segments = FlightSegment.arel_table
161
+
162
+ # non-working joins method
163
+ # update_all "aircraft.distance_1 = (SELECT * FROM (#{FlightSegment.joins(:aircraft).weighted_average_relation(:distance, :weighted_by => :passengers ).to_sql}) AS anonymous_1)"
164
+ # update_all "aircraft.load_factor_1 = (SELECT * FROM (#{FlightSegment.joins(:aircraft).weighted_average_relation(:load_factor, :weighted_by => :passengers ).to_sql}) AS anonymous_1)"
165
+ # execute %{
166
+ # update aircraft as t1
167
+ # set t1.distance_1 = (SELECT * FROM (#{FlightSegment.joins(:aircraft).weighted_average_relation(:distance, :weighted_by => :passengers ).where('t1.bts_aircraft_type_code = flight_segments.bts_aircraft_type_code').to_sql}) AS anonymous_1)
168
+ # }
169
+
170
+ conditional_relation = aircraft[:bts_aircraft_type_code].eq(segments[:bts_aircraft_type_code])
171
+ update_all "seats = (#{FlightSegment.weighted_average_relation(:seats, :weighted_by => :passengers ).where(conditional_relation).to_sql})"
172
+ update_all "distance = (#{FlightSegment.weighted_average_relation(:distance, :weighted_by => :passengers ).where(conditional_relation).to_sql})"
173
+ update_all "load_factor = (#{FlightSegment.weighted_average_relation(:load_factor, :weighted_by => :passengers ).where(conditional_relation).to_sql})"
174
+ update_all "freight_share = (#{FlightSegment.weighted_average_relation(:freight_share, :weighted_by => :passengers ).where(conditional_relation).to_sql})"
175
+ update_all "payload = (#{FlightSegment.weighted_average_relation(:payload, :weighted_by => :passengers, :disaggregate_by => :departures_performed).where(conditional_relation).to_sql})"
176
+
177
+ update_all "weighting = (#{segments.project(segments[:passengers].sum).where(aircraft[:bts_aircraft_type_code].eq(segments[:bts_aircraft_type_code])).to_sql})"
178
+ end
179
+
180
+ process "Synthesize AircraftManufacturer" do
181
+ AircraftManufacturer.run_data_miner!
182
+ end
183
+ end
184
+ end