adash 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 61f2c1aaecd17188279e2bdbdcbc27bd9dbcdca5
4
- data.tar.gz: 36f79b3aaee75b3a51fb5040e4209863b9c039e2
3
+ metadata.gz: 396638a8ef38f6b9167e149fa1fc627fccac9e61
4
+ data.tar.gz: a643cde5a6649f266ada88ebdc7f4f9530d75569
5
5
  SHA512:
6
- metadata.gz: '099bfecea21fc84cba496e203c126c8d1873a811ba9f1bd95c4e33ea9f94bd6fdb4294e10911144fbcfc8418bb8717f904da09cd3a812ba15eb7ee9a8c35e628'
7
- data.tar.gz: '016778d780cd3f95ede569ede0b0026aa8d19dd6d7eb7e40d4ba3797877f3c72f09419be56f3ed66d47b04ed7caba7afb9d6a2309b7b89cd85d4b0b5dd901ffe'
6
+ metadata.gz: a4b4451e6cc62c73845cb62d694eb282bdc4f5d16a83e68a89cfa6e6fdffad16e4bc25f1b6aad19d87d7901d162dad57d4421d63f30722bd964e4203c42cc8e0
7
+ data.tar.gz: 8c54f4d2e1640c0da553f6aa381051a224dc572e25b61da71d42368cf66fdba54e97a1de3075d6dbee5fe04ba777ec0f52b33945e239a41ed6a9981dd00fb099
data/.gitignore CHANGED
@@ -5,6 +5,5 @@
5
5
  /coverage/
6
6
  /doc/
7
7
  /pkg/
8
- /spec/reports/
9
8
  /tmp/
10
9
  *.swp
data/README.md CHANGED
@@ -20,19 +20,91 @@ Or install it yourself as:
20
20
 
21
21
  ## Usage
22
22
 
23
+ ### `adash init`
24
+
25
+ You can initialize with `adash init` sub-command. It takes `name` and `device_model` what likes `01234567-89ab-cdef-0123-456789abcdef`.
26
+
27
+ ```bash
28
+ $ adash init lozenge 01234567-89ab-cdef-0123-456789abcdef
29
+ [2016-12-23 00:11:44] INFO WEBrick 1.3.1
30
+ [2016-12-23 00:11:44] INFO ruby 2.3.3 (2016-11-21) [x86_64-linux]
31
+ [2016-12-23 00:11:44] INFO WEBrick::HTTPServer#start: pid=11687 port=55582
32
+ ...
33
+ ```
34
+
35
+ WEBrick web server runs intenally, and a browser is opened for it.
36
+ You are requested OAuth authorization and DRS initialization.
37
+
38
+ ### `adash list`
39
+
40
+ The sub-command `adash list` shows initialized devices list.
41
+
23
42
  ```bash
24
- $ adash init [device_model]
43
+ $ adash list
44
+ ---- name: lozenge
45
+ * device_model: 01234567-89ab-cdef-0123-456789abcdef
46
+ serial: d973f856-a21e-4701-bcfa-8e8eb8913c31_1482343916_3SVTiar3FX0CBnZW
47
+ ---- name: jaga
48
+ * device_model: fedcba98-7654-3210-fedc-ba9876543210
49
+ serial: fbb51681-d087-4495-806e-c1f58ac59d4e_1482419498_afSWz8PqGgyqOqaH
25
50
  ```
26
51
 
27
- ## Development
52
+ ### `adash list-slot`
53
+
54
+ ```bash
55
+ $ adash list-slot lozenge
56
+ ---- 0
57
+ * slot_id: 01a23b45-c56d-78e9-01a2-3b45c56d78e9
58
+ available: true
59
+ ---- 1
60
+ * slot_id: 9e87d65c-54b3-2a10-9e87-d65c54b32a10
61
+ available: true
62
+ ```
63
+
64
+ ### `adash replenish`
65
+
66
+ ```bash
67
+ $ adash replenish lozenge
68
+
69
+ ---- number: 0
70
+ * slot_id: 01a23b45-c56d-78e9-01a2-3b45c56d78e9
71
+ available: true
72
+
28
73
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
74
+ ---- number: 1
75
+ * slot_id: 9e87d65c-54b3-2a10-9e87-d65c54b32a10
76
+ available: true
30
77
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
78
+ Select slot number>
79
+ ```
80
+
81
+ You should select replenish slot.
82
+
83
+ ```bash
84
+ elect slot number> 1
85
+ Succeeded to order.
86
+ ```
87
+
88
+ If the slot is already ordered, the message below is shown.
89
+
90
+ ```bash
91
+ elect slot number> 1
92
+ The order is in progress.
93
+ ```
94
+
95
+ There are no the selection prompts when the slot is just one.
96
+
97
+ ### `adash deregistrate`
98
+
99
+ You can delete device from Adash and Amazon.
100
+
101
+ ```bash
102
+ $ adash deregistrate lozenge
103
+ ```
32
104
 
