Module: Carbon

Defined in:
lib/carbon.rb,
lib/carbon/query.rb,
lib/carbon/shell.rb,
lib/carbon/version.rb,
lib/carbon/registry.rb,
lib/carbon/query_pool.rb,
lib/carbon/shell/emitter.rb

Defined Under Namespace

Modules: ClassMethods Classes: QueryPool, Registry

Constant Summary

DOMAIN =
'http://impact.brighterplanet.com'.freeze
CONCURRENCY =
16
VERSION =
"3.0.1"
@@key =
nil
@@domain =
nil

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.domainString

Where we send queries.

Returns:

  • (String)

    The API endpoint.



49
50
51
# File 'lib/carbon.rb', line 49

def Carbon.domain
  @@domain || DOMAIN
end

.domain=(domain) ⇒ nil

Set an alternate API endpoint. You probably shouldn't do this.

Parameters:

Returns:

  • (nil)


41
42
43
44
# File 'lib/carbon.rb', line 41

def Carbon.domain=(domain)
  @@domain = domain
  nil
end

.keyString

Get the key you've set.

Returns:

  • (String)

    The key you set.



32
33
34
# File 'lib/carbon.rb', line 32

def Carbon.key
  @@key
end

.key=(key) ⇒ nil

Set the Brighter Planet API key that you can get from keys.brighterplanet.com

Parameters:

  • key (String)

    The alphanumeric key.

Returns:

  • (nil)


24
25
26
27
# File 'lib/carbon.rb', line 24

def Carbon.key=(key)
  @@key = key
  nil
end

.query(emitter, params) ⇒ Hashie::Mash .query(obj) ⇒ Hashie::Mash .query(array) ⇒ Hash{Object => Hashie::Mash}

Note:

We make up to 16 requests concurrently (hardcoded, per the Brighter Planet Terms of Service) and it can be more than 90% faster than running queries serially!

Note:

[emitter, params] is called a “plain query.”

Get impact estimates from Brighter Planet CM1; low-level method that does not require you to define Carbon::ClassMethods#emit_as blocks; just pass emitter/param or objects that respond to #as_impact_query.

Return values are Hashie::Mash objects because they are a simple way to access a deeply nested response.

Here's a map of what's included in a response:

certification
characteristics.{}.description
characteristics.{}.object
compliance.[]
decisions.{}.description
decisions.{}.methodology
decisions.{}.object
emitter
equivalents.{}
errors.[]
methodology
scope
timeframe.endDate
timeframe.startDate

Examples:

A flight taken in 2009

Carbon.query('Flight', :origin_airport => 'MSN', :destination_airport => 'ORD', :date => '2009-01-01', :timeframe => Timeframe.new(:year => 2009), :comply => [:tcr])

How do I use a Hashie::Mash?

1.8.7 :001 > require 'rubygems'
 => true 
1.8.7 :002 > require 'hashie/mash'
 => true 
1.8.7 :003 > mash = Hashie::Mash.new(:hello => 'world')
 => #<Hashie::Mash hello="world"> 
1.8.7 :004 > mash.hello
 => "world" 
1.8.7 :005 > mash['hello']
 => "world" 
1.8.7 :006 > mash[:hello]
 => "world" 
1.8.7 :007 > mash.keys
 => ["hello"] 

Other examples of what's in the response

my_impact.carbon.object.value
my_impact.characteristics.airline.description
my_impact.equivalents.lightbulbs_for_a_week

Flights and cars (concurrently, as arrays)

queries = [
  ['Flight', {:origin_airport => 'MSN', :destination_airport => 'ORD', :date => '2009-01-01', :timeframe => Timeframe.new(:year => 2009), :comply => [:tcr]}],
  ['Flight', {:origin_airport => 'SFO', :destination_airport => 'LAX', :date => '2011-09-29', :timeframe => Timeframe.new(:year => 2011), :comply => [:iso]}],
  ['Automobile', {:make => 'Nissan', :model => 'Altima', :timeframe => Timeframe.new(:year => 2008), :comply => [:tcr]}]
]
Carbon.query(queries)

Flights and cars (concurrently, as query-able objects)

Carbon.query(MyFlight.all+MyCar.all).each do |car_or_flight, impact|
  puts "Carbon emitter by #{car_or_flight} was #{impact.decisions.carbon.object.value.round(1)}"
end

