rrd-track 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +17 -0
- data/.travis.yml +5 -0
- data/Gemfile.lock +3 -3
- data/lib/rrd-track.rb +27 -0
- data/lib/rrd-track/client.rb +38 -0
- data/lib/rrd-track/configuration.rb +9 -0
- data/lib/rrd-track/errors.rb +35 -0
- data/lib/rrd-track/request/tracking.rb +21 -0
- data/lib/rrd-track/response/shipment_detail.rb +18 -0
- data/lib/rrd-track/response/track_detail.rb +14 -0
- data/lib/rrd-track/response/tracking.rb +43 -0
- data/lib/rrd-track/version.rb +3 -0
- data/spec/rrd-track/track_spec.rb +34 -0
- data/spec/rrd_api_responses/shipment_shipped.xml +1 -0
- data/spec/spec_helper.rb +9 -0
- metadata +19 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 347aed7783f12924af79b05b36445ddb85f457a5
|
4
|
+
data.tar.gz: 158a044571e878f540639677314b184f0292bfe1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b5d7a0ef976a86d7c0b0b7492ae89bc3807c544ae454f983e10b7b817be2a10ae7862578afbf5ec1fdc193c46ad195eea68c074eaca6427df40e0a62a764ed56
|
7
|
+
data.tar.gz: e4dc8f5c10707bcf4da0e8be7093d12b26ab517c161be3a0fd49e744ddc8dd1afcd941126f2d52136e4fe01c66642361b1fff8ccb6aaa72c6703d3d5cd183623
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile.lock
CHANGED
data/lib/rrd-track.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require "rrd-track/client"
|
2
|
+
require "rrd-track/configuration"
|
3
|
+
require "rrd-track/version"
|
4
|
+
|
5
|
+
module RRD
|
6
|
+
class << self
|
7
|
+
attr_writer :configuration
|
8
|
+
|
9
|
+
def client
|
10
|
+
@client ||= Client.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def configuration
|
14
|
+
@configuration ||= Configuration.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def configure
|
18
|
+
yield(configuration)
|
19
|
+
end
|
20
|
+
|
21
|
+
def track(tracking_number)
|
22
|
+
client.request(RRD::Request::Tracking.new(tracking_number))
|
23
|
+
end
|
24
|
+
|
25
|
+
alias_method :config, :configuration
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'typhoeus'
|
3
|
+
|
4
|
+
require "rrd-track/errors"
|
5
|
+
require "rrd-track/request/tracking"
|
6
|
+
require "rrd-track/response/tracking"
|
7
|
+
|
8
|
+
module RRD
|
9
|
+
class Client
|
10
|
+
|
11
|
+
def request(request, &block)
|
12
|
+
response = Typhoeus::Request.get(tracking_api_url, {
|
13
|
+
timeout: RRD.config.timeout,
|
14
|
+
params: request.api_params,
|
15
|
+
headers: { Accept: "application/xml" }
|
16
|
+
})
|
17
|
+
|
18
|
+
# Parse the request
|
19
|
+
xml = Nokogiri::XML.parse(response.body)
|
20
|
+
|
21
|
+
if (error = xml.search('error')).any?
|
22
|
+
code = error.search('code').text
|
23
|
+
description = error.search('description').text
|
24
|
+
|
25
|
+
raise Error.for_code(code).new(code, description)
|
26
|
+
end
|
27
|
+
|
28
|
+
request.response_handler(xml)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def tracking_api_url
|
34
|
+
"http://www.ppxtrack.com/api/ParcelTracking"
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module RRD
|
2
|
+
class Error < StandardError
|
3
|
+
attr_reader :code, :description
|
4
|
+
|
5
|
+
def initialize(code, description)
|
6
|
+
super(description)
|
7
|
+
@code = code
|
8
|
+
@description = description
|
9
|
+
end
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def for_code(code)
|
13
|
+
case code
|
14
|
+
when '100'; UsernameNotFoundError
|
15
|
+
when '110'; PasswordNotFoundError
|
16
|
+
when '120'; TrackingNumberNotFoundError
|
17
|
+
when '130'; AuthenticationError
|
18
|
+
when '200'; ShippingSiteError
|
19
|
+
when '300'; DatabaseError
|
20
|
+
when '400'; BadTrackingNumberError
|
21
|
+
else ; Error
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class ValidationError < Error; end
|
28
|
+
class UsernameNotFoundError < ValidationError; end
|
29
|
+
class PasswordNotFoundError < ValidationError; end
|
30
|
+
class TrackingNumberNotFoundError < ValidationError; end
|
31
|
+
class AuthenticationError < Error; end
|
32
|
+
class ShippingSiteError < Error; end
|
33
|
+
class DatabaseError < Error; end
|
34
|
+
class BadTrackingNumberError < Error; end
|
35
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module RRD::Request
|
2
|
+
class Tracking
|
3
|
+
|
4
|
+
attr_accessor :tracking_number
|
5
|
+
|
6
|
+
def initialize(tracking_number)
|
7
|
+
@tracking_number = tracking_number
|
8
|
+
end
|
9
|
+
|
10
|
+
def api_params
|
11
|
+
{
|
12
|
+
id: tracking_number
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
def response_handler(xml)
|
17
|
+
RRD::Response::Tracking.new(xml)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module RRD::Response
|
2
|
+
class ShipmentDetail
|
3
|
+
attr_accessor :airway_bill,
|
4
|
+
:tracking_number,
|
5
|
+
:location,
|
6
|
+
:status,
|
7
|
+
:vendor_code,
|
8
|
+
:vendor_name,
|
9
|
+
:is_courier
|
10
|
+
|
11
|
+
def initialize(init)
|
12
|
+
init.each_pair do |key, val|
|
13
|
+
instance_variable_set('@' + key.to_s, val)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module RRD::Response
|
2
|
+
class Tracking
|
3
|
+
require 'rrd-track/response/shipment_detail'
|
4
|
+
require 'rrd-track/response/track_detail'
|
5
|
+
|
6
|
+
attr_accessor :tracking_events, :shipment_detail
|
7
|
+
|
8
|
+
def initialize(xml)
|
9
|
+
@shipment_detail = parse_shipment_detail(xml.search("ParcelTrackingViewModel"))
|
10
|
+
@tracking_events = []
|
11
|
+
xml.search("StopDetailViewModel").each do |event|
|
12
|
+
@tracking_events << parse_tracking_detail(event)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def parse_shipment_detail(node)
|
19
|
+
RRD::Response::ShipmentDetail.new(
|
20
|
+
{
|
21
|
+
airway_bill: node.search('AirwayBill').text,
|
22
|
+
tracking_number: node.search('TrackingNumber').text,
|
23
|
+
location: node.search('Location').text,
|
24
|
+
status: node.search('Status').text,
|
25
|
+
vendor_code: node.search('VendorCode').text,
|
26
|
+
vendor_name: node.search('VendorName').text,
|
27
|
+
is_courier: node.search('IsCourier').text
|
28
|
+
}
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
def parse_tracking_detail(node)
|
33
|
+
RRD::Response::TrackDetail.new(
|
34
|
+
{
|
35
|
+
description: node.search('Description').text,
|
36
|
+
location: node.search('Location').text,
|
37
|
+
timestamp: node.search('TimeStamp').text
|
38
|
+
}
|
39
|
+
)
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RRD do
|
4
|
+
|
5
|
+
it "tracks shipped packages" do
|
6
|
+
|
7
|
+
rrd_tracking_xml = File.read("#{Dir.pwd}/spec/rrd_api_responses/shipment_shipped.xml")
|
8
|
+
|
9
|
+
WebMock.stub_request(:get, "http://www.ppxtrack.com/api/ParcelTracking?id=2043XXXXXX1513").
|
10
|
+
with(headers: {'User-Agent'=>'Typhoeus - https://github.com/typhoeus/typhoeus'}).
|
11
|
+
to_return(status: 200, body: rrd_tracking_xml)
|
12
|
+
|
13
|
+
result = RRD::track('2043XXXXXX1513')
|
14
|
+
|
15
|
+
expect(result).to be_kind_of(RRD::Response::Tracking)
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
it "tracks shipped packages with two events" do
|
20
|
+
|
21
|
+
rrd_tracking_xml = File.read("#{Dir.pwd}/spec/rrd_api_responses/shipment_shipped.xml")
|
22
|
+
|
23
|
+
WebMock.stub_request(:get, "http://www.ppxtrack.com/api/ParcelTracking?id=2043XXXXXX1513").
|
24
|
+
with(headers: {'User-Agent'=>'Typhoeus - https://github.com/typhoeus/typhoeus'}).
|
25
|
+
to_return(status: 200, body: rrd_tracking_xml)
|
26
|
+
|
27
|
+
result = RRD::track('2043XXXXXX1513')
|
28
|
+
|
29
|
+
expect(result.tracking_events.count).to eq(11)
|
30
|
+
expect(result.tracking_events.first).to be_kind_of(RRD::Response::TrackDetail)
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<ParcelTrackingViewModel xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Rrdl.International.Model.ViewModel"><AirwayBill>3999682</AirwayBill><AirwayBillDisplay>3999682(02)</AirwayBillDisplay><IsCourier>false</IsCourier><LastActivity>2014-02-07T10:09:58</LastActivity><Location>Brampton</Location><Status>Item successfully delivered</Status><Stops><StopDetailViewModel><Description>Item successfully delivered</Description><Location>Brampton</Location><TimeStamp>2014-02-07T10:09:58</TimeStamp></StopDetailViewModel><StopDetailViewModel><Description>Item out for delivery</Description><Location>Brampton</Location><TimeStamp>2014-02-07T08:57:21</TimeStamp></StopDetailViewModel><StopDetailViewModel><Description>Item processed at local delivery facility</Description><Location>Brampton</Location><TimeStamp>2014-02-07T05:34:21</TimeStamp></StopDetailViewModel><StopDetailViewModel><Description>Item processed</Description><Location>Mississauga</Location><TimeStamp>2014-02-06T20:02:32</TimeStamp></StopDetailViewModel><StopDetailViewModel><Description>Item processed</Description><Location>Mississauga</Location><TimeStamp>2014-02-06T19:52:56</TimeStamp></StopDetailViewModel><StopDetailViewModel><Description>Item picked up by Canada Post</Description><Location>Mississauga</Location><TimeStamp>2014-02-06T19:22:53</TimeStamp></StopDetailViewModel><StopDetailViewModel><Description>Electronic information submitted by shipper</Description><Location>Mississauga</Location><TimeStamp>2014-02-03T19:34:30</TimeStamp></StopDetailViewModel><StopDetailViewModel><Description>In transit to Canada Post tracking#: 7100848307767497</Description><Location></Location><TimeStamp>2014-02-03T14:22:54</TimeStamp></StopDetailViewModel><StopDetailViewModel><Description>Parcel Shipped</Description><Location>Itasca IL</Location><TimeStamp>2014-02-03T14:21:54</TimeStamp></StopDetailViewModel><StopDetailViewModel><Description>Parcel Received</Description><Location>Itasca IL</Location><TimeStamp>2014-02-03T14:07:40</TimeStamp></StopDetailViewModel><StopDetailViewModel><Description>E-File Uploaded</Description><Location>Itasca IL</Location><TimeStamp>2014-02-03T11:59:14</TimeStamp></StopDetailViewModel></Stops><TrackingNumber>7100848307767497</TrackingNumber><VendorCode>02</VendorCode><VendorName>CPC-PARCELS</VendorName></ParcelTrackingViewModel>
|
data/spec/spec_helper.rb
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rrd-track
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Scott Rocher
|
@@ -101,12 +101,26 @@ executables: []
|
|
101
101
|
extensions: []
|
102
102
|
extra_rdoc_files: []
|
103
103
|
files:
|
104
|
+
- ".gitignore"
|
105
|
+
- ".travis.yml"
|
104
106
|
- Gemfile
|
105
107
|
- Gemfile.lock
|
106
108
|
- LICENSE.txt
|
107
109
|
- README.md
|
108
110
|
- Rakefile
|
111
|
+
- lib/rrd-track.rb
|
112
|
+
- lib/rrd-track/client.rb
|
113
|
+
- lib/rrd-track/configuration.rb
|
114
|
+
- lib/rrd-track/errors.rb
|
115
|
+
- lib/rrd-track/request/tracking.rb
|
116
|
+
- lib/rrd-track/response/shipment_detail.rb
|
117
|
+
- lib/rrd-track/response/track_detail.rb
|
118
|
+
- lib/rrd-track/response/tracking.rb
|
119
|
+
- lib/rrd-track/version.rb
|
109
120
|
- rrd-track.gemspec
|
121
|
+
- spec/rrd-track/track_spec.rb
|
122
|
+
- spec/rrd_api_responses/shipment_shipped.xml
|
123
|
+
- spec/spec_helper.rb
|
110
124
|
homepage: https://github.com/rochers/rrd-track
|
111
125
|
licenses: []
|
112
126
|
metadata: {}
|
@@ -130,4 +144,7 @@ rubygems_version: 2.2.2
|
|
130
144
|
signing_key:
|
131
145
|
specification_version: 4
|
132
146
|
summary: Request, parse, and work with RR Donnelley tracking events.
|
133
|
-
test_files:
|
147
|
+
test_files:
|
148
|
+
- spec/rrd-track/track_spec.rb
|
149
|
+
- spec/rrd_api_responses/shipment_shipped.xml
|
150
|
+
- spec/spec_helper.rb
|