shoptet 0.0.5 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -3
  3. data/lib/shoptet.rb +133 -64
  4. data/lib/shoptet/request.rb +20 -0
  5. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8f8ef4e3ca1fad89c2736773c9ed8d85d579c0f065a87f77f78f19010f4626c6
4
- data.tar.gz: aad9e4adc1d9c73126f97638c90897cf067e3db8b129bcad13631f1a9b81eaad
3
+ metadata.gz: 419d01d58f819a79e524940a21eb8cca44fca53cc77257acd87f6a0e0f699bb6
4
+ data.tar.gz: 0366bbceb70df4b75ccef62ed9ac853b5fd1e5d56b81833ee5c1a87ee99f6208
5
5
  SHA512:
6
- metadata.gz: a4ad0b4003782abde395644bc8a981b72a69a43c84676bae4bbf4bef09fec1161d194cdd2e6e6df72bb711fe28c0ac4c1612619945542308428144e945b6ed77
7
- data.tar.gz: 9b085d8e2a808cb4ef80c7f27b89c6d9b801abfa715d9586c86df0f8138115592b7c0270a614d1b35482d8d596d7cc37e6d01d73f00ca73406fd817703cf9aff
6
+ metadata.gz: 4ced7cedf10bf236c1fe434ef729707cfb152fb747f02391d037ec2adff66f5aed43c41081e1b59b43e6b8d47fe52924d1323b0c554c340e49fad2cceebd5030
7
+ data.tar.gz: 887f3afe91e7b8bcbefe3bdac69bf6ce4c81a3525f27967969893aad172d5d4248e77585ec59a3c4f5ca6b8a79e7a1a16a45e605561f94a3e0b2e8e1aef8a41b
data/README.md CHANGED
@@ -1,8 +1,6 @@
1
1
  # Shoptet
2
2
 
