carbon 2.2.1 → 2.2.2
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.
- data/CHANGELOG +11 -0
- data/lib/carbon.rb +53 -36
- data/lib/carbon/future.rb +13 -9
- data/lib/carbon/version.rb +1 -1
- data/test/carbon_test.rb +34 -17
- metadata +52 -17
data/CHANGELOG
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
2.2.2 / 2012-04-05
|
2
|
+
|
3
|
+
* Enhancements
|
4
|
+
|
5
|
+
* Allow choosing domain (API endpoint)
|
6
|
+
* Slightly improved method signature explanations: query_array -> plain_query, o -> obj, os -> array
|
7
|
+
|
8
|
+
* Bug fixes
|
9
|
+
|
10
|
+
* Actually send keys set with Carbon.key
|
11
|
+
|
1
12
|
2.2.1 / 2012-03-21
|
2
13
|
|
3
14
|
* Enhancements
|
data/lib/carbon.rb
CHANGED
@@ -4,13 +4,17 @@ require 'carbon/registry'
|
|
4
4
|
require 'carbon/future'
|
5
5
|
|
6
6
|
module Carbon
|
7
|
-
DOMAIN = 'http://impact.brighterplanet.com'
|
7
|
+
DOMAIN = 'http://impact.brighterplanet.com'.freeze
|
8
8
|
CONCURRENCY = 16
|
9
9
|
|
10
10
|
# @private
|
11
11
|
# Make sure there are no warnings about class vars.
|
12
12
|
@@key = nil unless defined?(@@key)
|
13
13
|
|
14
|
+
# @private
|
15
|
+
# Make sure there are no warnings about class vars.
|
16
|
+
@@domain = nil unless defined?(@@domain)
|
17
|
+
|
14
18
|
# Set the Brighter Planet API key that you can get from http://keys.brighterplanet.com
|
15
19
|
#
|
16
20
|
# @param [String] key The alphanumeric key.
|
@@ -28,6 +32,23 @@ module Carbon
|
|
28
32
|
@@key
|
29
33
|
end
|
30
34
|
|
35
|
+
# Set an alternate API endpoint. You probably shouldn't do this.
|
36
|
+
#
|
37
|
+
# @param [String] domain ("http://impact.brighterplanet.com") The API endpoint
|
38
|
+
#
|
39
|
+
# @return [nil]
|
40
|
+
def Carbon.domain=(domain)
|
41
|
+
@@domain = domain
|
42
|
+
nil
|
43
|
+
end
|
44
|
+
|
45
|
+
# Where we send queries.
|
46
|
+
#
|
47
|
+
# @return [String] The API endpoint.
|
48
|
+
def Carbon.domain
|
49
|
+
@@domain || DOMAIN
|
50
|
+
end
|
51
|
+
|
31
52
|
# 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+.
|
32
53
|
#
|
33
54
|
# Return values are {http://rdoc.info/github/intridea/hashie/Hashie/Mash Hashie::Mash} objects because they are a simple way to access a deeply nested response.
|
@@ -50,7 +71,7 @@ module Carbon
|
|
50
71
|
# timeframe.startDate
|
51
72
|
#
|
52
73
|
# @overload query(emitter, params)
|
53
|
-
#
|
74
|
+
# The simplest form.
|
54
75
|
# @param [String] emitter The {http://impact.brighterplanet.com/emitters.json emitter name}.
|
55
76
|
# @param [optional, Hash] params Characteristics like airline/airport/etc., your API key (if you didn't set it globally), timeframe, compliance, etc.
|
56
77
|
# @option params [Timeframe] :timeframe (Timeframe.this_year) What time period to focus the calculation on. See {https://github.com/rossmeissl/timeframe timeframe} documentation.
|
@@ -58,18 +79,20 @@ module Carbon
|
|
58
79
|
# @option params [String, Numeric] <i>characteristic</i> Pieces of data about an emitter. The {http://impact.brighterplanet.com/flights/options Flight characteristics API} lists valid keys like +:aircraft+, +:origin_airport+, etc.
|
59
80
|
# @return [Hashie::Mash] The API response, contained in an easy-to-use +Hashie::Mash+
|
60
81
|
#
|
61
|
-
# @overload query(
|
82
|
+
# @overload query(obj)
|
62
83
|
# Pass in a single query-able object.
|
63
|
-
# @param [#as_impact_query]
|
84
|
+
# @param [#as_impact_query] obj An object that responds to +#as_impact_query+, generally because you've declared {Carbon::ClassMethods#emit_as} on its parent class.
|
64
85
|
# @return [Hashie::Mash] The API response, contained in an easy-to-use +Hashie::Mash+
|
65
86
|
#
|
66
|
-
# @overload query(
|
67
|
-
# Get
|
68
|
-
# @param [Array<Array, #as_impact_query>]
|
87
|
+
# @overload query(array)
|
88
|
+
# Get impact estimates for multiple query-able objects concurrently.
|
89
|
+
# @param [Array<Array, #as_impact_query>] array An array of plain queries and/or objects that respond to +#as_impact_query+.
|
69
90
|
# @return [Hash{Object => Hashie::Mash}] A +Hash+ of +Hashie::Mash+ objects, keyed on the original query object.
|
70
91
|
#
|
71
92
|
# @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!
|
72
93
|
#
|
94
|
+
# @note +[emitter, params]+ is called a "plain query."
|
95
|
+
#
|
73
96
|
# @raise [ArgumentError] If your arguments don't match any of the method signatures.
|
74
97
|
#
|
75
98
|
# @example A flight taken in 2009
|
@@ -105,29 +128,23 @@ module Carbon
|
|
105
128
|
# Carbon.query(queries)
|
106
129
|
#
|
107
130
|
# @example Flights and cars (concurrently, as query-able objects)
|
108
|
-
# Carbon.query(MyFlight.all+MyCar.all)
|
109
|
-
#
|
110
|
-
# @example Cars month-by-month (note that you won't get MyCar objects back, you'll get Arrays back. This will be fixed soon.)
|
111
|
-
# cars_by_month = MyCar.all.inject([]) do |memo, my_car|
|
112
|
-
# months.each do |first_day_of_the_month|
|
113
|
-
# my_car.as_impact_query(:date => first_day_of_the_month)
|
114
|
-
# end
|
131
|
+
# Carbon.query(MyFlight.all+MyCar.all).each do |car_or_flight, impact|
|
132
|
+
# puts "Carbon emitter by #{car_or_flight} was #{impact.decisions.carbon.object.value.round(1)}"
|
115
133
|
# end
|
116
|
-
# Carbon.query(cars_by_month)
|
117
134
|
def Carbon.query(*args)
|
118
135
|
case Carbon.method_signature(*args)
|
119
|
-
when :
|
120
|
-
|
121
|
-
future = Future.wrap
|
136
|
+
when :plain_query
|
137
|
+
plain_query = args
|
138
|
+
future = Future.wrap plain_query
|
122
139
|
future.result
|
123
|
-
when :
|
124
|
-
|
125
|
-
future = Future.wrap
|
140
|
+
when :obj
|
141
|
+
obj = args.first
|
142
|
+
future = Future.wrap obj
|
126
143
|
future.result
|
127
|
-
when :
|
128
|
-
|
129
|
-
futures =
|
130
|
-
future = Future.wrap
|
144
|
+
when :array
|
145
|
+
array = args.first
|
146
|
+
futures = array.map do |obj|
|
147
|
+
future = Future.wrap obj
|
131
148
|
future.multi!
|
132
149
|
future
|
133
150
|
end
|
@@ -136,13 +153,13 @@ module Carbon
|
|
136
153
|
memo
|
137
154
|
end
|
138
155
|
else
|
139
|
-
raise ::ArgumentError, "
|
156
|
+
raise ::ArgumentError, "You must pass one plain query, or one object that responds to #as_impact_query, or an array of such objects. Please check the docs!"
|
140
157
|
end
|
141
158
|
end
|
142
159
|
|
143
160
|
# Determine if a variable is a +[emitter, param]+ style "query"
|
144
161
|
# @private
|
145
|
-
def Carbon.
|
162
|
+
def Carbon.is_plain_query?(query)
|
146
163
|
return false unless query.is_a?(::Array)
|
147
164
|
return false unless query.first.is_a?(::String) or query.first.is_a?(::Symbol)
|
148
165
|
return true if query.length == 1
|
@@ -156,20 +173,20 @@ module Carbon
|
|
156
173
|
first_arg = args.first
|
157
174
|
case args.length
|
158
175
|
when 1
|
159
|
-
if
|
176
|
+
if is_plain_query?(args)
|
160
177
|
# query('Flight')
|
161
|
-
:
|
178
|
+
:plain_query
|
162
179
|
elsif first_arg.respond_to?(:as_impact_query)
|
163
180
|
# query(my_flight)
|
164
|
-
:
|
165
|
-
elsif first_arg.is_a?(::Array) and first_arg.all? { |
|
181
|
+
:obj
|
182
|
+
elsif first_arg.is_a?(::Array) and first_arg.all? { |obj| obj.respond_to?(:as_impact_query) or is_plain_query?(obj) }
|
166
183
|
# query([my_flight, my_flight])
|
167
|
-
:
|
184
|
+
:array
|
168
185
|
end
|
169
186
|
when 2
|
170
|
-
if
|
187
|
+
if is_plain_query?(args)
|
171
188
|
# query('Flight', :origin_airport => 'LAX')
|
172
|
-
:
|
189
|
+
:plain_query
|
173
190
|
end
|
174
191
|
end
|
175
192
|
end
|
@@ -287,8 +304,8 @@ module Carbon
|
|
287
304
|
# ?> my_impact.methodology
|
288
305
|
# => "http://impact.brighterplanet.com/flights?[...]"
|
289
306
|
def impact(extra_params = {})
|
290
|
-
|
291
|
-
future = Future.wrap
|
307
|
+
plain_query = as_impact_query extra_params
|
308
|
+
future = Future.wrap plain_query
|
292
309
|
future.result
|
293
310
|
end
|
294
311
|
end
|
data/lib/carbon/future.rb
CHANGED
@@ -8,18 +8,18 @@ module Carbon
|
|
8
8
|
# @private
|
9
9
|
class Future
|
10
10
|
class << self
|
11
|
-
def wrap(
|
12
|
-
future = if
|
13
|
-
new(*
|
11
|
+
def wrap(plain_query_or_o)
|
12
|
+
future = if plain_query_or_o.is_a?(::Array)
|
13
|
+
new(*plain_query_or_o)
|
14
14
|
else
|
15
|
-
new(*
|
15
|
+
new(*plain_query_or_o.as_impact_query)
|
16
16
|
end
|
17
|
-
future.object =
|
17
|
+
future.object = plain_query_or_o
|
18
18
|
future
|
19
19
|
end
|
20
20
|
|
21
21
|
def single(future)
|
22
|
-
uri = ::URI.parse("#{
|
22
|
+
uri = ::URI.parse("#{future.domain}/#{future.emitter.underscore.pluralize}.json")
|
23
23
|
raw_result = ::Net::HTTP.post_form(uri, future.params)
|
24
24
|
future.finalize raw_result.code.to_i, raw_result.body
|
25
25
|
future
|
@@ -41,14 +41,18 @@ module Carbon
|
|
41
41
|
|
42
42
|
attr_reader :emitter
|
43
43
|
attr_reader :params
|
44
|
+
attr_reader :domain
|
44
45
|
|
45
46
|
attr_accessor :object
|
46
47
|
|
47
48
|
def initialize(emitter, params = {})
|
48
49
|
@result = nil
|
49
50
|
@emitter = emitter
|
50
|
-
params = params || {}
|
51
|
-
params.
|
51
|
+
params = params.dup || {}
|
52
|
+
@domain = params.delete(:domain) || Carbon.domain
|
53
|
+
if Carbon.key and not params.has_key?(:key)
|
54
|
+
params[:key] = Carbon.key
|
55
|
+
end
|
52
56
|
@params = params
|
53
57
|
end
|
54
58
|
|
@@ -90,7 +94,7 @@ module Carbon
|
|
90
94
|
cache_method :result, 3_600 # one hour
|
91
95
|
|
92
96
|
def as_cache_key
|
93
|
-
[ @emitter, @params ]
|
97
|
+
[ @domain, @emitter, @params ]
|
94
98
|
end
|
95
99
|
|
96
100
|
def hash
|
data/lib/carbon/version.rb
CHANGED
data/test/carbon_test.rb
CHANGED
@@ -73,9 +73,20 @@ describe Carbon do
|
|
73
73
|
end
|
74
74
|
it "sends key properly" do
|
75
75
|
with_web_mock do
|
76
|
-
WebMock.stub_request(:post, 'http://impact.brighterplanet.com/flights.json').with(:key => 'carbon_test').to_return(:status => 500, :body => '
|
77
|
-
|
78
|
-
|
76
|
+
WebMock.stub_request(:post, 'http://impact.brighterplanet.com/flights.json').with(:body => hash_including(:key => 'carbon_test')).to_return(:status => 500, :body => 'default')
|
77
|
+
WebMock.stub_request(:post, 'http://impact.brighterplanet.com/flights.json').with(:body => hash_including(:key => 'carbon_test1')).to_return(:status => 500, :body => 'A')
|
78
|
+
WebMock.stub_request(:post, 'http://impact.brighterplanet.com/flights.json').with(:body => hash_including(:key => 'carbon_test2')).to_return(:status => 500, :body => 'B')
|
79
|
+
Carbon.query('Flight', :key => 'carbon_test2').errors.first.must_equal 'B'
|
80
|
+
Carbon.query('Flight').errors.first.must_equal 'default'
|
81
|
+
Carbon.query('Flight', :key => 'carbon_test1').errors.first.must_equal 'A'
|
82
|
+
end
|
83
|
+
end
|
84
|
+
it "allows choosing domain" do
|
85
|
+
with_web_mock do
|
86
|
+
WebMock.stub_request(:post, 'http://impact.brighterplanet.com/flights.json').to_return(:status => 500, :body => 'used impact')
|
87
|
+
WebMock.stub_request(:post, 'http://foo.brighterplanet.com/flights.json').to_return(:status => 500, :body => 'used foo')
|
88
|
+
Carbon.query('Flight', :domain => 'http://foo.brighterplanet.com').errors.first.must_equal 'used foo'
|
89
|
+
Carbon.query('Flight').errors.first.must_equal 'used impact'
|
79
90
|
end
|
80
91
|
end
|
81
92
|
it "raises ArgumentError if args are bad" do
|
@@ -116,7 +127,13 @@ describe Carbon do
|
|
116
127
|
Timeout.timeout(0.5) { Carbon.query([]) }.must_equal(Hash.new)
|
117
128
|
end
|
118
129
|
it "can be used on objects that respond to #as_impact_query" do
|
119
|
-
|
130
|
+
a = MyNissanAltima.new(2001)
|
131
|
+
b = MyNissanAltima.new(2006)
|
132
|
+
ab1 = Carbon.query([a, b])
|
133
|
+
ab2 = Carbon.query([a.as_impact_query, b.as_impact_query])
|
134
|
+
ab1.each do |k, v|
|
135
|
+
ab2[k.as_impact_query].must_equal v
|
136
|
+
end
|
120
137
|
end
|
121
138
|
it "runs multiple queries at once" do
|
122
139
|
reference_results = @queries.inject({}) do |memo, query|
|
@@ -197,22 +214,22 @@ describe Carbon do
|
|
197
214
|
|
198
215
|
describe :method_signature do
|
199
216
|
it "recognizes emitter_param" do
|
200
|
-
Carbon.method_signature('Flight').must_equal :
|
201
|
-
Carbon.method_signature('Flight', :origin_airport => 'LAX').must_equal :
|
202
|
-
Carbon.method_signature(:flight).must_equal :
|
203
|
-
Carbon.method_signature(:flight, :origin_airport => 'LAX').must_equal :
|
217
|
+
Carbon.method_signature('Flight').must_equal :plain_query
|
218
|
+
Carbon.method_signature('Flight', :origin_airport => 'LAX').must_equal :plain_query
|
219
|
+
Carbon.method_signature(:flight).must_equal :plain_query
|
220
|
+
Carbon.method_signature(:flight, :origin_airport => 'LAX').must_equal :plain_query
|
204
221
|
end
|
205
|
-
it "recognizes
|
206
|
-
Carbon.method_signature(MyNissanAltima.new(2006)).must_equal :
|
222
|
+
it "recognizes obj" do
|
223
|
+
Carbon.method_signature(MyNissanAltima.new(2006)).must_equal :obj
|
207
224
|
end
|
208
|
-
it "recognizes
|
209
|
-
Carbon.method_signature([MyNissanAltima.new(2001)]).must_equal :
|
210
|
-
Carbon.method_signature([['Flight']]).must_equal :
|
211
|
-
Carbon.method_signature([['Flight', {:origin_airport => 'LAX'}]]).must_equal :
|
212
|
-
Carbon.method_signature([['Flight'], ['Flight']]).must_equal :
|
213
|
-
Carbon.method_signature([['Flight', {:origin_airport => 'LAX'}], ['Flight', {:origin_airport => 'LAX'}]]).must_equal :
|
225
|
+
it "recognizes array" do
|
226
|
+
Carbon.method_signature([MyNissanAltima.new(2001)]).must_equal :array
|
227
|
+
Carbon.method_signature([['Flight']]).must_equal :array
|
228
|
+
Carbon.method_signature([['Flight', {:origin_airport => 'LAX'}]]).must_equal :array
|
229
|
+
Carbon.method_signature([['Flight'], ['Flight']]).must_equal :array
|
230
|
+
Carbon.method_signature([['Flight', {:origin_airport => 'LAX'}], ['Flight', {:origin_airport => 'LAX'}]]).must_equal :array
|
214
231
|
[MyNissanAltima.new(2006), ['Flight'], ['Flight', {:origin_airport => 'LAX'}]].permutation.each do |p|
|
215
|
-
Carbon.method_signature(p).must_equal :
|
232
|
+
Carbon.method_signature(p).must_equal :array
|
216
233
|
end
|
217
234
|
end
|
218
235
|
it "does not want splats for concurrent queries" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: carbon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.2.
|
4
|
+
version: 2.2.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-04-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,15 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: multi_json
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
35
|
- - ! '>='
|
@@ -32,10 +37,15 @@ dependencies:
|
|
32
37
|
version: '0'
|
33
38
|
type: :runtime
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
36
46
|
- !ruby/object:Gem::Dependency
|
37
47
|
name: hashie
|
38
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
39
49
|
none: false
|
40
50
|
requirements:
|
41
51
|
- - ! '>='
|
@@ -43,10 +53,15 @@ dependencies:
|
|
43
53
|
version: '0'
|
44
54
|
type: :runtime
|
45
55
|
prerelease: false
|
46
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
47
62
|
- !ruby/object:Gem::Dependency
|
48
63
|
name: cache_method
|
49
|
-
requirement:
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
50
65
|
none: false
|
51
66
|
requirements:
|
52
67
|
- - ! '>='
|
@@ -54,10 +69,15 @@ dependencies:
|
|
54
69
|
version: '0'
|
55
70
|
type: :runtime
|
56
71
|
prerelease: false
|
57
|
-
version_requirements:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
58
78
|
- !ruby/object:Gem::Dependency
|
59
79
|
name: bombshell
|
60
|
-
requirement:
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
61
81
|
none: false
|
62
82
|
requirements:
|
63
83
|
- - ! '>='
|
@@ -65,10 +85,15 @@ dependencies:
|
|
65
85
|
version: '0'
|
66
86
|
type: :runtime
|
67
87
|
prerelease: false
|
68
|
-
version_requirements:
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
69
94
|
- !ruby/object:Gem::Dependency
|
70
95
|
name: conversions
|
71
|
-
requirement:
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
72
97
|
none: false
|
73
98
|
requirements:
|
74
99
|
- - ! '>='
|
@@ -76,10 +101,15 @@ dependencies:
|
|
76
101
|
version: '0'
|
77
102
|
type: :runtime
|
78
103
|
prerelease: false
|
79
|
-
version_requirements:
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
80
110
|
- !ruby/object:Gem::Dependency
|
81
111
|
name: brighter_planet_metadata
|
82
|
-
requirement:
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
83
113
|
none: false
|
84
114
|
requirements:
|
85
115
|
- - ! '>='
|
@@ -87,7 +117,12 @@ dependencies:
|
|
87
117
|
version: '0'
|
88
118
|
type: :runtime
|
89
119
|
prerelease: false
|
90
|
-
version_requirements:
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
91
126
|
description: Brighter Planet API client for Ruby
|
92
127
|
email:
|
93
128
|
- seamus@abshere.net
|
@@ -139,7 +174,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
139
174
|
version: '0'
|
140
175
|
requirements: []
|
141
176
|
rubyforge_project:
|
142
|
-
rubygems_version: 1.8.
|
177
|
+
rubygems_version: 1.8.21
|
143
178
|
signing_key:
|
144
179
|
specification_version: 3
|
145
180
|
summary: Brighter Planet API client for Ruby
|