calculated 0.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.
- 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
|
+
|