calculated 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +0 -0
- data/LICENSE +20 -0
- data/ROADMAP.md +1 -0
- data/lib/calculated.rb +22 -0
- data/lib/calculated/answer_api_calls.rb +24 -0
- data/lib/calculated/generic_object_api_calls.rb +30 -0
- data/lib/calculated/logging.rb +41 -0
- data/lib/calculated/models/answer.rb +31 -0
- data/lib/calculated/models/characteristic.rb +18 -0
- data/lib/calculated/models/formula_input.rb +19 -0
- data/lib/calculated/models/generic_object.rb +34 -0
- data/lib/calculated/models/object_template.rb +48 -0
- data/lib/calculated/models/relatable_category.rb +23 -0
- data/lib/calculated/models/source.rb +14 -0
- data/lib/calculated/object_template_api_calls.rb +61 -0
- data/lib/calculated/relatable_category_api_calls.rb +38 -0
- data/lib/calculated/service.rb +51 -0
- data/lib/calculated/session.rb +106 -0
- data/lib/calculated/version.rb +3 -0
- metadata +153 -0
data/CHANGELOG.md
ADDED
File without changes
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Richard Hooker
|
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/ROADMAP.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Its coming
|
data/lib/calculated.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# requires
|
2
|
+
require "httparty"
|
3
|
+
require "hashie"
|
4
|
+
require "moneta"
|
5
|
+
require "moneta/memory"
|
6
|
+
|
7
|
+
|
8
|
+
require "calculated/generic_object_api_calls"
|
9
|
+
require "calculated/object_template_api_calls"
|
10
|
+
require "calculated/relatable_category_api_calls"
|
11
|
+
require "calculated/answer_api_calls"
|
12
|
+
require "calculated/session"
|
13
|
+
require "calculated/service"
|
14
|
+
require "calculated/logging"
|
15
|
+
|
16
|
+
require "calculated/models/characteristic"
|
17
|
+
require "calculated/models/formula_input"
|
18
|
+
require "calculated/models/generic_object"
|
19
|
+
require "calculated/models/object_template"
|
20
|
+
require "calculated/models/relatable_category"
|
21
|
+
require "calculated/models/source"
|
22
|
+
require "calculated/models/answer"
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Calculated
|
2
|
+
module AnswerApiCalls
|
3
|
+
|
4
|
+
# @param [String] id
|
5
|
+
# @param [Hash] params
|
6
|
+
# @return [Array<Calculated::Models::Answer>]
|
7
|
+
def answer_for_calculator(calculator_id, params = {})
|
8
|
+
api_call(:get, "/calculators/#{calculator_id}/answer", params) do |response|
|
9
|
+
Calculated::Models::Answer.new(response)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
# @param [String] id
|
15
|
+
# @param [Hash] params
|
16
|
+
# @return [Array<Calculated::Models::Answer>]
|
17
|
+
def answer_for_computation(compuation_id, params = {})
|
18
|
+
api_call(:get, "/computations/#{compuation_id}/answer", params) do |response|
|
19
|
+
Calculated::Models::Answer.new(response)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Calculated
|
2
|
+
module GenericObjectApiCalls
|
3
|
+
|
4
|
+
# @param [Hash] params
|
5
|
+
# @return [Array<Calculated::Models::GeneriObject>]
|
6
|
+
def generic_objects(params = {})
|
7
|
+
api_call(:get, "/generic_objects", params) do |response|
|
8
|
+
response["generic_objects"].map{|generic_object| Calculated::Models::GenericObject.new(generic_object)}
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# @param [String] id
|
13
|
+
# @param [Hash] params
|
14
|
+
# @return [Calculated::Models::GeneriObject
|
15
|
+
def generic_object(id, params = {})
|
16
|
+
api_call(:get, "/generic_objects/#{id}", params) do |response|
|
17
|
+
Calculated::Models::GenericObject.new(response["generic_object"])
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# @param [String] id
|
22
|
+
# @param [Hash] params
|
23
|
+
# @return [Array<Calculated::Models::FormulaInput>]
|
24
|
+
def formula_inputs_for_generic_object(id, params = {})
|
25
|
+
api_call(:get, "/generic_objects/#{id}/formula_inputs", params) do |response|
|
26
|
+
response["formula_inputs"].map{|formula_input| Calculated::Models::FormulaInput.new(formula_input)}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
module Calculated
|
3
|
+
@@logger = nil
|
4
|
+
def self.logger=(logger)
|
5
|
+
@@logger = logger
|
6
|
+
end
|
7
|
+
def self.logger
|
8
|
+
@@logger
|
9
|
+
end
|
10
|
+
|
11
|
+
module Logging
|
12
|
+
def self.log_calculated_api(method, path, options)
|
13
|
+
message = method
|
14
|
+
dump = format_da_dump(path, options)
|
15
|
+
if block_given?
|
16
|
+
result = nil
|
17
|
+
seconds = Benchmark.realtime { result = yield }
|
18
|
+
log_info(message, dump, seconds)
|
19
|
+
result
|
20
|
+
else
|
21
|
+
log_info(message, dump)
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
rescue Exception => e
|
25
|
+
exception = "#{e.class.name}: #{e.message}: #{dump}"
|
26
|
+
log_info(message, exception)
|
27
|
+
raise
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.format_da_dump(path, params)
|
31
|
+
"Calculated: PATH: #{path} PARAMS: #{params.inspect}"
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.log_info(message, dump, seconds = 0)
|
35
|
+
return unless Calculated.logger
|
36
|
+
log_message = "#{message} (#{seconds}) #{dump}"
|
37
|
+
Calculated.logger.info(log_message)
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# Answers from the api
|
2
|
+
# calculations will be in the form of a hash with value and units keys
|
3
|
+
# answer.calculations["co2"]["value"] == 10
|
4
|
+
# answer.calculations["co2"]["units"] == "kg"
|
5
|
+
module Calculated
|
6
|
+
module Models
|
7
|
+
class Answer < Hashie::Dash
|
8
|
+
|
9
|
+
# properties
|
10
|
+
property :calculations # [Hash]
|
11
|
+
property :object_references # [Hash]
|
12
|
+
property :used_global_computations # [Hash]
|
13
|
+
property :calculator_id # [String]
|
14
|
+
property :computation_id # [String]
|
15
|
+
property :answer_set_id # [String]
|
16
|
+
property :source # [Calculated::Models::Source]
|
17
|
+
property :errors # [Hash]
|
18
|
+
|
19
|
+
def source=(value)
|
20
|
+
unless value.nil?
|
21
|
+
self[:source] = Models::Source.new(value)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def valid?
|
26
|
+
errors.nil?
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Calculated
|
2
|
+
module Models
|
3
|
+
class Characteristic < Hashie::Dash
|
4
|
+
|
5
|
+
# properties
|
6
|
+
property :id # [String]
|
7
|
+
property :attribute # [String]
|
8
|
+
property :value # [String]
|
9
|
+
property :value_type # [String]
|
10
|
+
property :units # [String]
|
11
|
+
property :image_id # [String]
|
12
|
+
property :image_name # [String]
|
13
|
+
property :image_size # [String]
|
14
|
+
property :image_type # [String]
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Calculated
|
2
|
+
module Models
|
3
|
+
class FormulaInput < Hashie::Dash
|
4
|
+
|
5
|
+
# properties
|
6
|
+
property :id # [String]
|
7
|
+
property :values # [Hash]
|
8
|
+
property :name # [String]
|
9
|
+
property :base_unit # [String]
|
10
|
+
property :active_at # [Time] yes time
|
11
|
+
property :main_source_id # [String]
|
12
|
+
property :group_name # [String]
|
13
|
+
property :input_units # [String]
|
14
|
+
property :label_input_units # [String]
|
15
|
+
property :model_state # [String]
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Calculated
|
2
|
+
module Models
|
3
|
+
class GenericObject < Hashie::Dash
|
4
|
+
|
5
|
+
# properties
|
6
|
+
property :id # [String]
|
7
|
+
property :template_name # [String]
|
8
|
+
property :identifier # [String]
|
9
|
+
property :characteristics # [Array<Calculated::Models::Characteristic>]
|
10
|
+
property :formula_inputs # [Array<Calculated::Models::FormulaInput>]
|
11
|
+
|
12
|
+
# dont ask why I need to check for nil? here just dont!
|
13
|
+
def characteristics=(value)
|
14
|
+
unless value.nil?
|
15
|
+
self[:characteristics] = value.map{|characteristic| Calculated::Models::Characteristic.new(characteristic)}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# setting the formula inputs to a defined model
|
20
|
+
def formula_inputs=(value)
|
21
|
+
unless value.nil?
|
22
|
+
self[:formula_inputs] = value.map{|formula| Calculated::Models::FormulaInput.new(formula)}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def used_formula_inputs=(value)
|
27
|
+
unless value.nil?
|
28
|
+
self[:used_formula_inputs] = value.map{|formula| Calculated::Models::FormulaInput.new(formula)}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Calculated
|
2
|
+
module Models
|
3
|
+
class ObjectTemplate < Hashie::Dash
|
4
|
+
|
5
|
+
# properties
|
6
|
+
property :id # [String]
|
7
|
+
property :name # [String]
|
8
|
+
property :generic_objects # [Array<Calculated::Models::GenericObject>]
|
9
|
+
|
10
|
+
# characteristics from an object template will not have a value property set as it is a template
|
11
|
+
property :characteristics # [Hash] not the same as generi_objects characteristics
|
12
|
+
|
13
|
+
# formula_inputs from an object template will not have a value property set as it is a template
|
14
|
+
property :formula_inputs # [Hash] not the same as generi_objects formula_inputs
|
15
|
+
|
16
|
+
property :relatable_categories # [Array<Calculated::Models::RelatableCategory>]
|
17
|
+
|
18
|
+
# dont ask why I need to check for nil? here just dont!
|
19
|
+
def generic_objects=(value)
|
20
|
+
unless value.nil?
|
21
|
+
self[:generic_objects] = value.map{|generic_object| Calculated::Models::GenericObject.new(generic_object)}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# dont ask why I need to check for nil? here just dont!
|
26
|
+
def characteristics=(value)
|
27
|
+
unless value.nil?
|
28
|
+
self[:characteristics] = value.map{|characteristic| Calculated::Models::Characteristic.new(characteristic)}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# setting the formula inputs to a defined model
|
33
|
+
def formula_inputs=(value)
|
34
|
+
unless value.nil?
|
35
|
+
self[:formula_inputs] = value.map{|formula| Calculated::Models::FormulaInput.new(formula)}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# setting the formula inputs to a defined model
|
40
|
+
def relatable_categories=(value)
|
41
|
+
unless value.nil?
|
42
|
+
self[:relatable_categories] = value.map{|relatable_category| Calculated::Models::RelatableCategory.new(relatable_category)}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Calculated
|
2
|
+
module Models
|
3
|
+
class RelatableCategory < Hashie::Dash
|
4
|
+
|
5
|
+
# properties
|
6
|
+
property :id # [String]
|
7
|
+
property :name # [String]
|
8
|
+
property :related_attribute # [String]
|
9
|
+
property :related_object_name # [String]
|
10
|
+
# @example
|
11
|
+
# "emission_source" => {
|
12
|
+
# {
|
13
|
+
# "4c349f6068fe5434960178c2" => "flaring and venting",
|
14
|
+
# "4c349f6068fe54349601791f" => "fugitives",
|
15
|
+
# }
|
16
|
+
# }
|
17
|
+
property :related_categories # [Hash{name => <Hash{:id => identifier}}]
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Calculated
|
2
|
+
module Models
|
3
|
+
class Source < Hashie::Dash
|
4
|
+
|
5
|
+
# properties
|
6
|
+
property :id # [String]
|
7
|
+
property :description # [String]
|
8
|
+
property :main_source_ids # [Array<String>]
|
9
|
+
property :external_url # [String]
|
10
|
+
property :wave_id # [String]
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Calculated
|
2
|
+
module ObjectTemplateApiCalls
|
3
|
+
|
4
|
+
# @param [Hash] params
|
5
|
+
# @return [Array<Calculated::Models::ObjectTemplate>]
|
6
|
+
def object_templates(params = {})
|
7
|
+
api_call(:get, "/object_templates", params) do |response|
|
8
|
+
response["object_templates"].map{|object_template| Calculated::Models::ObjectTemplate.new(object_template)}
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
# this request will have loaded generic objects for the ready basically
|
14
|
+
# @param [String] name
|
15
|
+
# @param [Hash] params
|
16
|
+
# @return [Calculated::Models::ObjectTemplate]
|
17
|
+
def generic_objects_for_object_template(name, params = {})
|
18
|
+
api_call(:get, "/object_templates/#{name}/generic_objects", params) do |response|
|
19
|
+
Calculated::Models::ObjectTemplate.new(response["object_template"])
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# this request will have loaded relatable categories for the object template
|
24
|
+
# @param [String] related_attribute
|
25
|
+
# @param [String] name
|
26
|
+
# @param [Hash] params
|
27
|
+
# @return [Calculated::Models::ObjectTemplate]
|
28
|
+
def relatable_categories_for_object_template(name, related_attribute, params = {})
|
29
|
+
api_call(:get, "/object_templates/#{name}/relatable_categories", params.merge!(:related_attribute => related_attribute)) do |response|
|
30
|
+
Calculated::Models::ObjectTemplate.new(response["object_template"])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# This will filter the results of the generic objects from a simple text search
|
35
|
+
# note this is not an expancive text search so limit to 1 word searches for best
|
36
|
+
# results
|
37
|
+
#
|
38
|
+
# @example
|
39
|
+
# generic_objects_for_object_template_with_filter('airport', 'london')
|
40
|
+
#
|
41
|
+
# There is also the usuage of relatable_category_values with the params
|
42
|
+
# this will allow further filtering on the search its an AND Filter not an OR filter
|
43
|
+
#
|
44
|
+
# @example
|
45
|
+
# searching for ford diesel cars for example
|
46
|
+
#
|
47
|
+
# generic_objects_for_object_template_with_filter('car', 'diesel', :relatable_category_values => ["ford"])
|
48
|
+
#
|
49
|
+
# this request will have loaded relatable categories for the object template
|
50
|
+
# @param [String] name
|
51
|
+
# @param [String] filter
|
52
|
+
# @param [Hash] params
|
53
|
+
# @return [Calculated::Models::GeneriObject]
|
54
|
+
def generic_objects_for_object_template_with_filter(name, filter, params = {})
|
55
|
+
api_call(:get, "/object_templates/#{name}/generic_objects/filter", params.merge!(:filter => filter)) do |response|
|
56
|
+
Calculated::Models::ObjectTemplate.new(response["object_template"])
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Calculated
|
2
|
+
module RelatableCategoryApiCalls
|
3
|
+
|
4
|
+
# this call just beings back a native array with hash of ids and identifiers
|
5
|
+
# @example
|
6
|
+
#
|
7
|
+
# "4bf42d8b46a95925b5001a0c" => "Particle Board"
|
8
|
+
#
|
9
|
+
# @param [String] template_name
|
10
|
+
# @param [Array<String>] relatable_category_ids
|
11
|
+
# @param [Hash] params
|
12
|
+
# @return [Hash]
|
13
|
+
def related_objects_from_relatable_categories(template_name, relatable_category_ids, params = {})
|
14
|
+
relatable_category_ids = relatable_category_ids.is_a?(String) ? [relatable_category_ids] : relatable_category_ids
|
15
|
+
api_call(:get, "/relatable_categories/related_objects", params.merge!(:template_name => template_name, :relatable_category_ids => relatable_category_ids)) do |response|
|
16
|
+
response["related_objects"]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
## this call just beings back a native array with hash of ids and identifiers
|
23
|
+
# @example
|
24
|
+
#
|
25
|
+
# "4bf42d8a46a95925b5001999" => "timber"
|
26
|
+
#
|
27
|
+
# @param [String] id
|
28
|
+
# @param [String] related_attribute
|
29
|
+
# @param [Hash] params
|
30
|
+
# @return [Hash]
|
31
|
+
def related_categories_from_relatable_category(id, related_attribute, params = {})
|
32
|
+
api_call(:get, "/relatable_categories/#{id}/related_categories", params.merge!(:related_attribute => related_attribute)) do |response|
|
33
|
+
response["related_categories"]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Calculated
|
2
|
+
class Service
|
3
|
+
include HTTParty
|
4
|
+
format :json
|
5
|
+
headers 'Accept' => 'application/json'
|
6
|
+
|
7
|
+
# set the httparty defaults [this obviously makes 1 service] limitation me feels
|
8
|
+
def initialize(server, api_version, api_key)
|
9
|
+
self.class.base_uri "http://#{server}/api/#{api_version}"
|
10
|
+
self.class.default_params :api_key => api_key
|
11
|
+
end
|
12
|
+
|
13
|
+
def get(path, params = {})
|
14
|
+
perform_request(:get, path, params)
|
15
|
+
end
|
16
|
+
|
17
|
+
def post(path, params = {})
|
18
|
+
perform_request(:post, path, params)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
def perform_request(type, path, params)
|
23
|
+
response = self.class.send(type, path, :query => params)
|
24
|
+
check_response(response)
|
25
|
+
response
|
26
|
+
rescue Errno::ECONNREFUSED, SocketError
|
27
|
+
raise Calculated::Session::ServerNotFound, "Carbon Calculated Server could not be found"
|
28
|
+
end
|
29
|
+
|
30
|
+
# checking the status code of the response; if we are not authenticated
|
31
|
+
# then authenticate the session
|
32
|
+
# @raise [Calculated::PermissionDenied] if the status code is 403
|
33
|
+
# @raise [Calculated::SessionExpired] if a we get a 401
|
34
|
+
# @raise [Calculated::MissingParameter] if we get something strange
|
35
|
+
def check_response(response)
|
36
|
+
case response.code
|
37
|
+
when 200, 201
|
38
|
+
true
|
39
|
+
when 401
|
40
|
+
raise Calculated::Session::PermissionDenied.new("Your Request could not be authenticated is your api key valid?")
|
41
|
+
when 404
|
42
|
+
raise Calculated::Session::NotFound.new("Resource was not found")
|
43
|
+
when 412
|
44
|
+
raise Calculated::Session::MissingParameter.new("Missing Parameter: #{response.body}")
|
45
|
+
else
|
46
|
+
raise Calculated::Session::UnknownError.new("super strange type unknown error: #{response.code} :body #{response.body}")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'active_support/core_ext/object/to_query'
|
2
|
+
module Calculated
|
3
|
+
class Session
|
4
|
+
|
5
|
+
class CalculatedError < StandardError ;end
|
6
|
+
class Expired < CalculatedError; end
|
7
|
+
class UnAuthorized < CalculatedError; end
|
8
|
+
class NotAuthenticated < CalculatedError; end
|
9
|
+
class PermissionDenied < CalculatedError; end
|
10
|
+
class NotFound < CalculatedError; end
|
11
|
+
class ServerNotFound < CalculatedError; end
|
12
|
+
class MissingParameter < CalculatedError; end
|
13
|
+
class UnknownError < CalculatedError; end
|
14
|
+
|
15
|
+
# api calls that can be made on the session
|
16
|
+
include Calculated::GenericObjectApiCalls
|
17
|
+
include Calculated::ObjectTemplateApiCalls
|
18
|
+
include Calculated::RelatableCategoryApiCalls
|
19
|
+
include Calculated::AnswerApiCalls
|
20
|
+
|
21
|
+
# accessors
|
22
|
+
attr_accessor :cache, :caching, :logging, :server, :expires_in, :api_version
|
23
|
+
|
24
|
+
# creating a session one must supply the api_key as this is always required basically
|
25
|
+
# @param [Hash] options
|
26
|
+
# @return [Calculated::Session]
|
27
|
+
def self.create(options = {})
|
28
|
+
api_key = options.delete(:api_key)
|
29
|
+
raise ArgumentError.new("You need an API Key to save the planet") unless api_key
|
30
|
+
new(api_key, options)
|
31
|
+
end
|
32
|
+
|
33
|
+
# @param [String] api_key
|
34
|
+
# @param [Hash] options
|
35
|
+
# default options
|
36
|
+
# caching => true
|
37
|
+
# expires_in => 60*60*24
|
38
|
+
# cache => Moneta::Memory.new
|
39
|
+
# server => "api.carboncalculated.com"
|
40
|
+
# api_version => "v1"
|
41
|
+
# logging => true
|
42
|
+
def initialize(api_key, options)
|
43
|
+
@api_key = api_key
|
44
|
+
if @caching = options[:caching].nil? ? true : options.delete(:caching)
|
45
|
+
@expires_in = options.delete(:expires_in) || 60*60*24
|
46
|
+
@cache = options.delete(:cache) || Moneta::Memory.new
|
47
|
+
end
|
48
|
+
@server = options.delete(:server) || "api.carboncalculated.com"
|
49
|
+
@api_version = options.delete(:api_version) || "v1"
|
50
|
+
@logging = options[:logging].nil? ? true : options.delete(:caching)
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
# api calls
|
55
|
+
def api_call_without_logging(method, path, params = {}, &proc)
|
56
|
+
result = service.send(method, path, params)
|
57
|
+
result = yield result if block_given?
|
58
|
+
store_call(result, path, params || {}) if caching?
|
59
|
+
result
|
60
|
+
end
|
61
|
+
|
62
|
+
# if we caching and we have the same cache lets try and get the
|
63
|
+
# cache; otherwise we will make the request logging if need be
|
64
|
+
def api_call(method, path, params ={}, &proc)
|
65
|
+
if cache = caching? && (@cache[cache_key(path, params)])
|
66
|
+
return cache
|
67
|
+
else
|
68
|
+
if @logging
|
69
|
+
Calculated::Logging.log_calculated_api(method, path, params) do
|
70
|
+
api_call_without_logging(method, path, params, &proc)
|
71
|
+
end
|
72
|
+
else
|
73
|
+
api_call_without_logging(method, path, params, &proc)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def service
|
79
|
+
@service ||= Calculated::Service.new(@server, @api_version, @api_key)
|
80
|
+
end
|
81
|
+
|
82
|
+
def caching?
|
83
|
+
@caching
|
84
|
+
end
|
85
|
+
|
86
|
+
protected
|
87
|
+
# @param [String] path
|
88
|
+
# @param [Hash] params
|
89
|
+
# @return [String] the cache key from the path and the params
|
90
|
+
def cache_key(path, params = {})
|
91
|
+
parts = []
|
92
|
+
parts << path
|
93
|
+
parts << params.to_query
|
94
|
+
parts.join("/")
|
95
|
+
end
|
96
|
+
|
97
|
+
# @param [Object] result
|
98
|
+
# @param [String] path
|
99
|
+
# @param [Hash] params
|
100
|
+
def store_call(result, path, params)
|
101
|
+
key = cache_key(path, params ||{})
|
102
|
+
@cache.store(key, result, :expires_in => @expires_in)
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|
metadata
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: calculated
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Richard Hooker
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-07-14 00:00:00 +01:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: activesupport
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 3
|
29
|
+
- 0
|
30
|
+
- 0
|
31
|
+
- beta3
|
32
|
+
version: 3.0.0.beta3
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: httparty
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
segments:
|
43
|
+
- 0
|
44
|
+
- 6
|
45
|
+
- 1
|
46
|
+
version: 0.6.1
|
47
|
+
type: :runtime
|
48
|
+
version_requirements: *id002
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: hashie
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
segments:
|
57
|
+
- 0
|
58
|
+
- 2
|
59
|
+
- 1
|
60
|
+
version: 0.2.1
|
61
|
+
type: :runtime
|
62
|
+
version_requirements: *id003
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: moneta
|
65
|
+
prerelease: false
|
66
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
segments:
|
71
|
+
- 0
|
72
|
+
- 6
|
73
|
+
- 0
|
74
|
+
version: 0.6.0
|
75
|
+
type: :runtime
|
76
|
+
version_requirements: *id004
|
77
|
+
- !ruby/object:Gem::Dependency
|
78
|
+
name: tzinfo
|
79
|
+
prerelease: false
|
80
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
segments:
|
85
|
+
- 0
|
86
|
+
- 3
|
87
|
+
- 22
|
88
|
+
version: 0.3.22
|
89
|
+
type: :runtime
|
90
|
+
version_requirements: *id005
|
91
|
+
description: makes using a simple api even more simple;
|
92
|
+
email:
|
93
|
+
- richard.hooker@carboncalculated.com
|
94
|
+
executables: []
|
95
|
+
|
96
|
+
extensions: []
|
97
|
+
|
98
|
+
extra_rdoc_files: []
|
99
|
+
|
100
|
+
files:
|
101
|
+
- lib/calculated/answer_api_calls.rb
|
102
|
+
- lib/calculated/generic_object_api_calls.rb
|
103
|
+
- lib/calculated/logging.rb
|
104
|
+
- lib/calculated/models/answer.rb
|
105
|
+
- lib/calculated/models/characteristic.rb
|
106
|
+
- lib/calculated/models/formula_input.rb
|
107
|
+
- lib/calculated/models/generic_object.rb
|
108
|
+
- lib/calculated/models/object_template.rb
|
109
|
+
- lib/calculated/models/relatable_category.rb
|
110
|
+
- lib/calculated/models/source.rb
|
111
|
+
- lib/calculated/object_template_api_calls.rb
|
112
|
+
- lib/calculated/relatable_category_api_calls.rb
|
113
|
+
- lib/calculated/service.rb
|
114
|
+
- lib/calculated/session.rb
|
115
|
+
- lib/calculated/version.rb
|
116
|
+
- lib/calculated.rb
|
117
|
+
- LICENSE
|
118
|
+
- CHANGELOG.md
|
119
|
+
- ROADMAP.md
|
120
|
+
has_rdoc: true
|
121
|
+
homepage: http://github.com/hookercookerman/calculated
|
122
|
+
licenses: []
|
123
|
+
|
124
|
+
post_install_message:
|
125
|
+
rdoc_options: []
|
126
|
+
|
127
|
+
require_paths:
|
128
|
+
- lib
|
129
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - ">="
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
segments:
|
134
|
+
- 0
|
135
|
+
version: "0"
|
136
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - ">="
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
segments:
|
141
|
+
- 1
|
142
|
+
- 3
|
143
|
+
- 6
|
144
|
+
version: 1.3.6
|
145
|
+
requirements: []
|
146
|
+
|
147
|
+
rubyforge_project: calculated
|
148
|
+
rubygems_version: 1.3.6
|
149
|
+
signing_key:
|
150
|
+
specification_version: 3
|
151
|
+
summary: A gem to use the carbon calculated api
|
152
|
+
test_files: []
|
153
|
+
|