3
- This is Ruby API wrapper for [Shoptet API](https://developers.shoptet.com/) which provides access to e-shop data for addon developers.
4
-
5
- This is currently under development and hasn't been released to Rubygems yet.
3
+ This is Ruby API wrapper for [Shoptet API](https://shoptet.docs.apiary.io) which provides access to e-shop data for addon developers.
6
4
 
7
5
  # How to install
8
6
 
@@ -82,6 +80,7 @@ Also they accept hash with params which will be passed to Shoptet api. Through t
82
80
  ## Other
83
81
 
84
82
  * `Shoptet#new_api_token` - this returns new api token created with oauth token
83
+ * `Shoptet::install` - TODO
85
84
 
86
85
  ## License
87
86
 
@@ -1,15 +1,10 @@
1
+ require 'delegate'
1
2
  require_relative 'shoptet/request'
2
3
 
3
4
  class Shoptet
4
- class Error < StandardError
5
- #TODO: check that this works
6
- attr_reader :additional_data
5
+ include Shoptet::UrlHelpers
7
6
 
8
- def initialize message, additional_data = {}
9
- super(message)
10
- @additional_data = additional_data
11
- end
12
- end
7
+ class Error < StandardError; end
13
8
  class AddonSuspended < StandardError; end
14
9
  class AddonNotInstalled < StandardError; end
15
10
  class InvalidTokenNoRights < StandardError; end
@@ -18,8 +13,60 @@ class Shoptet
18
13
  api.api_token = api.new_api_token
19
14
  end
20
15
 
16
+ class ApiEnumerator < SimpleDelegator
17
+ def initialize base_url, filters, data_key, api
18
+ @base_url = base_url
19
+ @filters = filters
20
+ @data_key = data_key || URI(base_url).path.split('/').last
21
+ @api = api
22
+
23
+ @enum = Enumerator.new do |y|
24
+ first_page.dig('data', @data_key).each { y.yield _1 }
25
+
26
+ if total_pages > 1
27
+ other_pages = 2..(total_pages - 1)
28
+ other_pages.each do |page|
29
+ uri = @api.assemble_uri base_url, filters.merge(page: page)
30
+ result = @api.request uri
31
+ result.dig('data', @data_key).each { y.yield _1 }
32
+ end
33
+
34
+ last_page.dig('data', @data_key).each { y.yield _1 }
35
+ end
36
+ end
37
+
38
+ super @enum
39
+ end
40
+
41
+ def first_page
42
+ @first_page ||=
43
+ begin
44
+ uri = @api.assemble_uri @base_url, @filters
45
+ @api.request uri
46
+ end
47
+ end
48
+
49
+ def total_pages
50
+ first_page.dig('data', 'paginator', 'pageCount') || 0
51
+ end
52
+
53
+ def last_page
54
+ return first_page if total_pages < 2
55
+
56
+ @last_page ||=
57
+ begin
58
+ uri = @api.assemble_uri @base_url, @filters.merge(page: total_pages)
59
+ @api.request uri
60
+ end
61
+ end
62
+
63
+ def size
64
+ first_page['data']['paginator']['totalCount']
65
+ end
66
+ end
67
+
21
68
  def self.version
22
- '0.0.5'
69
+ '0.0.10'
23
70
  end
24
71
 
25
72
  def self.ar_on_token_error(model)
@@ -39,25 +86,83 @@ class Shoptet
39
86
  end
40
87
  end
41
88
 
89
+ def self.install url, redirect_url, client_id, client_secret, code
90
+ data = {
91
+ 'redirect_uri' => redirect_url,
92
+ 'client_id' => client_id,
93
+ 'client_secret' => client_secret,
94
+ 'code' => code,
95
+ 'grant_type' => 'authorization_code',
96
+ 'scope' => 'api'
97
+ }
98
+
99
+ Shoptet::Request.post url, data
100
+ end
101
+
102
+ def self.login_token url, code, client_id, client_secret, redirect_url
103
+ data = {
104
+ code: code,
105
+ grant_type: 'authorization_code',
106
+ client_id: client_id,
107
+ client_secret: client_secret,
108
+ redirect_uri: redirect_url,
109
+ scope: 'basic_eshop'
110
+ }
111
+
112
+ Shoptet::Request.post url, data
113
+ end
114
+
115
+ def self.basic_eshop url, access_token
116
+ Shoptet::Request.get url, { 'Authorization' => "Bearer #{access_token}" }
117
+ end
118
+
42
119
  attr_accessor :api_token
43
120
 
44
- def initialize(oauth_url, oauth_token, api_token = nil, on_token_error = nil)
121
+ def initialize oauth_url:, oauth_token:, shop_url:, client_id:, api_token: nil, on_token_error: nil
45
122
  @oauth_url = oauth_url
46
123
  @oauth_token = oauth_token
124
+ @shop_url = shop_url
125
+ @client_id = client_id
47
126
  @api_token = api_token
48
127
  @on_token_error = on_token_error || DEFAULT_ON_TOKEN_ERROR
49
128
  end
50
129
 
51
- #TODO: return ['data'] already
130
+ def endpoints api_params = {}
131
+ enumerize 'https://api.myshoptet.com/api/system/endpoints', api_params
132
+ end
133
+
134
+ def endpoint_approved? endpoint
135
+ @approved_endpoints ||= endpoints
136
+
137
+ @approved_endpoints.any? { _1['endpoint'] == endpoint }
138
+ end
139
+
140
+ def authorize_url redirect_url, state
141
+ query = {
142
+ client_id: @client_id,
143
+ state: state,
144
+ scope: 'basic_eshop',
145
+ response_type: 'code',
146
+ redirect_uri: redirect_url
147
+ }.to_query
148
+
149
+ URI("#{@shop_url}action/OAuthServer/authorize?#{query}").to_s
150
+ end
151
+
52
152
  def shop_info api_params = {}
53
- request 'https://api.myshoptet.com/api/eshop'
153
+ url = assemble_uri 'https://api.myshoptet.com/api/eshop', api_params
154
+ result = request url
155
+ result['data']
54
156
  end
55
157
 
56
158
  def design_info api_params = {}
57
- request 'https://api.myshoptet.com/api/eshop/design'
159
+ url = assemble_uri 'https://api.myshoptet.com/api/eshop/design', api_params
160
+ result = request url
161
+
162
+ result['data']
58
163
  end
59
164
 
60
- def warehouses api_params = {}
165
+ def stocks api_params = {}
61
166
  enumerize 'https://api.myshoptet.com/api/stocks', api_params
62
167
  end
63
168
 
@@ -70,6 +175,11 @@ class Shoptet
70
175
  enumerize uri, api_params
71
176
  end
72
177
 
178
+ def stocks_movements warehouse_id, api_params = {}
179
+ uri = "https://api.myshoptet.com/api/stocks/#{warehouse_id}/movements"
180
+ enumerize uri, api_params
181
+ end
182
+
73
183
  def product_categories api_params = {}
74
184
  enumerize 'https://api.myshoptet.com/api/categories', api_params
75
185
  end
@@ -100,13 +210,13 @@ class Shoptet
100
210
  def order code, api_params = {}
101
211
  uri = "https://api.myshoptet.com/api/orders/#{code}"
102
212
  result = request assemble_uri(uri, api_params)
103
- result.dig('data', 'order')
213
+ result.dig 'data', 'order'
104
214
  end
105
215
 
106
216
  def product guid, api_params = {}
107
217
  uri = "https://api.myshoptet.com/api/products/#{guid}"
108
218
  result = request assemble_uri(uri, api_params)
109
- result.dig('data')
219
+ result['data']
110
220
  end
111
221
 
112
222
  def new_api_token
@@ -118,35 +228,6 @@ class Shoptet
118
228
  result.fetch 'access_token'
119
229
  end
120
230
 
121
- private
122
-
123
- def assemble_uri base, params = {}
124
- u = URI(base)
125
- u.query = URI.encode_www_form(params) if params.any?
126
-
127
- u.to_s
128
- end
129
-
130
- def enumerize base_uri, filters = {}, data_key = nil
131
- data_key ||= URI(base_uri).path.split('/').last
132
- uri = assemble_uri base_uri, filters
133
- size_proc = -> () { request(uri)['data']['paginator']['totalCount'] }
134
-
135
- Enumerator.new(size_proc) do |y|
136
- first_page = request uri
137
- total_pages = first_page.dig('data', 'paginator', 'pageCount') || 0
138
- other_pages = 2..total_pages
139
-
140
- first_page.dig('data', data_key).each { y.yield _1 }
141
-
142
- other_pages.each do |page|
143
- uri = assemble_uri base_uri, filters.merge(page: page)
144
- result = request uri
145
- result.dig('data', data_key).each { y.yield _1 }
146
- end
147
- end
148
- end
149
-
150
231
  def request uri, retry_on_token_error = true
151
232
  headers = { 'Shoptet-Access-Token' => @api_token,
152
233
  'Content-Type' => 'application/vnd.shoptet.v1.0' }
@@ -166,6 +247,12 @@ class Shoptet
166
247
  end
167
248
  end
168
249
 
250
+ private
251
+
252
+ def enumerize base_url, filters = {}, data_key = nil
253
+ ApiEnumerator.new base_url, filters, data_key, self
254
+ end
255
+
169
256
  def handle_errors result, uri, headers
170
257
  error = result['error']
171
258
  errors = result['errors'] || []
@@ -179,28 +266,10 @@ class Shoptet
179
266
  elsif errors.any? { |err| err["errorCode"] == 'invalid-token-no-rights' }
180
267
  raise InvalidTokenNoRights
181
268
  else
182
- additional_data = {
183
- uri: uri,
184
- headers: scrub_sensitive_headers(headers)
185
- }
186
-
187
- raise Error.new result, additional_data
269
+ raise Error.new result
188
270
  end
189
271
  end
190
272
 
191
273
  token_errors
192
274
  end
193
-
194
- def scrub_sensitive_headers headers
195
- scrubbed = {}
196
-
197
- to_scrub = ['Shoptet-Access-Token', 'Authorization']
198
- to_scrub.each do |header|
199
- if headers[header]
200
- scrubbed[header] = "#{headers[header][0..20]}..."
201
- end
202
- end
203
-
204
- headers.merge scrubbed
205
- end
206
275
  end
@@ -3,6 +3,15 @@ require 'net/http'
3
3
  #TODO: keep_alive_timeout ?
4
4
 
5
5
  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
+
6
15
  class Request
7
16
  def self.get uri, headers
8
17
  attempt ||= 0
@@ -28,5 +37,16 @@ class Shoptet
28
37
  rescue Net::OpenTimeout
29
38
  retry if attempt < 4
30
39
  end
40
+
41
+ def self.post uri, body
42
+ req = Net::HTTP::Post.new uri
43
+ req.set_form_data body
44
+
45
+ res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
46
+ http.request req
47
+ end
48
+
49
+ JSON.parse res.body
50
+ end
31
51
  end
32
52
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shoptet
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.10
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-09 00:00:00.000000000 Z
11
+ date: 2020-11-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: irb