shoptet 0.0.21 → 0.0.22
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 +4 -4
- data/lib/shoptet.rb +40 -101
- data/lib/shoptet/api_enumerator.rb +44 -0
- data/lib/shoptet/request.rb +14 -26
- data/shoptet.gemspec +2 -0
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2009bb64f74a45fdc160d4cbe7040366ec918ad6ad392288cad5f00f3e4e2406
|
4
|
+
data.tar.gz: 72dfe3b46b578a2131e7c8b96ca1d951dddfa15eea60a8ce77d4666ae9186d91
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3aee7e5ad2e7c1006202513f8ca57faaeb07b96508097b6457b98b174e497530545553923106f61ec184a194d2af3caf3e14abffe81f4c1912c212c8846f7723
|
7
|
+
data.tar.gz: 89ae29433db50dede06c6eef59a311cef45aa9b0d59ae740ca5130cd47d207bf06cd172498862e7c2b6c4b6df96d25eb01f9b8485892d36750048e0f62bc3208
|
data/lib/shoptet.rb
CHANGED
@@ -1,78 +1,25 @@
|
|
1
1
|
require 'delegate'
|
2
2
|
require_relative 'shoptet/request'
|
3
|
+
require_relative 'shoptet/api_enumerator'
|
3
4
|
|
4
5
|
class Shoptet
|
5
|
-
include Shoptet::UrlHelpers
|
6
|
-
|
7
6
|
class Error < StandardError; end
|
8
7
|
class AddonSuspended < StandardError; end
|
9
8
|
class AddonNotInstalled < StandardError; end
|
10
9
|
class InvalidTokenNoRights < StandardError; end
|
11
|
-
class
|
10
|
+
class EmptyResponse < StandardError; end
|
12
11
|
class MaxPageReached < StandardError; end
|
13
12
|
|
14
13
|
EXPIRED_TOKEN_CODE = 'expired-token'
|
15
14
|
INVALID_TOKEN_CODE = 'invalid-token'
|
16
15
|
ADDON_NOT_INSTALLED = 'Addon installation is not approved.'
|
17
16
|
|
18
|
-
|
17
|
+
ON_TOKEN_ERROR = -> (api) do
|
19
18
|
api.api_token = api.new_api_token
|
20
19
|
end
|
21
20
|
|
22
|
-
class ApiEnumerator < SimpleDelegator
|
23
|
-
def initialize base_url, filters, data_key, api
|
24
|
-
@base_url = base_url
|
25
|
-
@filters = filters
|
26
|
-
@data_key = data_key || URI(base_url).path.split('/').last
|
27
|
-
@api = api
|
28
|
-
|
29
|
-
@enum = Enumerator.new do |y|
|
30
|
-
first_page.dig('data', @data_key).each { y.yield _1 }
|
31
|
-
|
32
|
-
if total_pages > 1
|
33
|
-
other_pages = 2..(total_pages - 1)
|
34
|
-
other_pages.each do |page|
|
35
|
-
uri = @api.assemble_uri base_url, filters.merge(page: page)
|
36
|
-
result = @api.request uri
|
37
|
-
result.dig('data', @data_key).each { y.yield _1 }
|
38
|
-
end
|
39
|
-
|
40
|
-
last_page.dig('data', @data_key).each { y.yield _1 }
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
super @enum
|
45
|
-
end
|
46
|
-
|
47
|
-
def first_page
|
48
|
-
@first_page ||=
|
49
|
-
begin
|
50
|
-
uri = @api.assemble_uri @base_url, @filters
|
51
|
-
@api.request uri
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def total_pages
|
56
|
-
first_page.dig('data', 'paginator', 'pageCount') || 0
|
57
|
-
end
|
58
|
-
|
59
|
-
def last_page
|
60
|
-
return first_page if total_pages < 2
|
61
|
-
|
62
|
-
@last_page ||=
|
63
|
-
begin
|
64
|
-
uri = @api.assemble_uri @base_url, @filters.merge(page: total_pages)
|
65
|
-
@api.request uri
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def size
|
70
|
-
first_page['data']['paginator']['totalCount']
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
21
|
def self.version
|
75
|
-
'0.0.
|
22
|
+
'0.0.22'
|
76
23
|
end
|
77
24
|
|
78
25
|
def self.ar_on_token_error(model)
|
@@ -102,7 +49,7 @@ class Shoptet
|
|
102
49
|
'scope' => 'api'
|
103
50
|
}
|
104
51
|
|
105
|
-
Shoptet::Request.post
|
52
|
+
Shoptet::Request.post(url, data)
|
106
53
|
end
|
107
54
|
|
108
55
|
def self.login_token url, code, client_id, client_secret, redirect_url
|
@@ -115,11 +62,11 @@ class Shoptet
|
|
115
62
|
scope: 'basic_eshop'
|
116
63
|
}
|
117
64
|
|
118
|
-
Shoptet::Request.post
|
65
|
+
Shoptet::Request.post(url, data)
|
119
66
|
end
|
120
67
|
|
121
68
|
def self.basic_eshop url, access_token
|
122
|
-
Shoptet::Request.get
|
69
|
+
Shoptet::Request.get(url, { 'Authorization' => "Bearer #{access_token}" })
|
123
70
|
end
|
124
71
|
|
125
72
|
attr_accessor :api_token
|
@@ -130,11 +77,11 @@ class Shoptet
|
|
130
77
|
@shop_url = shop_url
|
131
78
|
@client_id = client_id
|
132
79
|
@api_token = api_token
|
133
|
-
@on_token_error = on_token_error ||
|
80
|
+
@on_token_error = on_token_error || ON_TOKEN_ERROR
|
134
81
|
end
|
135
82
|
|
136
83
|
def endpoints api_params = {}
|
137
|
-
enumerize
|
84
|
+
enumerize('https://api.myshoptet.com/api/system/endpoints', api_params)
|
138
85
|
end
|
139
86
|
|
140
87
|
def endpoint_approved? endpoint
|
@@ -156,101 +103,95 @@ class Shoptet
|
|
156
103
|
redirect_uri: redirect_url
|
157
104
|
}.to_query
|
158
105
|
|
159
|
-
URI("#{@shop_url}action/OAuthServer/authorize?#{query}")
|
106
|
+
URI("#{@shop_url}action/OAuthServer/authorize?#{query}")
|
160
107
|
end
|
161
108
|
|
162
109
|
def shop_info api_params = {}
|
163
|
-
|
164
|
-
result = request url
|
110
|
+
result = request('https://api.myshoptet.com/api/eshop', api_params)
|
165
111
|
result['data']
|
166
112
|
end
|
167
113
|
|
168
114
|
def design_info api_params = {}
|
169
|
-
|
170
|
-
result = request url
|
115
|
+
result = request('https://api.myshoptet.com/api/eshop/design', api_params)
|
171
116
|
|
172
117
|
result['data']
|
173
118
|
end
|
174
119
|
|
175
120
|
def stocks api_params = {}
|
176
|
-
enumerize
|
121
|
+
enumerize('https://api.myshoptet.com/api/stocks', api_params)
|
177
122
|
end
|
178
123
|
|
179
124
|
def products api_params = {}
|
180
|
-
enumerize
|
125
|
+
enumerize("https://api.myshoptet.com/api/products", api_params)
|
181
126
|
end
|
182
127
|
|
183
128
|
def supplies warehouse_id, api_params = {}
|
184
|
-
|
185
|
-
enumerize uri, api_params
|
129
|
+
enumerize("https://api.myshoptet.com/api/stocks/#{warehouse_id}/supplies", api_params)
|
186
130
|
end
|
187
131
|
|
188
132
|
def stocks_movements warehouse_id, api_params = {}
|
189
|
-
|
190
|
-
enumerize uri, api_params
|
133
|
+
enumerize("https://api.myshoptet.com/api/stocks/#{warehouse_id}/movements", api_params)
|
191
134
|
end
|
192
135
|
|
193
136
|
def product_categories api_params = {}
|
194
|
-
enumerize
|
137
|
+
enumerize('https://api.myshoptet.com/api/categories', api_params)
|
195
138
|
end
|
196
139
|
|
197
140
|
def products_changes api_params = {}
|
198
|
-
|
199
|
-
enumerize uri, api_params
|
141
|
+
enumerize('https://api.myshoptet.com/api/products/changes', api_params)
|
200
142
|
end
|
201
143
|
|
202
144
|
def price_lists api_params = {}
|
203
|
-
enumerize
|
145
|
+
enumerize('https://api.myshoptet.com/api/pricelists', api_params)
|
204
146
|
end
|
205
147
|
|
206
148
|
def prices price_list_id, api_params = {}
|
207
|
-
|
208
|
-
enumerize uri, api_params, 'pricelist'
|
149
|
+
enumerize("https://api.myshoptet.com/api/pricelists/#{price_list_id}", api_params, 'pricelist')
|
209
150
|
end
|
210
151
|
|
211
152
|
def orders api_params = {}
|
212
|
-
enumerize
|
153
|
+
enumerize('https://api.myshoptet.com/api/orders', api_params)
|
213
154
|
end
|
214
155
|
|
215
156
|
def orders_changes api_params = {}
|
216
|
-
|
217
|
-
enumerize uri, api_params
|
157
|
+
enumerize('https://api.myshoptet.com/api/orders/changes', api_params)
|
218
158
|
end
|
219
159
|
|
220
160
|
def order code, api_params = {}
|
221
|
-
|
222
|
-
result
|
223
|
-
result.dig 'data', 'order'
|
161
|
+
result = request("https://api.myshoptet.com/api/orders/#{code}", api_params)
|
162
|
+
result.dig('data', 'order')
|
224
163
|
end
|
225
164
|
|
226
165
|
def product guid, api_params = {}
|
227
|
-
|
228
|
-
result = request assemble_uri(uri, api_params)
|
166
|
+
result = request("https://api.myshoptet.com/api/products/#{guid}", api_params)
|
229
167
|
result['data']
|
230
168
|
end
|
231
169
|
|
232
170
|
def new_api_token
|
233
171
|
headers = { 'Authorization' => "Bearer #{@oauth_token}" }
|
234
172
|
|
235
|
-
result = Shoptet::Request.get
|
236
|
-
handle_errors
|
173
|
+
result = Shoptet::Request.get(URI(@oauth_url), headers)
|
174
|
+
handle_errors(result)
|
237
175
|
|
238
|
-
result.fetch
|
176
|
+
result.fetch('access_token')
|
239
177
|
end
|
240
178
|
|
241
|
-
def request
|
179
|
+
def request url, api_params = {}, retry_on_token_error = true
|
180
|
+
url = URI(url)
|
181
|
+
url.query = URI.encode_www_form(api_params) if api_params.any?
|
182
|
+
|
242
183
|
headers = { 'Shoptet-Access-Token' => @api_token,
|
243
184
|
'Content-Type' => 'application/vnd.shoptet.v1.0' }
|
244
185
|
|
245
|
-
result = Shoptet::Request.get
|
246
|
-
token_errors = handle_errors
|
186
|
+
result = Shoptet::Request.get(url, headers)
|
187
|
+
token_errors = handle_errors(result)
|
247
188
|
|
248
189
|
if token_errors.any?
|
249
190
|
if retry_on_token_error
|
250
|
-
@on_token_error.call
|
251
|
-
request
|
191
|
+
@on_token_error.call(self)
|
192
|
+
request(url, api_params, false)
|
252
193
|
else
|
253
|
-
raise Error.new
|
194
|
+
raise Error.new(result)
|
254
195
|
end
|
255
196
|
else
|
256
197
|
result
|
@@ -258,9 +199,7 @@ class Shoptet
|
|
258
199
|
end
|
259
200
|
|
260
201
|
def suspended?
|
261
|
-
|
262
|
-
|
263
|
-
false if data
|
202
|
+
false if shop_info
|
264
203
|
rescue Shoptet::AddonSuspended
|
265
204
|
true
|
266
205
|
end
|
@@ -268,10 +207,10 @@ class Shoptet
|
|
268
207
|
private
|
269
208
|
|
270
209
|
def enumerize base_url, filters = {}, data_key = nil
|
271
|
-
ApiEnumerator.new
|
210
|
+
ApiEnumerator.new(base_url, filters, data_key, self)
|
272
211
|
end
|
273
212
|
|
274
|
-
def handle_errors result
|
213
|
+
def handle_errors result
|
275
214
|
error = result['error']
|
276
215
|
errors = result['errors'] || []
|
277
216
|
token_errors, non_token_errors = errors.partition do |err|
|
@@ -0,0 +1,44 @@
|
|
1
|
+
class Shoptet
|
2
|
+
class ApiEnumerator < SimpleDelegator
|
3
|
+
def initialize base_url, filters, data_key, api
|
4
|
+
@base_url = base_url
|
5
|
+
@filters = filters
|
6
|
+
@data_key = data_key || URI(base_url).path.split('/').last
|
7
|
+
@api = api
|
8
|
+
|
9
|
+
@enum = Enumerator.new do |y|
|
10
|
+
first_page.dig('data', @data_key).each { y.yield _1 }
|
11
|
+
|
12
|
+
if total_pages > 1
|
13
|
+
other_pages = 2..(total_pages - 1)
|
14
|
+
other_pages.each do |page|
|
15
|
+
result = @api.request(base_url, filters.merge(page: page))
|
16
|
+
result.dig('data', @data_key).each { y.yield _1 }
|
17
|
+
end
|
18
|
+
|
19
|
+
last_page.dig('data', @data_key).each { y.yield _1 }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
super @enum
|
24
|
+
end
|
25
|
+
|
26
|
+
def first_page
|
27
|
+
@first_page ||= @api.request(@base_url, @filters)
|
28
|
+
end
|
29
|
+
|
30
|
+
def last_page
|
31
|
+
return first_page if total_pages < 2
|
32
|
+
|
33
|
+
@last_page ||= @api.request(@base_url, @filters.merge(page: total_pages))
|
34
|
+
end
|
35
|
+
|
36
|
+
def total_pages
|
37
|
+
first_page.dig('data', 'paginator', 'pageCount') || 0
|
38
|
+
end
|
39
|
+
|
40
|
+
def size
|
41
|
+
first_page.dig('data', 'paginator', 'totalCount')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/shoptet/request.rb
CHANGED
@@ -1,53 +1,41 @@
|
|
1
1
|
require 'net/http'
|
2
|
-
|
3
|
-
#TODO: keep_alive_timeout ?
|
2
|
+
require 'oj'
|
4
3
|
|
5
4
|
class Shoptet
|
6
|
-
module UrlHelpers
|
7
|
-
def assemble_uri base, params = {}
|
8
|
-
u = URI(base)
|
9
|
-
u.query = URI.encode_www_form(params) if params.any?
|
10
|
-
|
11
|
-
u.to_s
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
5
|
class Request
|
16
|
-
def self.get
|
17
|
-
|
18
|
-
|
19
|
-
http = Net::HTTP.new parsed_uri.host, parsed_uri.port
|
6
|
+
def self.get url, headers
|
7
|
+
http = Net::HTTP.new(url.host, url.port)
|
20
8
|
http.use_ssl = true
|
21
9
|
http.open_timeout = 60
|
22
10
|
http.read_timeout = 60
|
23
11
|
http.write_timeout = 60
|
24
12
|
http.ssl_timeout = 60
|
25
13
|
|
26
|
-
request = Net::HTTP::Get.new
|
14
|
+
request = Net::HTTP::Get.new(url)
|
27
15
|
headers.each do |key, value|
|
28
16
|
request[key] = value
|
29
17
|
end
|
30
18
|
|
31
|
-
response = http.request
|
32
|
-
parsed_body =
|
19
|
+
response = http.request(request)
|
20
|
+
parsed_body = Oj.load(response.body, mode: :compat)
|
33
21
|
|
34
22
|
unless parsed_body
|
35
|
-
message = "Status code: #{response.code}, url: #{
|
36
|
-
fail Shoptet::
|
23
|
+
message = "Status code: #{response.code}, url: #{url}"
|
24
|
+
fail Shoptet::EmptyResponse.new(message)
|
37
25
|
end
|
38
26
|
|
39
27
|
parsed_body
|
40
28
|
end
|
41
29
|
|
42
|
-
def self.post
|
43
|
-
|
44
|
-
|
30
|
+
def self.post url, body
|
31
|
+
request = Net::HTTP::Post.new(url)
|
32
|
+
request.set_form_data(body)
|
45
33
|
|
46
|
-
|
47
|
-
http.request
|
34
|
+
response = Net::HTTP.start(url.host, url.port, use_ssl: true) do |http|
|
35
|
+
http.request(request)
|
48
36
|
end
|
49
37
|
|
50
|
-
|
38
|
+
Oj.load(response.body, mode: :compat)
|
51
39
|
end
|
52
40
|
end
|
53
41
|
end
|
data/shoptet.gemspec
CHANGED
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shoptet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.22
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Premysl Donat
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-12-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: oj
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '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'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: irb
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -40,6 +54,7 @@ files:
|
|
40
54
|
- bin/console
|
41
55
|
- bin/setup
|
42
56
|
- lib/shoptet.rb
|
57
|
+
- lib/shoptet/api_enumerator.rb
|
43
58
|
- lib/shoptet/request.rb
|
44
59
|
- shoptet.gemspec
|
45
60
|
homepage: https://github.com/Masa331/shoptet
|