33
105
  ## Contributing
34
106
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/adash.
107
+ Bug reports and pull requests are welcome on GitHub at https://github.com/aycabta/adash.
36
108
 
37
109
 
38
110
  ## License
data/Rakefile CHANGED
@@ -1,6 +1,3 @@
1
1
  require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
3
-
4
- RSpec::Core::RakeTask.new(:spec)
5
2
 
6
3
  task :default => :spec
@@ -9,8 +9,8 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ["Code Ass"]
10
10
  spec.email = ["aycabta@gmail.com"]
11
11
 
12
- spec.summary = %q{Adash}
13
- spec.description = %q{Adash}
12
+ spec.summary = %q{Adash is a Dash Replenishment Service CLI client}
13
+ spec.description = %Q{Adash is a Dash Replenishment Service CLI client.\nYou will login with OAuth (Login with Amazon) and replenish items.}
14
14
  spec.homepage = "https://github.com/aycabta/adash"
15
15
  spec.license = "MIT"
16
16
 
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
20
20
  spec.require_paths = ["lib"]
21
21
 
22
22
  spec.add_development_dependency "bundler", "~> 1.13"
23
- spec.add_development_dependency "rake", "~> 10.0"
24
- spec.add_development_dependency "rspec", "~> 3.0"
23
+ spec.add_development_dependency "rake", "~> 12.0"
24
+ spec.add_development_dependency "amazon-drs"
25
25
  spec.add_development_dependency "launchy", "~> 2.5"
26
26
  end
data/exe/adash CHANGED
@@ -9,6 +9,7 @@ require 'optparse'
9
9
  require 'readline'
10
10
  require 'fileutils'
11
11
  require 'yaml'
12
+ require 'amazon-drs'
12
13
 
13
14
  opt = OptionParser.new
14
15
 
@@ -60,12 +61,15 @@ def save_credentials_without_device_model(device_model)
60
61
  end
61
62
 
62
63
  def create_client_from_device(device)
63
- Adash::Client.new(device['device_model']) do |c|
64
+ AmazonDrs::Client.new(device['device_model']) do |c|
64
65
  c.authorization_code = device['authorization_code']
65
66
  c.serial = device['serial']
66
67
  c.redirect_uri = device['redirect_uri']
67
68
  c.access_token = device['access_token']
68
69
  c.refresh_token = device['refresh_token']
