parcel_api 0.2.0
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 +9 -0
- data/.rspec +2 -0
- data/.travis.yml +8 -0
- data/.yardopts +7 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +83 -0
- data/LICENSE +21 -0
- data/README.md +78 -0
- data/Rakefile +11 -0
- data/bin/console +7 -0
- data/bin/parcel +6 -0
- data/bin/setup +7 -0
- data/example/mock.rb +267 -0
- data/lib/parcel_api/address.rb +66 -0
- data/lib/parcel_api/cli.rb +10 -0
- data/lib/parcel_api/client.rb +59 -0
- data/lib/parcel_api/error.rb +80 -0
- data/lib/parcel_api/label.rb +60 -0
- data/lib/parcel_api/pickup.rb +26 -0
- data/lib/parcel_api/shipping_options.rb +44 -0
- data/lib/parcel_api/track.rb +32 -0
- data/lib/parcel_api/version.rb +3 -0
- data/lib/parcel_api.rb +14 -0
- data/parcel_api.gemspec +34 -0
- metadata +237 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 796b5726fcf645a3a08bc3f3604571543204838a
|
4
|
+
data.tar.gz: 0aa5d2dec24519e44ac578819d6604a3d86b31df
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a1719f6f35ac57609e2f3e142e82a0ff3e42f43bc29e9fcb40e935e00052e752995afbc19019426c52d3f77bd4b6de3522cad0159068c428e3314ea37cd56682
|
7
|
+
data.tar.gz: 214072e0c14a216fae2947d0faaecf01c1ab4b4c272f1c96c5f8565a13c5cbb6f0f3ad4d02bd8804241e7a97a374ad0edb23f1fc80ec3b97ff438aa9e765f900
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/.yardopts
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
parcel_api (0.2.0)
|
5
|
+
faraday (~> 0.9)
|
6
|
+
faraday_middleware (~> 0.9)
|
7
|
+
oauth2 (~> 1.0)
|
8
|
+
recursive-open-struct (~> 0.6)
|
9
|
+
thor (~> 0.19)
|
10
|
+
|
11
|
+
GEM
|
12
|
+
remote: https://rubygems.org/
|
13
|
+
specs:
|
14
|
+
addressable (2.3.8)
|
15
|
+
codeclimate-test-reporter (0.4.7)
|
16
|
+
simplecov (>= 0.7.1, < 1.0.0)
|
17
|
+
coderay (1.1.0)
|
18
|
+
crack (0.4.2)
|
19
|
+
safe_yaml (~> 1.0.0)
|
20
|
+
diff-lcs (1.2.5)
|
21
|
+
docile (1.1.5)
|
22
|
+
faraday (0.9.1)
|
23
|
+
multipart-post (>= 1.2, < 3)
|
24
|
+
faraday_middleware (0.9.1)
|
25
|
+
faraday (>= 0.7.4, < 0.10)
|
26
|
+
jwt (1.5.0)
|
27
|
+
method_source (0.8.2)
|
28
|
+
multi_json (1.11.0)
|
29
|
+
multi_xml (0.5.5)
|
30
|
+
multipart-post (2.0.0)
|
31
|
+
oauth2 (1.0.0)
|
32
|
+
faraday (>= 0.8, < 0.10)
|
33
|
+
jwt (~> 1.0)
|
34
|
+
multi_json (~> 1.3)
|
35
|
+
multi_xml (~> 0.5)
|
36
|
+
rack (~> 1.2)
|
37
|
+
pry (0.10.1)
|
38
|
+
coderay (~> 1.1.0)
|
39
|
+
method_source (~> 0.8.1)
|
40
|
+
slop (~> 3.4)
|
41
|
+
rack (1.6.4)
|
42
|
+
rake (10.4.2)
|
43
|
+
recursive-open-struct (0.6.4)
|
44
|
+
rspec (3.2.0)
|
45
|
+
rspec-core (~> 3.2.0)
|
46
|
+
rspec-expectations (~> 3.2.0)
|
47
|
+
rspec-mocks (~> 3.2.0)
|
48
|
+
rspec-core (3.2.1)
|
49
|
+
rspec-support (~> 3.2.0)
|
50
|
+
rspec-expectations (3.2.0)
|
51
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
52
|
+
rspec-support (~> 3.2.0)
|
53
|
+
rspec-mocks (3.2.1)
|
54
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
55
|
+
rspec-support (~> 3.2.0)
|
56
|
+
rspec-support (3.2.2)
|
57
|
+
safe_yaml (1.0.4)
|
58
|
+
simplecov (0.9.2)
|
59
|
+
docile (~> 1.1.0)
|
60
|
+
multi_json (~> 1.0)
|
61
|
+
simplecov-html (~> 0.9.0)
|
62
|
+
simplecov-html (0.9.0)
|
63
|
+
slop (3.6.0)
|
64
|
+
thor (0.19.1)
|
65
|
+
vcr (2.9.3)
|
66
|
+
webmock (1.21.0)
|
67
|
+
addressable (>= 2.3.6)
|
68
|
+
crack (>= 0.3.2)
|
69
|
+
yard (0.8.7.6)
|
70
|
+
|
71
|
+
PLATFORMS
|
72
|
+
ruby
|
73
|
+
|
74
|
+
DEPENDENCIES
|
75
|
+
bundler (~> 1.8)
|
76
|
+
codeclimate-test-reporter
|
77
|
+
parcel_api!
|
78
|
+
pry (~> 0.10)
|
79
|
+
rake (~> 10.0)
|
80
|
+
rspec (~> 3.2)
|
81
|
+
vcr (~> 2.9)
|
82
|
+
webmock (~> 1.21)
|
83
|
+
yard (~> 0.8)
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Robert Coleman
|
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,78 @@
|
|
1
|
+
# ParcelApi
|
2
|
+
|
3
|
+
[](https://rubygems.org/gems/parcel_api)[](https://magnum.travis-ci.com/etailer/parcel_api) [](https://codeclimate.com/repos/552dc72e69568025e8001d73/feed) [](https://codeclimate.com/repos/552dc72e69568025e8001d73/feed)
|
4
|
+
|
5
|
+
Ruby wrapper for [NZ Post's Shipping APIs](https://www.nzpost.co.nz/developer-centre#parcel).
|
6
|
+
|
7
|
+
You must be a registered user of these APIs to use this gem.
|
8
|
+
|
9
|
+
__Features__
|
10
|
+
|
11
|
+
* ParcelAddress
|
12
|
+
* ShippingOptions
|
13
|
+
* ParcelPickUp
|
14
|
+
* ParcelLabel
|
15
|
+
* ParcelTrack
|
16
|
+
|
17
|
+
## Installation
|
18
|
+
|
19
|
+
Add this line to your application's Gemfile:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
gem 'parcel_api'
|
23
|
+
```
|
24
|
+
|
25
|
+
And then execute:
|
26
|
+
|
27
|
+
`$ bundle`
|
28
|
+
|
29
|
+
Or install it yourself as:
|
30
|
+
|
31
|
+
`$ gem install parcel_api`
|
32
|
+
|
33
|
+
## Usage
|
34
|
+
|
35
|
+
### Configuration Options
|
36
|
+
|
37
|
+
By default credentials are taken from the local environment, for this to work the following ENV variables must be set:
|
38
|
+
|
39
|
+
* `ENV['CLIENT_ID']`
|
40
|
+
* `ENV['CLIENT_SECRET']`
|
41
|
+
* `ENV['USERNAME']`
|
42
|
+
* `ENV['PASSWORD']`
|
43
|
+
|
44
|
+
You can also configure credentials via `ParcelApi::Client.new`:
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
client = ParcelApi::Client.new.tap do |config|
|
48
|
+
config.client_id = ENV['CLIENT_ID']
|
49
|
+
config.client_secret = ENV['CLIENT_SECRET']
|
50
|
+
config.username = ENV['USERNAME']
|
51
|
+
config.password = ENV['PASSWORD']
|
52
|
+
config.address = 'https://api.uat.nzpost.co.nz/' # defaults to api.nzpost.co.nz
|
53
|
+
end
|
54
|
+
```
|
55
|
+
|
56
|
+
Client connections can be passed to each method:
|
57
|
+
|
58
|
+
`ParcelApi::Address(client.connection)`
|
59
|
+
|
60
|
+
## Documentation
|
61
|
+
|
62
|
+
Documentation is available [here](http://www.rubydoc.info/github/etailer/parcel_api)
|
63
|
+
|
64
|
+
Some usage examples are also available [here](example/mock.rb)
|
65
|
+
|
66
|
+
|
67
|
+
## Development
|
68
|
+
|
69
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
|
70
|
+
|
71
|
+
|
72
|
+
## Contributing
|
73
|
+
|
74
|
+
1. Fork it ( https://github.com/etailer/parcel_api/fork )
|
75
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
76
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
77
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
78
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/bin/console
ADDED
data/bin/parcel
ADDED
data/bin/setup
ADDED
data/example/mock.rb
ADDED
@@ -0,0 +1,267 @@
|
|
1
|
+
require 'parcel_api'
|
2
|
+
|
3
|
+
# configure the client
|
4
|
+
client = ParcelApi::Client.new.tap do |config|
|
5
|
+
config.client_id = ENV['CLIENT_ID']
|
6
|
+
config.client_secret = ENV['CLIENT_SECRET']
|
7
|
+
config.username = ENV['USERNAME']
|
8
|
+
config.password = ENV['PASSWORD']
|
9
|
+
config.address = 'https://api.uat.nzpost.co.nz/'
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
# Address examples
|
14
|
+
|
15
|
+
query = '151 vic'
|
16
|
+
address = ParcelApi::Address.new
|
17
|
+
# search for the query, 3 results
|
18
|
+
results = address.search(query, 3)
|
19
|
+
puts "Address Search: #{query}"
|
20
|
+
puts "Results:"
|
21
|
+
# dump the results out
|
22
|
+
puts results.map {|r| r.full_address}
|
23
|
+
|
24
|
+
# get details for the first result
|
25
|
+
puts 'First Address Details:'
|
26
|
+
details = address.details(results.first.address_id)
|
27
|
+
|
28
|
+
# dump the detail parts out
|
29
|
+
details.to_h.each {|k, v| puts "#{k}: #{v}"}
|
30
|
+
|
31
|
+
intl_query = '38 Lap'
|
32
|
+
# search for the query, defult number of results
|
33
|
+
intl_results = address.international_search(intl_query)
|
34
|
+
puts "International Address Search: #{query}"
|
35
|
+
puts "Results:"
|
36
|
+
puts intl_results.map {|r| r.full_address}
|
37
|
+
|
38
|
+
# get details for the first result
|
39
|
+
puts 'First International Address Details:'
|
40
|
+
intl_details = address.international_details(intl_results.first.address_id)
|
41
|
+
|
42
|
+
# dump the detail parts out
|
43
|
+
intl_details.to_h.each {|k, v| puts "#{k}: #{v}"}
|
44
|
+
|
45
|
+
|
46
|
+
# Tracking Example
|
47
|
+
|
48
|
+
tracking = ParcelApi::Track.new
|
49
|
+
results = tracking.details('1818120002213401AKL003HN')
|
50
|
+
|
51
|
+
# example tracking output
|
52
|
+
last_event = results.tracking_events.last
|
53
|
+
puts results.carrier
|
54
|
+
puts results.service
|
55
|
+
puts last_event.event_datetime.to_s + ' ' + last_event.event_description
|
56
|
+
|
57
|
+
|
58
|
+
# Labelling example
|
59
|
+
|
60
|
+
labeller = ParcelApi::Label.new
|
61
|
+
|
62
|
+
# Label options
|
63
|
+
cp_label_options = {
|
64
|
+
orientation: 'landscape',
|
65
|
+
requests: [
|
66
|
+
{
|
67
|
+
carrier: 'COURIERPOST',
|
68
|
+
sender_details: {
|
69
|
+
name: 'Glenn Dodd',
|
70
|
+
phone: '0274123456',
|
71
|
+
email: 'glenn@example.co.nz',
|
72
|
+
reference: '654334',
|
73
|
+
},
|
74
|
+
pickup_address: {
|
75
|
+
company: 'Glenns Acme Company',
|
76
|
+
city: 'Auckland',
|
77
|
+
floor: 'Floor 2',
|
78
|
+
postcode: '2102',
|
79
|
+
street: '25 Buller Crescent',
|
80
|
+
suburb: 'Manurewa',
|
81
|
+
unit_type: 'Flat',
|
82
|
+
unit_value: '2',
|
83
|
+
},
|
84
|
+
receiver_details: {
|
85
|
+
name: 'Glenn Dodd',
|
86
|
+
phone: '0274123456',
|
87
|
+
},
|
88
|
+
delivery_address: {
|
89
|
+
company: 'Acme Company',
|
90
|
+
city: 'Auckland',
|
91
|
+
floor: 'Floor 2',
|
92
|
+
postcode: '2102',
|
93
|
+
street: '151 Victoria Street',
|
94
|
+
suburb: 'Manurewa',
|
95
|
+
unit_type: 'Flat',
|
96
|
+
unit_value: '2',
|
97
|
+
},
|
98
|
+
return_indicator: 'NORMAL',
|
99
|
+
delivery_instructions: 'Dont feed my dog tonight',
|
100
|
+
service_code: 'CPOLE',
|
101
|
+
add_ons: [],
|
102
|
+
dimensions: {
|
103
|
+
weight: '10',
|
104
|
+
height: '35',
|
105
|
+
width: '45',
|
106
|
+
length: '15',
|
107
|
+
}
|
108
|
+
}
|
109
|
+
]
|
110
|
+
}
|
111
|
+
|
112
|
+
# create the label
|
113
|
+
cp = labeller.create(cp_label_options)
|
114
|
+
|
115
|
+
# get the label details
|
116
|
+
details = labeller.details(cp.label_id)
|
117
|
+
|
118
|
+
# Print the tracking references
|
119
|
+
details.tracking_reference.map {|tr| puts tr}
|
120
|
+
# download the ticket
|
121
|
+
cp_ticket = labeller.download(cp.label_id)
|
122
|
+
|
123
|
+
# Write the ticket out
|
124
|
+
File.open("#{cp.label_id}.pdf", 'w') do |f|
|
125
|
+
f.puts(cp_ticket.read)
|
126
|
+
end
|
127
|
+
|
128
|
+
# International Labelling Example
|
129
|
+
|
130
|
+
intl_labeller = ParcelApi::Label.new
|
131
|
+
|
132
|
+
# Label options
|
133
|
+
intl_label_options = {
|
134
|
+
requests: [
|
135
|
+
{
|
136
|
+
sender_details: {
|
137
|
+
name: 'The sender',
|
138
|
+
phone: '091428774',
|
139
|
+
email: 'the_sender@mail.com',
|
140
|
+
reference: 'Glqddd 008',
|
141
|
+
signatory: 'Mary Jones',
|
142
|
+
customs_code: 'HGD34373',
|
143
|
+
},
|
144
|
+
pickup_address: {
|
145
|
+
building: '',
|
146
|
+
company: 'Express Courier Limited',
|
147
|
+
street: '151 Victoria Street West',
|
148
|
+
suburb: 'Auckland Central',
|
149
|
+
city: 'Auckland',
|
150
|
+
country_code: 'NZ',
|
151
|
+
postcode: '1070',
|
152
|
+
},
|
153
|
+
receiver_details: {
|
154
|
+
name: 'Tom Smith',
|
155
|
+
phone: '051236547',
|
156
|
+
vat_number: 'GB123123123123',
|
157
|
+
},
|
158
|
+
delivery_address: {
|
159
|
+
building: '',
|
160
|
+
company: 'American Express',
|
161
|
+
street: '23 Broadway Street',
|
162
|
+
suburb: 'Queens',
|
163
|
+
city: 'New York',
|
164
|
+
postcode: '4414',
|
165
|
+
country_code: 'US',
|
166
|
+
state: 'New York',
|
167
|
+
},
|
168
|
+
delivery_instructions: 'Leave at door',
|
169
|
+
dimensions: {
|
170
|
+
length: 600,
|
171
|
+
width: 100,
|
172
|
+
height: 200
|
173
|
+
},
|
174
|
+
undeliverable_instructions: 'RETURN',
|
175
|
+
contents: [
|
176
|
+
{
|
177
|
+
unit_description: 'Light bulbs',
|
178
|
+
unit_count: 2,
|
179
|
+
unit_value: 5.1,
|
180
|
+
unit_weight: 0.5,
|
181
|
+
},
|
182
|
+
{
|
183
|
+
unit_description: 'Lego',
|
184
|
+
unit_count: 10,
|
185
|
+
unit_value: 6.1,
|
186
|
+
unit_weight: 0.6,
|
187
|
+
},
|
188
|
+
{
|
189
|
+
unit_description: 'Hot wheels',
|
190
|
+
unit_count: 13,
|
191
|
+
unit_value: 5.4,
|
192
|
+
unit_weight: 0.8,
|
193
|
+
}
|
194
|
+
],
|
195
|
+
service_code: 'TIEX',
|
196
|
+
indicia_number: '123456',
|
197
|
+
insurance_required: true,
|
198
|
+
contains_only_documents: true,
|
199
|
+
export_type: 'Gift',
|
200
|
+
harmonised_system_tariff: '12121212'
|
201
|
+
}
|
202
|
+
]
|
203
|
+
}
|
204
|
+
|
205
|
+
# create the label
|
206
|
+
intl = intl_labeller.international_create(intl_label_options)
|
207
|
+
|
208
|
+
# get the label details
|
209
|
+
intl_details = intl_labeller.details(intl.label_id)
|
210
|
+
|
211
|
+
# Print the tracking references
|
212
|
+
intl_details.tracking_reference.map {|tr| puts tr}
|
213
|
+
# download the ticket
|
214
|
+
intl_ticket = intl_labeller.download(intl.label_id)
|
215
|
+
|
216
|
+
# Write the ticket out
|
217
|
+
File.open("#{intl.label_id}.pdf", 'w') do |f|
|
218
|
+
f.puts(intl_ticket.read)
|
219
|
+
end
|
220
|
+
|
221
|
+
|
222
|
+
ShippingOptions Example
|
223
|
+
|
224
|
+
shipping_options = ParcelApi::ShippingOptions.new
|
225
|
+
|
226
|
+
params = {
|
227
|
+
weight: 10,
|
228
|
+
length: 10,
|
229
|
+
width: 10,
|
230
|
+
height: 10,
|
231
|
+
pickup_address_id: 990003,
|
232
|
+
delivery_dpid: 2727895,
|
233
|
+
}
|
234
|
+
|
235
|
+
domestic_options = shipping_options.get_domestic(params)
|
236
|
+
domestic_options.to_h.each {|k, v| puts "#{k}: #{v}"}
|
237
|
+
|
238
|
+
intl_params = {
|
239
|
+
value: 100,
|
240
|
+
length: 10,
|
241
|
+
height: 10,
|
242
|
+
width: 10,
|
243
|
+
weight: 13,
|
244
|
+
country_code: 'AU',
|
245
|
+
}
|
246
|
+
|
247
|
+
intl_options = shipping_options.get_international(intl_params)
|
248
|
+
intl_options.to_h.each {|k, v| puts "#{k}: #{v}"}
|
249
|
+
|
250
|
+
# Pickup Example
|
251
|
+
|
252
|
+
pickup_params = {
|
253
|
+
carrier: 'CourierPost',
|
254
|
+
message_id: 'Test Message ID',
|
255
|
+
message_date_time: '2015-05-27T14:19:50',
|
256
|
+
account_number: '91327067',
|
257
|
+
pickup_address: {
|
258
|
+
site_code: '28979',
|
259
|
+
instructions: 'TEST'
|
260
|
+
},
|
261
|
+
pickup_date_time: '2015-05-28T17:00:00',
|
262
|
+
quantity: 1
|
263
|
+
}
|
264
|
+
|
265
|
+
pickup = ParcelApi::Pickup.new(client.connection) # use a custom connection
|
266
|
+
pickup_results = pickup.create(pickup_params)
|
267
|
+
pickup_results.to_h.each {|k, v| puts "#{k}: #{v}"}
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module ParcelApi
|
2
|
+
|
3
|
+
# This module provides API requests to Search Domestic(NZ) Addresses, Get Specific Domestic Address Detail,
|
4
|
+
# Search International Addresses and Get Specifc International Address Detail.
|
5
|
+
|
6
|
+
class Address
|
7
|
+
DOMESTIC_URL = '/ParcelAddress/2.0/domestic/addresses'
|
8
|
+
INTERNATIONAL_URL = '/ParcelAddress/2.0/international/addresses'
|
9
|
+
|
10
|
+
# Creates a new ParcelApi::Address instance.
|
11
|
+
|
12
|
+
def initialize(connection=nil)
|
13
|
+
@connection ||= connection || ParcelApi::Client.connection
|
14
|
+
end
|
15
|
+
|
16
|
+
# Search for a Domestic (NZ) Address
|
17
|
+
# @param [String] characters to search for
|
18
|
+
# @param [Integer] number of search results to return (max 10)
|
19
|
+
# @return [Array] array of addresses
|
20
|
+
|
21
|
+
def search(query, count=10)
|
22
|
+
return [] if query.length < 4
|
23
|
+
|
24
|
+
response = @connection.get DOMESTIC_URL, { q: query, count: count }
|
25
|
+
addresses = response.body['addresses'].each do |a|
|
26
|
+
a['address_id'] = Integer(a['address_id'])
|
27
|
+
a['dpid'] = Integer(a['dpid'])
|
28
|
+
end
|
29
|
+
addresses.map {|address| OpenStruct.new(address)}
|
30
|
+
end
|
31
|
+
|
32
|
+
# Return domestic address details for a domestic address id
|
33
|
+
# @param address_id [String]
|
34
|
+
# @return address detail object
|
35
|
+
|
36
|
+
def details(address_id)
|
37
|
+
details_url = File.join(DOMESTIC_URL, address_id.to_s)
|
38
|
+
response = @connection.get details_url
|
39
|
+
OpenStruct.new(response.body['address'])
|
40
|
+
end
|
41
|
+
|
42
|
+
# Search for an International Address
|
43
|
+
# @param [String] characters to search for
|
44
|
+
# @param [Integer] number of search results to return (max 10)
|
45
|
+
# @param [String] country code for results - listed here: https://developers.google.com/public-data/docs/canonical/countries_csv/
|
46
|
+
# @return [Array] array of international addresses
|
47
|
+
|
48
|
+
def international_search(query, count=5, country_code=nil)
|
49
|
+
return [] if query.length < 4
|
50
|
+
|
51
|
+
response = @connection.get INTERNATIONAL_URL, { q: query, count: count, country_code: country_code }
|
52
|
+
response.body['addresses'].map {|address| OpenStruct.new(address)}
|
53
|
+
end
|
54
|
+
|
55
|
+
# Return international address details for a specific international address id
|
56
|
+
# @param address_id [String]
|
57
|
+
# @return international address detail
|
58
|
+
|
59
|
+
def international_details(address_id)
|
60
|
+
details_url = File.join(INTERNATIONAL_URL, address_id.to_s)
|
61
|
+
response = @connection.get details_url
|
62
|
+
RecursiveOpenStruct.new(response.body['result'], recurse_over_arrays: true)
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module ParcelApi
|
2
|
+
class Client
|
3
|
+
|
4
|
+
attr_accessor :client_id,
|
5
|
+
:client_secret,
|
6
|
+
:username,
|
7
|
+
:password,
|
8
|
+
:address,
|
9
|
+
:auth_address
|
10
|
+
|
11
|
+
def self.connection
|
12
|
+
@connection ||= new.connection
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@client_id = client_id || ENV['CLIENT_ID']
|
17
|
+
@client_secret = client_secret || ENV['CLIENT_SECRET']
|
18
|
+
@username = username || ENV['USERNAME']
|
19
|
+
@password = password || ENV['PASSWORD']
|
20
|
+
@address = address || 'https://api.nzpost.co.nz'
|
21
|
+
@auth_address = auth_address || 'https://oauth.nzpost.co.nz/as/token.oauth2'
|
22
|
+
end
|
23
|
+
|
24
|
+
def connection
|
25
|
+
Faraday.new(url: @address) do |conn|
|
26
|
+
conn.authorization 'Bearer', token
|
27
|
+
conn.headers['client_id'] = @client_id
|
28
|
+
conn.request :json
|
29
|
+
conn.response :json, :content_type => /\bjson$/
|
30
|
+
conn.use FaradayMiddleware::RaiseHttpException
|
31
|
+
conn.adapter Faraday.default_adapter
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def token
|
38
|
+
@token ||= begin
|
39
|
+
params = {
|
40
|
+
client_id: @client_id,
|
41
|
+
client_secret: @client_secret,
|
42
|
+
username: @username,
|
43
|
+
password: @password,
|
44
|
+
grant_type: 'password',
|
45
|
+
}
|
46
|
+
|
47
|
+
auth_api = Faraday.new do |conn|
|
48
|
+
conn.request :url_encoded
|
49
|
+
conn.response :json
|
50
|
+
conn.use FaradayMiddleware::RaiseHttpException
|
51
|
+
conn.adapter Faraday.default_adapter
|
52
|
+
end
|
53
|
+
response = auth_api.post @auth_address, params
|
54
|
+
response.body['access_token']
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# @private
|
2
|
+
module FaradayMiddleware
|
3
|
+
# @private
|
4
|
+
class RaiseHttpException < Faraday::Middleware
|
5
|
+
def call(env)
|
6
|
+
@app.call(env).on_complete do |response|
|
7
|
+
case response[:status].to_i
|
8
|
+
when 400
|
9
|
+
raise ParcelApi::BadRequest, error_message_400(response)
|
10
|
+
when 404
|
11
|
+
raise ParcelApi::NotFound, error_message_400(response)
|
12
|
+
when 500
|
13
|
+
raise ParcelApi::InternalServerError, error_message_500(response, "Something is technically wrong.")
|
14
|
+
when 502
|
15
|
+
raise ParcelApi::BadGateway, error_message_500(response, "The server returned an invalid or incomplete response.")
|
16
|
+
when 503
|
17
|
+
raise ParcelApi::ServiceUnavailable, error_message_500(response, "NZ Post is rate limiting your requests.")
|
18
|
+
when 504
|
19
|
+
raise ParcelApi::GatewayTimeout, error_message_500(response, "504 Gateway Time-out")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize(app)
|
25
|
+
super app
|
26
|
+
@parser = nil
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def error_message_400(response)
|
32
|
+
"#{response[:method].to_s.upcase} #{response[:url].to_s} status: #{response[:status]}#{error_body(response[:body])}"
|
33
|
+
end
|
34
|
+
|
35
|
+
def error_body(body)
|
36
|
+
# body gets passed as a string, not sure if it is passed as something else from other spots?
|
37
|
+
if not body.nil? and not body.empty? and body.kind_of?(String)
|
38
|
+
body = ::JSON.parse(body)
|
39
|
+
end
|
40
|
+
|
41
|
+
if body.nil? || body['errors'].nil?
|
42
|
+
nil
|
43
|
+
else
|
44
|
+
body_errors = body['errors'].flat_map {|error| error.map {|k,v| "#{k}: #{v}" }}.compact.join(', ')
|
45
|
+
" - #{body_errors}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def error_message_500(response, body=nil)
|
50
|
+
"#{response[:method].to_s.upcase} #{response[:url].to_s} status: #{[response[:status].to_s + ':', body].compact.join(' ')}"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
module ParcelApi
|
56
|
+
# Custom error class for rescuing from all NZ Post errors
|
57
|
+
class Error < StandardError; end
|
58
|
+
|
59
|
+
# Raised when NZ Post returns the HTTP status code 400
|
60
|
+
class BadRequest < Error; end
|
61
|
+
|
62
|
+
# Raised when NZ Post returns the HTTP status code 404
|
63
|
+
class NotFound < Error; end
|
64
|
+
|
65
|
+
# Raised when NZ Post returns the HTTP status code 429
|
66
|
+
class TooManyRequests < Error; end
|
67
|
+
|
68
|
+
# Raised when NZ Post returns the HTTP status code 500
|
69
|
+
class InternalServerError < Error; end
|
70
|
+
|
71
|
+
# Raised when NZ Post returns the HTTP status code 502
|
72
|
+
class BadGateway < Error; end
|
73
|
+
|
74
|
+
# Raised when NZ Post returns the HTTP status code 503
|
75
|
+
class ServiceUnavailable < Error; end
|
76
|
+
|
77
|
+
# Raised when NZ Post returns the HTTP status code 504
|
78
|
+
class GatewayTimeout < Error; end
|
79
|
+
|
80
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module ParcelApi
|
2
|
+
|
3
|
+
# This module provides API requests to label parcels, get existing label details
|
4
|
+
# and download labels.
|
5
|
+
|
6
|
+
class Label
|
7
|
+
LABEL_URL = '/ParcelLabel/2.0/labels'
|
8
|
+
|
9
|
+
# Creates a new ParcelApi::Label instance.
|
10
|
+
|
11
|
+
def initialize(connection=nil)
|
12
|
+
@connection ||= connection || ParcelApi::Client.connection
|
13
|
+
end
|
14
|
+
|
15
|
+
# Create a label with the specified options
|
16
|
+
# @param label_options [Hash]
|
17
|
+
# @return Single or array of label objects
|
18
|
+
|
19
|
+
def create(label_options)
|
20
|
+
domestic_url = File.join(LABEL_URL, 'domestic')
|
21
|
+
response = @connection.post domestic_url, label_options
|
22
|
+
labels = response.body['labels'].map {|label| OpenStruct.new(label)}
|
23
|
+
labels.first if labels.count == 1
|
24
|
+
end
|
25
|
+
|
26
|
+
# Create an international label with the specified options
|
27
|
+
# @param label_options [Hash]
|
28
|
+
# @return Single or array of label objects
|
29
|
+
|
30
|
+
def international_create(label_options)
|
31
|
+
international_url = File.join(LABEL_URL, 'international')
|
32
|
+
response = @connection.post international_url, label_options
|
33
|
+
labels = response.body['labels'].map {|label| OpenStruct.new(label)}
|
34
|
+
labels.first if labels.count == 1
|
35
|
+
end
|
36
|
+
|
37
|
+
# Get label details
|
38
|
+
# @param label_id [String]
|
39
|
+
# @return Object of label details
|
40
|
+
|
41
|
+
def details(label_id)
|
42
|
+
details_url = File.join(LABEL_URL, "#{label_id}.json")
|
43
|
+
response = @connection.get details_url
|
44
|
+
details = response.body.tap {|d| d.delete('success')}
|
45
|
+
OpenStruct.new(details)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Download label
|
49
|
+
# @param label_id [String]
|
50
|
+
# @return Object of label
|
51
|
+
|
52
|
+
def download(label_id)
|
53
|
+
download_url = File.join(LABEL_URL, "#{label_id}.pdf")
|
54
|
+
response = @connection.get download_url
|
55
|
+
StringIO.new(response.body)
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module ParcelApi
|
2
|
+
|
3
|
+
# The ParcelPickUp API that notifies PACE or CourierPost to come and pick up your parcel.
|
4
|
+
# The integrator provides the pick up location in the form of a site id or an address to create the pick up record.
|
5
|
+
|
6
|
+
class Pickup
|
7
|
+
PARCELPICKUP_URL = '/ParcelPickUp/2.0/bookings'
|
8
|
+
|
9
|
+
# Creates a new ParcelApi::Pickup instance.
|
10
|
+
|
11
|
+
def initialize(connection=nil)
|
12
|
+
@connection ||= connection || ParcelApi::Client.connection
|
13
|
+
end
|
14
|
+
|
15
|
+
# Create a new parcel booking
|
16
|
+
# @param pickup_options [Hash]
|
17
|
+
# @return Object of pickup details
|
18
|
+
|
19
|
+
def create(pickup_options)
|
20
|
+
response = @connection.post PARCELPICKUP_URL, pickup_options
|
21
|
+
RecursiveOpenStruct.new(response.body, recurse_over_arrays: true)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module ParcelApi
|
2
|
+
|
3
|
+
# Returns the shipping options and rates available depending on customer,
|
4
|
+
# pick up and destination addresses and parcel dimensions and weight.
|
5
|
+
# Both domestic and international.
|
6
|
+
|
7
|
+
class ShippingOptions
|
8
|
+
DOMESTIC_URL = '/ShippingOptions/2.0/domestic'
|
9
|
+
INTERNATIONAL_URL = '/ShippingOptions/2.0/international'
|
10
|
+
|
11
|
+
# Creates a new ParcelApi::ShippingOptions instance.
|
12
|
+
|
13
|
+
def initialize(connection=nil)
|
14
|
+
@connection ||= connection || ParcelApi::Client.connection
|
15
|
+
end
|
16
|
+
|
17
|
+
# Search for Domestic (NZ) Shipping Options
|
18
|
+
# @param parcel_params [Hash] parcel parameters
|
19
|
+
# @return [Array] return array of shipping options
|
20
|
+
|
21
|
+
def get_domestic(parcel_params)
|
22
|
+
response = @connection.get DOMESTIC_URL, parcel_params
|
23
|
+
options = response.body.tap do |so|
|
24
|
+
so.delete('success')
|
25
|
+
so.delete('message_id')
|
26
|
+
end
|
27
|
+
RecursiveOpenStruct.new(options, recurse_over_arrays: true)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Search for International Shipping Options
|
31
|
+
# @param parcel_params [Hash] parcel parameters
|
32
|
+
# @return [Array] return array of shipping options
|
33
|
+
|
34
|
+
def get_international(parcel_params)
|
35
|
+
response = @connection.get INTERNATIONAL_URL, parcel_params
|
36
|
+
options = response.body.tap do |so|
|
37
|
+
so.delete('success')
|
38
|
+
so.delete('message_id')
|
39
|
+
end
|
40
|
+
RecursiveOpenStruct.new(options, recurse_over_arrays: true)
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module ParcelApi
|
2
|
+
|
3
|
+
# This module provides API requests to track the parcels and
|
4
|
+
# return tracking information for a specific tracking reference.
|
5
|
+
|
6
|
+
class Track
|
7
|
+
PARCELTRACK_URL = '/ParcelTrack/2.0/parcels'
|
8
|
+
|
9
|
+
# Creates a new ParcelApi::Track instance.
|
10
|
+
|
11
|
+
def initialize(connection=nil)
|
12
|
+
@connection ||= connection || ParcelApi::Client.connection
|
13
|
+
end
|
14
|
+
|
15
|
+
# Return details for a specific tracking reference.
|
16
|
+
# @param tracking_reference [String]
|
17
|
+
# @return Object of tracking details
|
18
|
+
|
19
|
+
def details(tracking_reference)
|
20
|
+
details_url = File.join(PARCELTRACK_URL, tracking_reference.to_s)
|
21
|
+
response = @connection.get details_url
|
22
|
+
events = response.body.tap do |d|
|
23
|
+
d.delete('success')
|
24
|
+
d['tracking_events'].map {|e| e['event_datetime'] = Time.parse(e['event_datetime'])}
|
25
|
+
d['tracking_events'].sort_by! {|k| k['event_datetime'].to_i}
|
26
|
+
end
|
27
|
+
RecursiveOpenStruct.new(events, recurse_over_arrays: true)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
data/lib/parcel_api.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'faraday_middleware'
|
3
|
+
require 'recursive-open-struct'
|
4
|
+
|
5
|
+
require 'parcel_api/version'
|
6
|
+
require 'parcel_api/error'
|
7
|
+
require 'parcel_api/address'
|
8
|
+
require 'parcel_api/track'
|
9
|
+
require 'parcel_api/label'
|
10
|
+
require 'parcel_api/shipping_options'
|
11
|
+
require 'parcel_api/pickup'
|
12
|
+
require 'parcel_api/client'
|
13
|
+
|
14
|
+
module ParcelApi; end
|
data/parcel_api.gemspec
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'parcel_api/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'parcel_api'
|
8
|
+
spec.version = ParcelApi::VERSION
|
9
|
+
spec.authors = ['Robert Coleman']
|
10
|
+
spec.email = ['github@robert.net.nz']
|
11
|
+
|
12
|
+
spec.summary = %q{Ruby client for NZ Post's Parcel APIs}
|
13
|
+
spec.homepage = 'https://github.com/etailer/parcel_api'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
+
spec.bindir = 'exe'
|
18
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_dependency 'thor', '~> 0.19'
|
22
|
+
spec.add_dependency 'faraday', '~> 0.9'
|
23
|
+
spec.add_dependency 'faraday_middleware', '~> 0.9'
|
24
|
+
spec.add_dependency 'oauth2', '~> 1.0'
|
25
|
+
spec.add_dependency 'recursive-open-struct', '~> 0.6'
|
26
|
+
|
27
|
+
spec.add_development_dependency 'bundler', '~> 1.8'
|
28
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
29
|
+
spec.add_development_dependency 'rspec', '~> 3.2'
|
30
|
+
spec.add_development_dependency 'pry', '~> 0.10'
|
31
|
+
spec.add_development_dependency 'webmock', '~> 1.21'
|
32
|
+
spec.add_development_dependency 'vcr', '~> 2.9'
|
33
|
+
spec.add_development_dependency 'yard', '~> 0.8'
|
34
|
+
end
|
metadata
ADDED
@@ -0,0 +1,237 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: parcel_api
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Robert Coleman
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-09-13 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: thor
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.19'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.19'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: faraday
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.9'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.9'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: faraday_middleware
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.9'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.9'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: oauth2
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: recursive-open-struct
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.6'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.6'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: bundler
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.8'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.8'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rake
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '10.0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '10.0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rspec
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '3.2'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '3.2'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: pry
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0.10'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0.10'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: webmock
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '1.21'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '1.21'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: vcr
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '2.9'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '2.9'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: yard
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0.8'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - "~>"
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0.8'
|
181
|
+
description:
|
182
|
+
email:
|
183
|
+
- github@robert.net.nz
|
184
|
+
executables: []
|
185
|
+
extensions: []
|
186
|
+
extra_rdoc_files: []
|
187
|
+
files:
|
188
|
+
- ".gitignore"
|
189
|
+
- ".rspec"
|
190
|
+
- ".travis.yml"
|
191
|
+
- ".yardopts"
|
192
|
+
- Gemfile
|
193
|
+
- Gemfile.lock
|
194
|
+
- LICENSE
|
195
|
+
- README.md
|
196
|
+
- Rakefile
|
197
|
+
- bin/console
|
198
|
+
- bin/parcel
|
199
|
+
- bin/setup
|
200
|
+
- example/mock.rb
|
201
|
+
- lib/parcel_api.rb
|
202
|
+
- lib/parcel_api/address.rb
|
203
|
+
- lib/parcel_api/cli.rb
|
204
|
+
- lib/parcel_api/client.rb
|
205
|
+
- lib/parcel_api/error.rb
|
206
|
+
- lib/parcel_api/label.rb
|
207
|
+
- lib/parcel_api/pickup.rb
|
208
|
+
- lib/parcel_api/shipping_options.rb
|
209
|
+
- lib/parcel_api/track.rb
|
210
|
+
- lib/parcel_api/version.rb
|
211
|
+
- parcel_api.gemspec
|
212
|
+
homepage: https://github.com/etailer/parcel_api
|
213
|
+
licenses:
|
214
|
+
- MIT
|
215
|
+
metadata: {}
|
216
|
+
post_install_message:
|
217
|
+
rdoc_options: []
|
218
|
+
require_paths:
|
219
|
+
- lib
|
220
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
221
|
+
requirements:
|
222
|
+
- - ">="
|
223
|
+
- !ruby/object:Gem::Version
|
224
|
+
version: '0'
|
225
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
226
|
+
requirements:
|
227
|
+
- - ">="
|
228
|
+
- !ruby/object:Gem::Version
|
229
|
+
version: '0'
|
230
|
+
requirements: []
|
231
|
+
rubyforge_project:
|
232
|
+
rubygems_version: 2.4.5
|
233
|
+
signing_key:
|
234
|
+
specification_version: 4
|
235
|
+
summary: Ruby client for NZ Post's Parcel APIs
|
236
|
+
test_files: []
|
237
|
+
has_rdoc:
|