smartfocus 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/generators/install.rb +15 -0
- data/lib/generators/templates/smartfocus.yml +15 -0
- data/lib/smartfocus.rb +27 -0
- data/lib/smartfocus/api.rb +173 -0
- data/lib/smartfocus/exception.rb +8 -0
- data/lib/smartfocus/logger.rb +29 -0
- data/lib/smartfocus/malformed_response.rb +10 -0
- data/lib/smartfocus/notification.rb +48 -0
- data/lib/smartfocus/railtie.rb +24 -0
- data/lib/smartfocus/relation.rb +40 -0
- data/lib/smartfocus/request.rb +67 -0
- data/lib/smartfocus/request_error.rb +11 -0
- data/lib/smartfocus/response.rb +52 -0
- data/lib/smartfocus/session_error.rb +10 -0
- data/lib/smartfocus/tools.rb +130 -0
- data/lib/smartfocus/version.rb +3 -0
- metadata +126 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8eac52d54c0b68c2544736e196208f5197772123
|
4
|
+
data.tar.gz: d84d9da100cae9d4ed3fd9b7b0dc987d58004c83
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 45ae22b51f28b0f7e39684f7ff170535d8ca4a41e2044c9eb51ee12e6063a7ced9e037a0eb1b9912428f41ba5a4eb54be1fc13e88238c4cff257ff97c8b473b4
|
7
|
+
data.tar.gz: d0c8255336649508e0a83e3156810b9e01030cb3fc1150a885e38e5f127ee6948f0a2a1b29a79d576f844c914a048853ea408aa529e6246ed8cd63e0f8fb6e04
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
module Smartfocus
|
4
|
+
module Generators
|
5
|
+
class Install < Rails::Generators::Base
|
6
|
+
|
7
|
+
source_root File.expand_path('../templates', __FILE__)
|
8
|
+
|
9
|
+
def generate_config
|
10
|
+
copy_file "smartfocus.yml", "config/smartfocus.yml" unless File.exist?("config/smartfocus.yml")
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/smartfocus.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'crack/xml'
|
2
|
+
require 'httparty'
|
3
|
+
require 'active_support/inflector'
|
4
|
+
require 'logger'
|
5
|
+
require 'builder'
|
6
|
+
|
7
|
+
# Smartfocus API wrapper
|
8
|
+
#
|
9
|
+
module Smartfocus
|
10
|
+
autoload :Api, 'smartfocus/api'
|
11
|
+
autoload :Exception, 'smartfocus/exception'
|
12
|
+
autoload :Logger, 'smartfocus/logger'
|
13
|
+
autoload :MalformedResponse, 'smartfocus/malformed_response'
|
14
|
+
autoload :Relation, 'smartfocus/relation'
|
15
|
+
autoload :Request, 'smartfocus/request'
|
16
|
+
autoload :RequestError, 'smartfocus/request_error'
|
17
|
+
autoload :Response, 'smartfocus/response'
|
18
|
+
autoload :SessionError, 'smartfocus/session_error'
|
19
|
+
autoload :Tools, 'smartfocus/tools'
|
20
|
+
autoload :Notification, 'smartfocus/notification'
|
21
|
+
autoload :Version, 'smartfocus/version'
|
22
|
+
|
23
|
+
if defined?(Rails)
|
24
|
+
require 'smartfocus/railtie'
|
25
|
+
require 'generators/install'
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
module Smartfocus
|
2
|
+
|
3
|
+
# This is where the communication with the API is made.
|
4
|
+
#
|
5
|
+
class Api
|
6
|
+
include HTTParty
|
7
|
+
default_timeout 30
|
8
|
+
format :xml
|
9
|
+
headers 'Content-Type' => 'text/xml'
|
10
|
+
|
11
|
+
# HTTP verbs allowed to trigger a call-chain
|
12
|
+
HTTP_VERBS = [:get, :post].freeze
|
13
|
+
ATTRIBUTES = [:token, :server_name, :endpoint, :login, :password, :key, :debug].freeze
|
14
|
+
|
15
|
+
# Attributes
|
16
|
+
class << self
|
17
|
+
attr_accessor *ATTRIBUTES
|
18
|
+
end
|
19
|
+
attr_accessor *ATTRIBUTES
|
20
|
+
|
21
|
+
# Initialize
|
22
|
+
#
|
23
|
+
# @param [Hash] Instance attributes to assign
|
24
|
+
# @yield Freshly-created instance (optionnal)
|
25
|
+
#
|
26
|
+
def initialize(params = {})
|
27
|
+
yield(self) if block_given?
|
28
|
+
assign_attributes(params)
|
29
|
+
end
|
30
|
+
|
31
|
+
# ----------------- BEGIN Pre-configured methods -----------------
|
32
|
+
|
33
|
+
# Reset session
|
34
|
+
#
|
35
|
+
# Useful when the session has expired.
|
36
|
+
#
|
37
|
+
def reset_session
|
38
|
+
close_connection
|
39
|
+
open_connection
|
40
|
+
end
|
41
|
+
|
42
|
+
# Login to Smartfocus API
|
43
|
+
#
|
44
|
+
# @return [Boolean] true if the connection has been established.
|
45
|
+
#
|
46
|
+
def open_connection
|
47
|
+
return false if connected?
|
48
|
+
self.token = get.connect.open.call :login => @login, :password => @password, :key => @key
|
49
|
+
connected?
|
50
|
+
end
|
51
|
+
|
52
|
+
# Logout from Smartfocus API
|
53
|
+
#
|
54
|
+
# @return [Boolean] true if the connection has been destroyed
|
55
|
+
#
|
56
|
+
def close_connection
|
57
|
+
if connected?
|
58
|
+
get.connect.close.call
|
59
|
+
else
|
60
|
+
return false
|
61
|
+
end
|
62
|
+
rescue Smartfocus::Exception => e
|
63
|
+
ensure
|
64
|
+
invalidate_token!
|
65
|
+
not connected?
|
66
|
+
end
|
67
|
+
|
68
|
+
# Check whether the connection has been established or not
|
69
|
+
#
|
70
|
+
# @return [Boolean] true if the connection has been establshed
|
71
|
+
#
|
72
|
+
def connected?
|
73
|
+
!token.nil?
|
74
|
+
end
|
75
|
+
|
76
|
+
# When a token is no longer valid, this method can be called.
|
77
|
+
# The #connected? method will return false
|
78
|
+
#
|
79
|
+
def invalidate_token!
|
80
|
+
self.token = nil
|
81
|
+
end
|
82
|
+
# ----------------- END Pre-configured methods -----------------
|
83
|
+
|
84
|
+
# Perform an API call
|
85
|
+
#
|
86
|
+
# @param [Smartfocus::Request] Request to perform
|
87
|
+
#
|
88
|
+
def call(request)
|
89
|
+
# == Check presence of these essential attributes ==
|
90
|
+
unless server_name and endpoint
|
91
|
+
raise Smartfocus::Exception, "Cannot make an API call without a server name and an endpoint !"
|
92
|
+
end
|
93
|
+
|
94
|
+
with_retries do
|
95
|
+
logger.send "#{request.uri} with query : #{request.parameters} and body : #{request.body}"
|
96
|
+
|
97
|
+
response = perform_request(request)
|
98
|
+
|
99
|
+
Smartfocus::Response.new(response, logger).extract
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Set a new token
|
104
|
+
#
|
105
|
+
# @param [String] new token
|
106
|
+
#
|
107
|
+
def token=(value)
|
108
|
+
@token = value
|
109
|
+
end
|
110
|
+
|
111
|
+
# Change API endpoint.
|
112
|
+
# This will close the connection to the current endpoint
|
113
|
+
#
|
114
|
+
# @param [String] new endpoint (apimember, apiccmd, apitransactional, ...)
|
115
|
+
#
|
116
|
+
def endpoint=(value)
|
117
|
+
close_connection
|
118
|
+
@endpoint = value
|
119
|
+
end
|
120
|
+
|
121
|
+
# Base uri
|
122
|
+
#
|
123
|
+
def base_uri
|
124
|
+
"http://#{server_name}/#{endpoint}/services/rest/"
|
125
|
+
end
|
126
|
+
|
127
|
+
# Generate call-chain triggers
|
128
|
+
HTTP_VERBS.each do |http_verb|
|
129
|
+
define_method(http_verb) do
|
130
|
+
Smartfocus::Relation.new(self, build_request(http_verb))
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
private
|
135
|
+
|
136
|
+
def build_request(http_verb)
|
137
|
+
Smartfocus::Request.new(http_verb, token, server_name, endpoint)
|
138
|
+
end
|
139
|
+
|
140
|
+
def perform_request(request)
|
141
|
+
self.class.send request.http_verb, base_uri + request.uri, :query => request.parameters, :body => request.body, :timeout => 30
|
142
|
+
end
|
143
|
+
|
144
|
+
def assign_attributes(parameters)
|
145
|
+
parameters or return
|
146
|
+
ATTRIBUTES.each do |attribute|
|
147
|
+
public_send("#{attribute}=", (parameters[attribute] || self.class.public_send(attribute)))
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def with_retries
|
152
|
+
retries = 3
|
153
|
+
begin
|
154
|
+
yield
|
155
|
+
rescue Errno::ECONNRESET, Timeout::Error => e
|
156
|
+
if ((retries -= 1) > 0)
|
157
|
+
retry
|
158
|
+
else
|
159
|
+
raise e
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def logger
|
165
|
+
if @logger.nil?
|
166
|
+
@logger = Smartfocus::Logger.new(STDOUT)
|
167
|
+
@logger.level = (debug ? Logger::DEBUG : Logger::WARN)
|
168
|
+
end
|
169
|
+
@logger
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
173
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Smartfocus
|
2
|
+
|
3
|
+
# API logger class
|
4
|
+
#
|
5
|
+
class Logger < ::Logger
|
6
|
+
|
7
|
+
attr_accessor :debug
|
8
|
+
|
9
|
+
def initializer(*args)
|
10
|
+
debug = false
|
11
|
+
super args
|
12
|
+
end
|
13
|
+
|
14
|
+
# Log a message sent to smartfocus
|
15
|
+
#
|
16
|
+
# @param [String] message
|
17
|
+
def send(message)
|
18
|
+
info("[Smartfocus] Send -> #{message}")
|
19
|
+
end
|
20
|
+
|
21
|
+
# Log a message received from smartfocus
|
22
|
+
#
|
23
|
+
# @param [String] message
|
24
|
+
def receive(message)
|
25
|
+
info("[Smartfocus] Receive -> #{message}")
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Smartfocus
|
2
|
+
class Notification
|
3
|
+
include HTTParty
|
4
|
+
default_timeout 30
|
5
|
+
format :xml
|
6
|
+
headers 'Content-Type' => 'application/xml;charset=utf-8', 'encoding' => 'UTF-8', 'Accept' => '*/*'
|
7
|
+
|
8
|
+
class << self
|
9
|
+
attr_accessor :debug
|
10
|
+
end
|
11
|
+
attr_accessor :debug
|
12
|
+
|
13
|
+
def initialize(params = {})
|
14
|
+
yield(self) if block_given?
|
15
|
+
|
16
|
+
self.debug ||= params[:debug] || self.class.debug
|
17
|
+
end
|
18
|
+
|
19
|
+
def send(body, params = {})
|
20
|
+
# == Processing body ==
|
21
|
+
body_xml = Smartocus::Tools.to_xml_as_is body
|
22
|
+
|
23
|
+
# == Send request ==
|
24
|
+
logger.send "#{base_uri} with body : #{body_xml}"
|
25
|
+
response = self.class.send :post, base_uri, :body => body_xml
|
26
|
+
logger.receive "#{base_uri} with status : #{response.header.inspect}"
|
27
|
+
|
28
|
+
# == Check result ==
|
29
|
+
response.header.code == '200'
|
30
|
+
end
|
31
|
+
|
32
|
+
# Base uri
|
33
|
+
def base_uri
|
34
|
+
'http://api.notificationmessaging.com/NMSXML'
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def logger
|
40
|
+
if @logger.nil?
|
41
|
+
@logger = Smartocus::Logger.new(STDOUT)
|
42
|
+
@logger.level = (debug ? Logger::DEBUG : Logger::WARN)
|
43
|
+
end
|
44
|
+
@logger
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rails'
|
2
|
+
|
3
|
+
module Smartocus
|
4
|
+
class Railtie < Rails::Railtie
|
5
|
+
|
6
|
+
generators do
|
7
|
+
require 'generators/install'
|
8
|
+
end
|
9
|
+
|
10
|
+
config.to_prepare do
|
11
|
+
file = "#{Rails.root}/config/smartfocus.yml"
|
12
|
+
if File.exist?(file)
|
13
|
+
config = YAML.load_file(file)[Rails.env] || {}
|
14
|
+
Smartfocus::Api.server_name = config['server_name']
|
15
|
+
Smartfocus::Api.endpoint = config['endpoint']
|
16
|
+
Smartfocus::Api.login = config['login']
|
17
|
+
Smartfocus::Api.password = config['password']
|
18
|
+
Smartfocus::Api.key = config['key']
|
19
|
+
Smartfocus::Api.debug = config['debug']
|
20
|
+
Smartfocus::Notification.debug = config['debug']
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Smartfocus
|
2
|
+
|
3
|
+
# Relation is used for API-chained call
|
4
|
+
#
|
5
|
+
# e.g. emv.get.campaign.last(:limit => 5).call
|
6
|
+
#
|
7
|
+
class Relation
|
8
|
+
|
9
|
+
def initialize(instance, request)
|
10
|
+
@instance = instance
|
11
|
+
@request = request
|
12
|
+
@uri = []
|
13
|
+
@options = {}
|
14
|
+
end
|
15
|
+
|
16
|
+
# Trigger the API call
|
17
|
+
#
|
18
|
+
# @param [Object] parameters
|
19
|
+
# @return [Object] data returned from Smartfocus
|
20
|
+
#
|
21
|
+
def call(*args)
|
22
|
+
@options.merge! extract_args(args)
|
23
|
+
@request.prepare(@uri.join('/'), @options)
|
24
|
+
@instance.call(@request)
|
25
|
+
end
|
26
|
+
|
27
|
+
def method_missing(method, *args)
|
28
|
+
@uri << method.to_s.camelize(:lower)
|
29
|
+
@options.merge! extract_args(args)
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def extract_args(args)
|
36
|
+
(args[0] and args[0].kind_of? Hash) ? args[0] : {}
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Smartfocus
|
2
|
+
|
3
|
+
# Request object
|
4
|
+
#
|
5
|
+
# This class aims to format the request for Smartfocus
|
6
|
+
#
|
7
|
+
class Request
|
8
|
+
|
9
|
+
attr_reader(
|
10
|
+
:http_verb,
|
11
|
+
:token,
|
12
|
+
:server_name,
|
13
|
+
:endpoint,
|
14
|
+
:uri,
|
15
|
+
:body,
|
16
|
+
:parameters
|
17
|
+
)
|
18
|
+
|
19
|
+
def initialize(http_verb, token, server_name, endpoint)
|
20
|
+
@http_verb = http_verb
|
21
|
+
@token = token
|
22
|
+
@server_name = server_name
|
23
|
+
@endpoint = endpoint
|
24
|
+
end
|
25
|
+
|
26
|
+
def prepare(uri, parameters)
|
27
|
+
@uri = uri
|
28
|
+
@parameters = parameters || {}
|
29
|
+
|
30
|
+
@uri = prepare_uri
|
31
|
+
@body = prepare_body
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def prepare_uri
|
37
|
+
uri = @uri
|
38
|
+
if parameters[:uri]
|
39
|
+
uri += token ? "/#{token}/" : '/'
|
40
|
+
uri += (parameters[:uri].respond_to?(:join) ? parameters[:uri] : [parameters[:uri]]).compact.join '/'
|
41
|
+
parameters.delete :uri
|
42
|
+
elsif parameters[:body]
|
43
|
+
uri += token ? "/#{token}/" : '/'
|
44
|
+
else
|
45
|
+
parameters[:token] = token
|
46
|
+
end
|
47
|
+
uri
|
48
|
+
end
|
49
|
+
|
50
|
+
def prepare_body
|
51
|
+
body = parameters[:body] || {}
|
52
|
+
parameters.delete :body
|
53
|
+
# 2. Camelize all keys
|
54
|
+
body = Smartfocus::Tools.r_camelize body
|
55
|
+
# 3. Convert to xml
|
56
|
+
Smartfocus::Tools.to_xml_as_is body
|
57
|
+
end
|
58
|
+
|
59
|
+
def assign_attributes(attibutes)
|
60
|
+
attibutes or return
|
61
|
+
attibutes.each do |attribute, value|
|
62
|
+
public_send("#{attribute}=", value)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Smartfocus
|
2
|
+
|
3
|
+
# Response object
|
4
|
+
#
|
5
|
+
# This class aims to extract the response from Smartfocus
|
6
|
+
#
|
7
|
+
class Response
|
8
|
+
|
9
|
+
attr_reader :response, :logger
|
10
|
+
|
11
|
+
def initialize(response, logger)
|
12
|
+
@response = response
|
13
|
+
@logger = logger
|
14
|
+
end
|
15
|
+
|
16
|
+
def extract
|
17
|
+
logger.receive(content.inspect)
|
18
|
+
|
19
|
+
if succeed?
|
20
|
+
response = content["response"]["result"] || content["response"]
|
21
|
+
else
|
22
|
+
handle_errors
|
23
|
+
end
|
24
|
+
rescue MultiXml::ParseError, REXML::ParseException => error
|
25
|
+
wrapped_error = Smartfocus::MalformedResponse.new(error)
|
26
|
+
raise wrapped_error, "Error when parsing response body"
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def succeed?
|
32
|
+
(http_code == "200") and (content and content["response"])
|
33
|
+
end
|
34
|
+
|
35
|
+
def handle_errors
|
36
|
+
if content =~ /Your session has expired/ or content =~ /The maximum number of connection allowed per session has been reached/
|
37
|
+
raise Smartfocus::SessionError, content
|
38
|
+
else
|
39
|
+
raise Smartfocus::RequestError, content
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def content
|
44
|
+
@content ||= Crack::XML.parse(response.body)
|
45
|
+
end
|
46
|
+
|
47
|
+
def http_code
|
48
|
+
response.header.code
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
module Smartfocus
|
2
|
+
|
3
|
+
# Toolbox for the API
|
4
|
+
# This class is mainly used to convert data
|
5
|
+
#
|
6
|
+
class Tools
|
7
|
+
|
8
|
+
# Sanitize values from a Hash
|
9
|
+
#
|
10
|
+
# @param [Hash] hash to sanitize
|
11
|
+
# @return [Hash] sanitized hash
|
12
|
+
#
|
13
|
+
def self.sanitize_parameters(parameters)
|
14
|
+
r_each(parameters) do |value|
|
15
|
+
if value.kind_of?(DateTime) or value.kind_of?(Time)
|
16
|
+
date_time_format(value.to_datetime)
|
17
|
+
elsif value.kind_of?(Date)
|
18
|
+
date_format(value.to_date)
|
19
|
+
else
|
20
|
+
value
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.date_time_format(datetime)
|
26
|
+
datetime.strftime("%Y-%m-%dT%H:%M:%S")
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.date_format(date)
|
30
|
+
date.strftime('%d/%m/%Y')
|
31
|
+
end
|
32
|
+
|
33
|
+
# Convert hash keys to camel case
|
34
|
+
#
|
35
|
+
# @param [Object] structure to camelize
|
36
|
+
# @return [Object] structure with keys camelized (if any)
|
37
|
+
#
|
38
|
+
def self.r_camelize(obj)
|
39
|
+
if obj.is_a?(Hash)
|
40
|
+
new_obj = {}
|
41
|
+
obj.each do |key, value|
|
42
|
+
new_obj[key.to_s.camelize(:lower).to_sym] = r_camelize value
|
43
|
+
end
|
44
|
+
new_obj
|
45
|
+
elsif obj.is_a?(Array)
|
46
|
+
new_obj = []
|
47
|
+
obj.each_with_index do |item, index|
|
48
|
+
new_obj[index] = r_camelize item
|
49
|
+
end
|
50
|
+
new_obj
|
51
|
+
else
|
52
|
+
obj
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Convert data structure to XML
|
57
|
+
#
|
58
|
+
# @param [Object] structure to convert
|
59
|
+
# @return [String] XML structure
|
60
|
+
#
|
61
|
+
def self.to_xml_as_is(obj)
|
62
|
+
obj_xml = ""
|
63
|
+
|
64
|
+
unless obj.nil? or obj.empty?
|
65
|
+
xml = ::Builder::XmlMarkup.new(:target=> obj_xml)
|
66
|
+
xml.instruct! :xml, :version=> "1.0"
|
67
|
+
tag_obj xml, obj
|
68
|
+
end
|
69
|
+
|
70
|
+
obj_xml
|
71
|
+
end
|
72
|
+
|
73
|
+
# Iterate throught a Hash recursively
|
74
|
+
#
|
75
|
+
# @param [Hash] structure to iterate
|
76
|
+
# @yield called for each data
|
77
|
+
#
|
78
|
+
def self.r_each(hash, &block)
|
79
|
+
return enum_for(:dfs, hash) unless block
|
80
|
+
|
81
|
+
result = {}
|
82
|
+
if hash.is_a?(Hash)
|
83
|
+
hash.map do |k,v|
|
84
|
+
result[k] = if v.is_a? Array
|
85
|
+
v.map do |elm|
|
86
|
+
r_each(elm, &block)
|
87
|
+
end
|
88
|
+
elsif v.is_a? Hash
|
89
|
+
r_each(v, &block)
|
90
|
+
else
|
91
|
+
yield(v)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
else
|
95
|
+
result = yield(hash)
|
96
|
+
end
|
97
|
+
|
98
|
+
result
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
def self.tag_obj(xml, obj)
|
104
|
+
if obj.is_a? Hash
|
105
|
+
obj.each do |key, value|
|
106
|
+
if value.is_a?(Hash)
|
107
|
+
eval(%{
|
108
|
+
xml.#{key} do
|
109
|
+
tag_obj(xml, value)
|
110
|
+
end
|
111
|
+
})
|
112
|
+
elsif value.is_a?(Array)
|
113
|
+
value.each do |item|
|
114
|
+
eval(%{
|
115
|
+
xml.#{key} do
|
116
|
+
tag_obj(xml, item)
|
117
|
+
end
|
118
|
+
})
|
119
|
+
end
|
120
|
+
else
|
121
|
+
eval %{xml.#{key}(%{#{value}})}
|
122
|
+
end
|
123
|
+
end
|
124
|
+
else
|
125
|
+
obj
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
end
|
metadata
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: smartfocus
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- '''Bastien'
|
8
|
+
- Gysler',
|
9
|
+
- '''eboutic.ch'''
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2013-11-14 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: httparty
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.12.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - ~>
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: 0.12.0
|
29
|
+
- !ruby/object:Gem::Dependency
|
30
|
+
name: crack
|
31
|
+
requirement: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - ~>
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: 0.4.0
|
36
|
+
type: :runtime
|
37
|
+
prerelease: false
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ~>
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 0.4.0
|
43
|
+
- !ruby/object:Gem::Dependency
|
44
|
+
name: builder
|
45
|
+
requirement: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - '>='
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '3.0'
|
50
|
+
type: :runtime
|
51
|
+
prerelease: false
|
52
|
+
version_requirements: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - '>='
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '3.0'
|
57
|
+
- !ruby/object:Gem::Dependency
|
58
|
+
name: activesupport
|
59
|
+
requirement: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - '>='
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '3.0'
|
64
|
+
- - ~>
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: 4.0.0
|
67
|
+
type: :runtime
|
68
|
+
prerelease: false
|
69
|
+
version_requirements: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - '>='
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '3.0'
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 4.0.0
|
77
|
+
description: REST API wrapper interacting with Smartfocus (ex Emailvision)
|
78
|
+
email:
|
79
|
+
- '''basgys@gmail.com'','
|
80
|
+
- '''tech@eboutic.ch'''
|
81
|
+
executables: []
|
82
|
+
extensions: []
|
83
|
+
extra_rdoc_files: []
|
84
|
+
files:
|
85
|
+
- lib/generators/install.rb
|
86
|
+
- lib/generators/templates/smartfocus.yml
|
87
|
+
- lib/smartfocus/api.rb
|
88
|
+
- lib/smartfocus/exception.rb
|
89
|
+
- lib/smartfocus/logger.rb
|
90
|
+
- lib/smartfocus/malformed_response.rb
|
91
|
+
- lib/smartfocus/notification.rb
|
92
|
+
- lib/smartfocus/railtie.rb
|
93
|
+
- lib/smartfocus/relation.rb
|
94
|
+
- lib/smartfocus/request.rb
|
95
|
+
- lib/smartfocus/request_error.rb
|
96
|
+
- lib/smartfocus/response.rb
|
97
|
+
- lib/smartfocus/session_error.rb
|
98
|
+
- lib/smartfocus/tools.rb
|
99
|
+
- lib/smartfocus/version.rb
|
100
|
+
- lib/smartfocus.rb
|
101
|
+
homepage: https://github.com/eboutic/smartfocus
|
102
|
+
licenses:
|
103
|
+
- MIT
|
104
|
+
metadata: {}
|
105
|
+
post_install_message:
|
106
|
+
rdoc_options: []
|
107
|
+
require_paths:
|
108
|
+
- lib
|
109
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - '>='
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
114
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - '>='
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
requirements: []
|
120
|
+
rubyforge_project:
|
121
|
+
rubygems_version: 2.1.9
|
122
|
+
signing_key:
|
123
|
+
specification_version: 4
|
124
|
+
summary: Smartfocus
|
125
|
+
test_files: []
|
126
|
+
has_rdoc:
|