sblogistica 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: bc5149fe910a241513f66b45efb28ce0775d73225c9b96236a6c5e1aeee4550f
4
+ data.tar.gz: b350ed36fa639115803c650591dfb8c2364d3b6233674970fe18c8c0791ecb2d
5
+ SHA512:
6
+ metadata.gz: 948c74362b6cf771b4ec5b7535d92575293ef525503038c1a00769b99a6f27a985ae2c6ab05452aca54eb48326871263b5a2958912f7ff88e24471a5bdee2e71
7
+ data.tar.gz: a7b04bc3fc50beb3885c7bae945cc66ea7cad30ffd0cad3eca3168dc04b7bab03fd7aaaabd95c4de984d18e8abdc3d1031c03c5f15b69d20d63e4be6964fa9b9
@@ -0,0 +1,2 @@
1
+ Description:
2
+ sblogistica:install
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sblogistica
4
+ class InstallGenerator < Rails::Generators::Base
5
+ source_root File.expand_path('templates', __dir__)
6
+
7
+ def generate_install
8
+ copy_file 'sblogistica.yml', 'config/sblogistica.yml'
9
+ copy_file 'sblogistica.rb', 'config/initializers/sblogistica.rb'
10
+ end
11
+ end
12
+ end
13
+
@@ -0,0 +1,17 @@
1
+ require 'sblogistica'
2
+
3
+ Sblogistica.setup do |config|
4
+ if File.exist?('config/sblogistica.yml')
5
+ processed = YAML.load_file('config/sblogistica.yml')[Rails.env]
6
+
7
+ processed.each do |k, v|
8
+ config::register k.underscore.to_sym, v
9
+ end
10
+
11
+ config::Request.api_key = Sblogistica::api_key || ENV['SBLOGISTICA_API_KEY']
12
+ config::Request.timeout = 15
13
+ config::Request.open_timeout = 15
14
+ config::Request.symbolize_keys = true
15
+ config::Request.debug = false
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ defaults: &defaults
2
+ HOST: 'https://lk.sblogistica.ru'
3
+ API_TOKEN_URL: 'https://lk.sblogistica.ru/auth/oauth/token?system=LDAP'
4
+ API_GRANT_TYPE: 'request-body'
5
+ API_KEY: '***'
6
+ API_USERNAME: '***'
7
+ API_PASSWORD: '***'
8
+ API_CLIENT_ID: '***'
9
+ API_CLIENT_SECRET: '***'
10
+ production:
11
+ <<: *defaults
12
+ development:
13
+ <<: *defaults
14
+ test:
15
+ <<: *defaults
@@ -0,0 +1,196 @@
1
+ module Sblogistica
2
+ class APIRequest
3
+
4
+ def initialize(builder: nil)
5
+ @request_builder = builder
6
+ end
7
+
8
+ def post(params: nil, headers: nil, body: {})
9
+ validate_api_key
10
+
11
+ begin
12
+ response = self.rest_client.post do |request|
13
+ configure_request(request: request, params: params, headers: headers, body: MultiJson.dump(body))
14
+ end
15
+ parse_response(response)
16
+ rescue StandardError => e
17
+ handle_error(e)
18
+ end
19
+ end
20
+
21
+ def patch(params: nil, headers: nil, body: {})
22
+ validate_api_key
23
+
24
+ begin
25
+ response = self.rest_client.patch do |request|
26
+ configure_request(request: request, params: params, headers: headers, body: MultiJson.dump(body))
27
+ end
28
+ parse_response(response)
29
+ rescue StandardError => e
30
+ handle_error(e)
31
+ end
32
+ end
33
+
34
+ def put(params: nil, headers: nil, body: {})
35
+ validate_api_key
36
+
37
+ begin
38
+ response = self.rest_client.put do |request|
39
+ configure_request(request: request, params: params, headers: headers, body: MultiJson.dump(body))
40
+ end
41
+ parse_response(response)
42
+ rescue StandardError => e
43
+ handle_error(e)
44
+ end
45
+ end
46
+
47
+ def get(params: nil, headers: nil)
48
+ validate_api_key
49
+
50
+ begin
51
+ response = self.rest_client.get do |request|
52
+ configure_request(request: request, params: params, headers: headers)
53
+ end
54
+ parse_response(response)
55
+ rescue StandardError => e
56
+ handle_error(e)
57
+ end
58
+ end
59
+
60
+ def delete(params: nil, headers: nil)
61
+ validate_api_key
62
+
63
+ begin
64
+ response = self.rest_client.delete do |request|
65
+ configure_request(request: request, params: params, headers: headers)
66
+ end
67
+ parse_response(response)
68
+ rescue StandardError => e
69
+ handle_error(e)
70
+ end
71
+ end
72
+
73
+ protected
74
+
75
+ # Convenience accessors
76
+
77
+ def api_key
78
+ @request_builder.api_key
79
+ end
80
+
81
+ def api_endpoint
82
+ @request_builder.api_endpoint
83
+ end
84
+
85
+ def timeout
86
+ @request_builder.timeout
87
+ end
88
+
89
+ def open_timeout
90
+ @request_builder.open_timeout
91
+ end
92
+
93
+ def proxy
94
+ @request_builder.proxy
95
+ end
96
+
97
+ def ssl_options
98
+ @request_builder.ssl_options
99
+ end
100
+
101
+ def adapter
102
+ @request_builder.faraday_adapter
103
+ end
104
+
105
+ def symbolize_keys
106
+ @request_builder.symbolize_keys
107
+ end
108
+
109
+ # Helpers
110
+
111
+ def handle_error(error)
112
+ error_params = {}
113
+
114
+ begin
115
+ if error.is_a?(Faraday::ClientError) && error.response
116
+ error_params[:status_code] = error.response[:status]
117
+ error_params[:raw_body] = error.response[:body]
118
+
119
+ parsed_response = MultiJson.load(error.response[:body], symbolize_keys: symbolize_keys)
120
+
121
+ if parsed_response
122
+ error_params[:body] = parsed_response
123
+
124
+ title_key = symbolize_keys ? :title : "title"
125
+ detail_key = symbolize_keys ? :detail : "detail"
126
+
127
+ error_params[:title] = parsed_response[title_key] if parsed_response[title_key]
128
+ error_params[:detail] = parsed_response[detail_key] if parsed_response[detail_key]
129
+ end
130
+
131
+ end
132
+ rescue MultiJson::ParseError
133
+ end
134
+
135
+ error_to_raise = Error.new(error.message, error_params)
136
+
137
+ raise error_to_raise
138
+ end
139
+
140
+ def configure_request(request: nil, params: nil, headers: nil, body: nil)
141
+ if request
142
+ request.params.merge!(params) if params
143
+ request.headers['X-Api-Key'] = Sblogistica::Request.api_key
144
+ request.headers['Content-Type'] = 'application/json'
145
+ request.headers['User-Agent'] = "Sblogistica/#{Sblogistica::VERSION} Ruby gem"
146
+ request.headers.merge!(headers) if headers
147
+ request.body = body if body
148
+ request.options.timeout = self.timeout
149
+ request.options.open_timeout = self.open_timeout
150
+ end
151
+ end
152
+
153
+ def rest_client
154
+ client = Faraday.new(self.api_url, proxy: self.proxy, ssl: self.ssl_options) do |faraday|
155
+ faraday.response :raise_error
156
+ faraday.adapter adapter
157
+ if @request_builder.debug
158
+ faraday.response :logger, @request_builder.logger, bodies: true
159
+ end
160
+ end
161
+ client
162
+ end
163
+
164
+ def parse_response(response)
165
+ parsed_response = nil
166
+
167
+ if response.body && !response.body.empty?
168
+ begin
169
+ headers = response.headers
170
+ body = MultiJson.load(response.body, symbolize_keys: symbolize_keys)
171
+ parsed_response = Response.new(headers: headers, body: body)
172
+ rescue MultiJson::ParseError
173
+ error_params = { title: "UNPARSEABLE_RESPONSE", status_code: 500 }
174
+ error = Error.new("Unparseable response: #{response.body}", error_params)
175
+ raise error
176
+ end
177
+ end
178
+
179
+ parsed_response
180
+ end
181
+
182
+ def validate_api_key
183
+ unless self.api_key
184
+ raise Sblogistica::Error, "You must set an access_token prior to making a call"
185
+ end
186
+ end
187
+
188
+ def api_url
189
+ base_api_url + @request_builder.path + "/"
190
+ end
191
+
192
+ def base_api_url
193
+ "#{Sblogistica.host || 'https://lk.sblogistica.ru'}/api/"
194
+ end
195
+ end
196
+ end
@@ -0,0 +1,29 @@
1
+ module Sblogistica
2
+ class Error < StandardError
3
+ attr_reader :title, :detail, :body, :raw_body, :status_code
4
+
5
+ def initialize(message = "", params = {})
6
+ @title = params[:title]
7
+ @detail = params[:detail]
8
+ @body = params[:body]
9
+ @raw_body = params[:raw_body]
10
+ @status_code = params[:status_code]
11
+
12
+ super(message)
13
+ end
14
+
15
+ def to_s
16
+ super + " " + instance_variables_to_s
17
+ end
18
+
19
+ private
20
+
21
+ def instance_variables_to_s
22
+ [:title, :detail, :body, :raw_body, :status_code].map do |attr|
23
+ attr_value = send(attr)
24
+
25
+ "@#{attr}=#{attr_value.inspect}"
26
+ end.join(", ")
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,100 @@
1
+ module Sblogistica
2
+ class Request
3
+ attr_accessor :api_key, :api_endpoint, :timeout, :open_timeout, :proxy, :ssl_options, :faraday_adapter, :symbolize_keys, :debug, :logger, :test
4
+
5
+ DEFAULT_TIMEOUT = 60
6
+ DEFAULT_OPEN_TIMEOUT = 60
7
+
8
+ def initialize(api_key: nil, api_endpoint: nil, timeout: nil, open_timeout: nil, proxy: nil, ssl_options: nil,
9
+ faraday_adapter: nil, symbolize_keys: false, debug: false, logger: nil, test: false)
10
+ @path_parts = []
11
+ @api_key = api_key || self.class.api_key
12
+ @api_key = @api_key.strip if @api_key
13
+ @api_endpoint = api_endpoint || self.class.api_endpoint
14
+ @timeout = timeout || self.class.timeout || DEFAULT_TIMEOUT
15
+ @open_timeout = open_timeout || self.class.open_timeout || DEFAULT_OPEN_TIMEOUT
16
+ @proxy = proxy || self.class.proxy || ENV['SBLOGISTICA_PROXY']
17
+ @ssl_options = ssl_options || self.class.ssl_options || { version: "TLSv1_2" }
18
+ @faraday_adapter = faraday_adapter || self.class.faraday_adapter || Faraday.default_adapter
19
+ @symbolize_keys = symbolize_keys || self.class.symbolize_keys || false
20
+ @debug = debug || self.class.debug || false
21
+ @test = test || self.class.test || false
22
+ @logger = logger || self.class.logger || ::Logger.new(STDOUT)
23
+ end
24
+
25
+ def method_missing(method, *args)
26
+ @path_parts << method.to_s
27
+ @path_parts << args if args.length > 0
28
+ @path_parts.flatten!
29
+ self
30
+ end
31
+
32
+ def respond_to_missing?(method_name, include_private = false)
33
+ true
34
+ end
35
+
36
+ def send(*args)
37
+ if args.length == 0
38
+ method_missing(:send, args)
39
+ else
40
+ __send__(*args)
41
+ end
42
+ end
43
+
44
+ def path
45
+ @path_parts.join('/')
46
+ end
47
+
48
+ def create(params: nil, headers: nil, body: {})
49
+ APIRequest.new(builder: self).post(params: params, headers: headers, body: body)
50
+ ensure
51
+ reset
52
+ end
53
+
54
+ def update(params: nil, headers: nil, body: {})
55
+ APIRequest.new(builder: self).patch(params: params, headers: headers, body: body)
56
+ ensure
57
+ reset
58
+ end
59
+
60
+ def upsert(params: nil, headers: nil, body: {})
61
+ APIRequest.new(builder: self).put(params: params, headers: headers, body: body)
62
+ ensure
63
+ reset
64
+ end
65
+
66
+ def retrieve(params: nil, headers: nil)
67
+ APIRequest.new(builder: self).get(params: params, headers: headers)
68
+ ensure
69
+ reset
70
+ end
71
+
72
+ def delete(params: nil, headers: nil)
73
+ APIRequest.new(builder: self).delete(params: params, headers: headers)
74
+ ensure
75
+ reset
76
+ end
77
+
78
+ protected
79
+
80
+ def reset
81
+ @path_parts = []
82
+ end
83
+
84
+ class << self
85
+ attr_accessor :api_key, :timeout, :open_timeout, :api_endpoint, :proxy, :ssl_options, :faraday_adapter,
86
+ :symbolize_keys, :debug, :logger, :test
87
+
88
+ def method_missing(sym, *args, &block)
89
+ new(api_key: self.api_key, api_endpoint: self.api_endpoint, timeout: self.timeout,
90
+ open_timeout: self.open_timeout, faraday_adapter: self.faraday_adapter, symbolize_keys: self.symbolize_keys,
91
+ debug: self.debug, proxy: self.proxy, ssl_options: self.ssl_options, logger: self.logger,
92
+ test: self.test).send(sym, *args, &block)
93
+ end
94
+
95
+ def respond_to_missing?(method_name, include_private = false)
96
+ true
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,14 @@
1
+ module Sblogistica
2
+ class Response
3
+ attr_accessor :body, :headers
4
+
5
+ def initialize(body: {}, headers: {})
6
+ @body = body
7
+ @headers = headers
8
+ end
9
+
10
+ def data
11
+ body.try(:dig, :response, :data)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,3 @@
1
+ module Sblogistica
2
+ VERSION = "0.0.5"
3
+ end
@@ -0,0 +1,77 @@
1
+ require 'faraday'
2
+ require 'multi_json'
3
+ require "sblogistica/version"
4
+ require 'sblogistica/error'
5
+ require 'sblogistica/request'
6
+ require 'sblogistica/api_request'
7
+ require 'sblogistica/response'
8
+
9
+ module Sblogistica
10
+ class << self
11
+
12
+ def generate_access_token
13
+ client = Faraday.new(Sblogistica.api_token_url, proxy: Sblogistica::Request.proxy,
14
+ ssl: Sblogistica::Request.ssl_options) do |faraday|
15
+ faraday.response :raise_error
16
+ faraday.adapter Faraday.default_adapter
17
+ if Sblogistica::Request.debug
18
+ faraday.response :logger, Sblogistica::Request.logger, bodies: true
19
+ end
20
+ end
21
+ response = client.post do |request|
22
+ request.body = MultiJson.dump({
23
+ type: Sblogistica.api_grant_type,
24
+ client_id: Sblogistica.api_client_id,
25
+ client_secret: Sblogistica.api_client_secret,
26
+ username: Sblogistica.api_username,
27
+ password: Sblogistica.api_password
28
+ })
29
+ end
30
+ JSON.parse(response.body)
31
+ end
32
+
33
+ def setup
34
+ yield self
35
+ end
36
+
37
+ def register(name, value, type = nil)
38
+ cattr_accessor "#{name}_setting".to_sym
39
+
40
+ add_reader(name)
41
+ add_writer(name, type)
42
+ send "#{name}=", value
43
+ end
44
+
45
+ def add_reader(name)
46
+ define_singleton_method(name) do |*args|
47
+ send("#{name}_setting").value(*args)
48
+ end
49
+ end
50
+
51
+ def add_writer(name, type)
52
+ define_singleton_method("#{name}=") do |value|
53
+ send("#{name}_setting=", DynamicSetting.build(value, type))
54
+ end
55
+ end
56
+ end
57
+
58
+ class DynamicSetting
59
+ def self.build(setting, type)
60
+ (type ? klass(type) : self).new(setting)
61
+ end
62
+
63
+ def self.klass(type)
64
+ klass = "#{type.to_s.camelcase}Setting"
65
+ raise ArgumentError, "Unknown type: #{type}" unless Sblogistica.const_defined?(klass)
66
+ Sblogistica.const_get(klass)
67
+ end
68
+
69
+ def initialize(setting)
70
+ @setting = setting
71
+ end
72
+
73
+ def value(*_args)
74
+ @setting
75
+ end
76
+ end
77
+ end
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sblogistica
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.5
5
+ platform: ruby
6
+ authors:
7
+ - Pavel Osetrov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-05-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.16.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 0.16.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: multi_json
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.11.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 1.11.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: irb
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 1.3.6
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 1.3.6
55
+ description: ''
56
+ email: pavel.osetrov@me.com
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files: []
60
+ files:
61
+ - lib/generators/sblogistica/install/USAGE
62
+ - lib/generators/sblogistica/install/install_generator.rb
63
+ - lib/generators/sblogistica/install/templates/sblogistica.rb
64
+ - lib/generators/sblogistica/install/templates/sblogistica.yml
65
+ - lib/sblogistica.rb
66
+ - lib/sblogistica/api_request.rb
67
+ - lib/sblogistica/error.rb
68
+ - lib/sblogistica/request.rb
69
+ - lib/sblogistica/response.rb
70
+ - lib/sblogistica/version.rb
71
+ homepage: https://github.com/osetrov/sblogistica
72
+ licenses:
73
+ - MIT
74
+ metadata: {}
75
+ post_install_message:
76
+ rdoc_options: []
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '2.5'
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ requirements: []
90
+ rubygems_version: 3.2.32
91
+ signing_key:
92
+ specification_version: 4
93
+ summary: Sblogistica
94
+ test_files: []