finnegans 0.1.1
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.
- checksums.yaml +7 -0
- data/.gitignore +28 -0
- data/.rspec +3 -0
- data/.travis.yml +5 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +55 -0
- data/LICENSE.txt +21 -0
- data/README.md +97 -0
- data/Rakefile +37 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/finnegans-bar.gemspec +32 -0
- data/lib/finnegans/client.rb +147 -0
- data/lib/finnegans/core/authentication.rb +52 -0
- data/lib/finnegans/core/request.rb +40 -0
- data/lib/finnegans/resource.rb +102 -0
- data/lib/finnegans/support.rb +15 -0
- data/lib/finnegans/version.rb +3 -0
- data/lib/finnegans.rb +47 -0
- metadata +160 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e5822b4089facfcb96967504f78ffa50c095b575
|
4
|
+
data.tar.gz: 54430c1d1858d6207335559fcd1a216d5916a3bd
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0bbf3babbe4790152171aa020ac5a8585e5546bad5bfc82fbe03dd3732215784cf23eaf07a719a0a7ced804a683ae28afc49b59d8f4c63d12d0a5a98c8912346
|
7
|
+
data.tar.gz: 149f0444c945a9d3f370aef13fe2ead41b59b70e4cf9d0c96b3692461d6ee937bfc67c64dd6d67bf8554f1ae8304c91c1933781ad2de5cdf3b8c5164d50085be
|
data/.gitignore
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
/.bundle/
|
2
|
+
/.yardoc
|
3
|
+
/_yardoc/
|
4
|
+
/coverage/
|
5
|
+
/doc/
|
6
|
+
/pkg/
|
7
|
+
/spec/reports/
|
8
|
+
/tmp/
|
9
|
+
|
10
|
+
# rspec failure tracking
|
11
|
+
.rspec_status
|
12
|
+
|
13
|
+
# General private stuff
|
14
|
+
*.local.*
|
15
|
+
|
16
|
+
# OS generated files #
|
17
|
+
######################
|
18
|
+
.DS_Store
|
19
|
+
.DS_Store?
|
20
|
+
._*
|
21
|
+
.Spotlight-V100
|
22
|
+
.Trashes
|
23
|
+
dump.rdb
|
24
|
+
ehthumbs.db
|
25
|
+
Thumbs.db
|
26
|
+
|
27
|
+
# Other stuff
|
28
|
+
.gs/
|
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
finnegans (0.1.1)
|
5
|
+
oj (~> 3.0)
|
6
|
+
typhoeus (>= 1.0)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
coderay (1.1.2)
|
12
|
+
diff-lcs (1.3)
|
13
|
+
ethon (0.11.0)
|
14
|
+
ffi (>= 1.3.0)
|
15
|
+
ffi (1.9.25)
|
16
|
+
httplog (1.1.1)
|
17
|
+
rack (>= 1.0)
|
18
|
+
rainbow (>= 2.0.0)
|
19
|
+
method_source (0.9.0)
|
20
|
+
oj (3.6.10)
|
21
|
+
pry (0.11.3)
|
22
|
+
coderay (~> 1.1.0)
|
23
|
+
method_source (~> 0.9.0)
|
24
|
+
rack (2.0.5)
|
25
|
+
rainbow (3.0.0)
|
26
|
+
rake (10.5.0)
|
27
|
+
rspec (3.8.0)
|
28
|
+
rspec-core (~> 3.8.0)
|
29
|
+
rspec-expectations (~> 3.8.0)
|
30
|
+
rspec-mocks (~> 3.8.0)
|
31
|
+
rspec-core (3.8.0)
|
32
|
+
rspec-support (~> 3.8.0)
|
33
|
+
rspec-expectations (3.8.1)
|
34
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
35
|
+
rspec-support (~> 3.8.0)
|
36
|
+
rspec-mocks (3.8.0)
|
37
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
38
|
+
rspec-support (~> 3.8.0)
|
39
|
+
rspec-support (3.8.0)
|
40
|
+
typhoeus (1.3.0)
|
41
|
+
ethon (>= 0.9.0)
|
42
|
+
|
43
|
+
PLATFORMS
|
44
|
+
ruby
|
45
|
+
|
46
|
+
DEPENDENCIES
|
47
|
+
bundler (~> 1.16)
|
48
|
+
finnegans!
|
49
|
+
httplog
|
50
|
+
pry
|
51
|
+
rake (~> 10.0)
|
52
|
+
rspec (~> 3.0)
|
53
|
+
|
54
|
+
BUNDLED WITH
|
55
|
+
1.16.0
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2018 Agustin Cavilliotti
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
# Finnegans
|
2
|
+
|
3
|
+
## Installation
|
4
|
+
|
5
|
+
Add this line to your application's Gemfile:
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
gem 'finnegans'
|
9
|
+
```
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install finnegans
|
18
|
+
|
19
|
+
## Setup
|
20
|
+
|
21
|
+
You should first configure the namespace of the endpoints, by doing:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
Finnegans.setup do |config|
|
25
|
+
config.resources_namespace = "personal"
|
26
|
+
end
|
27
|
+
```
|
28
|
+
|
29
|
+
In a Rails environment make sense to place this in an initializer.
|
30
|
+
|
31
|
+
This will help to identify the relevant resources expose by Finnegans. On the **App Builder -> Diccionario de APIs** you should declare each relevant endpoint like `personalSomeOtherName`. Also this will allow to avoid collisions with other exposed APIs endpoints.
|
32
|
+
|
33
|
+
## Usage
|
34
|
+
|
35
|
+
Everything is done via an instance of `Finnegans::Client`, to instantiate one you need to:
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
client_args = {
|
39
|
+
client_id: "", # Client Id for your user. You can generate them in your user profile and clicking on "Keys api"
|
40
|
+
client_secret: "", # Client Secret for your user. You can generate them in your user profile and clicking on "Keys api"
|
41
|
+
base_url: "" # This is the Base URL of the api. Something similar to 'https://X.teamplace.finneg.com/XXX/api/'
|
42
|
+
}
|
43
|
+
|
44
|
+
client = Finnegans::Client.new(client_args)
|
45
|
+
```
|
46
|
+
|
47
|
+
With this `client` you can get make requests to the API or `initialize_namespaced_resources`, like:
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
client.initialize_namespaced_resources
|
51
|
+
```
|
52
|
+
|
53
|
+
and also if at this point you realize that you need a new namespaced resource in the API, you can run:
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
client.initialize_namespaced_resources(refresh: true)
|
57
|
+
```
|
58
|
+
|
59
|
+
to recreate the resources on the client instance.
|
60
|
+
|
61
|
+
This method (`initialize_namespaced_resources`) dynamically defines instance methods on the `client` and initialize them as an instanced of `Finnegans::Resource`. So for example, if you have an API endpoint like `personalProducts` (the *personal* is an arbitrary name, could be whatever you want but must be the same that you specify in the `Finnegans.setup` block) that are *Tipo: Entidad* and supports `get` and `list` then you can do this with the `client`:
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
client.products.list
|
65
|
+
# or
|
66
|
+
client.products.get([SOME_ID])
|
67
|
+
```
|
68
|
+
|
69
|
+
Notice that the method in the `client` is the same as the *non-namespaced* part of the API endpoint name. So as you can imagine, if you have another API endpoint called `personalProductCategories` then you can call `client.product_categories` and get the `Finnegans::Resource` instance).
|
70
|
+
|
71
|
+
> IMPORTANT: The only actions that are supported for now are **:get** and **:list**.
|
72
|
+
|
73
|
+
If the API endpoint is not a *Tipo: Entidad* but a *Tipo: Viewer* the only method expose in the resource is `.reports` so you can call:
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
client.some_viewer.reports # The API endpoint name in this case, as you guessed, personalSomeViewer
|
77
|
+
```
|
78
|
+
|
79
|
+
## TO-DOs
|
80
|
+
|
81
|
+
- Add `specs` for everything
|
82
|
+
- Add the other actions (**:insert**, **:update**, **:delete**)
|
83
|
+
|
84
|
+
|
85
|
+
## Development
|
86
|
+
|
87
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `rake console` for an interactive prompt that will allow you to experiment.
|
88
|
+
|
89
|
+
To install this gem onto your local machine, run `bundle exec rake install`.
|
90
|
+
|
91
|
+
## Contributing
|
92
|
+
|
93
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/nilusorg/finnegans.
|
94
|
+
|
95
|
+
## License
|
96
|
+
|
97
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rspec/core/rake_task"
|
3
|
+
|
4
|
+
RSpec::Core::RakeTask.new(:spec)
|
5
|
+
|
6
|
+
task :default => :spec
|
7
|
+
|
8
|
+
task :console do
|
9
|
+
require "pry"
|
10
|
+
require "./lib/finnegans"
|
11
|
+
require "httplog"
|
12
|
+
|
13
|
+
HttpLog.configure do |config|
|
14
|
+
# config.log_headers = true
|
15
|
+
end
|
16
|
+
|
17
|
+
def reload!
|
18
|
+
files = $LOADED_FEATURES.select { |feat| feat =~ %r{lib/finnegans} }
|
19
|
+
# Deactivate warning messages.
|
20
|
+
original_verbose, $VERBOSE = $VERBOSE, nil
|
21
|
+
files.each { |file| load file }
|
22
|
+
# Activate warning messages again.
|
23
|
+
$VERBOSE = original_verbose
|
24
|
+
initial_setup
|
25
|
+
"Console reloaded!"
|
26
|
+
end
|
27
|
+
|
28
|
+
def initial_setup
|
29
|
+
Finnegans.setup do |config|
|
30
|
+
config.resources_namespace = ""
|
31
|
+
end
|
32
|
+
end
|
33
|
+
initial_setup
|
34
|
+
|
35
|
+
ARGV.clear
|
36
|
+
Pry.start
|
37
|
+
end
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "finnegans"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "finnegans/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "finnegans"
|
8
|
+
spec.version = Finnegans::VERSION
|
9
|
+
spec.authors = ["Agustin Cavilliotti"]
|
10
|
+
spec.email = ["cavi21@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Client to interact with the API from Finnegans}
|
13
|
+
spec.description = %q{Allows to interact with Finnegans's API. https://www.finnegans.com.ar}
|
14
|
+
spec.homepage = "https://github.com/nilusorg/finnegans"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
|
+
f.match(%r{^(test|spec|features)/})
|
19
|
+
end
|
20
|
+
spec.bindir = "exe"
|
21
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.add_development_dependency "pry"
|
25
|
+
spec.add_development_dependency "httplog"
|
26
|
+
spec.add_development_dependency "bundler", "~> 1.16"
|
27
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
28
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
29
|
+
|
30
|
+
spec.add_dependency "typhoeus", ">= 1.0"
|
31
|
+
spec.add_dependency "oj", "~> 3.0"
|
32
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
require "finnegans/core/request"
|
2
|
+
require "finnegans/core/authentication"
|
3
|
+
|
4
|
+
module Finnegans
|
5
|
+
class Client
|
6
|
+
include Finnegans::Core::Request
|
7
|
+
include Finnegans::Core::Authentication
|
8
|
+
|
9
|
+
attr_reader :client_id, :base_url, :api_catalog_path, :namespace
|
10
|
+
|
11
|
+
def initialize(client_id:, client_secret:, base_url:, api_catalog_path: 'apicatalog', namespace: Finnegans.resources_namespace)
|
12
|
+
@client_id = client_id.to_s
|
13
|
+
@client_secret = client_secret.to_s
|
14
|
+
@base_url = base_url.to_s.gsub(/\/+$/, '')
|
15
|
+
@api_catalog_path = api_catalog_path
|
16
|
+
|
17
|
+
namespace = namespace.to_s
|
18
|
+
@namespace = (namespace.empty? ? nil : namespace)
|
19
|
+
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
def inspect
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize_namespaced_resources(refresh: false)
|
28
|
+
remove_previous_resources if refresh
|
29
|
+
|
30
|
+
_namespaced_catalog = namespaced_catalog(refresh: refresh)
|
31
|
+
|
32
|
+
_namespaced_catalog.each do |catalog_item|
|
33
|
+
define_resource(catalog_item)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def request(resource, request_params = {})
|
38
|
+
unless request_params.is_a?(Hash)
|
39
|
+
raise ArgumentError, 'The second argument in the :request must be a Hash ({}) ' \
|
40
|
+
'or nil. Definition -> request(resource, request_params = {})'
|
41
|
+
end
|
42
|
+
|
43
|
+
authenticated_request do
|
44
|
+
request_params[:params] = (request_params[:params] || {}).merge(authenticated_param)
|
45
|
+
response = request_call(resource, request_params)
|
46
|
+
body = json_load(response.body)
|
47
|
+
|
48
|
+
response.success? ? body : (raise RequestError.new(body), body['error'])
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def catalog_detail(id)
|
53
|
+
request("/#{@api_catalog_path}/#{id}")
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
attr_reader :client_secret, :access_token
|
59
|
+
|
60
|
+
def authenticate
|
61
|
+
begin
|
62
|
+
authenticate!
|
63
|
+
rescue Finnegans::AuthenticationError => e
|
64
|
+
nil
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def authenticate!
|
69
|
+
return if ready?
|
70
|
+
|
71
|
+
(@access_token = get_access_token) && nil
|
72
|
+
end
|
73
|
+
|
74
|
+
def ready?
|
75
|
+
!!@access_token
|
76
|
+
end
|
77
|
+
|
78
|
+
def catalog(refresh: false)
|
79
|
+
return @_catalog if defined?(@_catalog) && !refresh
|
80
|
+
|
81
|
+
@_catalog = request("/#{@api_catalog_path}/list")
|
82
|
+
end
|
83
|
+
|
84
|
+
def namespaced_catalog(refresh: false)
|
85
|
+
return @_namespaced_catalog if defined?(@_namespaced_catalog) && !refresh
|
86
|
+
|
87
|
+
@_namespaced_catalog = catalog(refresh: refresh).select do |catalog_item|
|
88
|
+
namespace.nil? || catalog_item['codigo'] =~ /#{namespace}/i
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def authenticated_request(&block)
|
93
|
+
authenticate! unless ready?
|
94
|
+
|
95
|
+
begin
|
96
|
+
yield
|
97
|
+
rescue Finnegans::RequestError => error
|
98
|
+
if error.message =~ /(invalid_token)/i
|
99
|
+
ready? ? refresh_authentication! : authenticate!
|
100
|
+
retry
|
101
|
+
else
|
102
|
+
raise error
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def refresh_authentication!
|
108
|
+
@access_token = refresh_access_token
|
109
|
+
end
|
110
|
+
|
111
|
+
def defined_resources
|
112
|
+
@_defined_resources ||= []
|
113
|
+
end
|
114
|
+
|
115
|
+
def remove_previous_resources
|
116
|
+
defined_resources.delete_if do |resource_name|
|
117
|
+
if respond_to?(resource_name.to_sym)
|
118
|
+
(class << self; self; end).class_eval do
|
119
|
+
remove_method resource_name.to_sym
|
120
|
+
end
|
121
|
+
end
|
122
|
+
if instance_variable_defined?("@_#{resource_name}")
|
123
|
+
send(:remove_instance_variable, :"@_#{resource_name}")
|
124
|
+
end
|
125
|
+
true
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def define_resource(data)
|
130
|
+
resource_code = data['codigo']
|
131
|
+
resource_name = Support.snakecase(resource_code.gsub(/#{namespace}/, ''))
|
132
|
+
resource_active = data['activo']
|
133
|
+
|
134
|
+
resource = Resource.new(code: resource_code, active: resource_active, client: self)
|
135
|
+
instance_variable_set("@_#{resource_name}", resource)
|
136
|
+
|
137
|
+
(class << self; self; end).class_eval do
|
138
|
+
define_method :"#{resource_name}" do
|
139
|
+
instance_variable_get("@_#{resource_name}")
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
defined_resources << resource_name.to_sym
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Finnegans
|
2
|
+
module Core
|
3
|
+
|
4
|
+
module Authentication
|
5
|
+
AUTH_PATH = '/oauth/token'.freeze
|
6
|
+
private_constant :AUTH_PATH
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def get_access_token
|
11
|
+
request_params = {
|
12
|
+
method: :get,
|
13
|
+
params: auth_common_params.merge({grant_type: 'client_credentials'})
|
14
|
+
}
|
15
|
+
|
16
|
+
auth_request(request_params)
|
17
|
+
end
|
18
|
+
|
19
|
+
def refresh_access_token
|
20
|
+
request_params = {
|
21
|
+
method: :get,
|
22
|
+
params: auth_common_params.merge({
|
23
|
+
grant_type: 'refresh_token',
|
24
|
+
refresh_token: @access_token
|
25
|
+
})
|
26
|
+
}
|
27
|
+
|
28
|
+
auth_request(request_params)
|
29
|
+
end
|
30
|
+
|
31
|
+
def auth_request(request_params)
|
32
|
+
response = request_call(AUTH_PATH, request_params)
|
33
|
+
|
34
|
+
body = json_load(response.body)
|
35
|
+
|
36
|
+
response.success? ? body : (raise AuthenticationError.new(body), body['error'])
|
37
|
+
end
|
38
|
+
|
39
|
+
def auth_common_params
|
40
|
+
{
|
41
|
+
client_id: @client_id,
|
42
|
+
client_secret: @client_secret
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
def authenticated_param
|
47
|
+
# For the Finnegan API the params are case sensitive and this should be in all caps
|
48
|
+
{ "ACCESS_TOKEN" => @access_token }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Finnegans
|
2
|
+
module Core
|
3
|
+
module Request
|
4
|
+
|
5
|
+
private
|
6
|
+
|
7
|
+
def default_headers
|
8
|
+
{
|
9
|
+
"Accept-Encoding" => "application/json"
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
def request_call(resource, request_params = {})
|
14
|
+
unless request_params.is_a?(Hash)
|
15
|
+
raise ArgumentError, 'The second argument in the :request_call must be a Hash ({}) ' \
|
16
|
+
'or nil. Definition -> request_call(resource, request_params = {})'
|
17
|
+
end
|
18
|
+
|
19
|
+
request_params[:headers] = default_headers.merge(request_params[:headers] || {})
|
20
|
+
|
21
|
+
request = Typhoeus::Request.new("#{@base_url}#{resource}", request_params)
|
22
|
+
request.run
|
23
|
+
request.response
|
24
|
+
end
|
25
|
+
|
26
|
+
def json_dump(hash)
|
27
|
+
Oj.dump(hash)
|
28
|
+
end
|
29
|
+
|
30
|
+
def json_load(string)
|
31
|
+
begin
|
32
|
+
Oj.load(string)
|
33
|
+
rescue Oj::ParseError => e
|
34
|
+
string
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module Finnegans
|
2
|
+
class Resource
|
3
|
+
|
4
|
+
class ActionError < StandardError; end
|
5
|
+
|
6
|
+
ACTIONS_MAP = {
|
7
|
+
'SoportaDelete' => :delete,
|
8
|
+
'SoportaGet' => :get,
|
9
|
+
'SoportaInsert' => :insert,
|
10
|
+
'SoportaList' => :list,
|
11
|
+
'SoportaUpdate' => :update
|
12
|
+
}.freeze
|
13
|
+
private_constant :ACTIONS_MAP
|
14
|
+
|
15
|
+
TYPE_NAMES = %i[ entity viewer java_class ].freeze
|
16
|
+
private_constant :TYPE_NAMES
|
17
|
+
|
18
|
+
attr_reader :code, :active
|
19
|
+
|
20
|
+
def initialize(code:, active:, client:, with_details: false)
|
21
|
+
@code = code
|
22
|
+
@active = active
|
23
|
+
@_client = client
|
24
|
+
get_details if with_details
|
25
|
+
end
|
26
|
+
|
27
|
+
alias active? active
|
28
|
+
|
29
|
+
def type
|
30
|
+
return @_type if defined?(@_type)
|
31
|
+
|
32
|
+
_type_index = (details['Tipo']).to_i
|
33
|
+
|
34
|
+
@type = TYPE_NAMES[_type_index]
|
35
|
+
end
|
36
|
+
|
37
|
+
def actions
|
38
|
+
return @_actions if defined?(@_actions)
|
39
|
+
|
40
|
+
@_actions = details.map do |(_key, _value)|
|
41
|
+
next unless _action = ACTIONS_MAP[_key]
|
42
|
+
|
43
|
+
_action if _value
|
44
|
+
end.compact
|
45
|
+
end
|
46
|
+
|
47
|
+
def get(resource_id)
|
48
|
+
ensure_type!(:entity)
|
49
|
+
|
50
|
+
unless actions.include?(:get)
|
51
|
+
raise ActionError.new, "The :get action is not available for this resource. Only #{actions} are available"
|
52
|
+
end
|
53
|
+
|
54
|
+
client.request("/#{code}/#{resource_id}")
|
55
|
+
end
|
56
|
+
|
57
|
+
def list
|
58
|
+
ensure_type!(:entity)
|
59
|
+
|
60
|
+
unless actions.include?(:list)
|
61
|
+
raise ActionError.new, "The :get action is not available for this resource. Only #{actions} are available"
|
62
|
+
end
|
63
|
+
|
64
|
+
client.request("/#{code}/list")
|
65
|
+
end
|
66
|
+
|
67
|
+
def reports(**report_params)
|
68
|
+
ensure_type!(:viewer)
|
69
|
+
|
70
|
+
request_params = {
|
71
|
+
params: { "PARAMWEBREPORT_MonedaID" => "PES" }.merge(report_params)
|
72
|
+
}
|
73
|
+
|
74
|
+
client.request("/reports/#{code}", request_params)
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def client
|
80
|
+
@_client
|
81
|
+
end
|
82
|
+
|
83
|
+
def details
|
84
|
+
@_details ||= get_details
|
85
|
+
end
|
86
|
+
|
87
|
+
def get_details(refresh: false)
|
88
|
+
return @_details if defined?(@_details) && !refresh
|
89
|
+
|
90
|
+
_details = client.catalog_detail(code)
|
91
|
+
_details.delete('DefinitionXml')
|
92
|
+
@_details = _details
|
93
|
+
end
|
94
|
+
|
95
|
+
def ensure_type!(type_name)
|
96
|
+
unless type == type_name.to_sym
|
97
|
+
raise ActionError.new, "This action is only available for resources that are type :#{type_name}"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Finnegans
|
2
|
+
module Support
|
3
|
+
class << self
|
4
|
+
def snakecase(string)
|
5
|
+
str = string.dup
|
6
|
+
str.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
7
|
+
str.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
8
|
+
str.tr!('-', '_')
|
9
|
+
str.gsub!(/\s/, '_')
|
10
|
+
str.gsub!(/__+/, '_')
|
11
|
+
str.downcase
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/finnegans.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'typhoeus'
|
3
|
+
require 'oj'
|
4
|
+
|
5
|
+
require "finnegans/version"
|
6
|
+
require "finnegans/support"
|
7
|
+
require "finnegans/resource"
|
8
|
+
require "finnegans/client"
|
9
|
+
|
10
|
+
module Finnegans
|
11
|
+
@@resources_namespace = ''
|
12
|
+
|
13
|
+
DEFAULT_USER_AGENT = "Finnegans API Client v#{Finnegans::VERSION}".freeze
|
14
|
+
private_constant :DEFAULT_USER_AGENT
|
15
|
+
|
16
|
+
Typhoeus::Config.user_agent = DEFAULT_USER_AGENT
|
17
|
+
|
18
|
+
class ArgumentError < StandardError; end
|
19
|
+
class SetupError < StandardError; end
|
20
|
+
|
21
|
+
class RequestError < StandardError
|
22
|
+
# We are following Rubocop Style to declare them and raise them
|
23
|
+
# https://github.com/rubocop-hq/ruby-style-guide#exception-class-messages
|
24
|
+
attr_reader :content
|
25
|
+
|
26
|
+
def initialize(content)
|
27
|
+
super
|
28
|
+
@content = content
|
29
|
+
end
|
30
|
+
end
|
31
|
+
class AuthenticationError < RequestError; end
|
32
|
+
|
33
|
+
class << self
|
34
|
+
def resources_namespace
|
35
|
+
@@resources_namespace
|
36
|
+
end
|
37
|
+
|
38
|
+
def setup
|
39
|
+
yield self
|
40
|
+
end
|
41
|
+
|
42
|
+
def resources_namespace=(value)
|
43
|
+
value = value.to_s
|
44
|
+
@@resources_namespace = (value.empty? ? nil : value)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
metadata
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: finnegans
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Agustin Cavilliotti
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-09-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: pry
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: httplog
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.16'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.16'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: typhoeus
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: oj
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '3.0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '3.0'
|
111
|
+
description: Allows to interact with Finnegans's API. https://www.finnegans.com.ar
|
112
|
+
email:
|
113
|
+
- cavi21@gmail.com
|
114
|
+
executables: []
|
115
|
+
extensions: []
|
116
|
+
extra_rdoc_files: []
|
117
|
+
files:
|
118
|
+
- ".gitignore"
|
119
|
+
- ".rspec"
|
120
|
+
- ".travis.yml"
|
121
|
+
- Gemfile
|
122
|
+
- Gemfile.lock
|
123
|
+
- LICENSE.txt
|
124
|
+
- README.md
|
125
|
+
- Rakefile
|
126
|
+
- bin/console
|
127
|
+
- bin/setup
|
128
|
+
- finnegans-bar.gemspec
|
129
|
+
- lib/finnegans.rb
|
130
|
+
- lib/finnegans/client.rb
|
131
|
+
- lib/finnegans/core/authentication.rb
|
132
|
+
- lib/finnegans/core/request.rb
|
133
|
+
- lib/finnegans/resource.rb
|
134
|
+
- lib/finnegans/support.rb
|
135
|
+
- lib/finnegans/version.rb
|
136
|
+
homepage: https://github.com/nilusorg/finnegans
|
137
|
+
licenses:
|
138
|
+
- MIT
|
139
|
+
metadata: {}
|
140
|
+
post_install_message:
|
141
|
+
rdoc_options: []
|
142
|
+
require_paths:
|
143
|
+
- lib
|
144
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
145
|
+
requirements:
|
146
|
+
- - ">="
|
147
|
+
- !ruby/object:Gem::Version
|
148
|
+
version: '0'
|
149
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - ">="
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
154
|
+
requirements: []
|
155
|
+
rubyforge_project:
|
156
|
+
rubygems_version: 2.6.11
|
157
|
+
signing_key:
|
158
|
+
specification_version: 4
|
159
|
+
summary: Client to interact with the API from Finnegans
|
160
|
+
test_files: []
|