carbon 0.1.6 → 0.2.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.
@@ -6,35 +6,41 @@ By querying the web service, it can estimate the carbon emissions of many real-l
6
6
 
7
7
  == Quick start
8
8
 
9
- *You'll need a Brighter Planet API key. See the "API keys" section below for details.*
9
+ <b>You'll need a Brighter Planet API key. See the "API keys" section below for details.</b>
10
10
 
11
11
  First get the gem:
12
12
 
13
13
  $ gem install carbon
14
14
 
15
- Carbon works by extending any Ruby class you're using to represent an emission source. For instance, let's say you have a Ruby class <tt>RentalCar</tt> that represents a rental car on your lot. (Note that ActiveRecord models work great with carbon.)
15
+ Carbon works by extending any Ruby class you're using to represent an emission source. For instance, let's say you have a Ruby class <tt>RentalCar</tt> that represents a rental car on your lot. (Note that ActiveRecord models work great with this gem.)
16
16
 
17
17
  class RentalCar
18
- attr_accessor :year, :make, :model, :fuel_efficiency, :daily_distance_average, :purchase_date, :retirement_date
18
+ attr_accessor :model, :model_year, :fuel_economy
19
+ class Make
20
+ attr_accessor :name
21
+ def to_param
22
+ name
23
+ end
24
+ end
25
+ def make
26
+ @make ||= Make.new
27
+ end
19
28
  end
20
29
 
21
30
  In order to calculate carbon emissions, we need to map the car's relevant attributes to characteristics that the {web service}[http://carbon.brighterplanet.com] will recognize. In this case, a review of the available characteristics for Automobile[http://carbon.brighterplanet.com/automobiles/options] yields the following map:
22
31
 
23
32
  class RentalCar
33
+ # [...]
24
34
  include Carbon
25
- [...]
26
35
  emit_as :automobile do
27
- provide :model_year, :as => :year # you say tomayto, I say tomahto
28
36
  provide :make
29
37
  provide :model
30
- provide :fuel_efficiency
31
- provide :daily_distance_estimate, :as => daily_distance_average
32
- provide :acquisition, :as => :purchase_date
33
- provide :retirement, :as => :retirement_date
38
+ provide :model_year
39
+ provide :fuel_economy, :as => :fuel_efficiency
34
40
  end
35
41
  end
36
42
 
37
- When you want to calculate emissions, simply call <tt>RentalCar</tt>#<tt>emission</tt>. Memoize this method on your class or store the result; <tt>#emision</tt> makes a web service call every time it is invoked.
43
+ When you want to calculate emissions, simply call <tt>RentalCar#emission</tt>.
38
44
 
39
45
  > my_car = RentalCar.new([...])
40
46
  => #<RentalCar [...]>
@@ -49,7 +55,7 @@ When you want to calculate emissions, simply call <tt>RentalCar</tt>#<tt>emissio
49
55
 
50
56
  === Asynchronous queries
51
57
 
52
- To request an emission estimate asynchronously, simply pass an URL as the +:callback+ option to +#emission+:
58
+ To request an emission estimate asynchronously, simply pass an URL as the <tt>:callback</tt> option to <tt>#emission</tt>:
53
59
 
54
60
  > RentalCar.new.emission :callback => http://example.com/my/callback/handler
55
61
 
data/Rakefile CHANGED
@@ -5,14 +5,15 @@ begin
5
5
  require 'jeweler'
6
6
  Jeweler::Tasks.new do |gemspec|
7
7
  gemspec.name = 'carbon'