70
+ c.client_id = Adash::Config.client_id
71
+ c.client_secret = Adash::Config.client_secret
72
+ c.redirect_uri = "http://localhost:#{Adash::Config.redirect_port}/"
69
73
  c.on_new_token = proc { |access_token, refresh_token|
70
74
  credentials = get_credentials
71
75
  updated_device = get_device_from_credentials(credentials, device['device_model'])
@@ -101,7 +105,10 @@ end
101
105
 
102
106
  def select_slot_prompt(client)
103
107
  resp = client.subscription_info
104
- slots = resp.json['slotsSubscriptionStatus']
108
+ slots = resp.json['slotsSubscriptionStatus'].select{ |k, v| v }
109
+ if slots.size == 1
110
+ return slots.keys.first
111
+ end
105
112
  loop do
106
113
  show_slots(slots)
107
114
  slot_num = Readline.readline('Select slot number> ')
@@ -1,3 +1,3 @@
1
1
  module Adash
2
- VERSION = '0.0.1'
2
+ VERSION = '0.0.2'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: adash
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Code Ass
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-12-21 00:00:00.000000000 Z
11
+ date: 2016-12-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -30,28 +30,28 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: '12.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '12.0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: rspec
42
+ name: amazon-drs
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '3.0'
47
+ version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '3.0'
54
+ version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: launchy
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -66,7 +66,9 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '2.5'
69
- description: Adash
69
+ description: |-
70
+ Adash is a Dash Replenishment Service CLI client.
71
+ You will login with OAuth (Login with Amazon) and replenish items.
70
72
  email:
71
73
  - aycabta@gmail.com
72
74
  executables:
@@ -75,7 +77,6 @@ extensions: []
75
77
  extra_rdoc_files: []
76
78
  files:
77
79
  - ".gitignore"
78
- - ".rspec"
79
80
  - ".travis.yml"
80
81
  - Gemfile
81
82
  - LICENSE.txt
@@ -87,7 +88,6 @@ files:
87
88
  - data/client
88
89
  - exe/adash
89
90
  - lib/adash.rb
90
- - lib/adash/client.rb
91
91
  - lib/adash/config.rb
92
92
  - lib/adash/version.rb
93
93
  - lib/adash/wait_indefinitely.rb
@@ -114,5 +114,5 @@ rubyforge_project:
114
114
  rubygems_version: 2.5.2
115
115
  signing_key:
116
116
  specification_version: 4
117
- summary: Adash
117
+ summary: Adash is a Dash Replenishment Service CLI client
118
118
  test_files: []
data/.rspec DELETED
@@ -1,2 +0,0 @@
1
- --format documentation
2
- --color
@@ -1,213 +0,0 @@
1
- require 'net/http'
2
- require 'uri'
3
- require 'json'
4
- require 'yaml'
5
- require 'time'
6
- require 'date'
7
- require 'adash/config'
8
-
9
- class Net::HTTPResponse
10
- attr_accessor :json
11
- end
12
-
13
- module Adash
14
- class Client
15
- attr_accessor :device_model, :serial, :authorization_code, :redirect_uri, :access_token, :refresh_token
16
- attr_accessor :on_new_token
17
- attr_writer :user_agent
18
-
19
- def initialize(device_model)
20
- @drs_host = 'dash-replenishment-service-na.amazon.com'
21
- @amazon_host = 'api.amazon.com'
22
- @device_model = device_model
23
- @serial = nil
24
- @authorization_code = nil
25
- @redirect_uri = nil
26
- @access_token = nil
27
- @refresh_token = nil
28
- @on_new_token = nil
29
- yield(self) if block_given?
30
- end
31
-
32
- def user_agent
33
- @user_agent ||= "AdashRubyGem/#{Adash::VERSION}/#{RUBY_DESCRIPTION}"
34
- end
35
-
36
- def deregistrate_device
37
- headers = {
38
- 'x-amzn-accept-type': 'com.amazon.dash.replenishment.DrsDeregisterResult@1.0',
39
- 'x-amzn-type-version': 'com.amazon.dash.replenishment.DrsDeregisterInput@1.0'
40
- }
41
- path = "/deviceModels/#{@device_model}/devices/#{@serial}/registration"
42
- request_drs(:delete, path, headers: headers)
43
- end
44
-
45
- def device_status(most_recently_active_date)
46
- headers = {
47
- 'x-amzn-accept-type': 'com.amazon.dash.replenishment.DrsDeviceStatusResult@1.0',
48
- 'x-amzn-type-version': 'com.amazon.dash.replenishment.DrsDeviceStatusInput@1.0'
49
- }
50
- path = '/deviceStatus'
51
- request_drs(:post, path, headers: headers, params: { 'mostRecentlyActiveDate' => convert_to_iso8601(most_recently_active_date) })
52
- end
53
-
54
- def subscription_info
55
- headers = {
56
- 'x-amzn-accept-type': 'com.amazon.dash.replenishment.DrsSubscriptionInfoResult@1.0',
57
- 'x-amzn-type-version': 'com.amazon.dash.replenishment.DrsSubscriptionInfoInput@1.0'
58
- }
59
- path = '/subscriptionInfo'
60
- request_drs(:get, path, headers: headers)
61
- end
62
-
63
- def slot_status(slot_id, expected_replenishment_date, remaining_quantity_in_unit, original_quantity_in_unit, total_quantity_on_hand, last_use_date)
64
- headers = {
65
- 'x-amzn-accept-type': 'com.amazon.dash.replenishment.DrsSlotStatusResult@1.0',
66
- 'x-amzn-type-version': 'com.amazon.dash.replenishment.DrsSlotStatusInput@1.0'
67
- }
68
- path = "/slotStatus/#{slot_id}"
69
- params = {
70
- 'expectedReplenishmentDate' => convert_to_iso8601(expected_replenishment_date),
71
- 'remainingQuantityInUnit' => remaining_quantity_in_unit,
72
- 'originalQuantityInUnit' => original_quantity_in_unit,
73
- 'totalQuantityOnHand' => total_quantity_on_hand,
74
- 'lastUseDate' => convert_to_iso8601(last_use_date)
75
- }
76
- request_drs(:post, path, headers: headers, params: params)
77
- end
78
-
79
- def replenish(slot_id)
80
- headers = {
81
- 'x-amzn-accept-type': 'com.amazon.dash.replenishment.DrsReplenishResult@1.0',
82
- 'x-amzn-type-version': 'com.amazon.dash.replenishment.DrsReplenishInput@1.0'
83
- }
84
- path = "/replenish/#{slot_id}"
85
- response = request_drs(:post, path, headers: headers)
86
- # TODO: imprement response processing
87
- # https://developer.amazon.com/public/solutions/devices/dash-replenishment-service/docs/dash-replenish-endpoint
88
- # response examples:
89
- # {"message":"Unable to place order - slot : <01234567-89ab-cdef-0123-456789abcdef> is unsubscribed."}
90
- # {"detailCode":"STANDARD_ORDER_PLACED","eventInstanceId":"amzn1.dash.v2.o.xxxxxx......"}
91
- # {"detailCode":"ORDER_INPROGRESS","eventInstanceId":"amzn1.dash.v2.o.xxxxxx......"}
92
- end
93
-
94
- def get_token
95
- if @access_token
96
- @access_token
97
- else
98
- resp = request_token
99
- process_token_response(resp)
100
- end
101
- end
102
-
103
- private
104
-
105
- def convert_to_iso8601(input)
106
- case input
107
- when Date, Time
108
- input.iso8601
109
- when String
110
- input
111
- else
112
- input.to_s
113
- end
114
- end
115
-
116
- def process_token_response(resp)
117
- if resp.json['error']
118
- puts resp.json['error']
119
- puts resp.json['error_description']
120
- nil
121
- else
122
- @access_token = resp.json['access_token']
123
- @refresh_token = resp.json['refresh_token']
124
- @on_new_token.call(@access_token, @refresh_token) if @on_new_token
125
- @access_token
126
- end
127
- end
128
-
129
- def request_drs(method, path, headers: {}, params: {})
130
- url = "https://#{@drs_host}#{path}"
131
- if @authorization_code.nil?
132
- raise 'Authorization Code is not set'
133
- end
134
- if @access_token.nil?
135
- token = get_token
136
- if token.nil?
137
- raise 'Failed to get token'
138
- end
139
- end
140
- resp = request(method, url, headers: headers, params: params)
141
- if resp.code == '400' && resp.json['message'] == 'Invalid token' && @refresh_token
142
- resp = refresh_access_token
143
- process_token_response(resp)
144
- request(method, url, headers: headers, params: params)
145
- else
146
- resp
147
- end
148
- end
149
-
150
- def refresh_access_token
151
- params = {
152
- grant_type: 'refresh_token',
153
- refresh_token: @refresh_token,
154
- client_id: Adash::Config.client_id,
155
- client_secret: Adash::Config.client_secret
156
- }
157
- @access_token = nil
158
- request(:post, "https://#{@amazon_host}/auth/o2/token", params: params)
159
- end
160
-
161
- def request_token
162
- params = {
163
- grant_type: 'authorization_code',
164
- code: @authorization_code,
165
- client_id: Adash::Config.client_id,
166
- client_secret: Adash::Config.client_secret,
167
- redirect_uri: "http://localhost:#{Adash::Config.redirect_port}/"
168
- }
169
- request(:post, "https://#{@amazon_host}/auth/o2/token", params: params)
170
- end
171
-
172
- def request(method, url, headers: {}, params: {})
173
- uri = URI.parse(url)
174
- if params.any?{ |key, value| value.is_a?(Enumerable) }
175
- converted_params = []
176
- params.each do |key, value|
177
- if value.is_a?(Enumerable)
178
- value.each_index do |i|
179
- converted_params << ["#{key}[#{i}]", value[i]]
180
- end
181
- else
182
- converted_params << [key, value]
183
- end
184
- end
185
- params = converted_params
186
- end
187
- case method
188
- when :delete
189
- uri.query = URI.encode_www_form(params)
190
- request = Net::HTTP::Delete.new(uri)
191
- when :get
192
- uri.query = URI.encode_www_form(params)
193
- request = Net::HTTP::Get.new(uri)
194
- when :post
195
- request = Net::HTTP::Post.new(uri.path)
196
- request.body = URI.encode_www_form(params)
197
- end
198
- request['Content-Type'] = 'application/x-www-form-urlencoded'
199
- request['User-Agent'] = @user_agent
200
- headers.each do |key, value|
201
- request[key] = value
202
- end
203
- if not @access_token.nil?
204
- request["Authorization"] = "Bearer #{@access_token}"
205
- end
206
- http = Net::HTTP.new(uri.host, uri.port)
207
- http.use_ssl = true
208
- response = http.request(request)
209
- response.json = JSON.parse(response.body)
210
- response
211
- end
212
- end
213
- end