sblogistica 0.0.5

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 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: []