8
- gemspec.summary = %q{A gem for calculating carbon footprints using Brighter Planet's Carbon Middleware service}
9
- gemspec.description = %q{Carbon allows you to easily calculate the carbon footprint of various activities. This is an API for the Brighter Planet Carbon Middleware service.}
8
+ gemspec.summary = %q{Carbon is a Ruby API wrapper for the Brighter Planet emission estimate web service (http://carbon.brighterplanet.com).}
9
+ gemspec.description = %q{Carbon is a Ruby API wrapper for the Brighter Planet emission estimate web service (http://carbon.brighterplanet.com). By querying the web service, it can estimate the carbon emissions of many real-life objects, such as cars and houses, based on particular attributes that they may have.}
10
10
  gemspec.email = 'derek.kastner@brighterplanet.com'
11
11
  gemspec.homepage = 'http://carbon.brighterplanet.com/libraries'
12
- gemspec.authors = ['Derek Kastner', 'Seamus Abshere']
12
+ gemspec.authors = ['Derek Kastner', 'Seamus Abshere', 'Andy Rossmeissl']
13
13
  gemspec.add_dependency 'activesupport', '>=2.3.5'
14
14
  gemspec.add_dependency 'nap', '>=0.4'
15
15
  gemspec.add_dependency 'timeframe', '>=0.0.7'
16
+ gemspec.add_dependency 'blockenspiel', '>=0.3.2'
16
17
 
17
18
  gemspec.add_development_dependency 'fakeweb', '>=1.2.8'
18
19
  # sabshere 7/16/10 if you're having trouble running specs, try "rspec spec" and/or "sudo gem install rspec --pre"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.6
1
+ 0.2.0
@@ -5,12 +5,12 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{carbon}
8
- s.version = "0.1.6"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Derek Kastner", "Seamus Abshere"]
12
- s.date = %q{2010-07-20}
13
- s.description = %q{Carbon allows you to easily calculate the carbon footprint of various activities. This is an API for the Brighter Planet Carbon Middleware service.}
11
+ s.authors = ["Derek Kastner", "Seamus Abshere", "Andy Rossmeissl"]
12
+ s.date = %q{2010-07-21}
13
+ s.description = %q{Carbon is a Ruby API wrapper for the Brighter Planet emission estimate web service (http://carbon.brighterplanet.com). By querying the web service, it can estimate the carbon emissions of many real-life objects, such as cars and houses, based on particular attributes that they may have.}
14
14
  s.email = %q{derek.kastner@brighterplanet.com}
15
15
  s.extra_rdoc_files = [
16
16
  "README.rdoc"
@@ -35,7 +35,7 @@ Gem::Specification.new do |s|
35
35
  s.rdoc_options = ["--charset=UTF-8"]
36
36
  s.require_paths = ["lib"]
37
37
  s.rubygems_version = %q{1.3.7}
38
- s.summary = %q{A gem for calculating carbon footprints using Brighter Planet's Carbon Middleware service}
38
+ s.summary = %q{Carbon is a Ruby API wrapper for the Brighter Planet emission estimate web service (http://carbon.brighterplanet.com).}
39
39
  s.test_files = [
40
40
  "spec/lib/carbon_spec.rb",
41
41
  "spec/spec_helper.rb"
@@ -49,12 +49,14 @@ Gem::Specification.new do |s|
49
49
  s.add_runtime_dependency(%q<activesupport>, [">= 2.3.5"])
50
50
  s.add_runtime_dependency(%q<nap>, [">= 0.4"])
51
51
  s.add_runtime_dependency(%q<timeframe>, [">= 0.0.7"])
52
+ s.add_runtime_dependency(%q<blockenspiel>, [">= 0.3.2"])
52
53
  s.add_development_dependency(%q<fakeweb>, [">= 1.2.8"])
53
54
  s.add_development_dependency(%q<rspec>, [">= 2.0.0.beta.17"])
54
55
  else
55
56
  s.add_dependency(%q<activesupport>, [">= 2.3.5"])
56
57
  s.add_dependency(%q<nap>, [">= 0.4"])
57
58
  s.add_dependency(%q<timeframe>, [">= 0.0.7"])
59
+ s.add_dependency(%q<blockenspiel>, [">= 0.3.2"])
58
60
  s.add_dependency(%q<fakeweb>, [">= 1.2.8"])
59
61
  s.add_dependency(%q<rspec>, [">= 2.0.0.beta.17"])
60
62
  end
@@ -62,6 +64,7 @@ Gem::Specification.new do |s|
62
64
  s.add_dependency(%q<activesupport>, [">= 2.3.5"])
63
65
  s.add_dependency(%q<nap>, [">= 0.4"])
64
66
  s.add_dependency(%q<timeframe>, [">= 0.0.7"])
67
+ s.add_dependency(%q<blockenspiel>, [">= 0.3.2"])
65
68
  s.add_dependency(%q<fakeweb>, [">= 1.2.8"])
66
69
  s.add_dependency(%q<rspec>, [">= 2.0.0.beta.17"])
67
70
  end
@@ -9,7 +9,6 @@ require 'active_support/version'
9
9
  active_support/core_ext/hash/keys
10
10
  active_support/core_ext/hash/reverse_merge
11
11
  active_support/core_ext/object/to_query
12
- active_support/core_ext/array/wrap
13
12
  active_support/inflector/inflections
14
13
  active_support/json/decoding
15
14
  }.each do |active_support_3_requirement|
@@ -78,9 +77,7 @@ module Carbon
78
77
 
79
78
  # Returns an emission estimate.
80
79
  #
81
- # Note: <b>You need to take care of storing the return value to a local variable!</b> Every call to <tt>emission</tt> runs a query.
82
- #
83
- # Note also: please see the README about exceptions that you should watch out for.
80
+ # Note: please see the README about <b>exceptions that you should watch out for</b>.
84
81
  #
85
82
  # You can use it like a number...
86
83
  # > my_car.emission + 5.1
@@ -21,30 +21,34 @@ module Carbon
21
21
  end
22
22
  # Indicate that you will send in a piece of data about the emitter.
23
23
  #
24
- # If you don't use the <tt>:as</tt> option, the name of the getter method will be guessed.
24
+ # Two general rules:
25
+ # * Take note of what Brighter Planet expects to receive. If you send <tt>fuel_economy</tt> and we're expecting <tt>fuel_efficiency</tt>, we won't understand! (Hint: use the <tt>:as</tt> option.)
26
+ # * Make sure <tt>#to_param</tt> is set up. The gem always calls <tt>#to_param</tt> before sending, so that's your change to key things by "EPA code" (fictional) or whatever else you want. (Hint: use the <tt>:key</tt> option.)
25
27
  #
26
28
  # There are two optional parameters:
27
- # * <tt>:of</tt> - the owner of a nested characteristic. So to send <tt>model[name]</tt> you write <tt>provide :name, :of => :model</tt>
28
- # * <tt>:as</tt> - the local getter name. So if Brighter Planet expects <tt>fuel_efficiency</tt>, and you only have <tt>fuel_economy</tt>, you can write <tt>provide :fuel_efficiency, :as => :fuel_economy</tt>.
29
+ # * <tt>:as</tt> - if Brighter Planet expects <tt>fuel_efficiency</tt>, and you say <tt>mpg</tt>, you can write <tt>provide :mpg, :as => :fuel_efficiency</tt>. This will result in a query like <tt>?fuel_efficiency=XYZ</tt>.
30
+ # * <tt>:key</tt> - if Brighter Planet expects a make's name ("Nissan") and you want to look things up by (fictional) "EPA code", you could say <tt>provide :make, :key => :epa_code</tt>. This will result in a query like <tt>?make[epa_code]=ABC</tt>.
29
31
  #
30
- # For example:
31
- #
32
- # emit_as :automobile do
33
- # # Official Brighter Planet characteristic name Your name for it
34
- # provide :model, :as => :carline_class # model carline_class
35
- # provide :name, :of => :make, :as => :mfr_name # make[name] mfr_name
32
+ # # What's sent to Brighter Planet
33
+ # emit_as :automobile do
34
+ # provide :mpg, :as => :fuel_efficiency # fuel_efficiency=my_car.mpg.to_param
35
+ # provide :make, :key => :epa_code # make[epa_code]=my_car.make.to_param
36
+ # # or really shaking things up...
37
+ # provide :manufacturer, :as => :make, :key => :epa_code # make[epa_code]=my_car.manufacturer.to_param
36
38
  # end
39
+ #
40
+ # Note that no matter what you send to us, the gem always calls <b>to_param</b> on the emitter. In this example, it's up to you to make sure my_car.manufacturer.to_param returns an epa_code.
37
41
  def provide(attr_name, options = {})
38
42
  options = options.symbolize_keys
39
- characteristic = if options.has_key? :of
40
- # [ :mixer, :size ]
41
- [options[:of], attr_name]
43
+ characteristic = if options.has_key? :as
44
+ # [ :mpg, :fuel_efficiency ]
45
+ [attr_name, options[:as]]
42
46
  else
43
- # :oven_count
47
+ # :make
44
48
  attr_name
45
49
  end
46
- # translation_table[[:mixer,:size]] = 'mixer_size'
47
- translation_table[characteristic] = options[:as] || Array.wrap(characteristic).join('_')
50
+ # translation_table[:make] = 'epa_code'
51
+ translation_table[characteristic] = options[:key]
48
52
  end
49
53
  # japanese-style preferred
50
54
  alias :provides :provide
@@ -27,20 +27,27 @@ module Carbon
27
27
  # Returns the params hash that will be send to the emission estimate server.
28
28
  def params
29
29
  params = parent.emitter.class.carbon_base.translation_table.inject({}) do |memo, translation|
30
- characteristic, as = translation
31
- current_value = parent.emitter.send as
30
+ characteristic, key = translation
31
+ if characteristic.is_a? ::Array
32
+ current_value = parent.emitter.send characteristic[0]
33
+ as = characteristic[1]
34
+ else
35
+ current_value = parent.emitter.send characteristic
36
+ as = characteristic
37
+ end
38
+ current_value = current_value.to_param
32
39
  if current_value.present?
33
- if characteristic.is_a? Array # [:mixer, :size]
34
- memo[characteristic[0]] ||= {} # { :mixer => Hash.new }
35
- memo[characteristic[0]][characteristic[1]] = current_value # { :mixer => { :size => 'foo' }}
36
- else # :oven_count
37
- memo[characteristic] = current_value # { :oven_count => 'bar' }
40
+ if key
41
+ memo[as] ||= {}
42
+ memo[as][key] = current_value
43
+ else
44
+ memo[as] = current_value
38
45
  end
39
46
  end
40
47
  memo
41
48
  end
42
- params[:timeframe] = parent.timeframe
43
- params[:key] = parent.key
49
+ params[:timeframe] = parent.timeframe if parent.timeframe
50
+ params[:key] = parent.key if parent.key
44
51
  params
45
52
  end
46
53
  def realtime_url # :nodoc:
@@ -2,24 +2,41 @@ require 'spec_helper'
2
2
 
3
3
  class RentalCar
4
4
  include Carbon
5
- attr_accessor :make, :model, :model_year, :fuel_economy
5
+ attr_accessor :model, :model_year, :fuel_economy
6
+ class Make
7
+ attr_accessor :name
8
+ def to_param
9
+ name
10
+ end
11
+ end
12
+ def make
13
+ @make ||= Make.new
14
+ end
6
15
  emit_as :automobile do
7
16
  provide :make
8
17
  provide :model
9
18
  provide :model_year
10
- provide :fuel_efficiency, :as => :fuel_economy
19
+ provide :fuel_economy, :as => :fuel_efficiency
11
20
  end
12
21
  end
13
22
 
14
23
  class DonutFactory
15
24
  include Carbon
16
- attr_accessor :smokestack_size, :oven_count, :mixer_size, :mixer_wattage, :employees
25
+ attr_accessor :smokestack_size, :oven_count, :employees
26
+ class Mixer
27
+ attr_accessor :upc
28
+ def to_param
29
+ upc
30
+ end
31
+ end
32
+ def mixer
33
+ @mixer ||= Mixer.new
34
+ end
17
35
  emit_as :factory do
18
36
  provide :smokestack_size
19
37
  provide :oven_count
20
- provide :size, :of => :mixer
21
- provide :wattage, :of => :mixer
22
- provide :personnel, :as => :employees
38
+ provide :employees, :as => :personnel
39
+ provide :mixer, :key => :upc
23
40
  end
24
41
  end
25
42
 
@@ -60,19 +77,37 @@ describe Carbon do
60
77
  c.emission.should == 134.599
61
78
  c.emission.response.raw_request.object_id.should_not == first_raw_request.object_id
62
79
  end
80
+
81
+ it "should recalculate if parameters change (though the options hash)" do
82
+ c = RentalCar.new
83
+ c.model = 'Acura'
84
+ c.model_year = 2003
85
+ c.fuel_economy = 32
86
+ c.emission.should == 134.599
87
+ first_raw_request = c.emission.response.raw_request
88
+ c.emission(:timeframe => Timeframe.new(:year => 2009)).should == 134.599
89
+ c.emission.response.raw_request.object_id.should_not == first_raw_request.object_id
90
+ end
63
91
  end
64
92
 
65
93
  describe 'synchronous (realtime) requests' do
66
- it 'should handle complex attributes like mixer[size]' do
94
+ it 'should send simple params' do
95
+ d = DonutFactory.new
96
+ d.oven_count = 12_000
97
+ d.emission.request.body.should =~ /oven_count=12000/
98
+ end
99
+
100
+ it 'send complex params' do
67
101
  d = DonutFactory.new
68
- d.mixer_size = 20
69
- d.emission.request.body.should =~ /mixer\[size\]=20/
102
+ d.mixer.upc = 123
103
+ d.emission.request.body.should =~ /mixer\[upc\]=123/
70
104
  end
71
105
 
72
106
  it 'should not send attributes that are blank' do
73
107
  d = DonutFactory.new
74
- d.mixer_size = 20
108
+ d.mixer.upc = 123
75
109
  d.emission.request.body.should_not =~ /oven_count/
110
+ d.emission.request.body.should_not =~ /timeframe/
76
111
  end
77
112
 
78
113
  it 'should send the key' do
metadata CHANGED
@@ -5,18 +5,19 @@ version: !ruby/object:Gem::Version
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 1
9
- - 6
10
- version: 0.1.6
8
+ - 2
9
+ - 0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Derek Kastner
14
14
  - Seamus Abshere
15
+ - Andy Rossmeissl
15
16
  autorequire:
16
17
  bindir: bin
17
18
  cert_chain: []
18
19
 
19
- date: 2010-07-20 00:00:00 -05:00
20
+ date: 2010-07-21 00:00:00 -05:00
20
21
  default_executable:
21
22
  dependencies:
22
23
  - !ruby/object:Gem::Dependency
@@ -67,9 +68,25 @@ dependencies:
67
68
  type: :runtime
68
69
  version_requirements: *id003
69
70
  - !ruby/object:Gem::Dependency
70
- name: fakeweb
71
+ name: blockenspiel
71
72
  prerelease: false
72
73
  requirement: &id004 !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ hash: 23
79
+ segments:
80
+ - 0
81
+ - 3
82
+ - 2
83
+ version: 0.3.2
84
+ type: :runtime
85
+ version_requirements: *id004
86
+ - !ruby/object:Gem::Dependency
87
+ name: fakeweb
88
+ prerelease: false
89
+ requirement: &id005 !ruby/object:Gem::Requirement
73
90
  none: false
74
91
  requirements:
75
92
  - - ">="
@@ -81,11 +98,11 @@ dependencies:
81
98
  - 8
82
99
  version: 1.2.8
83
100
  type: :development
84
- version_requirements: *id004
101
+ version_requirements: *id005
85
102
  - !ruby/object:Gem::Dependency
86
103
  name: rspec
87
104
  prerelease: false
88
- requirement: &id005 !ruby/object:Gem::Requirement
105
+ requirement: &id006 !ruby/object:Gem::Requirement
89
106
  none: false
90
107
  requirements:
91
108
  - - ">="
@@ -99,8 +116,8 @@ dependencies:
99
116
  - 17
100
117
  version: 2.0.0.beta.17
101
118
  type: :development
102
- version_requirements: *id005
103
- description: Carbon allows you to easily calculate the carbon footprint of various activities. This is an API for the Brighter Planet Carbon Middleware service.
119
+ version_requirements: *id006
120
+ description: Carbon is a Ruby API wrapper for the Brighter Planet emission estimate web service (http://carbon.brighterplanet.com). By querying the web service, it can estimate the carbon emissions of many real-life objects, such as cars and houses, based on particular attributes that they may have.
104
121
  email: derek.kastner@brighterplanet.com
105
122
  executables: []
106
123
 
@@ -156,7 +173,7 @@ rubyforge_project:
156
173
  rubygems_version: 1.3.7
157
174
  signing_key:
158
175
  specification_version: 3
159
- summary: A gem for calculating carbon footprints using Brighter Planet's Carbon Middleware service
176
+ summary: Carbon is a Ruby API wrapper for the Brighter Planet emission estimate web service (http://carbon.brighterplanet.com).
160
177
  test_files:
161
178
  - spec/lib/carbon_spec.rb
162
179
  - spec/spec_helper.rb