Overloads:

  • .query(emitter, params) ⇒ Hashie::Mash

    The simplest form.

    Parameters:

    • emitter (String)
    • params (optional, Hash)

      Characteristics like airline/airport/etc., your API key (if you didn't set it globally), timeframe, compliance, etc.

    Options Hash (params):

    • :timeframe (Timeframe) — default: Timeframe.this_year

      What time period to focus the calculation on. See timeframe documentation.

    • :comply (Array<Symbol>) — default: []

      What calculation protocols to require.

    • characteristic (String, Numeric)

      Pieces of data about an emitter. The Flight characteristics API lists valid keys like :aircraft, :origin_airport, etc.

    Returns:

    • (Hashie::Mash)

      The API response, contained in an easy-to-use Hashie::Mash

  • .query(obj) ⇒ Hashie::Mash

    Pass in a single query-able object.

    Parameters:

    • obj (#as_impact_query)

      An object that responds to #as_impact_query, generally because you've declared Carbon::ClassMethods#emit_as on its parent class.

    Returns:

    • (Hashie::Mash)

      The API response, contained in an easy-to-use Hashie::Mash

  • .query(array) ⇒ Hash{Object => Hashie::Mash}

    Get impact estimates for multiple query-able objects concurrently.

    Parameters:

    • array (Array<Array, #as_impact_query>)

      An array of plain queries and/or objects that respond to #as_impact_query.

    Returns:

    • (Hash{Object => Hashie::Mash})

      A Hash of Hashie::Mash objects, keyed on the original query object.

Raises:

  • (ArgumentError)

    If your arguments don't match any of the method signatures.

  • (ArgumentError)

    If you try to pass a block - you probably want +Carbon.query(array).each {}+ or something.



137
138
139
140
# File 'lib/carbon.rb', line 137

def Carbon.query(*args)
  raise ::ArgumentError, "Don't pass a block directly - instead use Carbon.query(array).each (for example)." if block_given?
  Query.perform(*args)
end

Instance Method Details

#as_impact_query(extra_params = {}) ⇒ Array

A query like what you could pass into Carbon.query.

Parameters:

  • extra_params (Hash) (defaults to: {})

    Anything you want to override.

Options Hash (extra_params):

  • :timeframe (Timeframe)
  • :comply (Array<Symbol>)
  • :key (String)

    In case you didn't define it globally, or want to use a different one here.

  • characteristic (String, Numeric)

    Override pieces of data about an emitter.

Returns:

  • (Array)

    Something you could pass into Carbon.query.



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/carbon.rb', line 208

def as_impact_query(extra_params = {})
  registration = Registry.instance[self.class.name]
  params = registration.characteristics.inject({}) do |memo, (method_id, translation_options)|
    k = translation_options.has_key?(:as) ? translation_options[:as] : method_id
    if translation_options.has_key?(:key)
      k = "#{k}[#{translation_options[:key]}]"
    end
    v = if translation_options.has_key?(:blk)
      translation_options[:blk].call self
    else
      send method_id
    end
    if v.present?
      memo[k] = v
    end
    memo
  end
  params.merge! extra_params
  if Carbon.key and not params.has_key?(:key)
    params[:key] = Carbon.key
  end
  [ registration.emitter, params ]
end

#impact(extra_params = {}) ⇒ Hashie::Mash

Get an impact estimate from Brighter Planet CM1; high-level convenience method that requires a Carbon::ClassMethods#emit_as block.

You get this when you include Carbon in a class.

See query for an explanation of the return value, a Hashie::Mash.

Examples:

Getting impact estimate for MyFlight

?> my_flight = MyFlight.new([...])
=> #<MyFlight [...]>
?> my_impact = my_flight.impact(:timeframe => Timeframe.new(:year => 2009))
=> #<Hashie::Mash [...]>
?> my_impact.decisions.carbon.object.value
=> 1014.92
?> my_impact.decisions.carbon.object.units
=> "kilograms"
?> my_impact.methodology
=> "http://impact.brighterplanet.com/flights?[...]"

Parameters:

  • extra_params (Hash) (defaults to: {})

    Anything you want to override.

Options Hash (extra_params):

  • :timeframe (Timeframe)
  • :comply (Array<Symbol>)
  • :key (String)

    In case you didn't define it globally, or want to use a different one here.

  • characteristic (String, Numeric)

    Override pieces of data about an emitter.

Returns:

  • (Hashie::Mash)


258
259
260
261
# File 'lib/carbon.rb', line 258

def impact(extra_params = {})
  plain_query = as_impact_query extra_params
  Carbon.query(*plain_query)
end