carbon 2.0.3 → 2.1.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.
@@ -0,0 +1,2 @@
1
+ --no-private
2
+ --readme README.markdown
data/CHANGELOG CHANGED
@@ -1,3 +1,14 @@
1
+ 2.1.0 / 2012-03-14
2
+
3
+ * Enhancements
4
+
5
+ * Simplified API down to just Carbon.query. It has three method signatures.
6
+ * Simplified EventMachine reactor
7
+
8
+ * Breaking changes
9
+
10
+ * Simplified API down to just Carbon.query :)
11
+
1
12
  2.0.3 / 2012-03-13
2
13
 
3
14
  * Enhancements
data/Gemfile CHANGED
@@ -10,3 +10,4 @@ gem 'webmock'
10
10
  gem 'aruba'
11
11
  gem 'cucumber'
12
12
  gem 'yard'
13
+ gem 'avro'
@@ -176,10 +176,10 @@ This library includes a special console for performing calculations interactivel
176
176
  : Set the [developer key](http://keys.brighterplanet.com) that should be used for this session. Alternatively, put this key in `~/.brighter_planet` and it will be auto-selected on console startup.
177
177
 
178
178
  _emitter_
179
- : (e.g. `Flight`) Enters emitter mode using this emitter type.
179
+ : (e.g. `flight`) Enters emitter mode using this emitter type.
180
180
 
181
181
  _emitter num_
182
- : (e.g. `Flight 0`) Recalls a previous emitter from this session.
182
+ : (e.g. `flight 0`) Recalls a previous emitter from this session.
183
183
 
184
184
  `exit`
185
185
  : Quits.
data/Rakefile CHANGED
@@ -18,3 +18,32 @@ YARD::Rake::YardocTask.new do |y|
18
18
  end
19
19
 
20
20
  task :default => [:test, :cucumber]
21
+
22
+ namespace :avro do
23
+ task :setup do
24
+ require 'rubygems'
25
+ require 'bundler/setup'
26
+ require File.expand_path("../developer/avro_helper", __FILE__)
27
+ require File.expand_path("../developer/cm1_avro", __FILE__)
28
+ @cm1 = Cm1Avro::Impact.new
29
+ end
30
+ task :api_paths => 'avro:setup' do
31
+ ary = []
32
+ AvroHelper.api_paths(@cm1.avro_response_schema) { |path| ary << path }
33
+ $stdout.write ary.sort.join("\n")
34
+ end
35
+ task :json => 'avro:setup' do
36
+ $stdout.write MultiJson.encode(@cm1.avro_response_schema)
37
+ end
38
+ task :example => 'avro:setup' do
39
+ require 'tempfile'
40
+ file = Tempfile.new('com.brighterplanet.Cm1.example.avr')
41
+ parsed_schema = Avro::Schema.parse(MultiJson.encode(@cm1.avro_response_schema))
42
+ writer = Avro::IO::DatumWriter.new(parsed_schema)
43
+ dw = Avro::DataFile::Writer.new(file, writer, parsed_schema)
44
+ dw << AvroHelper.recursively_stringify_keys(@cm1.example)
45
+ dw.close
46
+ file.close
47
+ $stdout.write File.read(file.path)
48
+ end
49
+ end
@@ -0,0 +1,81 @@
1
+ require 'hashie/mash'
2
+ require 'avro'
3
+ require 'multi_json'
4
+ require 'active_support/core_ext'
5
+
6
+ module AvroHelper
7
+ SCALAR = ['boolean', 'int', 'float', 'string' ]
8
+ OPTIONAL_SCALAR = SCALAR + [ 'null' ]
9
+ OPTIONAL_STRING = ['string', 'null']
10
+
11
+ def AvroHelper.api_paths(schema, parents = nil, last_type = nil, &blk)
12
+ return unless schema.is_a?(::Hash)
13
+
14
+ schema = ::Hashie::Mash.new(schema) unless schema.is_a?(::Hashie::Mash)
15
+
16
+ my_name = schema.name
17
+
18
+ my_type = if schema.type == 'record'
19
+ my_schema = schema
20
+ schema.type
21
+ elsif schema.type.is_a?(::Hash)
22
+ my_schema = schema.type
23
+ schema.type.type
24
+ end
25
+
26
+ nested_schemas = if my_schema
27
+ case my_type
28
+ when 'array'
29
+ my_schema.items
30
+ when 'map'
31
+ my_schema.values
32
+ when 'record'
33
+ my_schema.fields
34
+ end
35
+ end
36
+ nested_schemas = Array.wrap nested_schemas
37
+
38
+ # if the last type was enumerable, then i'm anonymous
39
+ me = case last_type
40
+ when 'array'
41
+ '[]'
42
+ when 'map'
43
+ '{}'
44
+ when NilClass
45
+ nil
46
+ else
47
+ my_name
48
+ end
49
+
50
+ nested_schemas.each { |x| api_paths(x, [parents, me].flatten.compact, my_type, &blk) }
51
+
52
+ # don't try to print the top leve which will be 'v2' depending on the api version number
53
+ return unless parents
54
+
55
+ if my_name.present? and nested_schemas.none? { |x| x.is_a?(::Hash) }
56
+ children = case my_type
57
+ when 'array'
58
+ '[]'
59
+ when 'map'
60
+ '{}'
61
+ end
62
+ blk.call [parents, me, children].flatten.compact.join('.')
63
+ end
64
+ end
65
+
66
+ def AvroHelper.recursively_stringify_keys(hash)
67
+ hash.inject({}) do |result, (key, value)|
68
+ new_key = case key
69
+ when ::Symbol then key.to_s
70
+ else key
71
+ end
72
+ new_value = case value
73
+ when ::Hash then recursively_stringify_keys(value)
74
+ when ::Array then value.map { |i| i.is_a?(::Hash) ? recursively_stringify_keys(i) : i }
75
+ else value
76
+ end
77
+ result[new_key] = new_value
78
+ result
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,955 @@
1
+ require 'active_support/core_ext'
2
+ require File.expand_path('../avro_helper', __FILE__)
3
+
4
+ module Cm1Avro
5
+ class Impact
6
+ def notes
7
+ [
8
+ "All emitters return carbon (@impact_response.decisions.carbon).",
9
+ "Check emitter documentation to see what other impacts (energy, waste, etc.) are returned."
10
+ ]
11
+ end
12
+
13
+ def dns_name
14
+ 'impact.brighterplanet.com'
15
+ end
16
+
17
+ def namespace
18
+ dns_name.split('.').reverse.join('.')
19
+ end
20
+
21
+ def example
22
+ {"compliance"=>[],
23
+ "decisions"=>
24
+ {"carbon"=>
25
+ {"description"=>"78.7 kg",
26
+ "object"=>{"value"=>78.67540811299375, "units"=>"kilograms"},
27
+ "methodology"=>"from fuel use and greenhouse gas emission factor"},
28
+ "ghg_emission_factor"=>
29
+ {"description"=>"5.15214",
30
+ "object"=>5.15214,
31
+ "methodology"=>"from fuel and aviation multiplier"},
32
+ "aviation_multiplier"=>
33
+ {"description"=>"2.0", "object"=>2.0, "methodology"=>"default"},
34
+ "energy"=>
35
+ {"description"=>"574.6 MJ",
36
+ "object"=>{"value"=>574.5759972448694, "units"=>"megajoules"},
37
+ "methodology"=>"from fuel use and fuel"},
38
+ "fuel_use"=>
39
+ {"description"=>"15.270432890603466",
40
+ "object"=>15.270432890603466,
41
+ "methodology"=>
42
+ "from fuel per segment, segments per trip, trips, freight_share, passengers, seat class multiplier, fuel, date, and timeframe"},
43
+ "fuel_per_segment"=>
44
+ {"description"=>"1480.9925950502234",
45
+ "object"=>1480.9925950502234,
46
+ "methodology"=>
47
+ "from adjusted distance per segment and fuel use coefficients"},
48
+ "seat_class_multiplier"=>
49
+ {"description"=>"1.0", "object"=>1.0, "methodology"=>"default"},
50
+ "distance_class"=>
51
+ {"description"=>"short haul",
52
+ "object"=>
53
+ {"flight_distance_class"=>
54
+ {"distance"=>1108.0,
55
+ "distance_units"=>"kilometres",
56
+ "max_distance"=>3700.0,
57
+ "max_distance_units"=>"kilometres",
58
+ "min_distance"=>0.0,
59
+ "min_distance_units"=>"kilometres",
60
+ "name"=>"short haul"}},
61
+ "methodology"=>"from adjusted distance per segment"},
62
+ "adjusted_distance_per_segment"=>
63
+ {"description"=>"100.8961154095222",
64
+ "object"=>100.8961154095222,
65
+ "methodology"=>"from adjusted distance and segments per trip"},
66
+ "adjusted_distance"=>
67
+ {"description"=>"100.8961154095222",
68
+ "object"=>100.8961154095222,
69
+ "methodology"=>
70
+ "from distance, route inefficiency factor, and dogleg factor"},
71
+ "distance"=>
72
+ {"description"=>"94.29543496217028",
73
+ "object"=>94.29543496217028,
74
+ "methodology"=>"from airports"},
75
+ "route_inefficiency_factor"=>
76
+ {"description"=>"1.07", "object"=>1.07, "methodology"=>"from country"},
77
+ "dogleg_factor"=>
78
+ {"description"=>"1.0",
79
+ "object"=>1.0,
80
+ "methodology"=>"from segments per trip"},
81
+ "fuel_use_coefficients"=>
82
+ {"description"=>
83
+ "BrighterPlanet::Flight::ImpactModel::FuelUseEquation::Given",
84
+ "object"=>{"m3"=>4.986e-08, "m2"=>8.255e-05, "m1"=>5.246, "b"=>950.8},
85
+ "methodology"=>"from aircraft"},
86
+ "fuel"=>
87
+ {"description"=>"Jet Fuel",
88
+ "object"=>
89
+ {"fuel"=>
90
+ {"biogenic_fraction"=>0.0,
91
+ "carbon_content"=>18.672,
92
+ "carbon_content_units"=>"grams_per_megajoule",
93
+ "co2_biogenic_emission_factor"=>0.0,
94
+ "co2_biogenic_emission_factor_units"=>"kilograms_per_litre",
95
+ "co2_emission_factor"=>2.57607,
96
+ "co2_emission_factor_units"=>"kilograms_per_litre",
97
+ "density"=>0.8156,
98
+ "density_units"=>"kilograms_per_litre",
99
+ "energy_content"=>37.6267,
100
+ "energy_content_units"=>"megajoules_per_litre",
101
+ "name"=>"Jet Fuel",
102
+ "oxidation_factor"=>1.0,
103
+ "physical_units"=>nil}},
104
+ "methodology"=>"default"},
105
+ "passengers"=>
106
+ {"description"=>"111",
107
+ "object"=>111,
108
+ "methodology"=>"from seats and load factor"},
109
+ "seats"=>
110
+ {"description"=>"143.096",
111
+ "object"=>143.096,
112
+ "methodology"=>"from aircraft"},
113
+ "load_factor"=>
114
+ {"description"=>"0.7734122348583675",
115
+ "object"=>0.7734122348583675,
116
+ "methodology"=>"default"},
117
+ "freight_share"=>
118
+ {"description"=>"0.0665336701213722",
119
+ "object"=>0.0665336701213722,
120
+ "methodology"=>"default"},
121
+ "country"=>
122
+ {"description"=>"US",
123
+ "object"=>
124
+ {"country"=>
125
+ {"automobile_city_speed"=>32.0259,
126
+ "automobile_city_speed_units"=>"kilometres_per_hour",
127
+ "automobile_fuel_efficiency"=>9.2669,
128
+ "automobile_fuel_efficiency_units"=>"kilometres_per_litre",
129
+ "automobile_highway_speed"=>91.8935,
130
+ "automobile_highway_speed_units"=>"kilometres_per_hour",
131
+ "automobile_trip_distance"=>16.3348,
132
+ "automobile_trip_distance_units"=>"kilometres",
133
+ "automobile_urbanity"=>0.43,
134
+ "cooling_degree_days"=>882.0,
135
+ "cooling_degree_days_units"=>"degrees_celsius",
136
+ "electricity_emission_factor"=>0.589455,
137
+ "electricity_emission_factor_units"=>
138
+ "kilograms_co2e_per_kilowatt_hour",
139
+ "electricity_loss_factor"=>0.0615633,
140
+ "flight_route_inefficiency_factor"=>1.07,
141
+ "heating_degree_days"=>2159.0,
142
+ "heating_degree_days_units"=>"degrees_celsius",
143
+ "iso_3166_alpha_3_code"=>"USA",
144
+ "iso_3166_code"=>"US",
145
+ "iso_3166_numeric_code"=>840,
146
+ "lodging_district_heat_intensity"=>1.73952,
147
+ "lodging_district_heat_intensity_units"=>"megajoules_per_room_night",
148
+ "lodging_electricity_intensity"=>33.3145,
149
+ "lodging_electricity_intensity_units"=>
150
+ "kilowatt_hours_per_room_night",
151
+ "lodging_fuel_oil_intensity"=>0.411674,
152
+ "lodging_fuel_oil_intensity_units"=>"gallons_per_room_night",
153
+ "lodging_natural_gas_intensity"=>1.96714,
154
+ "lodging_natural_gas_intensity_units"=>"cubic_metres_per_room_night",
155
+ "lodging_occupancy_rate"=>0.601,
156
+ "name"=>"United States",
157
+ "rail_passengers"=>4467000000.0,
158
+ "rail_speed"=>32.4972,
159
+ "rail_speed_units"=>"kilometres_per_hour",
160
+ "rail_trip_co2_emission_factor"=>0.0957617,
161
+ "rail_trip_co2_emission_factor_units"=>
162
+ "kilograms_per_passenger_kilometre",
163
+ "rail_trip_diesel_intensity"=>0.0194247,
164
+ "rail_trip_diesel_intensity_units"=>"litres_per_passenger_kilometre",
165
+ "rail_trip_distance"=>12.9952,
166
+ "rail_trip_distance_units"=>"kilometres",
167
+ "rail_trip_electricity_intensity"=>0.140512,
168
+ "rail_trip_electricity_intensity_units"=>
169
+ "kilowatt_hours_per_passenger_kilometre"}},
170
+ "methodology"=>"from origin airport and destination airport"},
171
+ "date"=>
172
+ {"description"=>"2012-01-01",
173
+ "object"=>"2012-01-01",
174
+ "methodology"=>"from timeframe"}},
175
+ "emitter"=>"Flight",
176
+ "equivalents"=>
177
+ {"cars_off_the_road_for_a_year"=>0.014318924276564863,
178
+ "cars_off_the_road_for_a_month"=>0.17166974050255235,
179
+ "cars_off_the_road_for_a_week"=>0.743875983708356,
180
+ "cars_off_the_road_for_a_day"=>5.221372134826943,
181
+ "cars_to_priuses_for_a_year"=>0.028637848553129727,
182
+ "cars_to_priuses_for_a_month"=>0.3433394810051047,
183
+ "cars_to_priuses_for_a_week"=>1.487751967416712,
184
+ "cars_to_priuses_for_a_day"=>10.442744269653886,
185
+ "one_way_domestic_flight"=>0.25569507636722966,
186
+ "round_trip_domestic_flight"=>0.12784753818361483,
187
+ "one_way_cross_country_flight"=>0.08984731606503886,
188
+ "round_trip_cross_country_flight"=>0.04492365803251943,
189
+ "vegan_meals_instead_of_non_vegan_ones"=>63.309078128220605,
190
+ "days_of_veganism"=>21.1030260427402,
191
+ "weeks_of_veganism"=>3.014684288073694,
192
+ "months_of_veganism"=>0.7034368239382771,
193
+ "years_of_veganism"=>0.057826424963050405,
194
+ "barrels_of_petroleum"=>0.18299899927082347,
195
+ "canisters_of_bbq_propane"=>3.278168229844111,
196
+ "railroad_cars_full_of_coal"=>0.0003933770405649688,
197
+ "homes_energy_in_a_year"=>0.007631514586960394,
198
+ "homes_energy_in_a_month"=>0.09118479800295977,
199
+ "homes_energy_in_a_week"=>0.39502922413534164,
200
+ "homes_energy_in_a_day"=>2.7730721097586906,
201
+ "homes_electricity_in_a_year"=>0.011565284992610081,
202
+ "homes_electricity_in_a_month"=>0.138390042870756,
203
+ "homes_electricity_in_a_week"=>0.5996639606372384,
204
+ "homes_electricity_in_a_day"=>4.209055658637053,
205
+ "homes_with_lowered_thermostat_2_degrees_for_a_winter"=>0.4129672171851042,
206
+ "homes_with_raised_thermostat_3_degrees_for_a_summer"=>0.18567396314666526,
207
+ "replaced_refrigerators"=>0.07922613596978471,
208
+ "loads_of_cold_laundry"=>36.077552495110645,
209
+ "lightbulbs_for_a_year"=>0.14523480337658645,
210
+ "lightbulbs_for_a_month"=>1.7674430432584045,
211
+ "lightbulbs_for_a_week"=>7.574710942302812,
212
+ "lightbulbs_for_a_day"=>53.023212622344026,
213
+ "lightbulbs_for_an_evening"=>318.1393544094722,
214
+ "lightbulbs_to_CFLs_for_a_day"=>902.523055958413,
215
+ "lightbulbs_to_CFLs_for_a_week"=>128.93184265822813,
216
+ "lightbulbs_to_CFLs_for_a_month"=>30.08413858047089,
217
+ "lightbulbs_to_CFLs_for_a_year"=>2.4726894015832803,
218
+ "days_with_lightbulbs_to_CFLs"=>20.05609238698059,
219
+ "weeks_with_lightbulbs_to_CFLs"=>2.8651223372508934,
220
+ "months_with_lightbulbs_to_CFLs"=>0.6685049427361078,
221
+ "years_with_lightbulbs_to_CFLs"=>0.05491543486286964,
222
+ "recycled_kgs_of_trash"=>54.258888582166705,
223
+ "recycled_bags_of_trash"=>30.064627079258866},
224
+ "methodology"=>
225
+ "http://impact.brighterplanet.com/flights?aircraft[icao_code]=B737&airline[iata_code]=UA&destination_airport[iata_code]=ORD&origin_airport[iata_code]=MSN&segments_per_trip=1&trips=1",
226
+ "scope"=>
227
+ "The flight greenhouse gas emission is the anthropogenic greenhouse gas emissions attributed to a single passenger on this flight. It includes CO2 emissions from combustion of non-biogenic fuel and extra forcing effects of high-altitude fuel combustion.",
228
+ "timeframe"=>{"startDate"=>"2012-01-01", "endDate"=>"2013-01-01"},
229
+ "characteristics"=>
230
+ {"segments_per_trip"=>{"description"=>"1", "object"=>1},
231
+ "trips"=>{"description"=>"1", "object"=>1},
232
+ "origin_airport"=>
233
+ {"description"=>"MSN",
234
+ "object"=>
235
+ {"airport"=>
236
+ {"city"=>"Madison",
237
+ "country_iso_3166_code"=>"US",
238
+ "country_name"=>"United States",
239
+ "iata_code"=>"MSN",
240
+ "latitude"=>43.1399,
241
+ "longitude"=>-89.3375,
242
+ "name"=>"Dane County Regional Truax Field"}}},
243
+ "destination_airport"=>
244
+ {"description"=>"ORD",
245
+ "object"=>
246
+ {"airport"=>
247
+ {"city"=>"Chicago",
248
+ "country_iso_3166_code"=>"US",
249
+ "country_name"=>"United States",
250
+ "iata_code"=>"ORD",
251
+ "latitude"=>41.9786,
252
+ "longitude"=>-87.9048,
253
+ "name"=>"Chicago Ohare International"}}},
254
+ "airline"=>
255
+ {"description"=>"United Airlines",
256
+ "object"=>
257
+ {"airline"=>
258
+ {"bts_code"=>"UA",
259
+ "iata_code"=>"UA",
260
+ "icao_code"=>"UAL",
261
+ "name"=>"United Airlines"}}},
262
+ "aircraft"=>
263
+ {"description"=>"B737",
264
+ "object"=>
265
+ {"aircraft"=>
266
+ {"aircraft_type"=>"Landplane",
267
+ "b"=>950.8,
268
+ "b_units"=>"kilograms",
269
+ "class_code"=>"Medium 2 engine Jet",
270
+ "description"=>"boeing 737-700",
271
+ "engine_type"=>"Jet",
272
+ "engines"=>2,
273
+ "fuel_use_specificity"=>"aircraft",
274
+ "icao_code"=>"B737",
275
+ "m1"=>5.246,
276
+ "m1_units"=>"kilograms_per_nautical_mile",
277
+ "m2"=>8.255e-05,
278
+ "m2_units"=>"kilograms_per_square_nautical_mile",
279
+ "m3"=>4.986e-08,
280
+ "m3_units"=>"kilograms_per_cubic_nautical_mile",
281
+ "manufacturer_name"=>"BOEING",
282
+ "model_name"=>"737-700",
283
+ "passengers"=>322259000.0,
284
+ "seats"=>143.096,
285
+ "seats_specificity"=>"aircraft",
286
+ "weight_class"=>"Large"}}}},
287
+ "errors"=>[]}
288
+ end
289
+
290
+ def avro_response_schema
291
+ timeframe = {
292
+ :type => 'record',
293
+ :name => 'Timeframe',
294
+ :fields => [
295
+ { :name => 'startDate', :type => 'string' },
296
+ { :name => 'endDate', :type => 'string' },
297
+ ]
298
+ }
299
+
300
+ decision_object = {
301
+ :namespace => namespace,
302
+ :type => 'record',
303
+ :name => 'DecisionObject',
304
+ :fields => [
305
+ { :name => 'value', :type => AvroHelper::OPTIONAL_SCALAR },
306
+ { :name => 'units', :type => AvroHelper::OPTIONAL_STRING },
307
+ ]
308
+ }
309
+
310
+ characteristic_object = {
311
+ :namespace => namespace,
312
+ :type => 'record',
313
+ :name => 'CharacteristicObject',
314
+ :fields => [
315
+ { :name => 'value', :type => AvroHelper::OPTIONAL_SCALAR },
316
+ { :name => 'units', :type => AvroHelper::OPTIONAL_STRING },
317
+ ]
318
+ }
319
+
320
+
321
+ # { :type => 'map', :values => AvroHelper::OPTIONAL_SCALAR }
322
+
323
+ decision = {
324
+ :namespace => namespace,
325
+ :type => 'record',
326
+ :name => 'Decision',
327
+ :fields => [
328
+ { :name => 'description', :type => 'string' },
329
+ { :name => 'object', :type => (AvroHelper::SCALAR+[decision_object]) }, # should really be optional map
330
+ { :name => 'methodology', :type => 'string' }
331
+ ]
332
+ }
333
+
334
+ characteristic = {
335
+ :namespace => namespace,
336
+ :type => 'record',
337
+ :name => 'Characteristic',
338
+ :fields => [
339
+ { :name => 'description', :type => 'string' },
340
+ { :name => 'object', :type => (AvroHelper::SCALAR+[characteristic_object]) }, # should really be optional map
341
+ ]
342
+ }
343
+
344
+ {
345
+ :namespace => namespace,
346
+ :type => 'record',
347
+ :name => 'Response',
348
+ :fields => [
349
+ { :name => 'emitter', :type => 'string' },
350
+ { :name => 'characteristics', :type => { :type => 'map', :values => characteristic } },
351
+ { :name => 'decisions', :type => { :type => 'map', :values => decision } },
352
+ { :name => 'errors', :type => { :type => 'array', :items => 'string' } },
353
+ { :name => 'timeframe', :type => timeframe },
354
+ { :name => 'methodology', :type => 'string' },
355
+ # { :name => 'audit_id', :type => 'string' }, # paid extra
356
+ { :name => 'scope', :type => 'string' },
357
+ { :name => 'compliance', :type => { :type => 'array', :items => 'string' } },
358
+ { :name => 'equivalents', :type => { :type => 'map', :values => 'float' } },
359
+ { :name => 'certification', :type => AvroHelper::OPTIONAL_STRING },
360
+ ]
361
+ }
362
+ end
363
+ end
364
+
365
+ class Carbon
366
+ def notes
367
+ [
368
+ "DEPRECATED. Use impact.brighterplanet.com, which will give you @impact_response.decisions.carbon",
369
+ "Characteristics are mixed into the root of the response. For example: @carbon_response.origin_airport",
370
+ "Used by Brighter Planet carbon library versions < 1.2"
371
+ ]
372
+ end
373
+
374
+ def dns_name
375
+ 'carbon.brighterplanet.com'
376
+ end
377
+
378
+ def namespace
379
+ dns_name.split('.').reverse.join('.')
380
+ end
381
+
382
+ def avro_response_schema
383
+ quorum = {
384
+ :namespace => namespace,
385
+ :type => 'record',
386
+ :name => 'Quorum',
387
+ :fields => [
388
+ { :name => 'name', :type => 'string' },
389
+ { :name => 'requirements', :type => { :type => 'array', :items => 'string' } },
390
+ { :name => 'appreciates', :type => { :type => 'array', :items => 'string' } },
391
+ { :name => 'complies', :type => { :type => 'array', :items => 'string' } }
392
+ ]
393
+ }
394
+ committee_stub = {
395
+ :namespace => namespace,
396
+ :type => 'record',
397
+ :name => 'Committee',
398
+ :fields => [
399
+ { :name => 'name', :type => 'string' }
400
+ ]
401
+ }
402
+ report = {
403
+ :namespace => namespace,
404
+ :type => 'record',
405
+ :name => 'Report',
406
+ :fields => [
407
+ { :name => 'committee', :type => committee_stub },
408
+ { :name => 'conclusion', :type => AvroHelper::SCALAR },
409
+ { :name => 'quorum', :type => quorum }
410
+ ]
411
+ }
412
+ {
413
+ :namespace => namespace,
414
+ :type => 'record',
415
+ :name => 'Response',
416
+ :fields => [
417
+ # { :name => '*', :type => OPTIONAL_SCALAR }, # the characteristics mixed in with the root
418
+ { :name => 'emission', :type => 'float' },
419
+ { :name => 'emitter', :type => 'string' },
420
+ { :name => 'timeframe', :type => 'string' },
421
+ { :name => 'emission_units', :type => 'string' },
422
+ { :name => 'methodology', :type => 'string' },
423
+ { :name => 'execution_id', :type => 'string' },
424
+ { :name => 'scope', :type => 'string' },
425
+ { :name => 'complies', :type => { :type => 'array', :items => 'string' } },
426
+ { :name => 'errors', :type => { :type => 'array', :items => 'string' } },
427
+ { :name => 'equivalents', :type => { :type => 'map', :values => 'float' } },
428
+ { :name => 'reports', :type => { :type => 'array', :items => report } },
429
+ { :name => 'certification', :type => AvroHelper::OPTIONAL_STRING },
430
+ ]
431
+ }
432
+ end
433
+
434
+ def example
435
+ ActiveSupport::JSON.decode <<-EOS
436
+ {
437
+ "emission": 619.3139931256935,
438
+ "emitter": "Flight",
439
+ "timeframe": "2011-01-01/2012-01-01",
440
+ "emission_units": "kilograms",
441
+ "methodology": "http://carbon.brighterplanet.com/flights.html?destination_airport[iata_code]=SFO&origin_airport[iata_code]=JAC&timeframe=2011-01-01%2F2012-01-01",
442
+ "execution_id": "ae70601773dab95c67665d6bfbba71006c03bd9e",
443
+ "scope": "The flight emission estimate is the anthropogenic emissions per passenger from aircraft fuel combustion and radiative forcing. It includes CO2 emissions from combustion of non-biogenic fuel and extra forcing effects of high-altitude combustion.",
444
+ "complies": [],
445
+ "errors": [],
446
+ "equivalents": {
447
+ "cars_off_the_road_for_a_year": 0.11271514674887623,
448
+ "cars_off_the_road_for_a_month": 1.3513431330002632,
449
+ "cars_off_the_road_for_a_week": 5.855613805003432,
450
+ "cars_off_the_road_for_a_day": 41.101392467779775,
451
+ "cars_to_priuses_for_a_year": 0.22543029349775245,
452
+ "cars_to_priuses_for_a_month": 2.7026862660005264,
453
+ "cars_to_priuses_for_a_week": 11.711227610006864,
454
+ "cars_to_priuses_for_a_day": 82.20278493555955,
455
+ "one_way_domestic_flight": 2.012770477658504,
456
+ "round_trip_domestic_flight": 1.006385238829252,
457
+ "one_way_cross_country_flight": 0.707256580149542,
458
+ "round_trip_cross_country_flight": 0.353628290074771,
459
+ "vegan_meals_instead_of_non_vegan_ones": 498.35391918633496,
460
+ "days_of_veganism": 166.11797306211164,
461
+ "weeks_of_veganism": 23.730873588590324,
462
+ "months_of_veganism": 5.537286412536825,
463
+ "years_of_veganism": 0.4551957849473847,
464
+ "barrels_of_petroleum": 1.440524348010363,
465
+ "canisters_of_bbq_propane": 25.804956151568273,
466
+ "railroad_cars_full_of_coal": 0.0030965699656284678,
467
+ "homes_energy_in_a_year": 0.06007345733319227,
468
+ "homes_energy_in_a_month": 0.7177849180326789,
469
+ "homes_energy_in_a_week": 3.1095755594841075,
470
+ "homes_energy_in_a_day": 21.82896031570132,
471
+ "homes_electricity_in_a_year": 0.09103915698947694,
472
+ "homes_electricity_in_a_month": 1.0893733139080948,
473
+ "homes_electricity_in_a_week": 4.720411255604036,
474
+ "homes_electricity_in_a_day": 33.132679318231474,
475
+ "homes_with_lowered_thermostat_2_degrees_for_a_winter": 3.2507791499167653,
476
+ "homes_with_raised_thermostat_3_degrees_for_a_summer": 1.4615810237766367,
477
+ "replaced_refrigerators": 0.6236491910775734,
478
+ "loads_of_cold_laundry": 283.9938633157043,
479
+ "lightbulbs_for_a_year": 1.1432536313100303,
480
+ "lightbulbs_for_a_month": 13.912888855568704,
481
+ "lightbulbs_for_a_week": 59.626312630155525,
482
+ "lightbulbs_for_a_day": 417.386046353068,
483
+ "lightbulbs_for_an_evening": 2504.3168974324008,
484
+ "lightbulbs_to_CFLs_for_a_day": 7104.445608605558,
485
+ "lightbulbs_to_CFLs_for_a_week": 1014.9206242825103,
486
+ "lightbulbs_to_CFLs_for_a_month": 236.81514263338204,
487
+ "lightbulbs_to_CFLs_for_a_year": 19.46441948994742,
488
+ "days_with_lightbulbs_to_CFLs": 157.87676175558803,
489
+ "weeks_with_lightbulbs_to_CFLs": 22.55355768765838,
490
+ "months_with_lightbulbs_to_CFLs": 5.262310999589017,
491
+ "years_with_lightbulbs_to_CFLs": 0.4322811672017341,
492
+ "recycled_kgs_of_trash": 427.1129919291002,
493
+ "recycled_bags_of_trash": 236.6615527630869
494
+ },
495
+ "origin_airport": {
496
+ "airport": {
497
+ "city": "Jacksn Hole",
498
+ "country_iso_3166_code": "US",
499
+ "country_name": "United States",
500
+ "iata_code": "JAC",
501
+ "latitude": 43.6073,
502
+ "longitude": -110.738,
503
+ "name": "Jackson Hole"
504
+ }
505
+ },
506
+ "destination_airport": {
507
+ "airport": {
508
+ "city": "San Francisco",
509
+ "country_iso_3166_code": "US",
510
+ "country_name": "United States",
511
+ "iata_code": "SFO",
512
+ "latitude": 37.619,
513
+ "longitude": -122.375,
514
+ "name": "San Francisco International"
515
+ }
516
+ },
517
+ "date": "2011-01-01",
518
+ "segments_per_trip": 1.68,
519
+ "country": {
520
+ "country": {
521
+ "automobile_city_speed": 32.0259,
522
+ "automobile_city_speed_units": "kilometres_per_hour",
523
+ "automobile_fuel_efficiency": 9.2669,
524
+ "automobile_fuel_efficiency_units": "kilometres_per_litre",
525
+ "automobile_highway_speed": 91.8935,
526
+ "automobile_highway_speed_units": "kilometres_per_hour",
527
+ "automobile_trip_distance": 16.3348,
528
+ "automobile_trip_distance_units": "kilometres",
529
+ "automobile_urbanity": 0.43,
530
+ "flight_route_inefficiency_factor": 1.07,
531
+ "iso_3166_code": "US",
532
+ "name": "UNITED STATES"
533
+ }
534
+ },
535
+ "trips": 1.7,
536
+ "freight_share": 0.070644984859677,
537
+ "load_factor": 0.76992050796823,
538
+ "seats": 171.0530182753,
539
+ "passengers": 132,
540
+ "fuel": {
541
+ "fuel": {
542
+ "biogenic_fraction": 0,
543
+ "carbon_content": 18.672,
544
+ "carbon_content_units": "grams_per_megajoule",
545
+ "co2_biogenic_emission_factor": 0,
546
+ "co2_biogenic_emission_factor_units": "kilograms_per_litre",
547
+ "co2_emission_factor": 2.57607,
548
+ "co2_emission_factor_units": "kilograms_per_litre",
549
+ "density": 0.808,
550
+ "density_units": "kilograms_per_litre",
551
+ "energy_content": 37.6267,
552
+ "energy_content_units": "megajoules_per_litre",
553
+ "name": "Jet Fuel",
554
+ "oxidation_factor": 1
555
+ }
556
+ },
557
+ "fuel_use_coefficients": [
558
+ 1.0886676283223e-7,
559
+ -0.00017055946628547,
560
+ 6.9195725633675,
561
+ 1572.3367918346
562
+ ],
563
+ "dogleg_factor": 1.1638548181950328,
564
+ "route_inefficiency_factor": 1.07,
565
+ "distance": 640.3861758339607,
566
+ "adjusted_distance": 797.4886937873359,
567
+ "adjusted_distance_per_segment": 474.69565106389047,
568
+ "seat_class_multiplier": 1,
569
+ "fuel_per_segment": 4830.2396558575165,
570
+ "fuel_use": 13795.164457129067,
571
+ "aviation_multiplier": 2,
572
+ "emission_factor": 3.1882054455445545,
573
+ "reports": [
574
+ {
575
+ "committee": {
576
+ "name": "emission"
577
+ },
578
+ "conclusion": "619.3139931256935",
579
+ "quorum": {
580
+ "name": "from fuel use, emission factor, freight share, passengers, multipliers, and date",
581
+ "requirements": [
582
+ "fuel_use",
583
+ "emission_factor",
584
+ "freight_share",
585
+ "passengers",
586
+ "seat_class_multiplier",
587
+ "aviation_multiplier",
588
+ "date"
589
+ ],
590
+ "appreciates": [],
591
+ "complies": [
592
+ "ghg_protocol_scope_3",
593
+ "iso",
594
+ "tcr"
595
+ ]
596
+ }
597
+ },
598
+ {
599
+ "committee": {
600
+ "name": "emission_factor"
601
+ },
602
+ "conclusion": "3.1882054455445545",
603
+ "quorum": {
604
+ "name": "from fuel",
605
+ "requirements": [
606
+ "fuel"
607
+ ],
608
+ "appreciates": [],
609
+ "complies": [
610
+ "ghg_protocol_scope_3",
611
+ "iso",
612
+ "tcr"
613
+ ]
614
+ }
615
+ },
616
+ {
617
+ "committee": {
618
+ "name": "aviation_multiplier"
619
+ },
620
+ "conclusion": "2.0",
621
+ "quorum": {
622
+ "name": "default",
623
+ "requirements": [],
624
+ "appreciates": [],
625
+ "complies": [
626
+ "ghg_protocol_scope_3",
627
+ "iso",
628
+ "tcr"
629
+ ]
630
+ }
631
+ },
632
+ {
633
+ "committee": {
634
+ "name": "fuel_use"
635
+ },
636
+ "conclusion": "13795.164457129067",
637
+ "quorum": {
638
+ "name": "from fuel per segment and segments per trip and trips",
639
+ "requirements": [
640
+ "fuel_per_segment",
641
+ "segments_per_trip",
642
+ "trips"
643
+ ],
644
+ "appreciates": [],
645
+ "complies": [
646
+ "ghg_protocol_scope_3",
647
+ "iso",
648
+ "tcr"
649
+ ]
650
+ }
651
+ },
652
+ {
653
+ "committee": {
654
+ "name": "fuel_per_segment"
655
+ },
656
+ "conclusion": "4830.2396558575165",
657
+ "quorum": {
658
+ "name": "from adjusted distance per segment and fuel use coefficients",
659
+ "requirements": [
660
+ "adjusted_distance_per_segment",
661
+ "fuel_use_coefficients"
662
+ ],
663
+ "appreciates": [],
664
+ "complies": [
665
+ "ghg_protocol_scope_3",
666
+ "iso",
667
+ "tcr"
668
+ ]
669
+ }
670
+ },
671
+ {
672
+ "committee": {
673
+ "name": "seat_class_multiplier"
674
+ },
675
+ "conclusion": "1.0",
676
+ "quorum": {
677
+ "name": "from adjusted distance per segment",
678
+ "requirements": [
679
+ "adjusted_distance_per_segment"
680
+ ],
681
+ "appreciates": [],
682
+ "complies": [
683
+ "ghg_protocol_scope_3",
684
+ "iso",
685
+ "tcr"
686
+ ]
687
+ }
688
+ },
689
+ {
690
+ "committee": {
691
+ "name": "adjusted_distance_per_segment"
692
+ },
693
+ "conclusion": "474.69565106389047",
694
+ "quorum": {
695
+ "name": "from adjusted distance and segments per trip",
696
+ "requirements": [
697
+ "adjusted_distance",
698
+ "segments_per_trip"
699
+ ],
700
+ "appreciates": [],
701
+ "complies": [
702
+ "ghg_protocol_scope_3",
703
+ "iso",
704
+ "tcr"
705
+ ]
706
+ }
707
+ },
708
+ {
709
+ "committee": {
710
+ "name": "adjusted_distance"
711
+ },
712
+ "conclusion": "797.4886937873359",
713
+ "quorum": {
714
+ "name": "from distance, route inefficiency factor, and dogleg factor",
715
+ "requirements": [
716
+ "distance",
717
+ "route_inefficiency_factor",
718
+ "dogleg_factor"
719
+ ],
720
+ "appreciates": [],
721
+ "complies": [
722
+ "ghg_protocol_scope_3",
723
+ "iso",
724
+ "tcr"
725
+ ]
726
+ }
727
+ },
728
+ {
729
+ "committee": {
730
+ "name": "distance"
731
+ },
732
+ "conclusion": "640.3861758339607",
733
+ "quorum": {
734
+ "name": "from airports",
735
+ "requirements": [
736
+ "origin_airport",
737
+ "destination_airport"
738
+ ],
739
+ "appreciates": [],
740
+ "complies": [
741
+ "ghg_protocol_scope_3",
742
+ "iso",
743
+ "tcr"
744
+ ]
745
+ }
746
+ },
747
+ {
748
+ "committee": {
749
+ "name": "route_inefficiency_factor"
750
+ },
751
+ "conclusion": "1.07",
752
+ "quorum": {
753
+ "name": "from country",
754
+ "requirements": [
755
+ "country"
756
+ ],
757
+ "appreciates": [],
758
+ "complies": [
759
+ "ghg_protocol_scope_3",
760
+ "iso",
761
+ "tcr"
762
+ ]
763
+ }
764
+ },
765
+ {
766
+ "committee": {
767
+ "name": "dogleg_factor"
768
+ },
769
+ "conclusion": "1.1638548181950328",
770
+ "quorum": {
771
+ "name": "from segments per trip",
772
+ "requirements": [
773
+ "segments_per_trip"
774
+ ],
775
+ "appreciates": [],
776
+ "complies": [
777
+ "ghg_protocol_scope_3",
778
+ "iso",
779
+ "tcr"
780
+ ]
781
+ }
782
+ },
783
+ {
784
+ "committee": {
785
+ "name": "fuel_use_coefficients"
786
+ },
787
+ "conclusion": "#<struct BrighterPlanet::Flight::CarbonModel::FuelUseEquation m3=1.0886676283223e-07, m2=-0.00017055946628547, m1=6.9195725633675, b=1572.3367918346>",
788
+ "quorum": {
789
+ "name": "default",
790
+ "requirements": [],
791
+ "appreciates": [],
792
+ "complies": [
793
+ "ghg_protocol_scope_3",
794
+ "iso",
795
+ "tcr"
796
+ ]
797
+ }
798
+ },
799
+ {
800
+ "committee": {
801
+ "name": "fuel"
802
+ },
803
+ "conclusion": "Jet Fuel",
804
+ "quorum": {
805
+ "name": "default",
806
+ "requirements": [],
807
+ "appreciates": [],
808
+ "complies": [
809
+ "ghg_protocol_scope_3",
810
+ "iso",
811
+ "tcr"
812
+ ]
813
+ }
814
+ },
815
+ {
816
+ "committee": {
817
+ "name": "passengers"
818
+ },
819
+ "conclusion": "132",
820
+ "quorum": {
821
+ "name": "from seats and load factor",
822
+ "requirements": [
823
+ "seats",
824
+ "load_factor"
825
+ ],
826
+ "appreciates": [],
827
+ "complies": [
828
+ "ghg_protocol_scope_3",
829
+ "iso",
830
+ "tcr"
831
+ ]
832
+ }
833
+ },
834
+ {
835
+ "committee": {
836
+ "name": "seats"
837
+ },
838
+ "conclusion": "171.0530182753",
839
+ "quorum": {
840
+ "name": "default",
841
+ "requirements": [],
842
+ "appreciates": [],
843
+ "complies": [
844
+ "ghg_protocol_scope_3",
845
+ "iso",
846
+ "tcr"
847
+ ]
848
+ }
849
+ },
850
+ {
851
+ "committee": {
852
+ "name": "load_factor"
853
+ },
854
+ "conclusion": "0.76992050796823",
855
+ "quorum": {
856
+ "name": "default",
857
+ "requirements": [],
858
+ "appreciates": [],
859
+ "complies": [
860
+ "ghg_protocol_scope_3",
861
+ "iso",
862
+ "tcr"
863
+ ]
864
+ }
865
+ },
866
+ {
867
+ "committee": {
868
+ "name": "freight_share"
869
+ },
870
+ "conclusion": "0.070644984859677",
871
+ "quorum": {
872
+ "name": "default",
873
+ "requirements": [],
874
+ "appreciates": [],
875
+ "complies": [
876
+ "ghg_protocol_scope_3",
877
+ "iso",
878
+ "tcr"
879
+ ]
880
+ }
881
+ },
882
+ {
883
+ "committee": {
884
+ "name": "trips"
885
+ },
886
+ "conclusion": "1.7",
887
+ "quorum": {
888
+ "name": "default",
889
+ "requirements": [],
890
+ "appreciates": [],
891
+ "complies": [
892
+ "ghg_protocol_scope_3",
893
+ "iso",
894
+ "tcr"
895
+ ]
896
+ }
897
+ },
898
+ {
899
+ "committee": {
900
+ "name": "country"
901
+ },
902
+ "conclusion": "#<Country:0xb035ac4>",
903
+ "quorum": {
904
+ "name": "from origin airport and destination airport",
905
+ "requirements": [
906
+ "origin_airport",
907
+ "destination_airport"
908
+ ],
909
+ "appreciates": [],
910
+ "complies": [
911
+ "ghg_protocol_scope_3",
912
+ "iso",
913
+ "tcr"
914
+ ]
915
+ }
916
+ },
917
+ {
918
+ "committee": {
919
+ "name": "segments_per_trip"
920
+ },
921
+ "conclusion": "1.68",
922
+ "quorum": {
923
+ "name": "default",
924
+ "requirements": [],
925
+ "appreciates": [],
926
+ "complies": [
927
+ "ghg_protocol_scope_3",
928
+ "iso",
929
+ "tcr"
930
+ ]
931
+ }
932
+ },
933
+ {
934
+ "committee": {
935
+ "name": "date"
936
+ },
937
+ "conclusion": "2011-01-01",
938
+ "quorum": {
939
+ "name": "from timeframe",
940
+ "requirements": [],
941
+ "appreciates": [],
942
+ "complies": [
943
+ "ghg_protocol_scope_3",
944
+ "iso",
945
+ "tcr"
946
+ ]
947
+ }
948
+ }
949
+ ]
950
+ }
951
+ EOS
952
+ end
953
+ end
954
+
955
+ end