stock_shaker 0.3.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 +7 -0
- data/.gitignore +18 -0
- data/.rspec +3 -0
- data/.rubocop.yml +53 -0
- data/.travis.yml +9 -0
- data/CHANGELOG.md +47 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +21 -0
- data/README.md +263 -0
- data/Rakefile +7 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/stock_shaker.rb +18 -0
- data/lib/stock_shaker/client/constants.rb +23 -0
- data/lib/stock_shaker/client/jd_central_op.rb +72 -0
- data/lib/stock_shaker/client/lazada_op.rb +116 -0
- data/lib/stock_shaker/client/shopee_op.rb +73 -0
- data/lib/stock_shaker/concern/utility.rb +18 -0
- data/lib/stock_shaker/config.rb +26 -0
- data/lib/stock_shaker/config/lazada_config.rb +15 -0
- data/lib/stock_shaker/config/shopee_config.rb +15 -0
- data/lib/stock_shaker/date_util.rb +15 -0
- data/lib/stock_shaker/request/jd_central_op.rb +40 -0
- data/lib/stock_shaker/request/lazada_op.rb +35 -0
- data/lib/stock_shaker/request/shopee_op.rb +34 -0
- data/lib/stock_shaker/version.rb +6 -0
- data/media/badge/lazada/generate_access_token.svg +1 -0
- data/media/badge/lazada/get_orders-get-green.svg +1 -0
- data/media/badge/lazada/lazada_api-order--api-yellow.svg +1 -0
- data/media/badge/lazada/lazada_api-system--api-yellow.svg +1 -0
- data/media/badge/lazada/refresh_access_token.svg +1 -0
- data/media/badge/made_with-shield_io-green.svg +1 -0
- data/media/badge/market_place_support/love-lazada-sky-blue.svg +1 -0
- data/media/badge/market_place_support/love-shopee-orange.svg +1 -0
- data/media/badge/shopee/get_orders_list-post-green.svg +1 -0
- data/media/badge/shopee/shopee_api-order--api-yellow.svg +1 -0
- data/media/badge/stock_shaker-new-orange.svg +1 -0
- data/media/icon.png +0 -0
- data/stock_shaker.gemspec +46 -0
- metadata +161 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 8ce3b6719c4b592c6a1d9756bc5bf8b6af2a67d28254e20d65788c345adf58f4
|
4
|
+
data.tar.gz: 99d5b98a57cb2355de108120850c359911084b803a792417bcc50be54e17c7e6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0ae4f8a29179046e7204961018f5637373852b37315f81d5109c4858afe7c2a7e11f320227bcb7c52839f99f233b40eee6d615dcf2edcc37c978b5168e563672
|
7
|
+
data.tar.gz: 0fb6fec3588c364d85c1c8f02b194a5e1b2dc7c7d4a631bdc6dfb304c18c0e8074dd85b0fa49a6298e4d66d9df29a3d1d4cc2d4c3bb01ada71051c1e1c3ff7ee
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: '2.3'
|
3
|
+
|
4
|
+
Metrics/BlockLength:
|
5
|
+
Exclude:
|
6
|
+
- 'stock_shaker.gemspec'
|
7
|
+
|
8
|
+
# Commonly used screens these days easily fit more than 80 characters.
|
9
|
+
Metrics/LineLength:
|
10
|
+
Max: 140
|
11
|
+
|
12
|
+
# Too short methods lead to extraction of single-use methods, which can make
|
13
|
+
# the code easier to read (by naming things), but can also clutter the class
|
14
|
+
Metrics/MethodLength:
|
15
|
+
Max: 20
|
16
|
+
|
17
|
+
# The guiding principle of classes is SRP, SRP can't be accurately measured by LoC
|
18
|
+
Metrics/ClassLength:
|
19
|
+
Max: 1500
|
20
|
+
|
21
|
+
# Single quotes being faster is hardly measurable and only affects parse time.
|
22
|
+
# Enforcing double quotes reduces the times where you need to change them
|
23
|
+
# when introducing an interpolation. Use single quotes only if their semantics
|
24
|
+
# are needed.
|
25
|
+
#Style/StringLiterals:
|
26
|
+
# EnforcedStyle: double_quotes
|
27
|
+
|
28
|
+
# Frozen string literals may be default in Ruby 3.0. Default Enabled: true
|
29
|
+
# See more: https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Style/FrozenStringLiteralComment
|
30
|
+
FrozenStringLiteralComment:
|
31
|
+
Enabled: true
|
32
|
+
|
33
|
+
# Style/ClassAndModuleChildren:
|
34
|
+
# EnforcedStyle: compact
|
35
|
+
|
36
|
+
# We do not need to support Ruby 1.9, so this is good to use.
|
37
|
+
Style/SymbolArray:
|
38
|
+
Enabled: true
|
39
|
+
|
40
|
+
# Disabled warning DateTime
|
41
|
+
Style/DateTime:
|
42
|
+
Enabled: false
|
43
|
+
|
44
|
+
# Disabled Style/Documentation
|
45
|
+
Style/Documentation:
|
46
|
+
Enabled: false
|
47
|
+
|
48
|
+
# Disabled เพื่อคอมเม้นภาษาไทยด้ายยยยยยยย
|
49
|
+
Style/AsciiComments:
|
50
|
+
Enabled: false
|
51
|
+
|
52
|
+
Metrics/AbcSize:
|
53
|
+
Max: 20
|
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
0.3.5 / 2019-10-11
|
2
|
+
---
|
3
|
+
- Rework perform method in `StockShaker::Client::LazadaOP`
|
4
|
+
|
5
|
+
0.3.4 / 2019-09-30
|
6
|
+
---
|
7
|
+
- Create new `StockShaker::Concern::Utility`
|
8
|
+
- Rework Utility -> DateUtil
|
9
|
+
- Rework `client/lazada_op`
|
10
|
+
- Remove `active_support` from dependencies
|
11
|
+
|
12
|
+
0.3.3 / 2018-10-8
|
13
|
+
---
|
14
|
+
- assign `business_params`
|
15
|
+
```ruby
|
16
|
+
# lib/stock_shaker/request/jd_central_op.rb
|
17
|
+
# JDCentralOP#add_business_params line 24 - 26
|
18
|
+
|
19
|
+
@business_params = {
|
20
|
+
param_json: hash.to_json
|
21
|
+
}
|
22
|
+
```
|
23
|
+
|
24
|
+
0.3.2 / 2018-10-4
|
25
|
+
---
|
26
|
+
- Added JD Central (TH) Integration
|
27
|
+
|
28
|
+
0.3.1 / 2018-08-14
|
29
|
+
---
|
30
|
+
- Return ::Client::ShopeeOP.perform as Object type not a JSON
|
31
|
+
|
32
|
+
0.3.0 / 2018-08-03
|
33
|
+
---
|
34
|
+
- Merge conflict
|
35
|
+
|
36
|
+
|
37
|
+
0.2.9 / 2018-08-3
|
38
|
+
---
|
39
|
+
- Added `rescue StandardError` for `ShopeeOP::Client.perform`
|
40
|
+
|
41
|
+
0.2.8 / 2018-07-26
|
42
|
+
---
|
43
|
+
- Update gemspec
|
44
|
+
|
45
|
+
0.2.7 / 2018-07-26
|
46
|
+
---
|
47
|
+
- Refactoring and publish beta version.
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2018 Nathakorn Chaninthanadecha
|
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,263 @@
|
|
1
|
+
<p align="center">
|
2
|
+
<a href="https://rubygems.org/gems/stock_shaker"><img src="https://github.com/nijicha/stock_shaker/blob/master/media/icon.png?raw=true" height="240" alt="Stock Shaker Logo" /></a>
|
3
|
+
<h3 align="center">Stock Shaker</h3>
|
4
|
+
<p align="center">Unofficial Rubygems for Thailand eCommerce Marketplace</p>
|
5
|
+
|
6
|
+
<p align="center">
|
7
|
+
<img src="https://img.shields.io/github/stars/nijicha/stock_shaker.svg?style=for-the-badge&label=Stars" alt="Github Stars" >
|
8
|
+
<a href="https://rubygems.org/gems/stock_shaker"><img src="https://img.shields.io/gem/v/stock_shaker.svg?style=for-the-badge" alt="Gem Version"></a>
|
9
|
+
<a href="https://travis-ci.org/nijicha/stock_shaker"><img src="https://img.shields.io/travis/nijicha/stock_shaker/master.svg?style=for-the-badge" alt="Branch master Travis-ci Build Status"></a>
|
10
|
+
<a href="https://github.com/nijicha/stock_shaker/blob/master/LICENSE.txt"><img src="https://img.shields.io/github/license/nijicha/stock_shaker.svg?style=for-the-badge" alt="License" /></a>
|
11
|
+
</p>
|
12
|
+
<p align="center">
|
13
|
+
<a href="https://forthebadge.com"><img src="https://forthebadge.com/images/badges/built-with-love.svg" alt="For The Badge Built with Love" height="28"></a>
|
14
|
+
<a href="https://forthebadge.com"><img src="https://forthebadge.com/images/badges/made-with-ruby.svg" alt="For The Badge Made with Ruby" height="28"></a>
|
15
|
+
<a href="https://shields.io/"><img src="https://github.com/nijicha/stock_shaker/blob/master/media/badge/made_with-shield_io-green.svg" alt="Shield.io Made with shield.io" /></a>
|
16
|
+
</p>
|
17
|
+
<p align="center">
|
18
|
+
<a href="https://www.lazada.co.th/"><img src="https://github.com/nijicha/stock_shaker/blob/master/media/badge/market_place_support/love-lazada-sky-blue.svg" alt="Love Lazada" /></a>
|
19
|
+
<a href="https://www.shopee.co.th/"><img src="https://github.com/nijicha/stock_shaker/blob/master/media/badge/market_place_support/love-shopee-orange.svg" alt="Love Shopee" /></a>
|
20
|
+
</p>
|
21
|
+
</p>
|
22
|
+
|
23
|
+
A gems used to kick off API of eCommerce in Thailand. This gems inspired from [Official Lazada Open Platform Gems](https://rubygems.org/gems/lazop_api_client/versions/1.2.5)
|
24
|
+
|
25
|
+
## Installation
|
26
|
+
|
27
|
+
**StockShaker**'s installation is Easy! Add this line to your application's `Gemfile`
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
gem 'stock_shaker', '~> 0.3.5'
|
31
|
+
```
|
32
|
+
|
33
|
+
If you'd rather install **StockShaker** with ruby-versions below than `2.4`.
|
34
|
+
|
35
|
+
You need to add `openssl` as dependencies in `Gemfile`
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
# Gemfile
|
39
|
+
|
40
|
+
gem 'stock_shaker', '~> 0.3.5'
|
41
|
+
gem 'openssl'
|
42
|
+
```
|
43
|
+
|
44
|
+
And then execute:
|
45
|
+
|
46
|
+
$ bundle install
|
47
|
+
|
48
|
+
Or install it yourself as:
|
49
|
+
|
50
|
+
$ gem install stock_shaker
|
51
|
+
|
52
|
+
## Usage
|
53
|
+
|
54
|
+
### Configurable
|
55
|
+
|
56
|
+
- Create `stock_shaker_config.rb` in `config/initializer`
|
57
|
+
- Please ensure you already configured it.
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
# config/initializer/stock_shaker_config.rb
|
61
|
+
StockShaker.configure do |config|
|
62
|
+
# Lazada Configuration
|
63
|
+
config.lazada_config.app_key = ENV['YOUR_LAZADA_APP_KEY']
|
64
|
+
config.lazada_config.app_secret_key = ENV['YOUR_LAZADA_APP_SECRET_KEY']
|
65
|
+
config.lazada_config.redirect_url = ENV['YOUR_LAZADA_REDIRECT_URL']
|
66
|
+
|
67
|
+
# Shopee Configuration
|
68
|
+
config.shopee_config.partner_id = ENV['YOUR_SHOPEE_PARTNER_ID']
|
69
|
+
config.shopee_config.secret_key = ENV['YOUR_SHOPEE_SECRET_KEY']
|
70
|
+
config.shopee_config.redirect_url = ENV['YOUR_SHOPEE_REDIRECT_URL']
|
71
|
+
end
|
72
|
+
```
|
73
|
+
### Do Authorization Link
|
74
|
+
|
75
|
+
<img src="https://github.com/nijicha/stock_shaker/blob/master/media/badge/stock_shaker-new-orange.svg" alt="NEW API" />
|
76
|
+
|
77
|
+
<b>* You should be define the `StockShaker.configure` before typing this command.</b>
|
78
|
+
|
79
|
+
#### Lazada
|
80
|
+
```ruby
|
81
|
+
StockShaker::Client::LazadaOP.do_authorization_link
|
82
|
+
|
83
|
+
=> "https://auth.lazada.com/oauth/authorize?client_id=YOUR_LAZADA_APP_KEY&force_auth=true&redirect_uri=YOUR_LAZADA_REDIRECT_URL&response_type=code"
|
84
|
+
```
|
85
|
+
|
86
|
+
#### Shopee
|
87
|
+
```ruby
|
88
|
+
StockShaker::Client::ShopeeOP.do_authorization_link
|
89
|
+
|
90
|
+
=> "https://partner.shopeemobile.com/api/v1/shop/auth_partner?id=YOUR_SHOPEE_PARTNER_ID&redirect=YOUR_SHOPEE_REDIRECT_URL&token=AUTHORIZATION_TOKEN"
|
91
|
+
```
|
92
|
+
|
93
|
+
### Lazada Open Platform
|
94
|
+
|
95
|
+
- <img src="https://github.com/nijicha/stock_shaker/blob/master/media/badge/lazada/lazada_api-system--api-yellow.svg" alt="SystemAPI" />
|
96
|
+
|
97
|
+
- <a href="https://open.lazada.com/doc/api.htm?spm=a2o9m.11193487.0.0.3ac413feha8qCs#/api?cid=11&path=/auth/token/create">
|
98
|
+
<img src="https://github.com/nijicha/stock_shaker/blob/master/media/badge/lazada/generate_access_token.svg" alt="Generate Access Token" />
|
99
|
+
</a>
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
server_url = StockShaker::Client::LAZADA_API_GATEWAY_URL_TH
|
103
|
+
lazada_client = StockShaker::Client::LazadaOP.new(server_url)
|
104
|
+
lazada_request = StockShaker::Request::LazadaOP.new('/auth/token/create', :post)
|
105
|
+
lazada_request_params = { code: 'YOUR_AUTHORIZATION_CODE' }
|
106
|
+
lazada_request_params.each { |key, value| request.add_lazada_api_params(key.to_s, value.to_s) }
|
107
|
+
response = lazada_client.execute(lazada_request)
|
108
|
+
response.success?
|
109
|
+
response.body
|
110
|
+
```
|
111
|
+
|
112
|
+
- <a href="https://open.lazada.com/doc/api.htm?spm=a2o9m.11193487.0.0.3ac413feha8qCs#/api?cid=11&path=/auth/token/refresh">
|
113
|
+
<img src="https://github.com/nijicha/stock_shaker/blob/master/media/badge/lazada/refresh_access_token.svg" alt="Refresh Access Token" />
|
114
|
+
</a>
|
115
|
+
|
116
|
+
```ruby
|
117
|
+
server_url = StockShaker::Client::LAZADA_API_GATEWAY_URL_TH
|
118
|
+
lazada_client = StockShaker::Client::LazadaOP.new(server_url)
|
119
|
+
lazada_request = StockShaker::Request::LazadaOP.new('/auth/token/refresh', :post)
|
120
|
+
lazada_request_params = { refresh_token: 'YOUR_REFRESH_TOKEN' }
|
121
|
+
lazada_request_params.each { |key, value| request.add_lazada_api_params(key.to_s, value.to_s) }
|
122
|
+
response = lazada_client.execute(lazada_request)
|
123
|
+
response.success?
|
124
|
+
response.body
|
125
|
+
```
|
126
|
+
|
127
|
+
- <img src="https://github.com/nijicha/stock_shaker/blob/master/media/badge/lazada/lazada_api-order--api-yellow.svg" alt="Lazada OrderAPI" />
|
128
|
+
|
129
|
+
- <a href="https://open.lazada.com/doc/api.htm?spm=a2o9m.11193535.0.0.62a738e4DBO8DQ#/api?cid=8&path=/orders/get">
|
130
|
+
<img src="https://github.com/nijicha/stock_shaker/blob/master/media/badge/lazada/get_orders-get-green.svg" alt="OrderAPI GetOrders" />
|
131
|
+
</a>
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
server_url = StockShaker::Client::LAZADA_API_GATEWAY_URL_TH
|
135
|
+
access_token = ENV['YOUR_ACCESS_TOKEN']
|
136
|
+
lazada_client = StockShaker::Client::LazadaOP.new(server_url)
|
137
|
+
lazada_request = StockShaker::Request::LazadaOP.new('/orders/get', :get)
|
138
|
+
|
139
|
+
# Get orders since last two days by update_after
|
140
|
+
days_backwards = 2 # Get backwards 2 days
|
141
|
+
update_after = StockShaker::DateUtil.datetime_to_iso8601(DateTime.now.beginning_of_day - days_backwards.days)
|
142
|
+
|
143
|
+
lazada_request_params = {
|
144
|
+
created_before: '2018-02-10T16:00:00+07:00',
|
145
|
+
created_after: '2017-02-10T09:00:00+07:00',
|
146
|
+
status: 'shipped',
|
147
|
+
update_before: '2018-02-10T16:00:00+07:00',
|
148
|
+
sort_direction: 'DESC',
|
149
|
+
offset: 0,
|
150
|
+
limit: 100,
|
151
|
+
update_after: update_after,
|
152
|
+
sort_by: 'updated_at'
|
153
|
+
}
|
154
|
+
|
155
|
+
lazada_request_params.each { |key, value| request.add_lazada_api_params(key.to_s, value.to_s) }
|
156
|
+
response = lazada_client.execute(lazada_request, access_token)
|
157
|
+
puts response.success?
|
158
|
+
puts response.body
|
159
|
+
```
|
160
|
+
|
161
|
+
### Shopee Open Platform
|
162
|
+
|
163
|
+
- <img src="https://github.com/nijicha/stock_shaker/blob/master/media/badge/shopee/shopee_api-order--api-yellow.svg" alt="Shopee OrderAPI" />
|
164
|
+
|
165
|
+
- <a href="https://open.shopee.com/documents?module=4&type=1&id=399">
|
166
|
+
<img src="https://github.com/nijicha/stock_shaker/blob/master/media/badge/shopee/get_orders_list-post-green.svg" alt="OrderAPI GetOrdersList" />
|
167
|
+
</a>
|
168
|
+
|
169
|
+
```ruby
|
170
|
+
server_url = StockShaker::Client::SHOPEE_API_GATEWAY_URL_TH
|
171
|
+
shop_id = ENV['YOUR_SHOP_ID']
|
172
|
+
|
173
|
+
update_time_from = StockShaker::DateUtil.datetime_to_timestamp(DateTime.now.beginning_of_day - 2.days)
|
174
|
+
update_time_to = StockShaker::DateUtil.datetime_to_timestamp(DateTime.now)
|
175
|
+
|
176
|
+
client = StockShaker::Client::ShopeeOP.new(server_url, shop_id)
|
177
|
+
request = StockShaker::Request::ShopeeOP.new('/orders/basics', :post)
|
178
|
+
|
179
|
+
request.add_shopee_api_params({
|
180
|
+
update_time_from: update_time_from,
|
181
|
+
update_time_to: update_time_to,
|
182
|
+
pagination_entries_per_page: 100,
|
183
|
+
pagination_offset: 0
|
184
|
+
})
|
185
|
+
|
186
|
+
response = client.execute(request)
|
187
|
+
puts response.body
|
188
|
+
```
|
189
|
+
|
190
|
+
## Compatibility
|
191
|
+
We supported
|
192
|
+
- Ruby MRI 2.2+
|
193
|
+
- Rails 5.0+
|
194
|
+
|
195
|
+
## Need helps!
|
196
|
+
- Contributed this gems!
|
197
|
+
- Write Test!
|
198
|
+
|
199
|
+
## TODO
|
200
|
+
|
201
|
+
### Core
|
202
|
+
|
203
|
+
- [x] Configurable
|
204
|
+
- [ ] Validation
|
205
|
+
- [ ] Generator
|
206
|
+
- [ ] Write Rspec
|
207
|
+
- [ ] Logger
|
208
|
+
- [ ] Sentry.io Integration
|
209
|
+
|
210
|
+
### Lazada
|
211
|
+
See more: [Lazada Open Platform Documentation](https://open.lazada.com/doc/api.htm?spm=a2o9m.11193535.0.0.62a738e4DBO8DQ#/api?cid=8&path=/order/document/get)
|
212
|
+
|
213
|
+
- [ ] Integrate with API reference
|
214
|
+
- [ ] Order API
|
215
|
+
- [x] GetOrders
|
216
|
+
- [x] GetMultipleOrderItems
|
217
|
+
- [ ] Product API
|
218
|
+
- [x] GetProducts
|
219
|
+
- [x] UpdatePriceQuantity
|
220
|
+
- [ ] Finance API
|
221
|
+
- [ ] Logistics API
|
222
|
+
- [ ] Seller API
|
223
|
+
- [x] System API
|
224
|
+
- [x] Generate Access Token
|
225
|
+
- [x] Refresh Access Token
|
226
|
+
- [ ] DataMoat API
|
227
|
+
|
228
|
+
### Shopee
|
229
|
+
See more: [Shopee Open Platform Documentation](https://open.shopee.com/documents)
|
230
|
+
- [ ] Integrate with API reference
|
231
|
+
- ItemAPI
|
232
|
+
- [x] GetItemsList (/items/get)
|
233
|
+
- [x] GetItemDetails (/item/get)
|
234
|
+
- [x] UpdateStock (/items/update_stock)
|
235
|
+
- [x] UpdateStockBatch (/items/update/items_stock)
|
236
|
+
- [x] UpdateVariationStock (/items/update_variation_stock)
|
237
|
+
- [x] UpdateVariationStockBatch (/items/update/vars_stock)
|
238
|
+
- [x] InsertItemImg (/item/img/insert)
|
239
|
+
- [x] DeleteItemImg (/item/img/delete)
|
240
|
+
- OrderAPI
|
241
|
+
- [x] GetOrdersList (/orders/basics)
|
242
|
+
- [x] GetOrdersDetail (/orders/detail)
|
243
|
+
- [x] GetEscrowDetails (/orders/my_income)
|
244
|
+
- ShopAPI
|
245
|
+
- [x] GetPerformance (/shop/performance)
|
246
|
+
|
247
|
+
### JD Central
|
248
|
+
|
249
|
+
- [ ] Integrate with API reference
|
250
|
+
|
251
|
+
## Development
|
252
|
+
1. `git clone https://github.com/nijicha/stock_shaker.git`
|
253
|
+
2. `bundle install`
|
254
|
+
|
255
|
+
## Contributing
|
256
|
+
|
257
|
+
Bug reports and pull requests are welcome on GitHub at [https://github.com/nijicha/stock_shaker](https://github.com/nijicha/stock_shaker).
|
258
|
+
|
259
|
+
This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
260
|
+
|
261
|
+
## License
|
262
|
+
|
263
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'stock_shaker'
|
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
data/lib/stock_shaker.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'stock_shaker/client/constants'
|
4
|
+
require 'stock_shaker/client/lazada_op'
|
5
|
+
require 'stock_shaker/client/shopee_op'
|
6
|
+
require 'stock_shaker/client/jd_central_op'
|
7
|
+
|
8
|
+
require 'stock_shaker/concern/utility'
|
9
|
+
|
10
|
+
require 'stock_shaker/config'
|
11
|
+
|
12
|
+
require 'stock_shaker/request/lazada_op'
|
13
|
+
require 'stock_shaker/request/shopee_op'
|
14
|
+
require 'stock_shaker/request/jd_central_op'
|
15
|
+
|
16
|
+
require 'stock_shaker/date_util'
|
17
|
+
|
18
|
+
require 'stock_shaker/version'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StockShaker
|
4
|
+
module Client
|
5
|
+
# LAZADA
|
6
|
+
LAZADA_API_AUTH_URL = 'https://auth.lazada.com/oauth/authorize'.freeze
|
7
|
+
LAZADA_API_AUTHENTICATION_URL = 'https://auth.lazada.com/rest'.freeze
|
8
|
+
LAZADA_API_GATEWAY_URL_SG = 'https://api.lazada.sg/rest'.freeze
|
9
|
+
LAZADA_API_GATEWAY_URL_MY = 'https://api.lazada.com.my/rest'.freeze
|
10
|
+
LAZADA_API_GATEWAY_URL_VN = 'https://api.lazada.vn/rest'.freeze
|
11
|
+
LAZADA_API_GATEWAY_URL_TH = 'https://api.lazada.co.th/rest'.freeze
|
12
|
+
LAZADA_API_GATEWAY_URL_PH = 'https://api.lazada.com.ph/rest'.freeze
|
13
|
+
LAZADA_API_GATEWAY_URL_ID = 'https://api.lazada.co.id/rest'.freeze
|
14
|
+
|
15
|
+
# SHOPEE
|
16
|
+
SHOPEE_API_AUTH_URL = 'https://partner.shopeemobile.com/api/v1/shop/auth_partner'.freeze
|
17
|
+
SHOPEE_API_CANCEL_AUTH_URL = 'https://partner.shopeemobile.com/api/v1/shop/cancel_auth_partner'.freeze
|
18
|
+
SHOPEE_API_GATEWAY_URL_TH = 'https://partner.shopeemobile.com/api/v1'.freeze
|
19
|
+
|
20
|
+
# JD_CENTRAL
|
21
|
+
JD_CENTRAL_API_GATEWAY_URL_TH = 'https://open.jd.co.th/api'.freeze
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'digest'
|
4
|
+
require 'openssl'
|
5
|
+
require 'rest-client'
|
6
|
+
|
7
|
+
module StockShaker
|
8
|
+
module Client
|
9
|
+
class JDCentralOP
|
10
|
+
attr_reader :common_params, :server_url, :app_secret
|
11
|
+
|
12
|
+
def initialize(server_url, app_secret)
|
13
|
+
@common_params = {
|
14
|
+
timestamp: DateTime.now.strftime('%F %T.%L%z'),
|
15
|
+
format: 'json',
|
16
|
+
v: '1.0'
|
17
|
+
}
|
18
|
+
|
19
|
+
@server_url = server_url
|
20
|
+
@app_secret = app_secret
|
21
|
+
|
22
|
+
validates!
|
23
|
+
end
|
24
|
+
|
25
|
+
def execute(request)
|
26
|
+
request_params = @common_params.merge(**request.api_params, **request.business_params)
|
27
|
+
request_params[:sign] = do_signature(request_params)
|
28
|
+
|
29
|
+
request.add_header_params('charset', 'utf-8')
|
30
|
+
|
31
|
+
perform(request, request_params.as_json)
|
32
|
+
end
|
33
|
+
|
34
|
+
def do_signature(request_params)
|
35
|
+
# Sort key by ASCII rule
|
36
|
+
sorted_params = request_params.sort_by { |key, _value| key }
|
37
|
+
|
38
|
+
# Create sign_base_string
|
39
|
+
sign_base_string = @app_secret
|
40
|
+
sorted_params.each { |key, value| sign_base_string += "#{key}#{value}" }
|
41
|
+
sign_base_string += @app_secret
|
42
|
+
|
43
|
+
# Conditional sign by sign_method
|
44
|
+
if request_params[:sign_method].include?('hmac')
|
45
|
+
digest = OpenSSL::Digest.new('sha256')
|
46
|
+
OpenSSL::HMAC.hexdigest(digest, @app_secret, sign_base_string).upcase
|
47
|
+
else
|
48
|
+
Digest::MD5.hexdigest(sign_base_string).upcase
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def perform(request, request_params)
|
53
|
+
RestClient::Request.execute(
|
54
|
+
method: request.http_method,
|
55
|
+
payload: request_params,
|
56
|
+
url: @server_url,
|
57
|
+
headers: request.header_params
|
58
|
+
)
|
59
|
+
rescue StandardError => err
|
60
|
+
err
|
61
|
+
end
|
62
|
+
|
63
|
+
def validates!
|
64
|
+
raise 'server_url is required' unless @server_url
|
65
|
+
raise 'app_secret is required' unless @app_secret
|
66
|
+
end
|
67
|
+
|
68
|
+
# TODO: May be JD Central issued this in the future
|
69
|
+
def self.do_authorization_link; end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'openssl'
|
5
|
+
require 'rest-client'
|
6
|
+
|
7
|
+
require_relative '../concern/utility'
|
8
|
+
|
9
|
+
module StockShaker
|
10
|
+
module Client
|
11
|
+
class LazadaOP
|
12
|
+
include Concern::Utility
|
13
|
+
|
14
|
+
attr_reader :common_params, :server_url, :rest_url
|
15
|
+
|
16
|
+
def initialize(server_url)
|
17
|
+
@common_params = {
|
18
|
+
app_key: StockShaker.config.lazada_config.app_key,
|
19
|
+
timestamp: (Time.now.to_f * 1000).to_i,
|
20
|
+
sign_method: 'sha256'
|
21
|
+
}
|
22
|
+
@server_url = server_url
|
23
|
+
@rest_url = nil
|
24
|
+
|
25
|
+
validates!
|
26
|
+
end
|
27
|
+
|
28
|
+
def execute(request, access_token = nil)
|
29
|
+
@common_params[:access_token] = access_token if access_token
|
30
|
+
@common_params[:sign] = do_signature(request.api_params, request.api_name)
|
31
|
+
@rest_url = do_rest_url(request.api_name)
|
32
|
+
if request.http_method == :post
|
33
|
+
perform_post(@rest_url, request)
|
34
|
+
else
|
35
|
+
perform_get(@rest_url, request)
|
36
|
+
end
|
37
|
+
|
38
|
+
rescue StandardError => err
|
39
|
+
raise "#{@rest_url}, HTTP_ERROR, #{err.message}"
|
40
|
+
end
|
41
|
+
|
42
|
+
def do_signature(api_params, api_name)
|
43
|
+
params = api_params.nil? ? @common_params : @common_params.merge(api_params)
|
44
|
+
sort_arrays = params.sort_by { |key, _value| key.to_s }
|
45
|
+
|
46
|
+
# See signature pattern : https://open.lazada.com/doc/doc.htm?spm=a2o9m.11193531.0.0.40ed6bbemuDwkW#?nodeId=10451&docId=108069
|
47
|
+
signature_base_string = api_name.to_s
|
48
|
+
sort_arrays.each { |key, value| signature_base_string += "#{key}#{value}" }
|
49
|
+
|
50
|
+
sign_digest = OpenSSL::Digest.new('sha256')
|
51
|
+
secret_key = StockShaker.config.lazada_config.app_secret_key
|
52
|
+
OpenSSL::HMAC.hexdigest(sign_digest, secret_key, signature_base_string).upcase
|
53
|
+
end
|
54
|
+
|
55
|
+
# REVIEW: Regarding to Lazada Open Platform Official rubygem
|
56
|
+
# @common_params didn't sort!!!!
|
57
|
+
# Can't use to_query method for @common_params
|
58
|
+
# Parse hash to query string by manually
|
59
|
+
def do_rest_url(api_name)
|
60
|
+
raise 'Signature should not be blank. Please generate signature by LazadaOP#do_signature.' if @common_params[:sign].blank?
|
61
|
+
length = @server_url.length
|
62
|
+
rest_url = @server_url[(length - 1)] == '/' ? @server_url.chomp!('/') : @server_url
|
63
|
+
|
64
|
+
common_params_string = ''
|
65
|
+
@common_params.each do |key, value|
|
66
|
+
common_params_string += '&' unless common_params_string.blank?
|
67
|
+
common_params_string += "#{key}=#{value}"
|
68
|
+
end
|
69
|
+
"#{rest_url + api_name}?#{common_params_string}"
|
70
|
+
end
|
71
|
+
|
72
|
+
# REVIEW: Regarding to Regarding to Lazada Open Platform Official rubygem
|
73
|
+
# header_params is unused.
|
74
|
+
def perform_get(rest_url, request)
|
75
|
+
query_params = request.api_params.blank? ? '' : to_query_params(request.api_params)
|
76
|
+
url = "#{rest_url}&#{query_params}"
|
77
|
+
|
78
|
+
response = RestClient::Request.execute(
|
79
|
+
method: request.http_method,
|
80
|
+
url: url,
|
81
|
+
headers: request.header_params,
|
82
|
+
read_timeout: 30,
|
83
|
+
open_timeout: 15
|
84
|
+
)
|
85
|
+
JSON.parse(response)
|
86
|
+
end
|
87
|
+
|
88
|
+
def perform_post(rest_url, request)
|
89
|
+
response = RestClient::Request.execute(
|
90
|
+
method: request.http_method,
|
91
|
+
url: rest_url,
|
92
|
+
payload: request.api_params,
|
93
|
+
headers: request.header_params,
|
94
|
+
read_timeout: 30,
|
95
|
+
open_timeout: 15
|
96
|
+
)
|
97
|
+
JSON.parse(response)
|
98
|
+
end
|
99
|
+
|
100
|
+
def validates!
|
101
|
+
raise 'server_url is required' unless @server_url
|
102
|
+
end
|
103
|
+
|
104
|
+
def self.do_authorization_link
|
105
|
+
params = {
|
106
|
+
response_type: 'code',
|
107
|
+
force_auth: true,
|
108
|
+
client_id: StockShaker.config.lazada_config.app_key,
|
109
|
+
redirect_uri: StockShaker.config.lazada_config.redirect_url
|
110
|
+
}
|
111
|
+
|
112
|
+
"#{StockShaker::Client::LAZADA_API_AUTH_URL}?#{to_query_params(params)}"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'digest'
|
4
|
+
require 'openssl'
|
5
|
+
require 'rest-client'
|
6
|
+
|
7
|
+
require_relative '../concern/utility'
|
8
|
+
|
9
|
+
module StockShaker
|
10
|
+
module Client
|
11
|
+
class ShopeeOP
|
12
|
+
include Concern::Utility
|
13
|
+
|
14
|
+
attr_reader :common_params, :server_url, :rest_url
|
15
|
+
|
16
|
+
def initialize(server_url, shop_id)
|
17
|
+
@common_params = {
|
18
|
+
shopid: shop_id.to_i,
|
19
|
+
partner_id: StockShaker.config.shopee_config.partner_id.to_i,
|
20
|
+
timestamp: DateTime.now.to_time.to_i
|
21
|
+
}
|
22
|
+
@server_url = server_url
|
23
|
+
@rest_url = nil
|
24
|
+
validates!
|
25
|
+
end
|
26
|
+
|
27
|
+
def execute(request)
|
28
|
+
request_params = @common_params.merge(request.api_params).to_json
|
29
|
+
@rest_url = "#{@server_url}#{request.api_name}"
|
30
|
+
|
31
|
+
signature = do_signature(@rest_url, request_params)
|
32
|
+
|
33
|
+
request.add_header_params('content-type', 'json')
|
34
|
+
request.add_header_params('Authorization', signature)
|
35
|
+
|
36
|
+
perform(@rest_url, request, request_params)
|
37
|
+
end
|
38
|
+
|
39
|
+
def do_signature(rest_url, request_params)
|
40
|
+
signature_base_string = "#{rest_url}|#{request_params}"
|
41
|
+
OpenSSL::HMAC.hexdigest('SHA256', StockShaker.config.shopee_config.secret_key, signature_base_string)
|
42
|
+
end
|
43
|
+
|
44
|
+
def perform(url, request, request_params)
|
45
|
+
RestClient::Request.execute(
|
46
|
+
method: request.http_method,
|
47
|
+
payload: request_params,
|
48
|
+
url: url,
|
49
|
+
headers: request.header_params
|
50
|
+
)
|
51
|
+
rescue StandardError => err
|
52
|
+
err
|
53
|
+
end
|
54
|
+
|
55
|
+
def validates!
|
56
|
+
raise 'server_url is required' unless @server_url
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.do_authorization_link
|
60
|
+
token_base_string = "#{StockShaker.config.shopee_config.secret_key}#{StockShaker.config.shopee_config.redirect_url}"
|
61
|
+
token = Digest::SHA256.hexdigest(token_base_string)
|
62
|
+
|
63
|
+
params = {
|
64
|
+
id: StockShaker.config.shopee_config.partner_id,
|
65
|
+
token: token,
|
66
|
+
redirect: StockShaker.config.shopee_config.redirect_url
|
67
|
+
}
|
68
|
+
|
69
|
+
"#{StockShaker::Client::SHOPEE_API_AUTH_URL}?#{to_query_params(params)}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StockShaker
|
4
|
+
module Concern
|
5
|
+
module Utility
|
6
|
+
def to_query_params(object)
|
7
|
+
base_string = ''
|
8
|
+
|
9
|
+
object.each do |key, value|
|
10
|
+
base_string += '&' if base_string.present?
|
11
|
+
base_string += "#{key}=#{value}"
|
12
|
+
end
|
13
|
+
|
14
|
+
base_string
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'config/lazada_config'
|
4
|
+
require_relative 'config/shopee_config'
|
5
|
+
|
6
|
+
module StockShaker
|
7
|
+
class << self
|
8
|
+
def configure
|
9
|
+
yield config
|
10
|
+
end
|
11
|
+
|
12
|
+
def config
|
13
|
+
@config ||= Config.new
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# TODO: Add validation
|
18
|
+
class Config
|
19
|
+
attr_accessor :lazada_config, :shopee_config
|
20
|
+
|
21
|
+
def initialize
|
22
|
+
@lazada_config = LazadaConfig.new
|
23
|
+
@shopee_config = ShopeeConfig.new
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StockShaker
|
4
|
+
class Config
|
5
|
+
class LazadaConfig
|
6
|
+
attr_accessor :app_key, :app_secret_key, :redirect_url
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@app_key = nil
|
10
|
+
@app_secret_key = nil
|
11
|
+
@redirect_url = nil
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StockShaker
|
4
|
+
class Config
|
5
|
+
class ShopeeConfig
|
6
|
+
attr_accessor :partner_id, :secret_key, :redirect_url
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@partner_id = nil
|
10
|
+
@secret_key = nil
|
11
|
+
@redirect_url = nil
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StockShaker
|
4
|
+
class DateUtil
|
5
|
+
# Parse format for Lazada Open Platform
|
6
|
+
def self.datetime_to_iso8601(datetime)
|
7
|
+
time_format = '%Y-%m-%dT%H:%M:%S'
|
8
|
+
datetime.strftime(time_format)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.datetime_to_timestamp(datetime)
|
12
|
+
datetime.to_time.to_i
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StockShaker
|
4
|
+
module Request
|
5
|
+
class JDCentralOP
|
6
|
+
attr_reader :http_method, :api_params, :business_params, :header_params
|
7
|
+
|
8
|
+
def initialize(http_method = :post)
|
9
|
+
@http_method = http_method
|
10
|
+
@api_params = {}
|
11
|
+
@business_params = {}
|
12
|
+
@header_params = {}
|
13
|
+
|
14
|
+
validate!
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_api_params(hash)
|
18
|
+
raise 'api_params is not hash' unless hash.is_a? Hash
|
19
|
+
@api_params = hash
|
20
|
+
end
|
21
|
+
|
22
|
+
def add_business_params(hash)
|
23
|
+
raise 'business_params is not hash' unless hash.is_a? Hash
|
24
|
+
@business_params = {
|
25
|
+
param_json: hash.to_json
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
def add_header_params(key, value)
|
30
|
+
raise 'header param key is not String' unless key.is_a? String
|
31
|
+
raise 'header param value is not String' unless value.is_a? String
|
32
|
+
@header_params[key] = value
|
33
|
+
end
|
34
|
+
|
35
|
+
def validate!
|
36
|
+
raise 'http_method accepted only :post' unless @http_method.eql?(:post)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StockShaker
|
4
|
+
module Request
|
5
|
+
class LazadaOP
|
6
|
+
attr_reader :api_name, :http_method, :api_params, :header_params
|
7
|
+
|
8
|
+
def initialize(api_name = nil, http_method = :post)
|
9
|
+
@api_name = api_name
|
10
|
+
@http_method = http_method
|
11
|
+
@api_params = {}
|
12
|
+
@header_params = {}
|
13
|
+
|
14
|
+
validate!
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_api_params(key, value)
|
18
|
+
raise 'api_params key is not String' unless key.is_a? String
|
19
|
+
raise 'api_params value is not String' unless value.is_a? String
|
20
|
+
@api_params[key] = value
|
21
|
+
end
|
22
|
+
|
23
|
+
def add_header_params(key, value)
|
24
|
+
raise 'header param key is not String' unless key.is_a? String
|
25
|
+
raise 'header param value is not String' unless value.is_a? String
|
26
|
+
@header_params[key] = value
|
27
|
+
end
|
28
|
+
|
29
|
+
def validate!
|
30
|
+
raise 'api_name is required' if @api_name.blank?
|
31
|
+
raise 'http_method accepted only :get or :post' unless %i[get post].include?(@http_method)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StockShaker
|
4
|
+
module Request
|
5
|
+
class ShopeeOP
|
6
|
+
attr_reader :api_name, :http_method, :api_params, :header_params
|
7
|
+
|
8
|
+
def initialize(api_name = nil, http_method = :post)
|
9
|
+
@api_name = api_name
|
10
|
+
@http_method = http_method
|
11
|
+
@api_params = {}
|
12
|
+
@header_params = {}
|
13
|
+
|
14
|
+
validate!
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_api_params(hash)
|
18
|
+
raise 'api_params is not hash' unless hash.is_a? Hash
|
19
|
+
@api_params = hash
|
20
|
+
end
|
21
|
+
|
22
|
+
def add_header_params(key, value)
|
23
|
+
raise 'header param key is not String' unless key.is_a? String
|
24
|
+
raise 'header param value is not String' unless value.is_a? String
|
25
|
+
@header_params[key] = value
|
26
|
+
end
|
27
|
+
|
28
|
+
def validate!
|
29
|
+
raise 'api_name is required' if @api_name.blank?
|
30
|
+
raise 'http_method accepted only :get or :post' unless %i[get post].include?(@http_method)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="293.5" height="28"><g shape-rendering="crispEdges"><path fill="#555" d="M0 0h200.5v28H0z"/><path fill="#97CA00" d="M200.5 0h93v28H200.5z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="100"><text x="1002.5" y="175" transform="scale(.1)" textLength="1765">GENERATE ACCESS TOKEN</text><text x="2470" y="175" font-weight="bold" transform="scale(.1)" textLength="690">GET/POST</text></g> </svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="157" height="28"><g shape-rendering="crispEdges"><path fill="#555" d="M0 0h108v28H0z"/><path fill="#97CA00" d="M108 0h49v28H108z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="100"><text x="540" y="175" transform="scale(.1)" textLength="840">GET ORDERS</text><text x="1325" y="175" font-weight="bold" transform="scale(.1)" textLength="250">GET</text></g> </svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="203" height="28"><g shape-rendering="crispEdges"><path fill="#555" d="M0 0h102v28H0z"/><path fill="#dfb317" d="M102 0h101v28H102z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="100"><text x="510" y="175" transform="scale(.1)" textLength="780">LAZADA API</text><text x="1525" y="175" font-weight="bold" transform="scale(.1)" textLength="770">ORDER-API</text></g> </svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="211" height="28"><g shape-rendering="crispEdges"><path fill="#555" d="M0 0h102v28H0z"/><path fill="#dfb317" d="M102 0h109v28H102z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="100"><text x="510" y="175" transform="scale(.1)" textLength="780">LAZADA API</text><text x="1565" y="175" font-weight="bold" transform="scale(.1)" textLength="850">SYSTEM-API</text></g> </svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="284" height="28"><g shape-rendering="crispEdges"><path fill="#555" d="M0 0h191v28H0z"/><path fill="#97CA00" d="M191 0h93v28H191z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="100"><text x="955" y="175" transform="scale(.1)" textLength="1670">REFRESH ACCESS TOKEN</text><text x="2375" y="175" font-weight="bold" transform="scale(.1)" textLength="690">GET/POST</text></g> </svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="197.5" height="28"><g shape-rendering="crispEdges"><path fill="#555" d="M0 0h100.5v28H0z"/><path fill="#97CA00" d="M100.5 0h97v28H100.5z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="100"><text x="502.5" y="175" transform="scale(.1)" textLength="765">MADE WITH</text><text x="1490" y="175" font-weight="bold" transform="scale(.1)" textLength="730">SHIELD.IO</text></g> </svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="112" height="28"><g shape-rendering="crispEdges"><path fill="#DD4F49" d="M0 0h35v28H0z"/><path fill="#163D50" d="M35 0h77v28H35z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="100"><image x="9" y="7" width="14" height="14" xlink:href="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNTEzcHgiIGhlaWdodD0iNDQ5cHgiIHZpZXdCb3g9IjAgMCA1MTMgNDQ5IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPCEtLSBHZW5lcmF0b3I6IFNrZXRjaCA1MS4xICg1NzUwMSkgLSBodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2ggLS0+CiAgICA8dGl0bGU+VW50aXRsZWQ8L3RpdGxlPgogICAgPGRlc2M+Q3JlYXRlZCB3aXRoIFNrZXRjaC48L2Rlc2M+CiAgICA8ZGVmcz48L2RlZnM+CiAgICA8ZyBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyBpZD0iaGVhcnQiIGZpbGw9IiNGRkZGRkYiIGZpbGwtcnVsZT0ibm9uemVybyI+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik00NjMuMywzMS42IEM0MDguNSwtMTUuMSAzMjcsLTYuNyAyNzYuNyw0NS4yIEwyNTcsNjUuNSBMMjM3LjMsNDUuMiBDMTg3LjEsLTYuNyAxMDUuNSwtMTUuMSA1MC43LDMxLjYgQy0xMi4xLDg1LjIgLTE1LjQsMTgxLjQgNDAuOCwyMzkuNSBMMjM0LjMsNDM5LjMgQzI0Ni44LDQ1Mi4yIDI2Ny4xLDQ1Mi4yIDI3OS42LDQzOS4zIEw0NzMuMSwyMzkuNSBDNTI5LjQsMTgxLjQgNTI2LjEsODUuMiA0NjMuMywzMS42IFoiIGlkPSJTaGFwZSI+PC9wYXRoPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+"/><text x="245" y="175" transform="scale(.1)" textLength="-30"></text><text x="735" y="175" font-weight="bold" transform="scale(.1)" textLength="530">LAZADA</text></g> </svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="112" height="28"><g shape-rendering="crispEdges"><path fill="#DD4F49" d="M0 0h35v28H0z"/><path fill="#ED6035" d="M35 0h77v28H35z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="100"><image x="9" y="7" width="14" height="14" xlink:href="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNTEzcHgiIGhlaWdodD0iNDQ5cHgiIHZpZXdCb3g9IjAgMCA1MTMgNDQ5IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPCEtLSBHZW5lcmF0b3I6IFNrZXRjaCA1MS4xICg1NzUwMSkgLSBodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2ggLS0+CiAgICA8dGl0bGU+VW50aXRsZWQ8L3RpdGxlPgogICAgPGRlc2M+Q3JlYXRlZCB3aXRoIFNrZXRjaC48L2Rlc2M+CiAgICA8ZGVmcz48L2RlZnM+CiAgICA8ZyBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyBpZD0iaGVhcnQiIGZpbGw9IiNGRkZGRkYiIGZpbGwtcnVsZT0ibm9uemVybyI+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik00NjMuMywzMS42IEM0MDguNSwtMTUuMSAzMjcsLTYuNyAyNzYuNyw0NS4yIEwyNTcsNjUuNSBMMjM3LjMsNDUuMiBDMTg3LjEsLTYuNyAxMDUuNSwtMTUuMSA1MC43LDMxLjYgQy0xMi4xLDg1LjIgLTE1LjQsMTgxLjQgNDAuOCwyMzkuNSBMMjM0LjMsNDM5LjMgQzI0Ni44LDQ1Mi4yIDI2Ny4xLDQ1Mi4yIDI3OS42LDQzOS4zIEw0NzMuMSwyMzkuNSBDNTI5LjQsMTgxLjQgNTI2LjEsODUuMiA0NjMuMywzMS42IFoiIGlkPSJTaGFwZSI+PC9wYXRoPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+"/><text x="245" y="175" transform="scale(.1)" textLength="-30"></text><text x="735" y="175" font-weight="bold" transform="scale(.1)" textLength="530">SHOPEE</text></g> </svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200.5" height="28"><g shape-rendering="crispEdges"><path fill="#555" d="M0 0h143.5v28H0z"/><path fill="#97CA00" d="M143.5 0h57v28H143.5z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="100"><text x="717.5" y="175" transform="scale(.1)" textLength="1195">GET ORDERS LIST</text><text x="1720" y="175" font-weight="bold" transform="scale(.1)" textLength="330">POST</text></g> </svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="203" height="28"><g shape-rendering="crispEdges"><path fill="#555" d="M0 0h102v28H0z"/><path fill="#dfb317" d="M102 0h101v28H102z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="100"><text x="510" y="175" transform="scale(.1)" textLength="780">SHOPEE API</text><text x="1525" y="175" font-weight="bold" transform="scale(.1)" textLength="770">ORDER-API</text></g> </svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="178" height="28"><g shape-rendering="crispEdges"><path fill="#555" d="M0 0h125v28H0z"/><path fill="#fe7d37" d="M125 0h53v28H125z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="100"><text x="625" y="175" transform="scale(.1)" textLength="1010">STOCK SHAKER</text><text x="1515" y="175" font-weight="bold" transform="scale(.1)" textLength="290">NEW</text></g> </svg>
|
data/media/icon.png
ADDED
Binary file
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'stock_shaker/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = 'stock_shaker'
|
9
|
+
spec.version = StockShaker::VERSION
|
10
|
+
spec.platform = Gem::Platform::RUBY
|
11
|
+
spec.required_ruby_version = '>= 2.3.0'
|
12
|
+
spec.authors = ['Nathakorn Chaninthanadecha']
|
13
|
+
spec.email = ['nathakorn.tonch@gmail.com']
|
14
|
+
|
15
|
+
spec.homepage = 'https://github.com/nijicha/stock_shaker'
|
16
|
+
spec.license = 'MIT'
|
17
|
+
spec.summary = <<-SUMMARY
|
18
|
+
Kick off API for eCommerce in Thailand.
|
19
|
+
SUMMARY
|
20
|
+
spec.description = <<-DESCRIPTION
|
21
|
+
Unofficial Rubygems for Thailand eCommerce Marketplace.
|
22
|
+
DESCRIPTION
|
23
|
+
|
24
|
+
spec.metadata = {
|
25
|
+
'homepage_uri' => 'https://rubygems.org/gems/stock_shaker',
|
26
|
+
'changelog_uri' => 'https://github.com/nijicha/stock_shaker/blob/master/CHANGELOG.md',
|
27
|
+
'source_code_uri' => 'https://github.com/nijicha/stock_shaker',
|
28
|
+
'bug_tracker_uri' => 'https://github.com/nijicha/stock_shaker/issues'
|
29
|
+
}
|
30
|
+
|
31
|
+
# Specify which files should be added to the gem when it is released.
|
32
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
33
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
34
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
35
|
+
end
|
36
|
+
spec.bindir = 'exe'
|
37
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
38
|
+
spec.require_paths = ['lib']
|
39
|
+
|
40
|
+
spec.add_runtime_dependency 'rest-client', '~> 2.0', '>= 2.0.2'
|
41
|
+
|
42
|
+
spec.add_development_dependency 'bundler', '~> 1.16'
|
43
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
44
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
45
|
+
spec.add_development_dependency 'rubocop', '~> 0.57.2'
|
46
|
+
end
|
metadata
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: stock_shaker
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.5
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nathakorn Chaninthanadecha
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-10-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rest-client
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 2.0.2
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '2.0'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 2.0.2
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: bundler
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '1.16'
|
40
|
+
type: :development
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '1.16'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rake
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '10.0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '10.0'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: rspec
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '3.0'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '3.0'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: rubocop
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: 0.57.2
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 0.57.2
|
89
|
+
description: " Unofficial Rubygems for Thailand eCommerce Marketplace.\n"
|
90
|
+
email:
|
91
|
+
- nathakorn.tonch@gmail.com
|
92
|
+
executables: []
|
93
|
+
extensions: []
|
94
|
+
extra_rdoc_files: []
|
95
|
+
files:
|
96
|
+
- ".gitignore"
|
97
|
+
- ".rspec"
|
98
|
+
- ".rubocop.yml"
|
99
|
+
- ".travis.yml"
|
100
|
+
- CHANGELOG.md
|
101
|
+
- Gemfile
|
102
|
+
- LICENSE.txt
|
103
|
+
- README.md
|
104
|
+
- Rakefile
|
105
|
+
- bin/console
|
106
|
+
- bin/setup
|
107
|
+
- lib/stock_shaker.rb
|
108
|
+
- lib/stock_shaker/client/constants.rb
|
109
|
+
- lib/stock_shaker/client/jd_central_op.rb
|
110
|
+
- lib/stock_shaker/client/lazada_op.rb
|
111
|
+
- lib/stock_shaker/client/shopee_op.rb
|
112
|
+
- lib/stock_shaker/concern/utility.rb
|
113
|
+
- lib/stock_shaker/config.rb
|
114
|
+
- lib/stock_shaker/config/lazada_config.rb
|
115
|
+
- lib/stock_shaker/config/shopee_config.rb
|
116
|
+
- lib/stock_shaker/date_util.rb
|
117
|
+
- lib/stock_shaker/request/jd_central_op.rb
|
118
|
+
- lib/stock_shaker/request/lazada_op.rb
|
119
|
+
- lib/stock_shaker/request/shopee_op.rb
|
120
|
+
- lib/stock_shaker/version.rb
|
121
|
+
- media/badge/lazada/generate_access_token.svg
|
122
|
+
- media/badge/lazada/get_orders-get-green.svg
|
123
|
+
- media/badge/lazada/lazada_api-order--api-yellow.svg
|
124
|
+
- media/badge/lazada/lazada_api-system--api-yellow.svg
|
125
|
+
- media/badge/lazada/refresh_access_token.svg
|
126
|
+
- media/badge/made_with-shield_io-green.svg
|
127
|
+
- media/badge/market_place_support/love-lazada-sky-blue.svg
|
128
|
+
- media/badge/market_place_support/love-shopee-orange.svg
|
129
|
+
- media/badge/shopee/get_orders_list-post-green.svg
|
130
|
+
- media/badge/shopee/shopee_api-order--api-yellow.svg
|
131
|
+
- media/badge/stock_shaker-new-orange.svg
|
132
|
+
- media/icon.png
|
133
|
+
- stock_shaker.gemspec
|
134
|
+
homepage: https://github.com/nijicha/stock_shaker
|
135
|
+
licenses:
|
136
|
+
- MIT
|
137
|
+
metadata:
|
138
|
+
homepage_uri: https://rubygems.org/gems/stock_shaker
|
139
|
+
changelog_uri: https://github.com/nijicha/stock_shaker/blob/master/CHANGELOG.md
|
140
|
+
source_code_uri: https://github.com/nijicha/stock_shaker
|
141
|
+
bug_tracker_uri: https://github.com/nijicha/stock_shaker/issues
|
142
|
+
post_install_message:
|
143
|
+
rdoc_options: []
|
144
|
+
require_paths:
|
145
|
+
- lib
|
146
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
147
|
+
requirements:
|
148
|
+
- - ">="
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: 2.3.0
|
151
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
152
|
+
requirements:
|
153
|
+
- - ">="
|
154
|
+
- !ruby/object:Gem::Version
|
155
|
+
version: '0'
|
156
|
+
requirements: []
|
157
|
+
rubygems_version: 3.0.3
|
158
|
+
signing_key:
|
159
|
+
specification_version: 4
|
160
|
+
summary: Kick off API for eCommerce in Thailand.
|
161
|
+
test_files: []
|